http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.04.2.tar.gz
[xscreensaver] / hacks / glx / gears.c
index 954acd1752b690e367a238638dd24636182627a2..52bdab820adf0e387b4674bacbc9487f0e9c59b3 100644 (file)
@@ -47,6 +47,8 @@ static const char sccsid[] = "@(#)gears.c     4.07 97/11/24 xlockmore";
 # define HACK_INIT                                     init_gears
 # define HACK_DRAW                                     draw_gears
 # define HACK_RESHAPE                          reshape_gears
+# define HACK_HANDLE_EVENT                     gears_handle_event
+# define EVENT_MASK                                    PointerMotionMask
 # define gears_opts                                    xlockmore_opts
 # define DEFAULTS      "*count:                1       \n"                     \
                                        "*cycles:               2       \n"                     \
@@ -61,6 +63,9 @@ static const char sccsid[] = "@(#)gears.c     4.07 97/11/24 xlockmore";
 
 #ifdef USE_GL
 
+#include "rotator.h"
+#include "gltrackball.h"
+
 #undef countof
 #define countof(x) (sizeof((x))/sizeof((*x)))
 
@@ -98,18 +103,15 @@ ModStruct   gears_description =
 
 
 typedef struct {
-
-  GLfloat rotx, roty, rotz;       /* current object rotation */
-  GLfloat dx, dy, dz;             /* current rotational velocity */
-  GLfloat ddx, ddy, ddz;          /* current rotational acceleration */
-  GLfloat d_max;                          /* max velocity */
-
   GLuint      gear1, gear2, gear3;
   GLuint      gear_inner, gear_outer;
   GLuint      armature;
   GLfloat     angle;
   GLXContext *glx_context;
   Window      window;
+  rotator    *rot;
+  trackball_state *trackball;
+  Bool           button_down_p;
 } gearsstruct;
 
 static gearsstruct *gears = NULL;
@@ -540,16 +542,14 @@ draw(ModeInfo * mi)
 
        glPushMatrix();
 
+    gltrackball_rotate (gp->trackball);
+
     {
-      GLfloat x = gp->rotx;
-      GLfloat y = gp->roty;
-      GLfloat z = gp->rotz;
-      if (x < 0) x = 1 - (x + 1);
-      if (y < 0) y = 1 - (y + 1);
-      if (z < 0) z = 1 - (z + 1);
-      glRotatef(x * 360, 1.0, 0.0, 0.0);
-      glRotatef(y * 360, 0.0, 1.0, 0.0);
-      glRotatef(z * 360, 0.0, 0.0, 1.0);
+      double x, y, z;
+      get_rotation (gp->rot, &x, &y, &z, !gp->button_down_p);
+      glRotatef (x * 360, 1.0, 0.0, 0.0);
+      glRotatef (y * 360, 0.0, 1.0, 0.0);
+      glRotatef (z * 360, 0.0, 0.0, 1.0);
     }
 
     if (!planetary) {
@@ -921,74 +921,36 @@ pinit(ModeInfo * mi)
 }
 
 
-/* lifted from lament.c */
-#define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
-#define RANDSIGN() ((random() & 1) ? 1 : -1)
-
-static void
-rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
+Bool
+gears_handle_event (ModeInfo *mi, XEvent *event)
 {
-  double ppos = *pos;
-
-  /* tick position */
-  if (ppos < 0)
-    ppos = -(ppos + *v);
-  else
-    ppos += *v;
-
-  if (ppos > 1.0)
-    ppos -= 1.0;
-  else if (ppos < 0)
-    ppos += 1.0;
-
-  if (ppos < 0) abort();
-  if (ppos > 1.0) abort();
-  *pos = (*pos > 0 ? ppos : -ppos);
+  gearsstruct *gp = &gears[MI_SCREEN(mi)];
 
-  /* accelerate */
-  *v += *dv;
-
-  /* clamp velocity */
-  if (*v > max_v || *v < -max_v)
+  if (event->xany.type == ButtonPress &&
+      event->xbutton.button & Button1)
     {
-      *dv = -*dv;
+      gp->button_down_p = True;
+      gltrackball_start (gp->trackball,
+                         event->xbutton.x, event->xbutton.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
     }
-  /* If it stops, start it going in the other direction. */
-  else if (*v < 0)
+  else if (event->xany.type == ButtonRelease &&
+           event->xbutton.button & Button1)
     {
-      if (random() % 4)
-       {
-         *v = 0;
-
-         /* keep going in the same direction */
-         if (random() % 2)
-           *dv = 0;
-         else if (*dv < 0)
-           *dv = -*dv;
-       }
-      else
-       {
-         /* reverse gears */
-         *v = -*v;
-         *dv = -*dv;
-         *pos = -*pos;
-       }
+      gp->button_down_p = False;
+      return True;
     }
-
-  /* Alter direction of rotational acceleration randomly. */
-  if (! (random() % 120))
-    *dv = -*dv;
-
-  /* Change acceleration very occasionally. */
-  if (! (random() % 200))
+  else if (event->xany.type == MotionNotify &&
+           gp->button_down_p)
     {
-      if (*dv == 0)
-       *dv = 0.00001;
-      else if (random() & 1)
-       *dv *= 1.2;
-      else
-       *dv *= 0.8;
+      gltrackball_track (gp->trackball,
+                         event->xmotion.x, event->xmotion.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
     }
+
+  return False;
 }
 
 
@@ -1010,20 +972,8 @@ init_gears(ModeInfo * mi)
 
        gp->window = MI_WINDOW(mi);
 
-    gp->rotx = frand(1.0) * RANDSIGN();
-    gp->roty = frand(1.0) * RANDSIGN();
-    gp->rotz = frand(1.0) * RANDSIGN();
-
-    /* bell curve from 0-1.5 degrees, avg 0.75 */
-    gp->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
-    gp->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
-    gp->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
-
-    gp->d_max = gp->dx * 2;
-
-    gp->ddx = 0.00006 + frand(0.00003);
-    gp->ddy = 0.00006 + frand(0.00003);
-    gp->ddz = 0.00006 + frand(0.00003);
+    gp->rot = make_rotator (1, 1, 1, 1, 0, True);
+    gp->trackball = gltrackball_init ();
 
        if ((gp->glx_context = init_GL(mi)) != NULL) {
                reshape_gears(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
@@ -1055,10 +1005,6 @@ draw_gears(ModeInfo * mi)
        /* let's do something so we don't get bored */
        gp->angle = (int) (gp->angle + angle_incr) % 360;
 
-    rotate(&gp->rotx, &gp->dx, &gp->ddx, gp->d_max);
-    rotate(&gp->roty, &gp->dy, &gp->ddy, gp->d_max);
-    rotate(&gp->rotz, &gp->dz, &gp->ddz, gp->d_max);
-
     if (mi->fps_p) do_fps (mi);
        glFinish();
        glXSwapBuffers(display, window);