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_COCOA /* 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;
90 gcv.foreground = fg.pixel;
91 gcv.background = bg.pixel;
92 st->gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
94 st->colors = (XColor *) calloc (st->ncolors, sizeof(XColor));
95 st->squares = (square *) calloc (st->nsquares, sizeof(square));
97 rgb_to_hsv (fg.red, fg.green, fg.blue, &h1, &s1, &v1);
98 rgb_to_hsv (bg.red, bg.green, bg.blue, &h2, &s2, &v2);
99 make_color_ramp (st->dpy, st->xgwa.colormap,
102 st->colors, &st->ncolors, /* would this be considered a value-result argument? */
106 fprintf (stderr, "%s: insufficient colors!\n", progname);
110 for (y = 0; y < st->gh; y++)
111 for (x = 0; x < st->gw; x++)
113 square *s = (square *) &st->squares[st->gw * y + x];
120 randomize_square_colors(st->squares, st->nsquares, st->ncolors);
124 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
125 st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined);
127 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
130 st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
131 st->bb = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth);
144 popsquares_draw (Display *dpy, Window window, void *closure)
146 struct state *st = (struct state *) closure;
148 for (y = 0; y < st->gh; y++)
149 for (x = 0; x < st->gw; x++)
151 square *s = (square *) &st->squares[st->gw * y + x];
152 XSetForeground (st->dpy, st->gc, st->colors[s->color].pixel);
153 XFillRectangle (st->dpy, st->b, st->gc, s->x, s->y,
154 st->border ? s->w - st->border : s->w,
155 st->border ? s->h - st->border : s->h);
157 if (s->color == st->ncolors)
159 if (st->twitch && ((random() % 4) == 0))
160 randomize_square_colors (st->squares, st->nsquares, st->ncolors);
162 s->color = random() % st->ncolors;
165 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
168 XdbeSwapInfo info[1];
169 info[0].swap_window = st->window;
170 info[0].swap_action = XdbeUndefined;
171 XdbeSwapBuffers (st->dpy, info, 1);
174 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
177 XCopyArea (st->dpy, st->b, st->window, st->gc, 0, 0,
178 st->xgwa.width, st->xgwa.height, 0, 0);
179 st->b = (st->b == st->ba ? st->bb : st->ba);
187 popsquares_reshape (Display *dpy, Window window, void *closure,
188 unsigned int w, unsigned int h)
193 popsquares_event (Display *dpy, Window window, void *closure, XEvent *event)
199 popsquares_free (Display *dpy, Window window, void *closure)
201 struct state *st = (struct state *) closure;
206 static const char *popsquares_defaults [] = {
207 ".background: #0000FF",
208 ".foreground: #00008B",
214 "*doubleBuffer: False",
215 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
217 "*useDBEClear: True",
218 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
222 static XrmOptionDescRec popsquares_options [] = {
223 { "-fg", ".foreground", XrmoptionSepArg, 0},
224 { "-bg", ".background", XrmoptionSepArg, 0},
225 { "-delay", ".delay", XrmoptionSepArg, 0 },
226 { "-subdivision", ".subdivision", XrmoptionSepArg, 0 },
227 { "-border", ".border", XrmoptionSepArg, 0},
228 { "-ncolors", ".ncolors", XrmoptionSepArg, 0 },
229 { "-twitch", ".twitch", XrmoptionNoArg, "True" },
230 { "-no-twitch", ".twitch", XrmoptionNoArg, "False" },
231 { "-db", ".doubleBuffer", XrmoptionNoArg, "True" },
232 { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" },
237 XSCREENSAVER_MODULE ("PopSquares", popsquares)