1 /* coral, by "Frederick G.M. Roeber" <roeber@netscape.com>, 15-jul-97.
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"
16 static GC draw_gc, erase_gc;
17 static unsigned int default_fg_pixel;
18 #define NCOLORSMAX 200
19 static XColor colors[NCOLORSMAX];
20 static int ncolors = 0;
21 static int colorindex = 0;
22 static int colorsloth;
24 static XPoint *walkers = 0;
26 static int width, widthb;
29 static unsigned int *board = 0;
30 #define getdot(x,y) (board[(y*widthb)+(x>>5)] & (1<<(x & 31)))
31 #define setdot(x,y) (board[(y*widthb)+(x>>5)] |= (1<<(x & 31)))
35 init_coral(Display *dpy, Window window)
39 XWindowAttributes xgwa;
40 Bool writeable = False;
45 XClearWindow(dpy, window);
46 XGetWindowAttributes(dpy, window, &xgwa);
48 widthb = ((xgwa.width + 31) >> 5);
50 if (board) free(board);
51 board = (unsigned int *)calloc(widthb * xgwa.height, sizeof(unsigned int));
55 free_colors(dpy, cmap, colors, ncolors);
58 gcv.foreground = default_fg_pixel = get_pixel_resource("foreground", "Foreground", dpy, cmap);
59 draw_gc = XCreateGC(dpy, window, GCForeground, &gcv);
60 gcv.foreground = get_pixel_resource ("background", "Background",dpy, cmap);
61 erase_gc = XCreateGC (dpy, window, GCForeground, &gcv);
63 make_uniform_colormap(dpy, xgwa.visual, cmap, colors, &ncolors, True, &writeable, False);
66 colors[0].red = colors[0].green = colors[0].blue = 0;
67 colors[1].red = colors[1].green = colors[1].blue = 0xFFFF;
68 XAllocColor(dpy, cmap, &colors[0]);
69 XAllocColor(dpy, cmap, &colors[1]);
71 colorindex = random()%ncolors;
73 density = get_integer_resource("density", "Integer");
74 if( density < 1 ) density = 1;
75 if( density > 100 ) density = 90; /* more like mold than coral */
76 nwalkers = (width*height*density)/100;
77 if (walkers) free(walkers);
78 walkers = (XPoint *)calloc(nwalkers, sizeof(XPoint));
79 if( (XPoint *)0 == walkers ) exit(1);
81 seeds = get_integer_resource("seeds", "Integer");
82 if( seeds < 1 ) seeds = 1;
83 if( seeds > 1000 ) seeds = 1000;
85 colorsloth = nwalkers*2/ncolors;
86 XSetForeground(dpy, draw_gc, colors[colorindex].pixel);
88 for( i = 0; i < seeds; i++ ) {
91 x = 1 + random() % (width - 2);
92 y = 1 + random() % (height - 2);
93 } while( getdot(x, y) );
95 setdot((x-1), (y-1)); setdot(x, (y-1)); setdot((x+1), (y-1));
96 setdot((x-1), y ); setdot(x, y ); setdot((x+1), y );
97 setdot((x-1), (y+1)); setdot(x, (y+1)); setdot((x+1), (y+1));
98 XDrawPoint(dpy, window, draw_gc, x, y);
101 for( i = 0; i < nwalkers; i++ ) {
102 walkers[i].x = (random() % (width-2)) + 1;
103 walkers[i].y = (random() % (height-2)) + 1;
108 /* returns 2 bits of randomness (conserving calls to random()).
109 This speeds things up a little, but not a lot (5-10% or so.)
124 register int j = (r & 3);
132 coral(Display *dpy, Window window)
134 int delay2 = get_integer_resource ("delay2", "Integer");
136 int max_points = 200;
138 XPoint *pointbuf = (XPoint *) calloc(sizeof(XPoint), max_points+2);
139 if (!pointbuf) exit(-1);
144 for( i = 0; i < nwalkers; i++ ) {
145 int x = walkers[i].x;
146 int y = walkers[i].y;
153 /* XDrawPoint(dpy, window, draw_gc, x, y); */
154 pointbuf[npoints].x = x;
155 pointbuf[npoints].y = y;
158 /* Mark the surrounding area as "sticky" */
159 setdot((x-1), (y-1)); setdot(x, (y-1)); setdot((x+1), (y-1));
160 setdot((x-1), y ); setdot((x+1), y );
161 setdot((x-1), (y+1)); setdot(x, (y+1)); setdot((x+1), (y+1));
163 walkers[i].x = walkers[nwalkers].x;
164 walkers[i].y = walkers[nwalkers].y;
165 if( 0 == (nwalkers%colorsloth) ) {
169 if (flush || color || 0 == nwalkers || npoints >= max_points) {
170 XDrawPoints(dpy, window, draw_gc, pointbuf, npoints,
178 if( colorindex == ncolors )
180 XSetForeground(dpy, draw_gc, colors[colorindex].pixel);
183 if( 0 == nwalkers ) {
189 /* move it a notch */
193 if( 1 == x ) continue;
197 if( width-2 == x ) continue;
201 if( 1 == y ) continue;
204 default: /* case 3: */
205 if( height-2 == y ) continue;
217 XDrawPoints(dpy, window, draw_gc, pointbuf, npoints,
222 screenhack_handle_events (dpy);
228 char *progclass = "Coral";
231 ".background: black",
232 ".foreground: white",
234 "*seeds: 20", /* too many for 640x480, too few for 1280x1024 */
240 XrmOptionDescRec options[] = {
241 { "-density", ".density", XrmoptionSepArg, 0 },
242 { "-seeds", ".seeds", XrmoptionSepArg, 0 },
243 { "-delay", ".delay", XrmoptionSepArg, 0 },
244 { "-delay2", ".delay2", XrmoptionSepArg, 0 },
249 screenhack(dpy, window)
253 int delay = get_integer_resource ("delay", "Integer");
255 init_coral(dpy, window);
257 screenhack_handle_events (dpy);
258 if( delay ) sleep(delay);
259 erase_full_window(dpy, window);