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

« back to all changes in this revision

Viewing changes to hacks/distort.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
1
/* -*- mode: C; tab-width: 4 -*-
2
 
 * xscreensaver, Copyright (c) 1992-2005 Jamie Zawinski <jwz@jwz.org>
 
2
 * xscreensaver, Copyright (c) 1992-2006 Jamie Zawinski <jwz@jwz.org>
3
3
 *
4
4
 * Permission to use, copy, modify, distribute, and sell this software and its
5
5
 * documentation for any purpose is hereby granted without fee, provided that
36
36
 
37
37
#include <math.h>
38
38
#include "screenhack.h"
39
 
#include <X11/Xutil.h>
40
 
#include <X11/Xmd.h>
 
39
/*#include <X11/Xmd.h>*/
41
40
 
42
41
#ifdef HAVE_XSHM_EXTENSION
43
42
# include "xshm.h"
44
 
static Bool use_shm = False;
45
 
static XShmSegmentInfo shm_info;
46
43
#endif /* HAVE_XSHM_EXTENSION */
47
44
 
 
45
#define CARD32 unsigned int
 
46
#define CARD16 unsigned short
 
47
#define CARD8  unsigned char
 
48
 
 
49
 
48
50
struct coo {
49
51
        int x;
50
52
        int y;
51
53
        int r, r_change;
52
54
        int xmove, ymove;
53
55
};
54
 
static struct coo xy_coo[10];
55
 
 
56
 
static int delay, radius, speed, number, blackhole, vortex, magnify, reflect, slow;
57
 
static XWindowAttributes xgwa;
58
 
static GC gc;
59
 
static Window g_window;
60
 
static Display *g_dpy;
61
 
static unsigned long black_pixel;
62
 
 
63
 
static XImage *orig_map, *buffer_map;
64
 
static unsigned long *buffer_map_cache;
65
 
 
66
 
static int ***from;
67
 
static int ****from_array;
68
 
static int *fast_from = NULL;
69
 
static void (*effect) (int) = NULL;
70
 
static void move_lense(int);
71
 
static void swamp_thing(int);
72
 
static void new_rnd_coo(int);
73
 
static void init_round_lense(void);
74
 
static void (*draw) (int) = NULL;
75
 
static void reflect_draw(int);
76
 
static void plain_draw(int);
77
 
 
78
 
static void (*draw_routine)(XImage *, XImage *, int, int, int *) = NULL;
79
 
static void fast_draw_8(XImage *, XImage *, int, int, int *);
80
 
static void fast_draw_16(XImage *, XImage *, int, int, int *);
81
 
static void fast_draw_32(XImage *, XImage *, int, int, int *);
82
 
static void generic_draw(XImage *, XImage *, int, int, int *);
83
 
static int bpp_size = 0;
84
 
 
85
 
 
86
 
static void init_distort(Display *dpy, Window window) 
 
56
 
 
57
struct state {
 
58
  Display *dpy;
 
59
  Window window;
 
60
 
 
61
  struct coo xy_coo[10];
 
62
 
 
63
  int delay, radius, speed, number, blackhole, vortex, magnify, reflect, slow;
 
64
  XWindowAttributes xgwa;
 
65
  GC gc;
 
66
  unsigned long black_pixel;
 
67
 
 
68
  XImage *orig_map, *buffer_map;
 
69
  unsigned long *buffer_map_cache;
 
70
 
 
71
  int ***from;
 
72
  int ****from_array;
 
73
  int *fast_from;
 
74
 
 
75
  int bpp_size;
 
76
 
 
77
#ifdef HAVE_XSHM_EXTENSION
 
78
  Bool use_shm;
 
79
  XShmSegmentInfo shm_info;
 
80
#endif /* HAVE_XSHM_EXTENSION */
 
81
 
 
82
  void (*effect) (struct state *, int);
 
83
  void (*draw) (struct state *, int);
 
84
  void (*draw_routine) (struct state *st, XImage *, XImage *, int, int, int *);
 
85
 
 
86
  async_load_state *img_loader;
 
87
};
 
88
 
 
89
 
 
90
static void move_lense(struct state *, int);
 
91
static void swamp_thing(struct state *, int);
 
92
static void new_rnd_coo(struct state *, int);
 
93
static void init_round_lense(struct state *st);
 
94
static void reflect_draw(struct state *, int);
 
95
static void plain_draw(struct state *, int);
 
96
 
 
97
static void fast_draw_8 (struct state *st, XImage *, XImage *, int, int, int *);
 
98
static void fast_draw_16(struct state *st, XImage *, XImage *, int, int, int *);
 
99
static void fast_draw_32(struct state *st, XImage *, XImage *, int, int, int *);
 
100
static void generic_draw(struct state *st, XImage *, XImage *, int, int, int *);
 
101
 
 
102
 
 
103
static void distort_finish_loading (struct state *);
 
104
 
 
105
static void *
 
106
distort_init (Display *dpy, Window window)
87
107
{
 
108
  struct state *st = (struct state *) calloc (1, sizeof(*st));
88
109
        XGCValues gcv;
89
110
        long gcflags;
90
111
        int i;
91
 
 
92
 
        g_window=window;
93
 
        g_dpy=dpy;
94
 
 
95
 
        delay = get_integer_resource("delay", "Integer");
96
 
        radius = get_integer_resource("radius", "Integer");
97
 
        speed = get_integer_resource("speed", "Integer");
98
 
        number = get_integer_resource("number", "Integer");
 
112
    char *s;
 
113
 
 
114
    st->dpy = dpy;
 
115
    st->window = window;
 
116
 
 
117
        st->delay = get_integer_resource(st->dpy, "delay", "Integer");
 
118
        st->radius = get_integer_resource(st->dpy, "radius", "Integer");
 
119
        st->speed = get_integer_resource(st->dpy, "speed", "Integer");
 
120
        st->number = get_integer_resource(st->dpy, "number", "Integer");
99
121
 
100
122
#ifdef HAVE_XSHM_EXTENSION
101
 
        use_shm = get_boolean_resource("useSHM", "Boolean");
 
123
        st->use_shm = get_boolean_resource(st->dpy, "useSHM", "Boolean");
102
124
#endif /* HAVE_XSHM_EXTENSION */
103
125
        
104
 
        blackhole = get_boolean_resource("blackhole", "Boolean");
105
 
        vortex = get_boolean_resource("vortex", "Boolean");
106
 
        magnify = get_boolean_resource("magnify", "Boolean");
107
 
        reflect = get_boolean_resource("reflect", "Boolean");
108
 
        slow = get_boolean_resource("slow", "Boolean");
 
126
        st->blackhole = get_boolean_resource(st->dpy, "blackhole", "Boolean");
 
127
        st->vortex = get_boolean_resource(st->dpy, "vortex", "Boolean");
 
128
        st->magnify = get_boolean_resource(st->dpy, "magnify", "Boolean");
 
129
        st->reflect = get_boolean_resource(st->dpy, "reflect", "Boolean");
 
130
        st->slow = get_boolean_resource(st->dpy, "slow", "Boolean");
109
131
        
110
 
        if (get_boolean_resource("swamp", "Boolean"))
111
 
                effect = &swamp_thing;
112
 
        if (get_boolean_resource("bounce", "Boolean"))
113
 
                effect = &move_lense;
114
 
 
115
 
        XGetWindowAttributes (dpy, window, &xgwa);
116
 
 
117
 
        if (effect == NULL && radius == 0 && speed == 0 && number == 0
118
 
                && !blackhole && !vortex && !magnify && !reflect) {
 
132
    st->effect = NULL;
 
133
    s = get_string_resource(st->dpy, "effect", "String");
 
134
        if (s && !strcasecmp(s,"swamp"))
 
135
      st->effect = &swamp_thing;
 
136
    else if (s && !strcasecmp(s,"bounce"))
 
137
      st->effect = &move_lense;
 
138
    else if (s && !strcasecmp(s,"none"))
 
139
      ;
 
140
    else if (s && *s)
 
141
      fprintf(stderr,"%s: bogus effect: %s\n", progname, s);
 
142
 
 
143
        XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
 
144
 
 
145
        if (st->effect == NULL && st->radius == 0 && st->speed == 0 && st->number == 0
 
146
                && !st->blackhole && !st->vortex && !st->magnify && !st->reflect) {
119
147
/* if no cmdline options are given, randomly choose one of:
120
148
 * -radius 50 -number 4 -speed 1 -bounce
121
149
 * -radius 50 -number 4 -speed 1 -blackhole
139
167
                
140
168
                i = (random() % 12 /* 17 */);
141
169
 
142
 
                draw = &plain_draw;
 
170
                st->draw = &plain_draw;
143
171
 
144
172
                switch (i) {
145
173
                        case 0:
146
 
                                radius=50;number=4;speed=1;
147
 
                                effect=&move_lense;break;
 
174
                                st->radius=50;st->number=4;st->speed=1;
 
175
                                st->effect=&move_lense;break;
148
176
                        case 1:
149
 
                                radius=50;number=4;speed=1;blackhole=1;
150
 
                                effect=&move_lense;break;
 
177
                                st->radius=50;st->number=4;st->speed=1;st->blackhole=1;
 
178
                                st->effect=&move_lense;break;
151
179
                        case 2:
152
 
                                radius=50;number=4;speed=1;vortex=1;
153
 
                                effect=&move_lense;break;
 
180
                                st->radius=50;st->number=4;st->speed=1;st->vortex=1;
 
181
                                st->effect=&move_lense;break;
154
182
                        case 3:
155
 
                                radius=50;number=4;speed=1;vortex=1;magnify=1;
156
 
                                effect=&move_lense;break;
 
183
                                st->radius=50;st->number=4;st->speed=1;st->vortex=1;st->magnify=1;
 
184
                                st->effect=&move_lense;break;
157
185
                        case 4:
158
 
                                radius=50;number=4;speed=1;vortex=1;magnify=1;blackhole=1;
159
 
                                effect=&move_lense;break;
 
186
                                st->radius=50;st->number=4;st->speed=1;st->vortex=1;st->magnify=1;st->blackhole=1;
 
187
                                st->effect=&move_lense;break;
160
188
                        case 5:
161
 
                                radius=100;number=1;speed=2;
162
 
                                effect=&move_lense;break;
 
189
                                st->radius=100;st->number=1;st->speed=2;
 
190
                                st->effect=&move_lense;break;
163
191
                        case 6:
164
 
                                radius=100;number=1;speed=2;blackhole=1;
165
 
                                effect=&move_lense;break;
 
192
                                st->radius=100;st->number=1;st->speed=2;st->blackhole=1;
 
193
                                st->effect=&move_lense;break;
166
194
                        case 7:
167
 
                                radius=100;number=1;speed=2;vortex=1;
168
 
                                effect=&move_lense;break;
 
195
                                st->radius=100;st->number=1;st->speed=2;st->vortex=1;
 
196
                                st->effect=&move_lense;break;
169
197
                        case 8:
170
 
                                radius=100;number=1;speed=2;vortex=1;magnify=1;
171
 
                                effect=&move_lense;break;
 
198
                                st->radius=100;st->number=1;st->speed=2;st->vortex=1;st->magnify=1;
 
199
                                st->effect=&move_lense;break;
172
200
                        case 9:
173
 
                                radius=100;number=1;speed=2;vortex=1;magnify=1;blackhole=1;
174
 
                                effect=&move_lense;break;
 
201
                                st->radius=100;st->number=1;st->speed=2;st->vortex=1;st->magnify=1;st->blackhole=1;
 
202
                                st->effect=&move_lense;break;
175
203
 
176
204
                        case 10:
177
 
                                radius=80;number=1;speed=2;reflect=1;
178
 
                                draw = &reflect_draw;effect = &move_lense;break;
 
205
                                st->radius=80;st->number=1;st->speed=2;st->reflect=1;
 
206
                                st->draw = &reflect_draw;st->effect = &move_lense;break;
179
207
                        case 11:
180
 
                                radius=50;number=4;speed=2;reflect=1;
181
 
                                draw = &reflect_draw;effect = &move_lense;break;
 
208
                                st->radius=50;st->number=4;st->speed=2;st->reflect=1;
 
209
                                st->draw = &reflect_draw;st->effect = &move_lense;break;
182
210
 
183
211
#if 0 /* jwz: not these */
184
212
                        case 12:
185
 
                                radius=50;number=4;speed=2;
 
213
                                st->radius=50;st->number=4;st->speed=2;
186
214
                                effect=&swamp_thing;break;
187
215
                        case 13:
188
 
                                radius=50;number=4;speed=2;blackhole=1;
 
216
                                st->radius=50;st->number=4;st->speed=2;st->blackhole=1;
189
217
                                effect=&swamp_thing;break;
190
218
                        case 14:
191
 
                                radius=50;number=4;speed=2;vortex=1;
 
219
                                st->radius=50;st->number=4;st->speed=2;st->vortex=1;
192
220
                                effect=&swamp_thing;break;
193
221
                        case 15:
194
 
                                radius=50;number=4;speed=2;vortex=1;magnify=1;
 
222
                                st->radius=50;st->number=4;st->speed=2;st->vortex=1;st->magnify=1;
195
223
                                effect=&swamp_thing;break;
196
224
                        case 16:
197
 
                                radius=50;number=4;speed=2;vortex=1;magnify=1;blackhole=1;
 
225
                                st->radius=50;st->number=4;st->speed=2;st->vortex=1;st->magnify=1;st->blackhole=1;
198
226
                                effect=&swamp_thing;break;
199
227
#endif
200
228
 
203
231
                }
204
232
 
205
233
        /* but if the window is small, reduce default radius */
206
 
        if (xgwa.width < radius * 8)
207
 
          radius = xgwa.width/8;
 
234
        if (st->xgwa.width < st->radius * 8)
 
235
          st->radius = st->xgwa.width/8;
208
236
        }
209
237
 
210
238
    /* never allow the radius to be too close to the min window dimension
211
239
     */
212
 
    if (radius >= xgwa.width  * 0.45) radius = xgwa.width  * 0.45;
213
 
    if (radius >= xgwa.height * 0.45) radius = xgwa.height * 0.45;
 
240
    if (st->radius >= st->xgwa.width  * 0.45) st->radius = st->xgwa.width  * 0.45;
 
241
    if (st->radius >= st->xgwa.height * 0.45) st->radius = st->xgwa.height * 0.45;
214
242
 
215
243
 
216
244
    /* -swamp mode consumes vast amounts of memory, proportional to radius --
217
245
       so throttle radius to a small-ish value (60 => ~30MB.)
218
246
     */
219
 
    if (effect == &swamp_thing && radius > 60)
220
 
      radius = 60;
 
247
    if (st->effect == &swamp_thing && st->radius > 60)
 
248
      st->radius = 60;
221
249
 
222
 
        if (delay < 0)
223
 
                delay = 0;
224
 
        if (radius <= 0)
225
 
                radius = 60;
226
 
        if (speed <= 0) 
227
 
                speed = 2;
228
 
        if (number <= 0)
229
 
                number=1;
230
 
        if (number >= 10)
231
 
                number=1;
232
 
        if (effect == NULL)
233
 
                effect = &move_lense;
234
 
        if (reflect) {
235
 
                draw = &reflect_draw;
236
 
                effect = &move_lense;
 
250
        if (st->delay < 0)
 
251
                st->delay = 0;
 
252
        if (st->radius <= 0)
 
253
                st->radius = 60;
 
254
        if (st->speed <= 0) 
 
255
                st->speed = 2;
 
256
        if (st->number <= 0)
 
257
                st->number=1;
 
258
        if (st->number >= 10)
 
259
                st->number=1;
 
260
        if (st->effect == NULL)
 
261
                st->effect = &move_lense;
 
262
        if (st->reflect) {
 
263
                st->draw = &reflect_draw;
 
264
                st->effect = &move_lense;
237
265
        }
238
 
        if (draw == NULL)
239
 
                draw = &plain_draw;
 
266
        if (st->draw == NULL)
 
267
                st->draw = &plain_draw;
240
268
 
241
 
        black_pixel = BlackPixelOfScreen( xgwa.screen );
 
269
        st->black_pixel = BlackPixelOfScreen( st->xgwa.screen );
242
270
 
243
271
        gcv.function = GXcopy;
244
272
        gcv.subwindow_mode = IncludeInferiors;
245
 
        gcflags = GCForeground |GCFunction;
246
 
        if (use_subwindow_mode_p(xgwa.screen, window)) /* see grabscreen.c */
 
273
        gcflags = GCFunction;
 
274
        if (use_subwindow_mode_p(st->xgwa.screen, st->window)) /* see grabscreen.c */
247
275
                gcflags |= GCSubwindowMode;
248
 
        gc = XCreateGC (dpy, window, gcflags, &gcv);
249
 
 
250
 
    load_random_image (xgwa.screen, window, window, NULL, NULL);
251
 
 
252
 
        buffer_map = 0;
253
 
        orig_map = XGetImage(dpy, window, 0, 0, xgwa.width, xgwa.height,
 
276
        st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
 
277
 
 
278
    st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
 
279
                                              st->window, 0, 0);
 
280
    return st;
 
281
}
 
282
 
 
283
static void
 
284
distort_finish_loading (struct state *st)
 
285
{
 
286
    int i;
 
287
 
 
288
        st->buffer_map = 0;
 
289
        st->orig_map = XGetImage(st->dpy, st->window, 0, 0, st->xgwa.width, st->xgwa.height,
254
290
                                                 ~0L, ZPixmap);
255
 
        buffer_map_cache = malloc(sizeof(unsigned long)*(2*radius+speed+2)*(2*radius+speed+2));
 
291
        st->buffer_map_cache = malloc(sizeof(unsigned long)*(2*st->radius+st->speed+2)*(2*st->radius+st->speed+2));
256
292
 
257
 
        if (buffer_map_cache == NULL) {
 
293
        if (st->buffer_map_cache == NULL) {
258
294
                perror("distort");
259
295
                exit(EXIT_FAILURE);
260
296
        }
261
297
 
262
298
# ifdef HAVE_XSHM_EXTENSION
263
299
 
264
 
        if (use_shm)
 
300
        if (st->use_shm)
265
301
          {
266
 
                buffer_map = create_xshm_image(dpy, xgwa.visual, orig_map->depth,
267
 
                                                                           ZPixmap, 0, &shm_info,
268
 
                                                                           2*radius + speed + 2,
269
 
                                                                           2*radius + speed + 2);
270
 
                if (!buffer_map)
271
 
                  use_shm = False;
 
302
                st->buffer_map = create_xshm_image(st->dpy, st->xgwa.visual, st->orig_map->depth,
 
303
                                                                           ZPixmap, 0, &st->shm_info,
 
304
                                                                           2*st->radius + st->speed + 2,
 
305
                                                                           2*st->radius + st->speed + 2);
 
306
                if (!st->buffer_map)
 
307
                  st->use_shm = False;
272
308
          }
273
309
# endif /* HAVE_XSHM_EXTENSION */
274
310
 
275
 
        if (!buffer_map)
 
311
        if (!st->buffer_map)
276
312
          {
277
 
                buffer_map = XCreateImage(dpy, xgwa.visual,
278
 
                                                                  orig_map->depth, ZPixmap, 0, 0,
279
 
                                                                  2*radius + speed + 2, 2*radius + speed + 2,
 
313
                st->buffer_map = XCreateImage(st->dpy, st->xgwa.visual,
 
314
                                                                  st->orig_map->depth, ZPixmap, 0, 0,
 
315
                                                                  2*st->radius + st->speed + 2, 2*st->radius + st->speed + 2,
280
316
                                                                  8, 0);
281
 
                buffer_map->data = (char *)
282
 
                  calloc(buffer_map->height, buffer_map->bytes_per_line);
 
317
                st->buffer_map->data = (char *)
 
318
                  calloc(st->buffer_map->height, st->buffer_map->bytes_per_line);
283
319
        }
284
320
 
285
 
        if ((buffer_map->byte_order == orig_map->byte_order)
286
 
                        && (buffer_map->depth == orig_map->depth)
287
 
                        && (buffer_map->format == ZPixmap)
288
 
                        && (orig_map->format == ZPixmap)
289
 
                        && !slow) {
290
 
                switch (orig_map->bits_per_pixel) {
 
321
        if ((st->buffer_map->byte_order == st->orig_map->byte_order)
 
322
                        && (st->buffer_map->depth == st->orig_map->depth)
 
323
                        && (st->buffer_map->format == ZPixmap)
 
324
                        && (st->orig_map->format == ZPixmap)
 
325
                        && !st->slow) {
 
326
                switch (st->orig_map->bits_per_pixel) {
291
327
                        case 32:
292
 
                                draw_routine = &fast_draw_32;
293
 
                                bpp_size = sizeof(CARD32);
 
328
                                st->draw_routine = &fast_draw_32;
 
329
                                st->bpp_size = sizeof(CARD32);
294
330
                                break;
295
331
                        case 16:
296
 
                                draw_routine = &fast_draw_16;
297
 
                                bpp_size = sizeof(CARD16);
 
332
                                st->draw_routine = &fast_draw_16;
 
333
                                st->bpp_size = sizeof(CARD16);
298
334
                                break;
299
335
                        case 8:
300
 
                                draw_routine = &fast_draw_8;
301
 
                                bpp_size = sizeof(CARD8);
 
336
                                st->draw_routine = &fast_draw_8;
 
337
                                st->bpp_size = sizeof(CARD8);
302
338
                                break;
303
339
                        default:
304
 
                                draw_routine = &generic_draw;
 
340
                                st->draw_routine = &generic_draw;
305
341
                                break;
306
342
                }
307
343
        } else {
308
 
                draw_routine = &generic_draw;
 
344
                st->draw_routine = &generic_draw;
309
345
        }
310
 
        init_round_lense();
 
346
        init_round_lense(st);
311
347
 
312
 
        for (i = 0; i < number; i++) {
313
 
                new_rnd_coo(i);
314
 
                if (number != 1)
315
 
                        xy_coo[i].r = (i*radius)/(number-1); /* "randomize" initial */
 
348
        for (i = 0; i < st->number; i++) {
 
349
                new_rnd_coo(st,i);
 
350
                if (st->number != 1)
 
351
                        st->xy_coo[i].r = (i*st->radius)/(st->number-1); /* "randomize" initial */
316
352
                else
317
 
                         xy_coo[i].r = 0;
318
 
                xy_coo[i].r_change = speed + (i%2)*2*(-speed);  /* values a bit */
319
 
                xy_coo[i].xmove = speed + (i%2)*2*(-speed);
320
 
                xy_coo[i].ymove = speed + (i%2)*2*(-speed);
 
353
                         st->xy_coo[i].r = 0;
 
354
                st->xy_coo[i].r_change = st->speed + (i%2)*2*(-st->speed);      /* values a bit */
 
355
                st->xy_coo[i].xmove = st->speed + (i%2)*2*(-st->speed);
 
356
                st->xy_coo[i].ymove = st->speed + (i%2)*2*(-st->speed);
321
357
        }
322
 
 
323
358
}
324
359
 
325
360
/* example: initializes a "see-trough" matrix */
326
 
/* static void make_null_lense(void)
 
361
/* static void make_null_lense(struct state *st)
327
362
{
328
363
        int i, j;
329
364
        for (i = 0; i < 2*radius+speed+2; i++) {
334
369
        } 
335
370
}
336
371
*/
337
 
static void convert(void) {
 
372
static void convert(struct state *st) 
 
373
{
338
374
        int *p;
339
375
        int i, j;
340
 
        fast_from = calloc(1, sizeof(int)*((buffer_map->bytes_per_line/bpp_size)*(2*radius+speed+2) + 2*radius+speed+2));
341
 
        if (fast_from == NULL) {
 
376
        st->fast_from = calloc(1, sizeof(int)*((st->buffer_map->bytes_per_line/st->bpp_size)*(2*st->radius+st->speed+2) + 2*st->radius+st->speed+2));
 
377
        if (st->fast_from == NULL) {
342
378
                perror("distort");
343
379
                exit(EXIT_FAILURE);
344
380
        }
345
 
        p = fast_from;
346
 
        for (i = 0; i < 2*radius+speed+2; i++) {
347
 
                for (j = 0; j < 2*radius+speed+2; j++) {
348
 
                        *(p + i + j*buffer_map->bytes_per_line/bpp_size)
349
 
                                = from[i][j][0] + xgwa.width*from[i][j][1];
350
 
                        if (*(p + i + j*buffer_map->bytes_per_line/bpp_size) < 0
351
 
                                        || *(p + i + j*buffer_map->bytes_per_line/bpp_size) >= orig_map->height*orig_map->width) {
352
 
                                *(p + i + j*buffer_map->bytes_per_line/bpp_size) = 0;
 
381
        p = st->fast_from;
 
382
        for (i = 0; i < 2*st->radius+st->speed+2; i++) {
 
383
                for (j = 0; j < 2*st->radius+st->speed+2; j++) {
 
384
                        *(p + i + j*st->buffer_map->bytes_per_line/st->bpp_size)
 
385
                                = st->from[i][j][0] + st->xgwa.width*st->from[i][j][1];
 
386
                        if (*(p + i + j*st->buffer_map->bytes_per_line/st->bpp_size) < 0
 
387
                                        || *(p + i + j*st->buffer_map->bytes_per_line/st->bpp_size) >= st->orig_map->height*st->orig_map->width) {
 
388
                                *(p + i + j*st->buffer_map->bytes_per_line/st->bpp_size) = 0;
353
389
                        }
354
390
                }
355
391
        }
358
394
/* makes a lense with the Radius=loop and centred in
359
395
 * the point (radius, radius)
360
396
 */
361
 
static void make_round_lense(int radius, int loop)
 
397
static void make_round_lense(struct state *st, int radius, int loop)
362
398
{
363
399
        int i, j;
364
400
 
365
 
        for (i = 0; i < 2*radius+speed+2; i++) {
366
 
                for(j = 0; j < ((0 == bpp_size) ? (2*radius+speed+2) : (buffer_map->bytes_per_line/bpp_size)); j++) {
 
401
        for (i = 0; i < 2*radius+st->speed+2; i++) {
 
402
                for(j = 0; j < ((0 == st->bpp_size) ? (2*radius+st->speed+2) : (st->buffer_map->bytes_per_line/st->bpp_size)); j++) {
367
403
                        double r, d;
368
404
                        r = sqrt ((i-radius)*(i-radius)+(j-radius)*(j-radius));
369
405
                        if (loop == 0)
373
409
 
374
410
                        if (r < loop-1) {
375
411
 
376
 
                                if (vortex) { /* vortex-twist effect */
 
412
                                if (st->vortex) { /* vortex-twist effect */
377
413
                                        double angle;
378
414
                /* this one-line formula for getting a nice rotation angle is borrowed
379
415
                 * (with permission) from the whirl plugin for gimp,
384
420
 
385
421
        /* Avoid atan2: DOMAIN error message */
386
422
                                        if ((radius-j) == 0.0 && (radius-i) == 0.0) {
387
 
                                                from[i][j][0] = radius + cos(angle)*r;
388
 
                                                from[i][j][1] = radius + sin(angle)*r;
 
423
                                                st->from[i][j][0] = radius + cos(angle)*r;
 
424
                                                st->from[i][j][1] = radius + sin(angle)*r;
389
425
                                        } else {
390
 
                                                from[i][j][0] = radius +
 
426
                                                st->from[i][j][0] = radius +
391
427
                                                        cos(angle - atan2(radius-j, -(radius-i)))*r;
392
 
                                                from[i][j][1] = radius +
 
428
                                                st->from[i][j][1] = radius +
393
429
                                                        sin(angle - atan2(radius-j, -(radius-i)))*r;
394
430
                                        }
395
 
                                        if (magnify) {
 
431
                                        if (st->magnify) {
396
432
                                                r = sin(d*M_PI_2);
397
 
                                                if (blackhole && r != 0) /* blackhole effect */
 
433
                                                if (st->blackhole && r != 0) /* blackhole effect */
398
434
                                                        r = 1/r;
399
 
                                                from[i][j][0] = radius + (from[i][j][0]-radius)*r;
400
 
                                                from[i][j][1] = radius + (from[i][j][1]-radius)*r;
 
435
                                                st->from[i][j][0] = radius + (st->from[i][j][0]-radius)*r;
 
436
                                                st->from[i][j][1] = radius + (st->from[i][j][1]-radius)*r;
401
437
                                        }
402
438
                                } else { /* default is to magnify */
403
439
                                        r = sin(d*M_PI_2);
406
442
         * distortion, a negative value sucks everything into a black hole
407
443
         */
408
444
                                /*      r = r*r; */
409
 
                                        if (blackhole && r != 0) /* blackhole effect */
 
445
                                        if (st->blackhole && r != 0) /* blackhole effect */
410
446
                                                r = 1/r;
411
447
                                                                        /* bubble effect (and blackhole) */
412
 
                                        from[i][j][0] = radius + (i-radius)*r;
413
 
                                        from[i][j][1] = radius + (j-radius)*r;
 
448
                                        st->from[i][j][0] = radius + (i-radius)*r;
 
449
                                        st->from[i][j][1] = radius + (j-radius)*r;
414
450
                                }
415
451
                        } else { /* not inside loop */
416
 
                                from[i][j][0] = i;
417
 
                                from[i][j][1] = j;
 
452
                                st->from[i][j][0] = i;
 
453
                                st->from[i][j][1] = j;
418
454
                        }
419
455
                }
420
456
        }
421
457
 
422
458
        /* this is really just a quick hack to keep both the compability mode with all depths and still
423
459
         * allow the custom optimized draw routines with the minimum amount of work */
424
 
        if (0 != bpp_size) {
425
 
                convert();
 
460
        if (0 != st->bpp_size) {
 
461
                convert(st);
426
462
        }
427
463
}
428
464
 
430
466
# define EXIT_FAILURE -1
431
467
#endif
432
468
 
433
 
static void allocate_lense(void)
 
469
static void allocate_lense(struct state *st)
434
470
{
435
471
        int i, j;
436
 
        int s = ((0 != bpp_size) ? (buffer_map->bytes_per_line/bpp_size) : (2*radius+speed+2));
 
472
        int s = ((0 != st->bpp_size) ? (st->buffer_map->bytes_per_line/st->bpp_size) : (2*st->radius+st->speed+2));
437
473
        /* maybe this should be redone so that from[][][] is in one block;
438
474
         * then pointers could be used instead of arrays in some places (and
439
475
         * maybe give a speedup - maybe also consume less memory)
440
476
         */
441
 
        from = (int ***)malloc(s*sizeof(int **));
442
 
        if (from == NULL) {
 
477
        st->from = (int ***)malloc(s*sizeof(int **));
 
478
        if (st->from == NULL) {
443
479
                perror("distort");
444
480
                exit(EXIT_FAILURE);
445
481
        }
446
482
        for (i = 0; i < s; i++) {
447
 
                from[i] = (int **)malloc((2*radius+speed+2) * sizeof(int *));
448
 
                if (from[i] == NULL) {
 
483
                st->from[i] = (int **)malloc((2*st->radius+st->speed+2) * sizeof(int *));
 
484
                if (st->from[i] == NULL) {
449
485
                        perror("distort");
450
486
                        exit(EXIT_FAILURE);
451
487
                }
452
488
                for (j = 0; j < s; j++) {
453
 
                        from[i][j] = (int *)malloc(2 * sizeof(int));
454
 
                        if (from[i][j] == NULL) {
 
489
                        st->from[i][j] = (int *)malloc(2 * sizeof(int));
 
490
                        if (st->from[i][j] == NULL) {
455
491
                                perror("distort");
456
492
                                exit(EXIT_FAILURE);
457
493
                        }
463
499
 * this is a double faced mem vs speed trade, it's faster, but eats
464
500
 * _a lot_ of mem for large radius (is there a bug here? I can't see it)
465
501
 */
466
 
static void init_round_lense(void)
 
502
static void init_round_lense(struct state *st)
467
503
{
468
504
        int k;
469
505
 
470
 
        if (effect == &swamp_thing) {
471
 
                from_array = (int ****)malloc((radius+1)*sizeof(int ***));
472
 
                for (k=0; k <= radius; k++) {
473
 
                        allocate_lense();
474
 
                        make_round_lense(radius, k);
475
 
                        from_array[k] = from;
 
506
        if (st->effect == &swamp_thing) {
 
507
                st->from_array = (int ****)malloc((st->radius+1)*sizeof(int ***));
 
508
                for (k=0; k <= st->radius; k++) {
 
509
                        allocate_lense(st);
 
510
                        make_round_lense(st, st->radius, k);
 
511
                        st->from_array[k] = st->from;
476
512
                }
477
513
        } else { /* just allocate one from[][][] */
478
 
                allocate_lense();
479
 
                make_round_lense(radius,radius);
 
514
                allocate_lense(st);
 
515
                make_round_lense(st, st->radius,st->radius);
480
516
        }
481
517
}
482
518
 
490
526
 * distort_matrix is a precalculated array of how to distort the matrix
491
527
 */
492
528
 
493
 
static void fast_draw_8(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
 
529
static void fast_draw_8(struct state *st, XImage *src, XImage *dest, int x, int y, int *distort_matrix)
 
530
{
494
531
        CARD8 *u = (CARD8 *)dest->data;
495
532
        CARD8 *t = (CARD8 *)src->data + x + y*src->bytes_per_line/sizeof(CARD8);
496
533
 
500
537
        }
501
538
}
502
539
 
503
 
static void fast_draw_16(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
 
540
static void fast_draw_16(struct state *st, XImage *src, XImage *dest, int x, int y, int *distort_matrix)
 
541
{
504
542
        CARD16 *u = (CARD16 *)dest->data;
505
543
        CARD16 *t = (CARD16 *)src->data + x + y*src->bytes_per_line/sizeof(CARD16);
506
544
 
510
548
        }
511
549
}
512
550
 
513
 
static void fast_draw_32(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
 
551
static void fast_draw_32(struct state *st, XImage *src, XImage *dest, int x, int y, int *distort_matrix)
 
552
{
514
553
        CARD32 *u = (CARD32 *)dest->data;
515
554
        CARD32 *t = (CARD32 *)src->data + x + y*src->bytes_per_line/sizeof(CARD32);
516
555
 
520
559
        }
521
560
}
522
561
 
523
 
static void generic_draw(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
 
562
static void generic_draw(struct state *st, XImage *src, XImage *dest, int x, int y, int *distort_matrix)
 
563
{
524
564
        int i, j;
525
565
        for (i = 0; i < dest->width; i++)
526
566
                for (j = 0; j < dest->height; j++)
527
 
                        if (from[i][j][0] + x >= 0 &&
528
 
                                        from[i][j][0] + x < src->width &&
529
 
                                        from[i][j][1] + y >= 0 &&
530
 
                                        from[i][j][1] + y < src->height)
 
567
                        if (st->from[i][j][0] + x >= 0 &&
 
568
                                        st->from[i][j][0] + x < src->width &&
 
569
                                        st->from[i][j][1] + y >= 0 &&
 
570
                                        st->from[i][j][1] + y < src->height)
531
571
                                XPutPixel(dest, i, j,
532
572
                                                XGetPixel(src,
533
 
                                                        from[i][j][0] + x,
534
 
                                                        from[i][j][1] + y));
 
573
                                                        st->from[i][j][0] + x,
 
574
                                                        st->from[i][j][1] + y));
535
575
}
536
576
 
537
577
/* generate an XImage of from[][][] and draw it on the screen */
538
 
static void plain_draw(int k)
 
578
static void plain_draw(struct state *st, int k)
539
579
{
540
 
        if (xy_coo[k].x+2*radius+speed+2 > orig_map->width ||
541
 
                        xy_coo[k].y+2*radius+speed+2 > orig_map->height)
 
580
        if (st->xy_coo[k].x+2*st->radius+st->speed+2 > st->orig_map->width ||
 
581
                        st->xy_coo[k].y+2*st->radius+st->speed+2 > st->orig_map->height)
542
582
                return;
543
583
 
544
 
        draw_routine(orig_map, buffer_map, xy_coo[k].x, xy_coo[k].y, fast_from);
 
584
        st->draw_routine(st, st->orig_map, st->buffer_map, st->xy_coo[k].x, st->xy_coo[k].y, st->fast_from);
545
585
 
546
586
# ifdef HAVE_XSHM_EXTENSION
547
 
        if (use_shm)
548
 
                XShmPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
549
 
                                2*radius+speed+2, 2*radius+speed+2, False);
 
587
        if (st->use_shm)
 
588
                XShmPutImage(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, st->xy_coo[k].x, st->xy_coo[k].y,
 
589
                                2*st->radius+st->speed+2, 2*st->radius+st->speed+2, False);
550
590
        else
551
591
 
552
 
        if (!use_shm)
 
592
        if (!st->use_shm)
553
593
# endif
554
 
                XPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
555
 
                                2*radius+speed+2, 2*radius+speed+2);
 
594
                XPutImage(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, st->xy_coo[k].x, st->xy_coo[k].y,
 
595
                                2*st->radius+st->speed+2, 2*st->radius+st->speed+2);
556
596
 
557
597
}
558
598
 
563
603
 * it should be possible to use the from[][] to speed it up
564
604
 * (once I figure out the algorithm used :)
565
605
 */
566
 
static void reflect_draw(int k)
 
606
static void reflect_draw(struct state *st, int k)
567
607
{
568
608
        int i, j;
569
609
        int     cx, cy;
570
 
        int     ly, lysq, lx, ny, dist, rsq = radius * radius;
571
 
 
572
 
        cx = cy = radius;
573
 
        if (xy_coo[k].ymove > 0)
574
 
                cy += speed;
575
 
        if (xy_coo[k].xmove > 0)
576
 
                cx += speed;
577
 
 
578
 
        for(i = 0 ; i < 2*radius+speed+2; i++) {
 
610
        int     ly, lysq, lx, ny, dist, rsq = st->radius * st->radius;
 
611
 
 
612
        cx = cy = st->radius;
 
613
        if (st->xy_coo[k].ymove > 0)
 
614
                cy += st->speed;
 
615
        if (st->xy_coo[k].xmove > 0)
 
616
                cx += st->speed;
 
617
 
 
618
        for(i = 0 ; i < 2*st->radius+st->speed+2; i++) {
579
619
                ly = i - cy;
580
620
                lysq = ly * ly;
581
 
                ny = xy_coo[k].y + i;
582
 
                if (ny >= orig_map->height) ny = orig_map->height-1;
583
 
                for(j = 0 ; j < 2*radius+speed+2 ; j++) {
 
621
                ny = st->xy_coo[k].y + i;
 
622
                if (ny >= st->orig_map->height) ny = st->orig_map->height-1;
 
623
                for(j = 0 ; j < 2*st->radius+st->speed+2 ; j++) {
584
624
                        lx = j - cx;
585
625
                        dist = lx * lx + lysq;
586
626
                        if (dist > rsq ||
587
 
                                ly < -radius || ly > radius ||
588
 
                                lx < -radius || lx > radius)
589
 
                                XPutPixel( buffer_map, j, i,
590
 
                                                   XGetPixel( orig_map, xy_coo[k].x + j, ny ));
 
627
                                ly < -st->radius || ly > st->radius ||
 
628
                                lx < -st->radius || lx > st->radius)
 
629
                                XPutPixel( st->buffer_map, j, i,
 
630
                                                   XGetPixel( st->orig_map, st->xy_coo[k].x + j, ny ));
591
631
                        else if (dist == 0)
592
 
                                XPutPixel( buffer_map, j, i, black_pixel );
 
632
                                XPutPixel( st->buffer_map, j, i, st->black_pixel );
593
633
                        else {
594
 
                                int     x = xy_coo[k].x + cx + (lx * rsq / dist);
595
 
                                int     y = xy_coo[k].y + cy + (ly * rsq / dist);
596
 
                                if (x < 0 || x >= xgwa.width ||
597
 
                                        y < 0 || y >= xgwa.height)
598
 
                                        XPutPixel( buffer_map, j, i, black_pixel );
 
634
                                int     x = st->xy_coo[k].x + cx + (lx * rsq / dist);
 
635
                                int     y = st->xy_coo[k].y + cy + (ly * rsq / dist);
 
636
                                if (x < 0 || x >= st->xgwa.width ||
 
637
                                        y < 0 || y >= st->xgwa.height)
 
638
                                        XPutPixel( st->buffer_map, j, i, st->black_pixel );
599
639
                                else
600
 
                                        XPutPixel( buffer_map, j, i,
601
 
                                                           XGetPixel( orig_map, x, y ));
 
640
                                        XPutPixel( st->buffer_map, j, i,
 
641
                                                           XGetPixel( st->orig_map, x, y ));
602
642
                        }
603
643
                }
604
644
        }
605
645
 
606
 
        XPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
607
 
                        2*radius+speed+2, 2*radius+speed+2);
 
646
        XPutImage(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, st->xy_coo[k].x, st->xy_coo[k].y,
 
647
                        2*st->radius+st->speed+2, 2*st->radius+st->speed+2);
608
648
}
609
649
 
610
650
/* create a new, random coordinate, that won't interfer with any other
611
651
 * coordinates, as the drawing routines would be significantly slowed
612
652
 * down if they were to handle serveral layers of distortions
613
653
 */
614
 
static void new_rnd_coo(int k)
 
654
static void new_rnd_coo(struct state *st, int k)
615
655
{
616
656
        int i;
617
657
 
618
 
        xy_coo[k].x = (random() % (xgwa.width-2*radius));
619
 
        xy_coo[k].y = (random() % (xgwa.height-2*radius));
 
658
        st->xy_coo[k].x = (random() % (st->xgwa.width-2*st->radius));
 
659
        st->xy_coo[k].y = (random() % (st->xgwa.height-2*st->radius));
620
660
        
621
 
        for (i = 0; i < number; i++) {
 
661
        for (i = 0; i < st->number; i++) {
622
662
                if (i != k) {
623
 
                        if ((abs(xy_coo[k].x - xy_coo[i].x) <= 2*radius+speed+2)
624
 
                         && (abs(xy_coo[k].y - xy_coo[i].y) <= 2*radius+speed+2)) {
625
 
                                xy_coo[k].x = (random() % (xgwa.width-2*radius));
626
 
                                xy_coo[k].y = (random() % (xgwa.height-2*radius));
 
663
                        if ((abs(st->xy_coo[k].x - st->xy_coo[i].x) <= 2*st->radius+st->speed+2)
 
664
                         && (abs(st->xy_coo[k].y - st->xy_coo[i].y) <= 2*st->radius+st->speed+2)) {
 
665
                                st->xy_coo[k].x = (random() % (st->xgwa.width-2*st->radius));
 
666
                                st->xy_coo[k].y = (random() % (st->xgwa.height-2*st->radius));
627
667
                                i=-1; /* ugly */
628
668
                        } 
629
669
                }
631
671
}
632
672
 
633
673
/* move lens and handle bounces with walls and other lenses */
634
 
static void move_lense(int k)
 
674
static void move_lense(struct state *st, int k)
635
675
{
636
676
        int i;
637
677
 
638
 
        if (xy_coo[k].x + 2*radius + speed + 2 >= xgwa.width)
639
 
                xy_coo[k].xmove = -abs(xy_coo[k].xmove);
640
 
        if (xy_coo[k].x <= speed) 
641
 
                xy_coo[k].xmove = abs(xy_coo[k].xmove);
642
 
        if (xy_coo[k].y + 2*radius + speed + 2 >= xgwa.height)
643
 
                xy_coo[k].ymove = -abs(xy_coo[k].ymove);
644
 
        if (xy_coo[k].y <= speed)
645
 
                xy_coo[k].ymove = abs(xy_coo[k].ymove);
 
678
        if (st->xy_coo[k].x + 2*st->radius + st->speed + 2 >= st->xgwa.width)
 
679
                st->xy_coo[k].xmove = -abs(st->xy_coo[k].xmove);
 
680
        if (st->xy_coo[k].x <= st->speed) 
 
681
                st->xy_coo[k].xmove = abs(st->xy_coo[k].xmove);
 
682
        if (st->xy_coo[k].y + 2*st->radius + st->speed + 2 >= st->xgwa.height)
 
683
                st->xy_coo[k].ymove = -abs(st->xy_coo[k].ymove);
 
684
        if (st->xy_coo[k].y <= st->speed)
 
685
                st->xy_coo[k].ymove = abs(st->xy_coo[k].ymove);
646
686
 
647
 
        xy_coo[k].x = xy_coo[k].x + xy_coo[k].xmove;
648
 
        xy_coo[k].y = xy_coo[k].y + xy_coo[k].ymove;
 
687
        st->xy_coo[k].x = st->xy_coo[k].x + st->xy_coo[k].xmove;
 
688
        st->xy_coo[k].y = st->xy_coo[k].y + st->xy_coo[k].ymove;
649
689
 
650
690
        /* bounce against othe lenses */
651
 
        for (i = 0; i < number; i++) {
 
691
        for (i = 0; i < st->number; i++) {
652
692
                if ((i != k)
653
693
                
654
694
/* This commented test is for rectangular lenses (not currently used) and
656
696
                && (abs(xy_coo[k].x - xy_coo[i].x) <= 2*radius)
657
697
                && (abs(xy_coo[k].y - xy_coo[i].y) <= 2*radius)) { */
658
698
 
659
 
                && ((xy_coo[k].x - xy_coo[i].x)*(xy_coo[k].x - xy_coo[i].x)
660
 
                  + (xy_coo[k].y - xy_coo[i].y)*(xy_coo[k].y - xy_coo[i].y)
661
 
                        <= 2*radius*2*radius)) {
 
699
                && ((st->xy_coo[k].x - st->xy_coo[i].x)*(st->xy_coo[k].x - st->xy_coo[i].x)
 
700
                  + (st->xy_coo[k].y - st->xy_coo[i].y)*(st->xy_coo[k].y - st->xy_coo[i].y)
 
701
                        <= 2*st->radius*2*st->radius)) {
662
702
 
663
703
                        int x, y;
664
 
                        x = xy_coo[k].xmove;
665
 
                        y = xy_coo[k].ymove;
666
 
                        xy_coo[k].xmove = xy_coo[i].xmove;
667
 
                        xy_coo[k].ymove = xy_coo[i].ymove;
668
 
                        xy_coo[i].xmove = x;
669
 
                        xy_coo[i].ymove = y;
 
704
                        x = st->xy_coo[k].xmove;
 
705
                        y = st->xy_coo[k].ymove;
 
706
                        st->xy_coo[k].xmove = st->xy_coo[i].xmove;
 
707
                        st->xy_coo[k].ymove = st->xy_coo[i].ymove;
 
708
                        st->xy_coo[i].xmove = x;
 
709
                        st->xy_coo[i].ymove = y;
670
710
                }
671
711
        }
672
712
 
673
713
}
674
714
 
675
715
/* make xy_coo[k] grow/shrink */
676
 
static void swamp_thing(int k)
 
716
static void swamp_thing(struct state *st, int k)
677
717
{
678
 
        if (xy_coo[k].r >= radius)
679
 
                xy_coo[k].r_change = -abs(xy_coo[k].r_change);
 
718
        if (st->xy_coo[k].r >= st->radius)
 
719
                st->xy_coo[k].r_change = -abs(st->xy_coo[k].r_change);
680
720
        
681
 
        if (xy_coo[k].r <= 0) {
682
 
                from = from_array[0];
683
 
                draw(k); 
684
 
                xy_coo[k].r_change = abs(xy_coo[k].r_change);
685
 
                new_rnd_coo(k);
686
 
                xy_coo[k].r=xy_coo[k].r_change;
 
721
        if (st->xy_coo[k].r <= 0) {
 
722
                st->from = st->from_array[0];
 
723
                st->draw(st,k); 
 
724
                st->xy_coo[k].r_change = abs(st->xy_coo[k].r_change);
 
725
                new_rnd_coo(st,k);
 
726
                st->xy_coo[k].r=st->xy_coo[k].r_change;
687
727
                return;
688
728
        }
689
729
 
690
 
        xy_coo[k].r = xy_coo[k].r + xy_coo[k].r_change;
691
 
 
692
 
        if (xy_coo[k].r >= radius)
693
 
                xy_coo[k].r = radius;
694
 
        if (xy_coo[k].r <= 0)
695
 
                xy_coo[k].r=0;
696
 
 
697
 
        from = from_array[xy_coo[k].r];
 
730
        st->xy_coo[k].r = st->xy_coo[k].r + st->xy_coo[k].r_change;
 
731
 
 
732
        if (st->xy_coo[k].r >= st->radius)
 
733
                st->xy_coo[k].r = st->radius;
 
734
        if (st->xy_coo[k].r <= 0)
 
735
                st->xy_coo[k].r=0;
 
736
 
 
737
        st->from = st->from_array[st->xy_coo[k].r];
 
738
}
 
739
 
 
740
 
 
741
static unsigned long
 
742
distort_draw (Display *dpy, Window window, void *closure)
 
743
{
 
744
  struct state *st = (struct state *) closure;
 
745
  int k;
 
746
 
 
747
  if (st->img_loader)   /* still loading */
 
748
    {
 
749
      st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0);
 
750
      if (! st->img_loader)  /* just finished */
 
751
        distort_finish_loading (st);
 
752
      return st->delay;
 
753
    }
 
754
 
 
755
  for (k = 0; k < st->number; k++) {
 
756
    st->effect(st,k);
 
757
    st->draw(st,k);
 
758
  }
 
759
  return st->delay;
 
760
}
 
761
 
 
762
static void
 
763
distort_reshape (Display *dpy, Window window, void *closure, 
 
764
                 unsigned int w, unsigned int h)
 
765
{
 
766
}
 
767
 
 
768
static Bool
 
769
distort_event (Display *dpy, Window window, void *closure, XEvent *event)
 
770
{
 
771
  return False;
 
772
}
 
773
 
 
774
static void
 
775
distort_free (Display *dpy, Window window, void *closure)
 
776
{
 
777
  struct state *st = (struct state *) closure;
 
778
  XFreeGC (st->dpy, st->gc);
 
779
  if (st->orig_map) XDestroyImage (st->orig_map);
 
780
  if (st->buffer_map) XDestroyImage (st->buffer_map);
 
781
  if (st->from) free (st->from);
 
782
  if (st->fast_from) free (st->fast_from);
 
783
  if (st->from_array) free (st->from_array);
 
784
  free (st);
698
785
}
699
786
 
700
787
 
701
788
 
702
789
 
703
 
char *progclass = "Distort";
704
 
 
705
 
char *defaults [] = {
 
790
static const char *distort_defaults [] = {
706
791
        "*dontClearRoot:                True",
 
792
        "*background:                   Black",
707
793
#ifdef __sgi    /* really, HAVE_READ_DISPLAY_EXTENSION */
708
794
        "*visualID:                     Best",
709
795
#endif
712
798
        "*radius:                       0",
713
799
        "*speed:                        0",
714
800
        "*number:                       0",
 
801
        "*slow:                         False",
715
802
        "*vortex:                       False",
716
803
        "*magnify:                      False",
717
 
        "*swamp:                        False",
718
 
        "*bounce:                       False",
719
804
        "*reflect:                      False",
720
805
        "*blackhole:            False",
 
806
        "*effect:                   none",
721
807
#ifdef HAVE_XSHM_EXTENSION
722
808
        "*useSHM:                       False",         /* xshm turns out not to help. */
723
809
#endif /* HAVE_XSHM_EXTENSION */
724
810
        0
725
811
};
726
812
 
727
 
XrmOptionDescRec options [] = {
728
 
        { "-delay",     ".delay",       XrmoptionSepArg, 0 },
729
 
        { "-radius",    ".radius",      XrmoptionSepArg, 0 },
730
 
        { "-speed",     ".speed",       XrmoptionSepArg, 0 },
731
 
        { "-number",    ".number",      XrmoptionSepArg, 0 },
732
 
        { "-swamp",     ".swamp",       XrmoptionNoArg, "True" },
733
 
        { "-bounce",    ".bounce",      XrmoptionNoArg, "True" },
734
 
        { "-reflect",   ".reflect",     XrmoptionNoArg, "True" },
735
 
        { "-vortex",    ".vortex",      XrmoptionNoArg, "True" },
736
 
        { "-magnify",   ".magnify",     XrmoptionNoArg, "True" },
737
 
        { "-blackhole", ".blackhole",   XrmoptionNoArg, "True" },
738
 
        { "-slow",      ".slow",        XrmoptionNoArg, "True" },
 
813
static XrmOptionDescRec distort_options [] = {
 
814
  { "-delay",     ".delay",       XrmoptionSepArg, 0 },
 
815
  { "-radius",    ".radius",      XrmoptionSepArg, 0 },
 
816
  { "-speed",     ".speed",       XrmoptionSepArg, 0 },
 
817
  { "-number",    ".number",      XrmoptionSepArg, 0 },
 
818
 
 
819
  { "-effect",    ".effect",      XrmoptionSepArg, 0 },
 
820
  { "-swamp",     ".effect",      XrmoptionNoArg, "swamp"  },
 
821
  { "-bounce",    ".effect",      XrmoptionNoArg, "bounce" },
 
822
 
 
823
  { "-reflect",   ".reflect",     XrmoptionNoArg, "True" },
 
824
  { "-vortex",    ".vortex",      XrmoptionNoArg, "True" },
 
825
  { "-magnify",   ".magnify",     XrmoptionNoArg, "True" },
 
826
  { "-blackhole", ".blackhole",   XrmoptionNoArg, "True" },
 
827
  { "-slow",      ".slow",        XrmoptionNoArg, "True" },
739
828
#ifdef HAVE_XSHM_EXTENSION
740
 
        { "-shm",               ".useSHM",      XrmoptionNoArg, "True" },
741
 
        { "-no-shm",    ".useSHM",      XrmoptionNoArg, "False" },
 
829
  { "-shm",       ".useSHM",      XrmoptionNoArg, "True" },
 
830
  { "-no-shm",    ".useSHM",      XrmoptionNoArg, "False" },
742
831
#endif /* HAVE_XSHM_EXTENSION */
743
 
        { 0, 0, 0, 0 }
 
832
  { 0, 0, 0, 0 }
744
833
};
745
834
 
746
 
 
747
 
void screenhack(Display *dpy, Window window)
748
 
{
749
 
        int k;
750
 
 
751
 
        init_distort (dpy, window);
752
 
        while (1) {
753
 
                for (k = 0; k < number; k++) {
754
 
                        effect(k);
755
 
                        draw(k);
756
 
                }
757
 
 
758
 
                XSync(dpy, False);
759
 
        screenhack_handle_events (dpy);
760
 
                if (delay) usleep(delay);
761
 
        }
762
 
 
763
 
}
 
835
XSCREENSAVER_MODULE ("Distort", distort)