X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fspotlight.c;h=73858991a749dbe77600370d4c088f185a0a8d8e;hb=78add6e627ee5f10e1fa6f3852602ea5066eee5a;hp=fffa6a83bcbaa4f836328676409a6ef38036abba;hpb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;p=xscreensaver diff --git a/hacks/spotlight.c b/hacks/spotlight.c index fffa6a83..73858991 100644 --- a/hacks/spotlight.c +++ b/hacks/spotlight.c @@ -1,6 +1,6 @@ /* * spotlight - an xscreensaver module - * Copyright (c) 1999, 2001 Rick Schultz + * Copyright (c) 1999, 2001 Rick Schultz * * loosely based on the BackSpace module "StefView" by Darcy Brockbank */ @@ -22,19 +22,22 @@ /* #define DEBUG */ #include +#include #include "screenhack.h" -#define MINX 0.0 -#define MINY 0.0 #define X_PERIOD 15000.0 #define Y_PERIOD 12000.0 struct state { Display *dpy; Window window; + Screen *screen; int sizex, sizey; /* screen size */ - int delay; /* in case it's too fast... */ + int delay; + int duration; + time_t start_time; + int first_time; GC window_gc; #ifdef DEBUG GC white_gc; @@ -60,6 +63,7 @@ struct state { Bool first_p; async_load_state *img_loader; + XRectangle geom; }; @@ -69,13 +73,15 @@ static long currentTimeInMs(struct state *st) { struct timeval curTime; + unsigned long ret_unsigned; #ifdef GETTIMEOFDAY_TWO_ARGS struct timezone tz = {0,0}; gettimeofday(&curTime, &tz); #else gettimeofday(&curTime); #endif - return curTime.tv_sec*1000 + curTime.tv_usec/1000.0; + ret_unsigned = curTime.tv_sec *1000U + curTime.tv_usec / 1000; + return (ret_unsigned <= LONG_MAX) ? ret_unsigned : -1 - (long)(ULONG_MAX - ret_unsigned); } @@ -87,7 +93,7 @@ spotlight_init (Display *dpy, Window window) XWindowAttributes xgwa; long gcflags; Colormap cmap; - unsigned long fg, bg; + unsigned long bg; GC clip_gc; Pixmap clip_pm; @@ -96,18 +102,22 @@ spotlight_init (Display *dpy, Window window) st->first_p = True; XGetWindowAttributes (st->dpy, st->window, &xgwa); + st->screen = xgwa.screen; st->sizex = xgwa.width; st->sizey = xgwa.height; cmap = xgwa.colormap; - fg = get_pixel_resource (st->dpy, cmap, "foreground", "Foreground"); bg = get_pixel_resource (st->dpy, cmap, "background", "Background"); /* read parameters, keep em sane */ st->delay = get_integer_resource (st->dpy, "delay", "Integer"); if (st->delay < 1) st->delay = 1; + st->duration = get_integer_resource (st->dpy, "duration", "Seconds"); + if (st->duration < 1) st->duration = 1; st->radius = get_integer_resource (st->dpy, "radius", "Integer"); if (st->radius < 0) st->radius = 125; + if (xgwa.width > 2560) st->radius *= 2; /* Retina displays */ + /* Don't let the spotlight be bigger than the window */ while (st->radius > xgwa.width * 0.45) st->radius /= 2; @@ -129,12 +139,13 @@ spotlight_init (Display *dpy, Window window) #endif st->window_gc = XCreateGC(st->dpy, st->window, gcflags, &gcv); - /* grab screen to pixmap */ st->pm = XCreatePixmap(st->dpy, st->window, st->sizex, st->sizey, xgwa.depth); XClearWindow(st->dpy, st->window); + st->first_time = 1; + /* create buffer to reduce flicker */ -#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ +#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */ st->buffer = 0; #else st->buffer = XCreatePixmap(st->dpy, st->window, st->sizex, st->sizey, xgwa.depth); @@ -144,14 +155,11 @@ spotlight_init (Display *dpy, Window window) if (st->buffer) XFillRectangle(st->dpy, st->buffer, st->buffer_gc, 0, 0, st->sizex, st->sizey); - /* blank out screen */ - XFillRectangle(st->dpy, st->window, st->window_gc, 0, 0, st->sizex, st->sizey); - XSetWindowBackground (st->dpy, st->window, bg); - /* create clip mask (so it's a circle, not a square) */ clip_pm = XCreatePixmap(st->dpy, st->window, st->radius*4, st->radius*4, 1); st->img_loader = load_image_async_simple (0, xgwa.screen, st->window, st->pm, - 0, 0); + 0, &st->geom); + st->start_time = time ((time_t *) 0); gcv.foreground = 0L; clip_gc = XCreateGC(st->dpy, clip_pm, gcflags, &gcv); @@ -173,11 +181,9 @@ spotlight_init (Display *dpy, Window window) st->off = random(); -#ifdef DEBUG - /* create GC with white fg */ - gcv.foreground = fg; - st->white_gc = XCreateGC(st->dpy, st->window, gcflags, &gcv); -#endif + /* blank out screen */ + XFillRectangle(st->dpy, st->window, st->window_gc, 0, 0, st->sizex, st->sizey); + return st; } @@ -189,13 +195,25 @@ static void onestep (struct state *st, Bool first_p) { long now; + unsigned long now_unsigned; if (st->img_loader) /* still loading */ { - st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0); + st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, + &st->geom); + if (! st->img_loader) { /* just finished */ + st->start_time = time ((time_t *) 0); + } return; } + 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, &st->geom); + return; + } + #define nrnd(x) (random() % (x)) st->oldx = st->x; @@ -203,13 +221,16 @@ onestep (struct state *st, Bool first_p) st->s = st->radius *4 ; /* s = width of buffer */ - now = currentTimeInMs(st) + st->off; + now_unsigned = (unsigned long) currentTimeInMs(st) + st->off; + now = (now_unsigned <= LONG_MAX) ? now_unsigned : -1 - (long)(ULONG_MAX - now_unsigned); /* 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; + st->x = st->geom.x + + ((1 + sin(((double)now) / X_PERIOD * 2. * M_PI))/2.0) + * (st->geom.width - st->s/2) -st->s/4; + st->y = st->geom.y + + ((1 + sin(((double)now) / Y_PERIOD * 2. * M_PI))/2.0) + * (st->geom.height - st->s/2) -st->s/4; if (!st->first_p) { @@ -236,8 +257,21 @@ onestep (struct state *st, Bool first_p) 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); + if (st->first_time) { + /* blank out screen */ + XFillRectangle(st->dpy, st->window, st->window_gc, 0, 0, st->sizex, st->sizey); + st->first_time = 0; + } + /* 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); + +# if 0 + XSetForeground (st->dpy, st->window_gc, + WhitePixel (st->dpy, DefaultScreen (st->dpy))); + XDrawRectangle(st->dpy, st->window, st->window_gc, + st->geom.x, st->geom.y, st->geom.width, st->geom.height); +# endif } #ifdef DEBUG @@ -266,6 +300,12 @@ spotlight_reshape (Display *dpy, Window window, void *closure, static Bool spotlight_event (Display *dpy, Window window, void *closure, XEvent *event) { + struct state *st = (struct state *) closure; + if (screenhack_event_helper (dpy, window, event)) + { + st->start_time = 0; + return True; + } return False; } @@ -287,18 +327,25 @@ static const char *spotlight_defaults [] = { ".background: black", ".foreground: white", "*dontClearRoot: True", + "*fpsSolid: true", #ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */ "*visualID: Best", #endif "*delay: 10000", + "*duration: 120", "*radius: 125", +#ifdef HAVE_MOBILE + "*ignoreRotation: True", + "*rotateImages: True", +#endif 0 }; static XrmOptionDescRec spotlight_options [] = { { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-duration", ".duration", XrmoptionSepArg, 0 }, { "-radius", ".radius", XrmoptionSepArg, 0 }, { 0, 0, 0, 0 } };