1 /* wander, by Rick Campbell <rick@campbellcentral.org>, 19 December 1998.
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
14 #include "screenhack.h"
18 #define MAXIMUM_COLOR_COUNT (256)
29 XColor colors [MAXIMUM_COLOR_COUNT];
41 int x, y, last_x, last_y, width_1, height_1, length_limit, reset_limit;
50 wander_init (Display *dpy, Window window)
52 struct state *st = (struct state *) calloc (1, sizeof(*st));
54 XWindowAttributes attributes;
58 st->delay = get_integer_resource (st->dpy, "delay", "Integer");
60 XClearWindow (st->dpy, st->window);
61 XGetWindowAttributes (st->dpy, st->window, &attributes);
62 st->width = attributes.width;
63 st->height = attributes.height;
64 st->depth = attributes.depth;
65 st->color_map = attributes.colormap;
68 free_colors (attributes.screen, st->color_map,
69 st->colors, st->color_count);
72 st->context = XCreateGC (st->dpy, st->window, 0, &values);
73 st->color_count = MAXIMUM_COLOR_COUNT;
74 make_color_loop (attributes.screen, attributes.visual, st->color_map,
78 st->colors, &st->color_count, True, False);
79 if (st->color_count <= 0)
82 st->colors [0].red = st->colors [0].green = st->colors [0].blue = 0;
83 st->colors [1].red = st->colors [1].green = st->colors [1].blue = 0xFFFF;
84 XAllocColor (st->dpy, st->color_map, &st->colors [0]);
85 XAllocColor (st->dpy, st->color_map, &st->colors [1]);
87 st->color_index = NRAND (st->color_count);
89 st->advance = get_integer_resource (st->dpy, "advance", "Integer");
90 st->density = get_integer_resource (st->dpy, "density", "Integer");
91 if (st->density < 1) st->density = 1;
92 st->reset = get_integer_resource (st->dpy, "reset", "Integer");
93 if (st->reset < 100) st->reset = 100;
94 st->circles = get_boolean_resource (st->dpy, "circles", "Boolean");
95 st->size = get_integer_resource (st->dpy, "size", "Integer");
96 if (st->size < 1) st->size = 1;
97 st->width = st->width / st->size;
98 st->height = st->height / st->size;
99 st->length = get_integer_resource (st->dpy, "length", "Integer");
100 if (st->length < 1) st->length = 1;
101 XSetForeground (st->dpy, st->context, st->colors [st->color_index].pixel);
104 st->x = NRAND (st->width);
105 st->y = NRAND (st->height);
108 st->width_1 = st->width - 1;
109 st->height_1 = st->height - 1;
110 st->length_limit = st->length;
111 st->reset_limit = st->reset;
112 st->color_index = NRAND (st->color_count);
113 st->color = st->colors [NRAND (st->color_count)].pixel;
114 st->pixmap = XCreatePixmap (st->dpy, window, st->size,
115 st->size, st->depth);
117 XSetForeground (st->dpy, st->context,
118 BlackPixel (st->dpy, DefaultScreen (st->dpy)));
119 XFillRectangle (st->dpy, st->pixmap, st->context, 0, 0,
120 st->width * st->size, st->height * st->size);
121 XSetForeground (st->dpy, st->context, st->color);
122 XFillArc (st->dpy, st->pixmap, st->context, 0, 0, st->size, st->size, 0, 360*64);
129 wander_draw (Display *dpy, Window window, void *closure)
131 struct state *st = (struct state *) closure;
135 st->eraser = erase_window (st->dpy, st->window, st->eraser);
139 for (i = 0; i < 2000; i++)
141 if (NRAND (st->density))
150 st->x += st->width_1 + NRAND (3);
151 while (st->x >= st->width)
153 st->y += st->height_1 + NRAND (3);
154 while (st->y >= st->height)
158 if (NRAND (st->length_limit) == 0)
160 if (st->advance == 0)
162 st->color_index = NRAND (st->color_count);
166 st->color_index = (st->color_index + st->advance) % st->color_count;
168 st->color = st->colors [st->color_index].pixel;
169 XSetForeground (st->dpy, st->context, st->color);
172 XFillArc (st->dpy, st->pixmap, st->context,
173 0, 0, st->size, st->size, 0, 360 * 64);
177 if (st->reset_p || NRAND (st->reset_limit) == 0)
180 st->eraser = erase_window (st->dpy, st->window, st->eraser);
181 st->color = st->colors [NRAND (st->color_count)].pixel;
182 st->x = NRAND (st->width);
183 st->y = NRAND (st->height);
188 XFillArc (st->dpy, st->pixmap, st->context, 0, 0, st->size, st->size, 0, 360*64);
194 XDrawPoint (st->dpy, st->window, st->context, st->x, st->y);
200 XCopyArea (st->dpy, st->pixmap, st->window, st->context, 0, 0, st->size, st->size,
201 st->x * st->size, st->y * st->size);
205 XFillRectangle (st->dpy, st->window, st->context, st->x * st->size, st->y * st->size,
217 wander_reshape (Display *dpy, Window window, void *closure,
218 unsigned int w, unsigned int h)
220 struct state *st = (struct state *) closure;
221 st->width = w / st->size;
222 st->height = h / st->size;
223 st->width_1 = st->width - 1;
224 st->height_1 = st->height - 1;
228 wander_event (Display *dpy, Window window, void *closure, XEvent *event)
230 struct state *st = (struct state *) closure;
231 if (screenhack_event_helper (dpy, window, event))
240 wander_free (Display *dpy, Window window, void *closure)
244 static const char *wander_defaults [] =
246 ".background: black",
247 ".foreground: white",
257 "*ignoreRotation: True",
262 static XrmOptionDescRec wander_options [] =
264 { "-advance", ".advance", XrmoptionSepArg, 0 },
265 { "-circles", ".circles", XrmoptionNoArg, "True" },
266 { "-no-circles",".circles", XrmoptionNoArg, "False" },
267 { "-density", ".density", XrmoptionSepArg, 0 },
268 { "-length", ".length", XrmoptionSepArg, 0 },
269 { "-delay", ".delay", XrmoptionSepArg, 0 },
270 { "-reset", ".reset", XrmoptionSepArg, 0 },
271 { "-size", ".size", XrmoptionSepArg, 0 },
276 XSCREENSAVER_MODULE ("Wander", wander)