From http://www.jwz.org/xscreensaver/xscreensaver-5.35.tar.gz
[xscreensaver] / hacks / fluidballs.c
index 958f7bc1b37272f34699143ef2380e9c572e1044..7fc43bd2c9d5ae8afb63c668b7de7dbfe8f28a97 100644 (file)
@@ -228,7 +228,7 @@ fluidballs_init (Display *dpy, Window window)
 
   state->dbuf = get_boolean_resource (dpy, "doubleBuffer", "Boolean");
 
-# ifdef HAVE_COCOA     /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ     /* Don't second-guess Quartz's double-buffering */
   state->dbuf = False;
 # endif
 
@@ -328,6 +328,12 @@ fluidballs_init (Display *dpy, Window window)
   state->shake_p = get_boolean_resource (dpy, "shake", "Shake");
   state->shake_threshold = get_float_resource (dpy, "shakeThreshold",
                                                "ShakeThreshold");
+  state->time_tick = 999999;
+
+# ifdef HAVE_MOBILE    /* Always obey real-world gravity */
+  state->shake_p = False;
+# endif
+
 
   state->fps_p = get_boolean_resource (dpy, "doFPS", "DoFPS");
   if (state->fps_p)
@@ -443,6 +449,21 @@ check_wall_clock (b_state *state, float max_d)
 
       state->time_since_shake += (now.tv_sec - state->last_time.tv_sec);
 
+# ifdef HAVE_MOBILE    /* Always obey real-world gravity */
+      {
+        float a = fabs (fabs(state->accx) > fabs(state->accy)
+                        ? state->accx : state->accy);
+        int rot = current_device_rotation();
+        switch (rot) {
+        case    0: case  360: state->accx =  0; state->accy =  a; break;
+        case  -90:            state->accx = -a; state->accy =  0; break;
+        case   90:            state->accx =  a; state->accy =  0; break;
+        case  180: case -180: state->accx =  0; state->accy = -a; break;
+        default: break;
+        }
+      }
+# endif /* HAVE_MOBILE */
+
       if (state->fps_p) 
        {
          float elapsed = ((now.tv_sec  + (now.tv_usec  / 1000000.0)) -
@@ -468,28 +489,32 @@ static void
 repaint_balls (b_state *state)
 {
   int a;
+# ifndef HAVE_JWXYZ
   int x1a, x2a, y1a, y2a;
+# endif
   int x1b, x2b, y1b, y2b;
   float max_d = 0;
 
-#ifdef HAVE_COCOA      /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ      /* Don't second-guess Quartz's double-buffering */
   XClearWindow (state->dpy, state->b);
 #endif
 
   for (a=1; a <= state->count; a++)
     {
       GC gc;
+# ifndef HAVE_JWXYZ
       x1a = (state->opx[a] - state->r[a] - state->xmin);
       y1a = (state->opy[a] - state->r[a] - state->ymin);
       x2a = (state->opx[a] + state->r[a] - state->xmin);
       y2a = (state->opy[a] + state->r[a] - state->ymin);
+# endif
 
       x1b = (state->px[a] - state->r[a] - state->xmin);
       y1b = (state->py[a] - state->r[a] - state->ymin);
       x2b = (state->px[a] + state->r[a] - state->xmin);
       y2b = (state->py[a] + state->r[a] - state->ymin);
 
-#ifndef HAVE_COCOA     /* Don't second-guess Quartz's double-buffering */
+#ifndef HAVE_JWXYZ     /* Don't second-guess Quartz's double-buffering */
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
       if (!state->dbeclear_p || !state->backb)
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
@@ -502,7 +527,7 @@ repaint_balls (b_state *state)
                        0, 360*64);
            }
        }
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
 
       if (state->mouse_ball == a)
         gc = state->draw_gc2;
@@ -715,17 +740,29 @@ fluidballs_event (Display *dpy, Window window, void *closure, XEvent *event)
           return True;
         }
       else
-        for (i=1; i <= state->count; i++)
-          {
-            float d = ((state->px[i] - rx) * (state->px[i] - rx) +
-                       (state->py[i] - ry) * (state->py[i] - ry));
-            float r = state->r[i];
-            if (d < r*r)
+        {
+          /* When trying to pick up a ball, first look for a click directly
+             inside the ball; but if we don't find it, expand the radius
+             outward until we find something nearby.
+           */
+          float max = state->max_radius * 4;
+          float step = max / 10;
+          float r2;
+          for (r2 = step; r2 < max; r2 += step) {
+            for (i = 1; i <= state->count; i++)
               {
-                state->mouse_ball = i;
-                return True;
+                float d = ((state->px[i] - rx) * (state->px[i] - rx) +
+                           (state->py[i] - ry) * (state->py[i] - ry));
+                float r = state->r[i];
+                if (r2 > r) r = r2;
+                if (d < r*r)
+                  {
+                    state->mouse_ball = i;
+                    return True;
+                  }
               }
           }
+        }
       return True;
     }
   else if (event->xany.type == ButtonRelease)   /* drop the ball */
@@ -763,7 +800,7 @@ fluidballs_free (Display *dpy, Window window, void *closure)
 static const char *fluidballs_defaults [] = {
   ".background:                black",
   ".foreground:                yellow",
-  ".textColor:         white",
+  ".textColor:         yellow",
   "*mouseForeground:   white",
   "*delay:             10000",
   "*count:             300",
@@ -780,6 +817,9 @@ static const char *fluidballs_defaults [] = {
   "*useDBE:            True",
   "*useDBEClear:       True",
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+#ifdef HAVE_MOBILE
+  "*ignoreRotation:    True",
+#endif
   0
 };