X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fdistort.c;h=54439d44733f03b3aa29843cf493845df34ff0cf;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hp=6903c8c7472c9096fe4aa37555d2e4686656f9ae;hpb=dba664f31aa87285db4d76cf8c5e66335299703a;p=xscreensaver diff --git a/hacks/distort.c b/hacks/distort.c index 6903c8c7..54439d44 100644 --- a/hacks/distort.c +++ b/hacks/distort.c @@ -32,15 +32,15 @@ * 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 +#include #include "screenhack.h" /*#include */ - -#ifdef HAVE_XSHM_EXTENSION # include "xshm.h" -#endif /* HAVE_XSHM_EXTENSION */ #define CARD32 unsigned int #define CARD16 unsigned short @@ -77,16 +77,14 @@ struct state { 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; }; @@ -105,17 +103,15 @@ static void generic_draw(struct state *st, XImage *, XImage *, int, int, int *); 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"); @@ -123,19 +119,15 @@ distort_init (Display *dpy, Window window) 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->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")) @@ -147,8 +139,6 @@ distort_init (Display *dpy, Window window) 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: @@ -268,6 +258,19 @@ distort_init (Display *dpy, Window window) } 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 ); @@ -278,9 +281,16 @@ distort_init (Display *dpy, Window window) 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; } @@ -289,11 +299,15 @@ distort_finish_loading (struct state *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) { @@ -301,28 +315,10 @@ distort_finish_loading (struct state *st) 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) @@ -589,17 +585,8 @@ static void plain_draw(struct state *st, int k) 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); } @@ -762,9 +749,12 @@ distort_draw (Display *dpy, Window window, void *closure) } 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; } @@ -791,6 +781,12 @@ distort_reshape (Display *dpy, Window window, void *closure, 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; } @@ -799,8 +795,9 @@ distort_free (Display *dpy, Window window, void *closure) { 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); @@ -832,8 +829,9 @@ static const char *distort_defaults [] = { #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 };