http://nanonyme.dy.fi/mirrors/hvl/distfiles/xscreensaver/xscreensaver-5.03.tar.gz
[xscreensaver] / hacks / cwaves.c
1 /* xscreensaver, Copyright (c) 2007 Jamie Zawinski <jwz@jwz.org>
2  *
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 
9  * implied warranty.
10  *
11  * cwaves -- languid sinusoidal colors.
12  */
13
14 #include "screenhack.h"
15 #include <stdio.h>
16 #include "xpm-pixmap.h"
17
18 #define ALIVE   1
19 #define CHANGED 2
20 #define UNDEAD  4
21
22 typedef struct {
23   double scale;
24   double offset;
25   double delta;
26 } wave;
27
28 typedef struct {
29   Display *dpy;
30   Window window;
31   XWindowAttributes xgwa;
32   GC gc;
33   int delay;
34   int ncolors;
35   XColor *colors;
36
37   int nwaves;
38   wave *waves;
39
40 } state;
41
42
43 static void *
44 cwaves_init (Display *dpy, Window window)
45 {
46   int i;
47   XGCValues gcv;
48   state *st = (state *) calloc (1, sizeof (*st));
49
50   st->dpy = dpy;
51   st->window = window;
52   XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
53
54   st->ncolors = get_integer_resource (dpy, "ncolors", "Integer");
55   if (st->ncolors < 4) st->ncolors = 4;
56   st->colors = (XColor *) malloc (sizeof(*st->colors) * (st->ncolors+1));
57   make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
58                         st->colors, &st->ncolors,
59                         True, 0, False);
60
61   st->gc = XCreateGC (st->dpy, st->window, 0, &gcv);
62   st->delay = get_integer_resource (dpy, "delay", "Integer");
63
64   st->nwaves  = get_integer_resource (dpy, "nwaves", "Integer");
65   st->waves  = (wave *) calloc (st->nwaves,  sizeof(*st->waves));
66
67   for (i = 0; i < st->nwaves; i++)
68     {
69       st->waves[i].scale  = frand(0.05) + 0.005;
70       st->waves[i].offset = frand(M_PI);
71       st->waves[i].delta  = (frand(2) - 1) / 20.0;
72     }
73
74   return st;
75 }
76
77
78 static unsigned long
79 cwaves_draw (Display *dpy, Window window, void *closure)
80 {
81   state *st = (state *) closure;
82   int i, x;
83
84   for (i = 0; i < st->nwaves; i++)
85     st->waves[i].offset += st->waves[i].delta;
86
87   for (x = 0; x < st->xgwa.width; x++)
88     {
89       double v = 0;
90       int j;
91       for (i = 0; i < st->nwaves; i++)
92         v += cos ((x * st->waves[i].scale) - st->waves[i].offset);
93       v /= st->nwaves;
94
95       j = st->ncolors * (v/2 + 0.5);
96       if (j < 0 || j >= st->ncolors) abort();
97       XSetForeground (st->dpy, st->gc, st->colors[j].pixel);
98       XDrawLine (st->dpy, st->window, st->gc, x, 0, x, st->xgwa.height);
99     }
100
101   return st->delay;
102 }
103
104
105 static void
106 cwaves_reshape (Display *dpy, Window window, void *closure, 
107                  unsigned int w, unsigned int h)
108 {
109   state *st = (state *) closure;
110   XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
111 }
112
113 static Bool
114 cwaves_event (Display *dpy, Window window, void *closure, XEvent *event)
115 {
116   state *st = (state *) closure;
117   if (event->type == ButtonPress)
118     {
119       make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
120                             st->colors, &st->ncolors,
121                             True, 0, False);
122       return True;
123     }
124   return False;
125 }
126
127 static void
128 cwaves_free (Display *dpy, Window window, void *closure)
129 {
130 }
131
132
133 static const char *cwaves_defaults [] = {
134   ".background:            black",
135   ".foreground:            white",
136   "*ncolors:               600",
137   "*nwaves:                15",
138   "*delay:                 20000",
139   0
140 };
141
142 static XrmOptionDescRec cwaves_options [] = {
143   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
144   { "-waves",           ".nwaves",              XrmoptionSepArg, 0 },
145   { "-colors",          ".ncolors",             XrmoptionSepArg, 0 },
146   { 0, 0, 0, 0 }
147 };
148
149
150 XSCREENSAVER_MODULE ("CWaves", cwaves)