X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Finterference.c;h=e1eebb6755071c52dbbda4c4332e5b821cba4507;hb=c1b9b55ad8d59dc05ef55e316aebf5863e7dfa56;hp=d877a01b1cd44c8804f4182dab33814a4b5b40ab;hpb=ce3185de9d9705e259f2b60dd4b5509007fa17d4;p=xscreensaver diff --git a/hacks/interference.c b/hacks/interference.c index d877a01b..e1eebb67 100644 --- a/hacks/interference.c +++ b/hacks/interference.c @@ -24,6 +24,9 @@ * * Created : Wed Apr 22 09:30:30 1998, hmallat * Last modified: Wed Apr 22 09:30:30 1998, hmallat + * Last modified: Sun Aug 31 23:40:14 2003, + * david slimp + * added -hue option to specify base color hue * * TODO: * @@ -48,28 +51,29 @@ #include "screenhack.h" -# include - /* I thought it would be faster this way, but it turns out not to be... -jwz */ #undef USE_XIMAGE -#undef HAVE_XSHM_EXTENSION -#undef HAVE_XDBE + +#ifndef USE_XIMAGE +# undef HAVE_XSHM_EXTENSION /* only applicable when using XImages */ +#endif /* USE_XIMAGE */ -#ifdef HAVE_XDBE -# include -#endif /* HAVE_XDBE */ +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION +# include "xdbe.h" +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ #ifdef HAVE_XSHM_EXTENSION # include "xshm.h" #endif /* HAVE_XSHM_EXTENSION */ -char *progclass="Interference"; - -char *defaults [] = { +static const char *interference_defaults [] = { + ".background: black", + ".foreground: white", "*count: 3", /* number of waves */ "*gridsize: 4", /* pixel size, smaller values for better resolution */ "*ncolors: 128", /* number of colours used */ + "*hue: 0", /* hue to use for base color (0-360) */ "*speed: 30", /* speed of wave origins moving around */ "*delay: 30000", /* or something */ "*color-shift: 60", /* h in hsv space, smaller values for smaller @@ -78,9 +82,10 @@ char *defaults [] = { "*gray: false", /* color or grayscale */ "*mono: false", /* monochrome, not very much fun */ -#ifdef HAVE_XDBE + "*doubleBuffer: True", +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION "*useDBE: True", /* use double buffering extension */ -#endif /* HAVE_XDBE */ +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ #ifdef HAVE_XSHM_EXTENSION "*useSHM: True", /* use shared memory extension */ @@ -88,20 +93,19 @@ char *defaults [] = { 0 }; -XrmOptionDescRec options [] = { +static XrmOptionDescRec interference_options [] = { { "-count", ".count", XrmoptionSepArg, 0 }, { "-ncolors", ".ncolors", XrmoptionSepArg, 0 }, { "-gridsize", ".gridsize", XrmoptionSepArg, 0 }, + { "-hue", ".hue", XrmoptionSepArg, 0 }, { "-speed", ".speed", XrmoptionSepArg, 0 }, { "-delay", ".delay", XrmoptionSepArg, 0 }, { "-color-shift", ".color-shift", XrmoptionSepArg, 0 }, { "-radius", ".radius", XrmoptionSepArg, 0 }, { "-gray", ".gray", XrmoptionNoArg, "True" }, { "-mono", ".mono", XrmoptionNoArg, "True" }, -#ifdef HAVE_XDBE - { "-db", ".useDBE", XrmoptionNoArg, "True" }, - { "-no-db", ".useDBE", XrmoptionNoArg, "False" }, -#endif /* HAVE_XDBE */ + { "-db", ".doubleBuffer", XrmoptionNoArg, "True" }, + { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" }, #ifdef HAVE_XSHM_EXTENSION { "-shm", ".useSHM", XrmoptionNoArg, "True" }, { "-no-shm", ".useSHM", XrmoptionNoArg, "False" }, @@ -109,8 +113,6 @@ XrmOptionDescRec options [] = { { 0, 0, 0, 0 } }; -int options_size = (sizeof (options) / sizeof (XrmOptionDescRec)); - struct inter_source { int x; int y; @@ -125,16 +127,16 @@ struct inter_context { Display* dpy; Window win; - Pixmap dbuf; +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + XdbeBackBuffer back_buf; +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + Pixmap pix_buf; + GC copy_gc; #ifdef USE_XIMAGE XImage *ximage; #endif /* USE_XIMAGE */ -#ifdef HAVE_XDBE - Status has_dbe; -#endif /* HAVE_XDBE */ - #ifdef HAVE_XSHM_EXTENSION Bool use_shm; XShmSegmentInfo shm_info; @@ -146,6 +148,7 @@ struct inter_context { int count; int grid_size; int colors; + float hue; int speed; int delay; int shift; @@ -158,9 +161,6 @@ struct inter_context { int h; Colormap cmap; XColor* pal; -#ifdef HAVE_XDBE - XdbeBackBuffer buf; -#endif /* HAVE_XDBE */ GC* gcs; /* @@ -174,77 +174,83 @@ struct inter_context { struct inter_source* source; }; -#ifdef HAVE_XDBE -# define TARGET(c) ((c)->has_dbe ? (c)->buf : (c)->dbuf) -#else /* HAVE_XDBE */ -# define TARGET(c) ((c)->dbuf) -#endif /* !HAVE_XDBE */ +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION +# define TARGET(c) ((c)->back_buf ? (c)->back_buf : \ + (c)->pix_buf ? (c)->pix_buf : (c)->win) +#else /* HAVE_DOUBLE_BUFFER_EXTENSION */ +# define TARGET(c) ((c)->pix_buf ? (c)->pix_buf : (c)->win) +#endif /* !HAVE_DOUBLE_BUFFER_EXTENSION */ -void inter_init(Display* dpy, Window win, struct inter_context* c) +static void inter_init(Display* dpy, Window win, struct inter_context* c) { XWindowAttributes xgwa; double H[3], S[3], V[3]; int i; int mono; int gray; -#ifdef HAVE_XDBE - int major, minor; - int use_dbe; -#endif /* HAVE_XDBE */ - XGCValues val; unsigned long valmask = 0; + Bool dbuf = get_boolean_resource (dpy, "doubleBuffer", "Boolean"); + +# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ + dbuf = False; +# endif + + memset (c, 0, sizeof(*c)); c->dpy = dpy; c->win = win; + c->delay = get_integer_resource(dpy, "delay", "Integer"); + + XGetWindowAttributes(c->dpy, c->win, &xgwa); c->w = xgwa.width; c->h = xgwa.height; c->cmap = xgwa.colormap; -#ifdef HAVE_XDBE - use_dbe = get_boolean_resource("useDBE", "Boolean"); - if(!use_dbe) { - c->has_dbe = False; - } else { - c->has_dbe = XdbeQueryExtension(dpy, &major, &minor); - } -#endif /* HAVE_XDBE */ - #ifdef HAVE_XSHM_EXTENSION - c->use_shm = get_boolean_resource("useSHM", "Boolean"); + c->use_shm = get_boolean_resource(dpy, "useSHM", "Boolean"); #endif /* HAVE_XSHM_EXTENSION */ -#ifdef HAVE_XDBE - if (!c->has_dbe) -#endif /* HAVE_XDBE */ + if (dbuf) { - c->dbuf = XCreatePixmap(dpy, win, xgwa.width, xgwa.height, xgwa.depth); - val.function = GXcopy; +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + c->back_buf = xdbe_get_backbuffer (c->dpy, c->win, XdbeUndefined); +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + if (!c->back_buf) +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + c->pix_buf = XCreatePixmap (dpy, win, xgwa.width, xgwa.height, + xgwa.depth); } - c->copy_gc = XCreateGC(c->dpy, c->dbuf, GCFunction, &val); + val.function = GXcopy; + c->copy_gc = XCreateGC(c->dpy, TARGET(c), GCFunction, &val); - c->count = get_integer_resource("count", "Integer"); + c->count = get_integer_resource(dpy, "count", "Integer"); if(c->count < 1) c->count = 1; - c->grid_size = get_integer_resource("gridsize", "Integer"); + c->grid_size = get_integer_resource(dpy, "gridsize", "Integer"); if(c->grid_size < 1) c->grid_size = 1; - mono = get_boolean_resource("mono", "Boolean"); + mono = get_boolean_resource(dpy, "mono", "Boolean"); if(!mono) { - c->colors = get_integer_resource("ncolors", "Integer"); + c->colors = get_integer_resource(dpy, "ncolors", "Integer"); if(c->colors < 2) c->colors = 2; } - c->speed = get_integer_resource("speed", "Integer"); - c->shift = get_float_resource("color-shift", "Float"); + c->hue = get_integer_resource(dpy, "hue", "Float"); + while (c->hue < 0 || c->hue >= 360) + c->hue = frand(360.0); + c->speed = get_integer_resource(dpy, "speed", "Integer"); + c->shift = get_float_resource(dpy, "color-shift", "Float"); while(c->shift >= 360.0) c->shift -= 360.0; while(c->shift <= -360.0) c->shift += 360.0; - c->radius = get_integer_resource("radius", "Integer");; + c->radius = get_integer_resource(dpy, "radius", "Integer");; if(c->radius < 1) c->radius = 1; @@ -278,11 +284,9 @@ void inter_init(Display* dpy, Window win, struct inter_context* c) if(!mono) { c->pal = calloc(c->colors, sizeof(XColor)); - srand48(time(NULL)); - - gray = get_boolean_resource("gray", "Boolean"); + gray = get_boolean_resource(dpy, "gray", "Boolean"); if(!gray) { - H[0] = drand48()*360.0; + H[0] = c->hue; H[1] = H[0] + c->shift < 360.0 ? H[0]+c->shift : H[0] + c->shift-360.0; H[2] = H[1] + c->shift < 360.0 ? H[1]+c->shift : H[1] + c->shift-360.0; S[0] = S[1] = S[2] = 1.0; @@ -312,11 +316,6 @@ void inter_init(Display* dpy, Window win, struct inter_context* c) c->pal[1].pixel = WhitePixel(c->dpy, DefaultScreen(c->dpy)); } -#ifdef HAVE_XDBE - if(c->has_dbe) - c->buf = XdbeAllocateBackBufferName(c->dpy, c->win, XdbeUndefined); -#endif /* HAVE_XDBE */ - valmask = GCForeground; c->gcs = calloc(c->colors, sizeof(GC)); for(i = 0; i < c->colors; i++) { @@ -337,8 +336,8 @@ void inter_init(Display* dpy, Window win, struct inter_context* c) c->source = calloc(c->count, sizeof(struct inter_source)); for(i = 0; i < c->count; i++) { - c->source[i].x_theta = drand48()*2.0*3.14159; - c->source[i].y_theta = drand48()*2.0*3.14159; + c->source[i].x_theta = frand(2.0)*3.14159; + c->source[i].y_theta = frand(2.0)*3.14159; } } @@ -355,14 +354,11 @@ void inter_init(Display* dpy, Window win, struct inter_context* c) * it, go ahead! */ -void do_inter(struct inter_context* c) +static void do_inter(struct inter_context* c) { int i, j, k; int result; int dist; -#ifdef HAVE_XDBE - XdbeSwapInfo info[1]; -#endif /* HAVE_XDBE */ int g; int dx, dy; @@ -387,7 +383,7 @@ void do_inter(struct inter_context* c) dx = i*g + g/2 - c->source[k].x; dy = j*g + g/2 - c->source[k].y; dist = sqrt(dx*dx + dy*dy); /* what's the performance penalty here? */ - result += (dist > c->radius ? 0 : c->wave_height[dist]); + result += (dist >= c->radius ? 0 : c->wave_height[dist]); } result %= c->colors; @@ -424,33 +420,54 @@ void do_inter(struct inter_context* c) #endif /* USE_XIMAGE */ } -#ifdef HAVE_XDBE - if(c->has_dbe) +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + if (c->back_buf) { + XdbeSwapInfo info[1]; info[0].swap_window = c->win; info[0].swap_action = XdbeUndefined; XdbeSwapBuffers(c->dpy, info, 1); } else -#endif /* HAVE_XDBE */ - { - XCopyArea (c->dpy, c->dbuf, c->win, c->copy_gc, - 0, 0, c->w, c->h, 0, 0); - } - XSync(c->dpy, False); +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + if (c->pix_buf) + { + XCopyArea (c->dpy, c->pix_buf, c->win, c->copy_gc, + 0, 0, c->w, c->h, 0, 0); + } } -void screenhack(Display *dpy, Window win) +static void * +interference_init (Display *dpy, Window win) { - struct inter_context c; - int delay; + struct inter_context *c = (struct inter_context *) calloc (1, sizeof(*c)); + inter_init(dpy, win, c); + return c; +} - delay = get_integer_resource("delay", "Integer"); +static unsigned long +interference_draw (Display *dpy, Window win, void *closure) +{ + struct inter_context *c = (struct inter_context *) closure; + do_inter(c); + return c->delay; +} - inter_init(dpy, win, &c); - while(1) { - do_inter(&c); - if(delay) - usleep(delay); - } +static void +interference_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ +} + +static Bool +interference_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; } + +static void +interference_free (Display *dpy, Window window, void *closure) +{ +} + +XSCREENSAVER_MODULE ("Interference", interference)