1 /* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997
2 * Jamie Zawinski <jwz@jwz.org>
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
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
20 * find the screen bitmap for the console and make it "decay" by
21 * randomly shifting random rectangles by one pixelwidth at a time.
24 * rewritten by Natuerlich!
25 * based on a similar "utility" on the Apollo ring at Yale.
29 * Vivek Khera <khera@cs.duke.edu>
32 * Hacked by jwz, 28-Nov-97 (sped up and added new motion directions)
35 #include "screenhack.h"
37 static int sizex, sizey;
56 init_decay (Display *dpy, Window window)
59 XWindowAttributes xgwa;
62 char *s = get_string_resource("mode", "Mode");
63 if (s && !strcmp(s, "shuffle")) mode = SHUFFLE;
64 else if (s && !strcmp(s, "up")) mode = UP;
65 else if (s && !strcmp(s, "left")) mode = LEFT;
66 else if (s && !strcmp(s, "right")) mode = RIGHT;
67 else if (s && !strcmp(s, "down")) mode = DOWN;
68 else if (s && !strcmp(s, "upleft")) mode = UPLEFT;
69 else if (s && !strcmp(s, "downleft")) mode = DOWNLEFT;
70 else if (s && !strcmp(s, "upright")) mode = UPRIGHT;
71 else if (s && !strcmp(s, "downright")) mode = DOWNRIGHT;
72 else if (s && !strcmp(s, "in")) mode = IN;
73 else if (s && !strcmp(s, "out")) mode = OUT;
75 if (s && *s && !!strcmp(s, "random"))
76 fprintf(stderr, "%s: unknown mode %s\n", progname, s);
77 mode = random() % (OUT+1);
80 delay = get_integer_resource ("delay", "Integer");
82 if (delay < 0) delay = 0;
84 XGetWindowAttributes (dpy, window, &xgwa);
86 gcv.function = GXcopy;
87 gcv.subwindow_mode = IncludeInferiors;
88 gcflags = GCForeground |GCFunction;
89 if (use_subwindow_mode_p(xgwa.screen, window)) /* see grabscreen.c */
90 gcflags |= GCSubwindowMode;
91 gc = XCreateGC (dpy, window, gcflags, &gcv);
96 grab_screen_image (xgwa.screen, window);
101 * perform one iteration of decay
104 decay1 (Display *dpy, Window window)
106 int left, top, width, height, toleft, totop;
112 static int no_bias[] = { L,L,L,L, R,R,R,R, U,U,U,U, D,D,D,D };
113 static int up_bias[] = { L,L,L,L, R,R,R,R, U,U,U,U, U,U,D,D };
114 static int down_bias[] = { L,L,L,L, R,R,R,R, U,U,D,D, D,D,D,D };
115 static int left_bias[] = { L,L,L,L, L,L,R,R, U,U,U,U, D,D,D,D };
116 static int right_bias[] = { L,L,R,R, R,R,R,R, U,U,U,U, D,D,D,D };
118 static int upleft_bias[] = { L,L,L,L, L,R,R,R, U,U,U,U, U,D,D,D };
119 static int downleft_bias[] = { L,L,L,L, L,R,R,R, U,U,U,D, D,D,D,D };
120 static int upright_bias[] = { L,L,L,R, R,R,R,R, U,U,U,U, U,D,D,D };
121 static int downright_bias[] = { L,L,L,R, R,R,R,R, U,U,U,D, D,D,D,D };
125 case SHUFFLE: bias = no_bias; break;
126 case UP: bias = up_bias; break;
127 case LEFT: bias = left_bias; break;
128 case RIGHT: bias = right_bias; break;
129 case DOWN: bias = down_bias; break;
130 case UPLEFT: bias = upleft_bias; break;
131 case DOWNLEFT: bias = downleft_bias; break;
132 case UPRIGHT: bias = upright_bias; break;
133 case DOWNRIGHT: bias = downright_bias; break;
134 case IN: bias = no_bias; break;
135 case OUT: bias = no_bias; break;
139 #define nrnd(x) (random() % (x))
141 left = nrnd(sizex - 1);
143 width = nrnd(sizex - left);
144 height = nrnd(sizey - top);
149 if (mode == IN || mode == OUT) {
150 int x = left+(width/2);
151 int y = top+(height/2);
155 if (x > cx && y > cy) bias = upleft_bias;
156 else if (x < cx && y > cy) bias = upright_bias;
157 else if (x < cx && y < cy) bias = downright_bias;
158 else /* (x > cx && y < cy)*/ bias = downleft_bias;
160 if (x > cx && y > cy) bias = downright_bias;
161 else if (x < cx && y > cy) bias = downleft_bias;
162 else if (x < cx && y < cy) bias = upleft_bias;
163 else /* (x > cx && y < cy)*/ bias = upright_bias;
167 switch (bias[random() % (sizeof(no_bias)/sizeof(*no_bias))]) {
168 case L: toleft = left-1; break;
169 case R: toleft = left+1; break;
170 case U: totop = top-1; break;
171 case D: totop = top+1; break;
172 default: abort(); break;
175 XCopyArea (dpy, window, window, gc, left, top, width, height,
181 char *progclass = "DecayScreen";
183 char *defaults [] = {
184 "*dontClearRoot: True",
186 #ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */
195 XrmOptionDescRec options [] = {
196 { "-delay", ".delay", XrmoptionSepArg, 0 },
197 { "-mode", ".mode", XrmoptionSepArg, 0 },
202 screenhack (Display *dpy, Window window)
204 init_decay (dpy, window);
207 for (i = 0; i < 100; i++)
208 decay1 (dpy, window);
210 screenhack_handle_events (dpy);
211 if (delay) usleep (delay);