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