From http://www.jwz.org/xscreensaver/xscreensaver-5.35.tar.gz
[xscreensaver] / hacks / goop.c
index 02a5b11352ff3f439c59d2f98f1df59066e1bfba..0f5c139e34968bbf89536ffa4b3ed067332b4c65 100644 (file)
@@ -129,6 +129,14 @@ make_blob (Display *dpy, int maxx, int maxy, int size)
   return b;
 }
 
+static void
+free_blob(struct blob *blob)
+{
+  free_spline(blob->spline);
+  free(blob->r);
+  free(blob);
+}
+
 static void 
 throb_blob (struct blob *b)
 {
@@ -266,15 +274,27 @@ make_layer (Display *dpy, Window window, int width, int height, int nblobs)
   layer->pixmap = XCreatePixmap (dpy, window, width, height, 1);
   layer->gc = XCreateGC (dpy, layer->pixmap, 0, &gcv);
 
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
   jwxyz_XSetAlphaAllowed (dpy, layer->gc, True);
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
 
   return layer;
 }
 
+static void
+free_layer(struct layer *layer, Display *dpy)
+{
+  int i;
+  for (i = 0; i < layer->nblobs; i++){
+    free_blob(layer->blobs[i]);
+  }
+  free(layer->blobs);
+  XFreeGC(dpy, layer->gc);
+  free(layer);
+}
+
 
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
 static void
 draw_layer_plane (Display *dpy, struct layer *layer, int width, int height)
 {
@@ -286,7 +306,7 @@ draw_layer_plane (Display *dpy, struct layer *layer, int width, int height)
       draw_blob (dpy, layer->pixmap, layer->gc, layer->blobs[i], True);
     }
 }
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
 
 
 static void
@@ -315,7 +335,7 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
   int nblobs = get_integer_resource (dpy, "count", "Count");
 
   unsigned long *plane_masks = 0;
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
   unsigned long base_pixel = 0;
 # endif
   char *s;
@@ -330,6 +350,7 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
     goop->mode = xor;
   else
     fprintf (stderr, "%s: bogus mode: \"%s\"\n", progname, s);
+  free(s);
 
   goop->delay = get_integer_resource (dpy, "delay", "Integer");
 
@@ -349,7 +370,7 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
   if (mono_p && goop->mode == transparent)
     goop->mode = opaque;
 
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
   /* Try to allocate some color planes before committing to nlayers.
    */
   if (goop->mode == transparent)
@@ -368,7 +389,7 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
          goop->mode = opaque;
        }
     }
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
 
   {
     int lblobs[32];
@@ -383,21 +404,21 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
                                    (nblobs > 0 ? nblobs : lblobs[i]));
   }
 
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
   if (goop->mode == transparent && plane_masks)
     {
       for (i = 0; i < goop->nlayers; i++)
        goop->layers[i]->pixel = base_pixel | plane_masks[i];
       goop->background = base_pixel;
     }
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
 
   if (plane_masks)
     free (plane_masks);
 
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
   if (goop->mode != transparent)
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
     {
       XColor color;
       color.flags = DoRed|DoGreen|DoBlue;
@@ -416,17 +437,17 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
          else
            goop->layers[i]->pixel =
              WhitePixelOfScreen(DefaultScreenOfDisplay(dpy));
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
           if (goop->mode == transparent)
             {
               /* give a non-opaque alpha to the color */
               unsigned long pixel = goop->layers[i]->pixel;
-              unsigned long amask = BlackPixelOfScreen (0);
+              unsigned long amask = BlackPixelOfScreen (screen);
               unsigned long a = (0xBBBBBBBB & amask);
               pixel = (pixel & (~amask)) | a;
               goop->layers[i]->pixel = pixel;
             }
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
        }
     }
 
@@ -439,13 +460,28 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
   goop->pixmap_gc = XCreateGC (dpy, goop->pixmap, GCLineWidth, &gcv);
   goop->window_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
 
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
   jwxyz_XSetAlphaAllowed (dpy, goop->pixmap_gc, True);
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
   
   return goop;
 }
 
+/* Well, the naming of this function is
+   confusing with goop_free()... */
+static void
+free_goop (struct goop *goop, Display *dpy)
+{
+  int i;
+  for (i = 0; i < goop->nlayers; i++){
+    struct layer * layer = goop->layers[i];
+    free_layer(layer, dpy);
+  }
+  free(goop->layers);
+  XFreeGC(dpy, goop->pixmap_gc);
+  XFreeGC(dpy, goop->window_gc);
+}
+
 static void *
 goop_init (Display *dpy, Window window)
 {
@@ -463,7 +499,7 @@ goop_draw (Display *dpy, Window window, void *closure)
 
   switch (goop->mode)
     {
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
     case transparent:
 
       for (i = 0; i < goop->nlayers; i++)
@@ -497,7 +533,7 @@ goop_draw (Display *dpy, Window window, void *closure)
       XCopyArea (dpy, goop->pixmap, window, goop->window_gc, 0, 0,
                 goop->width, goop->height, 0, 0);
       break;
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
 
     case xor:
       XSetFunction (dpy, goop->pixmap_gc, GXcopy);
@@ -514,7 +550,7 @@ goop_draw (Display *dpy, Window window, void *closure)
                  goop->width, goop->height, 0, 0, 1L);
       break;
 
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
     case transparent:
 # endif
     case opaque:
@@ -546,9 +582,13 @@ goop_reshape (Display *dpy, Window window, void *closure,
 {
   struct goop *goop = (struct goop *) closure;
 
-  /* #### leaks like crazy */
-  struct goop *goop2 = goop_init (dpy, window);
-  memcpy (goop, goop2, sizeof(*goop));
+  if (w != goop->width || h != goop->height)
+    {
+      struct goop *goop2 = goop_init (dpy, window);
+      free_goop(goop, dpy);
+      memcpy (goop, goop2, sizeof(*goop));
+      free(goop2);
+    }
 }
 
 static Bool
@@ -560,6 +600,9 @@ goop_event (Display *dpy, Window window, void *closure, XEvent *event)
 static void
 goop_free (Display *dpy, Window window, void *closure)
 {
+  struct goop *goop = (struct goop *) closure;
+  free_goop(goop, dpy);
+  free(goop);
 }
 
 
@@ -577,6 +620,9 @@ static const char *goop_defaults [] = {
   "*torque:            0.0075",
   "*elasticity:                0.9",
   "*maxVelocity:       0.5",
+#ifdef HAVE_MOBILE
+  "*ignoreRotation:     True",
+#endif
   0
 };