X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fdistort.c;h=477ee63b77844dbdaae1a07bf68f628558a7627d;hb=aa75c7476aeaa84cf3abc192b376a8b03c325213;hp=7755f0283fda8c722c23ef29b1c2e28a06a4dd0c;hpb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;p=xscreensaver diff --git a/hacks/distort.c b/hacks/distort.c index 7755f028..477ee63b 100644 --- a/hacks/distort.c +++ b/hacks/distort.c @@ -1,5 +1,5 @@ /* -*- mode: C; tab-width: 4 -*- - * xscreensaver, Copyright (c) 1992-2006 Jamie Zawinski + * xscreensaver, Copyright (c) 1992-2014 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -35,6 +35,7 @@ */ #include +#include #include "screenhack.h" /*#include */ @@ -61,6 +62,9 @@ struct state { struct coo xy_coo[10]; int delay, radius, speed, number, blackhole, vortex, magnify, reflect, slow; + int duration; + time_t start_time; + XWindowAttributes xgwa; GC gc; unsigned long black_pixel; @@ -102,33 +106,31 @@ 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"); st->radius = get_integer_resource(st->dpy, "radius", "Integer"); st->speed = get_integer_resource(st->dpy, "speed", "Integer"); st->number = get_integer_resource(st->dpy, "number", "Integer"); -#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")) @@ -140,29 +142,27 @@ 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: - * -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 */); @@ -171,74 +171,70 @@ distort_init (Display *dpy, Window window) 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 -- @@ -265,6 +261,23 @@ 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; + +#ifdef HAVE_XSHM_EXTENSION + st->use_shm = get_boolean_resource(st->dpy, "useSHM", "Boolean"); +#endif /* HAVE_XSHM_EXTENSION */ + + distort_reset (st); st->black_pixel = BlackPixelOfScreen( st->xgwa.screen ); @@ -277,6 +290,7 @@ distort_init (Display *dpy, Window window) st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window, st->window, 0, 0); + st->start_time = time ((time_t *) 0); return st; } @@ -285,6 +299,8 @@ distort_finish_loading (struct state *st) { int i; + 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); @@ -654,6 +670,7 @@ static void reflect_draw(struct state *st, int k) 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)); @@ -667,6 +684,7 @@ static void new_rnd_coo(struct state *st, int k) i=-1; /* ugly */ } } + if (loop++ > 1000) return; /* let's not get stuck */ } } @@ -747,11 +765,19 @@ distort_draw (Display *dpy, Window window, void *closure) if (st->img_loader) /* still loading */ { st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0); - if (! st->img_loader) /* just finished */ + if (! st->img_loader) { /* just finished */ distort_finish_loading (st); + } return st->delay; } + if (!st->img_loader && + st->start_time + st->duration < time ((time_t *) 0)) { + st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window, + st->window, 0, 0); + return st->delay; + } + for (k = 0; k < st->number; k++) { st->effect(st,k); st->draw(st,k); @@ -763,11 +789,24 @@ static void distort_reshape (Display *dpy, Window window, void *closure, unsigned int w, unsigned int h) { + struct state *st = (struct state *) closure; + XGetWindowAttributes (st->dpy, st->window, &st->xgwa); + /* XClearWindow (dpy, window); */ + /* Why doesn't this work? */ + if (st->orig_map) /* created in distort_finish_loading, might be early */ + XPutImage (st->dpy, st->window, st->gc, st->orig_map, + 0, 0, st->orig_map->width, st->orig_map->height, 0, 0); } 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; } @@ -790,11 +829,13 @@ distort_free (Display *dpy, Window window, void *closure) static const char *distort_defaults [] = { "*dontClearRoot: True", "*background: Black", + "*fpsSolid: true", #ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */ "*visualID: Best", #endif "*delay: 20000", + "*duration: 120", "*radius: 0", "*speed: 0", "*number: 0", @@ -807,11 +848,16 @@ static const char *distort_defaults [] = { #ifdef HAVE_XSHM_EXTENSION "*useSHM: False", /* xshm turns out not to help. */ #endif /* HAVE_XSHM_EXTENSION */ +#ifdef HAVE_MOBILE + "*ignoreRotation: True", + "*rotateImages: True", +#endif 0 }; static XrmOptionDescRec distort_options [] = { { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-duration", ".duration", XrmoptionSepArg, 0 }, { "-radius", ".radius", XrmoptionSepArg, 0 }, { "-speed", ".speed", XrmoptionSepArg, 0 }, { "-number", ".number", XrmoptionSepArg, 0 },