-/* imsmap, Copyright (c) 1992 Juergen Nickelsen <nickel@cs.tu-berlin.de>
+/* imsmap, Copyright (c) 1992-2008 Juergen Nickelsen and Jamie Zawinski.
* Derived from code by Markus Schirmer, TU Berlin.
*
* Permission to use, copy, modify, distribute, and sell this software and its
#include <stdio.h>
#include <math.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 imsmap_mode { MODE_H, MODE_S, MODE_V, MODE_RANDOM } mode;
-
-static GC gc, gc2;
-static XWindowAttributes xgwa;
+#define CELL(c, r) st->cell[((unsigned int)(c)) + ((unsigned int) (r)) * st->xmax]
#if defined(sun) && !__STDC__ /* sun cc doesn't know "signed char" */
#define signed /**/
#endif
-static Colormap cmap;
-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
-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 imsmap_mode this_mode;
- static Bool rv_p;
-
- XGCValues gcv;
-
- XGetWindowAttributes (dpy, window, &xgwa);
- cmap = xgwa.colormap;
-
- if (!ncolors)
- {
- char *mode_str = get_string_resource ("mode", "Mode");
- rv_p = get_boolean_resource ("reverseVideo", "ReverseVideo");
- cycle_p = get_boolean_resource ("cycle", "Cycle");
- ncolors = get_integer_resource ("ncolors", "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;
-
- if (ncolors <= 2) ncolors = 0;
- if (ncolors == 0) mono_p = True;
-
- 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 (dpy, window, GCForeground|GCBackground, &gcv);
- gcv.foreground = bg_pixel;
- gc2 = XCreateGC (dpy, window, GCForeground, &gcv);
-
- if (!mode_str || !strcmp (mode_str, "random"))
- mode = MODE_RANDOM;
- else if (!strcmp (mode_str, "h") || !strcmp (mode_str, "hue"))
- mode = MODE_H;
- else if (!strcmp (mode_str, "s") || !strcmp (mode_str, "saturation"))
- mode = MODE_S;
- else if (!strcmp (mode_str, "v") || !strcmp (mode_str, "value"))
- mode = MODE_V;
- else
- {
- fprintf (stderr,
- "%s: mode must be hue, saturation, value, or random, not \"%s\"\n",
- progname, mode_str);
- mode = MODE_RANDOM;
- }
- }
-
- this_mode = mode;
- if (!mono_p && mode == MODE_RANDOM)
- 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;
- }
+struct state {
+ Display *dpy;
+ Window window;
+ Colormap cmap;
+ int ncolors;
+ XColor *colors;
+ Bool extra_krinkly_p;
- if (mono_p)
- extra_krinkly_p = !(random() % 15);
- else
- extra_krinkly_p = !(random() % 5);
+ int delay, delay2;
+ signed char *cell;
+ int xmax, ymax;
+ int iteration, iterations;
- if (!mono_p)
- {
- double distance, fg_H, bg_H, dh;
-
- 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)
- {
- 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;
- }
+ int cx, xstep, ystep, xnextStep, ynextStep;
- cycle_p = True;
- if (colors)
- free_colors (dpy, cmap, colors, ncolors);
- else
- 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 (ncolors <= 0)
- mono_p = 1;
- }
+ unsigned int last_pixel, last_valid;
+ int flip_x;
+ int flip_xy;
- if (mono_p)
- {
- static Bool done = False;
- static XColor c[50];
- colors = c;
- cycle_p = False;
- ncolors = sizeof(c)/sizeof(*c);
- if (!done)
- {
- int i;
- done = True;
- colors[0].pixel = fg_pixel;
- for (i = 1; i < ncolors; i++)
- colors[i].pixel = bg_pixel;
- }
- }
+ GC gc, gc2;
+ XWindowAttributes xgwa;
- XSetForeground (dpy, gc, colors[1].pixel);
- XFillRectangle (dpy, window, gc, 0, 0, xgwa.width, xgwa.height);
-}
+ struct timeval then;
+};
-#define HEIGHT_TO_PIXEL(height) \
- ((height) < 0 \
- ? (extra_krinkly_p \
- ? ncolors - ((-(height)) % ncolors) \
- : 0) \
- : ((height) >= ncolors \
- ? (extra_krinkly_p \
- ? (height) % ncolors \
- : ncolors-1) \
+#define HEIGHT_TO_PIXEL(height) \
+ ((height) < 0 \
+ ? (st->extra_krinkly_p \
+ ? st->ncolors - 1 - ((-(height)) % st->ncolors) \
+ : 0) \
+ : ((height) >= st->ncolors \
+ ? (st->extra_krinkly_p \
+ ? (height) % st->ncolors \
+ : st->ncolors-1) \
: (height)))
static unsigned int
-set (unsigned int l,
+set (struct state *st,
+ unsigned int l,
unsigned int c,
unsigned int size,
int height)
height = height + (random () % rang) - rang / 2;
height = HEIGHT_TO_PIXEL(height);
CELL (l, c) = height;
- return colors[height].pixel;
+ return st->colors[height].pixel;
}
+
static void
-floyd_steinberg (Display *dpy, Window window)
+floyd_steinberg (struct state *st)
{
int x, y, err;
don't use enormous amounts of memory.
*/
XImage *image =
- XCreateImage (dpy, xgwa.visual,
+ XCreateImage (st->dpy, st->xgwa.visual,
1, XYBitmap, 0, /* depth, format, offset */
- (char *) calloc ((xmax + 8) / 8, 1), /* data */
- xmax, 1, 8, 0); /* w, h, pad, bpl */
+ (char *) calloc ((st->xmax + 8) / 8, 1), /* data */
+ st->xmax, 1, 8, 0); /* w, h, pad, bpl */
- XSetForeground (dpy, gc, colors[0].pixel);
- XSetBackground (dpy, gc, colors[1].pixel);
+ XSetForeground (st->dpy, st->gc, st->colors[0].pixel);
+ XSetBackground (st->dpy, st->gc, st->colors[1].pixel);
- for (y = 0; y < ymax - 1; y++)
+ for (y = 0; y < st->ymax - 1; y++)
{
- for (x = 0; x < xmax - 1; x++)
+ for (x = 0; x < st->xmax - 1; x++)
{
if (CELL(x, y) < 0)
{
CELL (x+1, y) += (int) (((float) err) * 3.0/8.0);
CELL (x+1, y+1) += (int) (((float) err) * 1.0/4.0);
}
- XPutImage (dpy, window, gc, image, 0, 0, 0, y, xmax, 1);
+ XPutImage (st->dpy, st->window, st->gc, image, 0, 0, 0, y, st->xmax, 1);
}
XDestroyImage (image);
}
+
static void
-draw (Display *dpy, Window window,
+draw (struct state *st,
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 (dpy, gc, pixel);
- last_valid = 1, last_pixel = pixel;
+ if (st->flip_x)
+ x = st->xmax - x;
+
+ if (st->flip_xy)
+ {
+ int swap = x;
+ x = y;
+ y = swap;
+ }
+
+ if (! (st->last_valid && pixel == st->last_pixel))
+ XSetForeground (st->dpy, st->gc, pixel);
+ st->last_valid = 1, st->last_pixel = pixel;
if (grid_size == 1)
- XDrawPoint (dpy, window, gc, x, y);
+ XDrawPoint (st->dpy, st->window, st->gc, x, y);
else
- XFillRectangle (dpy, window, gc, x, y, grid_size, grid_size);
+ XFillRectangle (st->dpy, st->window, st->gc, x, y, grid_size, grid_size);
}
-static void
-draw_map (Display *dpy, Window window)
+static void
+init_map (struct state *st)
{
- int xstep, ystep, xnextStep, ynextStep;
- int x, y, i, x1, x2, y1, y2;
- unsigned int pixel, qpixels [4];
+ XGCValues gcv;
- int backwards = random() & 1;
+ XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+ st->cmap = st->xgwa.colormap;
- xmax = xgwa.width;
- ymax = xgwa.height;
+ st->flip_x = (random() % 2);
+ st->flip_xy = (random() % 2);
- cell = (signed char *) calloc (xmax * ymax, 1);
- if (cell == NULL)
- exit (1);
+ if (mono_p)
+ st->flip_xy = 0;
+ else if (st->colors)
+ free_colors (st->dpy, st->cmap, st->colors, st->ncolors);
+ st->colors = 0;
- CELL (0, 0) = 0;
- xstep = (backwards ? -COUNT : COUNT);
- ystep = COUNT;
- for (i = 0; i < iterations; i++)
+ st->ncolors = get_integer_resource (st->dpy, "ncolors", "Integer");
+ st->delay = get_integer_resource (st->dpy, "delay", "Integer");
+ st->delay2 = get_integer_resource (st->dpy, "delay2", "Integer");
+ st->iterations = get_integer_resource (st->dpy, "iterations", "Integer");
+ if (st->iterations < 0) st->iterations = 0;
+ else if (st->iterations > 7) st->iterations = 7;
+
+ if (st->ncolors <= 2) st->ncolors = 0;
+ if (st->ncolors == 0) mono_p = True;
+ if (st->ncolors > 255) st->ncolors = 255; /* too many look bad */
+
+ if (!st->gc) st->gc = XCreateGC (st->dpy, st->window, 0, &gcv);
+ if (!st->gc2) st->gc2 = XCreateGC (st->dpy, st->window, 0, &gcv);
+
+ if (mono_p)
+ st->extra_krinkly_p = !(random() % 15);
+ else
+ st->extra_krinkly_p = !(random() % 5);
+
+ if (!mono_p)
{
- xnextStep = xstep / 2;
- ynextStep = ystep / 2;
- for (x = (backwards ? xmax-1 : 0);
- (backwards ? x >= 0 : x < xmax);
- x += xstep)
- {
- x1 = x + xnextStep;
- if (x1 < 0)
- x1 = xmax-1;
- else if (x1 >= xmax)
- x1 = 0;
-
- x2 = x + xstep;
- if (x2 < 0)
- x2 = xmax-1;
- else if (x2 >= xmax)
- x2 = 0;
-
- for (y = 0; y < ymax; y += ystep)
- {
- y1 = y + ynextStep;
- if (y1 < 0)
- y1 = ymax-1;
- else if (y1 >= ymax)
- y1 = 0;
-
- y2 = y + ystep;
- if (y2 < 0)
- y2 = ymax-1;
- else if (y2 >= ymax)
- y2 = 0;
-
- 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 (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 (dpy, window, x1, y, pixel, ynextStep);
-
- pixel = set (x1, y1, i,
- ((int) CELL (x, y) + (int) CELL (x, y2) +
- (int) CELL (x2, y) + (int) CELL (x2, y2) + 2)
- / 4);
- if (! mono_p &&
- (pixel != qpixels[0] || pixel != qpixels[1] ||
- pixel != qpixels[2] || pixel != qpixels[3]))
- draw (dpy, window, x1, y1, pixel, ynextStep);
-
-
- if (cycle_p)
- {
- struct timeval now;
- static struct timeval then = { 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;
- }
- }
- }
- }
- xstep = xnextStep;
- ystep = ynextStep;
- if (!mono_p)
- XSync (dpy, False);
- screenhack_handle_events (dpy);
+ st->colors = (XColor *) malloc (st->ncolors * sizeof(*st->colors));
+
+ make_smooth_colormap (st->dpy, st->xgwa.visual, st->cmap,
+ st->colors, &st->ncolors,
+ True, 0, False);
+ if (st->ncolors <= 2)
+ mono_p = 1;
}
+
if (mono_p)
- /* in mono-mode, we do all the drawing at the end */
- floyd_steinberg (dpy, window);
-
- free (cell);
- XSync (dpy, False);
+ {
+ int i;
+ unsigned long fg_pixel =
+ get_pixel_resource (st->dpy, st->xgwa.colormap,
+ "foreground", "Foreground");
+ unsigned long bg_pixel =
+ get_pixel_resource (st->dpy, st->xgwa.colormap,
+ "background", "Background");
+ if (!st->colors)
+ {
+ st->ncolors = 50;
+ st->colors = (XColor *) calloc (st->ncolors, sizeof(*st->colors));
+ }
+ st->colors[0].pixel = fg_pixel;
+ for (i = 1; i < st->ncolors; i++)
+ st->colors[i].pixel = bg_pixel;
+ }
+
+ XSetForeground (st->dpy, st->gc, st->colors[1].pixel);
+ XFillRectangle (st->dpy, st->window, st->gc, 0, 0,
+ st->xgwa.width, st->xgwa.height);
+
+ if (st->flip_xy)
+ {
+ st->xmax = st->xgwa.height;
+ st->ymax = st->xgwa.width;
+ }
+ else
+ {
+ st->xmax = st->xgwa.width;
+ st->ymax = st->xgwa.height;
+ }
+
+ if (st->cell) free (st->cell);
+ st->cell = (signed char *) calloc (st->xmax * st->ymax, 1);
+
+ CELL (0, 0) = 0;
+ st->xstep = COUNT;
+ st->ystep = COUNT;
+
+ st->iteration = 0;
+ st->cx = 0;
+}
+
+
+static void *
+imsmap_init (Display *dpy, Window window)
+{
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
+ st->dpy = dpy;
+ st->window = window;
+ init_map (st);
+ return st;
}
-char *progclass = "Imsmap";
+static unsigned long
+imsmap_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ int this_delay = st->delay2;
+ int i;
+
+ /* do this many lines at a time without pausing */
+ int col_chunk = st->iteration * 2 + 1;
+
+ if (st->iteration > st->iterations)
+ init_map (st);
+
+ if (st->cx == 0)
+ {
+ st->xnextStep = st->xstep / 2;
+ st->ynextStep = st->ystep / 2;
+ }
+
+ for (i = 0; i < col_chunk; i++)
+ {
+ int x1, x2, y1, y2;
+ int y;
+ int x = st->cx;
+
+ x1 = x + st->xnextStep;
+ if (x1 < 0)
+ x1 = st->xmax-1;
+ else if (x1 >= st->xmax)
+ x1 = 0;
+
+ x2 = x + st->xstep;
+ if (x2 < 0)
+ x2 = st->xmax-1;
+ else if (x2 >= st->xmax)
+ x2 = 0;
+
+ for (y = 0; y < st->ymax; y += st->ystep)
+ {
+ unsigned int pixel, qpixels [4];
+
+ y1 = y + st->ynextStep;
+ if (y1 < 0)
+ y1 = st->ymax-1;
+ else if (y1 >= st->ymax)
+ y1 = 0;
+
+ y2 = y + st->ystep;
+ if (y2 < 0)
+ y2 = st->ymax-1;
+ else if (y2 >= st->ymax)
+ y2 = 0;
+
+ qpixels [0] = st->colors [HEIGHT_TO_PIXEL (CELL (x, y))].pixel;
+ qpixels [1] = st->colors [HEIGHT_TO_PIXEL (CELL (x, y2))].pixel;
+ qpixels [2] = st->colors [HEIGHT_TO_PIXEL (CELL (x2, y))].pixel;
+ qpixels [3] = st->colors [HEIGHT_TO_PIXEL (CELL (x2, y2))].pixel;
+
+ pixel = set (st, x, y1, st->iteration,
+ ((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 (st, x, y1, pixel, st->ynextStep);
+
+ pixel = set (st, x1, y, st->iteration,
+ ((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 (st, x1, y, pixel, st->ynextStep);
+
+ pixel = set (st, x1, y1, st->iteration,
+ ((int) CELL (x, y) + (int) CELL (x, y2) +
+ (int) CELL (x2, y) + (int) CELL (x2, y2) + 2)
+ / 4);
+ if (! mono_p &&
+ (pixel != qpixels[0] || pixel != qpixels[1] ||
+ pixel != qpixels[2] || pixel != qpixels[3]))
+ draw (st, x1, y1, pixel, st->ynextStep);
+ }
+
+ st->cx += st->xstep;
+ if (st->cx >= st->xmax)
+ break;
+ }
-char *defaults [] = {
- ".background: black",
- ".foreground: black",
+ if (st->cx >= st->xmax)
+ {
+ st->cx = 0;
+ st->xstep = st->xnextStep;
+ st->ystep = st->ynextStep;
+
+ st->iteration++;
+
+ if (st->iteration > st->iterations)
+ this_delay = st->delay * 1000000;
+
+ if (mono_p)
+ floyd_steinberg (st); /* in mono, do all drawing at the end */
+ }
+
+ return this_delay;
+}
+
+
+static void
+imsmap_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
+{
+ struct state *st = (struct state *) closure;
+ init_map (st);
+}
+
+
+static Bool
+imsmap_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+ struct state *st = (struct state *) closure;
+ if (event->xany.type == ButtonPress)
+ {
+ init_map (st);
+ return True;
+ }
+
+ return False;
+}
+
+
+static void
+imsmap_free (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ if (st->colors) free (st->colors);
+ if (st->cell) free (st->cell);
+ free (st);
+}
+
+
+static const char *imsmap_defaults [] = {
+ ".background: #000066",
+ ".foreground: #FF00FF",
+ "*fpsSolid: true",
"*mode: random",
"*ncolors: 50",
"*iterations: 7",
- "*delay: 10",
- "*cycleDelay: 100000",
- "*cycle: true",
+ "*delay: 5",
+ "*delay2: 20000",
0
};
-XrmOptionDescRec options [] = {
+static XrmOptionDescRec imsmap_options [] = {
{ "-ncolors", ".ncolors", XrmoptionSepArg, 0 },
{ "-delay", ".delay", XrmoptionSepArg, 0 },
- { "-cycle-delay", ".cycleDelay", XrmoptionSepArg, 0 },
+ { "-delay2", ".delay2", XrmoptionSepArg, 0 },
{ "-mode", ".mode", XrmoptionSepArg, 0 },
{ "-iterations", ".iterations", XrmoptionSepArg, 0 },
- { "-cycle", ".cycle", XrmoptionNoArg, "True" },
- { "-no-cycle", ".cycle", XrmoptionNoArg, "False" },
{ 0, 0, 0, 0 }
};
-
-void
-screenhack (Display *dpy, Window window)
-{
- while (1)
- {
- init_map (dpy, window);
- draw_map (dpy, window);
- if (delay)
- {
- if (cycle_p)
- {
- 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
- {
- screenhack_handle_events (dpy);
- sleep (delay);
- }
- }
- }
-}
+XSCREENSAVER_MODULE ("IMSMap", imsmap)