X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Flcdscrub.c;h=e7f220c08aa28e242a2a1e1e574409ae3239ea61;hb=dba664f31aa87285db4d76cf8c5e66335299703a;hp=700de61ec99c36e0ef5a99986dad971ca0d1748d;hpb=6b1c86cf395f59389e4ece4ea8f4bea2c332745b;p=xscreensaver diff --git a/hacks/lcdscrub.c b/hacks/lcdscrub.c index 700de61e..e7f220c0 100644 --- a/hacks/lcdscrub.c +++ b/hacks/lcdscrub.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 2008 Jamie Zawinski +/* xscreensaver, Copyright (c) 2008-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 @@ -15,6 +15,9 @@ #include "screenhack.h" +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + struct state { Display *dpy; Window window; @@ -23,15 +26,31 @@ struct state { VERT_W, VERT_B, DIAG_W, DIAG_B, WHITE, BLACK, + RGB, END } mode; + unsigned int enabled_mask; int count; - GC fg, bg; + GC fg, bg, bg2; + int color_tick; int delay; int spread; int cycles; }; +static void +pick_mode (struct state *st) +{ + st->count = 0; + while (1) + { + if (++st->mode == END) + st->mode = 0; + if (st->enabled_mask & (1 << st->mode)) + break; + } +} + static void * lcdscrub_init (Display *dpy, Window window) { @@ -46,16 +65,39 @@ lcdscrub_init (Display *dpy, Window window) XGetWindowAttributes (st->dpy, st->window, &st->xgwa); gcv.foreground = BlackPixelOfScreen (st->xgwa.screen); gcv.background = WhitePixelOfScreen (st->xgwa.screen); - st->bg = XCreateGC (st->dpy, st->window, GCForeground, &gcv); + st->bg = XCreateGC (st->dpy, st->window, GCForeground, &gcv); + st->bg2 = XCreateGC (st->dpy, st->window, GCForeground, &gcv); gcv.foreground = WhitePixelOfScreen (st->xgwa.screen); gcv.background = BlackPixelOfScreen (st->xgwa.screen); st->fg = XCreateGC (st->dpy, st->window, GCForeground, &gcv); #ifdef HAVE_COCOA - jwxyz_XSetAntiAliasing (st->dpy, st->fg, False); - jwxyz_XSetAntiAliasing (st->dpy, st->bg, False); + jwxyz_XSetAntiAliasing (st->dpy, st->fg, False); + jwxyz_XSetAntiAliasing (st->dpy, st->bg, False); + jwxyz_XSetAntiAliasing (st->dpy, st->bg2, False); #endif + st->enabled_mask = 0; +# define PREF(R,F) \ + if (get_boolean_resource (st->dpy, R, "Mode")) st->enabled_mask |= (1 << F) + PREF("modeHW", HORIZ_W); + PREF("modeHB", HORIZ_B); + PREF("modeVW", VERT_W); + PREF("modeVB", VERT_B); + PREF("modeDW", DIAG_W); + PREF("modeDB", DIAG_B); + PREF("modeW", WHITE); + PREF("modeB", BLACK); + PREF("modeRGB", RGB); +# undef PREF + if (! st->enabled_mask) + { + fprintf (stderr, "%s: no modes enabled\n", progname); + exit (1); + } + + pick_mode (st); + return st; } @@ -94,9 +136,35 @@ lcdscrub_draw (Display *dpy, Window window, void *closure) XDrawLine (st->dpy, st->window, fg, 0, i, st->xgwa.height, i + st->xgwa.height); break; + case RGB: + { + int scale = 10 * 8; /* 8 sec */ + static const unsigned short colors[][3] = { + { 0xFFFF, 0x0000, 0x0000 }, + { 0x0000, 0xFFFF, 0x0000 }, + { 0x0000, 0x0000, 0xFFFF }, + { 0xFFFF, 0xFFFF, 0x0000 }, + { 0xFFFF, 0x0000, 0xFFFF }, + { 0x0000, 0xFFFF, 0xFFFF }, + { 0xFFFF, 0xFFFF, 0xFFFF }, + { 0x0000, 0x0000, 0x0000 }, + }; + static unsigned long last = 0; + XColor xc; + bg = st->bg2; + xc.red = colors[st->color_tick / scale][0]; + xc.green = colors[st->color_tick / scale][1]; + xc.blue = colors[st->color_tick / scale][2]; + if (last) XFreeColors (st->dpy, st->xgwa.colormap, &last, 1, 0); + XAllocColor (st->dpy, st->xgwa.colormap, &xc); + last = xc.pixel; + XSetForeground (st->dpy, bg, xc.pixel); + st->color_tick = (st->color_tick + 1) % (countof(colors) * scale); + /* fall through */ + } case WHITE: case BLACK: - XFillRectangle (st->dpy, st->window, fg, 0, 0, + XFillRectangle (st->dpy, st->window, bg, 0, 0, st->xgwa.width, st->xgwa.height); break; default: @@ -107,11 +175,7 @@ lcdscrub_draw (Display *dpy, Window window, void *closure) st->count++; if (st->count > st->spread * st->cycles) - { - st->count = 0; - if (++st->mode == END) - st->mode = 0; - } + pick_mode (st); return st->delay; } @@ -134,6 +198,7 @@ lcdscrub_free (Display *dpy, Window window, void *closure) struct state *st = (struct state *) closure; XFreeGC (dpy, st->fg); XFreeGC (dpy, st->bg); + XFreeGC (dpy, st->bg2); free (st); } @@ -144,6 +209,15 @@ static const char *lcdscrub_defaults [] = { "*delay: 100000", "*spread: 8", "*cycles: 60", + "*modeHW: True", + "*modeHB: True", + "*modeVW: True", + "*modeVB: True", + "*modeDW: True", + "*modeDB: True", + "*modeW: True", + "*modeB: True", + "*modeRGB: True", 0 }; @@ -151,6 +225,15 @@ static XrmOptionDescRec lcdscrub_options [] = { { "-delay", ".delay", XrmoptionSepArg, 0 }, { "-spread", ".spread", XrmoptionSepArg, 0 }, { "-cycles", ".cycles", XrmoptionSepArg, 0 }, + { "-no-hw", ".modeHW", XrmoptionNoArg, "False" }, + { "-no-hb", ".modeHB", XrmoptionNoArg, "False" }, + { "-no-vw", ".modeVW", XrmoptionNoArg, "False" }, + { "-no-vb", ".modeVB", XrmoptionNoArg, "False" }, + { "-no-dw", ".modeDW", XrmoptionNoArg, "False" }, + { "-no-db", ".modeDB", XrmoptionNoArg, "False" }, + { "-no-w", ".modeW", XrmoptionNoArg, "False" }, + { "-no-b", ".modeB", XrmoptionNoArg, "False" }, + { "-no-rgb", ".modeRGB", XrmoptionNoArg, "False" }, { 0, 0, 0, 0 } };