~ubuntu-branches/debian/sid/xscreensaver/sid

« back to all changes in this revision

Viewing changes to hacks/slidescreen.c

  • Committer: Bazaar Package Importer
  • Author(s): Jose Luis Rivas, Tormod Volden, Jose Luis Rivas
  • Date: 2008-07-15 14:48:48 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080715144848-c6c6mhyxij0dk2p7
Tags: 5.05-3
[ Tormod Volden ]
* debian/patches/10_jwz-xscreensaver-randr-patch-3.patch:
  from upstream, addresses issues with xrandr/xinerama
  (Closes: #482385, #428797, #471920, #453708, #473681, #479715, #480231)
* fixed typo "screen < real_nscreens" in driver/lock:1527 from above patch
* drop 61_DualHead-nVidia_bug471920.patch (obsolete)
* drop 67_XineRama-mode_bug473681.patch (obsolete)
* fix m6502.o typo in hacks/Makefile.in
* refresh 53_XScreenSaver.ad.in.patch
* refresh (disabled) 60_add-ant-hack.patch

[ Jose Luis Rivas ]
* add xscreensaver-demo desktop file, thanks to Daniel Dickinson
  (Closes: #480592)
* update package descriptions (thanks jwz)
* fix categories in xscreensaver.menu
* change build-deps from xlibmesa-gl-dev to libgl1-mesa-dev,
  xutils to xutils-dev, x-dev to x11proto-core-dev.
* bump Standards-Version to 3.8.0
* add Vcs fields and Homepage to debian/control
* Flurry is not installed until the bug get fixed (Closes: #484112)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* xscreensaver, Copyright (c) 1992-2005 Jamie Zawinski <jwz@jwz.org>
 
1
/* xscreensaver, Copyright (c) 1992-2006 Jamie Zawinski <jwz@jwz.org>
2
2
 *
3
3
 * Permission to use, copy, modify, distribute, and sell this software and its
4
4
 * documentation for any purpose is hereby granted without fee, provided that
14
14
enum { DOWN = 0, LEFT, UP, RIGHT };
15
15
enum { VERTICAL, HORIZONTAL };
16
16
 
17
 
static int grid_size;
18
 
static int pix_inc;
19
 
static int hole_x, hole_y;
20
 
static int bitmap_w, bitmap_h;
21
 
static int xoff, yoff;
22
 
static int grid_w, grid_h;
23
 
static int delay, delay2;
24
 
static GC gc;
25
 
static int max_width, max_height;
26
 
 
27
 
static void
28
 
init_slide (Display *dpy, Window window)
 
17
struct state {
 
18
  Display *dpy;
 
19
  Window window;
 
20
 
 
21
  int grid_size;
 
22
  int pix_inc;
 
23
  int hole_x, hole_y;
 
24
  int bitmap_w, bitmap_h;
 
25
  int xoff, yoff;
 
26
  int grid_w, grid_h;
 
27
  int delay, delay2;
 
28
  GC gc;
 
29
  unsigned long fg, bg;
 
30
  int max_width, max_height;
 
31
  int early_i;
 
32
 
 
33
  int draw_rnd, draw_i;
 
34
  int draw_x, draw_y, draw_ix, draw_iy, draw_dx, draw_dy;
 
35
  int draw_dir, draw_w, draw_h, draw_size, draw_inc;
 
36
  int draw_last;
 
37
  int draw_initted;
 
38
 
 
39
  async_load_state *img_loader;
 
40
};
 
41
 
 
42
 
 
43
static void *
 
44
slidescreen_init (Display *dpy, Window window)
29
45
{
30
 
  int i;
 
46
  struct state *st = (struct state *) calloc (1, sizeof(*st));
 
47
  XWindowAttributes xgwa;
 
48
  Visual *visual;
31
49
  XGCValues gcv;
32
 
  XWindowAttributes xgwa;
33
50
  long gcflags;
34
 
  int border;
35
 
  unsigned long fg, bg;
36
 
  Drawable d;
37
 
  Colormap cmap;
38
 
  Visual *visual;
39
 
 
40
 
  XGetWindowAttributes (dpy, window, &xgwa);
41
 
  load_random_image (xgwa.screen, window, window, NULL, NULL);
42
 
  cmap = xgwa.colormap;
 
51
 
 
52
  st->dpy = dpy;
 
53
  st->window = window;
 
54
  XGetWindowAttributes (st->dpy, st->window, &xgwa);
 
55
  st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
 
56
                                            st->window, 0, 0);
 
57
 
43
58
  visual = xgwa.visual;
44
 
  max_width = xgwa.width;
45
 
  max_height = xgwa.height;
46
 
 
47
 
  delay = get_integer_resource ("delay", "Integer");
48
 
  delay2 = get_integer_resource ("delay2", "Integer");
49
 
  grid_size = get_integer_resource ("gridSize", "Integer");
50
 
  pix_inc = get_integer_resource ("pixelIncrement", "Integer");
51
 
  border = get_integer_resource ("internalBorderWidth", "InternalBorderWidth");
52
 
 
53
 
  /* Don't let the grid be smaller than 3x3 */
54
 
  if (grid_size > xgwa.width / 3)
55
 
    grid_size = xgwa.width / 3;
56
 
  if (grid_size > xgwa.height / 3)
57
 
    grid_size = xgwa.height / 3;
 
59
  st->max_width = xgwa.width;
 
60
  st->max_height = xgwa.height;
 
61
 
 
62
  st->delay = get_integer_resource (st->dpy, "delay", "Integer");
 
63
  st->delay2 = get_integer_resource (st->dpy, "delay2", "Integer");
 
64
  st->grid_size = get_integer_resource (st->dpy, "gridSize", "Integer");
 
65
  st->pix_inc = get_integer_resource (st->dpy, "pixelIncrement", "Integer");
 
66
 
 
67
  /* Don't let the grid be smaller than 5x5 */
 
68
  while (st->grid_size > xgwa.width / 5)
 
69
    st->grid_size /= 2;
 
70
  while (st->grid_size > xgwa.height / 5)
 
71
    st->grid_size /= 2;
 
72
 
 
73
  if (st->delay < 0) st->delay = 0;
 
74
  if (st->delay2 < 0) st->delay2 = 0;
 
75
  if (st->pix_inc < 1) st->pix_inc = 1;
 
76
  if (st->grid_size < 1) st->grid_size = 1;
 
77
 
58
78
 
59
79
  {
60
80
    XColor fgc, bgc;
61
 
    char *fgs = get_string_resource("background", "Background");
62
 
    char *bgs = get_string_resource("foreground", "Foreground");
 
81
    char *fgs = get_string_resource(st->dpy, "background", "Background");
 
82
    char *bgs = get_string_resource(st->dpy, "foreground", "Foreground");
63
83
    Bool fg_ok, bg_ok;
64
 
    if (!XParseColor (dpy, cmap, fgs, &fgc))
65
 
      XParseColor (dpy, cmap, "black", &bgc);
66
 
    if (!XParseColor (dpy, cmap, bgs, &bgc))
67
 
      XParseColor (dpy, cmap, "gray", &fgc);
 
84
    if (!XParseColor (st->dpy, xgwa.colormap, fgs, &fgc))
 
85
      XParseColor (st->dpy, xgwa.colormap, "black", &bgc);
 
86
    if (!XParseColor (st->dpy, xgwa.colormap, bgs, &bgc))
 
87
      XParseColor (st->dpy, xgwa.colormap, "gray", &fgc);
68
88
 
69
 
    fg_ok = XAllocColor (dpy, cmap, &fgc);
70
 
    bg_ok = XAllocColor (dpy, cmap, &bgc);
 
89
    fg_ok = XAllocColor (st->dpy, xgwa.colormap, &fgc);
 
90
    bg_ok = XAllocColor (st->dpy, xgwa.colormap, &bgc);
71
91
 
72
92
    /* If we weren't able to allocate the two colors we want from the
73
93
       colormap (which is likely if the screen has been grabbed on an
76
96
       pixels without actually allocating them.
77
97
     */
78
98
    if (fg_ok)
79
 
      fg = fgc.pixel;
 
99
      st->fg = fgc.pixel;
80
100
    else
81
 
      fg = 0;
 
101
      st->fg = 0;
82
102
 
83
103
    if (bg_ok)
84
 
      bg = bgc.pixel;
 
104
      st->bg = bgc.pixel;
85
105
    else
86
 
      bg = 1;
 
106
      st->bg = 1;
87
107
 
 
108
#ifndef HAVE_COCOA
88
109
    if (!fg_ok || bg_ok)
89
110
      {
 
111
        int i;
90
112
        unsigned long fgd = ~0;
91
113
        unsigned long bgd = ~0;
92
 
        int max = visual_cells (xgwa.screen, visual);
 
114
        int max = visual_cells (xgwa.screen, xgwa.visual);
93
115
        XColor *all = (XColor *) calloc(sizeof (*all), max);
94
116
        for (i = 0; i < max; i++)
95
117
          {
96
118
            all[i].flags = DoRed|DoGreen|DoBlue;
97
119
            all[i].pixel = i;
98
120
          }
99
 
        XQueryColors (dpy, cmap, all, max);
 
121
        XQueryColors (st->dpy, xgwa.colormap, all, max);
100
122
        for(i = 0; i < max; i++)
101
123
          {
102
124
            long rd, gd, bd;
113
135
                if (dd < fgd)
114
136
                  {
115
137
                    fgd = dd;
116
 
                    fg = all[i].pixel;
 
138
                    st->fg = all[i].pixel;
117
139
                    if (dd == 0)
118
140
                      fg_ok = True;
119
141
                  }
131
153
                if (dd < bgd)
132
154
                  {
133
155
                    bgd = dd;
134
 
                    bg = all[i].pixel;
 
156
                    st->bg = all[i].pixel;
135
157
                    if (dd == 0)
136
158
                      bg_ok = True;
137
159
                  }
142
164
          }
143
165
        XFree(all);
144
166
      }
 
167
#endif /* !HAVE_COCOA */
145
168
  }
146
169
 
147
 
 
148
 
  if (delay < 0) delay = 0;
149
 
  if (delay2 < 0) delay2 = 0;
150
 
  if (pix_inc < 1) pix_inc = 1;
151
 
  if (grid_size < 1) grid_size = 1;
152
 
 
153
 
  gcv.foreground = fg;
 
170
  gcv.foreground = st->fg;
154
171
  gcv.function = GXcopy;
155
172
  gcv.subwindow_mode = IncludeInferiors;
156
173
  gcflags = GCForeground |GCFunction;
157
 
  if (use_subwindow_mode_p(xgwa.screen, window)) /* see grabscreen.c */
 
174
  if (use_subwindow_mode_p(xgwa.screen, st->window)) /* see grabscreen.c */
158
175
    gcflags |= GCSubwindowMode;
159
 
  gc = XCreateGC (dpy, window, gcflags, &gcv);
160
 
 
161
 
  XGetWindowAttributes (dpy, window, &xgwa);
162
 
  bitmap_w = xgwa.width;
163
 
  bitmap_h = xgwa.height;
164
 
 
165
 
  grid_w = bitmap_w / grid_size;
166
 
  grid_h = bitmap_h / grid_size;
167
 
  hole_x = random () % grid_w;
168
 
  hole_y = random () % grid_h;
169
 
  xoff = (bitmap_w - (grid_w * grid_size)) / 2;
170
 
  yoff = (bitmap_h - (grid_h * grid_size)) / 2;
171
 
 
172
 
  d = window;
 
176
  st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
 
177
 
 
178
  return st;
 
179
}
 
180
 
 
181
static void
 
182
draw_grid (struct state *st)
 
183
{
 
184
  int i;
 
185
  Drawable d;
 
186
  int border;
 
187
  XWindowAttributes xgwa;
 
188
 
 
189
  XGetWindowAttributes (st->dpy, st->window, &xgwa);
 
190
 
 
191
  border = get_integer_resource (st->dpy, "internalBorderWidth",
 
192
                                 "InternalBorderWidth");
 
193
 
 
194
  XGetWindowAttributes (st->dpy, st->window, &xgwa);
 
195
  st->bitmap_w = xgwa.width;
 
196
  st->bitmap_h = xgwa.height;
 
197
 
 
198
  st->grid_w = st->bitmap_w / st->grid_size;
 
199
  st->grid_h = st->bitmap_h / st->grid_size;
 
200
  st->hole_x = random () % st->grid_w;
 
201
  st->hole_y = random () % st->grid_h;
 
202
  st->xoff = (st->bitmap_w - (st->grid_w * st->grid_size)) / 2;
 
203
  st->yoff = (st->bitmap_h - (st->grid_h * st->grid_size)) / 2;
 
204
 
 
205
  d = st->window;
 
206
 
 
207
  st->early_i = -10;
 
208
  st->draw_last = -1;
173
209
 
174
210
  if (border)
175
211
    {
176
212
      int half = border/2;
177
213
      int half2 = (border & 1 ? half+1 : half);
178
 
      XSetForeground(dpy, gc, bg);
179
 
      for (i = 0; i < bitmap_w; i += grid_size)
 
214
      XSetForeground(st->dpy, st->gc, st->bg);
 
215
      for (i = 0; i < st->bitmap_w; i += st->grid_size)
180
216
        {
181
217
          int j;
182
 
          for (j = 0; j < bitmap_h; j += grid_size)
183
 
            XDrawRectangle (dpy, d, gc,
184
 
                            xoff+i+half2, yoff+j+half2,
185
 
                            grid_size-border-1, grid_size-border-1);
 
218
          for (j = 0; j < st->bitmap_h; j += st->grid_size)
 
219
            XDrawRectangle (st->dpy, d, st->gc,
 
220
                            st->xoff+i+half2, st->yoff+j+half2,
 
221
                            st->grid_size-border-1, st->grid_size-border-1);
186
222
        }
187
223
 
188
 
      XSetForeground(dpy, gc, fg);
189
 
      for (i = 0; i <= bitmap_w; i += grid_size)
190
 
        XFillRectangle (dpy, d, gc, xoff+i-half, yoff, border, bitmap_h);
191
 
      for (i = 0; i <= bitmap_h; i += grid_size)
192
 
        XFillRectangle (dpy, d, gc, xoff, yoff+i-half, bitmap_w, border);
193
 
    }
194
 
 
195
 
  if (xoff)
196
 
    {
197
 
      XFillRectangle (dpy, d, gc, 0, 0, xoff, bitmap_h);
198
 
      XFillRectangle (dpy, d, gc, bitmap_w - xoff, 0, xoff, bitmap_h);
199
 
    }
200
 
  if (yoff)
201
 
    {
202
 
      XFillRectangle (dpy, d, gc, 0, 0, bitmap_w, yoff);
203
 
      XFillRectangle (dpy, d, gc, 0, bitmap_h - yoff, bitmap_w, yoff);
204
 
    }
205
 
 
206
 
  XSync (dpy, False);
207
 
  if (delay2) usleep (delay2);
208
 
 for (i = 0; i < grid_size; i += pix_inc)
 
224
      XSetForeground(st->dpy, st->gc, st->fg);
 
225
      for (i = 0; i <= st->bitmap_w; i += st->grid_size)
 
226
        XFillRectangle (st->dpy, d, st->gc, st->xoff+i-half, st->yoff, border, st->bitmap_h);
 
227
      for (i = 0; i <= st->bitmap_h; i += st->grid_size)
 
228
        XFillRectangle (st->dpy, d, st->gc, st->xoff, st->yoff+i-half, st->bitmap_w, border);
 
229
    }
 
230
 
 
231
  if (st->xoff)
 
232
    {
 
233
      XFillRectangle (st->dpy, d, st->gc, 0, 0, st->xoff, st->bitmap_h);
 
234
      XFillRectangle (st->dpy, d, st->gc, st->bitmap_w - st->xoff, 0, st->xoff, st->bitmap_h);
 
235
    }
 
236
  if (st->yoff)
 
237
    {
 
238
      XFillRectangle (st->dpy, d, st->gc, 0, 0, st->bitmap_w, st->yoff);
 
239
      XFillRectangle (st->dpy, d, st->gc, 0, st->bitmap_h - st->yoff, st->bitmap_w, st->yoff);
 
240
    }
 
241
}
 
242
 
 
243
 
 
244
static int
 
245
slidescreen_draw_early (struct state *st)
 
246
{
 
247
  while (st->early_i < 0)
 
248
    {
 
249
      st->early_i++;
 
250
      return 1;
 
251
    }
 
252
 
 
253
  /* for (early_i = 0; early_i < grid_size; early_i += pix_inc) */
209
254
   {
210
255
     XPoint points [3];
211
 
     points[0].x = xoff + grid_size * hole_x;
212
 
     points[0].y = yoff + grid_size * hole_y;
213
 
     points[1].x = points[0].x + grid_size;
 
256
     points[0].x = st->xoff + st->grid_size * st->hole_x;
 
257
     points[0].y = st->yoff + st->grid_size * st->hole_y;
 
258
     points[1].x = points[0].x + st->grid_size;
214
259
     points[1].y = points[0].y;
215
260
     points[2].x = points[0].x;
216
 
     points[2].y = points[0].y + i;
217
 
     XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
 
261
     points[2].y = points[0].y + st->early_i;
 
262
     XFillPolygon (st->dpy, st->window, st->gc, points, 3, Convex, CoordModeOrigin);
218
263
 
219
264
     points[1].x = points[0].x;
220
 
     points[1].y = points[0].y + grid_size;
221
 
     points[2].x = points[0].x + i;
222
 
     points[2].y = points[0].y + grid_size;
223
 
     XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
 
265
     points[1].y = points[0].y + st->grid_size;
 
266
     points[2].x = points[0].x + st->early_i;
 
267
     points[2].y = points[0].y + st->grid_size;
 
268
     XFillPolygon (st->dpy, st->window, st->gc, points, 3, Convex, CoordModeOrigin);
224
269
 
225
 
     points[0].x = points[1].x + grid_size;
 
270
     points[0].x = points[1].x + st->grid_size;
226
271
     points[0].y = points[1].y;
227
272
     points[2].x = points[0].x;
228
 
     points[2].y = points[0].y - i;
229
 
     XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
 
273
     points[2].y = points[0].y - st->early_i;
 
274
     XFillPolygon (st->dpy, st->window, st->gc, points, 3, Convex, CoordModeOrigin);
230
275
 
231
276
     points[1].x = points[0].x;
232
 
     points[1].y = points[0].y - grid_size;
233
 
     points[2].x = points[1].x - i;
 
277
     points[1].y = points[0].y - st->grid_size;
 
278
     points[2].x = points[1].x - st->early_i;
234
279
     points[2].y = points[1].y;
235
 
     XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
236
 
 
237
 
     XSync (dpy, False);
238
 
     if (delay) usleep (delay);
 
280
     XFillPolygon (st->dpy, st->window, st->gc, points, 3, Convex, CoordModeOrigin);
239
281
   }
240
282
 
241
 
  XFillRectangle (dpy, window, gc,
242
 
                  xoff + grid_size * hole_x,
243
 
                  yoff + grid_size * hole_y,
244
 
                  grid_size, grid_size);
 
283
   st->early_i += st->pix_inc;
 
284
   if (st->early_i < st->grid_size)
 
285
     return 1;
245
286
 
246
 
  XSync (dpy, False);
247
 
  if (delay2) usleep (delay2);
 
287
   XFillRectangle (st->dpy, st->window, st->gc,
 
288
                   st->xoff + st->grid_size * st->hole_x,
 
289
                   st->yoff + st->grid_size * st->hole_y,
 
290
                   st->grid_size, st->grid_size);
 
291
   return 0;
248
292
}
249
293
 
250
 
static void
251
 
slide1 (Display *dpy, Window window)
 
294
 
 
295
static unsigned long
 
296
slidescreen_draw (Display *dpy, Window window, void *closure)
252
297
{
 
298
  struct state *st = (struct state *) closure;
 
299
  int this_delay = st->delay;
 
300
 
253
301
  /* this code is a total kludge, but who cares, it works... */
254
 
 int rnd, i, x, y, ix, iy, dx, dy, dir, w, h, size, inc;
255
 
 static int last = -1;
256
 
 
257
 
 if (last == -1) last = random () % 2;
258
 
 
259
 
/* alternate between horizontal and vertical slides */
260
 
/* note that dir specifies the direction the _hole_ moves, not the tiles */
261
 
 if (last == VERTICAL) {
262
 
   if ((rnd = random () % (grid_w - 1)) < hole_x) {
263
 
     dx = -1; dir = LEFT;  hole_x -= rnd;
264
 
   } else {
265
 
     dx =  1; dir = RIGHT; rnd -= hole_x;
266
 
   }
267
 
   dy = 0; w = size = rnd + 1; h = 1;
268
 
   last = HORIZONTAL;
269
 
 } else {
270
 
   if ((rnd = random () % (grid_h - 1)) < hole_y) {
271
 
     dy = -1; dir = UP;    hole_y -= rnd;
272
 
   } else {
273
 
     dy =  1; dir = DOWN;  rnd -= hole_y;
274
 
   }
275
 
   dx = 0; h = size = rnd + 1; w = 1;
276
 
   last = VERTICAL;
277
 
 }
 
302
 
 
303
  if (st->img_loader)   /* still loading */
 
304
    {
 
305
      st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0);
 
306
      if (! st->img_loader)  /* just finished */
 
307
        draw_grid (st);
 
308
      return st->delay;
 
309
    }
 
310
 
 
311
  if (! st->draw_initted)
 
312
    {
 
313
      if (!slidescreen_draw_early (st))
 
314
        {
 
315
          st->draw_initted = 1;
 
316
          return st->delay2;
 
317
        }
 
318
      else
 
319
        return st->delay;
 
320
    }
 
321
 
 
322
 if (st->draw_i == 0)
 
323
   {
 
324
     if (st->draw_last == -1) st->draw_last = random () % 2;
 
325
 
 
326
     /* alternate between horizontal and vertical slides */
 
327
     /* note that draw_dir specifies the direction the _hole_ moves, not the tiles */
 
328
     if (st->draw_last == VERTICAL) {
 
329
       if (((st->grid_w > 1) ? st->draw_rnd = random () % (st->grid_w - 1) : 0)
 
330
           < st->hole_x) {
 
331
         st->draw_dx = -1; st->draw_dir = LEFT;  st->hole_x -= st->draw_rnd;
 
332
       } else {
 
333
         st->draw_dx =  1; st->draw_dir = RIGHT; st->draw_rnd -= st->hole_x;
 
334
       }
 
335
       st->draw_dy = 0; st->draw_w = st->draw_size = st->draw_rnd + 1; st->draw_h = 1;
 
336
       st->draw_last = HORIZONTAL;
 
337
     } else {
 
338
       if (((st->grid_h > 1) ? st->draw_rnd = random () % (st->grid_h - 1) : 0)
 
339
           < st->hole_y) {
 
340
         st->draw_dy = -1; st->draw_dir = UP;    st->hole_y -= st->draw_rnd;
 
341
       } else {
 
342
         st->draw_dy =  1; st->draw_dir = DOWN;  st->draw_rnd -= st->hole_y;
 
343
       }
 
344
       st->draw_dx = 0; st->draw_h = st->draw_size = st->draw_rnd + 1; st->draw_w = 1;
 
345
       st->draw_last = VERTICAL;
 
346
     }
278
347
 
279
 
 ix = x = xoff + (hole_x + dx) * grid_size;
280
 
 iy = y = yoff + (hole_y + dy) * grid_size;
281
 
 inc = pix_inc;
282
 
 for (i = 0; i < grid_size; i += inc)
 
348
     st->draw_ix = st->draw_x = st->xoff + (st->hole_x + st->draw_dx) * st->grid_size;
 
349
     st->draw_iy = st->draw_y = st->yoff + (st->hole_y + st->draw_dy) * st->grid_size;
 
350
     st->draw_inc = st->pix_inc;
 
351
 
 
352
   }
 
353
 
 
354
 /* for (draw_i = 0; draw_i < grid_size; draw_i += draw_inc) */
283
355
   {
284
356
     int fx, fy, tox, toy;
285
 
     if (inc + i > grid_size)
286
 
       inc = grid_size - i;
287
 
     tox = x - dx * inc;
288
 
     toy = y - dy * inc;
289
 
 
290
 
     fx = (x < 0 ? 0 : x > max_width  ? max_width  : x);
291
 
     fy = (y < 0 ? 0 : y > max_height ? max_height : y);
292
 
     tox = (tox < 0 ? 0 : tox > max_width  ? max_width  : tox);
293
 
     toy = (toy < 0 ? 0 : toy > max_height ? max_height : toy);
294
 
 
295
 
     XCopyArea (dpy, window, window, gc,
 
357
     if (st->draw_inc + st->draw_i > st->grid_size)
 
358
       st->draw_inc = st->grid_size - st->draw_i;
 
359
     tox = st->draw_x - st->draw_dx * st->draw_inc;
 
360
     toy = st->draw_y - st->draw_dy * st->draw_inc;
 
361
 
 
362
     fx = (st->draw_x < 0 ? 0 : st->draw_x > st->max_width  ? st->max_width  : st->draw_x);
 
363
     fy = (st->draw_y < 0 ? 0 : st->draw_y > st->max_height ? st->max_height : st->draw_y);
 
364
     tox = (tox < 0 ? 0 : tox > st->max_width  ? st->max_width  : tox);
 
365
     toy = (toy < 0 ? 0 : toy > st->max_height ? st->max_height : toy);
 
366
 
 
367
     XCopyArea (st->dpy, st->window, st->window, st->gc,
296
368
                fx, fy,
297
 
                grid_size * w, grid_size * h,
 
369
                st->grid_size * st->draw_w, st->grid_size * st->draw_h,
298
370
                tox, toy);
299
371
 
300
 
     x -= dx * inc;
301
 
     y -= dy * inc;
302
 
     switch (dir)
 
372
     st->draw_x -= st->draw_dx * st->draw_inc;
 
373
     st->draw_y -= st->draw_dy * st->draw_inc;
 
374
     switch (st->draw_dir)
303
375
       {
304
 
       case DOWN: XFillRectangle (dpy, window, gc,
305
 
                               ix, y + grid_size * h, grid_size * w, iy - y);
306
 
         break;
307
 
       case LEFT: XFillRectangle (dpy, window, gc, ix, iy, x - ix, grid_size * h);
308
 
         break;
309
 
       case UP: XFillRectangle (dpy, window, gc, ix, iy, grid_size * w, y - iy);
310
 
         break;
311
 
       case RIGHT: XFillRectangle (dpy, window, gc,
312
 
                               x + grid_size * w, iy, ix - x, grid_size * h);
 
376
       case DOWN: XFillRectangle (st->dpy, st->window, st->gc,
 
377
                               st->draw_ix, st->draw_y + st->grid_size * st->draw_h, st->grid_size * st->draw_w, st->draw_iy - st->draw_y);
 
378
         break;
 
379
       case LEFT: XFillRectangle (st->dpy, st->window, st->gc, st->draw_ix, st->draw_iy, st->draw_x - st->draw_ix, st->grid_size * st->draw_h);
 
380
         break;
 
381
       case UP: XFillRectangle (st->dpy, st->window, st->gc, st->draw_ix, st->draw_iy, st->grid_size * st->draw_w, st->draw_y - st->draw_iy);
 
382
         break;
 
383
       case RIGHT: XFillRectangle (st->dpy, st->window, st->gc,
 
384
                               st->draw_x + st->grid_size * st->draw_w, st->draw_iy, st->draw_ix - st->draw_x, st->grid_size * st->draw_h);
313
385
         break;
314
386
       }
315
 
 
316
 
     XSync (dpy, False);
317
 
     if (delay) usleep (delay);
318
 
   }
319
 
 switch (dir)
320
 
   {
321
 
   case DOWN: hole_y += size; break;
322
 
   case LEFT: hole_x--; break;
323
 
   case UP: hole_y--; break;
324
 
   case RIGHT: hole_x += size; break;
325
 
   }
 
387
   }
 
388
 
 
389
   st->draw_i += st->draw_inc;
 
390
   if (st->draw_i >= st->grid_size)
 
391
     {
 
392
       st->draw_i = 0;
 
393
 
 
394
       switch (st->draw_dir)
 
395
         {
 
396
         case DOWN: st->hole_y += st->draw_size; break;
 
397
         case LEFT: st->hole_x--; break;
 
398
         case UP: st->hole_y--; break;
 
399
         case RIGHT: st->hole_x += st->draw_size; break;
 
400
         }
 
401
 
 
402
       this_delay = st->delay2;
 
403
     }
 
404
 
 
405
   return this_delay;
 
406
}
 
407
 
 
408
static void
 
409
slidescreen_reshape (Display *dpy, Window window, void *closure, 
 
410
                 unsigned int w, unsigned int h)
 
411
{
 
412
}
 
413
 
 
414
static Bool
 
415
slidescreen_event (Display *dpy, Window window, void *closure, XEvent *event)
 
416
{
 
417
  return False;
 
418
}
 
419
 
 
420
static void
 
421
slidescreen_free (Display *dpy, Window window, void *closure)
 
422
{
 
423
  struct state *st = (struct state *) closure;
 
424
  XFreeGC (dpy, st->gc);
 
425
  free (st);
326
426
}
327
427
 
328
428
 
329
 
char *progclass = "SlidePuzzle";
330
429
 
331
 
char *defaults [] = {
 
430
static const char *slidescreen_defaults [] = {
332
431
  "*dontClearRoot:              True",
333
432
 
334
433
#ifdef __sgi    /* really, HAVE_READ_DISPLAY_EXTENSION */
336
435
#endif
337
436
 
338
437
  ".background:                 Black",
339
 
  ".foreground:                 Gray",
 
438
  ".foreground:                 #BEBEBE",
340
439
  "*gridSize:                   70",
341
440
  "*pixelIncrement:             10",
342
441
  "*internalBorderWidth:        4",
345
444
  0
346
445
};
347
446
 
348
 
XrmOptionDescRec options [] = {
 
447
static XrmOptionDescRec slidescreen_options [] = {
349
448
  { "-grid-size",       ".gridSize",            XrmoptionSepArg, 0 },
350
449
  { "-ibw",             ".internalBorderWidth", XrmoptionSepArg, 0 },
351
450
  { "-increment",       ".pixelIncrement",      XrmoptionSepArg, 0 },
354
453
  { 0, 0, 0, 0 }
355
454
};
356
455
 
357
 
void
358
 
screenhack (Display *dpy, Window window)
359
 
{
360
 
  init_slide (dpy, window);
361
 
  while (1)
362
 
    {
363
 
      slide1 (dpy, window);
364
 
      screenhack_handle_events (dpy);
365
 
      if (delay2) usleep (delay2);
366
 
    }
367
 
}
 
456
XSCREENSAVER_MODULE ("Slidescreen", slidescreen)