ftp://ftp.linux.ncsu.edu/mirror/ftp.redhat.com/pub/redhat/linux/enterprise/4/en/os...
[xscreensaver] / hacks / glx / gflux.c
index f45e9ed7f4ab8b3b36a6e218b1ee9a7a720a0d3f..51aa59778b31c20fecd18daba5bc961b8045cbc4 100644 (file)
@@ -2,7 +2,7 @@
 /* gflux - creates a fluctuating 3D grid 
  * requires OpenGL or MesaGL
  * 
- * Copyright (c) Josiah Pease, 2000
+ * Copyright (c) Josiah Pease, 2000, 2003
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  * the above copyright notice appear in all copies and that both that
  */
 
 
-/*-
- * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
- * otherwise caddr_t is not defined correctly
- */
-
-#include <X11/Intrinsic.h>
-
-
 #ifdef STANDALONE
 # define PROGCLASS                                             "gflux"
 # define HACK_INIT                                             init_gflux
 # define HACK_DRAW                                             draw_gflux
 # define HACK_RESHAPE                                  reshape_gflux
+# define HACK_HANDLE_EVENT                             gflux_handle_event
+# define EVENT_MASK                                            PointerMotionMask
 # define gflux_opts                                            xlockmore_opts
 #define DEFAULTS                        "*delay:               20000   \n" \
                                                                                "*showFPS:      False   \n" \
 #include <math.h>
 
 #include "grab-ximage.h"
+#include "gltrackball.h"
 
 
 static enum {wire=0,solid,light,checker,textured,grab} _draw; /* draw style */
@@ -120,41 +115,44 @@ static int _waveChange = 50;
 static float _waveHeight = 1.0;
 static float _waveFreq = 3.0;
 
+static trackball_state *trackball;
+static Bool button_down_p = False;
+
 #define WIDTH 320
 #define HEIGHT 240
 
 static XrmOptionDescRec opts[] = {
-    {"-squares", ".gflux.squares", XrmoptionSepArg, (caddr_t) NULL},
-    {"-resolution", ".gflux.resolution", XrmoptionSepArg, (caddr_t) NULL},
-/*    {"-draw", ".gflux.draw", XrmoptionSepArg, (caddr_t) NULL},*/
-    {"-mode", ".gflux.mode", XrmoptionSepArg, (caddr_t) NULL},
-    {"-flat", ".gflux.flat", XrmoptionSepArg, (caddr_t) NULL},
-    {"-speed", ".gflux.speed", XrmoptionSepArg, (caddr_t) NULL},
-    {"-rotationx", ".gflux.rotationx", XrmoptionSepArg, (caddr_t) NULL},
-    {"-rotationy", ".gflux.rotationy", XrmoptionSepArg, (caddr_t) NULL},
-    {"-rotationz", ".gflux.rotationz", XrmoptionSepArg, (caddr_t) NULL},
-    {"-waves", ".gflux.waves", XrmoptionSepArg, (caddr_t) NULL},
-    {"-waveChange", ".gflux.waveChange", XrmoptionSepArg, (caddr_t) NULL},
-    {"-waveHeight", ".gflux.waveHeight", XrmoptionSepArg, (caddr_t) NULL},
-    {"-waveFreq", ".gflux.waveFreq", XrmoptionSepArg, (caddr_t) NULL},
-    {"-zoom", ".gflux.zoom", XrmoptionSepArg, (caddr_t) NULL},
+    {"-squares", ".gflux.squares", XrmoptionSepArg, 0},
+    {"-resolution", ".gflux.resolution", XrmoptionSepArg, 0},
+/*    {"-draw", ".gflux.draw", XrmoptionSepArg, 0},*/
+    {"-mode", ".gflux.mode", XrmoptionSepArg, 0},
+    {"-flat", ".gflux.flat", XrmoptionSepArg, 0},
+    {"-speed", ".gflux.speed", XrmoptionSepArg, 0},
+    {"-rotationx", ".gflux.rotationx", XrmoptionSepArg, 0},
+    {"-rotationy", ".gflux.rotationy", XrmoptionSepArg, 0},
+    {"-rotationz", ".gflux.rotationz", XrmoptionSepArg, 0},
+    {"-waves", ".gflux.waves", XrmoptionSepArg, 0},
+    {"-waveChange", ".gflux.waveChange", XrmoptionSepArg, 0},
+    {"-waveHeight", ".gflux.waveHeight", XrmoptionSepArg, 0},
+    {"-waveFreq", ".gflux.waveFreq", XrmoptionSepArg, 0},
+    {"-zoom", ".gflux.zoom", XrmoptionSepArg, 0},
 };
 
 
 static argtype vars[] = {
-    {(caddr_t *) & _squares, "squares", "Squares", "19", t_Int},
-    {(caddr_t *) & _resolution, "resolution", "Resolution", "4", t_Int},
-/*    {(caddr_t *) & _draw, "draw", "Draw", "2", t_Int},*/
-    {(caddr_t *) & _flat, "flat", "Flat", "0", t_Int},
-    {(caddr_t *) & _speed, "speed", "Speed", "0.05", t_Float},
-    {(caddr_t *) & _rotationx, "rotationx", "Rotationx", "0.01", t_Float},
-    {(caddr_t *) & _rotationy, "rotationy", "Rotationy", "0.0", t_Float},
-    {(caddr_t *) & _rotationz, "rotationz", "Rotationz", "0.1", t_Float},
-    {(caddr_t *) & _waves, "waves", "Waves", "3", t_Int},
-    {(caddr_t *) & _waveChange, "waveChange", "WaveChange", "50", t_Int},
-    {(caddr_t *) & _waveHeight, "waveHeight", "WaveHeight", "1.0", t_Float},
-    {(caddr_t *) & _waveFreq, "waveFreq", "WaveFreq", "3.0", t_Float},
-    {(caddr_t *) & _zoom, "zoom", "Zoom", "1.0", t_Float},
+    {&_squares, "squares", "Squares", "19", t_Int},
+    {&_resolution, "resolution", "Resolution", "4", t_Int},
+/*    {&_draw, "draw", "Draw", "2", t_Int},*/
+    {&_flat, "flat", "Flat", "0", t_Int},
+    {&_speed, "speed", "Speed", "0.05", t_Float},
+    {&_rotationx, "rotationx", "Rotationx", "0.01", t_Float},
+    {&_rotationy, "rotationy", "Rotationy", "0.0", t_Float},
+    {&_rotationz, "rotationz", "Rotationz", "0.1", t_Float},
+    {&_waves, "waves", "Waves", "3", t_Int},
+    {&_waveChange, "waveChange", "WaveChange", "50", t_Int},
+    {&_waveHeight, "waveHeight", "WaveHeight", "1.0", t_Float},
+    {&_waveFreq, "waveFreq", "WaveFreq", "3.0", t_Float},
+    {&_zoom, "zoom", "Zoom", "1.0", t_Float},
 };
 
 
@@ -207,7 +205,7 @@ typedef struct {
        int imageMax;
        GLubyte *image;
 #endif
-    GLint texName;
+    GLuint texName;
     GLfloat tex_xscale;
     GLfloat tex_yscale;
     void (*drawFunc)(void);
@@ -240,6 +238,43 @@ double getGrid(double,double,double);
 /* BEGINNING OF FUNCTIONS */
 
 
+Bool
+gflux_handle_event (ModeInfo *mi, XEvent *event)
+{
+  if (event->xany.type == ButtonPress &&
+      event->xbutton.button & Button1)
+    {
+      button_down_p = True;
+      gltrackball_start (trackball,
+                         event->xbutton.x, event->xbutton.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
+    }
+  else if (event->xany.type == ButtonRelease &&
+           event->xbutton.button & Button1)
+    {
+      button_down_p = False;
+      return True;
+    }
+  else if (event->xany.type == MotionNotify &&
+           button_down_p)
+    {
+      gltrackball_track (trackball,
+                         event->xmotion.x, event->xmotion.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
+    }
+
+  return False;
+}
+
+
+static void
+userRot(void)
+{
+  gltrackball_rotate (trackball);
+}
+
 /* draw the gflux once */
 void draw_gflux(ModeInfo * mi)
 {
@@ -343,6 +378,8 @@ void init_gflux(ModeInfo * mi)
     }
     gp = &gflux[screen];
 
+    trackball = gltrackball_init ();
+
     {
       char *s = get_string_resource ("mode", "Mode");
       if (!s || !*s)                       _draw = wire;
@@ -576,7 +613,8 @@ grabTexture(void)
   int real_width  = gflux->modeinfo->xgwa.width;
   int real_height = gflux->modeinfo->xgwa.height;
   XImage *ximage = screen_to_ximage (gflux->modeinfo->xgwa.screen,
-                                     gflux->window);
+                                     gflux->window,
+                                     NULL);
   Bool bigimage = False;
   int size = 0;
 
@@ -635,7 +673,7 @@ grabTexture(void)
 
   gflux->imageWidth  = ximage->width;
   gflux->imageHeight = ximage->height;
-  gflux->image = ximage->data;
+  gflux->image = (GLubyte *) ximage->data;
 
   if (bigimage)  /* don't scale really large images */
     {
@@ -717,6 +755,7 @@ void displayTexture(void)
     glRotatef(anglex,1,0,0);
     glRotatef(angley,0,1,0);
     glRotatef(anglez,0,0,1);
+    userRot();
     glScalef(1,1,(GLfloat)_waveHeight);
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glEnable(GL_TEXTURE_2D);
@@ -756,10 +795,12 @@ void displayTexture(void)
         glEnd();
     }
 
-    time -= _speed;
-    anglex -= _rotationx;
-    angley -= _rotationy;
-    anglez -= _rotationz;
+    if (! button_down_p) {
+      time -= _speed;
+      anglex -= _rotationx;
+      angley -= _rotationy;
+      anglez -= _rotationz;
+    }
 }
 void displaySolid(void)
 {
@@ -777,6 +818,7 @@ void displaySolid(void)
     glRotatef(anglex,1,0,0);
     glRotatef(angley,0,1,0);
     glRotatef(anglez,0,0,1);
+    userRot();
     glScalef(1,1,(GLfloat)_waveHeight);
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 
@@ -796,10 +838,12 @@ void displaySolid(void)
         glEnd();
     }
 
-    time -= _speed;
-    anglex -= _rotationx;
-    angley -= _rotationy;
-    anglez -= _rotationz;
+    if (! button_down_p) {
+      time -= _speed;
+      anglex -= _rotationx;
+      angley -= _rotationy;
+      anglez -= _rotationz;
+    }
 
 }
 
@@ -819,6 +863,7 @@ void displayLight(void)
     glRotatef(anglex,1,0,0);
     glRotatef(angley,0,1,0);
     glRotatef(anglez,0,0,1);
+    userRot();
     glScalef(1,1,(GLfloat)_waveHeight);
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 
@@ -848,10 +893,12 @@ void displayLight(void)
         glEnd();
     }
 
-    time -= _speed;
-    anglex -= _rotationx;
-    angley -= _rotationy;
-    anglez -= _rotationz;
+    if (! button_down_p) {
+      time -= _speed;
+      anglex -= _rotationx;
+      angley -= _rotationy;
+      anglez -= _rotationz;
+    }
 }
 
 void displayWire(void)
@@ -872,6 +919,7 @@ void displayWire(void)
     glRotatef(anglex,1,0,0);
     glRotatef(angley,0,1,0);
     glRotatef(anglez,0,0,1);
+    userRot();
     glScalef(1,1,(GLfloat)_waveHeight);
     glClear(GL_COLOR_BUFFER_BIT);
 
@@ -896,10 +944,12 @@ void displayWire(void)
         glEnd();
     }
 
-    time -= _speed;
-    anglex -= _rotationx;
-    angley -= _rotationy;
-    anglez -= _rotationz;
+    if (! button_down_p) {
+      time -= _speed;
+      anglex -= _rotationx;
+      angley -= _rotationy;
+      anglez -= _rotationz;
+    }
 }
 
 /* generates new ripples */
@@ -909,6 +959,8 @@ void calcGrid(void)
     double tmp;
     static int newWave;
 
+    if (button_down_p) return;
+
     tmp = 1.0/((double)_waveChange);
     if(!(counter%_waveChange)) {
         newWave = ((int)(counter*tmp))%_waves;