2eeb617035fa1926364a8863f133267cba3b6cad
[xscreensaver] / hacks / rorschach.c
1 /* xscreensaver, Copyright (c) 1992, 1996 Jamie Zawinski <jwz@netscape.com>
2  *
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 
9  * implied warranty.
10  *
11  * 19971004: Johannes Keukelaar <johannes@nada.kth.se>: Use helix screen
12  *           eraser.
13  */
14
15 #include "screenhack.h"
16 #include "erase.h"
17
18 static GC draw_gc, erase_gc;
19 static unsigned int default_fg_pixel;
20 static int iterations, offset;
21 static Bool xsym, ysym;
22 static int erase_speed, sleep_time, erase_mode;
23
24 void erase_window (Display *dpy, Window win, GC gc, int width, int height,
25                    int mode, int delay);
26
27 static void
28 init_rorschach (Display *dpy, Window window)
29 {
30   XGCValues gcv;
31   Colormap cmap;
32   XWindowAttributes xgwa;
33   XGetWindowAttributes (dpy, window, &xgwa);
34   cmap = xgwa.colormap;
35   gcv.foreground = default_fg_pixel =
36     get_pixel_resource ("foreground", "Foreground", dpy, cmap);
37   draw_gc = XCreateGC (dpy, window, GCForeground, &gcv);
38   gcv.foreground = get_pixel_resource ("background", "Background", dpy, cmap);
39   erase_gc = XCreateGC (dpy, window, GCForeground, &gcv);
40   iterations = get_integer_resource ("iterations", "Integer");
41   offset = get_integer_resource ("offset", "Integer");
42   if (offset <= 0) offset = 3;
43   if (iterations < 10) iterations = 10;
44   xsym = get_boolean_resource ("xsymmetry", "Symmetry");
45   ysym = get_boolean_resource ("ysymmetry", "Symmetry");
46 }
47
48 static void
49 hurm (Display *dpy, Window window)
50 {
51   Colormap cmap;
52   XWindowAttributes xgwa;
53   int xlim, ylim, x, y, i, got_color = 0;
54   XPoint points [4];
55   XColor color;
56   XClearWindow (dpy, window);
57   XGetWindowAttributes (dpy, window, &xgwa);
58   xlim = xgwa.width;
59   ylim = xgwa.height;
60   cmap = xgwa.colormap;
61
62   if (! mono_p)
63     hsv_to_rgb (random()%360, 1.0, 1.0, &color.red, &color.green, &color.blue);
64   if ((!mono_p) && (got_color = XAllocColor (dpy, cmap, &color)))
65     XSetForeground (dpy, draw_gc, color.pixel);
66   else
67     XSetForeground (dpy, draw_gc, default_fg_pixel);
68
69   x = xlim/2;
70   y = ylim/2;
71   for (i = 0; i < iterations; i++)
72     {
73       int j = 0;
74       x += ((random () % (1 + (offset << 1))) - offset);
75       y += ((random () % (1 + (offset << 1))) - offset);
76       points [j].x = x;
77       points [j].y = y;
78       j++;
79       if (xsym)
80         {
81           points [j].x = xlim - x;
82           points [j].y = y;
83           j++;
84         }
85       if (ysym)
86         {
87           points [j].x = x;
88           points [j].y = ylim - y;
89           j++;
90         }
91       if (xsym && ysym)
92         {
93           points [j].x = xlim - x;
94           points [j].y = ylim - y;
95           j++;
96         }
97       XDrawPoints (dpy, window, draw_gc, points, j, CoordModeOrigin);
98       XSync (dpy, True);
99     }
100   sleep ( sleep_time );
101
102   erase_window(dpy, window, erase_gc, xlim, ylim, erase_mode, erase_speed);
103
104   XClearWindow (dpy, window);
105   if (got_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0);
106   XSync (dpy, True);
107   sleep (1);
108 }
109
110 \f
111 char *progclass = "Rorschach";
112
113 char *defaults [] = {
114   "Rorschach.background:        black",         /* to placate SGI */
115   "Rorschach.foreground:        white",
116   "*xsymmetry:  true",
117   "*ysymmetry:  false",
118   "*iterations: 4000",
119   "*offset:     4",
120   "Rorschach.eraseSpeed: 400",
121   "Rorschach.delay: 5",
122   "Rorschach.eraseMode: -1",
123   0
124 };
125
126 XrmOptionDescRec options [] = {
127   { "-iterations",      ".iterations",  XrmoptionSepArg, 0 },
128   { "-offset",          ".offset",      XrmoptionSepArg, 0 },
129   { "-xsymmetry",       ".xsymmetry",   XrmoptionNoArg, "true" },
130   { "-ysymmetry",       ".ysymmetry",   XrmoptionNoArg, "true" },
131   { "-erase-speed",     ".eraseSpeed",          XrmoptionSepArg, 0 },
132   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
133   { "-erase-mode",      ".eraseMode",           XrmoptionSepArg, 0 },
134   { 0, 0, 0, 0 }
135 };
136
137 void
138 screenhack (Display *dpy, Window window)
139 {
140   erase_speed = get_integer_resource("eraseSpeed", "Integer");
141   sleep_time = get_integer_resource("delay", "Integer");
142   erase_mode = get_integer_resource("eraseMode", "Integer");
143   init_rorschach (dpy, window);
144   while (1)
145     hurm (dpy, window);
146 }