1 /* Copyright (c) 2003 Levi Burton <donburton@sbcglobal.net>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 #include "screenhack.h"
15 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
17 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
19 typedef struct _square {
25 randomize_square_colors(square *squares, int nsquares, int ncolors)
29 for (i = 0; i < nsquares; i++)
30 s[i].color = random() % ncolors;
38 int delay, subdivision, border, ncolors, twitch, dbuf;
39 XWindowAttributes xgwa;
42 int sw, sh, gw, gh, nsquares;
45 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
47 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
51 popsquares_init (Display *dpy, Window window)
53 struct state *st = (struct state *) calloc (1, sizeof(*st));
55 double s1, v1, s2, v2 = 0;
57 /* Not sure how to use DBEClear */
58 /* Bool dbeclear_p = get_boolean_resource(dpy, "useDBEClear", "Boolean"); */
65 st->delay = get_integer_resource (st->dpy, "delay", "Integer");
66 st->subdivision = get_integer_resource(st->dpy, "subdivision", "Integer");
67 st->border = get_integer_resource(st->dpy, "border", "Integer");
68 st->ncolors = get_integer_resource(st->dpy, "ncolors", "Integer");
69 st->twitch = get_boolean_resource(st->dpy, "twitch", "Boolean");
70 st->dbuf = get_boolean_resource(st->dpy, "doubleBuffer", "Boolean");
72 # ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
76 XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
78 fg.pixel = get_pixel_resource (st->dpy, st->xgwa.colormap, "foreground", "Foreground");
79 bg.pixel = get_pixel_resource (st->dpy, st->xgwa.colormap, "background", "Background");
81 XQueryColor (st->dpy, st->xgwa.colormap, &fg);
82 XQueryColor (st->dpy, st->xgwa.colormap, &bg);
84 st->sw = st->xgwa.width / st->subdivision;
85 st->sh = st->xgwa.height / st->subdivision;
86 st->gw = st->sw ? st->xgwa.width / st->sw : 0;
87 st->gh = st->sh ? st->xgwa.height / st->sh : 0;
88 st->nsquares = st->gw * st->gh;
89 if (st->nsquares < 1) st->nsquares = 1;
90 if (st->ncolors < 1) st->ncolors = 1;
92 gcv.foreground = fg.pixel;
93 gcv.background = bg.pixel;
94 st->gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
96 st->colors = (XColor *) calloc (st->ncolors, sizeof(XColor));
97 st->squares = (square *) calloc (st->nsquares, sizeof(square));
99 rgb_to_hsv (fg.red, fg.green, fg.blue, &h1, &s1, &v1);
100 rgb_to_hsv (bg.red, bg.green, bg.blue, &h2, &s2, &v2);
101 make_color_ramp (st->xgwa.screen, st->xgwa.visual, st->xgwa.colormap,
104 st->colors, &st->ncolors, /* would this be considered a value-result argument? */
108 fprintf (stderr, "%s: insufficient colors!\n", progname);
112 for (y = 0; y < st->gh; y++)
113 for (x = 0; x < st->gw; x++)
115 square *s = (square *) &st->squares[st->gw * y + x];
122 randomize_square_colors(st->squares, st->nsquares, st->ncolors);
126 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
127 st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined);
129 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
132 st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
133 st->bb = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
146 popsquares_draw (Display *dpy, Window window, void *closure)
148 struct state *st = (struct state *) closure;
150 for (y = 0; y < st->gh; y++)
151 for (x = 0; x < st->gw; x++)
153 square *s = (square *) &st->squares[st->gw * y + x];
154 XSetForeground (st->dpy, st->gc, st->colors[s->color].pixel);
155 XFillRectangle (st->dpy, st->b, st->gc, s->x, s->y,
156 st->border ? s->w - st->border : s->w,
157 st->border ? s->h - st->border : s->h);
159 if (s->color == st->ncolors)
161 if (st->twitch && ((random() % 4) == 0))
162 randomize_square_colors (st->squares, st->nsquares, st->ncolors);
164 s->color = random() % st->ncolors;
167 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
170 XdbeSwapInfo info[1];
171 info[0].swap_window = st->window;
172 info[0].swap_action = XdbeUndefined;
173 XdbeSwapBuffers (st->dpy, info, 1);
176 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
179 XCopyArea (st->dpy, st->b, st->window, st->gc, 0, 0,
180 st->xgwa.width, st->xgwa.height, 0, 0);
181 st->b = (st->b == st->ba ? st->bb : st->ba);
189 popsquares_reshape (Display *dpy, Window window, void *closure,
190 unsigned int w, unsigned int h)
192 struct state *st = (struct state *) closure;
194 XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
195 st->sw = st->xgwa.width / st->subdivision;
196 st->sh = st->xgwa.height / st->subdivision;
197 st->gw = st->sw ? st->xgwa.width / st->sw : 0;
198 st->gh = st->sh ? st->xgwa.height / st->sh : 0;
199 st->nsquares = st->gw * st->gh;
201 if (st->nsquares < 1) st->nsquares = 1;
202 st->squares = (square *) calloc (st->nsquares, sizeof(square));
204 for (y = 0; y < st->gh; y++)
205 for (x = 0; x < st->gw; x++)
207 square *s = (square *) &st->squares[st->gw * y + x];
214 randomize_square_colors(st->squares, st->nsquares, st->ncolors);
217 XFreePixmap (dpy, st->ba);
218 XFreePixmap (dpy, st->bb);
219 st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
220 st->bb = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
226 popsquares_event (Display *dpy, Window window, void *closure, XEvent *event)
232 popsquares_free (Display *dpy, Window window, void *closure)
234 struct state *st = (struct state *) closure;
239 static const char *popsquares_defaults [] = {
240 ".background: #0000FF",
241 ".foreground: #00008B",
247 "*doubleBuffer: False",
248 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
250 "*useDBEClear: True",
251 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
253 "*ignoreRotation: True",
258 static XrmOptionDescRec popsquares_options [] = {
259 { "-fg", ".foreground", XrmoptionSepArg, 0},
260 { "-bg", ".background", XrmoptionSepArg, 0},
261 { "-delay", ".delay", XrmoptionSepArg, 0 },
262 { "-subdivision", ".subdivision", XrmoptionSepArg, 0 },
263 { "-border", ".border", XrmoptionSepArg, 0},
264 { "-ncolors", ".ncolors", XrmoptionSepArg, 0 },
265 { "-twitch", ".twitch", XrmoptionNoArg, "True" },
266 { "-no-twitch", ".twitch", XrmoptionNoArg, "False" },
267 { "-db", ".doubleBuffer", XrmoptionNoArg, "True" },
268 { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" },
273 XSCREENSAVER_MODULE ("PopSquares", popsquares)