From http://www.jwz.org/xscreensaver/xscreensaver-5.22.tar.gz
[xscreensaver] / hacks / glx / gltrackball.c
index 51cb72e431e045b5d4736467f89156b2f02a74dd..ee54cf91d2432f4a541774a742621d77286a54c4 100644 (file)
@@ -1,4 +1,4 @@
-/* gltrackball, Copyright (c) 2002, 2005 Jamie Zawinski <jwz@jwz.org>
+/* gltrackball, Copyright (c) 2002-2012 Jamie Zawinski <jwz@jwz.org>
  * GL-flavored wrapper for trackball.c
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
 
 #include <math.h>
 #include <stdlib.h>
+#include <string.h>
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 
-#ifdef HAVE_COCOA
-# include <OpenGL/gl.h>
-#else
+#ifndef HAVE_COCOA
 # include <GL/gl.h>
 #endif
 
+#ifdef HAVE_JWZGLES
+# include "jwzgles.h"
+#endif /* HAVE_JWZGLES */
+
 #include "trackball.h"
 #include "gltrackball.h"
 
+extern double current_device_rotation (void);  /* Bah, it's in fps.h */
+
 struct trackball_state {
   int x, y;
   GLfloat q[4];
@@ -43,6 +48,16 @@ gltrackball_init (void)
   return ts;
 }
 
+/* Reset the trackball to the default unrotated state.
+ */
+void
+gltrackball_reset (trackball_state *ts)
+{
+  memset (ts, 0, sizeof(*ts));
+  trackball (ts->q, 0, 0, 0, 0);
+}
+
+
 /* Begin tracking the mouse: Call this when the mouse button goes down.
    x and y are the mouse position relative to the window.
    w and h are the size of the window.
@@ -86,35 +101,50 @@ gltrackball_rotate (trackball_state *ts)
 
 # define Button4 4  /* X11/Xlib.h */
 # define Button5 5
+# define Button6 6
+# define Button7 7
 
 /* Call this when a mouse-wheel click is detected.
    Clicks act like horizontal or vertical drags.
    Percent is the length of the drag as a percentage of the screen size.
-   Button is 'Button4' or 'Button5'.
+   Button is 'Button4' or 'Button5' (for the vertical wheel)
+   or 'Button5' or 'Button6' (for the horizontal wheel).
+   If `flip_p' is true, swap the horizontal and vertical axes.
  */
 void
 gltrackball_mousewheel (trackball_state *ts,
-                        int button, int percent, int horizontal_p)
+                        int button, int percent, int flip_p)
 {
   int up_p;
-  double move;
+  int horizontal_p;
+  int mx, my, move, scale;
+
+#ifdef HAVE_COCOA
+  flip_p = 0;      /* MacOS has already handled this. */
+#endif
+
   switch (button) {
-    case Button4: up_p = 1; break;
-    case Button5: up_p = 0; break;
+  case Button4: up_p = 1; horizontal_p = 0; break;
+  case Button5: up_p = 0; horizontal_p = 0; break;
+  case Button6: up_p = 1; horizontal_p = 1; break;
+  case Button7: up_p = 0; horizontal_p = 1; break;
   default: abort(); break;
   }
 
-  if (horizontal_p) up_p = !up_p;
+  if (flip_p)
+    {
+      horizontal_p = !horizontal_p;
+      up_p = !up_p;
+    }
 
+  scale = mx = my = 1000;
   move = (up_p
-          ? 1.0 - (percent / 100.0)
-          : 1.0 + (percent / 100.0));
-
-  gltrackball_start (ts, 50, 50, 100, 100);
-  if (horizontal_p)
-    gltrackball_track (ts, 50*move, 50, 100, 100);
-  else
-    gltrackball_track (ts, 50, 50*move, 100, 100);
+          ? floor (scale * (1.0 - (percent / 100.0)))
+          : ceil  (scale * (1.0 + (percent / 100.0))));
+  if (horizontal_p) mx = move;
+  else              my = move;
+  gltrackball_start (ts, scale, scale, scale*2, scale*2);
+  gltrackball_track (ts, mx, my, scale*2, scale*2);
 }
 
 void