+static unsigned long
+distort_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ int k;
+
+ 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 */
+ distort_finish_loading (st);
+ }
+ return st->delay;
+ }
+
+ if (!st->img_loader &&
+ 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->pm, 0, 0);
+ return st->delay;
+ }
+
+ for (k = 0; k < st->number; k++) {
+ st->effect(st,k);
+ st->draw(st,k);
+ }
+ return st->delay;
+}
+
+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;
+}
+
+static void
+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) 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);
+ free (st);
+}