http://nanonyme.dy.fi/mirrors/hvl/distfiles/xscreensaver/xscreensaver-5.03.tar.gz
[xscreensaver] / hacks / cwaves.c
diff --git a/hacks/cwaves.c b/hacks/cwaves.c
new file mode 100644 (file)
index 0000000..cb72a07
--- /dev/null
@@ -0,0 +1,150 @@
+/* xscreensaver, Copyright (c) 2007 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * cwaves -- languid sinusoidal colors.
+ */
+
+#include "screenhack.h"
+#include <stdio.h>
+#include "xpm-pixmap.h"
+
+#define ALIVE   1
+#define CHANGED 2
+#define UNDEAD  4
+
+typedef struct {
+  double scale;
+  double offset;
+  double delta;
+} wave;
+
+typedef struct {
+  Display *dpy;
+  Window window;
+  XWindowAttributes xgwa;
+  GC gc;
+  int delay;
+  int ncolors;
+  XColor *colors;
+
+  int nwaves;
+  wave *waves;
+
+} state;
+
+
+static void *
+cwaves_init (Display *dpy, Window window)
+{
+  int i;
+  XGCValues gcv;
+  state *st = (state *) calloc (1, sizeof (*st));
+
+  st->dpy = dpy;
+  st->window = window;
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+
+  st->ncolors = get_integer_resource (dpy, "ncolors", "Integer");
+  if (st->ncolors < 4) st->ncolors = 4;
+  st->colors = (XColor *) malloc (sizeof(*st->colors) * (st->ncolors+1));
+  make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
+                        st->colors, &st->ncolors,
+                        True, 0, False);
+
+  st->gc = XCreateGC (st->dpy, st->window, 0, &gcv);
+  st->delay = get_integer_resource (dpy, "delay", "Integer");
+
+  st->nwaves  = get_integer_resource (dpy, "nwaves", "Integer");
+  st->waves  = (wave *) calloc (st->nwaves,  sizeof(*st->waves));
+
+  for (i = 0; i < st->nwaves; i++)
+    {
+      st->waves[i].scale  = frand(0.05) + 0.005;
+      st->waves[i].offset = frand(M_PI);
+      st->waves[i].delta  = (frand(2) - 1) / 20.0;
+    }
+
+  return st;
+}
+
+
+static unsigned long
+cwaves_draw (Display *dpy, Window window, void *closure)
+{
+  state *st = (state *) closure;
+  int i, x;
+
+  for (i = 0; i < st->nwaves; i++)
+    st->waves[i].offset += st->waves[i].delta;
+
+  for (x = 0; x < st->xgwa.width; x++)
+    {
+      double v = 0;
+      int j;
+      for (i = 0; i < st->nwaves; i++)
+        v += cos ((x * st->waves[i].scale) - st->waves[i].offset);
+      v /= st->nwaves;
+
+      j = st->ncolors * (v/2 + 0.5);
+      if (j < 0 || j >= st->ncolors) abort();
+      XSetForeground (st->dpy, st->gc, st->colors[j].pixel);
+      XDrawLine (st->dpy, st->window, st->gc, x, 0, x, st->xgwa.height);
+    }
+
+  return st->delay;
+}
+
+
+static void
+cwaves_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+  state *st = (state *) closure;
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+}
+
+static Bool
+cwaves_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  state *st = (state *) closure;
+  if (event->type == ButtonPress)
+    {
+      make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
+                            st->colors, &st->ncolors,
+                            True, 0, False);
+      return True;
+    }
+  return False;
+}
+
+static void
+cwaves_free (Display *dpy, Window window, void *closure)
+{
+}
+
+
+static const char *cwaves_defaults [] = {
+  ".background:                   black",
+  ".foreground:                   white",
+  "*ncolors:              600",
+  "*nwaves:               15",
+  "*delay:                20000",
+  0
+};
+
+static XrmOptionDescRec cwaves_options [] = {
+  { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { "-waves",          ".nwaves",              XrmoptionSepArg, 0 },
+  { "-colors",         ".ncolors",             XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+
+XSCREENSAVER_MODULE ("CWaves", cwaves)