-/* xscreensaver, Copyright (c) 1997, 1998, 2001 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1997-2013 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* implied warranty.
*
* Concept snarfed from Michael D. Bayne in
- * http://www.go2net.com/internet/deep/1997/04/16/body.html
+ * http://samskivert.com/internet/deep/1997/04/16/body.html
*/
#include "screenhack.h"
-#include <X11/Xutil.h>
-#include <stdio.h>
-
-#ifdef HAVE_XSHM_EXTENSION
-# include "xshm.h"
-static Bool use_shm;
-static XShmSegmentInfo shm_info;
-#endif /* HAVE_XSHM_EXTENSION */
-
-static int offset = 0;
-static XColor *colors = 0;
-static int ncolors = 0;
-static GC gc = 0;
-static unsigned long fg_pixel = 0;
-static unsigned long bg_pixel = 0;
+#include "xshm.h"
+
+struct state {
+ Display *dpy;
+ Window window;
+ XShmSegmentInfo shm_info;
+
+ int delay;
+ int offset;
+ XColor *colors;
+ int ncolors;
+ GC gc;
+ unsigned long fg_pixel;
+ unsigned long bg_pixel;
+ int depth;
+
+ int draw_y, draw_xo, draw_yo;
+ int draw_factor;
+ XImage *draw_image;
+ XWindowAttributes xgwa;
+};
static void
-init_moire (Display *dpy, Window window)
+moire_init_1 (struct state *st)
{
int oncolors;
int i;
XWindowAttributes xgwa;
XColor fgc, bgc;
XGCValues gcv;
- XGetWindowAttributes (dpy, window, &xgwa);
- offset = get_integer_resource ("offset", "Integer");
- if (offset < 2) offset = 2;
+ XGetWindowAttributes (st->dpy, st->window, &xgwa);
-#ifdef HAVE_XSHM_EXTENSION
- use_shm = get_boolean_resource("useSHM", "Boolean");
-#endif /* HAVE_XSHM_EXTENSION */
+ st->delay = get_integer_resource (st->dpy, "delay", "Integer");
+ st->offset = get_integer_resource (st->dpy, "offset", "Integer");
+ if (st->offset < 2) st->offset = 2;
MONO:
- if (colors)
+ if (st->colors)
{
- for (i = 0; i < ncolors; i++)
- XFreeColors (dpy, xgwa.colormap, &colors[i].pixel, 1, 0);
- free(colors);
- colors = 0;
+ for (i = 0; i < st->ncolors; i++)
+ XFreeColors (st->dpy, xgwa.colormap, &st->colors[i].pixel, 1, 0);
+ free(st->colors);
+ st->colors = 0;
}
if (mono_p)
{
- fg_pixel = WhitePixelOfScreen (DefaultScreenOfDisplay(dpy));
- bg_pixel = BlackPixelOfScreen (DefaultScreenOfDisplay(dpy));
+ st->fg_pixel = WhitePixelOfScreen (DefaultScreenOfDisplay(st->dpy));
+ st->bg_pixel = BlackPixelOfScreen (DefaultScreenOfDisplay(st->dpy));
}
else
{
- fg_pixel = get_pixel_resource ("foreground", "Foreground", dpy,
- xgwa.colormap);
- bg_pixel = get_pixel_resource ("background", "Background", dpy,
- xgwa.colormap);
+ st->fg_pixel = get_pixel_resource (st->dpy,
+ xgwa.colormap, "foreground", "Foreground");
+ st->bg_pixel = get_pixel_resource (st->dpy,
+ xgwa.colormap, "background", "Background");
}
if (mono_p)
{
- offset *= 20; /* compensate for lack of shading */
- gcv.foreground = fg_pixel;
+ st->offset *= 20; /* compensate for lack of shading */
+ gcv.foreground = st->fg_pixel;
}
else
{
- ncolors = get_integer_resource ("ncolors", "Integer");
- if (ncolors < 2) ncolors = 2;
- oncolors = ncolors;
+ st->ncolors = get_integer_resource (st->dpy, "ncolors", "Integer");
+ if (st->ncolors < 2) st->ncolors = 2;
+ oncolors = st->ncolors;
fgc.flags = bgc.flags = DoRed|DoGreen|DoBlue;
- if (get_boolean_resource("random","Boolean"))
+ if (get_boolean_resource(st->dpy, "random","Boolean"))
{
fgc.red = random() & 0xFFFF;
fgc.green = random() & 0xFFFF;
}
else
{
- fgc.pixel = fg_pixel;
- bgc.pixel = bg_pixel;
- XQueryColor (dpy, xgwa.colormap, &fgc);
- XQueryColor (dpy, xgwa.colormap, &bgc);
+ fgc.pixel = st->fg_pixel;
+ bgc.pixel = st->bg_pixel;
+ XQueryColor (st->dpy, xgwa.colormap, &fgc);
+ XQueryColor (st->dpy, xgwa.colormap, &bgc);
}
rgb_to_hsv (fgc.red, fgc.green, fgc.blue, &fgh, &fgs, &fgv);
rgb_to_hsv (bgc.red, bgc.green, bgc.blue, &bgh, &bgs, &bgv);
- colors = (XColor *) malloc (sizeof (XColor) * (ncolors+2));
- memset(colors, 0, (sizeof (XColor) * (ncolors+2)));
- make_color_ramp (dpy, xgwa.colormap,
+ st->colors = (XColor *) malloc (sizeof (XColor) * (st->ncolors+2));
+ memset(st->colors, 0, (sizeof (XColor) * (st->ncolors+2)));
+ make_color_ramp (xgwa.screen, xgwa.visual, xgwa.colormap,
fgh, fgs, fgv, bgh, bgs, bgv,
- colors, &ncolors,
+ st->colors, &st->ncolors,
True, True, False);
- if (ncolors != oncolors)
+ if (st->ncolors != oncolors)
fprintf(stderr, "%s: got %d of %d requested colors.\n",
- progname, ncolors, oncolors);
+ progname, st->ncolors, oncolors);
- if (ncolors <= 2)
+ if (st->ncolors <= 2)
{
mono_p = True;
goto MONO;
}
- gcv.foreground = colors[0].pixel;
+ gcv.foreground = st->colors[0].pixel;
}
- gc = XCreateGC (dpy, window, GCForeground, &gcv);
+ st->gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
}
-static void
-moire (Display *dpy, Window window, int offset, XColor *colors, int ncolors)
+static void *
+moire_init (Display *dpy, Window window)
{
- long x, y, xo, yo;
- int factor = (random() % offset) + 1;
- XGCValues gcv;
- XWindowAttributes xgwa;
- XImage *image;
- int depth;
- XGetWindowAttributes (dpy, window, &xgwa);
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
+ st->dpy = dpy;
+ st->window = window;
+ moire_init_1 (st);
+ return st;
+}
- xo = (random() % xgwa.width) - xgwa.width/2;
- yo = (random() % xgwa.height) - xgwa.height/2;
- depth = visual_depth(DefaultScreenOfDisplay(dpy), xgwa.visual);
+static unsigned long
+moire_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ XGCValues gcv;
+ int chunk_size = 20, ii;
- image = 0;
-# ifdef HAVE_XSHM_EXTENSION
- if (use_shm)
+ if (st->draw_y == 0)
{
- image = create_xshm_image(dpy, xgwa.visual, depth, ZPixmap, 0,
- &shm_info, xgwa.width, 1);
- if (!image)
- use_shm = False;
- }
-# endif /* HAVE_XSHM_EXTENSION */
+ moire_init_1 (st);
- if (!image)
- {
- image = XCreateImage (dpy, xgwa.visual,
- depth, ZPixmap, 0, /* depth, format, offset */
- 0, xgwa.width, 1, 8, 0); /* data, w, h, pad, bpl */
- image->data = (char *) calloc(image->height, image->bytes_per_line);
+ XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+
+ st->draw_xo = (random() % st->xgwa.width) - st->xgwa.width/2;
+ st->draw_yo = (random() % st->xgwa.height) - st->xgwa.height/2;
+ st->draw_factor = (random() % st->offset) + 1;
+
+ st->depth = visual_depth(DefaultScreenOfDisplay(st->dpy), st->xgwa.visual);
+
+ st->draw_image = create_xshm_image(st->dpy, st->xgwa.visual,
+ st->depth, ZPixmap, &st->shm_info, /* depth, format, shm_info */
+ st->xgwa.width, chunk_size); /* w, h */
}
- for (y = 0; y < xgwa.height; y++)
+ /* for (y = 0; y < st->xgwa.height; y++) */
+ for (ii = 0; ii < chunk_size; ii++)
{
- for (x = 0; x < xgwa.width; x++)
+ int x;
+ for (x = 0; x < st->xgwa.width; x++)
{
- double xx = x + xo;
- double yy = y + yo;
- double i = ((xx * xx) + (yy * yy)) / (double) factor;
+ double xx = x + st->draw_xo;
+ double yy = st->draw_y + ii + st->draw_yo;
+ double i = ((xx * xx) + (yy * yy)) / (double) st->draw_factor;
if (mono_p)
- gcv.foreground = ((((long) i) & 1) ? fg_pixel : bg_pixel);
+ gcv.foreground = ((((long) i) & 1) ? st->fg_pixel : st->bg_pixel);
else
- gcv.foreground = colors[((long) i) % ncolors].pixel;
- XPutPixel (image, x, 0, gcv.foreground);
+ gcv.foreground = st->colors[((long) i) % st->ncolors].pixel;
+ XPutPixel (st->draw_image, x, ii, gcv.foreground);
}
-# ifdef HAVE_XSHM_EXTENSION
- if (use_shm)
- XShmPutImage(dpy, window, gc, image, 0, 0, 0, y, xgwa.width, 1, False);
- else
-# endif /* HAVE_XSHM_EXTENSION */
- XPutImage (dpy, window, gc, image, 0, 0, 0, y, xgwa.width, 1);
-
- XSync(dpy, False);
+ if (st->draw_y + ii >= st->xgwa.height)
+ break;
}
-# ifdef HAVE_XSHM_EXTENSION
- if (!use_shm)
-# endif /* HAVE_XSHM_EXTENSION */
- if (image->data)
+ put_xshm_image(st->dpy, st->window, st->gc, st->draw_image, 0, 0, 0, st->draw_y, st->xgwa.width, chunk_size, &st->shm_info);
+ st->draw_y += chunk_size;
+
+ if (st->draw_y >= st->xgwa.height)
{
- free(image->data);
- image->data = 0;
+ st->draw_y = 0;
+
+ destroy_xshm_image (st->dpy, st->draw_image, &st->shm_info);
+ st->draw_image = 0;
+
+ return st->delay * 1000000;
}
-# ifdef HAVE_XSHM_EXTENSION
- if (use_shm)
- destroy_xshm_image (dpy, image, &shm_info);
- else
-# endif /* HAVE_XSHM_EXTENSION */
- XDestroyImage (image);
+ return st->delay * 10000;
}
\f
-char *progclass = "Moire";
-
-char *defaults [] = {
+static const char *moire_defaults [] = {
".background: blue",
".foreground: red",
+ "*fpsSolid: true",
"*random: true",
"*delay: 5",
"*ncolors: 64",
"*offset: 50",
-#ifdef HAVE_XSHM_EXTENSION
"*useSHM: True",
-#endif /* HAVE_XSHM_EXTENSION */
+#ifdef HAVE_MOBILE
+ "*ignoreRotation: True",
+#endif
0
};
-XrmOptionDescRec options [] = {
+static XrmOptionDescRec moire_options [] = {
{ "-random", ".random", XrmoptionNoArg, "True" },
{ "-no-random", ".random", XrmoptionNoArg, "False" },
{ "-delay", ".delay", XrmoptionSepArg, 0 },
{ "-ncolors", ".ncolors", XrmoptionSepArg, 0 },
{ "-offset", ".offset", XrmoptionSepArg, 0 },
-#ifdef HAVE_XSHM_EXTENSION
{ "-shm", ".useSHM", XrmoptionNoArg, "True" },
{ "-no-shm", ".useSHM", XrmoptionNoArg, "False" },
-#endif /* HAVE_XSHM_EXTENSION */
{ 0, 0, 0, 0 }
};
-void
-screenhack (Display *dpy, Window window)
+static void
+moire_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
{
- int delay = get_integer_resource ("delay", "Integer");
- while (1)
- {
- init_moire (dpy, window);
- moire (dpy, window, offset, colors, ncolors);
- XSync (dpy, False);
- screenhack_handle_events (dpy);
- if (delay)
- sleep(delay);
- }
}
+
+static Bool
+moire_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+ return False;
+}
+
+static void
+moire_free (Display *dpy, Window window, void *closure)
+{
+}
+
+XSCREENSAVER_MODULE ("Moire", moire)