ftp://ftp.zenez.com/pub/SCO/Skunk96/UnixWare/FreeBird/x11/utils/xscreensaver-1.18...
[xscreensaver] / hacks / decayscreen.c
1 /* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@lucid.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 /* decayscreen
13  *
14  * Based on slidescreen program from the xscreensaver application and the
15  * decay program for Sun framebuffers.  This is the comment from the decay.c
16  * file:
17
18  * decay.c
19  *   find the screen bitmap for the console and make it "decay" by
20  *   randomly shifting random rectangles by one pixelwidth at a time.
21  *
22  *   by David Wald, 1988
23  *        rewritten by Natuerlich!
24  *   based on a similar "utility" on the Apollo ring at Yale.
25
26  * X version by
27  *
28  *  Vivek Khera <khera@cs.duke.edu>
29  *  5-AUG-1993
30  */
31
32 #include "screenhack.h"
33
34 static int sizex, sizey;
35 static int delay;
36 static GC gc;
37
38 static Bool
39 MapNotify_event_p (dpy, event, window)
40      Display *dpy;
41      XEvent *event;
42      XPointer window;
43 {
44   return (event->xany.type == MapNotify &&
45           event->xvisibility.window == (Window) window);
46 }
47
48
49 static Bool
50 screensaver_window_p (dpy, window)
51      Display *dpy;
52      Window window;
53 {
54   Atom type;
55   int format;
56   unsigned long nitems, bytesafter;
57   char *version;
58   if (XGetWindowProperty (dpy, window,
59                           XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
60                           0, 1, False, XA_STRING,
61                           &type, &format, &nitems, &bytesafter,
62                           (unsigned char **) &version)
63       == Success
64       && type != None)
65     return True;
66   return False;
67 }
68
69 static void
70 init_decay (dpy, window)
71      Display *dpy;
72      Window window;
73 {
74   XGCValues gcv;
75   XWindowAttributes xgwa;
76   int root_p;
77   Pixmap pixmap;
78
79   delay = get_integer_resource ("delay", "Integer");
80   root_p = get_boolean_resource ("root", "Boolean");
81
82   if (delay < 0) delay = 0;
83
84   gcv.function = GXcopy;
85   gcv.subwindow_mode = IncludeInferiors;
86   gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode,
87                   &gcv);
88
89   pixmap = grab_screen_image (dpy, window, root_p);
90
91   XGetWindowAttributes (dpy, window, &xgwa);
92   sizex = xgwa.width;
93   sizey = xgwa.height;
94 }
95
96
97 /*
98  * perform one iteration of decay
99  */
100 static void
101 decay1 (dpy, window)
102      Display *dpy;
103      Window window;
104 {
105     int left, top, width, height;
106
107 #define nrnd(x) (random() % (x))
108
109     switch (random() % 8) {
110       case 0:                   /* move a block left */
111       case 1:
112         left = nrnd(sizex - 1) + 1;
113         top = nrnd(sizey);
114         width = nrnd(sizex - left);
115         height = nrnd(sizey - top);
116         XCopyArea (dpy, window, window, gc, left, top, width, height,
117                    left - 1, top);
118         break;
119       case 2:                   /* move a block right */
120       case 3:
121         left = nrnd(sizex - 1);
122         top = nrnd(sizey);
123         width = nrnd(sizex - 1 - left);
124         height = nrnd(sizey - top);
125         XCopyArea (dpy, window, window, gc, left, top, width, height,
126                    left + 1, top);
127         break;
128       case 4:                   /* move a block up */
129         left = nrnd(sizex);
130         top = nrnd(sizey - 1) + 1;
131         width = nrnd(sizex - left);
132         height = nrnd(sizey - top);
133         XCopyArea (dpy, window, window, gc, left, top, width, height,
134                    left, top - 1);
135         break;
136       default:                  /* move block down (biased to this) */
137         left = nrnd(sizex);
138         top = nrnd(sizey - 1);
139         width = nrnd(sizex - left);
140         height = nrnd(sizey - 1 - top);
141         XCopyArea (dpy, window, window, gc, left, top, width, height,
142                    left, top + 1);
143         break;
144     }
145     XSync (dpy, True);
146 #undef nrnd
147 }
148
149 \f
150 char *progclass = "DecayScreen";
151
152 char *defaults [] = {
153   "DecayScreen.mappedWhenManaged:false",
154   "DecayScreen.dontClearWindow:  true",
155   "*delay:                      10",
156   0
157 };
158
159 XrmOptionDescRec options [] = {
160   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
161 };
162
163 int options_size = (sizeof (options) / sizeof (options[0]));
164
165 void
166 screenhack (dpy, window)
167      Display *dpy;
168      Window window;
169 {
170     init_decay (dpy, window);
171     while (1) {
172         decay1 (dpy, window);
173         if (delay) usleep (delay);
174     }
175 }