+static unsigned long
+ifs_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ int i;
+ int xmin = st->xmin, xmax = st->xmax, ymin = st->ymin, ymax = st->ymax;
+
+ /* erase whatever was drawn in the previous frame */
+ if (xmin <= xmax && ymin <= ymax) {
+ XSetForeground(st->dpy, st->gc, st->blackColor);
+ XFillRectangle(st->dpy, st->backbuffer, st->gc,
+ xmin, ymin,
+ xmax - xmin + 1, ymax - ymin + 1);
+ st->xmin = st->width + 1;
+ st->xmax = st->ymax = -1;
+ st->ymin = st->height + 1;
+ }
+
+ st->ccolour++;
+ st->ccolour %= st->ncolours;
+ XSetForeground(st->dpy, st->gc, st->colours[st->ccolour].pixel);
+
+ /* calculate and draw points for this frame */
+ memset(st->board, 0, st->widthb * st->height * sizeof(*st->board));
+ if (st->recurse)
+ recurse(st, st->width << 7, st->height << 7, st->length);
+ else
+ iterate(st, pow(st->lensnum, st->length));
+ if (st->npoints)
+ drawpoints(st);
+
+ /* if we just drew into a buffer, copy the changed area (including
+ * erased area) to screen */
+ if (st->backbuffer != st->window
+ && ((st->xmin <= st->xmax && st->ymin <= st->ymax)
+ || (xmin <= xmax && ymin <= ymax))) {
+ if (st->xmin < xmin) xmin = st->xmin;
+ if (st->xmax > xmax) xmax = st->xmax;
+ if (st->ymin < ymin) ymin = st->ymin;
+ if (st->ymax > ymax) ymax = st->ymax;
+ XCopyArea(st->dpy, st->backbuffer, st->window, st->gc,
+ xmin, ymin,
+ xmax - xmin + 1, ymax - ymin + 1,
+ xmin, ymin);
+ }
+
+ for(i = 0; i < st->lensnum; i++) {
+ mutate(st, &st->lenses[i]);
+ }
+
+ return st->delay;
+}
+