4a17ba36f114d7f6bd1b0bafc7a8929511f84cce
[xscreensaver] / hacks / greynetic.c
1 /* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998
2  *  Jamie Zawinski <jwz@jwz.org>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or 
10  * implied warranty.
11  */
12
13 #include "screenhack.h"
14
15 #define NBITS 12
16
17 /* On some systems (notably MacOS X) these files are messed up.
18  * They're tiny, so we might as well just inline them here.
19  *
20  * # include <X11/bitmaps/stipple>
21  * # include <X11/bitmaps/cross_weave>
22  * # include <X11/bitmaps/dimple1>
23  * # include <X11/bitmaps/dimple3>
24  * # include <X11/bitmaps/flipped_gray>
25  * # include <X11/bitmaps/gray1>
26  * # include <X11/bitmaps/gray3>
27  * # include <X11/bitmaps/hlines2>
28  * # include <X11/bitmaps/light_gray>
29  * # include <X11/bitmaps/root_weave>
30  * # include <X11/bitmaps/vlines2>
31  * # include <X11/bitmaps/vlines3>
32 */
33
34 #define stipple_width  16
35 #define stipple_height 4
36 static char stipple_bits[] = { 0x55, 0x55, 0xee, 0xee, 0x55, 0x55, 0xba, 0xbb};
37
38 #define cross_weave_width  16
39 #define cross_weave_height 16
40 static char cross_weave_bits[] = {
41    0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88,
42    0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22,
43    0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22};
44
45 #define dimple1_width 16
46 #define dimple1_height 16
47 static char dimple1_bits[] = {
48    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
49    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
50    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00};
51
52 #define dimple3_width 16
53 #define dimple3_height 16
54 static char dimple3_bits[] = {
55    0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
56    0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57    0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
58
59 #define flipped_gray_width  4
60 #define flipped_gray_height 2
61 static char flipped_gray_bits[] = { 0x07, 0x0d};
62 #define gray1_width  2
63 #define gray1_height 2
64 static char gray1_bits[] = { 0x01, 0x02};
65 #define gray3_width  4
66 #define gray3_height 4
67 static char gray3_bits[] = { 0x01, 0x00, 0x04, 0x00};
68 #define hlines2_width  1
69 #define hlines2_height 2
70 static char hlines2_bits[] = { 0x01, 0x00};
71 #define light_gray_width  4
72 #define light_gray_height 2
73 static char light_gray_bits[] = { 0x08, 0x02};
74 #define root_weave_width  4
75 #define root_weave_height 4
76 static char root_weave_bits[] = { 0x07, 0x0d, 0x0b, 0x0e};
77 #define vlines2_width  2
78 #define vlines2_height 1
79 static char vlines2_bits[] = { 0x01};
80 #define vlines3_width  3
81 #define vlines3_height 1
82 static char vlines3_bits[] = { 0x02};
83
84
85
86
87 static Pixmap pixmaps [NBITS];
88 static GC gc;
89 static int delay;
90 static unsigned long fg, bg, pixels [512];
91 static int npixels;
92
93 static void
94 init_greynetic (Display *dpy, Window window)
95 {
96   int i;
97   XGCValues gcv;
98   XWindowAttributes xgwa;
99   Colormap cmap;
100   XGetWindowAttributes (dpy, window, &xgwa);
101   cmap = xgwa.colormap;
102   npixels = 0;
103   gcv.foreground= fg= get_pixel_resource("foreground","Foreground", dpy, cmap);
104   gcv.background= bg= get_pixel_resource("background","Background", dpy, cmap);
105   gcv.fill_style= FillOpaqueStippled;
106   gc = XCreateGC (dpy, window, GCForeground|GCBackground|GCFillStyle, &gcv);
107
108   delay = get_integer_resource ("delay", "Integer");
109   if (delay < 0) delay = 0;
110
111   i = 0;
112 #define BITS(n,w,h) \
113   pixmaps [i++] = XCreatePixmapFromBitmapData (dpy, window, n, w, h, 1, 0, 1)
114
115   BITS (stipple_bits, stipple_width, stipple_height);
116   BITS (cross_weave_bits, cross_weave_width, cross_weave_height);
117   BITS (dimple1_bits, dimple1_width, dimple1_height);
118   BITS (dimple3_bits, dimple3_width, dimple3_height);
119   BITS (flipped_gray_bits, flipped_gray_width, flipped_gray_height);
120   BITS (gray1_bits, gray1_width, gray1_height);
121   BITS (gray3_bits, gray3_width, gray3_height);
122   BITS (hlines2_bits, hlines2_width, hlines2_height);
123   BITS (light_gray_bits, light_gray_width, light_gray_height);
124   BITS (root_weave_bits, root_weave_width, root_weave_height);
125   BITS (vlines2_bits, vlines2_width, vlines2_height);
126   BITS (vlines3_bits, vlines3_width, vlines3_height);
127 }
128
129 static void
130 greynetic (Display *dpy, Window window)
131 {
132   static int tick = 500, xlim, ylim;
133   static Colormap cmap;
134   int x, y, w=0, h=0, i;
135   XGCValues gcv;
136   if (tick++ == 500)
137     {
138       XWindowAttributes xgwa;
139       XGetWindowAttributes (dpy, window, &xgwa);
140       tick = 0;
141       xlim = xgwa.width;
142       ylim = xgwa.height;
143       cmap = xgwa.colormap;
144     }
145   for (i = 0; i < 10; i++) /* minimize area, but don't try too hard */
146     {
147       w = 50 + random () % (xlim - 50);
148       h = 50 + random () % (ylim - 50);
149       if (w + h < xlim && w + h < ylim)
150         break;
151     }
152   x = random () % (xlim - w);
153   y = random () % (ylim - h);
154   gcv.stipple = pixmaps [random () % NBITS];
155   if (mono_p)
156     {
157     MONO:
158       if (random () & 1)
159         gcv.foreground = fg, gcv.background = bg;
160       else
161         gcv.foreground = bg, gcv.background = fg;
162     }
163   else
164     {
165       XColor fgc, bgc;
166       if (npixels == sizeof (pixels) / sizeof (unsigned long))
167         goto REUSE;
168       fgc.flags = bgc.flags = DoRed|DoGreen|DoBlue;
169       fgc.red = random ();
170       fgc.green = random ();
171       fgc.blue = random ();
172       bgc.red = random ();
173       bgc.green = random ();
174       bgc.blue = random ();
175       if (! XAllocColor (dpy, cmap, &fgc))
176         goto REUSE;
177       pixels [npixels++] = fgc.pixel;
178       gcv.foreground = fgc.pixel;
179       if (! XAllocColor (dpy, cmap, &bgc))
180         goto REUSE;
181       pixels [npixels++] = bgc.pixel;
182       gcv.background = bgc.pixel;
183       goto DONE;
184     REUSE:
185       if (npixels <= 0)
186         {
187           mono_p = 1;
188           goto MONO;
189         }
190       gcv.foreground = pixels [random () % npixels];
191       gcv.background = pixels [random () % npixels];
192     DONE:
193       ;
194     }
195   XChangeGC (dpy, gc, GCStipple|GCForeground|GCBackground, &gcv);
196   XFillRectangle (dpy, window, gc, x, y, w, h);
197   XSync (dpy, False);
198 }
199
200 \f
201 char *progclass = "Greynetic";
202
203 char *defaults [] = {
204   ".background: black",
205   ".foreground: white",
206   "*delay:      10000",
207   0
208 };
209
210 XrmOptionDescRec options [] = {
211   { "-delay",           ".delay",       XrmoptionSepArg, 0 },
212   { 0, 0, 0, 0 }
213 };
214
215 void
216 screenhack (Display *dpy, Window window)
217 {
218   init_greynetic (dpy, window);
219   while (1)
220     {
221       greynetic (dpy, window);
222       screenhack_handle_events (dpy);
223       if (delay) usleep (delay);
224     }
225 }