X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fslidescreen.c;h=e31bcf0dda9e60ba20d340c02f1c576e9ba83d5b;hb=8eb2873d7054e705c4e83f22d18c40946a9e2529;hp=a3792cd08f9ecfe214bbc600727217fbf287b5ba;hpb=f3e0240915ed9f9b3a61781f5c7002d587563fe0;p=xscreensaver diff --git a/hacks/slidescreen.c b/hacks/slidescreen.c index a3792cd0..e31bcf0d 100644 --- a/hacks/slidescreen.c +++ b/hacks/slidescreen.c @@ -1,5 +1,5 @@ -/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997 - * Jamie Zawinski +/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997, 1998, 2001 + * 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 @@ -20,7 +20,7 @@ static int xoff, yoff; static int grid_w, grid_h; static int delay, delay2; static GC gc; -int max_width, max_height; +static int max_width, max_height; static void init_slide (Display *dpy, Window window) @@ -28,13 +28,15 @@ init_slide (Display *dpy, Window window) int i; XGCValues gcv; XWindowAttributes xgwa; + long gcflags; int border; - unsigned long fg; + unsigned long fg, bg; Drawable d; Colormap cmap; Visual *visual; XGetWindowAttributes (dpy, window, &xgwa); + grab_screen_image (xgwa.screen, window); cmap = xgwa.colormap; visual = xgwa.visual; max_width = xgwa.width; @@ -45,29 +47,114 @@ init_slide (Display *dpy, Window window) 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, cmap); - - grab_screen_image (xgwa.screen, window); - - /* Total kludge -- if grab_screen_image() installed a new colormap, assume - that pixel 0 is the one we should use. This further assumes that the - pixel is black, which overrides the user's -background setting, alas. - */ - XGetWindowAttributes (dpy, window, &xgwa); - if (cmap != xgwa.colormap) fg = 0; + /* 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 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; + 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; + bg = all[i].pixel; + if (d == 0) + bg_ok = True; + } + } + + if (fg_ok && bg_ok) + break; + } + XFree(all); + } + } if (delay < 0) delay = 0; if (delay2 < 0) delay2 = 0; if (pix_inc < 1) pix_inc = 1; - if (grid_size < 1) grid_size = 1; + if (grid_size < 10) grid_size = 10; gcv.foreground = fg; gcv.function = GXcopy; gcv.subwindow_mode = IncludeInferiors; - gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode, - &gcv); + 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; @@ -84,10 +171,23 @@ init_slide (Display *dpy, Window window) if (border) { + 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) @@ -101,7 +201,7 @@ init_slide (Display *dpy, Window window) XFillRectangle (dpy, d, gc, 0, bitmap_h - yoff, bitmap_w, yoff); } - XSync (dpy, True); + XSync (dpy, False); if (delay2) usleep (delay2 * 2); for (i = 0; i < grid_size; i += pix_inc) { @@ -132,7 +232,7 @@ init_slide (Display *dpy, Window 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); } @@ -213,7 +313,7 @@ slide1 (Display *dpy, Window window) break; } - XSync (dpy, True); + XSync (dpy, False); if (delay) usleep (delay); } switch (dir) @@ -235,10 +335,11 @@ char *defaults [] = { "*visualID: Best", #endif - "*background: Black", + ".background: Black", + ".foreground: Gray", "*gridSize: 70", "*pixelIncrement: 10", - "*internalBorderWidth: 1", + "*internalBorderWidth: 4", "*delay: 50000", "*delay2: 1000000", 0 @@ -260,6 +361,7 @@ screenhack (Display *dpy, Window window) while (1) { slide1 (dpy, window); + screenhack_handle_events (dpy); if (delay2) usleep (delay2); } }