-/* xscreensaver, Copyright (c) 1997, 1998 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1997, 1998, 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>
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
# include "xdbe.h"
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-static int ncolors;
-static XColor *colors = 0;
-static int fg_pixel, bg_pixel;
-static Pixmap p0 = 0, p1 = 0, p2 = 0, p3 = 0;
-static GC copy_gc = 0, erase_gc = 0, window_gc = 0;
-static int width, height, size;
-static int x1, x2, y1, y2, x3, y3;
-static int dx1, dx2, dx3, dy1, dy2, dy3;
-static int othickness, thickness;
-static Bool do_three;
+struct state {
+ Display *dpy;
+ Window window;
+
+ int ncolors;
+ XColor *colors;
+ int fg_pixel, bg_pixel;
+ Pixmap p0, p1, p2, p3;
+ GC copy_gc, erase_gc, window_gc;
+ int width, height, size;
+ int x1, x2, y1, y2, x3, y3;
+ int dx1, dx2, dx3, dy1, dy2, dy3;
+ int othickness, thickness;
+ Bool do_three;
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-XdbeBackBuffer back_buf = 0;
+ XdbeBackBuffer back_buf;
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+ Bool flip_a, flip_b;
+ int pix;
+ int delay, color_shift;
+
+ int reset;
+ int iterations, iteration;
+};
+
static void
-init_moire2 (Display *dpy, Window window)
+moire2_init_1 (struct state *st)
{
XWindowAttributes xgwa;
- XGetWindowAttributes (dpy, window, &xgwa);
+ XGetWindowAttributes (st->dpy, st->window, &xgwa);
- othickness = get_integer_resource("thickness", "Thickness");
+ st->othickness = get_integer_resource(st->dpy, "thickness", "Thickness");
if (mono_p)
- ncolors = 2;
+ st->ncolors = 2;
else
- 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));
+ st->colors = (XColor *) malloc(sizeof(*st->colors) * (st->ncolors+1));
if (mono_p)
;
else
- make_smooth_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors,
+ make_smooth_colormap (st->dpy, xgwa.visual, xgwa.colormap, st->colors, &st->ncolors,
True, 0, True);
- bg_pixel = get_pixel_resource("background", "Background", dpy,
- xgwa.colormap);
- fg_pixel = get_pixel_resource("foreground", "Foreground", dpy,
- xgwa.colormap);
+ st->bg_pixel = get_pixel_resource(st->dpy,
+ xgwa.colormap, "background", "Background");
+ st->fg_pixel = get_pixel_resource(st->dpy,
+ xgwa.colormap, "foreground", "Foreground");
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
- back_buf = xdbe_get_backbuffer (dpy, window, XdbeUndefined);
+ st->back_buf = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined);
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
}
static void
-reset_moire2 (Display *dpy, Window window)
+reset_moire2 (struct state *st)
{
GC gc;
XWindowAttributes xgwa;
XGCValues gcv;
Bool xor;
- XGetWindowAttributes (dpy, window, &xgwa);
+ XGetWindowAttributes (st->dpy, st->window, &xgwa);
- do_three = (0 == (random() % 3));
+ st->do_three = (0 == (random() % 3));
- width = xgwa.width;
- height = xgwa.height;
- size = width > height ? width : height;
+ st->width = xgwa.width;
+ st->height = xgwa.height;
+ st->size = st->width > st->height ? st->width : st->height;
- if (p0) XFreePixmap(dpy, p0);
- if (p1) XFreePixmap(dpy, p1);
- if (p2) XFreePixmap(dpy, p2);
- if (p3) XFreePixmap(dpy, p3);
+ if (st->p0) XFreePixmap(st->dpy, st->p0);
+ if (st->p1) XFreePixmap(st->dpy, st->p1);
+ if (st->p2) XFreePixmap(st->dpy, st->p2);
+ if (st->p3) XFreePixmap(st->dpy, st->p3);
- p0 = XCreatePixmap(dpy, window, width, height, 1);
- p1 = XCreatePixmap(dpy, window, width*2, height*2, 1);
- p2 = XCreatePixmap(dpy, window, width*2, height*2, 1);
- if (do_three)
- p3 = XCreatePixmap(dpy, window, width*2, height*2, 1);
+ st->p0 = XCreatePixmap(st->dpy, st->window, st->width, st->height, 1);
+ st->p1 = XCreatePixmap(st->dpy, st->window, st->width*2, st->height*2, 1);
+ st->p2 = XCreatePixmap(st->dpy, st->window, st->width*2, st->height*2, 1);
+ if (st->do_three)
+ st->p3 = XCreatePixmap(st->dpy, st->window, st->width*2, st->height*2, 1);
else
- p3 = 0;
+ st->p3 = 0;
- thickness = (othickness > 0 ? othickness : (1 + (random() % 4)));
+ st->thickness = (st->othickness > 0 ? st->othickness : (1 + (random() % 4)));
gcv.foreground = 0;
- gcv.line_width = (thickness == 1 ? 0 : thickness);
- gc = XCreateGC (dpy, p1, GCForeground|GCLineWidth, &gcv);
+ gcv.line_width = (st->thickness == 1 ? 0 : st->thickness);
+ gc = XCreateGC (st->dpy, st->p1, GCForeground|GCLineWidth, &gcv);
- XFillRectangle(dpy, p1, gc, 0, 0, width*2, height*2);
- XFillRectangle(dpy, p2, gc, 0, 0, width*2, height*2);
- if (do_three)
- XFillRectangle(dpy, p3, gc, 0, 0, width*2, height*2);
+ XFillRectangle(st->dpy, st->p1, gc, 0, 0, st->width*2, st->height*2);
+ XFillRectangle(st->dpy, st->p2, gc, 0, 0, st->width*2, st->height*2);
+ if (st->do_three)
+ XFillRectangle(st->dpy, st->p3, gc, 0, 0, st->width*2, st->height*2);
- XSetForeground(dpy, gc, 1);
+ XSetForeground(st->dpy, gc, 1);
- xor = (do_three || (thickness == 1) || (random() & 1));
+ xor = (st->do_three || (st->thickness == 1) || (random() & 1));
{
int i, ii, maxx, maxy;
#define FROB(P) do { \
- maxx = (size*4); \
- maxy = (size*4); \
+ maxx = (st->size*4); \
+ maxy = (st->size*4); \
if (0 == (random() % 5)) { \
float f = 1.0 + frand(0.05); \
if (random() & 1) maxx *= f; \
else maxy *= f; \
} \
- ii = (thickness + 1 + (xor ? 0 : 1) + (random() % (4 * thickness))); \
- for (i = 0; i < (size*2); i += ii) \
- XDrawArc(dpy, (P), gc, i-size, i-size, maxx-i-i, maxy-i-i, 0, 360*64); \
+ ii = (st->thickness + 1 + (xor ? 0 : 1) + (random() % (4 * st->thickness))); \
+ for (i = 0; i < (st->size*2); i += ii) \
+ XDrawArc(st->dpy, (P), gc, i-st->size, i-st->size, maxx-i-i, maxy-i-i, 0, 360*64); \
if (0 == (random() % 5)) \
{ \
- XSetFunction(dpy, gc, GXxor); \
- XFillRectangle(dpy, (P), gc, 0, 0, width*2, height*2); \
- XSetFunction(dpy, gc, GXcopy); \
+ XSetFunction(st->dpy, gc, GXxor); \
+ XFillRectangle(st->dpy, (P), gc, 0, 0, st->width*2, st->height*2); \
+ XSetFunction(st->dpy, gc, GXcopy); \
} \
} while(0)
- FROB(p1);
- FROB(p2);
- if (do_three)
- FROB(p3);
+ FROB(st->p1);
+ FROB(st->p2);
+ if (st->do_three)
+ FROB(st->p3);
#undef FROB
}
- XFreeGC(dpy, gc);
+ XFreeGC(st->dpy, gc);
- if (copy_gc) XFreeGC(dpy, copy_gc);
+ if (st->copy_gc) XFreeGC(st->dpy, st->copy_gc);
gcv.function = (xor ? GXxor : GXor);
gcv.foreground = 1;
gcv.background = 0;
- copy_gc = XCreateGC (dpy, p0, GCFunction|GCForeground|GCBackground, &gcv);
+ st->copy_gc = XCreateGC (st->dpy, st->p0, GCFunction|GCForeground|GCBackground, &gcv);
gcv.foreground = 0;
- if (erase_gc) XFreeGC(dpy, erase_gc);
- erase_gc = XCreateGC (dpy, p0, GCForeground, &gcv);
+ if (st->erase_gc) XFreeGC(st->dpy, st->erase_gc);
+ st->erase_gc = XCreateGC (st->dpy, st->p0, GCForeground, &gcv);
- gcv.foreground = fg_pixel;
- gcv.background = bg_pixel;
- if (window_gc) XFreeGC(dpy, window_gc);
- window_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
+ gcv.foreground = st->fg_pixel;
+ gcv.background = st->bg_pixel;
+ if (st->window_gc) XFreeGC(st->dpy, st->window_gc);
+ st->window_gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
#define FROB(N,DN,MAX) \
N = (MAX/2) + (random() % MAX); \
- DN = ((1 + (random() % (7*thickness))) * ((random() & 1) ? 1 : -1))
-
- FROB(x1,dx1,width);
- FROB(x2,dx2,width);
- FROB(x3,dx3,width);
- FROB(y1,dy1,height);
- FROB(y2,dy2,height);
- FROB(y3,dy3,height);
+ DN = ((1 + (random() % (7*st->thickness))) * ((random() & 1) ? 1 : -1))
+
+ FROB(st->x1,st->dx1,st->width);
+ FROB(st->x2,st->dx2,st->width);
+ FROB(st->x3,st->dx3,st->width);
+ FROB(st->y1,st->dy1,st->height);
+ FROB(st->y2,st->dy2,st->height);
+ FROB(st->y3,st->dy3,st->height);
#undef FROB
}
static void
-moire2 (Display *dpy, Window window)
+moire2 (struct state *st)
{
#define FROB(N,DN,MAX) \
N += DN; \
else if (0 == (random() % 50)) \
DN += (DN <= -20 ? 1 : (DN >= 20 ? -1 : ((random() & 1) ? 1 : -1)))
- FROB(x1,dx1,width);
- FROB(x2,dx2,width);
- FROB(x3,dx3,width);
- FROB(y1,dy1,height);
- FROB(y2,dy2,height);
- FROB(y3,dy3,height);
+ FROB(st->x1,st->dx1,st->width);
+ FROB(st->x2,st->dx2,st->width);
+ FROB(st->x3,st->dx3,st->width);
+ FROB(st->y1,st->dy1,st->height);
+ FROB(st->y2,st->dy2,st->height);
+ FROB(st->y3,st->dy3,st->height);
#undef FROB
- XFillRectangle(dpy, p0, erase_gc, 0, 0, width, height);
- XCopyArea(dpy, p1, p0, copy_gc, x1, y1, width, height, 0, 0);
- XCopyArea(dpy, p2, p0, copy_gc, x2, y2, width, height, 0, 0);
- if (do_three)
- XCopyArea(dpy, p3, p0, copy_gc, x3, y3, width, height, 0, 0);
+ XFillRectangle(st->dpy, st->p0, st->erase_gc, 0, 0, st->width, st->height);
+ XCopyArea(st->dpy, st->p1, st->p0, st->copy_gc, st->x1, st->y1, st->width, st->height, 0, 0);
+ XCopyArea(st->dpy, st->p2, st->p0, st->copy_gc, st->x2, st->y2, st->width, st->height, 0, 0);
+ if (st->do_three)
+ XCopyArea(st->dpy, st->p3, st->p0, st->copy_gc, st->x3, st->y3, st->width, st->height, 0, 0);
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
- if (back_buf)
+ if (st->back_buf)
{
XdbeSwapInfo info[1];
- info[0].swap_window = window;
+ info[0].swap_window = st->window;
info[0].swap_action = XdbeUndefined;
- XCopyPlane (dpy, p0, back_buf, window_gc, 0, 0, width, height, 0, 0, 1L);
- XdbeSwapBuffers (dpy, info, 1);
+ XCopyPlane (st->dpy, st->p0, st->back_buf, st->window_gc, 0, 0, st->width, st->height, 0, 0, 1L);
+ XdbeSwapBuffers (st->dpy, info, 1);
}
else
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
- XCopyPlane (dpy, p0, window, window_gc, 0, 0, width, height, 0, 0, 1L);
-
- XSync(dpy, False);
+ XCopyPlane (st->dpy, st->p0, st->window, st->window_gc, 0, 0, st->width, st->height, 0, 0, 1L);
#if 0
- XCopyPlane(dpy, p1, window, window_gc, (width*2)/3, (height*2)/3,
- width/2, height/2,
- 0, height/2, 1L);
- XCopyPlane(dpy, p2, window, window_gc, (width*2)/3, (height*2)/3,
- width/2, height/2,
- width/2, height/2, 1L);
+ XCopyPlane(st->dpy, st->p1, st->window, st->window_gc, (st->width*2)/3, (st->height*2)/3,
+ st->width/2, st->height/2,
+ 0, st->height/2, 1L);
+ XCopyPlane(st->dpy, st->p2, st->window, st->window_gc, (st->width*2)/3, (st->height*2)/3,
+ st->width/2, st->height/2,
+ st->width/2, st->height/2, 1L);
#endif
}
-\f
-char *progclass = "Moire2";
+static void *
+moire2_init (Display *dpy, Window window)
+{
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
+ st->dpy = dpy;
+ st->window = window;
+ st->reset = 1;
+
+ st->delay = get_integer_resource (st->dpy, "delay", "Integer");
+ st->color_shift = get_integer_resource (st->dpy, "colorShift", "Integer");
+
+ if (st->color_shift <= 0) st->color_shift = 1;
+ moire2_init_1 (st);
+ return st;
+}
+
+static unsigned long
+moire2_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+
+ if (st->reset)
+ {
+ st->reset = 0;
-char *defaults [] = {
+ st->iteration = 0;
+ st->iterations = 30 + (random() % 70) + (random() % 70);
+ reset_moire2 (st);
+
+ st->flip_a = mono_p ? False : (random() & 1);
+ st->flip_b = mono_p ? False : (random() & 1);
+
+ if (st->flip_b)
+ {
+ XSetForeground(st->dpy, st->window_gc, st->bg_pixel);
+ XSetBackground(st->dpy, st->window_gc, st->fg_pixel);
+ }
+ else
+ {
+ XSetForeground(st->dpy, st->window_gc, st->fg_pixel);
+ XSetBackground(st->dpy, st->window_gc, st->bg_pixel);
+ }
+ }
+
+ if (!mono_p)
+ {
+ st->pix++;
+ st->pix = st->pix % st->ncolors;
+
+ if (st->flip_a)
+ XSetBackground(st->dpy, st->window_gc, st->colors[st->pix].pixel);
+ else
+ XSetForeground(st->dpy, st->window_gc, st->colors[st->pix].pixel);
+ }
+
+
+ moire2 (st);
+ st->iteration++;
+ if (st->iteration >= st->color_shift)
+ {
+ st->iteration = 0;
+ st->iterations--;
+ if (st->iterations <= 0)
+ st->reset = 1;
+ }
+
+ return st->delay;
+}
+
+static void
+moire2_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
+{
+ struct state *st = (struct state *) closure;
+ st->reset = 1;
+}
+
+static Bool
+moire2_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+ return False;
+}
+
+static void
+moire2_free (Display *dpy, Window window, void *closure)
+{
+}
+
+static const char *moire2_defaults [] = {
".background: black",
".foreground: white",
"*delay: 50000",
0
};
-XrmOptionDescRec options [] = {
+static XrmOptionDescRec moire2_options [] = {
{ "-delay", ".delay", XrmoptionSepArg, 0 },
{ "-ncolors", ".colors", XrmoptionSepArg, 0 },
{ "-thickness", ".thickness", XrmoptionSepArg, 0 },
{ 0, 0, 0, 0 }
};
-void
-screenhack (Display *dpy, Window window)
-{
- int delay = get_integer_resource ("delay", "Integer");
- int color_shift = get_integer_resource ("colorShift", "Integer");
- int pix = 0;
- Bool flip_a, flip_b;
-
- if (color_shift <= 0) color_shift = 1;
- init_moire2 (dpy, window);
- while (1)
- {
- int iterations = 30 + (random() % 70) + (random() % 70);
- reset_moire2 (dpy, window);
-
- flip_a = mono_p ? False : (random() & 1);
- flip_b = mono_p ? False : (random() & 1);
-
- if (flip_b)
- {
- XSetForeground(dpy, window_gc, bg_pixel);
- XSetBackground(dpy, window_gc, fg_pixel);
- }
- else
- {
- XSetForeground(dpy, window_gc, fg_pixel);
- XSetBackground(dpy, window_gc, bg_pixel);
- }
-
- while (--iterations > 0)
- {
- int i;
-
- if (!mono_p)
- {
- pix++;
- pix = pix % ncolors;
-
- if (flip_a)
- XSetBackground(dpy, window_gc, colors[pix].pixel);
- else
- XSetForeground(dpy, window_gc, colors[pix].pixel);
- }
-
- for (i = 0; i < color_shift; i++)
- {
- moire2 (dpy, window);
- screenhack_handle_events (dpy);
- if (delay)
- usleep(delay);
- }
- }
- }
-}
+XSCREENSAVER_MODULE ("Moire2", moire2)