http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / halo.c
index fc69ea730af60d27e8f3709fba42ce335a0ababe..2b7e30fb79616a307fc67a50b7148d224e1a0e3e 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1993, 1995, 1996, 1997, 1998, 1999, 2003
+/* xscreensaver, Copyright (c) 1993, 1995, 1996, 1997, 1998, 1999, 2003, 2006
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -33,70 +33,81 @@ static enum color_mode {
 } cmode;
 
 
-static struct circle *circles;
-static int count, global_count;
-static Pixmap pixmap, buffer;
-static int width, height, global_inc;
-static int delay, delay2, cycle_delay;
-static unsigned long fg_pixel, bg_pixel;
-static GC draw_gc, erase_gc, copy_gc, merge_gc;
-static Bool anim_p;
-static Colormap cmap;
-
-static int ncolors;
-static XColor *colors;
-static Bool cycle_p;
-static int fg_index;
-static int bg_index;
-
+struct state {
+  Display *dpy;
+  Window window;
+
+  struct circle *circles;
+  int count, global_count;
+  Pixmap pixmap, buffer;
+  int width, height, global_inc;
+  int delay, delay2;
+  unsigned long fg_pixel, bg_pixel;
+  GC draw_gc, erase_gc, copy_gc, merge_gc;
+  Bool anim_p;
+  Colormap cmap;
+
+  int ncolors;
+  XColor *colors;
+  int fg_index;
+  int bg_index;
+
+  int iterations;
+  Bool done_once;
+  Bool done_once_no_really;
+  int clear_tick;
+  struct timeval then;
+};
 
 #define min(x,y) ((x)<(y)?(x):(y))
 #define max(x,y) ((x)>(y)?(x):(y))
 
 static void
-init_circles_1 (Display *dpy, Window window)
+init_circles_1 (struct state *st)
 {
   int i;
-  count = (global_count ? global_count
-          : (3 + (random () % max (1, (min (width, height) / 50)))
-               + (random () % max (1, (min (width, height) / 50)))));
-  circles = (struct circle *) malloc (count * sizeof (struct circle));
-  for (i = 0; i < count; i++)
+  st->count = (st->global_count ? st->global_count
+          : (3 + (random () % max (1, (min (st->width, st->height) / 50)))
+               + (random () % max (1, (min (st->width, st->height) / 50)))));
+  st->circles = (struct circle *) malloc (st->count * sizeof (struct circle));
+  for (i = 0; i < st->count; i++)
     {
-      circles [i].x = 10 + random () % (width - 20);
-      circles [i].y = 10 + random () % (height - 20);
-      if (global_inc)
-      circles [i].increment = global_inc;
+      st->circles [i].x = 10 + random () % (st->width - 20);
+      st->circles [i].y = 10 + random () % (st->height - 20);
+      if (st->global_inc)
+      st->circles [i].increment = st->global_inc;
       else
        { /* prefer smaller increments to larger ones */
          int j = 8;
          int inc = ((random()%j) + (random()%j) + (random()%j)) - ((j*3)/2);
          if (inc < 0) inc = -inc + 3;
-         circles [i].increment = inc + 3;
+         st->circles [i].increment = inc + 3;
        }
-      circles [i].radius = random () % circles [i].increment;
-      circles [i].dx = ((random () % 3) - 1) * (1 + random () % 5);
-      circles [i].dy = ((random () % 3) - 1) * (1 + random () % 5);
+      st->circles [i].radius = random () % st->circles [i].increment;
+      st->circles [i].dx = ((random () % 3) - 1) * (1 + random () % 5);
+      st->circles [i].dy = ((random () % 3) - 1) * (1 + random () % 5);
     }
 }
 
-static void
-init_circles (Display *dpy, Window window)
+static void *
+halo_init (Display *dpy, Window window)
 {
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
   XGCValues gcv;
   XWindowAttributes xgwa;
   char *mode_str = 0;
-  XGetWindowAttributes (dpy, window, &xgwa);
-  cmap = xgwa.colormap;
-  global_count = get_integer_resource ("count", "Integer");
-  if (global_count < 0) global_count = 0;
-  global_inc = get_integer_resource ("increment", "Integer");
-  if (global_inc < 0) global_inc = 0;
-  anim_p = get_boolean_resource ("animate", "Boolean");
-  delay = get_integer_resource ("delay", "Integer");
-  delay2 = get_integer_resource ("delay2", "Integer") * 1000000;
-  cycle_delay = get_integer_resource ("cycleDelay", "Integer");
-  mode_str = get_string_resource ("colorMode", "ColorMode");
+  st->dpy = dpy;
+  st->window = window;
+  XGetWindowAttributes (st->dpy, st->window, &xgwa);
+  st->cmap = xgwa.colormap;
+  st->global_count = get_integer_resource (st->dpy, "count", "Integer");
+  if (st->global_count < 0) st->global_count = 0;
+  st->global_inc = get_integer_resource (st->dpy, "increment", "Integer");
+  if (st->global_inc < 0) st->global_inc = 0;
+  st->anim_p = get_boolean_resource (st->dpy, "animate", "Boolean");
+  st->delay = get_integer_resource (st->dpy, "delay", "Integer");
+  st->delay2 = get_integer_resource (st->dpy, "delay2", "Integer") * 1000000;
+  mode_str = get_string_resource (st->dpy, "colorMode", "ColorMode");
   if (! mode_str) cmode = random_mode;
   else if (!strcmp (mode_str, "seuss"))  cmode = seuss_mode;
   else if (!strcmp (mode_str, "ramp"))   cmode = ramp_mode;
@@ -113,129 +124,126 @@ init_circles (Display *dpy, Window window)
     cmode = ((random()&3) == 1) ? ramp_mode : seuss_mode;
 
   if (cmode == ramp_mode)
-    anim_p = False;    /* This combo doesn't work right... */
+    st->anim_p = False;    /* This combo doesn't work right... */
 
-  ncolors = get_integer_resource ("colors", "Colors");
-  if (ncolors < 2) ncolors = 2;
-  if (ncolors <= 2) mono_p = True;
+  st->ncolors = get_integer_resource (st->dpy, "colors", "Colors");
+  if (st->ncolors < 2) st->ncolors = 2;
+  if (st->ncolors <= 2) mono_p = True;
 
   if (mono_p)
-    colors = 0;
+    st->colors  = 0;
   else
-    colors = (XColor *) malloc(sizeof(*colors) * (ncolors+1));
-
-  cycle_p = mono_p ? False : get_boolean_resource ("cycle", "Cycle");
-
-  /* If the visual isn't color-indexed, don't bother trying to
-     allocate writable cells. */
-  if (cycle_p && !has_writable_cells (xgwa.screen, xgwa.visual))
-    cycle_p = False;
+    st->colors = (XColor *) malloc(sizeof(*st->colors) * (st->ncolors+1));
 
 
   if (mono_p)
     ;
   else if (random() % (cmode == seuss_mode ? 2 : 10))
-    make_uniform_colormap (dpy, xgwa.visual, cmap, colors, &ncolors,
-                          True, &cycle_p, True);
+    make_uniform_colormap (st->dpy, xgwa.visual, st->cmap, st->colors, &st->ncolors,
+                          True, 0, True);
   else
-    make_smooth_colormap (dpy, xgwa.visual, cmap, colors, &ncolors,
-                         True, &cycle_p, True);
+    make_smooth_colormap (st->dpy, xgwa.visual, st->cmap, st->colors, &st->ncolors,
+                         True, 0, True);
 
-  if (ncolors <= 2) mono_p = True;
-  if (mono_p) cycle_p = False;
+  if (st->ncolors <= 2) mono_p = True;
   if (mono_p) cmode = seuss_mode;
 
   if (mono_p)
     {
-      fg_pixel = get_pixel_resource ("foreground", "Foreground", dpy, cmap);
-      bg_pixel = get_pixel_resource ("background", "Background", dpy, cmap);
+      st->fg_pixel = get_pixel_resource (st->dpy, st->cmap, "foreground", "Foreground");
+      st->bg_pixel = get_pixel_resource (st->dpy, st->cmap, "background", "Background");
     }
   else
     {
-      fg_index = 0;
-      bg_index = ncolors / 4;
-      if (fg_index == bg_index) bg_index++;
-      fg_pixel = colors[fg_index].pixel;
-      bg_pixel = colors[bg_index].pixel;
+      st->fg_index = 0;
+      st->bg_index = st->ncolors / 4;
+      if (st->fg_index == st->bg_index) st->bg_index++;
+      st->fg_pixel = st->colors[st->fg_index].pixel;
+      st->bg_pixel = st->colors[st->bg_index].pixel;
     }
 
-  width = max (50, xgwa.width);
-  height = max (50, xgwa.height);
+  st->width = max (50, xgwa.width);
+  st->height = max (50, xgwa.height);
 
 #ifdef DEBUG
-  width/=2; height/=2;
+  st->width/=2; st->height/=2;
 #endif
 
-  pixmap = XCreatePixmap (dpy, window, width, height, 1);
+  st->pixmap = XCreatePixmap (st->dpy, st->window, st->width, st->height, 1);
   if (cmode == seuss_mode)
-    buffer = XCreatePixmap (dpy, window, width, height, 1);
+    st->buffer = XCreatePixmap (st->dpy, st->window, st->width, st->height, 1);
   else
-    buffer = 0;
+    st->buffer = 0;
 
   gcv.foreground = 1;
   gcv.background = 0;
-  draw_gc = XCreateGC (dpy, pixmap, GCForeground | GCBackground, &gcv);
+  st->draw_gc = XCreateGC (st->dpy, st->pixmap, GCForeground | GCBackground, &gcv);
   gcv.foreground = 0;
-  erase_gc = XCreateGC (dpy, pixmap, GCForeground, &gcv);
-  gcv.foreground = fg_pixel;
-  gcv.background = bg_pixel;
-  copy_gc = XCreateGC (dpy, window, GCForeground | GCBackground, &gcv);
+  st->erase_gc = XCreateGC (st->dpy, st->pixmap, GCForeground, &gcv);
+  gcv.foreground = st->fg_pixel;
+  gcv.background = st->bg_pixel;
+  st->copy_gc = XCreateGC (st->dpy, st->window, GCForeground | GCBackground, &gcv);
+
+#ifdef HAVE_COCOA
+  jwxyz_XSetAntiAliasing (dpy, st->draw_gc,  False);
+  jwxyz_XSetAntiAliasing (dpy, st->erase_gc, False);
+  jwxyz_XSetAntiAliasing (dpy, st->copy_gc,  False);
+#endif
 
   if (cmode == seuss_mode)
     {
       gcv.foreground = 1;
       gcv.background = 0;
       gcv.function = GXxor;
-      merge_gc = XCreateGC (dpy, pixmap,
+      st->merge_gc = XCreateGC (st->dpy, st->pixmap,
                            GCForeground | GCBackground | GCFunction, &gcv);
     }
   else
     {
-      gcv.foreground = fg_pixel;
-      gcv.background = bg_pixel;
+      gcv.foreground = st->fg_pixel;
+      gcv.background = st->bg_pixel;
       gcv.function = GXcopy;
-      merge_gc = XCreateGC (dpy, window,
+      st->merge_gc = XCreateGC (st->dpy, st->window,
                            GCForeground | GCBackground | GCFunction, &gcv);
     }
 
-  init_circles_1 (dpy, window);
-  XClearWindow (dpy, window);
-  if (buffer) XFillRectangle (dpy, buffer, erase_gc, 0, 0, width, height);
+  init_circles_1 (st);
+  XClearWindow (st->dpy, st->window);
+  if (st->buffer) XFillRectangle (st->dpy, st->buffer, st->erase_gc, 0, 0, st->width, st->height);
+  return st;
 }
 
-static void
-run_circles (Display *dpy, Window window)
+static unsigned long
+halo_draw (Display *dpy, Window window, void *closure)
 {
+  struct state *st = (struct state *) closure;
   int i;
-  static int iterations = 0;
-  static int oiterations = 0;
-  static Bool first_time_p = True;
   Bool done = False;
   Bool inhibit_sleep = False;
-  static int clear_tick = 0;
+  int this_delay = st->delay;
 
-  XFillRectangle (dpy, pixmap, erase_gc, 0, 0, width, height);
-  for (i = 0; i < count; i++)
+  XFillRectangle (st->dpy, st->pixmap, st->erase_gc, 0, 0, st->width, st->height);
+  for (i = 0; i < st->count; i++)
     {
-      int radius = circles [i].radius;
-      int inc = circles [i].increment;
+      int radius = st->circles [i].radius;
+      int inc = st->circles [i].increment;
 
-      if (! (iterations & 1))  /* never stop on an odd number of iterations */
+      if (! (st->iterations & 1))  /* never stop on an odd number of iterations */
        ;
       else if (radius == 0)    /* eschew inf */
        ;
       else if (radius < 0)     /* stop when the circles are points */
        done = True;
-      else                     /* stop when the circles fill the window */
+      else                     /* stop when the circles fill the st->window */
        {
          /* Probably there's a simpler way to ask the musical question,
             "is this square completely enclosed by this circle," but I've
             forgotten too much trig to know it...  (That's not really the
             right question anyway, but the right question is too hard.) */
-         double x1 = ((double) (-circles [i].x)) / ((double) radius);
-         double y1 = ((double) (-circles [i].y)) / ((double) radius);
-         double x2 = ((double) (width - circles [i].x)) / ((double) radius);
-         double y2 = ((double) (height - circles [i].y)) / ((double) radius);
+         double x1 = ((double) (-st->circles [i].x)) / ((double) radius);
+         double y1 = ((double) (-st->circles [i].y)) / ((double) radius);
+         double x2 = ((double) (st->width - st->circles [i].x)) / ((double) radius);
+         double y2 = ((double) (st->height - st->circles [i].y)) / ((double) radius);
          x1 *= x1; x2 *= x2; y1 *= y1; y2 *= y2;
          if ((x1 + y1) < 1 && (x2 + y2) < 1 && (x1 + y2) < 1 && (x2 + y1) < 1)
            done = True;
@@ -243,224 +251,186 @@ run_circles (Display *dpy, Window window)
 
       if (radius > 0 &&
          (cmode == seuss_mode ||       /* drawing all circles, or */
-          circles [0].increment < 0))  /* on the way back in */
+          st->circles [0].increment < 0))      /* on the way back in */
        {
-         XFillArc (dpy,
-                   (cmode == seuss_mode ? pixmap : window),
-                   (cmode == seuss_mode ? draw_gc : merge_gc),
-                   circles [i].x - radius, circles [i].y - radius,
+         XFillArc (st->dpy,
+                   (cmode == seuss_mode ? st->pixmap : st->window),
+                   (cmode == seuss_mode ? st->draw_gc : st->merge_gc),
+                   st->circles [i].x - radius, st->circles [i].y - radius,
                    radius * 2, radius * 2, 0, 360*64);
        }
-      circles [i].radius += inc;
+      st->circles [i].radius += inc;
     }
 
-  if (cycle_p && cmode != seuss_mode)
-    {
-      struct timeval now;
-      static struct timeval then = { 0, 0 };
-      unsigned long diff;
-#ifdef GETTIMEOFDAY_TWO_ARGS
-      struct timezone tzp;
-      gettimeofday(&now, &tzp);
-#else
-      gettimeofday(&now);
-#endif
-      diff = (((now.tv_sec - then.tv_sec)  * 1000000) +
-             (now.tv_usec - then.tv_usec));
-      if (diff > cycle_delay)
-       {
-         rotate_colors (dpy, cmap, colors, ncolors, 1);
-         then = now;
-       }
-    }
-
-  if (anim_p && !first_time_p)
+  if (st->anim_p && !st->done_once)
     inhibit_sleep = !done;
 
   if (done)
     {
-      if (anim_p)
+      if (st->anim_p)
        {
-         first_time_p = False;
-         for (i = 0; i < count; i++)
+         st->done_once = True;
+         for (i = 0; i < st->count; i++)
            {
-             circles [i].x += circles [i].dx;
-             circles [i].y += circles [i].dy;
-             circles [i].radius %= circles [i].increment;
-             if (circles [i].x < 0 || circles [i].x >= width)
+             st->circles [i].x += st->circles [i].dx;
+             st->circles [i].y += st->circles [i].dy;
+             st->circles [i].radius %= st->circles [i].increment;
+             if (st->circles [i].x < 0 || st->circles [i].x >= st->width)
                {
-                 circles [i].dx = -circles [i].dx;
-                 circles [i].x += (2 * circles [i].dx);
+                 st->circles [i].dx = -st->circles [i].dx;
+                 st->circles [i].x += (2 * st->circles [i].dx);
                }
-             if (circles [i].y < 0 || circles [i].y >= height)
+             if (st->circles [i].y < 0 || st->circles [i].y >= st->height)
                {
-                 circles [i].dy = -circles [i].dy;
-                 circles [i].y += (2 * circles [i].dy);
+                 st->circles [i].dy = -st->circles [i].dy;
+                 st->circles [i].y += (2 * st->circles [i].dy);
                }
            }
        }
-      else if (circles [0].increment < 0)
+      else if (st->circles [0].increment < 0)
        {
          /* We've zoomed out and the screen is blank -- re-pick the
-            center points, and shift the colors.
+            center points, and shift the st->colors.
           */
-         free (circles);
-         init_circles_1 (dpy, window);
+         free (st->circles);
+         init_circles_1 (st);
          if (! mono_p)
            {
-             fg_index = (fg_index + 1) % ncolors;
-             bg_index = (fg_index + (ncolors/2)) % ncolors;
-             XSetForeground (dpy, copy_gc, colors [fg_index].pixel);
-             XSetBackground (dpy, copy_gc, colors [bg_index].pixel);
+             st->fg_index = (st->fg_index + 1) % st->ncolors;
+             st->bg_index = (st->fg_index + (st->ncolors/2)) % st->ncolors;
+             XSetForeground (st->dpy, st->copy_gc, st->colors [st->fg_index].pixel);
+             XSetBackground (st->dpy, st->copy_gc, st->colors [st->bg_index].pixel);
            }
        }
       /* Sometimes go out from the inside instead of the outside */
-      else if (clear_tick == 0 && ((random () % 3) == 0))
+      else if (st->clear_tick == 0 && ((random () % 3) == 0))
        {
-         iterations = 0; /* ick */
-         for (i = 0; i < count; i++)
-           circles [i].radius %= circles [i].increment;
+         st->iterations = 0; /* ick */
+         for (i = 0; i < st->count; i++)
+           st->circles [i].radius %= st->circles [i].increment;
 
-          clear_tick = ((random() % 8) + 4) | 1;   /* must be odd */
+          st->clear_tick = ((random() % 8) + 4) | 1;   /* must be odd */
        }
       else
        {
-         oiterations = iterations;
-         for (i = 0; i < count; i++)
+         for (i = 0; i < st->count; i++)
            {
-             circles [i].increment = -circles [i].increment;
-             circles [i].radius += (2 * circles [i].increment);
+             st->circles [i].increment = -st->circles [i].increment;
+             st->circles [i].radius += (2 * st->circles [i].increment);
            }
        }
     }
 
-  if (buffer)
-    XCopyPlane (dpy, pixmap, buffer, merge_gc, 0, 0, width, height, 0, 0, 1);
+  if (st->buffer)
+    XCopyPlane (st->dpy, st->pixmap, st->buffer, st->merge_gc, 0, 0, st->width, st->height, 0, 0, 1);
   else if (cmode != seuss_mode)
     {
 
       if (!mono_p)
        {
-         fg_index++;
-         bg_index++;
-         if (fg_index >= ncolors) fg_index = 0;
-         if (bg_index >= ncolors) bg_index = 0;
-         XSetForeground (dpy, merge_gc, colors [fg_index].pixel);
+         st->fg_index++;
+         st->bg_index++;
+         if (st->fg_index >= st->ncolors) st->fg_index = 0;
+         if (st->bg_index >= st->ncolors) st->bg_index = 0;
+         XSetForeground (st->dpy, st->merge_gc, st->colors [st->fg_index].pixel);
        }
 
-      if (circles [0].increment >= 0)
+      if (st->circles [0].increment >= 0)
        inhibit_sleep = True;
       else if (done && cmode == seuss_mode)
-       XFillRectangle (dpy, window, merge_gc, 0, 0, width, height);
+       XFillRectangle (st->dpy, st->window, st->merge_gc, 0, 0, st->width, st->height);
     }
   else
-    XCopyPlane (dpy, pixmap, window, merge_gc, 0, 0, width, height, 0, 0, 1);
+    XCopyPlane (st->dpy, st->pixmap, st->window, st->merge_gc, 0, 0, st->width, st->height, 0, 0, 1);
 
-  /* buffer is only used in seuss-mode or anim-mode */
-  if (buffer && (anim_p
-                ? (done || (first_time_p && (iterations & 1)))
-                : (iterations & 1)))
+  /* st->buffer is only used in seuss-mode or anim-mode */
+  if (st->buffer && (st->anim_p
+                ? (done || (!st->done_once && (st->iterations & 1)))
+                : (st->iterations & 1)))
     {
-      XCopyPlane (dpy, buffer, window, copy_gc, 0, 0, width, height, 0, 0, 1);
-      XSync (dpy, False);
-      if (anim_p && done)
-       XFillRectangle (dpy, buffer, erase_gc, 0, 0, width, height);
+      XCopyPlane (st->dpy, st->buffer, st->window, st->copy_gc, 0, 0, st->width, st->height, 0, 0, 1);
+      if (st->anim_p && done)
+       XFillRectangle (st->dpy, st->buffer, st->erase_gc, 0, 0, st->width, st->height);
     }
 
 #ifdef DEBUG
-  XCopyPlane (dpy, pixmap, window, copy_gc, 0,0,width,height,width,height, 1);
-  if (buffer)
-    XCopyPlane (dpy, buffer, window, copy_gc, 0,0,width,height,0,height, 1);
-  XSync (dpy, False);
+  XCopyPlane (st->dpy, st->pixmap, st->window, st->copy_gc, 0,0,st->width,st->height,st->width,st->height, 1);
+  if (st->buffer)
+    XCopyPlane (st->dpy, st->buffer, st->window, st->copy_gc, 0,0,st->width,st->height,0,st->height, 1);
 #endif
 
   if (done)
-    iterations = 0;
+    st->iterations = 0;
   else
-    iterations++;
+    st->iterations++;
 
-  if (delay && !inhibit_sleep)
+  if (st->delay && !inhibit_sleep)
     {
-      static Bool really_first_p = True;
-      int direction = 1;
-      int d = delay;
-      if (done && cycle_p && cmode != seuss_mode && !really_first_p)
-       {
-         d = delay2;
-         if (! (random() % 10))
-           direction = -1;
-       }
-
-      XSync(dpy, False);
-      screenhack_handle_events (dpy);
+      int d = st->delay;
 
-      if (cycle_p && cycle_delay)
-       {
-          i = 0;
-         while (i < d)
-           {
-             rotate_colors (dpy, cmap, colors, ncolors, direction);
-             usleep(cycle_delay);
-              screenhack_handle_events (dpy);
-             i += cycle_delay;
-           }
-       }
-      else if (cmode != seuss_mode &&
-               done && !really_first_p && cycle_delay > 0)
-        usleep (cycle_delay * 50);
+      if (cmode == seuss_mode && st->anim_p)
+        this_delay = d/100;
       else
-        usleep (d);
+        this_delay = d;
 
       if (done)
-       really_first_p = False;
+       st->done_once_no_really = True;
     }
 
-  if (done && clear_tick > 0)
+  if (done && st->clear_tick > 0)
     {
-      clear_tick--;
-      if (!clear_tick)
+      st->clear_tick--;
+      if (!st->clear_tick)
         {
-          XClearWindow (dpy, window);
-          if (buffer) XFillRectangle (dpy, buffer, erase_gc, 0,0,width,height);
+          XClearWindow (st->dpy, st->window);
+          if (st->buffer) XFillRectangle (st->dpy, st->buffer, st->erase_gc, 0,0,st->width,st->height);
         }
     }
+
+  if (inhibit_sleep) this_delay = 0;
+
+  return this_delay;
 }
 
 \f
-char *progclass = "Halo";
 
-char *defaults [] = {
+static const char *halo_defaults [] = {
   ".background:                black",
   ".foreground:                white",
   "*colorMode:         random",
   "*colors:            100",
-  "*cycle:             true",
   "*count:             0",
   "*delay:             100000",
   "*delay2:            20",
-  "*cycleDelay:                100000",
+  "*increment:         0",
+  "*animate:           False",
   0
 };
 
-XrmOptionDescRec options [] = {
+static XrmOptionDescRec halo_options [] = {
   { "-count",          ".count",       XrmoptionSepArg, 0 },
   { "-delay",          ".delay",       XrmoptionSepArg, 0 },
-  { "-cycle-delay",    ".cycleDelay",  XrmoptionSepArg, 0 },
   { "-animate",                ".animate",     XrmoptionNoArg, "True" },
   { "-mode",           ".colorMode",   XrmoptionSepArg, 0 },
   { "-colors",         ".colors",      XrmoptionSepArg, 0 },
-  { "-cycle",          ".cycle",       XrmoptionNoArg, "True" },
-  { "-no-cycle",       ".cycle",       XrmoptionNoArg, "False" },
   { 0, 0, 0, 0 }
 };
 
-void
-screenhack (Display *dpy, Window window)
+static void
+halo_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
 {
-  init_circles (dpy, window);
-  while (1)
-    {
-      run_circles (dpy, window);
-      screenhack_handle_events (dpy);
-    }
 }
+
+static Bool
+halo_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  return False;
+}
+
+static void
+halo_free (Display *dpy, Window window, void *closure)
+{
+}
+
+XSCREENSAVER_MODULE ("Halo", halo)