1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* slip --- lots of slipping blits */
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)slip.c 5.00 2000/11/01 xlockmore";
10 * Copyright (c) 1992 by Scott Draves <spot@cs.cmu.edu>
12 * Permission to use, copy, modify, and distribute this software and its
13 * documentation for any purpose and without fee is hereby granted,
14 * provided that the above copyright notice appear in all copies and that
15 * both that copyright notice and this permission notice appear in
16 * supporting documentation.
18 * This file is provided AS IS with no warranties of any kind. The author
19 * shall have no liability with respect to the infringement of copyrights,
20 * trade secrets or any patents by this file or any part thereof. In no
21 * event will the author be liable for any lost revenue or profits or
22 * other special, indirect and consequential damages.
24 * 01-Nov-2000: Allocation checks
25 * 10-May-1997: Jamie Zawinski <jwz@jwz.org> compatible with xscreensaver
26 * 01-Dec-1995: Patched for VMS <joukj@hrem.stm.tudelft.nl>
31 #define PROGCLASS "Slip"
32 #define HACK_INIT init_slip
33 #define HACK_DRAW draw_slip
34 #define slip_opts xlockmore_opts
35 #define DEFAULTS "*delay: 50000 \n" \
39 #include "xlockmore.h" /* in xscreensaver distribution */
40 #else /* STANDALONE */
41 #include "xlock.h" /* in xlockmore distribution */
42 #endif /* STANDALONE */
46 ModeSpecOpt slip_opts =
47 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
50 ModStruct slip_description =
51 {"slip", "init_slip", "draw_slip", "release_slip",
52 "init_slip", "init_slip", (char *) NULL, &slip_opts,
53 50000, 35, 50, 1, 64, 1.0, "",
54 "Shows slipping blits", 0, NULL};
61 int blit_width, blit_height;
69 static slipstruct *slips = (slipstruct *) NULL;
72 halfrandom(slipstruct *sp, int mv)
81 sp->lasthalf = (short) (r >> 16);
87 erandom(slipstruct *sp, int mv)
95 res = (int) (sp->r & 0xf);
105 prepare_screen(ModeInfo * mi, slipstruct * sp)
108 Display *display = MI_DISPLAY(mi);
110 int i, n, w = sp->width / 20;
111 int not_solid = halfrandom(sp, 10);
113 #ifdef STANDALONE /* jwz -- sometimes hack the desktop image! */
114 if (halfrandom(sp, 2) == 0) {
115 grab_screen_image(DefaultScreenOfDisplay(display),
120 sp->backwards = (int) (LRAND() & 1); /* jwz: go the other way sometimes */
122 if (sp->first_time || !halfrandom(sp, 10)) {
126 if (halfrandom(sp, 5))
128 if (halfrandom(sp, 5))
134 if (MI_NPIXELS(mi) > 2)
135 XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(sp, MI_NPIXELS(mi))));
136 else if (halfrandom(sp, 2))
137 XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
139 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
141 for (i = 0; i < n; i++) {
142 int ww = ((w / 2) + halfrandom(sp, MAX(w, 1)));
145 if (MI_NPIXELS(mi) > 2)
146 XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(sp, MI_NPIXELS(mi))));
147 else if (halfrandom(sp, 2))
148 XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
150 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
152 XFillRectangle(display, MI_WINDOW(mi), gc,
153 halfrandom(sp, MAX(sp->width - ww, 1)),
154 halfrandom(sp, MAX(sp->height - ww, 1)),
163 int i = (int) floor(d);
166 if ((LRAND() & 0xff) < f * 0xff)
172 init_slip(ModeInfo * mi)
177 if ((slips = (slipstruct *) calloc(MI_NUM_SCREENS(mi),
178 sizeof (slipstruct))) == NULL)
181 sp = &slips[MI_SCREEN(mi)];
183 sp->width = MI_WIDTH(mi);
184 sp->height = MI_HEIGHT(mi);
186 sp->blit_width = sp->width / 25;
187 sp->blit_height = sp->height / 25;
188 sp->nblits_remaining = 0;
192 /* no "NoExpose" events from XCopyArea wanted */
193 XSetGraphicsExposures(MI_DISPLAY(mi), MI_GC(mi), False);
197 draw_slip(ModeInfo * mi)
199 Display *display = MI_DISPLAY(mi);
200 Window window = MI_WINDOW(mi);
207 sp = &slips[MI_SCREEN(mi)];
209 timer = MI_COUNT(mi) * MI_CYCLES(mi);
211 MI_IS_DRAWN(mi) = True;
214 int xi = halfrandom(sp, MAX(sp->width - sp->blit_width, 1));
215 int yi = halfrandom(sp, MAX(sp->height - sp->blit_height, 1));
216 double x, y, dx = 0, dy = 0, t, s1, s2;
218 if (0 == sp->nblits_remaining--) {
220 {0, 0, 0, 1, 1, 1, 2};
222 prepare_screen(mi, sp);
223 sp->nblits_remaining = MI_COUNT(mi) *
224 (2000 + halfrandom(sp, 1000) + halfrandom(sp, 1000));
226 sp->mode = halfrandom(sp, 2);
228 sp->mode = lut[halfrandom(sp, 7)];
230 x = (2 * xi + sp->blit_width) / (double) sp->width - 1;
231 y = (2 * yi + sp->blit_height) / (double) sp->height - 1;
233 /* (x,y) is in biunit square */
249 t = dx * dx + dy * dy + 1e-10;
250 s1 = 2 * dx * dx / t - 1;
251 s2 = 2 * dx * dy / t;
255 if (sp->backwards) { /* jwz: go the other way sometimes */
260 case 1: /* shuffle */
264 case 2: /* explode */
270 int qx = xi + quantize(dx), qy = yi + quantize(dy);
273 if (qx < 0 || qy < 0 ||
274 qx >= sp->width - sp->blit_width ||
275 qy >= sp->height - sp->blit_height)
279 Seems to cause problems using Exceed
281 X Error of failed request: BadGC (invalid GC parameter)
283 X Error of failed request: BadDrawable (invalid Pixmap or Window parameter)
284 Major opcode of failed request: 62 (X_CopyArea)
286 XCopyArea(display, window, window, gc, xi, yi,
287 sp->blit_width, sp->blit_height,
292 wrap = sp->width - (2 * sp->blit_width);
294 XCopyArea(display, window, window, gc, qx, qy,
295 sp->blit_width, sp->blit_height,
298 if (qx < 2 * sp->blit_width) {
299 XCopyArea(display, window, window, gc, qx, qy,
300 sp->blit_width, sp->blit_height,
303 wrap = sp->height - (2 * sp->blit_height);
305 XCopyArea(display, window, window, gc, qx, qy,
306 sp->blit_width, sp->blit_height,
309 if (qy < 2 * sp->blit_height) {
310 XCopyArea(display, window, window, gc, qx, qy,
311 sp->blit_width, sp->blit_height,
324 release_slip(ModeInfo * mi)
327 (void) free((void *) slips);
328 slips = (slipstruct *) NULL;
332 #endif /* MODE_slip */