X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fmoire.c;h=4add45768b9c89d74e4946278a62ad448b92facf;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hp=7d9798c212907af04c98dd22d579d32a156b9ac7;hpb=f3e0240915ed9f9b3a61781f5c7002d587563fe0;p=xscreensaver diff --git a/hacks/moire.c b/hacks/moire.c index 7d9798c2..4add4576 100644 --- a/hacks/moire.c +++ b/hacks/moire.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1997 Jamie Zawinski +/* xscreensaver, Copyright (c) 1997-2013 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -9,22 +9,34 @@ * 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 -#include +#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 offset = 0; -XColor *colors = 0; -int ncolors = 0; -GC gc = 0; -unsigned long fg_pixel = 0; -unsigned long bg_pixel = 0; + 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; @@ -33,46 +45,48 @@ init_moire (Display *dpy, Window window) 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); + + 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; @@ -83,111 +97,149 @@ init_moire (Display *dpy, Window window) } 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) +{ + struct state *st = (struct state *) calloc (1, sizeof(*st)); + st->dpy = dpy; + st->window = window; + moire_init_1 (st); + return st; +} + + +static unsigned long +moire_draw (Display *dpy, Window window, void *closure) { - long x, y, xo, yo; - int factor = (random() % offset) + 1; + struct state *st = (struct state *) closure; XGCValues gcv; - XWindowAttributes xgwa; - XImage *image; - int depth; - XGetWindowAttributes (dpy, window, &xgwa); + int chunk_size = 20, ii; + + if (st->draw_y == 0) + { + moire_init_1 (st); - xo = (random() % xgwa.width) - xgwa.width/2; - yo = (random() % xgwa.height) - xgwa.height/2; + XGetWindowAttributes (st->dpy, st->window, &st->xgwa); - depth = visual_depth(DefaultScreenOfDisplay(dpy), xgwa.visual); - image = XCreateImage (dpy, xgwa.visual, - depth, ZPixmap, 0, /* depth, format, offset */ - 0, xgwa.width, 1, 8, 0); /* data, w, h, pad, bpl */ + 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; - image->data = (char *) malloc (((xgwa.width + 1) * depth / 8) - * 2 /* uh, I dunno... */ - ); + st->depth = visual_depth(DefaultScreenOfDisplay(st->dpy), st->xgwa.visual); - for (y = 0; y < xgwa.height; y++) + 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 < 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); } - XPutImage (dpy, window, gc, image, 0, 0, 0, y, xgwa.width, 1); - XSync(dpy, False); + + if (st->draw_y + ii >= st->xgwa.height) + break; } - if (image->data) free(image->data); - image->data = 0; - XDestroyImage (image); + + 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) + { + st->draw_y = 0; + + destroy_xshm_image (st->dpy, st->draw_image, &st->shm_info); + st->draw_image = 0; + + return st->delay * 1000000; + } + + return st->delay * 10000; } -char *progclass = "Moire"; - -char *defaults [] = { - "Moire.background: blue", /* to placate SGI */ - "Moire.foreground: red", +static const char *moire_defaults [] = { + ".background: blue", + ".foreground: red", + "*fpsSolid: true", "*random: true", "*delay: 5", "*ncolors: 64", "*offset: 50", + "*useSHM: True", +#ifdef HAVE_MOBILE + "*ignoreRotation: True", +#endif 0 }; -XrmOptionDescRec options [] = { - { "-random", ".random", XrmoptionSepArg, 0 }, +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 }, + { "-shm", ".useSHM", XrmoptionNoArg, "True" }, + { "-no-shm", ".useSHM", XrmoptionNoArg, "False" }, { 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, True); - 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)