X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fpopsquares.c;h=0bea52ef6c9145aff1b4043d9bf2538d6b76b983;hp=8660f9697e9d418cd86e43dc8fc7d1bd0887cc18;hb=07faf451b99879183ed7e909e43a0e065be1ee7f;hpb=4cecfc89e5e889c7232693897c06168fb378bd5c diff --git a/hacks/popsquares.c b/hacks/popsquares.c index 8660f969..0bea52ef 100644 --- a/hacks/popsquares.c +++ b/hacks/popsquares.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003 Levi Burton +/* Copyright (c) 2003 Levi Burton * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -21,7 +21,7 @@ typedef struct _square { int color; } square; -void +static void randomize_square_colors(square *squares, int nsquares, int ncolors) { int i; @@ -30,166 +30,208 @@ randomize_square_colors(square *squares, int nsquares, int ncolors) s[i].color = random() % ncolors; } - -char *progclass = "popsquares"; -char *defaults [] = { - ".background: blue", - ".foreground: blue4", - "*delay: 25000", - "*subdivision: 5", - "*border: 1", - "*ncolors: 128", - "*twitch: False", - "*doubleBuffer: False", +struct state { + Display *dpy; + Window window; + + int delay, subdivision, border, ncolors, twitch, dbuf; + XWindowAttributes xgwa; + GC gc; + XColor *colors; + int sw, sh, gw, gh, nsquares; + square *squares; + Pixmap b, ba, bb; #ifdef HAVE_DOUBLE_BUFFER_EXTENSION - "*useDBE: True", - "*useDBEClear: True", + XdbeBackBuffer backb; #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - 0 -}; - -XrmOptionDescRec options [] = { - { "-fg", ".foreground", XrmoptionSepArg, 0}, - { "-bg", ".background", XrmoptionSepArg, 0}, - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-subdivision", ".subdivision", XrmoptionSepArg, 0 }, - { "-border", ".border", XrmoptionSepArg, 0}, - { "-ncolors", ".ncolors", XrmoptionSepArg, 0 }, - { "-twitch", ".twitch", XrmoptionNoArg, "True" }, - { "-no-twitch", ".twitch", XrmoptionNoArg, "False" }, - { "-db", ".doubleBuffer", XrmoptionNoArg, "True" }, - { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" }, - { 0, 0, 0, 0 } }; -void -screenhack (Display *dpy, Window window) +static void * +popsquares_init (Display *dpy, Window window) { - int delay = get_integer_resource ("delay", "Integer"); - int subdivision = get_integer_resource("subdivision", "Integer"); - int border = get_integer_resource("border", "Integer"); - int ncolors = get_integer_resource("ncolors", "Integer"); - Bool twitch = get_boolean_resource("twitch", "Boolean"); - Bool dbuf = get_boolean_resource("doubleBuffer", "Boolean"); + struct state *st = (struct state *) calloc (1, sizeof(*st)); int x, y; - int sw, sh, gw, gh, nsquares = 0; double s1, v1, s2, v2 = 0; int h1, h2 = 0; /* Not sure how to use DBEClear */ - /* Bool dbeclear_p = get_boolean_resource("useDBEClear", "Boolean"); */ - XColor *colors = 0; + /* Bool dbeclear_p = get_boolean_resource(dpy, "useDBEClear", "Boolean"); */ XColor fg, bg; XGCValues gcv; - GC gc; - square *squares; - XWindowAttributes xgwa; - Pixmap b=0, ba=0, bb=0; -#ifdef HAVE_DOUBLE_BUFFER_EXTENSION - XdbeBackBuffer backb = 0; -#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - XGetWindowAttributes (dpy, window, &xgwa); + st->dpy = dpy; + st->window = window; + + st->delay = get_integer_resource (st->dpy, "delay", "Integer"); + st->subdivision = get_integer_resource(st->dpy, "subdivision", "Integer"); + st->border = get_integer_resource(st->dpy, "border", "Integer"); + st->ncolors = get_integer_resource(st->dpy, "ncolors", "Integer"); + st->twitch = get_boolean_resource(st->dpy, "twitch", "Boolean"); + st->dbuf = get_boolean_resource(st->dpy, "doubleBuffer", "Boolean"); + +# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ + st->dbuf = False; +# endif - fg.pixel = get_pixel_resource ("foreground", "Foreground", dpy, xgwa.colormap); - bg.pixel = get_pixel_resource ("background", "Background", dpy, xgwa.colormap); + XGetWindowAttributes (st->dpy, st->window, &st->xgwa); - XQueryColor (dpy, xgwa.colormap, &fg); - XQueryColor (dpy, xgwa.colormap, &bg); + fg.pixel = get_pixel_resource (st->dpy, st->xgwa.colormap, "foreground", "Foreground"); + bg.pixel = get_pixel_resource (st->dpy, st->xgwa.colormap, "background", "Background"); - sw = xgwa.width / subdivision; - sh = xgwa.height / subdivision; - gw = xgwa.width / sw; - gh = xgwa.height / sh; - nsquares = gw * gh; + XQueryColor (st->dpy, st->xgwa.colormap, &fg); + XQueryColor (st->dpy, st->xgwa.colormap, &bg); - gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv); + st->sw = st->xgwa.width / st->subdivision; + st->sh = st->xgwa.height / st->subdivision; + st->gw = st->sw ? st->xgwa.width / st->sw : 0; + st->gh = st->sh ? st->xgwa.height / st->sh : 0; + st->nsquares = st->gw * st->gh; - colors = (XColor *) calloc (ncolors, sizeof(XColor)); - squares = (square *) calloc (nsquares, sizeof(square)); + gcv.foreground = fg.pixel; + gcv.background = bg.pixel; + st->gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv); + + st->colors = (XColor *) calloc (st->ncolors, sizeof(XColor)); + st->squares = (square *) calloc (st->nsquares, sizeof(square)); rgb_to_hsv (fg.red, fg.green, fg.blue, &h1, &s1, &v1); rgb_to_hsv (bg.red, bg.green, bg.blue, &h2, &s2, &v2); - make_color_ramp (dpy, xgwa.colormap, + make_color_ramp (st->dpy, st->xgwa.colormap, h1, s1, v1, h2, s2, v2, - colors, &ncolors, /* would this be considered a value-result argument? */ + st->colors, &st->ncolors, /* would this be considered a value-result argument? */ True, True, False); - if (ncolors < 2) + if (st->ncolors < 2) { fprintf (stderr, "%s: insufficient colors!\n", progname); exit (1); } - for (y = 0; y < gh; y++) - for (x = 0; x < gw; x++) + for (y = 0; y < st->gh; y++) + for (x = 0; x < st->gw; x++) { - square *s = (square *) &squares[gw * y + x]; - s->w = sw; - s->h = sh; - s->x = x * sw; - s->y = y * sh; + square *s = (square *) &st->squares[st->gw * y + x]; + s->w = st->sw; + s->h = st->sh; + s->x = x * st->sw; + s->y = y * st->sh; } - randomize_square_colors(squares, nsquares, ncolors); + randomize_square_colors(st->squares, st->nsquares, st->ncolors); - if (dbuf) + if (st->dbuf) { #ifdef HAVE_DOUBLE_BUFFER_EXTENSION - b = xdbe_get_backbuffer (dpy, window, XdbeUndefined); - backb = b; + st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined); + st->backb = st->b; #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - if (!b) + if (!st->b) { - ba = XCreatePixmap (dpy, window, xgwa.width, xgwa.height, xgwa.depth); - bb = XCreatePixmap (dpy, window, xgwa.width, xgwa.height, xgwa.depth); - b = ba; + st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth); + st->bb = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height, st->xgwa.depth); + st->b = st->ba; } } else { - b = window; + st->b = st->window; } - while (1) - { - for (y = 0; y < gh; y++) - for (x = 0; x < gw; x++) + return st; +} + +static unsigned long +popsquares_draw (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + int x, y; + for (y = 0; y < st->gh; y++) + for (x = 0; x < st->gw; x++) + { + square *s = (square *) &st->squares[st->gw * y + x]; + XSetForeground (st->dpy, st->gc, st->colors[s->color].pixel); + XFillRectangle (st->dpy, st->b, st->gc, s->x, s->y, + st->border ? s->w - st->border : s->w, + st->border ? s->h - st->border : s->h); + s->color++; + if (s->color == st->ncolors) { - square *s = (square *) &squares[gw * y + x]; - XSetForeground (dpy, gc, colors[s->color].pixel); - XFillRectangle (dpy, b, gc, s->x, s->y, - border ? s->w - border : s->w, - border ? s->h - border : s->h); - s->color++; - if (s->color == ncolors) - { - if (twitch && ((random() % 4) == 0)) - randomize_square_colors (squares, nsquares, ncolors); - else - s->color = random() % ncolors; - } + if (st->twitch && ((random() % 4) == 0)) + randomize_square_colors (st->squares, st->nsquares, st->ncolors); + else + s->color = random() % st->ncolors; } + } #ifdef HAVE_DOUBLE_BUFFER_EXTENSION - if (backb) - { - XdbeSwapInfo info[1]; - info[0].swap_window = window; - info[0].swap_action = XdbeUndefined; - XdbeSwapBuffers (dpy, info, 1); - } - else + if (st->backb) + { + XdbeSwapInfo info[1]; + info[0].swap_window = st->window; + info[0].swap_action = XdbeUndefined; + XdbeSwapBuffers (st->dpy, info, 1); + } + else #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - if (dbuf) - { - XCopyArea (dpy, b, window, gc, 0, 0, - xgwa.width, xgwa.height, 0, 0); - b = (b == ba ? bb : ba); - } + if (st->dbuf) + { + XCopyArea (st->dpy, st->b, st->window, st->gc, 0, 0, + st->xgwa.width, st->xgwa.height, 0, 0); + st->b = (st->b == st->ba ? st->bb : st->ba); + } - XSync (dpy, False); - screenhack_handle_events (dpy); - if (delay) - usleep (delay); - } + return st->delay; +} + + +static void +popsquares_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ } + +static Bool +popsquares_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; +} + +static void +popsquares_free (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + free (st); +} + + +static const char *popsquares_defaults [] = { + ".background: #0000FF", + ".foreground: #00008B", + "*delay: 25000", + "*subdivision: 5", + "*border: 1", + "*ncolors: 128", + "*twitch: False", + "*doubleBuffer: False", +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + "*useDBE: True", + "*useDBEClear: True", +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + 0 +}; + +static XrmOptionDescRec popsquares_options [] = { + { "-fg", ".foreground", XrmoptionSepArg, 0}, + { "-bg", ".background", XrmoptionSepArg, 0}, + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-subdivision", ".subdivision", XrmoptionSepArg, 0 }, + { "-border", ".border", XrmoptionSepArg, 0}, + { "-ncolors", ".ncolors", XrmoptionSepArg, 0 }, + { "-twitch", ".twitch", XrmoptionNoArg, "True" }, + { "-no-twitch", ".twitch", XrmoptionNoArg, "False" }, + { "-db", ".doubleBuffer", XrmoptionNoArg, "True" }, + { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" }, + { 0, 0, 0, 0 } +}; + + +XSCREENSAVER_MODULE ("PopSquares", popsquares)