-/* xscreensaver, Copyright (c) 1992, 1995, 1997
- * Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 1999
+ * Jamie Zawinski <jwz@jwz.org>
*
* reaction/diffusion textures
* Copyright (c) 1997 Scott Draves spot@transmeta.com
#include <math.h>
#include "screenhack.h"
+#include <X11/Xutil.h>
+
+#ifdef HAVE_XSHM_EXTENSION
+# include "xshm.h"
+#endif /* HAVE_XSHM_EXTENSION */
/* costs ~6% speed */
#define dither_when_mapped 1
-int verbose;
-int ncolors = 0;
-XColor *colors = 0;
-Display *display;
-Visual *visual;
+static int verbose;
+static int ncolors = 0;
+static XColor *colors = 0;
+static Display *display;
+static Visual *visual;
#if dither_when_mapped
-unsigned char *mc = 0;
+static unsigned char *mc = 0;
#endif
-Colormap cmap = 0;
-Window window;
-int mapped;
-int pdepth;
-void random_colors(void);
+static Colormap cmap = 0;
+static Window window;
+static int mapped;
+static int pdepth;
+static void random_colors(void);
/* -----------------------------------------------------------
pixel hack, 8-bit pixel grid, first/next frame interface
/* why strip bit? */
#define R (ya_random()&((1<<30)-1))
-int frame = 0, epoch_time;
-ushort *r1, *r2, *r1b, *r2b;
-int width, height, npix;
-int radius;
-int reaction = 0;
-int diffusion = 0;
+static int frame = 0, epoch_time;
+static ushort *r1, *r2, *r1b, *r2b;
+static int width, height, npix;
+static int radius;
+static int reaction = 0;
+static int diffusion = 0;
/* returns number of pixels that the pixack produces. called once. */
-void
-pixack_init(int *size_h, int *size_v) {
+static void
+pixack_init(int *size_h, int *size_v)
+{
int sz_base;
width = get_integer_resource ("width", "Integer");
height = get_integer_resource ("height", "Integer");
sz_base = 80 + (R%40);
if (width <= 0) width = (R%20) ? sz_base : (28 + R%10);
if (height <= 0) height = (R%20) ? sz_base : (28 + R%10);
+
+ /* jwz: when (and only when) XSHM is in use on an SGI 8-bit visual,
+ we get shear unless width is a multiple of 4. I don't understand
+ why. This is undoubtedly the wrong fix... */
+ width &= ~0x7;
+
/* don't go there */
if (width < 10) width = 10;
if (height < 10) height = 10;
/* returns the pixels. called many times. */
-void
-pixack_frame(char *pix_buf) {
+static void
+pixack_frame(char *pix_buf)
+{
int i, j;
int w2 = width + 2;
ushort *t;
char *defaults [] = {
- "RD.background: black", /* to placate SGI */
- "RD.foreground: white",
+ ".background: black",
+ ".foreground: white",
"*width: 0", /* tried to use -1 but it complained */
"*height: 0",
"*epoch: 40000",
"*verbose: off",
"*radius: -1",
"*speed: 0.0",
- "*size: 0.66",
+ "*size: 1.0",
"*delay: 1",
"*colors: -1",
+#ifdef HAVE_XSHM_EXTENSION
+ "*useSHM: True",
+#endif /* HAVE_XSHM_EXTENSION */
0
};
{ "-size", ".size", XrmoptionSepArg, 0 },
{ "-delay", ".delay", XrmoptionSepArg, 0 },
{ "-ncolors", ".colors", XrmoptionSepArg, 0 },
+#ifdef HAVE_XSHM_EXTENSION
+ { "-shm", ".useSHM", XrmoptionNoArg, "True" },
+ { "-no-shm", ".useSHM", XrmoptionNoArg, "False" },
+#endif /* HAVE_XSHM_EXTENSION */
{ 0, 0, 0, 0 }
};
-/* why doesn't this work??? and more importantly, do i really still have
- to do this in X? */
-
-#ifdef HAVE_XSHM_EXTENSION
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/extensions/XShm.h>
-#endif
-
-
-void
-random_colors() {
+static void
+random_colors(void)
+{
memset(colors, 0, ncolors*sizeof(*colors));
make_smooth_colormap (display, visual, cmap, colors, &ncolors,
True, 0, True);
int vdepth;
int npix;
#ifdef HAVE_XSHM_EXTENSION
- int use_shm = 0;
+ Bool use_shm = get_boolean_resource("useSHM", "Boolean");
XShmSegmentInfo shm_info;
#endif
array_y = (xgwa.height - array_height)/2;
array_dx = p;
array_dy = .31415926 * p;
+
+ /* start in a random direction */
+ if (random() & 1) array_dx = -array_dx;
+ if (random() & 1) array_dy = -array_dy;
+
}
verbose = get_boolean_resource ("verbose", "Boolean");
npix = (width + 2) * (height + 2);
vdepth <= 16 ? 16 :
32);
+ /* Ok, this like, sucks and stuff. There are some XFree86 systems
+ that have depth-24 visuals, that do not accept depth-32 XImages!
+ Which if you ask me is just absurd, since all it would take is
+ for the server to truncate the bits in that case. So, this crap
+ here detects the specific case of: we have chosen depth 32;
+ and the server does not support depth 32. In that case, we
+ try and use depth 16 instead.
+
+ The real fix would be to rewrite this program to deal with
+ depth 24 directly (or even better, arbitrary depths, but that
+ would mean going through the XImage routines instead of messing
+ with the XImage->data directly.)
+
+ jwz, 18-Mar-99: well, the X servers I have access to these days do
+ support 32-deep images on deep visuals, so I no longer have the
+ ability to test this code -- but it was causing problems on the
+ visuals that I do have, and I think that's because I mistakenly
+ wrote `pfv[i].depth' when I meant to write `pfv[i].bits_per_pixel'.
+ The symptom I was seeing was that the grid was 64x64, but the
+ images were being drawn 32x32 -- so there was a black stripe on
+ every other row. Wow, this code sucks so much.
+ */
+ if (pdepth == 32)
+ {
+ int i, pfvc = 0;
+ Bool ok = False;
+ XPixmapFormatValues *pfv = XListPixmapFormats (dpy, &pfvc);
+ for (i = 0; i < pfvc; i++)
+ if (pfv[i].bits_per_pixel == pdepth)
+ ok = True;
+ if (!ok)
+ pdepth = 16;
+ }
+
cmap = xgwa.colormap;
ncolors = get_integer_resource ("colors", "Integer");
int i, di;
mc = (unsigned char *) malloc(1<<16);
for (i = 0; i < (1<<16); i++) {
- di = (i + (ya_random()&255))>>8;
+ di = (i + (random()&255))>>8;
if (di > 255) di = 255;
mc[i] = di;
}
exit(1);
}
+ image = 0;
+
#ifdef HAVE_XSHM_EXTENSION
- if (use_shm) {
- printf("p=%X\n", p);
- free(p);
- image = XShmCreateImage(dpy, xgwa.visual, vdepth,
- ZPixmap, 0, &shm_info, width, height);
- shm_info.shmid = shmget(IPC_PRIVATE,
- image->bytes_per_line * image->height,
- IPC_CREAT | 0777);
- if (shm_info.shmid == -1)
- printf ("shmget failed!");
- shm_info.readOnly = False;
- p = shmat(shm_info.shmid, 0, 0);
- printf("p=%X %d\n", p, image->bytes_per_line);
- XShmAttach(dpy, &shm_info);
- XSync(dpy, False);
- } else
-#endif
- image = XCreateImage(dpy, xgwa.visual, vdepth,
- ZPixmap, 0, p,
- width, height, 8, 0);
+ if (use_shm)
+ {
+ image = create_xshm_image(dpy, xgwa.visual, vdepth,
+ ZPixmap, 0, &shm_info, width, height);
+ if (!image)
+ use_shm = False;
+ else
+ {
+ free(p);
+ p = image->data;
+ }
+ }
+#endif /* HAVE_XSHM_EXTENSION */
+
+ if (!image)
+ {
+ image = XCreateImage(dpy, xgwa.visual, vdepth,
+ ZPixmap, 0, p,
+ width, height, 8, 0);
+ }
while (1) {
+ Bool bump = False;
+
int i, j;
pixack_frame(p);
for (i = 0; i < array_width; i += width)
for (j = 0; j < array_height; j += height)
#ifdef HAVE_XSHM_EXTENSION
if (use_shm)
- XShmPutImage(dpy, win, gc, image, 0, 0, i, j,
+ XShmPutImage(dpy, win, gc, image, 0, 0, i+array_x, j+array_y,
width, height, False);
else
#endif
- XPutImage(dpy, win, gc, image, 0, 0, i+array_x, j+array_y, width, height);
+ XPutImage(dpy, win, gc, image, 0, 0, i+array_x, j+array_y,
+ width, height);
array_x += array_dx;
array_y += array_dy;
if (array_x < 0) {
array_x = 0;
array_dx = -array_dx;
+ bump = True;
} else if (array_x > (xgwa.width - array_width)) {
array_x = (xgwa.width - array_width);
array_dx = -array_dx;
+ bump = True;
}
if (array_y < 0) {
array_y = 0;
array_dy = -array_dy;
+ bump = True;
} else if (array_y > (xgwa.height - array_height)) {
array_y = (xgwa.height - array_height);
array_dy = -array_dy;
+ bump = True;
}
+
+ if (bump) {
+ if (random() & 1) {
+ double swap = array_dx;
+ array_dx = array_dy;
+ array_dy = swap;
+ }
+ }
+
frame++;
XSync(dpy, False);
+ screenhack_handle_events (dpy);
if (delay > 0)
usleep(1000 * delay);
}