diff -r -u -p glxgears.orig/glxgears.c glxgears/glxgears.c
--- glxgears.orig/glxgears.c	2003-11-30 11:18:09.000000000 -0500
+++ glxgears/glxgears.c	2003-11-30 18:38:25.000000000 -0500
@@ -24,8 +24,12 @@
  * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
  * Port by Brian Paul  23 March 2001
  *
+ * Exact timing added by Behdad Esfahbod to achieve a fixed speed regardless
+ * of frame rate.  November 2003
+ *
  * Command line options:
  *    -info      print GL implementation information
+ *    -debug     draw only one tooth for each gear
  *
  */
 
@@ -40,35 +44,37 @@
 #include <GL/glx.h>
 
 
-#define BENCHMARK
+#define TIMING
 
-#ifdef BENCHMARK
+#ifdef TIMING
 
 /* XXX this probably isn't very portable */
 
 #include <sys/time.h>
+#include <sys/timeb.h>
 #include <unistd.h>
+#include <sched.h>
 
 /* return current time (in seconds) */
-static int
+static long
 current_time(void)
 {
    struct timeval tv;
    struct timezone tz;
    (void) gettimeofday(&tv, &tz);
-   return (int) tv.tv_sec;
+   return (long) tv.tv_sec * 1000000 + (long) tv.tv_usec;
 }
 
-#else /*BENCHMARK*/
+#else /*TIMING*/
 
 /* dummy */
-static int
+static long
 current_time(void)
 {
    return 0;
 }
 
-#endif /*BENCHMARK*/
+#endif /*TIMING*/
 
 
 
@@ -76,11 +82,11 @@ current_time(void)
 #define M_PI 3.14159265
 #endif
 
-
 static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
 static GLint gear1, gear2, gear3;
 static GLfloat angle = 0.0;
-
+static GLint speed = 60;
+static int debug = 0, paused = 0;
 
 /*
  *
@@ -98,13 +104,14 @@ gear(GLfloat inner_radius, GLfloat outer
      GLint teeth, GLfloat tooth_depth)
 {
    GLint i;
-   GLfloat r0, r1, r2;
+   GLfloat r0, r1, r2, maxr2, minr2;
    GLfloat angle, da;
    GLfloat u, v, len;
 
    r0 = inner_radius;
    r1 = outer_radius - tooth_depth / 2.0;
-   r2 = outer_radius + tooth_depth / 2.0;
+   maxr2 = r2 = outer_radius + tooth_depth / 2.0;
+   minr2 = debug ? r1 : r2;
 
    da = 2.0 * M_PI / teeth / 4.0;
 
@@ -128,7 +135,6 @@ gear(GLfloat inner_radius, GLfloat outer
 
    /* draw front sides of teeth */
    glBegin(GL_QUADS);
-   da = 2.0 * M_PI / teeth / 4.0;
    for (i = 0; i < teeth; i++) {
       angle = i * 2.0 * M_PI / teeth;
 
@@ -138,7 +144,9 @@ gear(GLfloat inner_radius, GLfloat outer
 		 width * 0.5);
       glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 		 width * 0.5);
+      r2 = minr2;
    }
+   r2 = maxr2;
    glEnd();
 
    glNormal3f(0.0, 0.0, -1.0);
@@ -169,7 +177,9 @@ gear(GLfloat inner_radius, GLfloat outer
 		 -width * 0.5);
       glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
       glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+      r2 = minr2;
    }
+   r2 = maxr2;
    glEnd();
 
    /* draw outward faces of teeth */
@@ -187,7 +197,7 @@ gear(GLfloat inner_radius, GLfloat outer
       glNormal3f(v, -u, 0.0);
       glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
       glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
-      glNormal3f(cos(angle), sin(angle), 0.0);
+      glNormal3f(cos(angle + 1.5 * da), sin(angle + 1.5 * da), 0.0);
       glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 		 width * 0.5);
       glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
@@ -199,8 +209,10 @@ gear(GLfloat inner_radius, GLfloat outer
 		 width * 0.5);
       glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 		 -width * 0.5);
-      glNormal3f(cos(angle), sin(angle), 0.0);
+      glNormal3f(cos(angle + 3.5 * da), sin(angle + 3.5 * da), 0.0);
+      r2 = minr2;
    }
+   r2 = maxr2;
 
    glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
    glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
@@ -262,7 +274,11 @@ reshape(int width, int height)
    glViewport(0, 0, (GLint) width, (GLint) height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
-   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
+   /* fit width and height */
+   if (h >= 1.0)
+     glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
+   else
+     glFrustum(-1.0/h, 1.0/h, -1.0, 1.0, 5.0, 60.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -40.0);
@@ -335,7 +351,7 @@ make_window( Display *dpy, const char *n
 
    visinfo = glXChooseVisual( dpy, scrnum, attrib );
    if (!visinfo) {
-      printf("Error: couldn't get an RGB, Double-buffered visual\n");
+      fprintf(stderr, "Error: couldn't get an RGB, Double-buffered visual\n");
       exit(1);
    }
 
@@ -365,7 +381,7 @@ make_window( Display *dpy, const char *n
 
    ctx = glXCreateContext( dpy, visinfo, NULL, True );
    if (!ctx) {
-      printf("Error: glXCreateContext failed\n");
+      fprintf(stderr, "Error: glXCreateContext failed\n");
       exit(1);
    }
 
@@ -410,41 +426,83 @@ event_loop(Display *dpy, Window win)
                else {
                   r = XLookupString(&event.xkey, buffer, sizeof(buffer),
                                     NULL, NULL);
-                  if (buffer[0] == 27) {
-                     /* escape */
-                     return;
+                  switch (buffer[0]) {
+		     case 27: /* escape */
+		     case 'q':
+                        return;
+		     case 32: /* space */
+			paused = 1 - paused;
+			break;
+		     case 'a':
+			if (speed < 360)
+			   speed += 5;
+			break;
+		     case 'z':
+			if (speed > -360)
+			   speed -= 5;
+			break;
                   }
                }
             }
          }
       }
 
-      /* next frame */
-      angle += 2.0;
-
-      draw();
-      glXSwapBuffers(dpy, win);
-
-      /* calc framerate */
       {
-         static int t0 = -1;
-         static int frames = 0;
-         int t = current_time();
+         long t = current_time();
+         {
+            /* next frame */
+	    static long t0 = 0;
+            long useconds;
+
+	    if (!t0)
+	       t0 = t;
+
+            useconds = t - t0;
+            if (!useconds) /* assume 100FPS if we don't have timer */
+	       useconds = 10000;
+
+	    if (!paused)
+                angle = angle + ((double)speed * useconds) / 1000000.0;
+                /*angle = angle + 0.2;*/
+
+	    /* keep angle small so we don't lose precision! */
+	    if (angle > 360.0)
+	       angle = angle - 360.0;
 
-         if (t0 < 0)
-            t0 = t;
+            draw();
+            glXSwapBuffers(dpy, win);
 
-         frames++;
-
-         if (t - t0 >= 5.0) {
-            GLfloat seconds = t - t0;
-            GLfloat fps = frames / seconds;
-            printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
-                   fps);
             t0 = t;
-            frames = 0;
+         }
+
+#ifdef TIMING
+         {
+            /* calc framerate */
+            static int frames = 0;
+            static long t0 = 0;
+
+            if (!t0)
+               t0 = t;
+
+            frames++;
+
+            if (t - t0 >= 5000000) {
+	       GLfloat seconds = (t - t0) / 1000000.0;
+               GLfloat fps = frames / seconds;
+
+               printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
+                      fps);
+               t0 = t;
+               frames = 0;
+	    }
          }
       }
+
+      /* need to give cpu away in order to get precise timing next cycle,
+         otherwise, gettimeofday would return almost the same value. */
+      sched_yield();
+
+#endif /*TIMING*/
    }
 }
 
@@ -467,11 +525,14 @@ main(int argc, char *argv[])
       else if (strcmp(argv[i], "-info") == 0) {
          printInfo = GL_TRUE;
       }
+      else if (strcmp(argv[i], "-debug") == 0) {
+         debug = 1;
+      }
    }
 
    dpy = XOpenDisplay(dpyName);
    if (!dpy) {
-      printf("Error: couldn't open display %s\n", dpyName);
+      fprintf(stderr, "Error: couldn't open display %s\n", dpyName);
       return -1;
    }
 
diff -r -u -p glxgears.orig/glxgears.man glxgears/glxgears.man
--- glxgears.orig/glxgears.man	2003-11-30 11:18:09.000000000 -0500
+++ glxgears/glxgears.man	2003-11-30 11:50:03.000000000 -0500
@@ -19,6 +19,9 @@ Print out GL implementation information 
 .TP 8
 .BI "\-display " displayname
 Specify the display to query.
+.TP 8
+.B \-debug
+Draw a single tooth on each gear.
 .SH ENVIRONMENT
 .PP
 .TP 8
diff -r -u -p glxgears.orig/glxgears._man glxgears/glxgears._man
--- glxgears.orig/glxgears._man	2003-11-30 11:18:09.000000000 -0500
+++ glxgears/glxgears._man	2003-11-30 11:50:19.000000000 -0500
@@ -19,6 +19,9 @@ Print out GL implementation information 
 .TP 8
 .BI "\-display " displayname
 Specify the display to query.
+.TP 8
+.B \-debug
+Draw a single tooth on each gear.
 .SH ENVIRONMENT
 .PP
 .TP 8
