http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / moire.c
index 0584dd9581906f3281781ab5df9843bac311e13f..c52d2236bc7207af9bf2707be974e64539500918 100644 (file)
@@ -1,4 +1,5 @@
-/* xscreensaver, Copyright (c) 1997, 1998, 2001 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1997, 1998, 2001, 2006
+ *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  */
 
 #include "screenhack.h"
-#include <X11/Xutil.h>
-#include <stdio.h>
+
+#undef HAVE_XSHM_EXTENSION  /* this is broken here at the moment */
+
 
 #ifdef HAVE_XSHM_EXTENSION
 # include "xshm.h"
-static Bool use_shm;
-static XShmSegmentInfo shm_info;
 #endif /* HAVE_XSHM_EXTENSION */
 
-static int offset = 0;
-static XColor *colors = 0;
-static int ncolors = 0;
-static GC gc = 0;
-static unsigned long fg_pixel = 0;
-static unsigned long bg_pixel = 0;
+struct state {
+  Display *dpy;
+  Window window;
+#ifdef HAVE_XSHM_EXTENSION
+  Bool use_shm;
+  XShmSegmentInfo shm_info;
+#endif /* HAVE_XSHM_EXTENSION */
+
+  int delay;
+  int offset;
+  XColor *colors;
+  int ncolors;
+  GC gc;
+  unsigned long fg_pixel;
+  unsigned long bg_pixel;
+  int depth;
+
+  int draw_y, draw_xo, draw_yo;
+  int draw_factor;
+  XImage *draw_image;
+  XWindowAttributes xgwa;
+};
 
 static void
-init_moire (Display *dpy, Window window)
+moire_init_1 (struct state *st)
 {
   int oncolors;
   int i;
@@ -39,50 +55,52 @@ init_moire (Display *dpy, Window window)
   XWindowAttributes xgwa;
   XColor fgc, bgc;
   XGCValues gcv;
-  XGetWindowAttributes (dpy, window, &xgwa);
 
-  offset = get_integer_resource ("offset", "Integer");
-  if (offset < 2) offset = 2;
+  XGetWindowAttributes (st->dpy, st->window, &xgwa);
+
+  st->delay = get_integer_resource (st->dpy, "delay", "Integer");
+  st->offset = get_integer_resource (st->dpy, "offset", "Integer");
+  if (st->offset < 2) st->offset = 2;
 
 #ifdef HAVE_XSHM_EXTENSION
-  use_shm = get_boolean_resource("useSHM", "Boolean");
+  st->use_shm = get_boolean_resource(st->dpy, "useSHM", "Boolean");
 #endif /*  HAVE_XSHM_EXTENSION */
 
  MONO:
-  if (colors)
+  if (st->colors)
     {
-      for (i = 0; i < ncolors; i++)
-       XFreeColors (dpy, xgwa.colormap, &colors[i].pixel, 1, 0);
-      free(colors);
-      colors = 0;
+      for (i = 0; i < st->ncolors; i++)
+       XFreeColors (st->dpy, xgwa.colormap, &st->colors[i].pixel, 1, 0);
+      free(st->colors);
+      st->colors = 0;
     }
 
   if (mono_p)
     {
-      fg_pixel = WhitePixelOfScreen (DefaultScreenOfDisplay(dpy));
-      bg_pixel = BlackPixelOfScreen (DefaultScreenOfDisplay(dpy));
+      st->fg_pixel = WhitePixelOfScreen (DefaultScreenOfDisplay(st->dpy));
+      st->bg_pixel = BlackPixelOfScreen (DefaultScreenOfDisplay(st->dpy));
     }
   else
     {
-      fg_pixel = get_pixel_resource ("foreground", "Foreground", dpy,
-                                    xgwa.colormap);
-      bg_pixel = get_pixel_resource ("background", "Background", dpy,
-                                    xgwa.colormap);
+      st->fg_pixel = get_pixel_resource (st->dpy,
+                                    xgwa.colormap, "foreground", "Foreground");
+      st->bg_pixel = get_pixel_resource (st->dpy,
+                                    xgwa.colormap, "background", "Background");
     }
 
   if (mono_p)
     {
-      offset *= 20;   /* compensate for lack of shading */
-      gcv.foreground = fg_pixel;
+      st->offset *= 20;   /* compensate for lack of shading */
+      gcv.foreground = st->fg_pixel;
     }
   else
     {
-      ncolors = get_integer_resource ("ncolors", "Integer");
-      if (ncolors < 2) ncolors = 2;
-      oncolors = ncolors;
+      st->ncolors = get_integer_resource (st->dpy, "ncolors", "Integer");
+      if (st->ncolors < 2) st->ncolors = 2;
+      oncolors = st->ncolors;
 
       fgc.flags = bgc.flags = DoRed|DoGreen|DoBlue;
-      if (get_boolean_resource("random","Boolean"))
+      if (get_boolean_resource(st->dpy, "random","Boolean"))
        {
          fgc.red   = random() & 0xFFFF;
          fgc.green = random() & 0xFFFF;
@@ -93,116 +111,144 @@ init_moire (Display *dpy, Window window)
        }
       else
        {
-         fgc.pixel = fg_pixel;
-         bgc.pixel = bg_pixel;
-         XQueryColor (dpy, xgwa.colormap, &fgc);
-         XQueryColor (dpy, xgwa.colormap, &bgc);
+         fgc.pixel = st->fg_pixel;
+         bgc.pixel = st->bg_pixel;
+         XQueryColor (st->dpy, xgwa.colormap, &fgc);
+         XQueryColor (st->dpy, xgwa.colormap, &bgc);
        }
       rgb_to_hsv (fgc.red, fgc.green, fgc.blue, &fgh, &fgs, &fgv);
       rgb_to_hsv (bgc.red, bgc.green, bgc.blue, &bgh, &bgs, &bgv);
 
-      colors = (XColor *) malloc (sizeof (XColor) * (ncolors+2));
-      memset(colors, 0, (sizeof (XColor) * (ncolors+2)));
-      make_color_ramp (dpy, xgwa.colormap,
+      st->colors = (XColor *) malloc (sizeof (XColor) * (st->ncolors+2));
+      memset(st->colors, 0, (sizeof (XColor) * (st->ncolors+2)));
+      make_color_ramp (st->dpy, xgwa.colormap,
                       fgh, fgs, fgv, bgh, bgs, bgv,
-                      colors, &ncolors,
+                      st->colors, &st->ncolors,
                       True, True, False);
-      if (ncolors != oncolors)
+      if (st->ncolors != oncolors)
        fprintf(stderr, "%s: got %d of %d requested colors.\n",
-               progname, ncolors, oncolors);
+               progname, st->ncolors, oncolors);
 
-      if (ncolors <= 2)
+      if (st->ncolors <= 2)
        {
          mono_p = True;
          goto MONO;
        }
 
-      gcv.foreground = colors[0].pixel;
+      gcv.foreground = st->colors[0].pixel;
     }
-  gc = XCreateGC (dpy, window, GCForeground, &gcv);
+  st->gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
 }
 
 
-static void
-moire (Display *dpy, Window window, int offset, XColor *colors, int ncolors)
+static void *
+moire_init (Display *dpy, Window window)
+{
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
+  st->dpy = dpy;
+  st->window = window;
+  moire_init_1 (st);
+  return st;
+}
+
+
+static unsigned long
+moire_draw (Display *dpy, Window window, void *closure)
 {
-  long x, y, xo, yo;
-  int factor = (random() % offset) + 1;
+  struct state *st = (struct state *) closure;
   XGCValues gcv;
-  XWindowAttributes xgwa;
-  XImage *image;
-  int depth;
-  XGetWindowAttributes (dpy, window, &xgwa);
+  int chunk_size = 20, ii;
+
+  if (st->draw_y == 0) 
+    {
+      moire_init_1 (st);
+
+      XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
 
-  xo = (random() % xgwa.width)  - xgwa.width/2;
-  yo = (random() % xgwa.height) - xgwa.height/2;
+      st->draw_xo = (random() % st->xgwa.width)  - st->xgwa.width/2;
+      st->draw_yo = (random() % st->xgwa.height) - st->xgwa.height/2;
+      st->draw_factor = (random() % st->offset) + 1;
 
-  depth = visual_depth(DefaultScreenOfDisplay(dpy), xgwa.visual);
+      st->depth = visual_depth(DefaultScreenOfDisplay(st->dpy), st->xgwa.visual);
 
-  image = 0;
 # ifdef HAVE_XSHM_EXTENSION
-  if (use_shm)
-    {
-      image = create_xshm_image(dpy, xgwa.visual, depth, ZPixmap, 0,
-                               &shm_info, xgwa.width, 1);
-      if (!image)
-       use_shm = False;
-    }
+      if (st->use_shm)
+        {
+          st->draw_image = create_xshm_image(st->dpy, st->xgwa.visual, 
+                                             st->depth, ZPixmap, 0,
+                                             &st->shm_info, st->xgwa.width, 1);
+          if (!st->draw_image)
+            st->use_shm = False;
+        }
 # endif /* HAVE_XSHM_EXTENSION */
 
-  if (!image)
-    {
-      image = XCreateImage (dpy, xgwa.visual,
-                           depth, ZPixmap, 0,      /* depth, format, offset */
-                           0, xgwa.width, 1, 8, 0); /* data, w, h, pad, bpl */
-      image->data = (char *) calloc(image->height, image->bytes_per_line);
+      if (!st->draw_image)
+        {
+          st->draw_image = XCreateImage (st->dpy, st->xgwa.visual,
+                                         st->depth, ZPixmap, 0,            /* depth, format, offset */
+                                         0, st->xgwa.width, 1, 8, 0); /* data, w, h, pad, bpl */
+          st->draw_image->data = (char *) calloc(st->draw_image->height, st->draw_image->bytes_per_line);
+        }
     }
 
-  for (y = 0; y < xgwa.height; y++)
+  /* for (y = 0; y < st->xgwa.height; y++) */
+  for (ii = 0; ii < chunk_size; ii++)
     {
-      for (x = 0; x < xgwa.width; x++)
+      int x;
+      for (x = 0; x < st->xgwa.width; x++)
        {
-         double xx = x + xo;
-         double yy = y + yo;
-         double i = ((xx * xx) + (yy * yy)) / (double) factor;
+         double xx = x + st->draw_xo;
+         double yy = st->draw_y + st->draw_yo;
+         double i = ((xx * xx) + (yy * yy)) / (double) st->draw_factor;
          if (mono_p)
-           gcv.foreground = ((((long) i) & 1) ? fg_pixel : bg_pixel);
+           gcv.foreground = ((((long) i) & 1) ? st->fg_pixel : st->bg_pixel);
          else
-           gcv.foreground = colors[((long) i) % ncolors].pixel;
-         XPutPixel (image, x, 0, gcv.foreground);
+           gcv.foreground = st->colors[((long) i) % st->ncolors].pixel;
+         XPutPixel (st->draw_image, x, 0, gcv.foreground);
        }
 
 # ifdef HAVE_XSHM_EXTENSION
-      if (use_shm)
-       XShmPutImage(dpy, window, gc, image, 0, 0, 0, y, xgwa.width, 1, False);
+      if (st->use_shm)
+       XShmPutImage(st->dpy, st->window, st->gc, st->draw_image, 0, 0, 0, st->draw_y, st->xgwa.width, 1, False);
       else
 # endif /*  HAVE_XSHM_EXTENSION */
-       XPutImage (dpy, window, gc, image, 0, 0, 0, y, xgwa.width, 1);
+       XPutImage (st->dpy, st->window, st->gc, st->draw_image, 0, 0, 0, st->draw_y, st->xgwa.width, 1);
 
-      XSync(dpy, False);
+      st->draw_y++;
+      if (st->draw_y >= st->xgwa.height)
+        break;
     }
 
+
+    if (st->draw_y >= st->xgwa.height)
+      {
+        st->draw_y = 0;
+
 # ifdef HAVE_XSHM_EXTENSION
-  if (!use_shm)
+        if (!st->use_shm)
 # endif /*  HAVE_XSHM_EXTENSION */
-    if (image->data)
-      {
-       free(image->data);
-       image->data = 0;
-      }
+          if (st->draw_image->data)
+            {
+              free(st->draw_image->data);
+              st->draw_image->data = 0;
+            }
 
 # ifdef HAVE_XSHM_EXTENSION
-  if (use_shm)
-    destroy_xshm_image (dpy, image, &shm_info);
-  else
+        if (st->use_shm)
+          destroy_xshm_image (st->dpy, st->draw_image, &st->shm_info);
+        else
 # endif /*  HAVE_XSHM_EXTENSION */
-    XDestroyImage (image);
+          XDestroyImage (st->draw_image);
+        st->draw_image = 0;
+
+        return st->delay * 1000000;
+      }
+
+  return st->delay * 10000;
 }
 
 \f
-char *progclass = "Moire";
-
-char *defaults [] = {
+static const char *moire_defaults [] = {
   ".background:                blue",
   ".foreground:                red",
   "*random:            true",
@@ -211,34 +257,38 @@ char *defaults [] = {
   "*offset:            50",
 #ifdef HAVE_XSHM_EXTENSION
   "*useSHM:          True",
-#endif /*  HAVE_XSHM_EXTENSION */
+#else
+  "*useSHM:          False",
+#endif
   0
 };
 
-XrmOptionDescRec options [] = {
+static XrmOptionDescRec moire_options [] = {
   { "-random",         ".random",      XrmoptionNoArg, "True" },
   { "-no-random",      ".random",      XrmoptionNoArg, "False" },
   { "-delay",          ".delay",       XrmoptionSepArg, 0 },
   { "-ncolors",                ".ncolors",     XrmoptionSepArg, 0 },
   { "-offset",         ".offset",      XrmoptionSepArg, 0 },
-#ifdef HAVE_XSHM_EXTENSION
   { "-shm",            ".useSHM",      XrmoptionNoArg, "True" },
   { "-no-shm",         ".useSHM",      XrmoptionNoArg, "False" },
-#endif /*  HAVE_XSHM_EXTENSION */
   { 0, 0, 0, 0 }
 };
 
-void
-screenhack (Display *dpy, Window window)
+static void
+moire_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
 {
-  int delay = get_integer_resource ("delay", "Integer");
-  while (1)
-    {
-      init_moire (dpy, window);
-      moire (dpy, window, offset, colors, ncolors);
-      XSync (dpy, False);
-      screenhack_handle_events (dpy);
-      if (delay)
-       sleep(delay);
-    }
 }
+
+static Bool
+moire_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  return False;
+}
+
+static void
+moire_free (Display *dpy, Window window, void *closure)
+{
+}
+
+XSCREENSAVER_MODULE ("Moire", moire)