http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.14.tar.gz
[xscreensaver] / hacks / imsmap.c
index 8c36bccbe5351f29736b99698c0640e8ce84db52..fad6a8ca4dedf993df6257e681277f1ef84c60c4 100644 (file)
@@ -8,54 +8,61 @@
  * documentation.  No representations are made about the suitability of this
  * software for any purpose.  It is provided "as is" without express or 
  * implied warranty.
+ *
+ * Revision History:
+ * 24-aug-92: jwz: hacked.
+ * 17-May-97: jwz: hacked more.
  */
 
-#include "screenhack.h"
 #include <stdio.h>
+#include <math.h>
+#include <time.h>
+#include <sys/time.h> /* for gettimeofday() */
+
+#include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
+#include "screenhack.h"
+
 #define NSTEPS 7
 #define COUNT (1 << NSTEPS)
 #define CELL(c, r) cell[((unsigned int)(c)) + ((unsigned int) (r)) * xmax]
 
-static enum mode_t { MODE_H, MODE_S, MODE_V, MODE_RANDOM } mode;
+static enum imsmap_mode { MODE_H, MODE_S, MODE_V, MODE_RANDOM } mode;
 
 static GC gc, gc2;
-static Display *disp;
-static Window wind;
-static XWindowAttributes wattrs;
+static XWindowAttributes xgwa;
 
 #if defined(sun) && !__STDC__  /* sun cc doesn't know "signed char" */
 #define signed /**/
 #endif
 
-static unsigned long *pixels = 0, fg_pixel, bg_pixel;
-static int npixels = 0;
 static Colormap cmap;
-static int timeout, cycle_delay;
-static int cycle_p;
+static int ncolors;
+static XColor *colors;
+static Bool cycle_p;
+static int cycle_direction;
+static Bool extra_krinkly_p;
+
+static int delay, cycle_delay;
 static signed char *cell = NULL;
 static int xmax, ymax;
 static int iterations;
 
 static void
-initwin (dsp, win)
-     Display *dsp;
-     Window win;
+init_map (Display *dpy, Window window)
 {
+  unsigned long fg_pixel = 0, bg_pixel = 0;
   int fg_h, bg_h;
   double fg_s, fg_v, bg_s, bg_v;
 
-  enum mode_t this_mode;
+  enum imsmap_mode this_mode;
   static Bool rv_p;
-  static int ncolors = 0;
-  int shift;
-  double dshift;
     
   XGCValues gcv;
 
-  XGetWindowAttributes (dsp, win, &wattrs);
-  cmap = wattrs.colormap;
+  XGetWindowAttributes (dpy, window, &xgwa);
+  cmap = xgwa.colormap;
 
   if (!ncolors)
     {
@@ -63,25 +70,40 @@ initwin (dsp, win)
       rv_p = get_boolean_resource ("reverseVideo", "ReverseVideo");
       cycle_p = get_boolean_resource ("cycle", "Cycle");
       ncolors = get_integer_resource ("ncolors", "Integer");
-      timeout = get_integer_resource ("timeout", "Integer");
+      delay = get_integer_resource ("delay", "Integer");
       cycle_delay = get_integer_resource ("cycleDelay", "Integer");
       iterations = get_integer_resource ("iterations", "Integer");
       if (iterations < 0) iterations = 0;
       else if (iterations > 7) iterations = 7;
-      pixels = (unsigned long *) calloc (ncolors, sizeof (unsigned int));
-      fg_pixel = get_pixel_resource ("background", "Background", dsp, cmap);
-      bg_pixel = get_pixel_resource ("foreground", "Foreground", dsp, cmap);
 
-      if (mono_p && fg_pixel == bg_pixel)
-       bg_pixel = !bg_pixel;
+      if (ncolors <= 2) ncolors = 0;
+      if (ncolors == 0) mono_p = True;
+      if (ncolors > 255) ncolors = 255;  /* too many look bad */
+
+      fg_pixel = get_pixel_resource ("background", "Background", dpy, cmap);
+      bg_pixel = get_pixel_resource ("foreground", "Foreground", dpy, cmap);
+
+      if (fg_pixel == bg_pixel)
+       {
+         XColor black, white;
+         black.red = black.green = black.blue = 0;
+         white.red = white.green = white.blue = 0xFFFF;
+         black.flags = white.flags = DoRed|DoGreen|DoBlue;
+         XAllocColor(dpy, cmap, &black);
+         XAllocColor(dpy, cmap, &white);
+         if (bg_pixel == black.pixel)
+           fg_pixel = white.pixel;
+         else
+           fg_pixel = black.pixel;
+       }
 
       if (mono_p) cycle_p = False;
 
       gcv.foreground = fg_pixel;
       gcv.background = bg_pixel;
-      gc = XCreateGC (dsp, win, GCForeground|GCBackground, &gcv);
+      gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
       gcv.foreground = bg_pixel;
-      gc2 = XCreateGC (dsp, win, GCForeground, &gcv);
+      gc2 = XCreateGC (dpy, window, GCForeground, &gcv);
 
       if (!mode_str || !strcmp (mode_str, "random"))
        mode = MODE_RANDOM;
@@ -99,142 +121,163 @@ initwin (dsp, win)
          mode = MODE_RANDOM;
        }
     }
-    else if (! mono_p)
-      XFreeColors (dsp, cmap, pixels, npixels, 0);
 
   this_mode = mode;
   if (!mono_p && mode == MODE_RANDOM)
-    switch (random () % 3) {
+    switch (random () % 6) {
     case 0: this_mode = MODE_H; break;
     case 1: this_mode = MODE_S; break;
     case 2: this_mode = MODE_V; break;
+    default: break;
     }
 
   if (mono_p)
-    {
-      npixels = ncolors;
-      pixels [0] = fg_pixel;
-      pixels [1] = bg_pixel;
-    }
+    extra_krinkly_p = !(random() % 15);
   else
+    extra_krinkly_p = !(random() % 5);
+
+  if (!mono_p)
     {
-      XColor fg_color, bg_color;
+      double distance, fg_H, bg_H, dh;
 
-      if (fg_pixel == bg_pixel)
+    RETRY:
+      fg_h = random() % 360;
+      fg_s = frand(1.0);
+      fg_v = frand(1.0);
+
+      bg_h = fg_h;
+      bg_s = fg_s;
+      bg_v = fg_v;
+
+      switch (this_mode)
        {
-       HSV_AGAIN:
-         fg_h = random () % 360;
-         bg_h = random () % 360;
-         fg_s = frand (1.0);
-         bg_s = frand (1.0);
-       V_AGAIN:
-         fg_v = frand (1.0);
-         bg_v = frand (1.0);
-         if ((fg_v - bg_v) > -0.4 && (fg_v - bg_v) < 0.4)
-           goto V_AGAIN;
-         hsv_to_rgb (fg_h, fg_s, fg_v, 
-                     &fg_color.red, &fg_color.green, &fg_color.blue);
-         hsv_to_rgb (bg_h, bg_s, bg_v, 
-                     &bg_color.red, &bg_color.green, &bg_color.blue);
+       case MODE_H:
+         bg_h = random() % 360;
+         if (fg_v < 0.4)
+           goto RETRY;
+         distance = fg_h - bg_h;
+         if (distance < 0)
+           distance = -distance;
+         if (distance > 360)
+           distance = 180 - (distance - 180);
+         if (distance < 30)
+           goto RETRY;
+         break;
+
+       case MODE_S:
+         bg_s = frand(1.0);
+         if (fg_v < 0.4)
+           goto RETRY;
+         distance = fg_s - bg_s;
+         if (distance < 0)
+           distance = -distance;
+         if (distance < 0.2)
+           goto RETRY;
+         break;
+
+       case MODE_V:
+         bg_v = frand(1.0);
+         distance = fg_v - bg_v;
+         if (distance < 0)
+           distance = -distance;
+         if (distance < 0.4)
+           goto RETRY;
+         break;
+
+       default:
+         bg_h = random() % 360;
+         bg_s = frand(1.0);
+         bg_v = frand(1.0);
+
+         fg_H = ((double) fg_h) / 360;
+         bg_H = ((double) bg_h) / 360;
+         dh = fg_H - bg_H;
+         if (dh < 0) dh = -dh;
+         if (dh > 0.5) dh = 0.5 - (dh - 0.5);
+         distance = sqrt ((dh * dh) +
+                          ((fg_s - bg_s) * (fg_s - bg_s)) +
+                          ((fg_v - bg_v) * (fg_v - bg_v)));
+         if (distance < 0.2)
+           goto RETRY;
        }
+
+      cycle_p = True;
+      if (colors)
+       free_colors (dpy, cmap, colors, ncolors);
       else
-       {
-         fg_color.pixel = fg_pixel;
-         if (! XQueryColor (dsp, cmap, &fg_color))
-           abort ();
-         bg_color.pixel = bg_pixel;
-         if (! XQueryColor (dsp, cmap, &bg_color))
-           abort ();
-       }
-      fg_color.flags = DoRed|DoGreen|DoBlue;
-      bg_color.flags = DoRed|DoGreen|DoBlue;
-
-      rgb_to_hsv (fg_color.red, fg_color.green, fg_color.blue,
-                 &fg_h, &fg_s, &fg_v);
-      rgb_to_hsv (bg_color.red, bg_color.green, bg_color.blue,
-                 &bg_h, &bg_s, &bg_v);
-
-      if (/*mode == MODE_RANDOM &&*/
-         ((this_mode == MODE_S && (fg_s-bg_s) > -0.3 && (fg_s-bg_s) < 0.3) ||
-          (this_mode == MODE_V && (fg_v-bg_v) > -0.3 && (fg_v-bg_v) < 0.3) ||
-          (this_mode == MODE_H && (fg_h-bg_h) > -30 && (fg_h-bg_h) < 30)))
-       goto HSV_AGAIN;
-
-      switch (this_mode) {
-      case MODE_H:  shift = (bg_h - fg_h) / ncolors; break;
-      case MODE_S: dshift = (bg_s - fg_s) / ncolors; break;
-      case MODE_V: dshift = (bg_v - fg_v) / ncolors; break;
-      default: abort ();
+       colors = (XColor *) malloc (ncolors * sizeof(*colors));
+
+      cycle_direction = (random() & 1 ? 1 : -1);
+
+    RETRY_NON_WRITABLE:
+      {
+       int n = ncolors;
+       make_color_ramp (dpy, cmap,
+                        fg_h, fg_s, fg_v,
+                        bg_h, bg_s, bg_v,
+                        colors, &n,
+                        True, True, cycle_p);
+       if (n == 0 && cycle_p)
+         {
+           cycle_p = False;
+           goto RETRY_NON_WRITABLE;
+         }
+       ncolors = n;
       }
-      
-      if (mode == MODE_RANDOM &&
-         ((this_mode == MODE_H)
-          ? ((shift > -2 && shift < 2) || fg_s < 0.3 || fg_v < 0.3)
-          : (dshift > -0.005 && dshift < 0.005)))
-       goto HSV_AGAIN;
 
-      if (mode == MODE_RANDOM && this_mode == MODE_S && fg_v < 0.5)
-       goto V_AGAIN;
+      if (ncolors <= 0)
+       mono_p = 1;
+    }
 
-      for (npixels = 0; npixels < ncolors; npixels++)
+  if (mono_p)
+    {
+      static Bool done = False;
+      static XColor c[50];
+         colors = c;
+      cycle_p = False;
+      ncolors = sizeof(c)/sizeof(*c);
+      if (!done)
        {
-         if (cycle_p)
-           {
-             unsigned long plane_masks;
-             /* allocate the writable color cells, one at a time. */
-             if (! XAllocColorCells (dsp, cmap, False, &plane_masks, 0,
-                                     &fg_color.pixel, 1))
-               {
-                 fprintf (stderr,
-   "%s: couldn't allocate %s writable color cells.  Turning off -cycle.\n",
-                          progname, (npixels ? "enough" : "any"));
-                 cycle_p = 0;
-                 goto NON_CYCLE;
-               }
-             XStoreColor (dsp, cmap, &fg_color);
-           }
-         else
-           {
-           NON_CYCLE:
-             if (!XAllocColor (dsp, cmap, &fg_color))
-               break;
-           }
-         pixels[npixels] = fg_color.pixel;
-       
-         switch (this_mode)
-           {
-           case MODE_H: fg_h = (fg_h + shift) % 360; break;
-           case MODE_S: fg_s += dshift; break;
-           case MODE_V: fg_v += dshift; break;
-           default: abort ();
-           }
-         hsv_to_rgb (fg_h, fg_s, fg_v,
-                     &fg_color.red, &fg_color.green, &fg_color.blue);
+         int i;
+         done = True;
+         colors[0].pixel = fg_pixel;
+         for (i = 1; i < ncolors; i++)
+           colors[i].pixel = bg_pixel;
        }
     }
-  XSetForeground (dsp, gc, pixels [0]);
-  XFillRectangle (dsp, win, gc, 0, 0, wattrs.width, wattrs.height);
+
+  XSetForeground (dpy, gc, colors[1].pixel);
+  XFillRectangle (dpy, window, gc, 0, 0, xgwa.width, xgwa.height);
 }
 
 
-#define HEIGHT_TO_PIXEL(height) \
-       (((int) (height)) < 0 ? 0 : \
-        ((int) (height)) >= npixels ? npixels - 3 : ((int) (height)))
+#define HEIGHT_TO_PIXEL(height)                                \
+       ((height) < 0                                   \
+        ? (extra_krinkly_p                             \
+           ? ncolors - ((-(height)) % ncolors)         \
+           : 0)                                        \
+        : ((height) >= ncolors                         \
+           ? (extra_krinkly_p                          \
+              ? (height) % ncolors                     \
+              : ncolors-1)                             \
+           : (height)))
+
 
 static unsigned int
-set (l, c, size, height)
-     unsigned int l, c, size;
-     int height;
+set (unsigned int l,
+     unsigned int c,
+     unsigned int size,
+     int height)
 {
   int rang = 1 << (NSTEPS - size);
   height = height + (random () % rang) - rang / 2;
+  height = HEIGHT_TO_PIXEL(height);
   CELL (l, c) = height;
-
-  return pixels [HEIGHT_TO_PIXEL (height)];
+  return colors[height].pixel;
 }
 
 static void
-floyd_steinberg ()
+floyd_steinberg (Display *dpy, Window window)
 {
   int x, y, err;
 
@@ -244,11 +287,14 @@ floyd_steinberg ()
      don't use enormous amounts of memory.
    */
   XImage *image =
-    XCreateImage (disp, DefaultVisual(disp,DefaultScreen(disp)),
+    XCreateImage (dpy, xgwa.visual,
                  1, XYBitmap, 0,               /* depth, format, offset */
-                 (char *) calloc ((xmax + 1) / 8, 1),  /* data */
+                 (char *) calloc ((xmax + 8) / 8, 1),  /* data */
                  xmax, 1, 8, 0);               /* w, h, pad, bpl */
 
+  XSetForeground (dpy, gc, colors[0].pixel);
+  XSetBackground (dpy, gc, colors[1].pixel);
+
   for (y = 0; y < ymax - 1; y++)
     {
       for (x = 0; x < xmax - 1; x++)
@@ -268,80 +314,97 @@ floyd_steinberg ()
          CELL (x+1, y)   += (int) (((float) err) * 3.0/8.0);
          CELL (x+1, y+1) += (int) (((float) err) * 1.0/4.0);
        }
-      XPutImage (disp, wind, gc, image, 0, 0, 0, y, xmax, 1);
+      XPutImage (dpy, window, gc, image, 0, 0, 0, y, xmax, 1);
     }
   XDestroyImage (image);
 }
 
 static void
-draw (x, y, pixel, grid_size)  /* not called in mono mode */
-     int x, y, grid_size;
-     unsigned long pixel;
+draw (Display *dpy, Window window,
+      int x, int y, unsigned long pixel, int grid_size)
 {
   static unsigned int last_pixel, last_valid = 0;
   if (! (last_valid && pixel == last_pixel))
-    XSetForeground (disp, gc, pixel);
+    XSetForeground (dpy, gc, pixel);
   last_valid = 1, last_pixel = pixel;
   if (grid_size == 1)
-    XDrawPoint (disp, wind, gc, x, y);
+    XDrawPoint (dpy, window, gc, x, y);
   else
-    XFillRectangle (disp, wind, gc, x, y, grid_size, grid_size);
+    XFillRectangle (dpy, window, gc, x, y, grid_size, grid_size);
 }
 
 
 static void 
-drawmap ()
+draw_map (Display *dpy, Window window)
 {
-  unsigned int x, y, i, step, nextStep, x1, x2, y1, y2;
+  int xstep, ystep, xnextStep, ynextStep;
+  int x, y, i, x1, x2, y1, y2;
   unsigned int pixel, qpixels [4];
 
-  xmax = wattrs.width;
-  ymax = wattrs.height;
+  int backwards = random() & 1;
+
+  xmax = xgwa.width;
+  ymax = xgwa.height;
 
   cell = (signed char *) calloc (xmax * ymax, 1);
   if (cell == NULL)
     exit (1);
 
   CELL (0, 0) = 0;
-  step = COUNT;
+  xstep = (backwards ? -COUNT : COUNT);
+  ystep = COUNT;
   for (i = 0; i < iterations; i++)
     {
-      nextStep = step / 2;
-      for (x = 0; x < xmax; x += step)
+      xnextStep = xstep / 2;
+      ynextStep = ystep / 2;
+      for (x = (backwards ? xmax-1 : 0);
+          (backwards ? x >= 0 : x < xmax);
+          x += xstep)
        {
-         x1 = x + nextStep;
-         if (x1 >= xmax)
+         x1 = x + xnextStep;
+         if (x1 < 0)
+           x1 = xmax-1;
+         else if (x1 >= xmax)
            x1 = 0;
-         x2 = x + step;
-         if (x2 >= xmax)
+
+         x2 = x + xstep;
+         if (x2 < 0)
+           x2 = xmax-1;
+         else if (x2 >= xmax)
            x2 = 0;
-         for (y = 0; y < ymax; y += step)
+
+         for (y = 0; y < ymax; y += ystep)
            {
-             y1 = y + nextStep;
-             if (y1 >= ymax)
+             y1 = y + ynextStep;
+             if (y1 < 0)
+               y1 = ymax-1;
+             else if (y1 >= ymax)
                y1 = 0;
-             y2 = y + step;
-             if (y2 >= ymax)
+
+             y2 = y + ystep;
+             if (y2 < 0)
+               y2 = ymax-1;
+             else if (y2 >= ymax)
                y2 = 0;
 
-             qpixels [0] = pixels [HEIGHT_TO_PIXEL (CELL (x, y))];
-             qpixels [1] = pixels [HEIGHT_TO_PIXEL (CELL (x, y2))];
-             qpixels [2] = pixels [HEIGHT_TO_PIXEL (CELL (x2, y))];
-             qpixels [3] = pixels [HEIGHT_TO_PIXEL (CELL (x2, y2))];
+             qpixels [0] = colors [HEIGHT_TO_PIXEL (CELL (x, y))].pixel;
+             qpixels [1] = colors [HEIGHT_TO_PIXEL (CELL (x, y2))].pixel;
+             qpixels [2] = colors [HEIGHT_TO_PIXEL (CELL (x2, y))].pixel;
+             qpixels [3] = colors [HEIGHT_TO_PIXEL (CELL (x2, y2))].pixel;
 
              pixel = set (x, y1, i,
                           ((int) CELL (x, y) + (int) CELL (x, y2) + 1) / 2);
              if (! mono_p &&
                  (pixel != qpixels[0] || pixel != qpixels[1] || 
                   pixel != qpixels[2] || pixel != qpixels[3]))
-               draw (x, y1, pixel, nextStep);
+               draw (dpy, window, x, y1, pixel, ynextStep);
 
              pixel = set (x1, y, i,
                           ((int) CELL (x, y) + (int) CELL (x2, y) + 1) / 2);
              if (! mono_p &&
                  (pixel != qpixels[0] || pixel != qpixels[1] || 
                   pixel != qpixels[2] || pixel != qpixels[3]))
-               draw (x1, y, pixel, nextStep);
+               draw (dpy, window, x1, y, pixel, ynextStep);
 
              pixel = set (x1, y1, i,
                           ((int) CELL (x, y) + (int) CELL (x, y2) +
@@ -350,56 +413,55 @@ drawmap ()
              if (! mono_p &&
                  (pixel != qpixels[0] || pixel != qpixels[1] || 
                   pixel != qpixels[2] || pixel != qpixels[3]))
-               draw (x1, y1, pixel, nextStep);
+               draw (dpy, window, x1, y1, pixel, ynextStep);
+
+
+             if (cycle_p)
+               {
+                 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,
+                                    cycle_direction);
+                     then = now;
+                   }
+               }
            }
        }
-      step = nextStep;
+      xstep = xnextStep;
+      ystep = ynextStep;
       if (!mono_p)
-       XSync (disp, True);
+       XSync (dpy, False);
+      screenhack_handle_events (dpy);
     }
   if (mono_p)
     /* in mono-mode, we do all the drawing at the end */
-    floyd_steinberg ();
+    floyd_steinberg (dpy, window);
   
   free (cell);
-  XSync (disp, True);
-}
-
-static void
-cycle (dpy)
-     Display *dpy;
-{
-  XColor *colors = malloc (npixels * sizeof (XColor));
-  time_t stop;
-  int i;
-  for (i = 0; i < npixels; i++)
-    colors [i].pixel = pixels [i];
-  XQueryColors (dpy, cmap, colors, npixels);
-  stop = (time_t) ((time ((time_t) 0)) + timeout);
-  while (stop >= (time_t) time ((time_t) 0))
-    {
-      unsigned long scratch = colors [npixels-1].pixel;
-      for (i = npixels-1; i > 0; i--)
-       colors [i].pixel = colors [i-1].pixel;
-      colors [0].pixel = scratch;
-      XStoreColors (dpy, cmap, colors, npixels);
-      XSync (dpy, True);
-      if (cycle_delay) usleep (cycle_delay);
-    }
-  XSync (dpy, True);
-  free (colors);
+  XSync (dpy, False);
 }
 
 
 char *progclass = "Imsmap";
 
 char *defaults [] = {
-  "*background:        black",
-  "*foreground:        black",
+  ".background:        black",
+  ".foreground:        black",
   "*mode:      random",
   "*ncolors:   50",
   "*iterations:        7",
-  "*timeout:   10",
+  "*delay:     10",
   "*cycleDelay:        100000",
   "*cycle:     true",
   0
@@ -407,33 +469,41 @@ char *defaults [] = {
 
 XrmOptionDescRec options [] = {
   { "-ncolors",                ".ncolors",     XrmoptionSepArg, 0 },
-  { "-timeout",                ".timeout",     XrmoptionSepArg, 0 },
+  { "-delay",          ".delay",       XrmoptionSepArg, 0 },
   { "-cycle-delay",    ".cycleDelay",  XrmoptionSepArg, 0 },
   { "-mode",           ".mode",        XrmoptionSepArg, 0 },
   { "-iterations",     ".iterations",  XrmoptionSepArg, 0 },
   { "-cycle",          ".cycle",       XrmoptionNoArg, "True"  },
-  { "-no-cycle",       ".cycle",       XrmoptionNoArg, "False" }
+  { "-no-cycle",       ".cycle",       XrmoptionNoArg, "False" },
+  { 0, 0, 0, 0 }
 };
-int options_size = (sizeof (options) / sizeof (options[0]));
 
 
 void
-screenhack (dpy, window)
-     Display *dpy;
-     Window window;
+screenhack (Display *dpy, Window window)
 {
-    disp = dpy;
-    wind = window;
     while (1)
       {
-       initwin (dpy, window);
-       drawmap ();
-       if (timeout)
+       init_map (dpy, window);
+       draw_map (dpy, window);
+       if (delay)
          {
            if (cycle_p)
-             cycle (dpy);
+             {
+               time_t start = time((time_t) 0);
+               while (start + delay > time((time_t) 0))
+                 {
+                   rotate_colors (dpy, cmap, colors, ncolors,
+                                  cycle_direction);
+                   if (cycle_delay) usleep(cycle_delay);
+                    screenhack_handle_events (dpy);
+                 }
+             }
            else
-             sleep (timeout);
+              {
+                screenhack_handle_events (dpy);
+                sleep (delay);
+              }
          }
       }
 }