~ubuntu-branches/ubuntu/wily/xscreensaver/wily

« back to all changes in this revision

Viewing changes to hacks/glx/tronbit.c

  • Committer: Jamie Strandboge
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2012-01-30 23:21:11 UTC
  • Revision ID: jamie@canonical.com-20120130232111-eu6ryx01f1ynscj7
Tags: 5.15-2ubuntu1
* Merge with Debian testing, remaining Ubuntu changes:
  - debian/control:
    + Add Vcs-Bzr link
    + Add/Update replaces with Ubuntu versions
    + Update package descriptions to list Ubuntu screensavers
  - debian/rules:
    + Use /usr/share/backgrounds as image directory
    + Add translation domain to .desktop files
  - debian/source_xscreensaver.py: 
    + Add apport hook
  - debian/split-hacks.config:
    + Use different set of default hacks than Debian
  - debian/xscreensaver.dirs
    + Install /usr/share/backgrounds. By default, settings search in
      /usr/share/backgrounds and without it, it displays an error
  - debian/patches/53_XScreenSaver.ad.in.patch:
    + Use Ubuntu branding
  - debian/patches/60_sequential_glslideshow.patch:
    + Allow going through images sequentially rather than just at random in
      the GLSlideshow hack. 
* debian/changelog: really clean up changelog, some entries were still out of
  place.
* Build-dep on libjpeg-dev instead of libjpeg62-dev (Closes: #647110)
[ Tormod Volden ]
* New upstream version 5.15
  - New hacks: hilbert, companioncube and tronbit
  - Turned on LC_CTYPE on Linux (LP: #671923)
* debian/rules: Add build-arch and build-indep targets
[ Jose Luis Rivas ]
* postrm: Kill xscreensaver after removal (Closes: #558024)
* Bump Standards-Version to 3.9.2 (no changes needed)
* Non-maintainer upload by the security team.
* Fix local screen lock bypass vulnerability (closes: #539699).
[ Tormod Volden ]
* New Upstream Version
* driver/XScreensaver.ad.in:
  + Use ISO time/date format in password dialog
  + Use url as default text method
  + remove dnalogo and flurry which are not installed 
* remove xsublim hack since upstream no more installs it
* add desktop file comment to cubicgrid, hypnowheel and lcdscrub
* debian/patches: renamed, commented, refreshed patches and series
* debian/control: use Suggests xscreensaver instead of Enhances
  for -data and -gl packages
* Fixed Exec and TryExec entries in desktop files.
* Fixed manpages warnings and bad-formatting.
* Fixed Vcs-Browser URI.
* Drop xli | xloadimage recommends to universe. Both are in universe, and
  xli is orphaned in Debian.
* Restore the fix from 5.05-1ubuntu2, which was lost in the latest
  merge:
* xscreensaver-gl and xscreensaver-gl-extras Recommend xscreensaver |
  gnome-screensaver rather than merely xscreensaver, so that germinate
  won't pull xscreensaver into the desktop (LP: #242495).
* Upgrade upstream version
* debian/control: Remove suggest xdaliclock as it is no longer
  included
* Remove 10_jwz-screensaver-randr-patch-3.patch as it has been merged
  upstream.
* Add 24_hacks_xsublim_enable.patch as it seems that xsublim was dropped
  from the build files.  There is nothing in the Changelog about it
  so I believe it was accidental.
* Updating the .desktop files from the XML files using gnome-screensaver's
  utility to do so.  Lots of text updates.  Also:
    * Added: abstractile.desktop
    * Added: cwaves.desktop
    * Added: m6502.desktop
    * Added: skytentacles.desktop
    * Removed: xteevee.desktop
* xscreensaver-gl-extra.files: Added skytentacles
* xscreensaver-data-extra.files: Added abstractile, cwaves and m6502
* xscreensaver-data.files: Remove partial abstractile, m6502 and cwaves
[ Jose Luis Rivas ]
* New upstream release
* debian/patches:
 + delete patch for xinerama, is now merged upstream
 + add patch for hacks/Makefile.in
[ Tormod Volden ]
* debian/control: let the hacks packages "enhance" xscreensaver
  and gnome-screensaver since they can be used independently
* use upstream xscreensaver-properties.desktop instead of our own
* move man pages to section 6x in a consistent way
* ship the lcdscrub man page
* factor out common stuff from hacks desktop files into one stub
  file for easier mass modification
* add OnlyShowIn=GNOME to desktop files (fixes lintian warnings)
* add -randomize to truchet and xlyap desktop files
* add desktop file for m6502, abstractile and cwaves
* fixed up names in several desktop files
* use yelp to display man pages in Preferences dialog if available,
  and do the right thing in a terminal window if not
* NMU.
* should not kill running xscreensavers (Close: #334193)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* tronbit, Copyright (c) 2011 Jamie Zawinski <jwz@jwz.org>
 
2
 *
 
3
 * Permission to use, copy, modify, distribute, and sell this software and its
 
4
 * documentation for any purpose is hereby granted without fee, provided that
 
5
 * the above copyright notice appear in all copies and that both that
 
6
 * copyright notice and this permission notice appear in supporting
 
7
 * documentation.  No representations are made about the suitability of this
 
8
 * software for any purpose.  It is provided "as is" without express or 
 
9
 * implied warranty.
 
10
 */
 
11
 
 
12
#define DEFAULTS        "*delay:        30000       \n" \
 
13
                        "*count:        30          \n" \
 
14
                        "*showFPS:      False       \n" \
 
15
                        "*wireframe:    False       \n"
 
16
 
 
17
# define refresh_bit 0
 
18
# define release_bit 0
 
19
#undef countof
 
20
#define countof(x) (sizeof((x))/sizeof((*x)))
 
21
 
 
22
#include "xlockmore.h"
 
23
#include "colors.h"
 
24
#include "sphere.h"
 
25
#include "rotator.h"
 
26
#include "gltrackball.h"
 
27
#include <ctype.h>
 
28
 
 
29
#ifdef USE_GL /* whole file */
 
30
 
 
31
#include "gllist.h"
 
32
 
 
33
extern const struct gllist *tronbit_idle1, *tronbit_idle2,
 
34
  *tronbit_no, *tronbit_yes;
 
35
static const struct gllist * const *all_objs[] = {
 
36
  &tronbit_idle1, &tronbit_idle2, &tronbit_no, &tronbit_yes };
 
37
 
 
38
 
 
39
#define DEF_SPIN        "True"
 
40
#define DEF_WANDER      "True"
 
41
#define DEF_SPEED       "1.0"
 
42
 
 
43
#define HISTORY_LENGTH 512
 
44
typedef enum { BIT_IDLE1, BIT_IDLE2, BIT_NO, BIT_YES } bit_state;
 
45
#define MODELS 4
 
46
 
 
47
 
 
48
typedef struct {
 
49
  GLXContext *glx_context;
 
50
  rotator *rot;
 
51
  trackball_state *trackball;
 
52
  Bool button_down_p;
 
53
 
 
54
  double frequency;
 
55
  double confidence;
 
56
 
 
57
  double last_time;
 
58
  unsigned char history   [HISTORY_LENGTH];
 
59
  unsigned char histogram [HISTORY_LENGTH];
 
60
  int history_fp, histogram_fp;
 
61
 
 
62
  GLuint dlists[MODELS], polys[MODELS];
 
63
  char kbd;
 
64
 
 
65
} bit_configuration;
 
66
 
 
67
static bit_configuration *bps = NULL;
 
68
 
 
69
static const GLfloat colors[][4] = {
 
70
  { 0.66, 0.85, 1.00, 1.00 },
 
71
  { 0.66, 0.85, 1.00, 1.00 },
 
72
  { 1.00, 0.12, 0.12, 1.00 },
 
73
  { 0.98, 0.85, 0.30, 1.00 }
 
74
};
 
75
 
 
76
 
 
77
static Bool do_spin;
 
78
static GLfloat speed;
 
79
static Bool do_wander;
 
80
 
 
81
static XrmOptionDescRec opts[] = {
 
82
  { "-spin",   ".spin",   XrmoptionNoArg, "True" },
 
83
  { "+spin",   ".spin",   XrmoptionNoArg, "False" },
 
84
  { "-speed",  ".speed",  XrmoptionSepArg, 0 },
 
85
  { "-wander", ".wander", XrmoptionNoArg, "True" },
 
86
  { "+wander", ".wander", XrmoptionNoArg, "False" }
 
87
};
 
88
 
 
89
static argtype vars[] = {
 
90
  {&do_spin,   "spin",   "Spin",   DEF_SPIN,   t_Bool},
 
91
  {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
 
92
  {&speed,     "speed",  "Speed",  DEF_SPEED,  t_Float},
 
93
};
 
94
 
 
95
ENTRYPOINT ModeSpecOpt bit_opts = {countof(opts), opts, countof(vars), vars, NULL};
 
96
 
 
97
 
 
98
/* Returns the current time in seconds as a double.
 
99
 */
 
100
static double
 
101
double_time (void)
 
102
{
 
103
  struct timeval now;
 
104
# ifdef GETTIMEOFDAY_TWO_ARGS
 
105
  struct timezone tzp;
 
106
  gettimeofday(&now, &tzp);
 
107
# else
 
108
  gettimeofday(&now);
 
109
# endif
 
110
 
 
111
  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
 
112
}
 
113
 
 
114
 
 
115
static int
 
116
make_bit (ModeInfo *mi, bit_state which)
 
117
{
 
118
  static const GLfloat spec[4] = {1.0, 1.0, 1.0, 1.0};
 
119
  static const GLfloat shiny   = 128.0;
 
120
  const GLfloat *color = colors[which];
 
121
  int wire = MI_IS_WIREFRAME(mi);
 
122
  int polys = 0;
 
123
  GLfloat s;
 
124
  const struct gllist *gll;
 
125
 
 
126
  glMaterialfv (GL_FRONT, GL_SPECULAR,            spec);
 
127
  glMateriali  (GL_FRONT, GL_SHININESS,           shiny);
 
128
  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
 
129
  glColor4f (color[0], color[1], color[2], color[3]);
 
130
 
 
131
  glPushMatrix();
 
132
  switch (which)
 
133
    {
 
134
    case BIT_IDLE1:
 
135
      glRotatef (-44, 0, 1, 0);   /* line up the models with each other */
 
136
      glRotatef (-11, 1, 0, 0);
 
137
      glRotatef (  8, 0, 0, 1);
 
138
      s = 1.0;
 
139
      break;
 
140
    case BIT_IDLE2:
 
141
      glRotatef ( 16.0, 0, 0, 1);
 
142
      glRotatef (-28.0, 1, 0, 0);
 
143
      s = 1.0;
 
144
      break;
 
145
    case BIT_NO:
 
146
      glRotatef ( 16.0, 0, 0, 1);
 
147
      glRotatef (-28.0, 1, 0, 0);
 
148
      s = 1.6;
 
149
      break;
 
150
    case BIT_YES:
 
151
      glRotatef (-44.0, 0, 1, 0);
 
152
      glRotatef (-32.0, 1, 0, 0);
 
153
      s = 1.53;
 
154
      break;
 
155
    default:
 
156
      abort();
 
157
      break;
 
158
    }
 
159
  glScalef (s, s, s);
 
160
  gll = *all_objs[which];
 
161
  renderList (gll, wire);
 
162
  polys += gll->points / 3;
 
163
  glPopMatrix();
 
164
 
 
165
  return polys;
 
166
}
 
167
 
 
168
 
 
169
static void
 
170
tick_bit (ModeInfo *mi, double now)
 
171
{
 
172
  bit_configuration *bp = &bps[MI_SCREEN(mi)];
 
173
  double freq = bp->frequency;
 
174
  int n = bp->history[bp->history_fp];
 
175
  int histogram_speed = 3 * speed;
 
176
  int i;
 
177
 
 
178
  if (histogram_speed < 1) histogram_speed = 1;
 
179
 
 
180
  if (n == BIT_YES || n == BIT_NO)
 
181
    freq *= 2;
 
182
 
 
183
  if (bp->button_down_p) return;
 
184
 
 
185
  for (i = 0; i < histogram_speed; i++)
 
186
    {
 
187
      int nn = (n == BIT_YES ? 240 : n == BIT_NO  ? 17 : 128);
 
188
      int on = bp->histogram[(bp->histogram_fp-1) % countof(bp->histogram)];
 
189
 
 
190
      /* smooth out the square wave a little bit */
 
191
 
 
192
      if (!(nn > 100 && nn < 200) !=
 
193
          !(on > 100 && on < 200))
 
194
        nn += (((random() % 48) - 32) *
 
195
               ((on > 100 && on < 200) ? 1 : -1));
 
196
 
 
197
      nn += (random() % 16) - 8;
 
198
 
 
199
      bp->histogram_fp++;
 
200
      if (bp->histogram_fp >= countof(bp->history))
 
201
        bp->histogram_fp = 0;
 
202
      bp->histogram [bp->histogram_fp] = nn;
 
203
    }
 
204
 
 
205
 
 
206
  if (bp->last_time + freq > now && !bp->kbd) return;
 
207
 
 
208
  bp->last_time = now;
 
209
 
 
210
  bp->history_fp++;
 
211
  if (bp->history_fp >= countof(bp->history))
 
212
    bp->history_fp = 0;
 
213
 
 
214
  if (bp->kbd)
 
215
    {
 
216
      n = (bp->kbd == '1' ? BIT_YES :
 
217
           bp->kbd == '0' ? BIT_NO :
 
218
           (random() & 1) ? BIT_YES : BIT_NO);
 
219
      bp->kbd = 0;
 
220
    }
 
221
  else if (n == BIT_YES || 
 
222
           n == BIT_NO ||
 
223
           frand(1.0) >= bp->confidence)
 
224
    n = (n == BIT_IDLE1 ? BIT_IDLE2 : BIT_IDLE1);
 
225
  else
 
226
    n = (random() & 1) ? BIT_YES : BIT_NO;
 
227
 
 
228
  bp->history [bp->history_fp] = n;
 
229
}
 
230
 
 
231
 
 
232
static int
 
233
animate_bits (ModeInfo *mi, bit_state omodel, bit_state nmodel, GLfloat ratio)
 
234
{
 
235
  bit_configuration *bp = &bps[MI_SCREEN(mi)];
 
236
  int polys = 0;
 
237
  GLfloat scale = sin (ratio * M_PI / 2);
 
238
  GLfloat osize, nsize, small;
 
239
 
 
240
 if ((omodel == BIT_IDLE1 || omodel == BIT_IDLE2) &&
 
241
     (nmodel == BIT_IDLE1 || nmodel == BIT_IDLE2))
 
242
   small = 0.9;
 
243
 else
 
244
   small = 0.5;
 
245
 
 
246
  nsize = small + (1 - small) * scale;
 
247
  osize = small + (1 - small) * (1 - scale);
 
248
 
 
249
  glPushMatrix();
 
250
  glScalef (osize, osize, osize);
 
251
  glCallList (bp->dlists [omodel]);
 
252
  polys += bp->polys [omodel];
 
253
  glPopMatrix();
 
254
 
 
255
  glPushMatrix();
 
256
  glScalef (nsize, nsize, nsize);
 
257
  glCallList (bp->dlists [nmodel]);
 
258
  polys += bp->polys [nmodel];
 
259
  glPopMatrix();
 
260
 
 
261
  return polys;
 
262
}
 
263
 
 
264
 
 
265
static int
 
266
draw_histogram (ModeInfo *mi, GLfloat ratio)
 
267
{
 
268
  bit_configuration *bp = &bps[MI_SCREEN(mi)];
 
269
  int samples = countof (bp->histogram);
 
270
  GLfloat scalex = (GLfloat) mi->xgwa.width / samples;
 
271
  GLfloat scaley = mi->xgwa.height / 255.0 / 4;  /* about 1/4th of screen */
 
272
  int polys = 0;
 
273
  int overlays = 5;
 
274
  int k;
 
275
  
 
276
  glPushAttrib (GL_TRANSFORM_BIT |  /* for matrix contents */
 
277
                GL_ENABLE_BIT |     /* for various glDisable calls */
 
278
                GL_CURRENT_BIT |    /* for glColor3f() */
 
279
                GL_LIST_BIT);       /* for glListBase() */
 
280
 
 
281
  glDisable (GL_TEXTURE_2D);
 
282
  glDisable (GL_LIGHTING);
 
283
  glDisable (GL_BLEND);
 
284
  glDisable (GL_DEPTH_TEST);
 
285
  glDisable (GL_CULL_FACE);
 
286
 
 
287
  glMatrixMode(GL_PROJECTION);
 
288
  glPushMatrix();
 
289
  {
 
290
    glLoadIdentity();
 
291
    glMatrixMode(GL_MODELVIEW);
 
292
    glPushMatrix();
 
293
 
 
294
    glLoadIdentity();
 
295
    gluOrtho2D (0, mi->xgwa.width, 0, mi->xgwa.height);
 
296
 
 
297
    for (k = 0; k < overlays; k++)
 
298
      {
 
299
        int i, j;
 
300
        GLfloat a = (GLfloat) k / overlays;
 
301
 
 
302
        glColor3f (0.3 * a, 0.7 * a, 1.0 * a);
 
303
 
 
304
        glBegin (GL_LINE_STRIP);
 
305
 
 
306
        j = bp->histogram_fp + 1;
 
307
        for (i = 0; i < samples; i++)
 
308
          {
 
309
            GLfloat x = i;
 
310
            GLfloat y = bp->histogram[j];
 
311
            GLfloat z = 0;
 
312
 
 
313
            y += (int) ((random() % 16) - 8);
 
314
            y += 16;  /* margin at bottom of screen */
 
315
 
 
316
            x *= scalex;
 
317
            y *= scaley;
 
318
 
 
319
            glVertex3f (x, y, z);
 
320
            if (++j >= samples) j = 0;
 
321
            polys++;
 
322
          }
 
323
        glEnd();
 
324
      }
 
325
 
 
326
    glPopMatrix();
 
327
  }
 
328
  glMatrixMode(GL_PROJECTION);
 
329
  glPopMatrix();
 
330
 
 
331
  glPopAttrib();
 
332
 
 
333
  glMatrixMode(GL_MODELVIEW);
 
334
 
 
335
  return polys;
 
336
}
 
337
 
 
338
 
 
339
/* Window management, etc
 
340
 */
 
341
ENTRYPOINT void
 
342
reshape_bit (ModeInfo *mi, int width, int height)
 
343
{
 
344
  GLfloat h = (GLfloat) height / (GLfloat) width;
 
345
 
 
346
  glViewport (0, 0, (GLint) width, (GLint) height);
 
347
 
 
348
  glMatrixMode(GL_PROJECTION);
 
349
  glLoadIdentity();
 
350
  gluPerspective (30.0, 1/h, 1.0, 100.0);
 
351
 
 
352
  glMatrixMode(GL_MODELVIEW);
 
353
  glLoadIdentity();
 
354
  gluLookAt( 0.0, 0.0, 30.0,
 
355
             0.0, 0.0, 0.0,
 
356
             0.0, 1.0, 0.0);
 
357
 
 
358
  glClear(GL_COLOR_BUFFER_BIT);
 
359
}
 
360
 
 
361
 
 
362
 
 
363
ENTRYPOINT Bool
 
364
bit_handle_event (ModeInfo *mi, XEvent *event)
 
365
{
 
366
  bit_configuration *bp = &bps[MI_SCREEN(mi)];
 
367
 
 
368
  if (event->xany.type == ButtonPress &&
 
369
      event->xbutton.button == Button1)
 
370
    {
 
371
      bp->button_down_p = True;
 
372
      gltrackball_start (bp->trackball,
 
373
                         event->xbutton.x, event->xbutton.y,
 
374
                         MI_WIDTH (mi), MI_HEIGHT (mi));
 
375
      return True;
 
376
    }
 
377
  else if (event->xany.type == ButtonRelease &&
 
378
           event->xbutton.button == Button1)
 
379
    {
 
380
      bp->button_down_p = False;
 
381
      return True;
 
382
    }
 
383
  else if (event->xany.type == ButtonPress &&
 
384
           (event->xbutton.button == Button4 ||
 
385
            event->xbutton.button == Button5 ||
 
386
            event->xbutton.button == Button6 ||
 
387
            event->xbutton.button == Button7))
 
388
    {
 
389
      gltrackball_mousewheel (bp->trackball, event->xbutton.button, 3,
 
390
                              !!event->xbutton.state);
 
391
      return True;
 
392
    }
 
393
  else if (event->xany.type == MotionNotify &&
 
394
           bp->button_down_p)
 
395
    {
 
396
      gltrackball_track (bp->trackball,
 
397
                         event->xmotion.x, event->xmotion.y,
 
398
                         MI_WIDTH (mi), MI_HEIGHT (mi));
 
399
      return True;
 
400
    }
 
401
  else if (event->xany.type == KeyPress)
 
402
    {
 
403
      KeySym keysym;
 
404
      char c = 0;
 
405
      XLookupString (&event->xkey, &c, 1, &keysym, 0);
 
406
      if (c == ' ' || c == '1' || c == '0')
 
407
        {
 
408
          bp->kbd = c;
 
409
          return True;
 
410
        }
 
411
    }
 
412
 
 
413
  return False;
 
414
}
 
415
 
 
416
 
 
417
ENTRYPOINT void 
 
418
init_bit (ModeInfo *mi)
 
419
{
 
420
  bit_configuration *bp;
 
421
  int wire = MI_IS_WIREFRAME(mi);
 
422
  int i;
 
423
 
 
424
  if (!bps) {
 
425
    bps = (bit_configuration *)
 
426
      calloc (MI_NUM_SCREENS(mi), sizeof (bit_configuration));
 
427
    if (!bps) {
 
428
      fprintf(stderr, "%s: out of memory\n", progname);
 
429
      exit(1);
 
430
    }
 
431
  }
 
432
 
 
433
  bp = &bps[MI_SCREEN(mi)];
 
434
 
 
435
  bp->glx_context = init_GL(mi);
 
436
 
 
437
  reshape_bit (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
 
438
 
 
439
  if (!wire)
 
440
    {
 
441
      GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0};
 
442
      GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};
 
443
      GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
 
444
      GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0};
 
445
 
 
446
      glEnable(GL_LIGHTING);
 
447
      glEnable(GL_LIGHT0);
 
448
      glEnable(GL_DEPTH_TEST);
 
449
      glEnable(GL_CULL_FACE);
 
450
 
 
451
      glLightfv(GL_LIGHT0, GL_POSITION, pos);
 
452
      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
 
453
      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
 
454
      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
 
455
    }
 
456
 
 
457
  {
 
458
    double spin_speed   = 3.0;
 
459
    double wander_speed = 0.03 * speed;
 
460
    double spin_accel   = 4.0;
 
461
 
 
462
    bp->rot = make_rotator (do_spin ? spin_speed : 0,
 
463
                            do_spin ? spin_speed : 0,
 
464
                            do_spin ? spin_speed : 0,
 
465
                            spin_accel,
 
466
                            do_wander ? wander_speed : 0,
 
467
                            False);
 
468
    bp->trackball = gltrackball_init ();
 
469
  }
 
470
 
 
471
  for (i = 0; i < countof(bp->dlists); i++)
 
472
    {
 
473
      bp->dlists[i] = glGenLists (1);
 
474
      glNewList (bp->dlists[i], GL_COMPILE);
 
475
      bp->polys [i] = make_bit (mi, i);
 
476
      glEndList ();
 
477
    }
 
478
 
 
479
  bp->frequency  = 0.30 / speed;        /* parity around 3x/second */
 
480
  bp->confidence = 0.06;                /* provide answer 1/15 or so */
 
481
 
 
482
  for (i = 0; i < countof(bp->histogram); i++)
 
483
    bp->histogram[i] = 128 + (random() % 16) - 8;
 
484
}
 
485
 
 
486
 
 
487
ENTRYPOINT void
 
488
draw_bit (ModeInfo *mi)
 
489
{
 
490
  bit_configuration *bp = &bps[MI_SCREEN(mi)];
 
491
  Display *dpy = MI_DISPLAY(mi);
 
492
  Window window = MI_WINDOW(mi);
 
493
 
 
494
  if (!bp->glx_context)
 
495
    return;
 
496
 
 
497
  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
 
498
 
 
499
  glShadeModel(GL_SMOOTH);
 
500
 
 
501
  glEnable(GL_DEPTH_TEST);
 
502
  glEnable(GL_NORMALIZE);
 
503
  glEnable(GL_CULL_FACE);
 
504
 
 
505
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
506
 
 
507
  glPushMatrix ();
 
508
 
 
509
  glScalef(1.1, 1.1, 1.1);
 
510
 
 
511
  {
 
512
    double x, y, z;
 
513
    get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
 
514
    glTranslatef((x - 0.5) * 11,
 
515
                 (y - 0.5) * 5,
 
516
                 (z - 0.5) * 3);
 
517
 
 
518
    gltrackball_rotate (bp->trackball);
 
519
 
 
520
    get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p);
 
521
    glRotatef (x * 360, 1.0, 0.0, 0.0);
 
522
    glRotatef (y * 360, 0.0, 1.0, 0.0);
 
523
    glRotatef (z * 360, 0.0, 0.0, 1.0);
 
524
  }
 
525
 
 
526
  mi->polygon_count = 0;
 
527
 
 
528
  glScalef (6, 6, 6);
 
529
 
 
530
 
 
531
  {
 
532
    int nmodel = bp->history [bp->history_fp];
 
533
    int omodel = bp->history [bp->history_fp > 0
 
534
                              ? bp->history_fp-1
 
535
                              : countof(bp->history)-1];
 
536
    double now = double_time();
 
537
    double ratio = 1 - ((bp->last_time + bp->frequency) - now) / bp->frequency;
 
538
    if (ratio > 1) ratio = 1;
 
539
    mi->polygon_count += draw_histogram (mi, ratio);
 
540
    mi->polygon_count += animate_bits (mi, omodel, nmodel, ratio);
 
541
    tick_bit (mi, now);
 
542
  }
 
543
  glPopMatrix ();
 
544
 
 
545
  if (mi->fps_p) do_fps (mi);
 
546
  glFinish();
 
547
 
 
548
  glXSwapBuffers(dpy, window);
 
549
}
 
550
 
 
551
XSCREENSAVER_MODULE_2 ("TronBit", tronbit, bit)
 
552
 
 
553
#endif /* USE_GL */