http://svn.poeml.de/viewvc/ppc/src-unpacked/xscreensaver/xscreensaver-4.12.tar.bz2...
[xscreensaver] / hacks / greynetic.c
1 /* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998, 2003
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 unsigned char stipple_bits[] = {
37   0x55, 0x55, 0xee, 0xee, 0x55, 0x55, 0xba, 0xbb};
38
39 #define cross_weave_width  16
40 #define cross_weave_height 16
41 static unsigned char cross_weave_bits[] = {
42    0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88,
43    0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22,
44    0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22};
45
46 #define dimple1_width 16
47 #define dimple1_height 16
48 static unsigned char dimple1_bits[] = {
49    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
50    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
51    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00};
52
53 #define dimple3_width 16
54 #define dimple3_height 16
55 static unsigned char dimple3_bits[] = {
56    0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
57    0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58    0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
59
60 #define flipped_gray_width  4
61 #define flipped_gray_height 2
62 static char flipped_gray_bits[] = { 0x07, 0x0d};
63 #define gray1_width  2
64 #define gray1_height 2
65 static char gray1_bits[] = { 0x01, 0x02};
66 #define gray3_width  4
67 #define gray3_height 4
68 static char gray3_bits[] = { 0x01, 0x00, 0x04, 0x00};
69 #define hlines2_width  1
70 #define hlines2_height 2
71 static char hlines2_bits[] = { 0x01, 0x00};
72 #define light_gray_width  4
73 #define light_gray_height 2
74 static char light_gray_bits[] = { 0x08, 0x02};
75 #define root_weave_width  4
76 #define root_weave_height 4
77 static char root_weave_bits[] = { 0x07, 0x0d, 0x0b, 0x0e};
78 #define vlines2_width  2
79 #define vlines2_height 1
80 static char vlines2_bits[] = { 0x01};
81 #define vlines3_width  3
82 #define vlines3_height 1
83 static char vlines3_bits[] = { 0x02};
84
85
86
87
88 static Pixmap pixmaps [NBITS];
89 static GC gc;
90 static int delay;
91 static unsigned long fg, bg, pixels [512];
92 static int npixels;
93
94 static void
95 init_greynetic (Display *dpy, Window window)
96 {
97   int i;
98   XGCValues gcv;
99   XWindowAttributes xgwa;
100   Colormap cmap;
101   XGetWindowAttributes (dpy, window, &xgwa);
102   cmap = xgwa.colormap;
103   npixels = 0;
104   gcv.foreground= fg= get_pixel_resource("foreground","Foreground", dpy, cmap);
105   gcv.background= bg= get_pixel_resource("background","Background", dpy, cmap);
106   gcv.fill_style= FillOpaqueStippled;
107   gc = XCreateGC (dpy, window, GCForeground|GCBackground|GCFillStyle, &gcv);
108
109   delay = get_integer_resource ("delay", "Integer");
110   if (delay < 0) delay = 0;
111
112   i = 0;
113 #define BITS(n,w,h) \
114   pixmaps [i++] = \
115     XCreatePixmapFromBitmapData (dpy, window, (char *) n, w, h, 1, 0, 1)
116
117   BITS (stipple_bits, stipple_width, stipple_height);
118   BITS (cross_weave_bits, cross_weave_width, cross_weave_height);
119   BITS (dimple1_bits, dimple1_width, dimple1_height);
120   BITS (dimple3_bits, dimple3_width, dimple3_height);
121   BITS (flipped_gray_bits, flipped_gray_width, flipped_gray_height);
122   BITS (gray1_bits, gray1_width, gray1_height);
123   BITS (gray3_bits, gray3_width, gray3_height);
124   BITS (hlines2_bits, hlines2_width, hlines2_height);
125   BITS (light_gray_bits, light_gray_width, light_gray_height);
126   BITS (root_weave_bits, root_weave_width, root_weave_height);
127   BITS (vlines2_bits, vlines2_width, vlines2_height);
128   BITS (vlines3_bits, vlines3_width, vlines3_height);
129 }
130
131 static void
132 greynetic (Display *dpy, Window window)
133 {
134   static int tick = 500, xlim, ylim;
135   static Colormap cmap;
136   int x, y, w=0, h=0, i;
137   XGCValues gcv;
138   if (tick++ == 500)
139     {
140       XWindowAttributes xgwa;
141       XGetWindowAttributes (dpy, window, &xgwa);
142       tick = 0;
143       xlim = xgwa.width;
144       ylim = xgwa.height;
145       cmap = xgwa.colormap;
146     }
147   for (i = 0; i < 10; i++) /* minimize area, but don't try too hard */
148     {
149       w = 50 + random () % (xlim - 50);
150       h = 50 + random () % (ylim - 50);
151       if (w + h < xlim && w + h < ylim)
152         break;
153     }
154   x = random () % (xlim - w);
155   y = random () % (ylim - h);
156   gcv.stipple = pixmaps [random () % NBITS];
157   if (mono_p)
158     {
159     MONO:
160       if (random () & 1)
161         gcv.foreground = fg, gcv.background = bg;
162       else
163         gcv.foreground = bg, gcv.background = fg;
164     }
165   else
166     {
167       XColor fgc, bgc;
168       if (npixels == sizeof (pixels) / sizeof (unsigned long))
169         goto REUSE;
170       fgc.flags = bgc.flags = DoRed|DoGreen|DoBlue;
171       fgc.red = random ();
172       fgc.green = random ();
173       fgc.blue = random ();
174       bgc.red = random ();
175       bgc.green = random ();
176       bgc.blue = random ();
177       if (! XAllocColor (dpy, cmap, &fgc))
178         goto REUSE;
179       pixels [npixels++] = fgc.pixel;
180       gcv.foreground = fgc.pixel;
181       if (! XAllocColor (dpy, cmap, &bgc))
182         goto REUSE;
183       pixels [npixels++] = bgc.pixel;
184       gcv.background = bgc.pixel;
185       goto DONE;
186     REUSE:
187       if (npixels <= 0)
188         {
189           mono_p = 1;
190           goto MONO;
191         }
192       gcv.foreground = pixels [random () % npixels];
193       gcv.background = pixels [random () % npixels];
194     DONE:
195       ;
196     }
197   XChangeGC (dpy, gc, GCStipple|GCForeground|GCBackground, &gcv);
198   XFillRectangle (dpy, window, gc, x, y, w, h);
199   XSync (dpy, False);
200 }
201
202 \f
203 char *progclass = "Greynetic";
204
205 char *defaults [] = {
206   ".background: black",
207   ".foreground: white",
208   "*delay:      10000",
209   0
210 };
211
212 XrmOptionDescRec options [] = {
213   { "-delay",           ".delay",       XrmoptionSepArg, 0 },
214   { 0, 0, 0, 0 }
215 };
216
217 void
218 screenhack (Display *dpy, Window window)
219 {
220   init_greynetic (dpy, window);
221   while (1)
222     {
223       greynetic (dpy, window);
224       screenhack_handle_events (dpy);
225       if (delay) usleep (delay);
226     }
227 }