1 /* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@lucid.com>
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
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
19 * find the screen bitmap for the console and make it "decay" by
20 * randomly shifting random rectangles by one pixelwidth at a time.
23 * rewritten by Natuerlich!
24 * based on a similar "utility" on the Apollo ring at Yale.
28 * Vivek Khera <khera@cs.duke.edu>
32 #include "screenhack.h"
34 static int sizex, sizey;
39 MapNotify_event_p (dpy, event, window)
44 return (event->xany.type == MapNotify &&
45 event->xvisibility.window == (Window) window);
50 screensaver_window_p (dpy, window)
56 unsigned long nitems, bytesafter;
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)
70 init_decay (dpy, window)
75 XWindowAttributes xgwa;
79 delay = get_integer_resource ("delay", "Integer");
80 root_p = get_boolean_resource ("root", "Boolean");
82 if (delay < 0) delay = 0;
84 gcv.function = GXcopy;
85 gcv.subwindow_mode = IncludeInferiors;
86 gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode,
89 pixmap = grab_screen_image (dpy, window, root_p);
91 XGetWindowAttributes (dpy, window, &xgwa);
98 * perform one iteration of decay
105 int left, top, width, height;
107 #define nrnd(x) (random() % (x))
109 switch (random() % 8) {
110 case 0: /* move a block left */
112 left = nrnd(sizex - 1) + 1;
114 width = nrnd(sizex - left);
115 height = nrnd(sizey - top);
116 XCopyArea (dpy, window, window, gc, left, top, width, height,
119 case 2: /* move a block right */
121 left = nrnd(sizex - 1);
123 width = nrnd(sizex - 1 - left);
124 height = nrnd(sizey - top);
125 XCopyArea (dpy, window, window, gc, left, top, width, height,
128 case 4: /* move a block up */
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,
136 default: /* move block down (biased to this) */
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,
150 char *progclass = "DecayScreen";
152 char *defaults [] = {
153 "DecayScreen.mappedWhenManaged:false",
154 "DecayScreen.dontClearWindow: true",
159 XrmOptionDescRec options [] = {
160 { "-delay", ".delay", XrmoptionSepArg, 0 },
163 int options_size = (sizeof (options) / sizeof (options[0]));
166 screenhack (dpy, window)
170 init_decay (dpy, window);
172 decay1 (dpy, window);
173 if (delay) usleep (delay);