X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Ftwang.c;h=1b2cdf6255793ae6734cbf64779ca851ebad0f9e;hb=78add6e627ee5f10e1fa6f3852602ea5066eee5a;hp=ce22944fca1c22b38cceacb54a1030f856961813;hpb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;p=xscreensaver diff --git a/hacks/twang.c b/hacks/twang.c index ce22944f..1b2cdf62 100644 --- a/hacks/twang.c +++ b/hacks/twang.c @@ -15,10 +15,7 @@ #include #include "screenhack.h" - -#ifdef HAVE_XSHM_EXTENSION #include "xshm.h" -#endif #define FLOAT double @@ -48,6 +45,7 @@ struct state { Window window; int delay; /* delay (usec) between iterations */ + int duration; /* time (sec) before loading new image */ int maxColumns; /* the maximum number of columns of tiles */ int maxRows; /* the maximum number of rows of tiles */ int tileSize; /* the size (width and height) of a tile */ @@ -61,7 +59,6 @@ struct state { Screen *screen; /* the screen to draw on */ XImage *sourceImage; /* image source of stuff to draw */ XImage *workImage; /* work area image, used when rendering */ - XImage *backgroundImage; /* image filled with background pixels */ GC backgroundGC; /* GC for the background color */ GC foregroundGC; /* GC for the foreground color */ @@ -76,12 +73,11 @@ struct state { Tile **sortedTiles; /* array of tile pointers, sorted by zoom */ int tileCount; /* total number of tiles */ + time_t start_time; async_load_state *img_loader; + Pixmap pm; - Bool useShm; /* whether or not to use xshm */ -#ifdef HAVE_XSHM_EXTENSION XShmSegmentInfo shmInfo; -#endif }; @@ -102,46 +98,39 @@ struct state { */ /* grab the source image */ -static void grabImage_start (struct state *st, XWindowAttributes *xwa) +static void +grabImage_start (struct state *st, XWindowAttributes *xwa) { - XFillRectangle (st->dpy, st->window, st->backgroundGC, 0, 0, - st->windowWidth, st->windowHeight); - st->backgroundImage = - XGetImage (st->dpy, st->window, 0, 0, st->windowWidth, st->windowHeight, - ~0L, ZPixmap); - + /* 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, + xwa->width, xwa->height, xwa->depth); + + st->start_time = time ((time_t *) 0); st->img_loader = load_image_async_simple (0, xwa->screen, st->window, - st->window, 0, 0); + st->pm, 0, 0); } -static void grabImage_done (struct state *st) +static void +grabImage_done (struct state *st) { - XWindowAttributes xwa; - XGetWindowAttributes (st->dpy, st->window, &xwa); + XWindowAttributes xwa; + XGetWindowAttributes (st->dpy, st->window, &xwa); - st->sourceImage = XGetImage (st->dpy, st->window, 0, 0, st->windowWidth, st->windowHeight, + st->start_time = time ((time_t *) 0); + if (st->sourceImage) XDestroyImage (st->sourceImage); + st->sourceImage = XGetImage (st->dpy, st->pm, 0, 0, + st->windowWidth, st->windowHeight, ~0L, ZPixmap); -#ifdef HAVE_XSHM_EXTENSION - st->workImage = NULL; - if (st->useShm) - { - st->workImage = create_xshm_image (st->dpy, xwa.visual, xwa.depth, - ZPixmap, 0, &st->shmInfo, - st->windowWidth, st->windowHeight); - if (!st->workImage) - { - st->useShm = False; - fprintf (stderr, "create_xshm_image failed\n"); - } - } - - if (st->workImage == NULL) -#endif /* HAVE_XSHM_EXTENSION */ + if (st->workImage) destroy_xshm_image (st->dpy, st->workImage, + &st->shmInfo); - /* just use XSubImage to acquire the right visual, depth, etc; - * easier than the other alternatives */ - st->workImage = XSubImage (st->sourceImage, 0, 0, st->windowWidth, st->windowHeight); + st->workImage = create_xshm_image (st->dpy, xwa.visual, xwa.depth, + ZPixmap, &st->shmInfo, + st->windowWidth, st->windowHeight); } /* set up the system */ @@ -515,7 +504,8 @@ static void renderFrame (struct state *st) { int n; - memcpy (st->workImage->data, st->backgroundImage->data, + /* This assumes black is zero. */ + memset (st->workImage->data, 0, st->workImage->bytes_per_line * st->workImage->height); sortTiles (st); @@ -525,14 +515,8 @@ static void renderFrame (struct state *st) renderTile (st, st->sortedTiles[n]); } -#ifdef HAVE_XSHM_EXTENSION - if (st->useShm) - XShmPutImage (st->dpy, st->window, st->backgroundGC, st->workImage, 0, 0, 0, 0, - st->windowWidth, st->windowHeight, False); - else -#endif /* HAVE_XSHM_EXTENSION */ - XPutImage (st->dpy, st->window, st->backgroundGC, st->workImage, - 0, 0, 0, 0, st->windowWidth, st->windowHeight); + put_xshm_image (st->dpy, st->window, st->backgroundGC, st->workImage, 0, 0, 0, 0, + st->windowWidth, st->windowHeight, &st->shmInfo); } /* set up the model */ @@ -554,8 +538,8 @@ static void setupModel (struct state *st) st->tileSize = st->windowHeight / 2; } - st->columns = st->windowWidth / st->tileSize; - st->rows = st->windowHeight / st->tileSize; + st->columns = st->tileSize ? st->windowWidth / st->tileSize : 0; + st->rows = st->tileSize ? st->windowHeight / st->tileSize : 0; if ((st->maxColumns != 0) && (st->columns > st->maxColumns)) { @@ -572,6 +556,7 @@ static void setupModel (struct state *st) leftX = (st->windowWidth - (st->columns * st->tileSize) + st->tileSize) / 2; topY = (st->windowHeight - (st->rows * st->tileSize) + st->tileSize) / 2; + if (st->tileCount < 1) st->tileCount = 1; st->tiles = calloc (st->tileCount, sizeof (Tile)); st->sortedTiles = calloc (st->tileCount, sizeof (Tile *)); @@ -605,6 +590,13 @@ twang_draw (Display *dpy, Window window, void *closure) return st->delay; } + if (!st->img_loader && + st->start_time + st->duration < time ((time_t *) 0)) { + XWindowAttributes xgwa; + XGetWindowAttributes (st->dpy, st->window, &xgwa); + grabImage_start (st, &xgwa); + return st->delay; + } modelEvents (st); updateModel (st); @@ -622,6 +614,12 @@ twang_reshape (Display *dpy, Window window, void *closure, static Bool twang_event (Display *dpy, Window window, void *closure, XEvent *event) { + struct state *st = (struct state *) closure; + if (screenhack_event_helper (dpy, window, event)) + { + st->start_time = 0; + return True; + } return False; } @@ -629,6 +627,7 @@ static void twang_free (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; + if (st->pm) XFreePixmap (dpy, st->pm); free (st); } @@ -655,6 +654,9 @@ static void initParams (struct state *st) problems = 1; } + st->duration = get_integer_resource (st->dpy, "duration", "Seconds"); + if (st->duration < 1) st->duration = 1; + st->eventChance = get_float_resource (st->dpy, "eventChance", "Double"); if ((st->eventChance < 0.0) || (st->eventChance > 1.0)) { @@ -704,10 +706,6 @@ static void initParams (struct state *st) problems = 1; } -#ifdef HAVE_XSHM_EXTENSION - st->useShm = get_boolean_resource (st->dpy, "useSHM", "Boolean"); -#endif - if (problems) { exit (1); @@ -732,9 +730,11 @@ twang_init (Display *dpy, Window win) static const char *twang_defaults [] = { ".background: black", ".foreground: white", + ".lowrez: true", "*borderColor: blue", "*borderWidth: 3", "*delay: 10000", + "*duration: 120", "*eventChance: 0.01", "*friction: 0.05", "*maxColumns: 0", @@ -746,6 +746,10 @@ static const char *twang_defaults [] = { "*useSHM: True", #else "*useSHM: False", +#endif +#ifdef HAVE_MOBILE + "*ignoreRotation: True", + "*rotateImages: True", #endif 0 }; @@ -754,6 +758,7 @@ static XrmOptionDescRec twang_options [] = { { "-border-color", ".borderColor", XrmoptionSepArg, 0 }, { "-border-width", ".borderWidth", XrmoptionSepArg, 0 }, { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-duration", ".duration", XrmoptionSepArg, 0 }, { "-event-chance", ".eventChance", XrmoptionSepArg, 0 }, { "-friction", ".friction", XrmoptionSepArg, 0 }, { "-max-columns", ".maxColumns", XrmoptionSepArg, 0 },