http://se.aminet.net/pub/X11/ftp.x.org/contrib/vms/xscreensaver-124.zip
[xscreensaver] / hacks / decayscreen.c
1 /* xscreensaver, Copyright (c) 1992, 1993, 1994 Jamie Zawinski <jwz@mcom.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 void
39 init_decay (dpy, window)
40      Display *dpy;
41      Window window;
42 {
43   XGCValues gcv;
44   XWindowAttributes xgwa;
45   int root_p;
46   Pixmap pixmap;
47
48   delay = get_integer_resource ("delay", "Integer");
49   root_p = get_boolean_resource ("root", "Boolean");
50
51   if (delay < 0) delay = 0;
52
53   gcv.function = GXcopy;
54   gcv.subwindow_mode = IncludeInferiors;
55   gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode,
56                   &gcv);
57
58   XGetWindowAttributes (dpy, window, &xgwa);
59   sizex = xgwa.width;
60   sizey = xgwa.height;
61
62   copy_default_colormap_contents (dpy, xgwa.colormap, xgwa.visual);
63   pixmap = grab_screen_image (dpy, window, root_p);
64 }
65
66
67 /*
68  * perform one iteration of decay
69  */
70 static void
71 decay1 (dpy, window)
72      Display *dpy;
73      Window window;
74 {
75     int left, top, width, height;
76
77 #define nrnd(x) (random() % (x))
78
79     switch (random() % 8) {
80       case 0:                   /* move a block left */
81       case 1:
82         left = nrnd(sizex - 1) + 1;
83         top = nrnd(sizey);
84         width = nrnd(sizex - left);
85         height = nrnd(sizey - top);
86         XCopyArea (dpy, window, window, gc, left, top, width, height,
87                    left - 1, top);
88         break;
89       case 2:                   /* move a block right */
90       case 3:
91         left = nrnd(sizex - 1);
92         top = nrnd(sizey);
93         width = nrnd(sizex - 1 - left);
94         height = nrnd(sizey - top);
95         XCopyArea (dpy, window, window, gc, left, top, width, height,
96                    left + 1, top);
97         break;
98       case 4:                   /* move a block up */
99         left = nrnd(sizex);
100         top = nrnd(sizey - 1) + 1;
101         width = nrnd(sizex - left);
102         height = nrnd(sizey - top);
103         XCopyArea (dpy, window, window, gc, left, top, width, height,
104                    left, top - 1);
105         break;
106       default:                  /* move block down (biased to this) */
107         left = nrnd(sizex);
108         top = nrnd(sizey - 1);
109         width = nrnd(sizex - left);
110         height = nrnd(sizey - 1 - top);
111         XCopyArea (dpy, window, window, gc, left, top, width, height,
112                    left, top + 1);
113         break;
114     }
115     XSync (dpy, True);
116 #undef nrnd
117 }
118
119 \f
120 char *progclass = "DecayScreen";
121
122 char *defaults [] = {
123   "DecayScreen.mappedWhenManaged:false",
124   "DecayScreen.dontClearWindow:  true",
125   "*delay:                      10",
126   0
127 };
128
129 XrmOptionDescRec options [] = {
130   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
131 };
132
133 int options_size = (sizeof (options) / sizeof (options[0]));
134
135 void
136 screenhack (dpy, window)
137      Display *dpy;
138      Window window;
139 {
140     init_decay (dpy, window);
141     while (1) {
142         decay1 (dpy, window);
143         if (delay) usleep (delay);
144     }
145 }