http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / interference.c
index d436ebb4ecf4e689f01a3c5c53c45da2fda3d11f..fefaf9d9de1ceefce55751bf510a8ffce9466fca 100644 (file)
 
 # include <X11/Xutil.h>
 
-#ifdef HAVE_XDBE
-# include <X11/extensions/Xdbe.h>
-#endif /* HAVE_XDBE */
-
+/* I thought it would be faster this way, but it turns out not to be... -jwz */
+#undef USE_XIMAGE
 
-/* I haven't gotten the shm stuff to work yet... and I'm not sure it would
-   help much anyway.  -- jwz */
-#undef HAVE_XSHM_EXTENSION
+#ifndef USE_XIMAGE
+# undef HAVE_XSHM_EXTENSION  /* only applicable when using XImages */
+#endif /* USE_XIMAGE */
 
-#ifdef HAVE_XSHM_EXTENSION
-# include <sys/ipc.h>
-# include <sys/shm.h>
-# include <X11/extensions/XShm.h>
-#endif /*  HAVE_XSHM_EXTENSION */
 
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+# include "xdbe.h"
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 
-/* I thought it would be faster this way, but it turns out not to be... -jwz */
-/* #define USE_XIMAGE */
+#ifdef HAVE_XSHM_EXTENSION
+# include "xshm.h"
+#endif /* HAVE_XSHM_EXTENSION */
 
 char *progclass="Interference";
 
 char *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 */
@@ -83,12 +82,13 @@ char *defaults [] = {
   "*gray:        false", /* color or grayscale */
   "*mono:        false", /* monochrome, not very much fun */
 
-#ifdef HAVE_XDBE
-  "*nodb:        true", /* don't use double buffering */
-#endif /* HAVE_XDBE */
+  "*doubleBuffer: True",
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+  "*useDBE:      True", /* use double buffering extension */
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 
 #ifdef HAVE_XSHM_EXTENSION
-  "*noshm:        false", /* don't use shared memory */
+  "*useSHM:      True", /* use shared memory extension */
 #endif /*  HAVE_XSHM_EXTENSION */
   0
 };
@@ -103,11 +103,11 @@ XrmOptionDescRec options [] = {
   { "-radius",      ".radius",      XrmoptionSepArg, 0 },
   { "-gray",        ".gray",        XrmoptionNoArg,  "True" },
   { "-mono",        ".mono",        XrmoptionNoArg,  "True" },
-#ifdef HAVE_XDBE
-  { "-nodb",        ".nodb",        XrmoptionNoArg,  "True" },
-#endif /* HAVE_XDBE */
+  { "-db",         ".doubleBuffer", XrmoptionNoArg,  "True" },
+  { "-no-db",      ".doubleBuffer", XrmoptionNoArg,  "False" },
 #ifdef HAVE_XSHM_EXTENSION
-  { "-noshm",        ".noshm",      XrmoptionNoArg,  "True" },
+  { "-shm",    ".useSHM",      XrmoptionNoArg, "True" },
+  { "-no-shm", ".useSHM",      XrmoptionNoArg, "False" },
 #endif /*  HAVE_XSHM_EXTENSION */
   { 0, 0, 0, 0 }
 };
@@ -128,18 +128,18 @@ 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
-  int use_shm;
+  Bool use_shm;
   XShmSegmentInfo shm_info;
 #endif /* HAVE_XSHM_EXTENSION */
 
@@ -161,9 +161,6 @@ struct inter_context {
   int h;
   Colormap cmap;
   XColor* pal;
-#ifdef HAVE_XDBE
-  XdbeBackBuffer buf;
-#endif /* HAVE_XDBE */
   GC* gcs;
 
   /*
@@ -177,11 +174,12 @@ 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) 
 {
@@ -190,13 +188,11 @@ void inter_init(Display* dpy, Window win, struct inter_context* c)
   int i;
   int mono;
   int gray;
-#ifdef HAVE_XDBE
-  int major, minor;
-  int nodb;
-#endif /* HAVE_XDBE */
-
   XGCValues val;
   unsigned long valmask = 0;
+  Bool dbuf = get_boolean_resource ("doubleBuffer", "Boolean");
+
+  memset (c, 0, sizeof(*c));
 
   c->dpy = dpy;
   c->win = win;
@@ -206,28 +202,25 @@ void inter_init(Display* dpy, Window win, struct inter_context* c)
   c->h = xgwa.height;
   c->cmap = xgwa.colormap;
 
-#ifdef HAVE_XDBE
-  nodb = get_boolean_resource("nodb", "Boolean");
-  if(nodb) {
-    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("noshm", "Boolean");
+  c->use_shm = get_boolean_resource("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");
   if(c->count < 1)
@@ -253,27 +246,20 @@ void inter_init(Display* dpy, Window win, struct inter_context* c)
 
 #ifdef USE_XIMAGE
 
-# ifdef HAVE_XSHM_EXTENSION
+  c->ximage = 0;
 
+# ifdef HAVE_XSHM_EXTENSION
   if (c->use_shm)
     {
-      c->ximage = XShmCreateImage(dpy, xgwa.visual, xgwa.depth,
-                                 ZPixmap, 0, &c->shm_info,
-                                 xgwa.width, c->grid_size);
-      c->shm_info.shmid = shmget(IPC_PRIVATE,
-                                c->ximage->height * c->ximage->bytes_per_line,
-                                IPC_CREAT | 0777);
-      if (c->shm_info.shmid == -1)
-       printf ("shmget failed!");
-      c->shm_info.readOnly = False;
-      c->ximage->data = shmat(c->shm_info.shmid, 0, 0);
-      printf("data=0x%X %d %d\n", c->ximage->data,
-            c->ximage->height, c->ximage->bytes_per_line);
-      XShmAttach(dpy, &c->shm_info);
-      XSync(dpy, False);
+      c->ximage = create_xshm_image(dpy, xgwa.visual, xgwa.depth,
+                                   ZPixmap, 0, &c->shm_info,
+                                   xgwa.width, c->grid_size);
+      if (!c->ximage)
+       c->use_shm = False;
     }
-  else
 # endif /* HAVE_XSHM_EXTENSION */
+
+  if (!c->ximage)
     {
       c->ximage =
        XCreateImage (dpy, xgwa.visual,
@@ -288,11 +274,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");
     if(!gray) {
-      H[0] = drand48()*360.0
+      H[0] = frand(360.0)
       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;
@@ -322,11 +306,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++) {
@@ -347,8 +326,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;
   }
 
 }
@@ -370,9 +349,6 @@ 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;
@@ -421,38 +397,35 @@ void do_inter(struct inter_context* c)
             c->ximage->bytes_per_line);
 
     /* Move the bits for this horizontal stripe to the server. */
-#ifdef HAVE_XSHM_EXTENSION
+# ifdef HAVE_XSHM_EXTENSION
     if (c->use_shm)
-      {
-       /* wtf? we get a badmatch unless ximage->data == 0 ? */
-       char *d = c->ximage->data;
-       c->ximage->data = 0;
-       XShmPutImage(c->dpy, TARGET(c), c->copy_gc, c->ximage,
-                    0, 0, 0, g*j, c->ximage->width, c->ximage->height,
-                    False);
-       c->ximage->data = d;
-      }
+      XShmPutImage(c->dpy, TARGET(c), c->copy_gc, c->ximage,
+                  0, 0, 0, g*j, c->ximage->width, c->ximage->height,
+                  False);
     else
-#endif /*  HAVE_XSHM_EXTENSION */
+# endif /*  HAVE_XSHM_EXTENSION */
       XPutImage(c->dpy, TARGET(c), c->copy_gc, c->ximage,
                0, 0, 0, g*j, c->ximage->width, c->ximage->height);
 
 #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);
-    }
+#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);
+      }
+
   XSync(c->dpy, False);
 }
 
@@ -466,7 +439,7 @@ void screenhack(Display *dpy, Window win)
   inter_init(dpy, win, &c);
   while(1) {
     do_inter(&c); 
-    if(delay) 
-      usleep(delay);
+    screenhack_handle_events (dpy);
+    if(delay) usleep(delay);
   }
 }