#include <math.h>
#include "screenhack.h"
-
-#ifdef HAVE_XSHM_EXTENSION
#include "xshm.h"
-#endif
#define FLOAT double
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 */
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 */
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
};
*/
/* 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 */
{
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);
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 */
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))
{
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 *));
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);
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;
}
twang_free (Display *dpy, Window window, void *closure)
{
struct state *st = (struct state *) closure;
+ if (st->pm) XFreePixmap (dpy, st->pm);
free (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))
{
problems = 1;
}
-#ifdef HAVE_XSHM_EXTENSION
- st->useShm = get_boolean_resource (st->dpy, "useSHM", "Boolean");
-#endif
-
if (problems)
{
exit (1);
"*borderColor: blue",
"*borderWidth: 3",
"*delay: 10000",
+ "*duration: 120",
"*eventChance: 0.01",
"*friction: 0.05",
"*maxColumns: 0",
"*useSHM: True",
#else
"*useSHM: False",
+#endif
+#ifdef HAVE_MOBILE
+ "*ignoreRotation: True",
+ "*rotateImages: True",
#endif
0
};
{ "-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 },