1 /* -*- Mode: C; tab-width: 4 -*-
2 * slip --- lots of blits.
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)slip.c 4.00 97/01/01 xlockmore";
8 /* Copyright (c) 1992 by Scott Draves (spot@cs.cmu.edu)
10 * Permission to use, copy, modify, and distribute this software and its
11 * documentation for any purpose and without fee is hereby granted,
12 * provided that the above copyright notice appear in all copies and that
13 * both that copyright notice and this permission notice appear in
14 * supporting documentation.
16 * This file is provided AS IS with no warranties of any kind. The author
17 * shall have no liability with respect to the infringement of copyrights,
18 * trade secrets or any patents by this file or any part thereof. In no
19 * event will the author be liable for any lost revenue or profits or
20 * other special, indirect and consequential damages.
23 * 12-May-97: jwz@jwz.org: turned into a standalone program.
24 * 01-Dec-95: Patched for VMS <joukj@alpha.chem.uva.nl>.
28 # define PROGCLASS "Slip"
29 # define HACK_INIT init_slip
30 # define HACK_DRAW draw_slip
31 # define slip_opts xlockmore_opts
32 # define DEFAULTS "*count: 35 \n" \
36 # include "xlockmore.h" /* from the xscreensaver distribution */
37 #else /* !STANDALONE */
38 # include "xlock.h" /* from the xlockmore distribution */
39 #endif /* !STANDALONE */
41 ModeSpecOpt slip_opts = {
42 0, NULL, 0, NULL, NULL };
47 int blit_width, blit_height;
52 static slipstruct *slips = NULL;
57 static short lasthalf = 0;
74 static unsigned long r;
91 prepare_screen(ModeInfo * mi, slipstruct * s)
94 Display *display = MI_DISPLAY(mi);
96 int i, n, w = s->width / 20;
97 int not_solid = halfrandom(10);
99 #ifdef STANDALONE /* jwz -- sometimes hack the desktop image! */
100 if (halfrandom(2) == 0)
102 grab_screen_image(DefaultScreenOfDisplay (MI_DISPLAY(mi)),
108 s->backwards = LRAND() & 1; /* jwz: go the other way sometimes */
110 if (s->first_time || (0 == halfrandom(10))) {
111 XClearWindow(display, MI_WINDOW(mi));
122 if (MI_NPIXELS(mi) > 2)
123 XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(MI_NPIXELS(mi))));
124 else if (halfrandom(2))
125 XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
127 XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi));
129 for (i = 0; i < n; i++) {
130 int ww = ((w/2) + halfrandom(w));
132 if (MI_NPIXELS(mi) > 2)
133 XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(MI_NPIXELS(mi))));
134 else if (halfrandom(2))
135 XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
137 XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi));
138 XFillRectangle(display, MI_WINDOW(mi), gc,
139 halfrandom(s->width - ww),
140 halfrandom(s->height - ww),
149 int i = (int) floor(d);
152 if ((LRAND() & 0xff) < f * 0xff)
158 init_slip(ModeInfo * mi)
163 if ((slips = (slipstruct *) calloc(MI_NUM_SCREENS(mi),
164 sizeof (slipstruct))) == NULL)
167 sp = &slips[MI_SCREEN(mi)];
169 sp->width = MI_WIN_WIDTH(mi);
170 sp->height = MI_WIN_HEIGHT(mi);
172 sp->blit_width = sp->width / 25;
173 sp->blit_height = sp->height / 25;
174 sp->nblits_remaining = 0;
178 /* no "NoExpose" events from XCopyArea wanted */
179 XSetGraphicsExposures(MI_DISPLAY(mi), MI_GC(mi), False);
183 draw_slip(ModeInfo * mi)
185 Display *display = MI_DISPLAY(mi);
186 Window window = MI_WINDOW(mi);
188 slipstruct *s = &slips[MI_SCREEN(mi)];
191 timer = MI_BATCHCOUNT(mi) * MI_CYCLES(mi);
194 int xi = halfrandom(s->width - s->blit_width);
195 int yi = halfrandom(s->height - s->blit_height);
196 double x, y, dx = 0, dy = 0, t, s1, s2;
198 if (0 == s->nblits_remaining--) {
200 {0, 0, 0, 1, 1, 1, 2};
202 prepare_screen(mi, s);
203 s->nblits_remaining = MI_BATCHCOUNT(mi) *
204 (2000 + halfrandom(1000) + halfrandom(1000));
206 s->mode = halfrandom(2);
208 s->mode = lut[halfrandom(7)];
210 x = (2 * xi + s->blit_width) / (double) s->width - 1;
211 y = (2 * yi + s->blit_height) / (double) s->height - 1;
213 /* (x,y) is in biunit square */
229 t = dx * dx + dy * dy + 1e-10;
230 s1 = 2 * dx * dx / t - 1;
231 s2 = 2 * dx * dy / t;
234 if (s->backwards) { /* jwz: go the other way sometimes */
239 case 1: /* shuffle */
243 case 2: /* explode */
249 int qx = xi + quantize(dx), qy = yi + quantize(dy);
252 if (qx < 0 || qy < 0 ||
253 qx >= s->width - s->blit_width ||
254 qy >= s->height - s->blit_height)
257 XCopyArea(display, window, window, gc, xi, yi,
258 s->blit_width, s->blit_height,
264 wrap = s->width - (2 * s->blit_width);
266 XCopyArea(display, window, window, gc, qx, qy,
267 s->blit_width, s->blit_height,
270 if (qx < 2 * s->blit_width)
271 XCopyArea(display, window, window, gc, qx, qy,
272 s->blit_width, s->blit_height,
275 wrap = s->height - (2 * s->blit_height);
277 XCopyArea(display, window, window, gc, qx, qy,
278 s->blit_width, s->blit_height,
281 if (qy < 2 * s->blit_height)
282 XCopyArea(display, window, window, gc, qx, qy,
283 s->blit_width, s->blit_height,
295 release_slip(ModeInfo * mi)
298 (void) free((void *) slips);