http://www.ibiblio.org/pub/historic-linux/ftp-archives/sunsite.unc.edu/Sep-29-1996...
[xscreensaver] / hacks / decayscreen.c
1 /* xscreensaver, Copyright (c) 1992, 1993, 1994 
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 /* decayscreen
14  *
15  * Based on slidescreen program from the xscreensaver application and the
16  * decay program for Sun framebuffers.  This is the comment from the decay.c
17  * file:
18
19  * decay.c
20  *   find the screen bitmap for the console and make it "decay" by
21  *   randomly shifting random rectangles by one pixelwidth at a time.
22  *
23  *   by David Wald, 1988
24  *        rewritten by Natuerlich!
25  *   based on a similar "utility" on the Apollo ring at Yale.
26
27  * X version by
28  *
29  *  Vivek Khera <khera@cs.duke.edu>
30  *  5-AUG-1993
31  */
32
33 #include "screenhack.h"
34
35 static int sizex, sizey;
36 static int delay;
37 static GC gc;
38
39 static void
40 init_decay (dpy, window)
41      Display *dpy;
42      Window window;
43 {
44   XGCValues gcv;
45   XWindowAttributes xgwa;
46   int root_p;
47   Pixmap pixmap;
48
49   delay = get_integer_resource ("delay", "Integer");
50   root_p = get_boolean_resource ("root", "Boolean");
51
52   if (delay < 0) delay = 0;
53
54   gcv.function = GXcopy;
55   gcv.subwindow_mode = IncludeInferiors;
56   gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode,
57                   &gcv);
58
59   XGetWindowAttributes (dpy, window, &xgwa);
60   sizex = xgwa.width;
61   sizey = xgwa.height;
62
63   copy_default_colormap_contents (dpy, xgwa.colormap, xgwa.visual);
64   pixmap = grab_screen_image (dpy, window, root_p);
65 }
66
67
68 /*
69  * perform one iteration of decay
70  */
71 static void
72 decay1 (dpy, window)
73      Display *dpy;
74      Window window;
75 {
76     int left, top, width, height;
77
78 #define nrnd(x) (random() % (x))
79
80     switch (random() % 8) {
81       case 0:                   /* move a block left */
82       case 1:
83         left = nrnd(sizex - 1) + 1;
84         top = nrnd(sizey);
85         width = nrnd(sizex - left);
86         height = nrnd(sizey - top);
87         XCopyArea (dpy, window, window, gc, left, top, width, height,
88                    left - 1, top);
89         break;
90       case 2:                   /* move a block right */
91       case 3:
92         left = nrnd(sizex - 1);
93         top = nrnd(sizey);
94         width = nrnd(sizex - 1 - left);
95         height = nrnd(sizey - top);
96         XCopyArea (dpy, window, window, gc, left, top, width, height,
97                    left + 1, top);
98         break;
99       case 4:                   /* move a block up */
100         left = nrnd(sizex);
101         top = nrnd(sizey - 1) + 1;
102         width = nrnd(sizex - left);
103         height = nrnd(sizey - top);
104         XCopyArea (dpy, window, window, gc, left, top, width, height,
105                    left, top - 1);
106         break;
107       default:                  /* move block down (biased to this) */
108         left = nrnd(sizex);
109         top = nrnd(sizey - 1);
110         width = nrnd(sizex - left);
111         height = nrnd(sizey - 1 - top);
112         XCopyArea (dpy, window, window, gc, left, top, width, height,
113                    left, top + 1);
114         break;
115     }
116     XSync (dpy, True);
117 #undef nrnd
118 }
119
120 \f
121 char *progclass = "DecayScreen";
122
123 char *defaults [] = {
124   "DecayScreen.mappedWhenManaged:false",
125   "DecayScreen.dontClearWindow:  true",
126   "*delay:                      10",
127   0
128 };
129
130 XrmOptionDescRec options [] = {
131   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
132 };
133
134 int options_size = (sizeof (options) / sizeof (options[0]));
135
136 void
137 screenhack (dpy, window)
138      Display *dpy;
139      Window window;
140 {
141     init_decay (dpy, window);
142     while (1) {
143         decay1 (dpy, window);
144         if (delay) usleep (delay);
145     }
146 }