1 /* xscreensaver, Copyright (c) 2007 Jamie Zawinski <jwz@jwz.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
11 * cwaves -- languid sinusoidal colors.
14 #include "screenhack.h"
16 #include "xpm-pixmap.h"
18 #define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
29 XWindowAttributes xgwa;
44 cwaves_init (Display *dpy, Window window)
48 state *st = (state *) calloc (1, sizeof (*st));
52 XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
54 st->debug_p = get_boolean_resource (dpy, "debug", "Boolean");
55 st->scale = get_integer_resource (dpy, "scale", "Integer");
56 if (st->scale <= 0) st->scale = 1;
57 st->ncolors = get_integer_resource (dpy, "ncolors", "Integer");
58 if (st->ncolors < 4) st->ncolors = 4;
59 st->colors = (XColor *) malloc (sizeof(*st->colors) * (st->ncolors+1));
60 make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
61 st->colors, &st->ncolors,
64 st->gc = XCreateGC (st->dpy, st->window, 0, &gcv);
65 st->delay = get_integer_resource (dpy, "delay", "Integer");
67 st->nwaves = get_integer_resource (dpy, "nwaves", "Integer");
68 st->waves = (wave *) calloc (st->nwaves, sizeof(*st->waves));
70 for (i = 0; i < st->nwaves; i++)
72 st->waves[i].scale = frand(0.03) + 0.005;
73 st->waves[i].offset = frand(M_PI);
74 st->waves[i].delta = (BELLRAND(2)-1) / 15.0;
82 cwaves_draw (Display *dpy, Window window, void *closure)
84 state *st = (state *) closure;
87 for (i = 0; i < st->nwaves; i++)
88 st->waves[i].offset += st->waves[i].delta;
90 for (x = 0; x < st->xgwa.width; x += st->scale)
94 for (i = 0; i < st->nwaves; i++)
95 v += cos ((x * st->waves[i].scale) - st->waves[i].offset);
98 j = st->ncolors * (v/2 + 0.5);
99 if (j < 0 || j >= st->ncolors) abort();
100 XSetForeground (st->dpy, st->gc, st->colors[j].pixel);
101 XFillRectangle (st->dpy, st->window, st->gc,
102 x, 0, st->scale, st->xgwa.height);
107 int wh = (st->xgwa.height / (st->nwaves + 1)) * 0.9;
109 XSetLineAttributes (st->dpy, st->gc, 2, LineSolid, CapRound, JoinRound);
110 XSetForeground (st->dpy, st->gc, BlackPixelOfScreen (st->xgwa.screen));
111 for (i = 0; i < st->nwaves; i++)
113 int y = st->xgwa.height * i / (st->nwaves + 1);
114 int ox = -1, oy = -1;
116 for (x = 0; x < st->xgwa.width; x += st->scale)
120 v = cos ((x * st->waves[i].scale) - st->waves[i].offset);
123 yy = y + wh/2 + (wh * v);
126 XDrawLine (st->dpy, st->window, st->gc, ox, oy, x, yy);
133 int y = st->xgwa.height * i / (st->nwaves + 1);
134 int ox = -1, oy = -1;
136 for (x = 0; x < st->xgwa.width; x += st->scale)
140 for (i = 0; i < st->nwaves; i++)
141 v += cos ((x * st->waves[i].scale) - st->waves[i].offset);
145 yy = y + wh/2 + (wh * v);
148 XDrawLine (st->dpy, st->window, st->gc, ox, oy, x, yy);
160 cwaves_reshape (Display *dpy, Window window, void *closure,
161 unsigned int w, unsigned int h)
163 state *st = (state *) closure;
164 XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
168 cwaves_event (Display *dpy, Window window, void *closure, XEvent *event)
170 state *st = (state *) closure;
171 if (event->type == ButtonPress)
173 make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
174 st->colors, &st->ncolors,
182 cwaves_free (Display *dpy, Window window, void *closure)
187 static const char *cwaves_defaults [] = {
188 ".background: black",
189 ".foreground: white",
198 static XrmOptionDescRec cwaves_options [] = {
199 { "-delay", ".delay", XrmoptionSepArg, 0 },
200 { "-waves", ".nwaves", XrmoptionSepArg, 0 },
201 { "-colors", ".ncolors", XrmoptionSepArg, 0 },
202 { "-scale", ".scale", XrmoptionSepArg, 0 },
203 { "-debug", ".debug", XrmoptionNoArg, "True" },
208 XSCREENSAVER_MODULE ("CWaves", cwaves)