*
* 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 <rock808@DavidSlimp.com>
+ * added -hue option to specify base color hue
*
* TODO:
*
#include "screenhack.h"
-# include <X11/Xutil.h>
-
/* 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 <X11/extensions/Xdbe.h>
-#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
"*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 */
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" },
{ 0, 0, 0, 0 }
};
-int options_size = (sizeof (options) / sizeof (XrmOptionDescRec));
-
struct inter_source {
int x;
int y;
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;
int count;
int grid_size;
int colors;
+ float hue;
int speed;
int delay;
int shift;
int h;
Colormap cmap;
XColor* pal;
-#ifdef HAVE_XDBE
- XdbeBackBuffer buf;
-#endif /* HAVE_XDBE */
GC* gcs;
/*
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;
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;
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++) {
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;
}
}
* 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;
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;
#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)
+{
+ struct inter_context *c = (struct inter_context *) closure;
+ c->w = w;
+ c->h = 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)