38
38
#include "screenhack.h"
39
#include <X11/Xutil.h>
39
/*#include <X11/Xmd.h>*/
42
41
#ifdef HAVE_XSHM_EXTENSION
44
static Bool use_shm = False;
45
static XShmSegmentInfo shm_info;
46
43
#endif /* HAVE_XSHM_EXTENSION */
45
#define CARD32 unsigned int
46
#define CARD16 unsigned short
47
#define CARD8 unsigned char
54
static struct coo xy_coo[10];
56
static int delay, radius, speed, number, blackhole, vortex, magnify, reflect, slow;
57
static XWindowAttributes xgwa;
59
static Window g_window;
60
static Display *g_dpy;
61
static unsigned long black_pixel;
63
static XImage *orig_map, *buffer_map;
64
static unsigned long *buffer_map_cache;
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);
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;
86
static void init_distort(Display *dpy, Window window)
61
struct coo xy_coo[10];
63
int delay, radius, speed, number, blackhole, vortex, magnify, reflect, slow;
64
XWindowAttributes xgwa;
66
unsigned long black_pixel;
68
XImage *orig_map, *buffer_map;
69
unsigned long *buffer_map_cache;
77
#ifdef HAVE_XSHM_EXTENSION
79
XShmSegmentInfo shm_info;
80
#endif /* HAVE_XSHM_EXTENSION */
82
void (*effect) (struct state *, int);
83
void (*draw) (struct state *, int);
84
void (*draw_routine) (struct state *st, XImage *, XImage *, int, int, int *);
86
async_load_state *img_loader;
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);
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 *);
103
static void distort_finish_loading (struct state *);
106
distort_init (Display *dpy, Window window)
108
struct state *st = (struct state *) calloc (1, sizeof(*st));
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");
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");
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 */
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");
110
if (get_boolean_resource("swamp", "Boolean"))
111
effect = &swamp_thing;
112
if (get_boolean_resource("bounce", "Boolean"))
113
effect = &move_lense;
115
XGetWindowAttributes (dpy, window, &xgwa);
117
if (effect == NULL && radius == 0 && speed == 0 && number == 0
118
&& !blackhole && !vortex && !magnify && !reflect) {
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"))
141
fprintf(stderr,"%s: bogus effect: %s\n", progname, s);
143
XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
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
140
168
i = (random() % 12 /* 17 */);
170
st->draw = &plain_draw;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
183
211
#if 0 /* jwz: not these */
185
radius=50;number=4;speed=2;
213
st->radius=50;st->number=4;st->speed=2;
186
214
effect=&swamp_thing;break;
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;
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;
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;
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;
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;
210
238
/* never allow the radius to be too close to the min window dimension
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;
216
244
/* -swamp mode consumes vast amounts of memory, proportional to radius --
217
245
so throttle radius to a small-ish value (60 => ~30MB.)
219
if (effect == &swamp_thing && radius > 60)
247
if (st->effect == &swamp_thing && st->radius > 60)
233
effect = &move_lense;
235
draw = &reflect_draw;
236
effect = &move_lense;
258
if (st->number >= 10)
260
if (st->effect == NULL)
261
st->effect = &move_lense;
263
st->draw = &reflect_draw;
264
st->effect = &move_lense;
266
if (st->draw == NULL)
267
st->draw = &plain_draw;
241
black_pixel = BlackPixelOfScreen( xgwa.screen );
269
st->black_pixel = BlackPixelOfScreen( st->xgwa.screen );
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);
250
load_random_image (xgwa.screen, window, window, NULL, NULL);
253
orig_map = XGetImage(dpy, window, 0, 0, xgwa.width, xgwa.height,
276
st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
278
st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
284
distort_finish_loading (struct state *st)
289
st->orig_map = XGetImage(st->dpy, st->window, 0, 0, st->xgwa.width, st->xgwa.height,
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));
257
if (buffer_map_cache == NULL) {
293
if (st->buffer_map_cache == NULL) {
258
294
perror("distort");
259
295
exit(EXIT_FAILURE);
262
298
# ifdef HAVE_XSHM_EXTENSION
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);
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);
273
309
# endif /* HAVE_XSHM_EXTENSION */
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,
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);
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)
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)
326
switch (st->orig_map->bits_per_pixel) {
292
draw_routine = &fast_draw_32;
293
bpp_size = sizeof(CARD32);
328
st->draw_routine = &fast_draw_32;
329
st->bpp_size = sizeof(CARD32);
296
draw_routine = &fast_draw_16;
297
bpp_size = sizeof(CARD16);
332
st->draw_routine = &fast_draw_16;
333
st->bpp_size = sizeof(CARD16);
300
draw_routine = &fast_draw_8;
301
bpp_size = sizeof(CARD8);
336
st->draw_routine = &fast_draw_8;
337
st->bpp_size = sizeof(CARD8);
304
draw_routine = &generic_draw;
340
st->draw_routine = &generic_draw;
308
draw_routine = &generic_draw;
344
st->draw_routine = &generic_draw;
346
init_round_lense(st);
312
for (i = 0; i < number; i++) {
315
xy_coo[i].r = (i*radius)/(number-1); /* "randomize" initial */
348
for (i = 0; i < st->number; i++) {
351
st->xy_coo[i].r = (i*st->radius)/(st->number-1); /* "randomize" initial */
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);
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);
325
360
/* example: initializes a "see-trough" matrix */
326
/* static void make_null_lense(void)
361
/* static void make_null_lense(struct state *st)
329
364
for (i = 0; i < 2*radius+speed+2; i++) {
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)
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,
573
st->from[i][j][0] + x,
574
st->from[i][j][1] + y));
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)
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)
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);
546
586
# ifdef HAVE_XSHM_EXTENSION
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);
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);
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);
563
603
* it should be possible to use the from[][] to speed it up
564
604
* (once I figure out the algorithm used :)
566
static void reflect_draw(int k)
606
static void reflect_draw(struct state *st, int k)
570
int ly, lysq, lx, ny, dist, rsq = radius * radius;
573
if (xy_coo[k].ymove > 0)
575
if (xy_coo[k].xmove > 0)
578
for(i = 0 ; i < 2*radius+speed+2; i++) {
610
int ly, lysq, lx, ny, dist, rsq = st->radius * st->radius;
612
cx = cy = st->radius;
613
if (st->xy_coo[k].ymove > 0)
615
if (st->xy_coo[k].xmove > 0)
618
for(i = 0 ; i < 2*st->radius+st->speed+2; i++) {
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++) {
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 );
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 );
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 ));
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);
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
614
static void new_rnd_coo(int k)
654
static void new_rnd_coo(struct state *st, int k)
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));
621
for (i = 0; i < number; i++) {
661
for (i = 0; i < st->number; i++) {
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));
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)
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);
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;
650
690
/* bounce against othe lenses */
651
for (i = 0; i < number; i++) {
691
for (i = 0; i < st->number; i++) {
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)) { */
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)) {
666
xy_coo[k].xmove = xy_coo[i].xmove;
667
xy_coo[k].ymove = xy_coo[i].ymove;
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;
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)
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);
681
if (xy_coo[k].r <= 0) {
682
from = from_array[0];
684
xy_coo[k].r_change = abs(xy_coo[k].r_change);
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];
724
st->xy_coo[k].r_change = abs(st->xy_coo[k].r_change);
726
st->xy_coo[k].r=st->xy_coo[k].r_change;
690
xy_coo[k].r = xy_coo[k].r + xy_coo[k].r_change;
692
if (xy_coo[k].r >= radius)
693
xy_coo[k].r = radius;
694
if (xy_coo[k].r <= 0)
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;
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)
737
st->from = st->from_array[st->xy_coo[k].r];
742
distort_draw (Display *dpy, Window window, void *closure)
744
struct state *st = (struct state *) closure;
747
if (st->img_loader) /* still loading */
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);
755
for (k = 0; k < st->number; k++) {
763
distort_reshape (Display *dpy, Window window, void *closure,
764
unsigned int w, unsigned int h)
769
distort_event (Display *dpy, Window window, void *closure, XEvent *event)
775
distort_free (Display *dpy, Window window, void *closure)
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);
703
char *progclass = "Distort";
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",
715
802
"*vortex: False",
716
803
"*magnify: False",
719
804
"*reflect: False",
720
805
"*blackhole: False",
721
807
#ifdef HAVE_XSHM_EXTENSION
722
808
"*useSHM: False", /* xshm turns out not to help. */
723
809
#endif /* HAVE_XSHM_EXTENSION */
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 },
819
{ "-effect", ".effect", XrmoptionSepArg, 0 },
820
{ "-swamp", ".effect", XrmoptionNoArg, "swamp" },
821
{ "-bounce", ".effect", XrmoptionNoArg, "bounce" },
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 */
747
void screenhack(Display *dpy, Window window)
751
init_distort (dpy, window);
753
for (k = 0; k < number; k++) {
759
screenhack_handle_events (dpy);
760
if (delay) usleep(delay);
835
XSCREENSAVER_MODULE ("Distort", distort)