static unsigned long zoom_draw (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; unsigned x, y, i, j; long now; 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 */ XClearWindow (st->dpy, st->window); st->start_time = time ((time_t) 0); if (!st->lenses) { st->orig_map = XGetImage(st->dpy, st->pm, 0, 0, st->sizex, st->sizey, ~0L, ZPixmap); /* XFreePixmap(st->dpy, st->pm); st->pm = 0;*/ } } 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->screen, st->window, st->pm, 0, 0); return st->delay; } #define nrnd(x) (random() % (x)) now = currentTimeInMs(st); now += st->sinusoid_offset; /* don't run multiple screens in lock-step */ /* find new x,y */ st->tlx = ((1. + sin(((double)now) / X_PERIOD * 2. * M_PI))/2.0) * (st->sizex - st->s/2) /* -s/4 */ + MINX; st->tly = ((1. + sin(((double)now) / Y_PERIOD * 2. * M_PI))/2.0) * (st->sizey - st->s/2) /* -s/4 */ + MINY; if (st->lenses) { for (x = i = 0; x < st->sizex; x += (st->pixwidth + st->pixspacex), ++i) for (y = j = 0; y < st->sizey; y += (st->pixheight + st->pixspacey), ++j) { XCopyArea(st->dpy, st->pm /* src */, st->window /* dest */, st->window_gc, st->tlx + i * st->lensoffsetx /* src_x */, st->tly + j * st->lensoffsety /* src_y */, st->pixwidth, st->pixheight, x /* dest_x */, y /* dest_y */); } } else { for (x = i = 0; x < st->sizex; x += (st->pixwidth + st->pixspacex), ++i) for (y = j = 0; y < st->sizey; y += (st->pixheight + st->pixspacey), ++j) { XSetForeground(st->dpy, st->window_gc, XGetPixel(st->orig_map, st->tlx+i, st->tly+j)); XFillRectangle(st->dpy, st->window, st->window_gc, i * (st->pixwidth + st->pixspacex), j * (st->pixheight + st->pixspacey), st->pixwidth, st->pixheight); } } return st->delay; }
/* * perform one iteration */ static void onestep (struct state *st, Bool first_p) { long now; if (st->img_loader) /* still loading */ { st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0); return; } #define nrnd(x) (random() % (x)) st->oldx = st->x; st->oldy = st->y; st->s = st->radius *4 ; /* s = width of buffer */ now = currentTimeInMs(st) + st->off; /* find new x,y */ st->x = ((1 + sin(((double)now) / X_PERIOD * 2. * M_PI))/2.0) * (st->sizex - st->s/2) -st->s/4 + MINX; st->y = ((1 + sin(((double)now) / Y_PERIOD * 2. * M_PI))/2.0) * (st->sizey - st->s/2) -st->s/4 + MINY; if (!st->first_p) { /* limit change in x and y to buffer width */ if ( st->x < (st->oldx - st->max_x_speed) ) st->x = st->oldx - st->max_x_speed; if ( st->x > (st->oldx + st->max_x_speed) ) st->x = st->oldx + st->max_x_speed; if ( st->y < (st->oldy - st->max_y_speed) ) st->y = st->oldy - st->max_y_speed; if ( st->y > (st->oldy + st->max_y_speed) ) st->y = st->oldy + st->max_y_speed; } if (! st->buffer) { XClearWindow (st->dpy, st->window); XSetClipOrigin(st->dpy, st->buffer_gc, st->x,st->y); XCopyArea(st->dpy, st->pm, st->window, st->buffer_gc, st->x, st->y, st->s, st->s, st->x, st->y); } else { /* clear buffer */ XFillRectangle(st->dpy, st->buffer, st->buffer_gc, st->x, st->y, st->s, st->s); /* copy area of screen image (pm) to buffer Clip to a circle */ XSetClipOrigin(st->dpy, st->buffer_gc, st->x,st->y); XCopyArea(st->dpy, st->pm, st->buffer, st->buffer_gc, st->x, st->y, st->s, st->s, st->x, st->y); /* copy buffer to screen (window) */ XCopyArea(st->dpy, st->buffer, st->window, st->window_gc, st->x , st->y, st->s, st->s, st->x, st->y); } #ifdef DEBUG /* draw a box around the buffer */ XDrawRectangle(st->dpy, st->window, st->white_gc, st->x , st->y, st->s, st->s); #endif }