http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / greynetic.c
1 /* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998, 2003, 2006
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 #ifndef HAVE_COCOA
16 # define DO_STIPPLE
17 #endif
18
19 #define NBITS 12
20
21 /* On some systems (notably MacOS X) these files are messed up.
22  * They're tiny, so we might as well just inline them here.
23  *
24  * # include <X11/bitmaps/stipple>
25  * # include <X11/bitmaps/cross_weave>
26  * # include <X11/bitmaps/dimple1>
27  * # include <X11/bitmaps/dimple3>
28  * # include <X11/bitmaps/flipped_gray>
29  * # include <X11/bitmaps/gray1>
30  * # include <X11/bitmaps/gray3>
31  * # include <X11/bitmaps/hlines2>
32  * # include <X11/bitmaps/light_gray>
33  * # include <X11/bitmaps/root_weave>
34  * # include <X11/bitmaps/vlines2>
35  * # include <X11/bitmaps/vlines3>
36 */
37
38 #ifdef DO_STIPPLE
39 #define stipple_width  16
40 #define stipple_height 4
41 static unsigned char stipple_bits[] = {
42   0x55, 0x55, 0xee, 0xee, 0x55, 0x55, 0xba, 0xbb};
43
44 #define cross_weave_width  16
45 #define cross_weave_height 16
46 static unsigned char cross_weave_bits[] = {
47    0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88,
48    0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22,
49    0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22};
50
51 #define dimple1_width 16
52 #define dimple1_height 16
53 static unsigned char dimple1_bits[] = {
54    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
55    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
56    0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00};
57
58 #define dimple3_width 16
59 #define dimple3_height 16
60 static unsigned char dimple3_bits[] = {
61    0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
62    0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63    0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
64
65 #define flipped_gray_width  4
66 #define flipped_gray_height 2
67 static char flipped_gray_bits[] = { 0x07, 0x0d};
68 #define gray1_width  2
69 #define gray1_height 2
70 static char gray1_bits[] = { 0x01, 0x02};
71 #define gray3_width  4
72 #define gray3_height 4
73 static char gray3_bits[] = { 0x01, 0x00, 0x04, 0x00};
74 #define hlines2_width  1
75 #define hlines2_height 2
76 static char hlines2_bits[] = { 0x01, 0x00};
77 #define light_gray_width  4
78 #define light_gray_height 2
79 static char light_gray_bits[] = { 0x08, 0x02};
80 #define root_weave_width  4
81 #define root_weave_height 4
82 static char root_weave_bits[] = { 0x07, 0x0d, 0x0b, 0x0e};
83 #define vlines2_width  2
84 #define vlines2_height 1
85 static char vlines2_bits[] = { 0x01};
86 #define vlines3_width  3
87 #define vlines3_height 1
88 static char vlines3_bits[] = { 0x02};
89
90 #endif /* DO_STIPPLE */
91
92 struct state {
93   Display *dpy;
94   Window window;
95
96   Pixmap pixmaps [NBITS];
97
98   GC gc;
99   int delay;
100   unsigned long fg, bg, pixels [512];
101   int npixels;
102   int xlim, ylim;
103   Colormap cmap;
104 };
105
106
107 static void *
108 greynetic_init (Display *dpy, Window window)
109 {
110   struct state *st = (struct state *) calloc (1, sizeof(*st));
111 # ifdef DO_STIPPLE
112   int i;
113 # endif /* DO_STIPPLE */
114   XGCValues gcv;
115   XWindowAttributes xgwa;
116   st->dpy = dpy;
117   st->window = window;
118
119   XGetWindowAttributes (st->dpy, st->window, &xgwa);
120   st->xlim = xgwa.width;
121   st->ylim = xgwa.height;
122   st->cmap = xgwa.colormap;
123   st->npixels = 0;
124   gcv.foreground= st->fg= get_pixel_resource(st->dpy, st->cmap, "foreground","Foreground");
125   gcv.background= st->bg= get_pixel_resource(st->dpy, st->cmap, "background","Background");
126
127   st->delay = get_integer_resource (st->dpy, "delay", "Integer");
128   if (st->delay < 0) st->delay = 0;
129
130 # ifndef DO_STIPPLE
131   st->gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
132 #  ifdef HAVE_COCOA /* allow non-opaque alpha components in pixel values */
133   jwxyz_XSetAlphaAllowed (st->dpy, st->gc, True);
134 #  endif /* HAVE_COCOA */
135 # else /* DO_STIPPLE */
136   gcv.fill_style= FillOpaqueStippled;
137   st->gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground|GCFillStyle, &gcv);
138   
139   i = 0;
140 # define BITS(n,w,h) \
141   st->pixmaps [i++] = \
142     XCreatePixmapFromBitmapData (st->dpy, st->window, (char *) n, w, h, 1, 0, 1)
143
144   BITS (stipple_bits, stipple_width, stipple_height);
145   BITS (cross_weave_bits, cross_weave_width, cross_weave_height);
146   BITS (dimple1_bits, dimple1_width, dimple1_height);
147   BITS (dimple3_bits, dimple3_width, dimple3_height);
148   BITS (flipped_gray_bits, flipped_gray_width, flipped_gray_height);
149   BITS (gray1_bits, gray1_width, gray1_height);
150   BITS (gray3_bits, gray3_width, gray3_height);
151   BITS (hlines2_bits, hlines2_width, hlines2_height);
152   BITS (light_gray_bits, light_gray_width, light_gray_height);
153   BITS (root_weave_bits, root_weave_width, root_weave_height);
154   BITS (vlines2_bits, vlines2_width, vlines2_height);
155   BITS (vlines3_bits, vlines3_width, vlines3_height);
156 # endif /* DO_STIPPLE */
157   return st;
158 }
159
160 static unsigned long
161 greynetic_draw (Display *dpy, Window window, void *closure)
162 {
163   struct state *st = (struct state *) closure;
164   int x, y, w=0, h=0, i;
165   XGCValues gcv;
166
167   for (i = 0; i < 10; i++) /* minimize area, but don't try too hard */
168     {
169       w = 50 + random () % (st->xlim - 50);
170       h = 50 + random () % (st->ylim - 50);
171       if (w + h < st->xlim && w + h < st->ylim)
172         break;
173     }
174   x = random () % (st->xlim - w);
175   y = random () % (st->ylim - h);
176 # ifdef DO_STIPPLE
177   gcv.stipple = st->pixmaps [random () % NBITS];
178 # endif /* !DO_STIPPLE */
179   if (mono_p)
180     {
181     MONO:
182       if (random () & 1)
183         gcv.foreground = st->fg, gcv.background = st->bg;
184       else
185         gcv.foreground = st->bg, gcv.background = st->fg;
186     }
187   else
188     {
189       XColor fgc, bgc;
190       if (st->npixels == sizeof (st->pixels) / sizeof (unsigned long))
191         goto REUSE;
192       fgc.flags = bgc.flags = DoRed|DoGreen|DoBlue;
193       fgc.red = random ();
194       fgc.green = random ();
195       fgc.blue = random ();
196 # ifdef DO_STIPPLE
197       bgc.red = random ();
198       bgc.green = random ();
199       bgc.blue = random ();
200 # endif /* DO_STIPPLE */
201
202       if (! XAllocColor (st->dpy, st->cmap, &fgc))
203         goto REUSE;
204       st->pixels [st->npixels++] = fgc.pixel;
205       gcv.foreground = fgc.pixel;
206 # ifdef DO_STIPPLE
207       if (! XAllocColor (st->dpy, st->cmap, &bgc))
208         goto REUSE;
209       st->pixels [st->npixels++] = bgc.pixel;
210       gcv.background = bgc.pixel;
211 # endif /* DO_STIPPLE */
212       goto DONE;
213     REUSE:
214       if (st->npixels <= 0)
215         {
216           mono_p = 1;
217           goto MONO;
218         }
219       gcv.foreground = st->pixels [random () % st->npixels];
220 # ifdef DO_STIPPLE
221       gcv.background = st->pixels [random () % st->npixels];
222 # endif /* DO_STIPPLE */
223     DONE:
224       ;
225
226 # ifdef HAVE_COCOA
227       {
228         /* give a non-opaque alpha to the color */
229         unsigned long pixel = gcv.foreground;
230         unsigned long amask = BlackPixelOfScreen (0);
231         unsigned long a = (random() & amask);
232         pixel = (pixel & (~amask)) | a;
233         gcv.foreground = pixel;
234       }
235 # endif /* !HAVE_COCOA */
236     }
237 # ifndef DO_STIPPLE
238   XChangeGC (st->dpy, st->gc, GCForeground, &gcv);
239 # else  /* DO_STIPPLE */
240   XChangeGC (st->dpy, st->gc, GCStipple|GCForeground|GCBackground, &gcv);
241 # endif /* DO_STIPPLE */
242   XFillRectangle (st->dpy, st->window, st->gc, x, y, w, h);
243   return st->delay;
244 }
245
246 \f
247 static const char *greynetic_defaults [] = {
248   ".background: black",
249   ".foreground: white",
250   "*delay:      10000",
251   0
252 };
253
254 static XrmOptionDescRec greynetic_options [] = {
255   { "-delay",           ".delay",       XrmoptionSepArg, 0 },
256   { 0, 0, 0, 0 }
257 };
258
259 static void
260 greynetic_reshape (Display *dpy, Window window, void *closure, 
261                  unsigned int w, unsigned int h)
262 {
263   struct state *st = (struct state *) closure;
264   st->xlim = w;
265   st->ylim = h;
266 }
267
268 static Bool
269 greynetic_event (Display *dpy, Window window, void *closure, XEvent *event)
270 {
271   return False;
272 }
273
274 static void
275 greynetic_free (Display *dpy, Window window, void *closure)
276 {
277 }
278
279 XSCREENSAVER_MODULE ("Greynetic", greynetic)
280