From http://www.jwz.org/xscreensaver/xscreensaver-5.38.tar.gz
[xscreensaver] / hacks / popsquares.c
index 15cb61b4a6f36cc1219987811e3c74250f3ecb21..3b83fd768be60b57db5601d42b288341ef508cc3 100644 (file)
@@ -35,7 +35,7 @@ struct state {
   Display *dpy;
   Window window;
 
-   int delay, subdivision, border, ncolors, twitch, dbuf;
+   int delay, subdivisionx, subdivisiony, border, ncolors, twitch, dbuf;
     XWindowAttributes xgwa;
     GC gc; 
     XColor *colors;
@@ -47,6 +47,73 @@ struct state {
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 };
 
+static void
+popsquares_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+  struct state *st = (struct state *) closure;
+  int s = get_integer_resource(st->dpy, "subdivision", "Integer");
+  int x, y;
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+
+  if (st->xgwa.width < 100 || st->xgwa.height < 100) /* tiny window */
+    {
+      int ss = (st->xgwa.width < st->xgwa.height
+                ? st->xgwa.width : st->xgwa.height);
+      s = ss / 15;
+      if (s < 1) s = 1;
+    }
+
+  if (st->xgwa.width > st->xgwa.height * 5 ||  /* weird aspect ratio */
+      st->xgwa.height > st->xgwa.width * 5)
+    {
+      double r = st->xgwa.width / (double) st->xgwa.height;
+      if (r > 1)
+        {
+          st->subdivisiony = s;
+          st->subdivisionx = s * r;
+        }
+      else
+        {
+          st->subdivisionx = s;
+          st->subdivisiony = s / r;
+        }
+    }
+  else
+    {
+      st->subdivisionx = st->subdivisiony = s;
+    }
+
+  st->sw = st->xgwa.width / st->subdivisionx;
+  st->sh = st->xgwa.height / st->subdivisiony;
+  st->gw = st->sw ? st->xgwa.width / st->sw : 0;
+  st->gh = st->sh ? st->xgwa.height / st->sh : 0;
+  st->nsquares = st->gw * st->gh;
+  free (st->squares);
+  if (st->nsquares < 1) st->nsquares = 1;
+  st->squares = (square *) calloc (st->nsquares, sizeof(square));
+
+  for (y = 0; y < st->gh; y++)
+    for (x = 0; x < st->gw; x++) 
+      {
+        square *s = (square *) &st->squares[st->gw * y + x];
+        s->w = st->sw;
+        s->h = st->sh;
+        s->x = x * st->sw;
+        s->y = y * st->sh;
+      }
+
+  randomize_square_colors(st->squares, st->nsquares, st->ncolors);
+
+  if (st->dbuf) {
+    XFreePixmap (dpy, st->ba);
+    XFreePixmap (dpy, st->bb);
+    st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
+    st->bb = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
+    st->b = st->ba;
+  }
+}
+
 static void *
 popsquares_init (Display *dpy, Window window)
 {
@@ -63,13 +130,14 @@ popsquares_init (Display *dpy, Window window)
   st->window = window;
 
   st->delay = get_integer_resource (st->dpy, "delay", "Integer");
-  st->subdivision = get_integer_resource(st->dpy, "subdivision", "Integer");
+  st->subdivisionx = get_integer_resource(st->dpy, "subdivision", "Integer");
+  st->subdivisiony = st->subdivisionx;
   st->border = get_integer_resource(st->dpy, "border", "Integer");
   st->ncolors = get_integer_resource(st->dpy, "ncolors", "Integer");
   st->twitch = get_boolean_resource(st->dpy, "twitch", "Boolean");
   st->dbuf = get_boolean_resource(st->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 */
   st->dbuf = False;
 # endif
 
@@ -81,11 +149,13 @@ popsquares_init (Display *dpy, Window window)
   XQueryColor (st->dpy, st->xgwa.colormap, &fg);
   XQueryColor (st->dpy, st->xgwa.colormap, &bg);
 
-  st->sw = st->xgwa.width / st->subdivision;
-  st->sh = st->xgwa.height / st->subdivision;
+  st->sw = st->xgwa.width / st->subdivisionx;
+  st->sh = st->xgwa.height / st->subdivisiony;
   st->gw = st->sw ? st->xgwa.width / st->sw : 0;
   st->gh = st->sh ? st->xgwa.height / st->sh : 0;
   st->nsquares = st->gw * st->gh;
+  if (st->nsquares < 1) st->nsquares = 1;
+  if (st->ncolors < 1) st->ncolors = 1;
 
   gcv.foreground = fg.pixel;
   gcv.background = bg.pixel;
@@ -96,7 +166,7 @@ popsquares_init (Display *dpy, Window window)
 
   rgb_to_hsv (fg.red, fg.green, fg.blue, &h1, &s1, &v1);
   rgb_to_hsv (bg.red, bg.green, bg.blue, &h2, &s2, &v2);
-  make_color_ramp (st->dpy, st->xgwa.colormap,
+  make_color_ramp (st->xgwa.screen, st->xgwa.visual, st->xgwa.colormap,
                    h1, s1, v1,
                    h2, s2, v2,
                    st->colors, &st->ncolors,  /* would this be considered a value-result argument? */
@@ -137,6 +207,8 @@ popsquares_init (Display *dpy, Window window)
       st->b = st->window;
     }
 
+  popsquares_reshape (dpy, window, st, st->xgwa.width, st->xgwa.height);
+
   return st;
 }
 
@@ -183,42 +255,6 @@ popsquares_draw (Display *dpy, Window window, void *closure)
 }
 
 
-static void
-popsquares_reshape (Display *dpy, Window window, void *closure, 
-                 unsigned int w, unsigned int h)
-{
-  struct state *st = (struct state *) closure;
-  int x, y;
-  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
-  st->sw = st->xgwa.width / st->subdivision;
-  st->sh = st->xgwa.height / st->subdivision;
-  st->gw = st->sw ? st->xgwa.width / st->sw : 0;
-  st->gh = st->sh ? st->xgwa.height / st->sh : 0;
-  st->nsquares = st->gw * st->gh;
-  free (st->squares);
-  st->squares = (square *) calloc (st->nsquares, sizeof(square));
-
-  for (y = 0; y < st->gh; y++)
-    for (x = 0; x < st->gw; x++) 
-      {
-        square *s = (square *) &st->squares[st->gw * y + x];
-        s->w = st->sw;
-        s->h = st->sh;
-        s->x = x * st->sw;
-        s->y = y * st->sh;
-      }
-
-  randomize_square_colors(st->squares, st->nsquares, st->ncolors);
-
-  if (st->dbuf) {
-    XFreePixmap (dpy, st->ba);
-    XFreePixmap (dpy, st->bb);
-    st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
-    st->bb = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
-    st->b = st->ba;
-  }
-}
-
 static Bool
 popsquares_event (Display *dpy, Window window, void *closure, XEvent *event)
 {
@@ -246,6 +282,9 @@ static const char *popsquares_defaults [] = {
   "*useDBE: True",
   "*useDBEClear: True",
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+#ifdef HAVE_MOBILE
+  "*ignoreRotation: True",
+#endif
   0
 };