http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / deco.c
1 /* xscreensaver, Copyright (c) 1997, 1998, 2002 Jamie Zawinski <jwz@jwz.org>
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  * Concept snarfed from Michael D. Bayne in
12  * http://www.go2net.com/internet/deep/1997/04/16/body.html
13  */
14
15 #include "screenhack.h"
16 #include <stdio.h>
17 #include <time.h>
18 #include <sys/time.h>
19
20 static XColor colors[255];
21 static int ncolors = 0;
22 static int max_depth = 0;
23 static int min_height = 0;
24 static int min_width = 0;
25
26 static void
27 deco (Display *dpy,
28       Window window,
29       Colormap cmap,
30       GC fgc, GC bgc,
31       int x, int y, int w, int h, int depth)
32 {
33   if (((random() % max_depth) < depth) || (w < min_width) || (h < min_height))
34     {
35       if (!mono_p)
36         {
37           static int current_color = 0;
38           if (++current_color >= ncolors)
39             current_color = 0;
40           XSetForeground(dpy, bgc, colors[current_color].pixel);
41         }
42       XFillRectangle (dpy, window, bgc, x, y, w, h);
43       XDrawRectangle (dpy, window, fgc, x, y, w, h);
44     }
45   else
46     {
47       if (random() & 1)
48         {
49           deco (dpy, window, cmap, fgc, bgc, x, y, w/2, h, depth+1);
50           deco (dpy, window, cmap, fgc, bgc, x+w/2, y, w/2, h, depth+1);
51         }
52       else
53         {
54           deco (dpy, window, cmap, fgc, bgc, x, y, w, h/2, depth+1);
55           deco (dpy, window, cmap, fgc, bgc, x, y+h/2, w, h/2, depth+1);
56         }
57     }
58 }
59
60 \f
61 char *progclass = "Deco";
62
63 char *defaults [] = {
64   ".background:         black",
65   ".foreground:         white",
66   "*maxDepth:           12",
67   "*minWidth:           20",
68   "*minHeight:          20",
69   "*cycle:              False",
70   "*delay:              5",
71   "*cycleDelay:         1000000",
72   "*ncolors:            64",
73   0
74 };
75
76 XrmOptionDescRec options [] = {
77   { "-max-depth",       ".maxDepth",    XrmoptionSepArg, 0 },
78   { "-min-width",       ".minWidth",    XrmoptionSepArg, 0 },
79   { "-min-height",      ".minHeight",   XrmoptionSepArg, 0 },
80   { "-delay",           ".delay",       XrmoptionSepArg, 0 },
81   { "-ncolors",         ".ncolors",     XrmoptionSepArg, 0 },
82   { "-cycle",           ".cycle",       XrmoptionNoArg, "True" },
83   { "-no-cycle",        ".cycle",       XrmoptionNoArg, "False" },
84   { "-cycle-delay",     ".cycleDelay",  XrmoptionSepArg, 0 },
85   { 0, 0, 0, 0 }
86 };
87
88 void
89 screenhack (Display *dpy, Window window)
90 {
91   GC fgc, bgc;
92   XGCValues gcv;
93   XWindowAttributes xgwa;
94   int delay = get_integer_resource ("delay", "Integer");
95   int cycle_delay = get_integer_resource ("cycleDelay", "Integer");
96   Bool writable = get_boolean_resource ("cycle", "Boolean");
97
98   max_depth = get_integer_resource ("maxDepth", "Integer");
99   if (max_depth < 1) max_depth = 1;
100   else if (max_depth > 1000) max_depth = 1000;
101
102   min_width = get_integer_resource ("minWidth", "Integer");
103   if (min_width < 2) min_width = 2;
104   min_height = get_integer_resource ("minHeight", "Integer");
105   if (min_height < 2) min_height = 2;
106
107   XGetWindowAttributes (dpy, window, &xgwa);
108
109   gcv.foreground = get_pixel_resource("foreground", "Foreground",
110                                       dpy, xgwa.colormap);
111   fgc = XCreateGC (dpy, window, GCForeground, &gcv);
112
113   gcv.foreground = get_pixel_resource("background", "Background",
114                                       dpy, xgwa.colormap);
115   bgc = XCreateGC (dpy, window, GCForeground, &gcv);
116
117   ncolors = get_integer_resource ("ncolors", "Integer");
118
119   make_random_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors,
120                         False, True, &writable, True);
121
122   if (ncolors <= 2)
123     mono_p = True;
124
125   if (!mono_p)
126     {
127       GC tmp = fgc;
128       fgc = bgc;
129       bgc = tmp;
130     }
131
132   while (1)
133     {
134       XGetWindowAttributes (dpy, window, &xgwa);
135       XFillRectangle(dpy, window, bgc, 0, 0, xgwa.width, xgwa.height);
136       deco (dpy, window, xgwa.colormap, fgc, bgc,
137             0, 0, xgwa.width, xgwa.height, 0);
138       XSync (dpy, False);
139       screenhack_handle_events (dpy);
140
141       if (!delay) continue;
142       if (!writable)
143         sleep (delay);
144       else
145         {
146           time_t start = time((time_t) 0);
147           while (start - delay < time((time_t) 0))
148             {
149               rotate_colors (dpy, xgwa.colormap, colors, ncolors, 1);
150               XSync (dpy, False);
151               screenhack_handle_events (dpy);
152               if (cycle_delay)
153                 usleep (cycle_delay);
154             }
155         }
156     }
157 }