X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fslidescreen.c;h=78a30843fbb3485525402a6435811a02bbd0d427;hb=96a411663168b0ba5432b407a83be55f3df0c802;hp=52f0d975d4a7a35339f91c6e70f447c5a21cd899;hpb=65740e2a8dea3d6309ae6e8914a0fb79e993ada8;p=xscreensaver diff --git a/hacks/slidescreen.c b/hacks/slidescreen.c old mode 100755 new mode 100644 index 52f0d975..78a30843 --- a/hacks/slidescreen.c +++ b/hacks/slidescreen.c @@ -1,4 +1,5 @@ -/* xscreensaver, Copyright (c) 1992, 1993, 1994 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997, 1998, 2001, 2003 + * 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 @@ -19,38 +20,128 @@ static int xoff, yoff; static int grid_w, grid_h; static int delay, delay2; static GC gc; +static int max_width, max_height; static void -init_slide (dpy, window) - Display *dpy; - Window window; +init_slide (Display *dpy, Window window) { int i; XGCValues gcv; XWindowAttributes xgwa; + long gcflags; int border; - int root_p; - unsigned long fg; - Pixmap pixmap; + unsigned long fg, bg; Drawable d; Colormap cmap; Visual *visual; XGetWindowAttributes (dpy, window, &xgwa); + load_random_image (xgwa.screen, window, window, NULL); cmap = xgwa.colormap; visual = xgwa.visual; - - copy_default_colormap_contents (dpy, cmap, visual); + max_width = xgwa.width; + max_height = xgwa.height; delay = get_integer_resource ("delay", "Integer"); delay2 = get_integer_resource ("delay2", "Integer"); grid_size = get_integer_resource ("gridSize", "Integer"); pix_inc = get_integer_resource ("pixelIncrement", "Integer"); border = get_integer_resource ("internalBorderWidth", "InternalBorderWidth"); - fg = get_pixel_resource ("background", "Background", dpy, - /* Pixels always come out of default map. */ - XDefaultColormapOfScreen (xgwa.screen)); - root_p = get_boolean_resource ("root", "Boolean"); + + /* Don't let the grid be smaller than 3x3 */ + if (grid_size > xgwa.width / 3) + grid_size = xgwa.width / 3; + if (grid_size > xgwa.height / 3) + grid_size = xgwa.height / 3; + + { + XColor fgc, bgc; + char *fgs = get_string_resource("background", "Background"); + char *bgs = get_string_resource("foreground", "Foreground"); + Bool fg_ok, bg_ok; + if (!XParseColor (dpy, cmap, fgs, &fgc)) + XParseColor (dpy, cmap, "black", &bgc); + if (!XParseColor (dpy, cmap, bgs, &bgc)) + XParseColor (dpy, cmap, "gray", &fgc); + + fg_ok = XAllocColor (dpy, cmap, &fgc); + bg_ok = XAllocColor (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) + fg = fgc.pixel; + else + fg = 0; + + if (bg_ok) + bg = bgc.pixel; + else + bg = 1; + + if (!fg_ok || bg_ok) + { + unsigned long fgd = ~0; + unsigned long bgd = ~0; + int max = visual_cells (xgwa.screen, 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 (dpy, cmap, all, max); + for(i = 0; i < max; i++) + { + long rd, gd, bd; + unsigned long dd; + 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; + dd = (rd << 1) + (gd << 2) + bd; + if (dd < fgd) + { + fgd = dd; + fg = all[i].pixel; + if (dd == 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; + dd = (rd << 1) + (gd << 2) + bd; + if (dd < bgd) + { + bgd = dd; + bg = all[i].pixel; + if (dd == 0) + bg_ok = True; + } + } + + if (fg_ok && bg_ok) + break; + } + XFree(all); + } + } + if (delay < 0) delay = 0; if (delay2 < 0) delay2 = 0; @@ -60,10 +151,10 @@ init_slide (dpy, window) gcv.foreground = fg; gcv.function = GXcopy; gcv.subwindow_mode = IncludeInferiors; - gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode, - &gcv); - - pixmap = grab_screen_image (dpy, window, root_p); + gcflags = GCForeground |GCFunction; + if (use_subwindow_mode_p(xgwa.screen, window)) /* see grabscreen.c */ + gcflags |= GCSubwindowMode; + gc = XCreateGC (dpy, window, gcflags, &gcv); XGetWindowAttributes (dpy, window, &xgwa); bitmap_w = xgwa.width; @@ -76,15 +167,27 @@ init_slide (dpy, window) xoff = (bitmap_w - (grid_w * grid_size)) / 2; yoff = (bitmap_h - (grid_h * grid_size)) / 2; - d = (pixmap ? pixmap : window); + d = window; if (border) { - int i; + int half = border/2; + int half2 = (border & 1 ? half+1 : half); + XSetForeground(dpy, gc, bg); + for (i = 0; i < bitmap_w; i += grid_size) + { + int j; + for (j = 0; j < bitmap_h; j += grid_size) + XDrawRectangle (dpy, d, gc, + xoff+i+half2, yoff+j+half2, + grid_size-border-1, grid_size-border-1); + } + + XSetForeground(dpy, gc, fg); for (i = 0; i <= bitmap_w; i += grid_size) - XFillRectangle (dpy, d, gc, xoff+i-border/2, yoff, border, bitmap_h); + XFillRectangle (dpy, d, gc, xoff+i-half, yoff, border, bitmap_h); for (i = 0; i <= bitmap_h; i += grid_size) - XFillRectangle (dpy, d, gc, xoff, yoff+i-border/2, bitmap_w, border); + XFillRectangle (dpy, d, gc, xoff, yoff+i-half, bitmap_w, border); } if (xoff) @@ -98,8 +201,7 @@ init_slide (dpy, window) XFillRectangle (dpy, d, gc, 0, bitmap_h - yoff, bitmap_w, yoff); } - if (pixmap) XClearWindow (dpy, window); - XSync (dpy, True); + XSync (dpy, False); if (delay2) usleep (delay2 * 2); for (i = 0; i < grid_size; i += pix_inc) { @@ -130,7 +232,7 @@ init_slide (dpy, window) points[2].y = points[1].y; XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin); - XSync (dpy, True); + XSync (dpy, False); if (delay) usleep (delay); } @@ -141,9 +243,7 @@ init_slide (dpy, window) } static void -slide1 (dpy, window) - Display *dpy; - Window window; +slide1 (Display *dpy, Window window) { /* this code is a total kludge, but who cares, it works... */ int i, x, y, ix, iy, dx, dy, dir, w, h, size, inc; @@ -181,10 +281,22 @@ slide1 (dpy, window) inc = pix_inc; for (i = 0; i < grid_size; i += inc) { + int fx, fy, tox, toy; if (inc + i > grid_size) inc = grid_size - i; - XCopyArea (dpy, window, window, gc, x, y, grid_size * w, grid_size * h, - x - dx * inc, y - dy * inc); + tox = x - dx * inc; + toy = y - dy * inc; + + fx = (x < 0 ? 0 : x > max_width ? max_width : x); + fy = (y < 0 ? 0 : y > max_height ? max_height : y); + tox = (tox < 0 ? 0 : tox > max_width ? max_width : tox); + toy = (toy < 0 ? 0 : toy > max_height ? max_height : toy); + + XCopyArea (dpy, window, window, gc, + fx, fy, + grid_size * w, grid_size * h, + tox, toy); + x -= dx * inc; y -= dy * inc; switch (dir) @@ -201,7 +313,7 @@ slide1 (dpy, window) break; } - XSync (dpy, True); + XSync (dpy, False); if (delay) usleep (delay); } switch (dir) @@ -217,12 +329,17 @@ slide1 (dpy, window) char *progclass = "SlidePuzzle"; char *defaults [] = { - "SlidePuzzle.mappedWhenManaged:false", - "SlidePuzzle.dontClearWindow: true", - "*background: black", + "*dontClearRoot: True", + +#ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */ + "*visualID: Best", +#endif + + ".background: Black", + ".foreground: Gray", "*gridSize: 70", "*pixelIncrement: 10", - "*internalBorderWidth: 1", + "*internalBorderWidth: 4", "*delay: 50000", "*delay2: 1000000", 0 @@ -234,19 +351,17 @@ XrmOptionDescRec options [] = { { "-increment", ".pixelIncrement", XrmoptionSepArg, 0 }, { "-delay", ".delay", XrmoptionSepArg, 0 }, { "-delay2", ".delay2", XrmoptionSepArg, 0 }, + { 0, 0, 0, 0 } }; -int options_size = (sizeof (options) / sizeof (options[0])); - void -screenhack (dpy, window) - Display *dpy; - Window window; +screenhack (Display *dpy, Window window) { init_slide (dpy, window); while (1) { slide1 (dpy, window); + screenhack_handle_events (dpy); if (delay2) usleep (delay2); } }