http://ftp.x.org/contrib/applications/xscreensaver-2.23.tar.gz
[xscreensaver] / hacks / greynetic.c
1 /* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997
2  *  Jamie Zawinski <jwz@netscape.com>
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 #ifndef VMS
18 # include <X11/bitmaps/stipple>
19 # include <X11/bitmaps/cross_weave>
20 # include <X11/bitmaps/dimple1>
21 # include <X11/bitmaps/dimple3>
22 # include <X11/bitmaps/flipped_gray>
23 # include <X11/bitmaps/gray1>
24 # include <X11/bitmaps/gray3>
25 # include <X11/bitmaps/hlines2>
26 # include <X11/bitmaps/light_gray>
27 # include <X11/bitmaps/root_weave>
28 # include <X11/bitmaps/vlines2>
29 # include <X11/bitmaps/vlines3>
30 #else /* VMS */
31 # include "sys$common:[decw$include.bitmaps]stipple.xbm"
32 # include "sys$common:[decw$include.bitmaps]cross_weave.xbm"
33 # include "sys$common:[decw$include.bitmaps]dimple1.xbm"
34 # include "sys$common:[decw$include.bitmaps]dimple3.xbm"
35 # include "sys$common:[decw$include.bitmaps]flipped_gray.xbm"
36 # include "sys$common:[decw$include.bitmaps]gray1.xbm"
37 # include "sys$common:[decw$include.bitmaps]gray3.xbm"
38 # include "sys$common:[decw$include.bitmaps]hlines2.xbm"
39 # include "sys$common:[decw$include.bitmaps]light_gray.xbm"
40 # include "sys$common:[decw$include.bitmaps]root_weave.xbm"
41 # include "sys$common:[decw$include.bitmaps]vlines2.xbm"
42 # include "sys$common:[decw$include.bitmaps]vlines3.xbm"
43 #endif /* VMS */
44
45 static Pixmap pixmaps [NBITS];
46 static GC gc;
47 static int delay;
48 static unsigned long fg, bg, pixels [512];
49 static int npixels;
50
51 static void
52 init_greynetic (Display *dpy, Window window)
53 {
54   int i;
55   XGCValues gcv;
56   XWindowAttributes xgwa;
57   Colormap cmap;
58   XGetWindowAttributes (dpy, window, &xgwa);
59   cmap = xgwa.colormap;
60   npixels = 0;
61   gcv.foreground= fg= get_pixel_resource("foreground","Foreground", dpy, cmap);
62   gcv.background= bg= get_pixel_resource("background","Background", dpy, cmap);
63   gcv.fill_style= FillOpaqueStippled;
64   gc = XCreateGC (dpy, window, GCForeground|GCBackground|GCFillStyle, &gcv);
65
66   delay = get_integer_resource ("delay", "Integer");
67   if (delay < 0) delay = 0;
68
69   i = 0;
70 #define BITS(n,w,h) \
71   pixmaps [i++] = XCreatePixmapFromBitmapData (dpy, window, n, w, h, 1, 0, 1)
72
73   BITS (stipple_bits, stipple_width, stipple_height);
74   BITS (cross_weave_bits, cross_weave_width, cross_weave_height);
75   BITS (dimple1_bits, dimple1_width, dimple1_height);
76   BITS (dimple3_bits, dimple3_width, dimple3_height);
77   BITS (flipped_gray_bits, flipped_gray_width, flipped_gray_height);
78   BITS (gray1_bits, gray1_width, gray1_height);
79   BITS (gray3_bits, gray3_width, gray3_height);
80   BITS (hlines2_bits, hlines2_width, hlines2_height);
81   BITS (light_gray_bits, light_gray_width, light_gray_height);
82   BITS (root_weave_bits, root_weave_width, root_weave_height);
83   BITS (vlines2_bits, vlines2_width, vlines2_height);
84   BITS (vlines3_bits, vlines3_width, vlines3_height);
85 }
86
87 static void
88 greynetic (Display *dpy, Window window)
89 {
90   static int tick = 500, xlim, ylim;
91   static Colormap cmap;
92   int x, y, w, h, i;
93   XGCValues gcv;
94   if (tick++ == 500)
95     {
96       XWindowAttributes xgwa;
97       XGetWindowAttributes (dpy, window, &xgwa);
98       tick = 0;
99       xlim = xgwa.width;
100       ylim = xgwa.height;
101       cmap = xgwa.colormap;
102     }
103   for (i = 0; i < 10; i++) /* minimize area, but don't try too hard */
104     {
105       w = 50 + random () % (xlim - 50);
106       h = 50 + random () % (ylim - 50);
107       if (w + h < xlim && w + h < ylim)
108         break;
109     }
110   x = random () % (xlim - w);
111   y = random () % (ylim - h);
112   gcv.stipple = pixmaps [random () % NBITS];
113   if (mono_p)
114     {
115     MONO:
116       if (random () & 1)
117         gcv.foreground = fg, gcv.background = bg;
118       else
119         gcv.foreground = bg, gcv.background = fg;
120     }
121   else
122     {
123       XColor fgc, bgc;
124       if (npixels == sizeof (pixels) / sizeof (unsigned long))
125         goto REUSE;
126       fgc.flags = bgc.flags = DoRed|DoGreen|DoBlue;
127       fgc.red = random ();
128       fgc.green = random ();
129       fgc.blue = random ();
130       bgc.red = random ();
131       bgc.green = random ();
132       bgc.blue = random ();
133       if (! XAllocColor (dpy, cmap, &fgc))
134         goto REUSE;
135       pixels [npixels++] = fgc.pixel;
136       gcv.foreground = fgc.pixel;
137       if (! XAllocColor (dpy, cmap, &bgc))
138         goto REUSE;
139       pixels [npixels++] = bgc.pixel;
140       gcv.background = bgc.pixel;
141       goto DONE;
142     REUSE:
143       if (npixels <= 0)
144         {
145           mono_p = 1;
146           goto MONO;
147         }
148       gcv.foreground = pixels [random () % npixels];
149       gcv.background = pixels [random () % npixels];
150     DONE:
151       ;
152     }
153   XChangeGC (dpy, gc, GCStipple|GCForeground|GCBackground, &gcv);
154   XFillRectangle (dpy, window, gc, x, y, w, h);
155   XSync (dpy, True);
156 }
157
158 \f
159 char *progclass = "Greynetic";
160
161 char *defaults [] = {
162   ".background: black",
163   ".foreground: white",
164   "*delay:      0",
165   0
166 };
167
168 XrmOptionDescRec options [] = {
169   { "-delay",           ".delay",       XrmoptionSepArg, 0 },
170   { 0, 0, 0, 0 }
171 };
172
173 void
174 screenhack (Display *dpy, Window window)
175 {
176   init_greynetic (dpy, window);
177   while (1)
178     {
179       greynetic (dpy, window);
180       if (delay) usleep (delay);
181     }
182 }