1 /* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@jwz.org>
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"
13 #include <X11/Xutil.h>
17 static XColor *colors = 0;
18 static int fg_pixel, bg_pixel;
19 static Pixmap p0 = 0, p1 = 0, p2 = 0, p3 = 0;
20 static GC copy_gc = 0, erase_gc = 0, window_gc = 0;
21 static int width, height, size;
22 static int x1, x2, y1, y2, x3, y3;
23 static int dx1, dx2, dx3, dy1, dy2, dy3;
24 static int othickness, thickness;
28 init_moire2 (Display *dpy, Window window)
30 XWindowAttributes xgwa;
31 XGetWindowAttributes (dpy, window, &xgwa);
33 othickness = get_integer_resource("thickness", "Thickness");
38 ncolors = get_integer_resource ("colors", "Colors");
39 if (ncolors < 2) ncolors = 2;
40 if (ncolors <= 2) mono_p = True;
45 colors = (XColor *) malloc(sizeof(*colors) * (ncolors+1));
50 make_smooth_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors,
53 bg_pixel = get_pixel_resource("background", "Background", dpy,
55 fg_pixel = get_pixel_resource("foreground", "Foreground", dpy,
61 reset_moire2 (Display *dpy, Window window)
64 XWindowAttributes xgwa;
67 XGetWindowAttributes (dpy, window, &xgwa);
69 do_three = (0 == (random() % 3));
73 size = width > height ? width : height;
75 if (p0) XFreePixmap(dpy, p0);
76 if (p1) XFreePixmap(dpy, p1);
77 if (p2) XFreePixmap(dpy, p2);
78 if (p3) XFreePixmap(dpy, p3);
80 p0 = XCreatePixmap(dpy, window, width, height, 1);
81 p1 = XCreatePixmap(dpy, window, width*2, height*2, 1);
82 p2 = XCreatePixmap(dpy, window, width*2, height*2, 1);
84 p3 = XCreatePixmap(dpy, window, width*2, height*2, 1);
88 thickness = (othickness > 0 ? othickness : (1 + (random() % 4)));
91 gcv.line_width = (thickness == 1 ? 0 : thickness);
92 gc = XCreateGC (dpy, p1, GCForeground|GCLineWidth, &gcv);
94 XFillRectangle(dpy, p1, gc, 0, 0, width*2, height*2);
95 XFillRectangle(dpy, p2, gc, 0, 0, width*2, height*2);
97 XFillRectangle(dpy, p3, gc, 0, 0, width*2, height*2);
99 XSetForeground(dpy, gc, 1);
101 xor = (do_three || (thickness == 1) || (random() & 1));
104 int i, ii, maxx, maxy;
106 #define FROB(P) do { \
109 if (0 == (random() % 5)) { \
110 float f = 1.0 + frand(0.05); \
111 if (random() & 1) maxx *= f; \
114 ii = (thickness + 1 + (xor ? 0 : 1) + (random() % (4 * thickness))); \
115 for (i = 0; i < (size*2); i += ii) \
116 XDrawArc(dpy, (P), gc, i-size, i-size, maxx-i-i, maxy-i-i, 0, 360*64); \
117 if (0 == (random() % 5)) \
119 XSetFunction(dpy, gc, GXxor); \
120 XFillRectangle(dpy, (P), gc, 0, 0, width*2, height*2); \
121 XSetFunction(dpy, gc, GXcopy); \
134 if (copy_gc) XFreeGC(dpy, copy_gc);
135 gcv.function = (xor ? GXxor : GXor);
139 copy_gc = XCreateGC (dpy, p0, GCFunction|GCForeground|GCBackground, &gcv);
142 if (erase_gc) XFreeGC(dpy, erase_gc);
143 erase_gc = XCreateGC (dpy, p0, GCForeground, &gcv);
145 gcv.foreground = fg_pixel;
146 gcv.background = bg_pixel;
147 if (window_gc) XFreeGC(dpy, window_gc);
148 window_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
150 #define FROB(N,DN,MAX) \
151 N = (MAX/2) + (random() % MAX); \
152 DN = ((1 + (random() % (7*thickness))) * ((random() & 1) ? 1 : -1))
166 moire2 (Display *dpy, Window window)
168 #define FROB(N,DN,MAX) \
170 if (N <= 0) N = 0, DN = -DN; \
171 else if (N >= MAX) N = MAX, DN = -DN; \
172 else if (0 == (random() % 100)) DN = -DN; \
173 else if (0 == (random() % 50)) \
174 DN += (DN <= -20 ? 1 : (DN >= 20 ? -1 : ((random() & 1) ? 1 : -1)))
184 XFillRectangle(dpy, p0, erase_gc, 0, 0, width, height);
185 XCopyArea(dpy, p1, p0, copy_gc, x1, y1, width, height, 0, 0);
186 XCopyArea(dpy, p2, p0, copy_gc, x2, y2, width, height, 0, 0);
188 XCopyArea(dpy, p3, p0, copy_gc, x3, y3, width, height, 0, 0);
191 XCopyPlane(dpy, p0, window, window_gc, 0, 0, width, height, 0, 0, 1L);
195 XCopyPlane(dpy, p1, window, window_gc, (width*2)/3, (height*2)/3,
198 XCopyPlane(dpy, p2, window, window_gc, (width*2)/3, (height*2)/3,
200 width/2, height/2, 1L);
207 char *progclass = "Moire2";
209 char *defaults [] = {
210 ".background: black",
211 ".foreground: white",
219 XrmOptionDescRec options [] = {
220 { "-delay", ".delay", XrmoptionSepArg, 0 },
221 { "-ncolors", ".colors", XrmoptionSepArg, 0 },
222 { "-thickness", ".thickness", XrmoptionSepArg, 0 },
227 screenhack (Display *dpy, Window window)
229 int delay = get_integer_resource ("delay", "Integer");
230 int color_shift = get_integer_resource ("colorShift", "Integer");
234 if (color_shift <= 0) color_shift = 1;
235 init_moire2 (dpy, window);
238 int iterations = 30 + (random() % 70) + (random() % 70);
239 reset_moire2 (dpy, window);
241 flip_a = mono_p ? False : (random() & 1);
242 flip_b = mono_p ? False : (random() & 1);
246 XSetForeground(dpy, window_gc, bg_pixel);
247 XSetBackground(dpy, window_gc, fg_pixel);
251 XSetForeground(dpy, window_gc, fg_pixel);
252 XSetBackground(dpy, window_gc, bg_pixel);
255 while (--iterations > 0)
265 XSetBackground(dpy, window_gc, colors[pix].pixel);
267 XSetForeground(dpy, window_gc, colors[pix].pixel);
270 for (i = 0; i < color_shift; i++)
272 moire2 (dpy, window);