X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fjigsaw.c;fp=hacks%2Fjigsaw.c;h=0000000000000000000000000000000000000000;hb=7b34ef992563d7bcbb64cc5597dc45fa24470b05;hp=5e2ddc58e007884adcf68bcc640659c9b6e32f4c;hpb=c1b9b55ad8d59dc05ef55e316aebf5863e7dfa56;p=xscreensaver diff --git a/hacks/jigsaw.c b/hacks/jigsaw.c deleted file mode 100644 index 5e2ddc58..00000000 --- a/hacks/jigsaw.c +++ /dev/null @@ -1,894 +0,0 @@ -/* xscreensaver, Copyright (c) 1997-2008 Jamie Zawinski - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - */ - -/* - TODO: - - = Rather than just flickering the pieces before swapping them, - show them lifting up and moving to their new positions. - The path on which they move shouldn't be a straight line; - try to avoid having them cross each other by moving them in - oppositely-positioned arcs. - - = Rotate the pieces as well, so that we can swap the corner - and edge pieces with each other. - - = Have it drop all pieces to the "floor" then pick them up to - reassemble the picture. - - = As a joke, maybe sometimes have one piece that doesn't fit? - Or lose a piece? - */ - -#include "screenhack.h" -#include "spline.h" - -#undef countof -#define countof(x) (sizeof((x))/sizeof((*x))) - -#define CENTER 0 -#define NORTH 1 -#define NORTHEAST 2 -#define EAST 3 -#define SOUTHEAST 4 -#define SOUTH 5 -#define SOUTHWEST 6 -#define WEST 7 -#define NORTHWEST 8 - -struct piece { - int width, height; - int x, y; - Pixmap pixmap; -}; - -struct set { - struct piece pieces[9]; -}; - -#define PIECE_A_HOLLOW 0 -#define PIECE_A_FILLED 1 -#define PIECE_B_HOLLOW 2 -#define PIECE_B_FILLED 3 - -struct swap_state { - int flashing; - int x1, y1, x2, y2; - Bool draw_p; -}; - -struct state { - Display *dpy; - Window window; - - struct set all_pieces[4]; - - int piece_width, piece_height; - int width, height; - int x_border, y_border; - Pixmap source; - GC gc; - int fg, bg; - int border_width; - XPoint *state; - int delay, delay2; - - int jigstate; - - struct swap_state swap; - int clearing; - - async_load_state *img_loader; -}; - - -/* Returns a spline describing one edge of a puzzle piece of the given length. - */ -static spline * -make_puzzle_curve (int pixels) -{ - double x0 = 0.0000, y0 = 0.0000; - double x1 = 0.3333, y1 = 0.1000; - double x2 = 0.4333, y2 = 0.0333; - double x3 = 0.4666, y3 = -0.0666; - double x4 = 0.3333, y4 = -0.1666; - double x5 = 0.3666, y5 = -0.2900; - double x6 = 0.5000, y6 = -0.3333; - - spline *s = make_spline(20); - s->n_controls = 0; - -# define PT(x,y) \ - s->control_x[s->n_controls] = pixels * (x); \ - s->control_y[s->n_controls] = pixels * (y); \ - s->n_controls++ - PT ( x0, y0); - PT ( x1, y1); - PT ( x2, y2); - PT ( x3, y3); - PT ( x4, y4); - PT ( x5, y5); - PT ( x6, y6); - PT (1-x5, y5); - PT (1-x4, y4); - PT (1-x3, y3); - PT (1-x2, y2); - PT (1-x1, y1); - PT (1-x0, y0); -# undef PT - - compute_spline (s); - return s; -} - - -/* Draws a puzzle piece. The top/right/bottom/left_type args - indicate the direction the tabs point: 1 for out, -1 for in, 0 for flat. - */ -static void -draw_puzzle_shape (Display *dpy, Drawable d, GC gc, - int x, int y, int size, int bw, - int top_type, int right_type, - int bottom_type, int left_type, - Bool fill_p) -{ - spline *s = make_puzzle_curve (size); - XPoint *pts = (XPoint *) malloc (s->n_points * 4 * sizeof(*pts)); - int i, o; - - /* The border is twice as wide for "flat" edges, otherwise it looks funny. */ - if (fill_p) - bw = 0; - else - bw /= 2; - - o = 0; - if (top_type == 0) { - pts[o].x = x; pts[o].y = y + bw; o++; - pts[o].x = x + size; pts[o].y = y + bw; o++; - } else { - for (i = 0; i < s->n_points; i++) { - pts[o].x = x + s->points[i].x; - pts[o].y = y + s->points[i].y * top_type; - o++; - } - } - - if (right_type == 0) { - pts[o-1].x -= bw; - pts[o].x = x + size - bw; pts[o].y = y + size; o++; - } else { - for (i = 1; i < s->n_points; i++) { - pts[o].x = x + size + s->points[i].y * (-right_type); - pts[o].y = y + s->points[i].x; - o++; - } - } - - if (bottom_type == 0) { - pts[o-1].y -= bw; - pts[o].x = x; pts[o].y = y + size - bw; o++; - } else { - for (i = 1; i < s->n_points; i++) { - pts[o].x = x + s->points[s->n_points-i-1].x; - pts[o].y = y + size + s->points[s->n_points-i-1].y * (-bottom_type); - o++; - } - } - - if (left_type == 0) { - pts[o-1].x += bw; - pts[o].x = x + bw; pts[o].y = y; o++; - } else { - for (i = 1; i < s->n_points; i++) { - pts[o].x = x + s->points[s->n_points-i-1].y * left_type; - pts[o].y = y + s->points[s->n_points-i-1].x; - o++; - } - } - - free_spline (s); - - if (fill_p) - XFillPolygon (dpy, d, gc, pts, o, Complex, CoordModeOrigin); - else - XDrawLines (dpy, d, gc, pts, o, CoordModeOrigin); - - free (pts); -} - - -/* Creates two pixmaps for a puzzle piece: - - The first is a solid bit-mask with 1 for each pixel inside the piece; - - The second is an outline of the piece, where all drawn pixels are - contained within the mask. - - The top/right/bottom/left_type args indicate the direction the - tabs point: 1 for out, -1 for in, 0 for flat. - - Size is how big the piece should be, from origin to origin. - - Returned x/y is the origin within the pixmaps. - */ -static void -make_puzzle_pixmap_pair (Display *dpy, Drawable d, int size, int bw, - int top_type, int right_type, - int bottom_type, int left_type, - int *x_ret, int *y_ret, - Pixmap *mask_ret, Pixmap *outline_ret) -{ - int w = (size ? size * 3 : 2); - int h = w; - int x = size; - int y = size; - Pixmap p0 = XCreatePixmap (dpy, d, w, h, 1); - Pixmap p1 = XCreatePixmap (dpy, d, w, h, 1); - XGCValues gcv; - GC gc; - gcv.foreground = 0; - gcv.background = 0; - gc = XCreateGC (dpy, p0, GCForeground|GCBackground, &gcv); - XFillRectangle (dpy, p0, gc, 0, 0, w, h); - XFillRectangle (dpy, p1, gc, 0, 0, w, h); - XSetForeground (dpy, gc, 0); - -# ifdef HAVE_COCOA - jwxyz_XSetAlphaAllowed (dpy, gc, False); -# endif - - /* To ensure that each pixel is drawn only once, we render the piece - such that it "owns" the left and top edges, but not the right and - bottom edges. - - - - + "#" is this piece. - - # + It overlaps "-" and is overlapped by "+". - - + + - - To accomplish this, we clear to black, draw "#" in white, - then draw "+" in black. - */ - - /* Center square */ - XSetForeground (dpy, gc, 1); - draw_puzzle_shape (dpy, p0, gc, x, y, size, bw, - top_type, right_type, bottom_type, left_type, - True); - - /* Top right square */ - XSetForeground (dpy, gc, 0); - draw_puzzle_shape (dpy, p0, gc, x + size, y - size, size, bw, - 0, 0, -top_type, -left_type, - True); - - /* Center right square */ - draw_puzzle_shape (dpy, p0, gc, x + size, y, size, bw, - 0, 0, 0, -right_type, - True); - - /* Bottom center square */ - draw_puzzle_shape (dpy, p0, gc, x, y + size, size, bw, - -bottom_type, 0, 0, 0, - True); - - /* And Charles Nelson Reilly in the bottom right square */ - draw_puzzle_shape (dpy, p0, gc, x + size, y + size, size, bw, - -bottom_type, -right_type, 0, 0, - True); - - /* Done with p0 (the mask). - To make p1 (the outline) draw an outlined piece through the mask. - */ - if (bw < 0) - { - bw = size / 30; - if (bw < 1) bw = 1; - } - - if (bw > 0) - { - XSetForeground (dpy, gc, 1); - XSetClipMask (dpy, gc, p0); - XSetLineAttributes (dpy, gc, bw, LineSolid, CapButt, JoinRound); - draw_puzzle_shape (dpy, p1, gc, x, y, size, bw, - top_type, right_type, bottom_type, left_type, - False); - } - - XFreeGC (dpy, gc); - *x_ret = x; - *y_ret = x; - *mask_ret = p0; - *outline_ret = p1; -} - - -static void -make_puzzle_pixmaps (struct state *st) -{ - int i, j; - - int edges[9][4] = { - { -1, 1, -1, 1 }, /* CENTER */ - { 0, 1, -1, 1 }, /* NORTH */ - { 0, 0, -1, 1 }, /* NORTHEAST */ - { -1, 0, -1, 1 }, /* EAST */ - { -1, 0, 0, 1 }, /* SOUTHEAST */ - { -1, 1, 0, 1 }, /* SOUTH */ - { -1, 1, 0, 0 }, /* SOUTHWEST */ - { -1, 1, -1, 0 }, /* WEST */ - { 0, 1, -1, 0 }, /* NORTHWEST */ - }; - - /* sometimes swap direction of horizontal edges */ - if (random() & 1) - for (j = 0; j < countof(edges); j++) { - edges[j][0] = -edges[j][0]; - edges[j][2] = -edges[j][2]; - } - - /* sometimes swap direction of vertical edges */ - if (random() & 1) - for (j = 0; j < countof(edges); j++) { - edges[j][1] = -edges[j][1]; - edges[j][3] = -edges[j][3]; - } - - for (j = 0; j < 9; j++) { - for (i = 0; i < 2; i++) { - int x, y; - int top, right, bottom, left; - Pixmap mask, outline; - top = edges[j][0]; - right = edges[j][1]; - bottom = edges[j][2]; - left = edges[j][3]; - if (i) { - top = -top; - right = -right; - bottom = -bottom; - left = -left; - } - make_puzzle_pixmap_pair (st->dpy, st->window, st->piece_width, - st->border_width, - top, right, bottom, left, - &x, &y, &mask, &outline); - - st->all_pieces[i*2].pieces[j].x = x; - st->all_pieces[i*2].pieces[j].y = y; - st->all_pieces[i*2].pieces[j].pixmap = outline; - - st->all_pieces[i*2+1].pieces[j].x = x; - st->all_pieces[i*2+1].pieces[j].y = y; - st->all_pieces[i*2+1].pieces[j].pixmap = mask; - } - } -} - -static void -free_puzzle_pixmaps (struct state *st) -{ - int i, j; - for (i = 0; i < countof(st->all_pieces); i++) - for (j = 0; j < countof (st->all_pieces[i].pieces); j++) - if (st->all_pieces[i].pieces[j].pixmap) { - XFreePixmap (st->dpy, st->all_pieces[i].pieces[j].pixmap); - st->all_pieces[i].pieces[j].pixmap = 0; - } -} - - -static void -jigsaw_init_1 (struct state *st) -{ - XWindowAttributes xgwa; - int x, y; - XGCValues gcv; - Colormap cmap; - - XGetWindowAttributes (st->dpy, st->window, &xgwa); - - st->piece_width = 40 + (random() % 100); - if (xgwa.width / st->piece_width < 4) - st->piece_width = xgwa.width / 4; - st->piece_height = st->piece_width; - - free_puzzle_pixmaps (st); - make_puzzle_pixmaps (st); - - cmap = xgwa.colormap; - st->width = (st->piece_width ? xgwa.width / st->piece_width : 0); - st->height = (st->piece_height ? xgwa.height / st->piece_height : 0); - st->x_border = (xgwa.width - (st->width * st->piece_width)) / 2; - st->y_border = (xgwa.height - (st->height * st->piece_width)) / 2; - - if (st->width < 4) st->width = 4, st->x_border = 0; - if (st->height < 4) st->height = 4, st->y_border = 0; - - if (st->state) free (st->state); - st->state = (XPoint *) malloc (st->width * st->height * sizeof(*st->state)); - - if (!st->gc) - { - XColor fgc, bgc; - char *fgs = get_string_resource(st->dpy, "foreground", "Foreground"); - char *bgs = get_string_resource(st->dpy, "background", "Background"); - Bool fg_ok, bg_ok; - - st->gc = XCreateGC (st->dpy, st->window, 0, &gcv); - -# ifdef HAVE_COCOA - jwxyz_XSetAlphaAllowed (st->dpy, st->gc, False); -# endif - - if (!XParseColor (st->dpy, cmap, fgs, &fgc)) - XParseColor (st->dpy, cmap, "gray", &fgc); - if (!XParseColor (st->dpy, cmap, bgs, &bgc)) - XParseColor (st->dpy, cmap, "black", &bgc); - - free (fgs); - free (bgs); - fgs = bgs = 0; - - fg_ok = XAllocColor (st->dpy, cmap, &fgc); - bg_ok = XAllocColor (st->dpy, cmap, &bgc); - - /* If we weren't able to allocate the two colors we want from the - colormap (which is likely if the screen has been grabbed on an - 8-bit SGI visual -- don't ask) then just go through the map - and find the closest color to the ones we wanted, and use those - pixels without actually allocating them. - */ - if (fg_ok) - st->fg = fgc.pixel; - else - st->fg = 0; - - if (bg_ok) - st->bg = bgc.pixel; - else - st->bg = 1; - -#ifndef HAVE_COCOA - if (!fg_ok || bg_ok) - { - int i; - unsigned long fgd = ~0; - unsigned long bgd = ~0; - int max = visual_cells (xgwa.screen, xgwa.visual); - XColor *all = (XColor *) calloc(sizeof (*all), max); - for (i = 0; i < max; i++) - { - all[i].flags = DoRed|DoGreen|DoBlue; - all[i].pixel = i; - } - XQueryColors (st->dpy, cmap, all, max); - for(i = 0; i < max; i++) - { - long rd, gd, bd; - unsigned long d; - if (!fg_ok) - { - rd = (all[i].red >> 8) - (fgc.red >> 8); - gd = (all[i].green >> 8) - (fgc.green >> 8); - bd = (all[i].blue >> 8) - (fgc.blue >> 8); - if (rd < 0) rd = -rd; - if (gd < 0) gd = -gd; - if (bd < 0) bd = -bd; - d = (rd << 1) + (gd << 2) + bd; - if (d < fgd) - { - fgd = d; - st->fg = all[i].pixel; - if (d == 0) - fg_ok = True; - } - } - - if (!bg_ok) - { - rd = (all[i].red >> 8) - (bgc.red >> 8); - gd = (all[i].green >> 8) - (bgc.green >> 8); - bd = (all[i].blue >> 8) - (bgc.blue >> 8); - if (rd < 0) rd = -rd; - if (gd < 0) gd = -gd; - if (bd < 0) bd = -bd; - d = (rd << 1) + (gd << 2) + bd; - if (d < bgd) - { - bgd = d; - st->bg = all[i].pixel; - if (d == 0) - bg_ok = True; - } - } - - if (fg_ok && bg_ok) - break; - } - XFree(all); - } -#endif /* HAVE_COCOA */ - } - - /* Reset the window's background color... */ - XSetWindowBackground (st->dpy, st->window, st->bg); - XClearWindow(st->dpy, st->window); - - for (y = 0; y < st->height; y++) - for (x = 0; x < st->width; x++) - { - st->state[y * st->width + x].x = x; - st->state[y * st->width + x].y = y; - } - - if (st->source) - XFreePixmap (st->dpy, st->source); - st->source = XCreatePixmap (st->dpy, st->window, xgwa.width, xgwa.height, - xgwa.depth); - - st->img_loader = load_image_async_simple (0, xgwa.screen, st->window, - st->source, 0, 0); -} - - -static void -get_piece (struct state *st, - int x, int y, struct piece **hollow, struct piece **filled) -{ - int p; - Bool which = (x & 1) == (y & 1); - - if (x == 0 && y == 0) p = NORTHWEST; - else if (x == st->width-1 && y == 0) p = NORTHEAST; - else if (x == st->width-1 && y == st->height-1) p = SOUTHEAST; - else if (x == 0 && y == st->height-1) p = SOUTHWEST; - else if (y == 0) p = NORTH; - else if (x == st->width-1) p = EAST; - else if (y == st->height-1) p = SOUTH; - else if (x == 0) p = WEST; - else p = CENTER; - - if (hollow) - *hollow = (which - ? &st->all_pieces[PIECE_A_HOLLOW].pieces[p] - : &st->all_pieces[PIECE_B_HOLLOW].pieces[p]); - if (filled) - *filled = (which - ? &st->all_pieces[PIECE_A_FILLED].pieces[p] - : &st->all_pieces[PIECE_B_FILLED].pieces[p]); -} - - -static void -draw_piece (struct state *st, int x, int y, int clear_p) -{ - struct piece *hollow, *filled; - int from_x = st->state[y * st->width + x].x; - int from_y = st->state[y * st->width + x].y; - - get_piece(st, x, y, &hollow, &filled); - - XSetClipMask(st->dpy, st->gc, filled->pixmap); - XSetClipOrigin(st->dpy, st->gc, - st->x_border + (x * st->piece_width) - filled->x - 1, - st->y_border + (y * st->piece_width) - filled->y - 1); - - if (clear_p) - { - XSetForeground(st->dpy, st->gc, st->bg); - XFillRectangle(st->dpy, st->window, st->gc, - st->x_border + (x * st->piece_width) -st->piece_width/2, - st->y_border + (y * st->piece_height) -st->piece_height/2, - st->piece_width*2, st->piece_height*2); - } - else - XCopyArea(st->dpy, st->source, st->window, st->gc, - st->x_border + (from_x * st->piece_width) - st->piece_width/2, - st->y_border + (from_y * st->piece_height) - st->piece_height/2, - st->piece_width*2, st->piece_height*2, - st->x_border + (x * st->piece_width) - st->piece_width/2, - st->y_border + (y * st->piece_height) - st->piece_height/2); - - if (clear_p > 1) - return; - - XSetForeground(st->dpy, st->gc, st->fg); - XSetClipMask(st->dpy, st->gc, hollow->pixmap); - XSetClipOrigin(st->dpy, st->gc, - st->x_border + (x * st->piece_width) - hollow->x - 1, - st->y_border + (y * st->piece_width) - hollow->y - 1); - XFillRectangle(st->dpy, st->window, st->gc, - st->x_border + (x * st->piece_width) - st->piece_width/2, - st->y_border + (y * st->piece_height) - st->piece_height/2, - st->piece_width*2, st->piece_height*2); -} - - -static int -animate_swap (struct state *st, struct swap_state *sw) -{ - XPoint swap; - - if (sw->flashing > 1) - { - draw_piece(st, sw->x1, sw->y1, sw->flashing & 1); - draw_piece(st, sw->x2, sw->y2, sw->flashing & 1); - sw->flashing--; - return st->delay; - } - - swap = st->state[sw->y1 * st->width + sw->x1]; - st->state[sw->y1 * st->width + sw->x1] = - st->state[sw->y2 * st->width + sw->x2]; - st->state[sw->y2 * st->width + sw->x2] = swap; - - if (sw->draw_p) - { - draw_piece(st, sw->x1, sw->y1, 0); - draw_piece(st, sw->x2, sw->y2, 0); - sw->flashing = 0; - } - - return 0; -} - - -static int -swap_pieces (struct state *st, - int src_x, int src_y, int dst_x, int dst_y, - Bool draw_p) -{ - struct swap_state *sw = &st->swap; - - sw->x1 = src_x; - sw->y1 = src_y; - sw->x2 = dst_x; - sw->y2 = dst_y; - sw->draw_p = draw_p; - - /* if animating, plan to flash the pieces on and off a few times */ - sw->flashing = sw->draw_p ? 7 : 0; - - return animate_swap(st, sw); -} - - -static Bool -done (struct state *st) -{ - int x, y; - for (y = 0; y < st->height; y++) - for (x = 0; x < st->width; x++) - { - int x2 = st->state[y * st->width + x].x; - int y2 = st->state[y * st->width + x].y; - if (x != x2 || y != y2) - return False; - } - return True; -} - - -static int -shuffle (struct state *st, Bool draw_p) -{ - struct piece *p1, *p2; - int src_x, src_y, dst_x = -1, dst_y = -1; - - AGAIN: - p1 = p2 = 0; - src_x = random() % st->width; - src_y = random() % st->height; - - get_piece(st, src_x, src_y, &p1, 0); - - /* Pick random coordinates until we find one that has the same kind of - piece as the first one we picked. Note that it's possible for there - to be only one piece of a particular shape on the board (this always - happens with the four corner pieces.) - */ - while (p1 != p2) - { - dst_x = random() % st->width; - dst_y = random() % st->height; - get_piece(st, dst_x, dst_y, &p2, 0); - } - - if (src_x == dst_x && src_y == dst_y) - goto AGAIN; - - return swap_pieces(st, src_x, src_y, dst_x, dst_y, draw_p); -} - - -static void -shuffle_all (struct state *st) -{ - int j; - for (j = 0; j < 5; j++) { - /* swap each piece with another 5x */ - int i = (st->width * st->height * 5); - while (--i > 0) - shuffle (st, False); - - /* and do that whole process up to 5x if we ended up with a solved - board (this often happens with 4x4 boards.) */ - if (!done(st)) - break; - } -} - - -static int -unshuffle (struct state *st) -{ - int i; - for (i = 0; i < st->width * st->height * 4; i++) - { - int x = random() % st->width; - int y = random() % st->height; - int x2 = st->state[y * st->width + x].x; - int y2 = st->state[y * st->width + x].y; - if (x != x2 || y != y2) - { - return swap_pieces(st, x, y, x2, y2, True); - } - } - return 0; -} - - -static int -animate_clear (struct state *st) -{ - while (st->clearing > 0) - { - int x = random() % st->width; - int y = random() % st->height; - XPoint *p = &st->state[y * st->width + x]; - if (p->x == -1) - continue; - draw_piece(st, p->x, p->y, 2); - p->x = p->y = -1; - st->clearing--; - return st->delay; - } - return 0; -} - - -static int -clear_all (struct state *st) -{ - st->clearing = st->width * st->height; - return animate_clear(st); -} - - -static void * -jigsaw_init (Display *dpy, Window window) -{ - struct state *st = (struct state *) calloc (1, sizeof(*st)); - st->dpy = dpy; - st->window = window; - st->delay = get_integer_resource (st->dpy, "delay", "Integer"); - st->delay2 = get_integer_resource (st->dpy, "delay2", "Integer") * 1000000; - st->border_width = get_integer_resource (st->dpy, "pieceBorderWidth", - "Integer"); - if (st->delay == 0) st->delay = 1; /* kludge */ - return st; -} - - -static unsigned long -jigsaw_draw (Display *dpy, Window window, void *closure) -{ - struct state *st = (struct state *) closure; - int x, y; - int delay = 0; - - 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 */ - shuffle_all (st); - for (y = 0; y < st->height; y++) - for (x = 0; x < st->width; x++) - draw_piece(st, x, y, 0); - } - return st->delay; - } - - if (st->swap.flashing) - delay = animate_swap (st, &st->swap); - else if (st->clearing) - delay = animate_clear (st); - - if (!delay) { - if (st->jigstate == 0) - { - jigsaw_init_1 (st); - st->jigstate = 1; - } - else if (st->jigstate == 1) - { - if (done(st)) - { - st->jigstate = 2; - delay = st->delay2; - } - else - { - delay = unshuffle(st); - } - } - else if (st->jigstate == 2) - { - st->jigstate = 0; - delay = clear_all(st); - } - else - abort(); - } - - if (delay == 1) delay = 0; /* kludge */ - return (delay ? delay : st->delay * 10); -} - -static void -jigsaw_reshape (Display *dpy, Window window, void *closure, - unsigned int w, unsigned int h) -{ - /* window size is checked each time a new puzzle begins */ -} - -static Bool -jigsaw_event (Display *dpy, Window window, void *closure, XEvent *event) -{ - return False; -} - -static void -jigsaw_free (Display *dpy, Window window, void *closure) -{ - struct state *st = (struct state *) closure; - free_puzzle_pixmaps (st); - if (st->state) free (st->state); - if (st->gc) XFreeGC (dpy, st->gc); - if (st->source) XFreePixmap (dpy, st->source); - free (st); -} - - - -static const char *jigsaw_defaults [] = { - ".background: Black", - ".foreground: #AAAAAA", - "*fpsSolid: true", - "*delay: 70000", - "*delay2: 5", - "*pieceBorderWidth: -1", -#ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */ - "*visualID: Best", -#endif - 0 -}; - -static XrmOptionDescRec jigsaw_options [] = { - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-delay2", ".delay2", XrmoptionSepArg, 0 }, - { "-bw", ".pieceBorderWidth", XrmoptionSepArg, 0 }, - { "-border-width", ".pieceBorderWidth", XrmoptionSepArg, 0 }, - { 0, 0, 0, 0 } -}; - - -XSCREENSAVER_MODULE ("Jigsaw", jigsaw)