X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fmoire2.c;h=0b6c9cd62b80d46ebfc16080973441df0b668131;hb=aa75c7476aeaa84cf3abc192b376a8b03c325213;hp=463478c674a6429287cf4e92dd2c131e646ec5e7;hpb=6bb727f03bff0389fbb1349d7df4c9d8d7532959;p=xscreensaver diff --git a/hacks/moire2.c b/hacks/moire2.c index 463478c6..0b6c9cd6 100644 --- a/hacks/moire2.c +++ b/hacks/moire2.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 @@ -10,160 +10,182 @@ */ #include "screenhack.h" -#include -#include - -static int ncolors, color_shift; -static XColor *colors = 0; -static int fg_pixel, bg_pixel; -static Pixmap p0 = 0, p1 = 0, p2 = 0, p3 = 0; -static GC copy_gc = 0, erase_gc = 0, window_gc = 0; -static int width, height, size; -static int x1, x2, y1, y2, x3, y3; -static int dx1, dx2, dx3, dy1, dy2, dy3; -static int othickness, thickness; -static Bool do_three; + +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION +# include "xdbe.h" +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + +struct state { + Display *dpy; + Window window; + + int ncolors; + XColor *colors; + int fg_pixel, bg_pixel; + Pixmap p0, p1, p2, p3; + GC copy_gc, erase_gc, window_gc; + int width, height, size; + int x1, x2, y1, y2, x3, y3; + int dx1, dx2, dx3, dy1, dy2, dy3; + int othickness, thickness; + Bool do_three; +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + XdbeBackBuffer back_buf; +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + + Bool flip_a, flip_b; + int pix; + int delay, color_shift; + + int reset; + int iterations, iteration; +}; static void -init_moire2 (Display *dpy, Window window) +moire2_init_1 (struct state *st) { XWindowAttributes xgwa; - XGetWindowAttributes (dpy, window, &xgwa); + XGetWindowAttributes (st->dpy, st->window, &xgwa); - othickness = get_integer_resource("thickness", "Thickness"); + st->othickness = get_integer_resource(st->dpy, "thickness", "Thickness"); if (mono_p) - ncolors = 2; + st->ncolors = 2; else - ncolors = get_integer_resource ("colors", "Colors"); - if (ncolors < 2) ncolors = 2; - if (ncolors <= 2) mono_p = True; + st->ncolors = get_integer_resource (st->dpy, "colors", "Colors"); + if (st->ncolors < 2) st->ncolors = 2; + if (st->ncolors <= 2) mono_p = True; if (mono_p) - colors = 0; + st->colors = 0; else - colors = (XColor *) malloc(sizeof(*colors) * (ncolors+1)); + st->colors = (XColor *) malloc(sizeof(*st->colors) * (st->ncolors+1)); if (mono_p) ; else - make_smooth_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors, + make_smooth_colormap (xgwa.screen, xgwa.visual, xgwa.colormap, + st->colors, &st->ncolors, True, 0, True); - bg_pixel = get_pixel_resource("background", "Background", dpy, - xgwa.colormap); - fg_pixel = get_pixel_resource("foreground", "Foreground", dpy, - xgwa.colormap); + st->bg_pixel = get_pixel_resource(st->dpy, + xgwa.colormap, "background", "Background"); + st->fg_pixel = get_pixel_resource(st->dpy, + xgwa.colormap, "foreground", "Foreground"); + +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + st->back_buf = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined); +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ } static void -reset_moire2 (Display *dpy, Window window) +reset_moire2 (struct state *st) { GC gc; XWindowAttributes xgwa; XGCValues gcv; Bool xor; - XGetWindowAttributes (dpy, window, &xgwa); + XGetWindowAttributes (st->dpy, st->window, &xgwa); - do_three = (0 == (random() % 3)); + st->do_three = (0 == (random() % 3)); - width = xgwa.width; - height = xgwa.height; - size = width > height ? width : height; + st->width = xgwa.width; + st->height = xgwa.height; + st->size = st->width > st->height ? st->width : st->height; - if (p0) XFreePixmap(dpy, p0); - if (p1) XFreePixmap(dpy, p1); - if (p2) XFreePixmap(dpy, p2); - if (p3) XFreePixmap(dpy, p3); + if (st->p0) XFreePixmap(st->dpy, st->p0); + if (st->p1) XFreePixmap(st->dpy, st->p1); + if (st->p2) XFreePixmap(st->dpy, st->p2); + if (st->p3) XFreePixmap(st->dpy, st->p3); - p0 = XCreatePixmap(dpy, window, width, height, 1); - p1 = XCreatePixmap(dpy, window, width*2, height*2, 1); - p2 = XCreatePixmap(dpy, window, width*2, height*2, 1); - if (do_three) - p3 = XCreatePixmap(dpy, window, width*2, height*2, 1); + st->p0 = XCreatePixmap(st->dpy, st->window, st->width, st->height, 1); + st->p1 = XCreatePixmap(st->dpy, st->window, st->width*2, st->height*2, 1); + st->p2 = XCreatePixmap(st->dpy, st->window, st->width*2, st->height*2, 1); + if (st->do_three) + st->p3 = XCreatePixmap(st->dpy, st->window, st->width*2, st->height*2, 1); else - p3 = 0; + st->p3 = 0; - thickness = (othickness > 0 ? othickness : (1 + (random() % 4))); + st->thickness = (st->othickness > 0 ? st->othickness : (1 + (random() % 4))); gcv.foreground = 0; - gcv.line_width = (thickness == 1 ? 0 : thickness); - gc = XCreateGC (dpy, p1, GCForeground|GCLineWidth, &gcv); + gcv.line_width = (st->thickness == 1 ? 0 : st->thickness); + gc = XCreateGC (st->dpy, st->p1, GCForeground|GCLineWidth, &gcv); - XFillRectangle(dpy, p1, gc, 0, 0, width*2, height*2); - XFillRectangle(dpy, p2, gc, 0, 0, width*2, height*2); - if (do_three) - XFillRectangle(dpy, p3, gc, 0, 0, width*2, height*2); + XFillRectangle(st->dpy, st->p1, gc, 0, 0, st->width*2, st->height*2); + XFillRectangle(st->dpy, st->p2, gc, 0, 0, st->width*2, st->height*2); + if (st->do_three) + XFillRectangle(st->dpy, st->p3, gc, 0, 0, st->width*2, st->height*2); - XSetForeground(dpy, gc, 1); + XSetForeground(st->dpy, gc, 1); - xor = (do_three || (thickness == 1) || (random() & 1)); + xor = (st->do_three || (st->thickness == 1) || (random() & 1)); { int i, ii, maxx, maxy; #define FROB(P) do { \ - maxx = (size*4); \ - maxy = (size*4); \ + maxx = (st->size*4); \ + maxy = (st->size*4); \ if (0 == (random() % 5)) { \ float f = 1.0 + frand(0.05); \ if (random() & 1) maxx *= f; \ else maxy *= f; \ } \ - ii = (thickness + 1 + (xor ? 0 : 1) + (random() % (4 * thickness))); \ - for (i = 0; i < (size*2); i += ii) \ - XDrawArc(dpy, (P), gc, i-size, i-size, maxx-i-i, maxy-i-i, 0, 360*64); \ + ii = (st->thickness + 1 + (xor ? 0 : 1) + (random() % (4 * st->thickness))); \ + for (i = 0; i < (st->size*2); i += ii) \ + XDrawArc(st->dpy, (P), gc, i-st->size, i-st->size, maxx-i-i, maxy-i-i, 0, 360*64); \ if (0 == (random() % 5)) \ { \ - XSetFunction(dpy, gc, GXxor); \ - XFillRectangle(dpy, (P), gc, 0, 0, width*2, height*2); \ - XSetFunction(dpy, gc, GXcopy); \ + XSetFunction(st->dpy, gc, GXxor); \ + XFillRectangle(st->dpy, (P), gc, 0, 0, st->width*2, st->height*2); \ + XSetFunction(st->dpy, gc, GXcopy); \ } \ } while(0) - FROB(p1); - FROB(p2); - if (do_three) - FROB(p3); + FROB(st->p1); + FROB(st->p2); + if (st->do_three) + FROB(st->p3); #undef FROB } - XFreeGC(dpy, gc); + XFreeGC(st->dpy, gc); - if (copy_gc) XFreeGC(dpy, copy_gc); + if (st->copy_gc) XFreeGC(st->dpy, st->copy_gc); gcv.function = (xor ? GXxor : GXor); gcv.foreground = 1; gcv.background = 0; - copy_gc = XCreateGC (dpy, p0, GCFunction|GCForeground|GCBackground, &gcv); + st->copy_gc = XCreateGC (st->dpy, st->p0, GCFunction|GCForeground|GCBackground, &gcv); gcv.foreground = 0; - if (erase_gc) XFreeGC(dpy, erase_gc); - erase_gc = XCreateGC (dpy, p0, GCForeground, &gcv); + if (st->erase_gc) XFreeGC(st->dpy, st->erase_gc); + st->erase_gc = XCreateGC (st->dpy, st->p0, GCForeground, &gcv); - gcv.foreground = fg_pixel; - gcv.background = bg_pixel; - if (window_gc) XFreeGC(dpy, window_gc); - window_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv); + gcv.foreground = st->fg_pixel; + gcv.background = st->bg_pixel; + if (st->window_gc) XFreeGC(st->dpy, st->window_gc); + st->window_gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv); #define FROB(N,DN,MAX) \ N = (MAX/2) + (random() % MAX); \ - DN = ((1 + (random() % (7*thickness))) * ((random() & 1) ? 1 : -1)) - - FROB(x1,dx1,width); - FROB(x2,dx2,width); - FROB(x3,dx3,width); - FROB(y1,dy1,height); - FROB(y2,dy2,height); - FROB(y3,dy3,height); + DN = ((1 + (random() % (7*st->thickness))) * ((random() & 1) ? 1 : -1)) + + FROB(st->x1,st->dx1,st->width); + FROB(st->x2,st->dx2,st->width); + FROB(st->x3,st->dx3,st->width); + FROB(st->y1,st->dy1,st->height); + FROB(st->y2,st->dy2,st->height); + FROB(st->y3,st->dy3,st->height); #undef FROB } static void -moire2 (Display *dpy, Window window) +moire2 (struct state *st) { #define FROB(N,DN,MAX) \ N += DN; \ @@ -173,106 +195,161 @@ moire2 (Display *dpy, Window window) else if (0 == (random() % 50)) \ DN += (DN <= -20 ? 1 : (DN >= 20 ? -1 : ((random() & 1) ? 1 : -1))) - FROB(x1,dx1,width); - FROB(x2,dx2,width); - FROB(x3,dx3,width); - FROB(y1,dy1,height); - FROB(y2,dy2,height); - FROB(y3,dy3,height); + FROB(st->x1,st->dx1,st->width); + FROB(st->x2,st->dx2,st->width); + FROB(st->x3,st->dx3,st->width); + FROB(st->y1,st->dy1,st->height); + FROB(st->y2,st->dy2,st->height); + FROB(st->y3,st->dy3,st->height); #undef FROB - XFillRectangle(dpy, p0, erase_gc, 0, 0, width, height); - XCopyArea(dpy, p1, p0, copy_gc, x1, y1, width, height, 0, 0); - XCopyArea(dpy, p2, p0, copy_gc, x2, y2, width, height, 0, 0); - if (do_three) - XCopyArea(dpy, p3, p0, copy_gc, x3, y3, width, height, 0, 0); + XFillRectangle(st->dpy, st->p0, st->erase_gc, 0, 0, st->width, st->height); + XCopyArea(st->dpy, st->p1, st->p0, st->copy_gc, st->x1, st->y1, st->width, st->height, 0, 0); + XCopyArea(st->dpy, st->p2, st->p0, st->copy_gc, st->x2, st->y2, st->width, st->height, 0, 0); + if (st->do_three) + XCopyArea(st->dpy, st->p3, st->p0, st->copy_gc, st->x3, st->y3, st->width, st->height, 0, 0); - XSync(dpy, False); - XCopyPlane(dpy, p0, window, window_gc, 0, 0, width, height, 0, 0, 1L); - XSync(dpy, False); +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + if (st->back_buf) + { + XdbeSwapInfo info[1]; + info[0].swap_window = st->window; + info[0].swap_action = XdbeUndefined; + XCopyPlane (st->dpy, st->p0, st->back_buf, st->window_gc, 0, 0, st->width, st->height, 0, 0, 1L); + XdbeSwapBuffers (st->dpy, info, 1); + } + else +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + XCopyPlane (st->dpy, st->p0, st->window, st->window_gc, 0, 0, st->width, st->height, 0, 0, 1L); #if 0 - XCopyPlane(dpy, p1, window, window_gc, (width*2)/3, (height*2)/3, - width/2, height/2, - 0, height/2, 1L); - XCopyPlane(dpy, p2, window, window_gc, (width*2)/3, (height*2)/3, - width/2, height/2, - width/2, height/2, 1L); + XCopyPlane(st->dpy, st->p1, st->window, st->window_gc, (st->width*2)/3, (st->height*2)/3, + st->width/2, st->height/2, + 0, st->height/2, 1L); + XCopyPlane(st->dpy, st->p2, st->window, st->window_gc, (st->width*2)/3, (st->height*2)/3, + st->width/2, st->height/2, + st->width/2, st->height/2, 1L); #endif } - -char *progclass = "Moire2"; +static void * +moire2_init (Display *dpy, Window window) +{ + struct state *st = (struct state *) calloc (1, sizeof(*st)); + st->dpy = dpy; + st->window = window; + st->reset = 1; + + st->delay = get_integer_resource (st->dpy, "delay", "Integer"); + st->color_shift = get_integer_resource (st->dpy, "colorShift", "Integer"); + + if (st->color_shift <= 0) st->color_shift = 1; + moire2_init_1 (st); + return st; +} + +static unsigned long +moire2_draw (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + + if (st->reset) + { + st->reset = 0; + + st->iteration = 0; + st->iterations = 30 + (random() % 70) + (random() % 70); + reset_moire2 (st); + + st->flip_a = mono_p ? False : (random() & 1); + st->flip_b = mono_p ? False : (random() & 1); + + if (st->flip_b) + { + XSetForeground(st->dpy, st->window_gc, st->bg_pixel); + XSetBackground(st->dpy, st->window_gc, st->fg_pixel); + } + else + { + XSetForeground(st->dpy, st->window_gc, st->fg_pixel); + XSetBackground(st->dpy, st->window_gc, st->bg_pixel); + } + } + + if (!mono_p) + { + st->pix++; + st->pix = st->pix % st->ncolors; + + if (st->flip_a) + XSetBackground(st->dpy, st->window_gc, st->colors[st->pix].pixel); + else + XSetForeground(st->dpy, st->window_gc, st->colors[st->pix].pixel); + } + + + moire2 (st); + st->iteration++; + if (st->iteration >= st->color_shift) + { + st->iteration = 0; + st->iterations--; + if (st->iterations <= 0) + st->reset = 1; + } + + return st->delay; +} + +static void +moire2_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + struct state *st = (struct state *) closure; + st->reset = 1; +} + +static Bool +moire2_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; +} + +static void +moire2_free (Display *dpy, Window window, void *closure) +{ +} -char *defaults [] = { - "Moire2.background: black", /* to placate SGI */ - "Moire2.foreground: white", +static const char *moire2_defaults [] = { + ".background: black", + ".foreground: white", "*delay: 50000", "*thickness: 0", "*colors: 150", "*colorShift: 5", +#ifdef HAVE_MOBILE + "*ignoreRotation: True", +#endif + +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + /* Off by default, since it slows it down a lot, and the flicker isn't really + all that bad without it... Or rather, it flickers just as badly with it. + The XFree86 implementation of the XDBE extension totally blows! There is + just *no* excuse for the "swap buffers" operation to flicker like it does. + */ + "*useDBE: False", +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + 0 }; -XrmOptionDescRec options [] = { +static XrmOptionDescRec moire2_options [] = { { "-delay", ".delay", XrmoptionSepArg, 0 }, { "-ncolors", ".colors", XrmoptionSepArg, 0 }, { "-thickness", ".thickness", XrmoptionSepArg, 0 }, { 0, 0, 0, 0 } }; -void -screenhack (Display *dpy, Window window) -{ - int delay = get_integer_resource ("delay", "Integer"); - int color_shift = get_integer_resource ("colorShift", "Integer"); - int pix = 0; - Bool flip_a, flip_b; - - if (color_shift <= 0) color_shift = 1; - init_moire2 (dpy, window); - while (1) - { - int iterations = 30 + (random() % 70) + (random() % 70); - reset_moire2 (dpy, window); - - flip_a = mono_p ? False : (random() & 1); - flip_b = mono_p ? False : (random() & 1); - - if (flip_b) - { - XSetForeground(dpy, window_gc, bg_pixel); - XSetBackground(dpy, window_gc, fg_pixel); - } - else - { - XSetForeground(dpy, window_gc, fg_pixel); - XSetBackground(dpy, window_gc, bg_pixel); - } - - while (--iterations > 0) - { - int i; - - if (!mono_p) - { - pix++; - pix = pix % ncolors; - - if (flip_a) - XSetBackground(dpy, window_gc, colors[pix].pixel); - else - XSetForeground(dpy, window_gc, colors[pix].pixel); - } - - for (i = 0; i < color_shift; i++) - { - moire2 (dpy, window); - if (delay) - usleep(delay); - } - } - } -} +XSCREENSAVER_MODULE ("Moire2", moire2)