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