/* -*- mode: C; tab-width: 4 -*-
- * xscreensaver, Copyright (c) 1992-2013 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1992-2018 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* on wood).
* 08 Oct 1999 Jonas Munsin (jmunsin@iki.fi)
* Corrected several bugs causing references beyond allocated memory.
+ * 09 Oct 2016 Dave Odell (dmo2118@gmail.com)
+ * Updated for new xshm.c.
*/
#include <math.h>
+#include <time.h>
#include "screenhack.h"
/*#include <X11/Xmd.h>*/
-
-#ifdef HAVE_XSHM_EXTENSION
# include "xshm.h"
-#endif /* HAVE_XSHM_EXTENSION */
#define CARD32 unsigned int
#define CARD16 unsigned short
int bpp_size;
-#ifdef HAVE_XSHM_EXTENSION
- Bool use_shm;
XShmSegmentInfo shm_info;
-#endif /* HAVE_XSHM_EXTENSION */
void (*effect) (struct state *, int);
void (*draw) (struct state *, int);
void (*draw_routine) (struct state *st, XImage *, XImage *, int, int, int *);
async_load_state *img_loader;
+ Pixmap pm;
};
static void distort_finish_loading (struct state *);
-static void *
-distort_init (Display *dpy, Window window)
+static void
+distort_reset (struct state *st)
{
- struct state *st = (struct state *) calloc (1, sizeof(*st));
- XGCValues gcv;
- long gcflags;
- int i;
char *s;
+ int i;
- st->dpy = dpy;
- st->window = window;
+ st->start_time = 0;
+
+ XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
st->delay = get_integer_resource(st->dpy, "delay", "Integer");
st->duration = get_integer_resource (st->dpy, "duration", "Seconds");
st->speed = get_integer_resource(st->dpy, "speed", "Integer");
st->number = get_integer_resource(st->dpy, "number", "Integer");
- if (st->delay < 0) st->delay = 0;
- if (st->duration < 1) st->duration = 1;
-
-#ifdef HAVE_XSHM_EXTENSION
- st->use_shm = get_boolean_resource(st->dpy, "useSHM", "Boolean");
-#endif /* HAVE_XSHM_EXTENSION */
-
st->blackhole = get_boolean_resource(st->dpy, "blackhole", "Boolean");
st->vortex = get_boolean_resource(st->dpy, "vortex", "Boolean");
st->magnify = get_boolean_resource(st->dpy, "magnify", "Boolean");
st->reflect = get_boolean_resource(st->dpy, "reflect", "Boolean");
st->slow = get_boolean_resource(st->dpy, "slow", "Boolean");
+ if (st->xgwa.width > 2560) st->radius *= 3; /* Retina displays */
+
+ if (st->delay < 0) st->delay = 0;
+ if (st->duration < 1) st->duration = 1;
+
st->effect = NULL;
s = get_string_resource(st->dpy, "effect", "String");
if (s && !strcasecmp(s,"swamp"))
else if (s && *s)
fprintf(stderr,"%s: bogus effect: %s\n", progname, s);
- XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
-
if (st->effect == NULL && st->radius == 0 && st->speed == 0 && st->number == 0
&& !st->blackhole && !st->vortex && !st->magnify && !st->reflect) {
/* if no cmdline options are given, randomly choose one of:
- * -radius 50 -number 4 -speed 1 -bounce
- * -radius 50 -number 4 -speed 1 -blackhole
- * -radius 50 -number 4 -speed 1 -vortex
- * -radius 50 -number 4 -speed 1 -vortex -magnify
- * -radius 50 -number 4 -speed 1 -vortex -magnify -blackhole
- * -radius 100 -number 1 -speed 2 -bounce
- * -radius 100 -number 1 -speed 2 -blackhole
- * -radius 100 -number 1 -speed 2 -vortex
- * -radius 100 -number 1 -speed 2 -vortex -magnify
- * -radius 100 -number 1 -speed 2 -vortex -magnify -blackhole
+ * -radius 125 -number 4 -speed 1 -bounce
+ * -radius 125 -number 4 -speed 1 -blackhole
+ * -radius 125 -number 4 -speed 1 -vortex
+ * -radius 125 -number 4 -speed 1 -vortex -magnify
+ * -radius 125 -number 4 -speed 1 -vortex -magnify -blackhole
+ * -radius 250 -number 1 -speed 2 -bounce
+ * -radius 250 -number 1 -speed 2 -blackhole
+ * -radius 250 -number 1 -speed 2 -vortex
+ * -radius 250 -number 1 -speed 2 -vortex -magnify
+ * -radius 250 -number 1 -speed 2 -vortex -magnify -blackhole
* -radius 80 -number 1 -speed 2 -reflect
- * -radius 50 -number 3 -speed 2 -reflect
+ * -radius 125 -number 3 -speed 2 -reflect
* jwz: not these
- * -radius 50 -number 4 -speed 2 -swamp
- * -radius 50 -number 4 -speed 2 -swamp -blackhole
- * -radius 50 -number 4 -speed 2 -swamp -vortex
- * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify
- * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify -blackhole
+ * -radius 125 -number 4 -speed 2 -swamp
+ * -radius 125 -number 4 -speed 2 -swamp -blackhole
+ * -radius 125 -number 4 -speed 2 -swamp -vortex
+ * -radius 125 -number 4 -speed 2 -swamp -vortex -magnify
+ * -radius 125 -number 4 -speed 2 -swamp -vortex -magnify -blackhole
*/
i = (random() % 12 /* 17 */);
switch (i) {
case 0:
- st->radius=50;st->number=4;st->speed=1;
+ st->radius=125;st->number=4;st->speed=1;
st->effect=&move_lense;break;
case 1:
- st->radius=50;st->number=4;st->speed=1;st->blackhole=1;
+ st->radius=125;st->number=4;st->speed=1;st->blackhole=1;
st->effect=&move_lense;break;
case 2:
- st->radius=50;st->number=4;st->speed=1;st->vortex=1;
+ st->radius=125;st->number=4;st->speed=1;st->vortex=1;
st->effect=&move_lense;break;
case 3:
- st->radius=50;st->number=4;st->speed=1;st->vortex=1;st->magnify=1;
+ st->radius=125;st->number=4;st->speed=1;st->vortex=1;st->magnify=1;
st->effect=&move_lense;break;
case 4:
- st->radius=50;st->number=4;st->speed=1;st->vortex=1;st->magnify=1;st->blackhole=1;
+ st->radius=125;st->number=4;st->speed=1;st->vortex=1;st->magnify=1;st->blackhole=1;
st->effect=&move_lense;break;
case 5:
- st->radius=100;st->number=1;st->speed=2;
+ st->radius=250;st->number=1;st->speed=2;
st->effect=&move_lense;break;
case 6:
- st->radius=100;st->number=1;st->speed=2;st->blackhole=1;
+ st->radius=250;st->number=1;st->speed=2;st->blackhole=1;
st->effect=&move_lense;break;
case 7:
- st->radius=100;st->number=1;st->speed=2;st->vortex=1;
+ st->radius=250;st->number=1;st->speed=2;st->vortex=1;
st->effect=&move_lense;break;
case 8:
- st->radius=100;st->number=1;st->speed=2;st->vortex=1;st->magnify=1;
+ st->radius=250;st->number=1;st->speed=2;st->vortex=1;st->magnify=1;
st->effect=&move_lense;break;
case 9:
- st->radius=100;st->number=1;st->speed=2;st->vortex=1;st->magnify=1;st->blackhole=1;
+ st->radius=250;st->number=1;st->speed=2;st->vortex=1;st->magnify=1;st->blackhole=1;
st->effect=&move_lense;break;
case 10:
st->radius=80;st->number=1;st->speed=2;st->reflect=1;
st->draw = &reflect_draw;st->effect = &move_lense;break;
case 11:
- st->radius=50;st->number=4;st->speed=2;st->reflect=1;
+ st->radius=125;st->number=4;st->speed=2;st->reflect=1;
st->draw = &reflect_draw;st->effect = &move_lense;break;
#if 0 /* jwz: not these */
case 12:
- st->radius=50;st->number=4;st->speed=2;
+ st->radius=125;st->number=4;st->speed=2;
effect=&swamp_thing;break;
case 13:
- st->radius=50;st->number=4;st->speed=2;st->blackhole=1;
+ st->radius=125;st->number=4;st->speed=2;st->blackhole=1;
effect=&swamp_thing;break;
case 14:
- st->radius=50;st->number=4;st->speed=2;st->vortex=1;
+ st->radius=125;st->number=4;st->speed=2;st->vortex=1;
effect=&swamp_thing;break;
case 15:
- st->radius=50;st->number=4;st->speed=2;st->vortex=1;st->magnify=1;
+ st->radius=125;st->number=4;st->speed=2;st->vortex=1;st->magnify=1;
effect=&swamp_thing;break;
case 16:
- st->radius=50;st->number=4;st->speed=2;st->vortex=1;st->magnify=1;st->blackhole=1;
+ st->radius=125;st->number=4;st->speed=2;st->vortex=1;st->magnify=1;st->blackhole=1;
effect=&swamp_thing;break;
#endif
default:
abort(); break;
}
-
- /* but if the window is small, reduce default radius */
- if (st->xgwa.width < st->radius * 8)
- st->radius = st->xgwa.width/8;
}
/* never allow the radius to be too close to the min window dimension
*/
- if (st->radius >= st->xgwa.width * 0.45) st->radius = st->xgwa.width * 0.45;
- if (st->radius >= st->xgwa.height * 0.45) st->radius = st->xgwa.height * 0.45;
+ if (st->radius > st->xgwa.width * 0.3) st->radius = st->xgwa.width * 0.3;
+ if (st->radius > st->xgwa.height * 0.3) st->radius = st->xgwa.height * 0.3;
/* -swamp mode consumes vast amounts of memory, proportional to radius --
}
if (st->draw == NULL)
st->draw = &plain_draw;
+}
+
+static void *
+distort_init (Display *dpy, Window window)
+{
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
+ XGCValues gcv;
+ long gcflags;
+
+ st->dpy = dpy;
+ st->window = window;
+
+ distort_reset (st);
st->black_pixel = BlackPixelOfScreen( st->xgwa.screen );
gcflags |= GCSubwindowMode;
st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
+ /* On MacOS X11, XGetImage on a Window often gets an inexplicable BadMatch,
+ possibly due to the window manager having occluded something? It seems
+ nondeterministic. Loading the image into a pixmap instead fixes it. */
+ if (st->pm) XFreePixmap (st->dpy, st->pm);
+ st->pm = XCreatePixmap (st->dpy, st->window,
+ st->xgwa.width, st->xgwa.height, st->xgwa.depth);
+
st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
- st->window, 0, 0);
- st->start_time = time ((time_t) 0);
+ st->pm, 0, 0);
+ st->start_time = time ((time_t *) 0);
return st;
}
{
int i;
- st->start_time = time ((time_t) 0);
+ st->start_time = time ((time_t *) 0);
- st->buffer_map = 0;
- st->orig_map = XGetImage(st->dpy, st->window, 0, 0, st->xgwa.width, st->xgwa.height,
- ~0L, ZPixmap);
+ if (! st->pm) abort();
+ XClearWindow (st->dpy, st->window);
+ XCopyArea (st->dpy, st->pm, st->window, st->gc,
+ 0, 0, st->xgwa.width, st->xgwa.height, 0, 0);
+ st->orig_map = XGetImage(st->dpy, st->pm, 0, 0,
+ st->xgwa.width, st->xgwa.height,
+ ~0L, ZPixmap);
st->buffer_map_cache = malloc(sizeof(unsigned long)*(2*st->radius+st->speed+2)*(2*st->radius+st->speed+2));
if (st->buffer_map_cache == NULL) {
exit(EXIT_FAILURE);
}
-# ifdef HAVE_XSHM_EXTENSION
-
- if (st->use_shm)
- {
- st->buffer_map = create_xshm_image(st->dpy, st->xgwa.visual, st->orig_map->depth,
- ZPixmap, 0, &st->shm_info,
- 2*st->radius + st->speed + 2,
- 2*st->radius + st->speed + 2);
- if (!st->buffer_map)
- st->use_shm = False;
- }
-# endif /* HAVE_XSHM_EXTENSION */
-
- if (!st->buffer_map)
- {
- st->buffer_map = XCreateImage(st->dpy, st->xgwa.visual,
- st->orig_map->depth, ZPixmap, 0, 0,
- 2*st->radius + st->speed + 2, 2*st->radius + st->speed + 2,
- 8, 0);
- st->buffer_map->data = (char *)
- calloc(st->buffer_map->height, st->buffer_map->bytes_per_line);
- }
+ st->buffer_map = create_xshm_image(st->dpy, st->xgwa.visual, st->orig_map->depth,
+ ZPixmap, &st->shm_info,
+ 2*st->radius + st->speed + 2,
+ 2*st->radius + st->speed + 2);
if ((st->buffer_map->byte_order == st->orig_map->byte_order)
&& (st->buffer_map->depth == st->orig_map->depth)
st->draw_routine(st, st->orig_map, st->buffer_map, st->xy_coo[k].x, st->xy_coo[k].y, st->fast_from);
-# ifdef HAVE_XSHM_EXTENSION
- if (st->use_shm)
- XShmPutImage(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, st->xy_coo[k].x, st->xy_coo[k].y,
- 2*st->radius+st->speed+2, 2*st->radius+st->speed+2, False);
- else
-
- if (!st->use_shm)
-# endif
- XPutImage(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, st->xy_coo[k].x, st->xy_coo[k].y,
- 2*st->radius+st->speed+2, 2*st->radius+st->speed+2);
-
+ put_xshm_image(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, st->xy_coo[k].x, st->xy_coo[k].y,
+ 2*st->radius+st->speed+2, 2*st->radius+st->speed+2, &st->shm_info);
}
static void new_rnd_coo(struct state *st, int k)
{
int i;
+ int loop = 0;
st->xy_coo[k].x = (random() % (st->xgwa.width-2*st->radius));
st->xy_coo[k].y = (random() % (st->xgwa.height-2*st->radius));
i=-1; /* ugly */
}
}
+ if (loop++ > 1000) return; /* let's not get stuck */
}
}
}
if (!st->img_loader &&
- st->start_time + st->duration < time ((time_t) 0)) {
+ st->start_time + st->duration < time ((time_t *) 0)) {
+ if (st->pm) XFreePixmap (st->dpy, st->pm);
+ st->pm = XCreatePixmap (st->dpy, st->window,
+ st->xgwa.width, st->xgwa.height, st->xgwa.depth);
st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
- st->window, 0, 0);
+ st->pm, 0, 0);
return st->delay;
}
static Bool
distort_event (Display *dpy, Window window, void *closure, XEvent *event)
{
+ struct state *st = (struct state *) closure;
+ if (screenhack_event_helper (dpy, window, event))
+ {
+ distort_reset(st);
+ return True;
+ }
return False;
}
{
struct state *st = (struct state *) closure;
XFreeGC (st->dpy, st->gc);
+ if (st->pm) XFreePixmap (dpy, st->pm);
if (st->orig_map) XDestroyImage (st->orig_map);
- if (st->buffer_map) XDestroyImage (st->buffer_map);
+ if (st->buffer_map) destroy_xshm_image (st->dpy, st->buffer_map, &st->shm_info);
if (st->from) free (st->from);
if (st->fast_from) free (st->fast_from);
if (st->from_array) free (st->from_array);
#ifdef HAVE_XSHM_EXTENSION
"*useSHM: False", /* xshm turns out not to help. */
#endif /* HAVE_XSHM_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
+ "*rotateImages: True",
#endif
0
};