http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / deco.c
index 628deb988184d2b6b5f4ff8b35ca64447af24582..6e3612fa23ef11a8c92e81037b07e817a3176c6e 100644 (file)
@@ -1,4 +1,5 @@
-/* xscreensaver, Copyright (c) 1997, 1998, 2002 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1997, 1998, 2002, 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 <stdio.h>
-#include <time.h>
-#include <sys/time.h>
 
-static XColor colors[255];
-static int ncolors = 0;
-static int max_depth = 0;
-static int min_height = 0;
-static int min_width = 0;
+struct state {
+  XColor colors[255];
+  int ncolors;
+  int max_depth;
+  int min_height;
+  int min_width;
+  int delay;
+  XWindowAttributes xgwa;
+  GC fgc, bgc;
+  int current_color;
+};
 
 static void
-deco (Display *dpy,
-      Window window,
-      Colormap cmap,
-      GC fgc, GC bgc,
+deco (Display *dpy, Window window, struct state *st,
       int x, int y, int w, int h, int depth)
 {
-  if (((random() % max_depth) < depth) || (w < min_width) || (h < min_height))
+  if (((random() % st->max_depth) < depth) || (w < st->min_width) || (h < st->min_height))
     {
       if (!mono_p)
        {
-         static int current_color = 0;
-         if (++current_color >= ncolors)
-           current_color = 0;
-         XSetForeground(dpy, bgc, colors[current_color].pixel);
+         if (++st->current_color >= st->ncolors)
+           st->current_color = 0;
+         XSetForeground(dpy, st->bgc, st->colors[st->current_color].pixel);
        }
-      XFillRectangle (dpy, window, bgc, x, y, w, h);
-      XDrawRectangle (dpy, window, fgc, x, y, w, h);
+      XFillRectangle (dpy, window, st->bgc, x, y, w, h);
+      XDrawRectangle (dpy, window, st->fgc, x, y, w, h);
     }
   else
     {
       if (random() & 1)
        {
-         deco (dpy, window, cmap, fgc, bgc, x, y, w/2, h, depth+1);
-         deco (dpy, window, cmap, fgc, bgc, x+w/2, y, w/2, h, depth+1);
+         deco (dpy, window, st, x, y, w/2, h, depth+1);
+         deco (dpy, window, st, x+w/2, y, w/2, h, depth+1);
        }
       else
        {
-         deco (dpy, window, cmap, fgc, bgc, x, y, w, h/2, depth+1);
-         deco (dpy, window, cmap, fgc, bgc, x, y+h/2, w, h/2, depth+1);
+         deco (dpy, window, st, x, y, w, h/2, depth+1);
+         deco (dpy, window, st, x, y+h/2, w, h/2, depth+1);
        }
     }
 }
 
-\f
-char *progclass = "Deco";
+static void *
+deco_init (Display *dpy, Window window)
+{
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
+  XGCValues gcv;
+
+  st->delay = get_integer_resource (dpy, "delay", "Integer");
+
+  st->max_depth = get_integer_resource (dpy, "maxDepth", "Integer");
+  if (st->max_depth < 1) st->max_depth = 1;
+  else if (st->max_depth > 1000) st->max_depth = 1000;
+
+  st->min_width = get_integer_resource (dpy, "minWidth", "Integer");
+  if (st->min_width < 2) st->min_width = 2;
+  st->min_height = get_integer_resource (dpy, "minHeight", "Integer");
+  if (st->min_height < 2) st->min_height = 2;
+
+  XGetWindowAttributes (dpy, window, &st->xgwa);
+
+  gcv.foreground = get_pixel_resource(dpy, st->xgwa.colormap,
+                                      "foreground", "Foreground");
+  st->fgc = XCreateGC (dpy, window, GCForeground, &gcv);
+
+  gcv.foreground = get_pixel_resource(dpy, st->xgwa.colormap,
+                                      "background", "Background");
+  st->bgc = XCreateGC (dpy, window, GCForeground, &gcv);
+
+  st->ncolors = get_integer_resource (dpy, "ncolors", "Integer");
+
+  make_random_colormap (dpy, st->xgwa.visual, st->xgwa.colormap, st->colors, &st->ncolors,
+                       False, True, 0, True);
+
+  if (st->ncolors <= 2)
+    mono_p = True;
 
-char *defaults [] = {
+  if (!mono_p)
+    {
+      GC tmp = st->fgc;
+      st->fgc = st->bgc;
+      st->bgc = tmp;
+    }
+
+  return st;
+}
+
+static unsigned long
+deco_draw (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  XFillRectangle (dpy, window, st->bgc, 0, 0, st->xgwa.width, st->xgwa.height);
+  deco (dpy, window, st, 0, 0, st->xgwa.width, st->xgwa.height, 0);
+  return 1000000 * st->delay;
+}
+
+static void
+deco_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+  struct state *st = (struct state *) closure;
+  st->xgwa.width = w;
+  st->xgwa.height = h;
+}
+
+static Bool
+deco_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  return False;
+}
+
+static void
+deco_free (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  free (st);
+}
+
+\f
+static const char *deco_defaults [] = {
   ".background:                black",
   ".foreground:                white",
   "*maxDepth:          12",
   "*minWidth:          20",
   "*minHeight:         20",
-  "*cycle:             False",
   "*delay:             5",
-  "*cycleDelay:                1000000",
   "*ncolors:           64",
   0
 };
 
-XrmOptionDescRec options [] = {
+static XrmOptionDescRec deco_options [] = {
   { "-max-depth",      ".maxDepth",    XrmoptionSepArg, 0 },
   { "-min-width",      ".minWidth",    XrmoptionSepArg, 0 },
   { "-min-height",     ".minHeight",   XrmoptionSepArg, 0 },
   { "-delay",          ".delay",       XrmoptionSepArg, 0 },
   { "-ncolors",                ".ncolors",     XrmoptionSepArg, 0 },
-  { "-cycle",          ".cycle",       XrmoptionNoArg, "True" },
-  { "-no-cycle",       ".cycle",       XrmoptionNoArg, "False" },
-  { "-cycle-delay",    ".cycleDelay",  XrmoptionSepArg, 0 },
   { 0, 0, 0, 0 }
 };
 
-void
-screenhack (Display *dpy, Window window)
-{
-  GC fgc, bgc;
-  XGCValues gcv;
-  XWindowAttributes xgwa;
-  int delay = get_integer_resource ("delay", "Integer");
-  int cycle_delay = get_integer_resource ("cycleDelay", "Integer");
-  Bool writable = get_boolean_resource ("cycle", "Boolean");
-
-  max_depth = get_integer_resource ("maxDepth", "Integer");
-  if (max_depth < 1) max_depth = 1;
-  else if (max_depth > 1000) max_depth = 1000;
-
-  min_width = get_integer_resource ("minWidth", "Integer");
-  if (min_width < 2) min_width = 2;
-  min_height = get_integer_resource ("minHeight", "Integer");
-  if (min_height < 2) min_height = 2;
-
-  XGetWindowAttributes (dpy, window, &xgwa);
-
-  gcv.foreground = get_pixel_resource("foreground", "Foreground",
-                                     dpy, xgwa.colormap);
-  fgc = XCreateGC (dpy, window, GCForeground, &gcv);
-
-  gcv.foreground = get_pixel_resource("background", "Background",
-                                     dpy, xgwa.colormap);
-  bgc = XCreateGC (dpy, window, GCForeground, &gcv);
-
-  ncolors = get_integer_resource ("ncolors", "Integer");
-
-  make_random_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors,
-                       False, True, &writable, True);
-
-  if (ncolors <= 2)
-    mono_p = True;
-
-  if (!mono_p)
-    {
-      GC tmp = fgc;
-      fgc = bgc;
-      bgc = tmp;
-    }
-
-  while (1)
-    {
-      XGetWindowAttributes (dpy, window, &xgwa);
-      XFillRectangle(dpy, window, bgc, 0, 0, xgwa.width, xgwa.height);
-      deco (dpy, window, xgwa.colormap, fgc, bgc,
-           0, 0, xgwa.width, xgwa.height, 0);
-      XSync (dpy, False);
-      screenhack_handle_events (dpy);
-
-      if (!delay) continue;
-      if (!writable)
-       sleep (delay);
-      else
-       {
-         time_t start = time((time_t) 0);
-         while (start - delay < time((time_t) 0))
-           {
-             rotate_colors (dpy, xgwa.colormap, colors, ncolors, 1);
-              XSync (dpy, False);
-              screenhack_handle_events (dpy);
-             if (cycle_delay)
-               usleep (cycle_delay);
-           }
-       }
-    }
-}
+XSCREENSAVER_MODULE ("Deco", deco)