1 /* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997
2 * Jamie Zawinski <jwz@netscape.com>
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
13 #include "screenhack.h"
17 static int hole_x, hole_y;
18 static int bitmap_w, bitmap_h;
19 static int xoff, yoff;
20 static int grid_w, grid_h;
21 static int delay, delay2;
23 int max_width, max_height;
26 init_slide (Display *dpy, Window window)
30 XWindowAttributes xgwa;
37 XGetWindowAttributes (dpy, window, &xgwa);
40 max_width = xgwa.width;
41 max_height = xgwa.height;
43 delay = get_integer_resource ("delay", "Integer");
44 delay2 = get_integer_resource ("delay2", "Integer");
45 grid_size = get_integer_resource ("gridSize", "Integer");
46 pix_inc = get_integer_resource ("pixelIncrement", "Integer");
47 border = get_integer_resource ("internalBorderWidth", "InternalBorderWidth");
48 fg = get_pixel_resource ("background", "Background", dpy, cmap);
50 grab_screen_image (xgwa.screen, window);
53 /* Total kludge -- if grab_screen_image() installed a new colormap, assume
54 that pixel 0 is the one we should use. This further assumes that the
55 pixel is black, which overrides the user's -background setting, alas.
57 XGetWindowAttributes (dpy, window, &xgwa);
58 if (cmap != xgwa.colormap) fg = 0;
61 if (delay < 0) delay = 0;
62 if (delay2 < 0) delay2 = 0;
63 if (pix_inc < 1) pix_inc = 1;
64 if (grid_size < 1) grid_size = 1;
67 gcv.function = GXcopy;
68 gcv.subwindow_mode = IncludeInferiors;
69 gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode,
72 XGetWindowAttributes (dpy, window, &xgwa);
73 bitmap_w = xgwa.width;
74 bitmap_h = xgwa.height;
76 grid_w = bitmap_w / grid_size;
77 grid_h = bitmap_h / grid_size;
78 hole_x = random () % grid_w;
79 hole_y = random () % grid_h;
80 xoff = (bitmap_w - (grid_w * grid_size)) / 2;
81 yoff = (bitmap_h - (grid_h * grid_size)) / 2;
87 for (i = 0; i <= bitmap_w; i += grid_size)
88 XFillRectangle (dpy, d, gc, xoff+i-border/2, yoff, border, bitmap_h);
89 for (i = 0; i <= bitmap_h; i += grid_size)
90 XFillRectangle (dpy, d, gc, xoff, yoff+i-border/2, bitmap_w, border);
95 XFillRectangle (dpy, d, gc, 0, 0, xoff, bitmap_h);
96 XFillRectangle (dpy, d, gc, bitmap_w - xoff, 0, xoff, bitmap_h);
100 XFillRectangle (dpy, d, gc, 0, 0, bitmap_w, yoff);
101 XFillRectangle (dpy, d, gc, 0, bitmap_h - yoff, bitmap_w, yoff);
105 if (delay2) usleep (delay2 * 2);
106 for (i = 0; i < grid_size; i += pix_inc)
109 points[0].x = xoff + grid_size * hole_x;
110 points[0].y = yoff + grid_size * hole_y;
111 points[1].x = points[0].x + grid_size;
112 points[1].y = points[0].y;
113 points[2].x = points[0].x;
114 points[2].y = points[0].y + i;
115 XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
117 points[1].x = points[0].x;
118 points[1].y = points[0].y + grid_size;
119 points[2].x = points[0].x + i;
120 points[2].y = points[0].y + grid_size;
121 XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
123 points[0].x = points[1].x + grid_size;
124 points[0].y = points[1].y;
125 points[2].x = points[0].x;
126 points[2].y = points[0].y - i;
127 XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
129 points[1].x = points[0].x;
130 points[1].y = points[0].y - grid_size;
131 points[2].x = points[1].x - i;
132 points[2].y = points[1].y;
133 XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
136 if (delay) usleep (delay);
139 XFillRectangle (dpy, window, gc,
140 xoff + grid_size * hole_x,
141 yoff + grid_size * hole_y,
142 grid_size, grid_size);
146 slide1 (Display *dpy, Window window)
148 /* this code is a total kludge, but who cares, it works... */
149 int i, x, y, ix, iy, dx, dy, dir, w, h, size, inc;
150 static int last = -1;
155 case 0: dx = 0, dy = 1; break;
156 case 1: dx = -1, dy = 0; break;
157 case 2: dx = 0, dy = -1; break;
158 case 3: dx = 1, dy = 0; break;
161 } while (dir == last ||
162 hole_x + dx < 0 || hole_x + dx >= grid_w ||
163 hole_y + dy < 0 || hole_y + dy >= grid_h);
164 if (grid_w > 1 && grid_h > 1)
165 last = (dir == 0 ? 2 : dir == 2 ? 0 : dir == 1 ? 3 : 1);
169 case 0: size = 1 + (random()%(grid_h - hole_y - 1)); h = size; w = 1; break;
170 case 1: size = 1 + (random()%hole_x); w = size; h = 1; break;
171 case 2: size = 1 + (random()%hole_y); h = size; w = 1; break;
172 case 3: size = 1 + (random()%(grid_w - hole_x - 1)); w = size; h = 1; break;
176 if (dx == -1) hole_x -= (size - 1);
177 else if (dy == -1) hole_y -= (size - 1);
179 ix = x = xoff + (hole_x + dx) * grid_size;
180 iy = y = yoff + (hole_y + dy) * grid_size;
182 for (i = 0; i < grid_size; i += inc)
184 int fx, fy, tox, toy;
185 if (inc + i > grid_size)
190 fx = (x < 0 ? 0 : x > max_width ? max_width : x);
191 fy = (y < 0 ? 0 : y > max_height ? max_height : y);
192 tox = (tox < 0 ? 0 : tox > max_width ? max_width : tox);
193 toy = (toy < 0 ? 0 : toy > max_height ? max_height : toy);
195 XCopyArea (dpy, window, window, gc,
197 grid_size * w, grid_size * h,
204 case 0: XFillRectangle (dpy, window, gc,
205 ix, y + grid_size * h, grid_size * w, iy - y);
207 case 1: XFillRectangle (dpy, window, gc, ix, iy, x - ix, grid_size * h);
209 case 2: XFillRectangle (dpy, window, gc, ix, iy, grid_size * w, y - iy);
211 case 3: XFillRectangle (dpy, window, gc,
212 x + grid_size * w, iy, ix - x, grid_size * h);
217 if (delay) usleep (delay);
221 case 0: hole_y += size; break;
222 case 1: hole_x--; break;
223 case 2: hole_y--; break;
224 case 3: hole_x += size; break;
229 char *progclass = "SlidePuzzle";
231 char *defaults [] = {
232 "*dontClearRoot: True",
234 #ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */
238 "*background: Black",
240 "*pixelIncrement: 10",
241 "*internalBorderWidth: 1",
247 XrmOptionDescRec options [] = {
248 { "-grid-size", ".gridSize", XrmoptionSepArg, 0 },
249 { "-ibw", ".internalBorderWidth", XrmoptionSepArg, 0 },
250 { "-increment", ".pixelIncrement", XrmoptionSepArg, 0 },
251 { "-delay", ".delay", XrmoptionSepArg, 0 },
252 { "-delay2", ".delay2", XrmoptionSepArg, 0 },
257 screenhack (Display *dpy, Window window)
259 init_slide (dpy, window);
262 slide1 (dpy, window);
263 if (delay2) usleep (delay2);