X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fspotlight.c;h=2616b849a9662c0561607849bb78f8379fe85fcf;hp=8eb5d0c22d68ac521881f78d4fdf76392c112d45;hb=ffd8c0873576a9e3065696a624dce6b766b77062;hpb=a719ec12b8b2563112366a8ac3196816fd64d2c7 diff --git a/hacks/spotlight.c b/hacks/spotlight.c index 8eb5d0c2..2616b849 100644 --- a/hacks/spotlight.c +++ b/hacks/spotlight.c @@ -1,6 +1,6 @@ /* * spotlight - an xscreensaver module - * Copyright (c) 1999 Rick Schultz + * Copyright (c) 1999, 2001 Rick Schultz * * loosely based on the BackSpace module "StefView" by Darcy Brockbank */ @@ -33,14 +33,13 @@ static int sizex, sizey; /* screen size */ static int delay; /* in case it's too fast... */ -static GC gc; +static GC window_gc; #ifdef DEBUG static GC white_gc; #endif static GC buffer_gc; /* draw in buffer, then flush to screen to avoid flicker */ static int radius; /* radius of spotlight in pixels */ -static XGCValues gcv; static Pixmap pm; /* pixmap grabbed from screen */ static Pixmap clip_pm; /* pixmap for clipping (spotlight shape) */ @@ -48,10 +47,14 @@ static Pixmap buffer; /* pixmap for the buffer */ static GC clip_gc; /* GC for the clip pixmap */ -int x, y, s; /* x & y coords of buffer (upper left corner) */ +static int x, y, s; /* x & y coords of buffer (upper left corner) */ /* s is the width of the buffer */ -int oldx, oldy, max_x_speed, max_y_speed; +static int off = 0; /* random offset from currentTimeInMs(), so that + two concurrent copies of spotlight have different + behavior. */ + +static int oldx, oldy, max_x_speed, max_y_speed; /* used to keep the new buffer position over the old spotlight image to make sure the old image is completely erased */ @@ -75,6 +78,7 @@ currentTimeInMs(void) static void init_hack (Display *dpy, Window window) { + XGCValues gcv; XWindowAttributes xgwa; long gcflags; Colormap cmap; @@ -93,65 +97,65 @@ init_hack (Display *dpy, Window window) radius = get_integer_resource ("radius", "Integer"); if (radius < 0) radius = 125; + /* Don't let the spotlight be bigger than 1/4 of the window */ + if (radius > xgwa.width / 4) radius = xgwa.width / 4; + if (radius > xgwa.height / 4) radius = xgwa.height / 4; + /* do the dance */ gcv.function = GXcopy; gcv.subwindow_mode = IncludeInferiors; gcflags = GCForeground | GCFunction; gcv.foreground = bg; - gcv.background = fg; #ifdef NOPE if (use_subwindow_mode_p(xgwa.screen, window)) /* see grabscreen.c */ gcflags |= GCSubwindowMode; #endif - gc = XCreateGC (dpy, window, gcflags, &gcv); - + window_gc = XCreateGC(dpy, window, gcflags, &gcv); - /* grab screen to window */ - grab_screen_image (xgwa.screen, window); - - /* save screen to pixmap for copying later */ + /* grab screen to pixmap */ pm = XCreatePixmap(dpy, window, sizex, sizey, xgwa.depth); - XCopyArea(dpy, window, pm, gc, 0, 0, sizex, sizey, 0, 0); - + load_random_image (xgwa.screen, window, pm, NULL); + XClearWindow(dpy, window); + XFlush (dpy); /* create buffer to reduce flicker */ buffer = XCreatePixmap(dpy, window, sizex, sizey, xgwa.depth); - buffer_gc = XCreateGC (dpy, buffer, gcflags, &gcv); + buffer_gc = XCreateGC(dpy, buffer, gcflags, &gcv); + XFillRectangle(dpy, buffer, buffer_gc, 0, 0, sizex, sizey); /* blank out screen */ - XFillRectangle(dpy,window,gc,0,0,sizex,sizey); + XFillRectangle(dpy, window, window_gc, 0, 0, sizex, sizey); + XSetWindowBackground (dpy, window, bg); /* create clip mask (so it's a circle, not a square) */ clip_pm = XCreatePixmap(dpy, window, radius*4, radius*4, 1); - gcv.foreground=bg; - gcv.background=bg; + + gcv.foreground = 0L; clip_gc = XCreateGC(dpy, clip_pm, gcflags, &gcv); - XFillRectangle(dpy,clip_pm,clip_gc,0,0,radius*4, radius*4); - XSetForeground(dpy,clip_gc,fg); + XFillRectangle(dpy, clip_pm, clip_gc, 0, 0, radius*4, radius*4); + + XSetForeground(dpy, clip_gc, 1L); XFillArc(dpy, clip_pm, clip_gc, radius , radius, radius*2, radius*2, 0, 360*64); + /* set buffer's clip mask to the one we just made */ XSetClipMask(dpy, buffer_gc, clip_pm); + /* free everything */ XFreeGC(dpy, clip_gc); XFreePixmap(dpy, clip_pm); /* avoid remants */ max_x_speed = max_y_speed = radius; + + off = random(); #ifdef DEBUG /* create GC with white fg */ gcv.foreground = fg; - white_gc = XCreateGC (dpy, window, gcflags, &gcv); + white_gc = XCreateGC(dpy, window, gcflags, &gcv); #endif - - /* initialize x and y to avoid initial `jump' across screen */ - x = ((1 + sin(((float)currentTimeInMs()) / X_PERIOD * 2. * M_PI))/2.0) - * (sizex - s/2) -s/4 + MINX; - y = ((1 + sin(((float)currentTimeInMs()) / Y_PERIOD * 2. * M_PI))/2.0) - * (sizey - s/2) -s/4 + MINY; - } @@ -159,7 +163,7 @@ init_hack (Display *dpy, Window window) * perform one iteration */ static void -onestep (Display *dpy, Window window) +onestep (Display *dpy, Window window, Bool first_p) { long now; @@ -174,7 +178,7 @@ onestep (Display *dpy, Window window) s = radius *4 ; /* s = width of buffer */ - now = currentTimeInMs(); + now = currentTimeInMs() + off; /* find new x,y */ x = ((1 + sin(((float)now) / X_PERIOD * 2. * M_PI))/2.0) @@ -182,18 +186,21 @@ onestep (Display *dpy, Window window) y = ((1 + sin(((float)now) / Y_PERIOD * 2. * M_PI))/2.0) * (sizey - s/2) -s/4 + MINY; - /* limit change in x and y to buffer width */ - if ( x < (oldx - max_x_speed) ) x = oldx - max_x_speed; - if ( x > (oldx + max_x_speed) ) x = oldx + max_x_speed; - if ( y < (oldy - max_y_speed) ) y = oldy - max_y_speed; - if ( y > (oldy + max_y_speed) ) y = oldy + max_y_speed; + if (!first_p) + { + /* limit change in x and y to buffer width */ + if ( x < (oldx - max_x_speed) ) x = oldx - max_x_speed; + if ( x > (oldx + max_x_speed) ) x = oldx + max_x_speed; + if ( y < (oldy - max_y_speed) ) y = oldy - max_y_speed; + if ( y > (oldy + max_y_speed) ) y = oldy + max_y_speed; + } /* copy area of screen image (pm) to buffer Clip to a circle */ XSetClipOrigin(dpy, buffer_gc, x,y); XCopyArea(dpy, pm, buffer, buffer_gc, x, y, s, s, x, y); /* copy buffer to screen (window) */ - XCopyArea(dpy, buffer, window, gc, x , y, s, s, x, y); + XCopyArea(dpy, buffer, window, window_gc, x , y, s, s, x, y); #ifdef DEBUG /* draw a box around the buffer */ @@ -209,6 +216,8 @@ onestep (Display *dpy, Window window) char *progclass = "Spotlight"; char *defaults [] = { + ".background: black", + ".foreground: white", "*dontClearRoot: True", #ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */ @@ -229,9 +238,11 @@ XrmOptionDescRec options [] = { void screenhack (Display *dpy, Window window) { + Bool first_p = True; init_hack (dpy, window); while (1) { - onestep(dpy, window); + onestep(dpy, window, first_p); + first_p = False; XSync(dpy, False); if (delay) usleep (delay); screenhack_handle_events (dpy);