http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / whirlygig.c
index 118d7dd961c1a49a10513dd1d93f00c4959c9307..d4205bf8b141c3165b2b0ff028ec8e5dbae93900 100644 (file)
@@ -12,6 +12,7 @@
  *  by the beauty of the shapes one receives when playing with sine waves
  *  Here is a little experiment to show that beauty is simple
  */
+
 #include <stdio.h>
 #include <math.h>
 #include "screenhack.h"
@@ -41,98 +42,62 @@ struct info {
     double xoffset;
     double yoffset;
     double offset_period;
-    int wrap;
+    Bool wrap;
 };
 
 enum object_mode {
     spin_mode, funky_mode, circle_mode, linear_mode, test_mode, fun_mode, innie_mode, lissajous_mode
-} mode;
-
-static void explain(int, int, struct info *, Display *, Window, GC);
-static void draw_explain_string(int, int, Display *, Window, GC);
-static void spin(unsigned long int, struct info *, int *, int);
-static void funky(unsigned long int, struct info *, int *, int);
-static void circle(unsigned long int, struct info *, int *, int);
-static void fun(unsigned long int, struct info *, int *, int);
-static void linear(unsigned long int, struct info *, int *, int);
-static void lissajous(unsigned long int, struct info *, int *, int);
-static void test(unsigned long int, struct info *, int *, int);
-static void innie(unsigned long int, struct info *, int *, int, double);
-
-XColor colors[NCOLORS];
-int ncolors = NCOLORS;
-char *progclass = "Whirlygig";
-
-char *defaults [] = {
-  ".background: black",
-  ".foreground: white",
-  "*xspeed: 1.0",
-  "*yspeed: 1.0",
-  "*xamplitude: 1.0",
-  "*yamplitude: 1.0",
-  "*whirlies: -1",
-  "*nlines: -1",
-  "*xmode: change",
-  "*ymode: change",
-  "*speed: 1",
-  "*trail: 0",
-  "*color_modifier: -1",
-  "*start_time: -1",
-  "*explain: False",
-  "*xoffset: 1.0",
-  "*yoffset: 1.0",
-  "*offset_period:    1",
-  "*wrap:               0",
-  "*doubleBuffer:      True",
+};
+
+struct state {
+  Display *dpy;
+  Window window;
+
+    XGCValues gcv;      /* The structure to hold the GC data */
+    XWindowAttributes xgwa;       /*  A structure to hold window data */
+    Pixmap b, ba;      /* double-buffer to reduce flicker */
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-  "*useDBE:            True",
-  "*useDBEClear:       True",
+    Bool dbeclear_p;
+    XdbeBackBuffer backb;
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-  0
-};
 
-XrmOptionDescRec options [] = {
-  { "-xspeed",          ".xspeed", XrmoptionSepArg, 0 },
-      /* xspeed is a modifier of the argument to cos -- changing it thus
-         changes the frequency of cos */
-  { "-yspeed",          ".yspeed", XrmoptionSepArg, 0 },
-      /*  Similiarly, yspeed changes the frequency of sin */
-  { "-xamplitude",      ".xamplitude", XrmoptionSepArg, 0 },
-      /* A factor by which to increase/decrease the amplitude of the sin */
-  { "-yamplitude",      ".yamplitude", XrmoptionSepArg, 0 },
-      /* A factor by which to increase/decrease the amplitude of the cos */
-  { "-whirlies",         ".whirlies",XrmoptionSepArg, 0 },
-      /*  whirlies defines the number of circles to draw per line */
-  { "-nlines",         ".nlines",XrmoptionSepArg, 0 },
-      /* nlines is the number of lines of whirlies to draw */
-  { "-xmode",        ".xmode", XrmoptionSepArg, 0 },
-      /*  There are a few different modes that I have written -- each mode
-          is in theory a different experiment with the possible modifiers to sin/cos */
-  { "-ymode",       ".ymode", XrmoptionSepArg, 0 },
-  { "-speed",        ".speed", XrmoptionSepArg, 0 },
-      /*  This will modify how often it should draw, changing it will probably suck */
-  { "-trail",           ".trail", XrmoptionSepArg, 0 },
-      /* Control whether or not you want the old circles to be erased */
-  { "-color_modifier",          ".color_modifier", XrmoptionSepArg, 0 },
-      /*  How many colors away from the current should the next whirly be? */
-  { "-start_time",                ".start_time", XrmoptionSepArg, 0 },
-      /*  Specify exactly at what time to start graphing...  */
-  { "-xoffset",                    ".xoffset", XrmoptionSepArg, 0 },
-      /*  Tell the whirlies to be offset by this factor of a sin */
-  { "-yoffset",                    ".yoffset", XrmoptionSepArg, 0 },
-      /*  Tell the whirlies to be offset by this factor of a cos */
-  { "-offset_period",          ".offset_period", XrmoptionSepArg, 0 },
-      /*  Change the period of an offset cycle */
-  { "-explain",                    ".explain", XrmoptionNoArg, "True" },
-      /*  Specify whether or not to print an explanation of the function used. */
-  { "-wrap",                      ".wrap", XrmoptionSepArg, 0 },
-      /* Specify if you want whirlies which are out of the boundary of the screen to be
-         wrapped around to the other side */
-  { "-db",             ".doubleBuffer", XrmoptionNoArg,  "True" },
-  { "-no-db",          ".doubleBuffer", XrmoptionNoArg,  "False" },
-  { 0, 0, 0, 0 }
+    GC fgc, bgc;
+    int screen;
+    Bool dbuf;
+
+    unsigned long int current_time; /* The global int telling the current time */
+    unsigned long int start_time;
+    struct info  *info;
+    char *xmode_str, *ymode_str; /* holds the current mode for x and y computation */
+
+ /* pos is the current position x,y -- last_x contains one cell of
+    every x coordinate for every position of every whirly in every
+    line up to 100 whirlies in 100 lines -- lasy_y and last_size hold
+    the same information for y and size respectively */
+
+    int pos[2], last_x[100][100], last_y[100][100], last_size[100][100];
+    int current_color;
+    Bool wrap;
+    int xmode, ymode;
+    double modifier;    /* for innie */
+
+   XColor colors[NCOLORS];
+   int ncolors;
+   int explaining;
 };
 
+static void draw_explain_string(struct state *, int, int, Display *, Window, GC);
+static void spin(struct state *, unsigned long int, struct info *, int *, int);
+static void funky(struct state *, unsigned long int, struct info *, int *, int);
+static void circle(struct state *, unsigned long int, struct info *, int *, int);
+static void fun(struct state *, unsigned long int, struct info *, int *, int);
+static void linear(struct state *, unsigned long int, struct info *, int *, int);
+static void lissajous(struct state *, unsigned long int, struct info *, int *, int);
+static void test(struct state *, unsigned long int, struct info *, int *, int);
+static void innie(struct state *, unsigned long int, struct info *, int *, int, double);
+
+
+
 static const char spin_explanation[] =
 "Spin mode is a simple sin/cos with every argument modified";
 
@@ -158,93 +123,82 @@ static const char lissajous_explanation[] =
 "Lissajous mode draws a slightly modified lissajous curve";
 
 static void
-explain(int xmode, int ymode, struct info *info, Display *display, Window window, GC fgc)
-{
-    XClearWindow(display, window);
-    draw_explain_string(xmode, info->half_height-100, display, window, fgc);
-/*    draw_explain_string(ymode, info->half_height-50, display, window, fgc);*/
-    XSync(display, False);
-    sleep(3);
-    XClearWindow(display, window);
-}
-
-static void
-draw_explain_string(int mode, int offset, Display *display, Window window, GC fgc) 
+draw_explain_string(struct state *st, int mode, int offset, Display *dpy, Window window, GC fgc) 
 {
   switch(mode) {
   case spin_mode:
-    XDrawString(display, window, fgc, 50, offset, spin_explanation
-               strlen(spin_explanation));
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) spin_explanation, strlen(spin_explanation));
     break;
   case funky_mode:
-    XDrawString(display, window, fgc, 50, offset, funky_explanation
-               strlen(funky_explanation));
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) funky_explanation, strlen(funky_explanation));
     break;
   case circle_mode:
-    XDrawString(display, window, fgc, 50, offset, circle_explanation
-               strlen(circle_explanation));
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) circle_explanation, strlen(circle_explanation));
     break;
   case linear_mode:
-    XDrawString(display, window, fgc, 50, offset, linear_explanation
-               strlen(linear_explanation));
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) linear_explanation, strlen(linear_explanation));
     break;
   case test_mode:
-    XDrawString(display, window, fgc, 50, offset, test_explanation
-               strlen(test_explanation));
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) test_explanation, strlen(test_explanation));
     break;
   case fun_mode:
-    XDrawString(display, window, fgc, 50, offset, fun_explanation
-               strlen(fun_explanation));
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) fun_explanation, strlen(fun_explanation));
     break;
   case innie_mode:
-    XDrawString(display, window, fgc, 50, offset, innie_explanation
-               strlen(innie_explanation));
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) innie_explanation, strlen(innie_explanation));
     break;
   case lissajous_mode:
-    XDrawString(display, window, fgc, 50, offset, lissajous_explanation
-               strlen(linear_explanation));    
+    XDrawString(st->dpy, st->window, st->fgc, 50, offset
+                (char*) lissajous_explanation, strlen(linear_explanation));    
   }
 }
 
 static void
-funky(unsigned long int the_time, struct info *info, int pos[], int index)
+funky(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
 {
     double new_time = ((the_time % 360 ) / 180.0) * M_PI;
     if (index == 0) {
         double time_modifier = cos(new_time / 180.0);
-        double the_cos = cos((new_time * (double)info->xspeed) + (time_modifier * 80.0));
-        double dist_mod_x = cos(new_time) * (info->half_width - 50);
-        pos[index]= info->xamplitude * (the_cos * dist_mod_x) + info->half_width;
+        double the_cos = cos((new_time * (double)st->info->xspeed) + (time_modifier * 80.0));
+        double dist_mod_x = cos(new_time) * (st->info->half_width - 50);
+        st->pos[index]= st->info->xamplitude * (the_cos * dist_mod_x) + st->info->half_width;
     }
     else {
         double new_time = ((the_time % 360 ) / 180.0) * M_PI;
         double time_modifier = sin(new_time / 180.0);
-        double the_sin = sin((new_time * (double)info->yspeed) + (time_modifier * 80.0));
-        double dist_mod_y = sin(new_time) * (info->half_height - 50);
-        pos[index] = info->yamplitude * (the_sin * dist_mod_y) + info->half_height;
+        double the_sin = sin((new_time * (double)st->info->yspeed) + (time_modifier * 80.0));
+        double dist_mod_y = sin(new_time) * (st->info->half_height - 50);
+        st->pos[index] = st->info->yamplitude * (the_sin * dist_mod_y) + st->info->half_height;
     }
 }
 
 static void
-innie(unsigned long int the_time, struct info *info, int pos[], int index, double modifier)
+innie(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index, double modifier)
 {
-    double frequency = 2000000.0 + (modifier * cos(((double)the_time / 100.0)));
+    double frequency = 2000000.0 + (st->modifier * cos(((double)the_time / 100.0)));
     double arg = (double)the_time / frequency;
     double amplitude = 200.0 * cos(arg);
     double fun = 150.0 * cos((double)the_time / 2000.0);
     int vert_mod, horiz_mod;
     if (index == 0) {
-        horiz_mod = (int)(fun * cos((double)the_time / 100.0)) + info->half_width;
-        pos[index] = (amplitude * cos((double)the_time / 100.0 * info->xspeed)) + horiz_mod;
+        horiz_mod = (int)(fun * cos((double)the_time / 100.0)) + st->info->half_width;
+        st->pos[index] = (amplitude * cos((double)the_time / 100.0 * st->info->xspeed)) + horiz_mod;
     }
     else {
-        vert_mod = (int)(fun * sin((double)the_time / 100.0)) + info->half_height;
-        pos[index] = (amplitude * sin((double)the_time / 100.0 * info->yspeed)) + vert_mod;
+        vert_mod = (int)(fun * sin((double)the_time / 100.0)) + st->info->half_height;
+        st->pos[index] = (amplitude * sin((double)the_time / 100.0 * st->info->yspeed)) + vert_mod;
     }
 }
 
 static void
-lissajous(unsigned long int the_time, struct info *info, int pos[], int index)
+lissajous(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
 {
       /*  This is a pretty standard lissajous curve
            x = a sin(nt + c) 
@@ -256,25 +210,25 @@ lissajous(unsigned long int the_time, struct info *info, int pos[], int index)
   double weird = cos((time / 1100000.0) / 1000.0);
 
   if (index == 0) {
-      result = info->xamplitude * 200.0 * sin((weird * time) + fun) + info->half_width;
+      result = st->info->xamplitude * 200.0 * sin((weird * time) + fun) + st->info->half_width;
   }
   else {
-      result = info->yamplitude * 200.0 * sin(time) + info->half_height;
+      result = st->info->yamplitude * 200.0 * sin(time) + st->info->half_height;
   }
-  pos[index] = result;
+  st->pos[index] = result;
 } 
 
 static void
-circle(unsigned long int the_time, struct info *info, int pos[], int index)
+circle(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
 {
     int result;
     if (index == 0) {
-        result = info->xamplitude * (cos((double)the_time / 100.0 * info->xspeed) * (info->half_width / 2)) + info->half_width;
+        result = st->info->xamplitude * (cos((double)the_time / 100.0 * st->info->xspeed) * (st->info->half_width / 2)) + st->info->half_width;
     }
     else {
-        result = info->yamplitude * (sin((double)the_time / 100.0 * info->yspeed) * (info->half_height / 2)) + info->half_height;
+        result = st->info->yamplitude * (sin((double)the_time / 100.0 * st->info->yspeed) * (st->info->half_height / 2)) + st->info->half_height;
     }
-    pos[index] = result;
+    st->pos[index] = result;
 }
 
 #if 0
@@ -282,7 +236,7 @@ static void
 mod(unsigned long int the_time, struct info *info, int pos[], int index)
 {
     int amplitude;
-    int max = info->half_width;
+    int max = st->info->half_width;
     if ((the_time % (max * 2)) < max)
         amplitude = max - ((the_time % (max * 2)) - max);
     else
@@ -292,56 +246,56 @@ mod(unsigned long int the_time, struct info *info, int pos[], int index)
 #endif
 
 static void
-spin(unsigned long int the_time, struct info *info, int pos[], int index)
+spin(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
 {
     double funky = (((the_time % 360) * 1.0) / 180.0) * M_PI;
     if (index ==0) {
-    double the_cos = cos((double)the_time / (180.0 * info->xspeed));
-    double dist_mod_x = cos((double)funky) * (info->half_width - 50);
-    pos[index] = info->xamplitude * (the_cos * dist_mod_x) + info->half_width;
+    double the_cos = cos((double)the_time / (180.0 * st->info->xspeed));
+    double dist_mod_x = cos((double)funky) * (st->info->half_width - 50);
+    st->pos[index] = st->info->xamplitude * (the_cos * dist_mod_x) + st->info->half_width;
     }
     else {
-    double the_sin = sin((double)the_time / (180.0 * info->yspeed));
-    double dist_mod_y = sin((double)funky) * (info->half_height - 50);
-    pos[index] = info->yamplitude * (the_sin * dist_mod_y) + info->half_height;
+    double the_sin = sin((double)the_time / (180.0 * st->info->yspeed));
+    double dist_mod_y = sin((double)funky) * (st->info->half_height - 50);
+    st->pos[index] = st->info->yamplitude * (the_sin * dist_mod_y) + st->info->half_height;
     }
 }
 
 static void
-fun(unsigned long int the_time, struct info *info, int pos[], int index)
+fun(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
 {
     int amplitude;
-    int max = info->half_width;
+    int max = st->info->half_width;
     if ((the_time % (max * 2)) < max)
         amplitude = max - ((the_time % (max * 2)) - max);
     else
         amplitude = the_time % (max * 2);
     amplitude = amplitude - max;
     if (index ==0) {
-        pos[index] = (amplitude * cos((double)the_time / 100.0 * info->xspeed)) + info->half_width;
+        st->pos[index] = (amplitude * cos((double)the_time / 100.0 * st->info->xspeed)) + st->info->half_width;
     }
     else {
-        pos[index] = (amplitude * sin((double)the_time / 100.0 * info->yspeed)) + info->half_height;
+        st->pos[index] = (amplitude * sin((double)the_time / 100.0 * st->info->yspeed)) + st->info->half_height;
     }
 }
 
 static void
-linear(unsigned long int the_time, struct info *info, int pos[], int index)
+linear(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
 {
     if (index == 0)   /* Calculate for the x axis */
-        pos[index] = ((the_time / 2) % (info->half_width * 2));
+        st->pos[index] = ((the_time / 2) % (st->info->half_width * 2));
     else
-        pos[index] = ((the_time / 2) % (info->half_height * 2));
+        st->pos[index] = ((the_time / 2) % (st->info->half_height * 2));
 }
 
 static void
-test(unsigned long int the_time, struct info *info, int pos[], int index)
+test(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
 {
     if (index == 0) {
-        pos[index] = info->xamplitude * (cos((double)the_time / 100.0 * info->xspeed) * (info->half_width / 2)) + info->half_width;
+        st->pos[index] = st->info->xamplitude * (cos((double)the_time / 100.0 * st->info->xspeed) * (st->info->half_width / 2)) + st->info->half_width;
     }
     else {
-        pos[index] = info->yamplitude * (sin((double)the_time / 100.0 * info->yspeed) * (info->half_height / 2)) + info->half_height;
+        st->pos[index] = st->info->yamplitude * (sin((double)the_time / 100.0 * st->info->yspeed) * (st->info->half_height / 2)) + st->info->half_height;
     }   
 }
 
@@ -354,7 +308,7 @@ static int preen(int current, int max) {
 }
 
 static void
-smoothen(int x, int lastx, int y, int lasty, int size, int last_color, XColor *colors, Display *display, Window window, GC bgc, int screen, struct info *info)
+smoothen(struct state *st, int x, int lastx, int y, int lasty, int size, int last_color, XColor *colors, Display *dpy, Window window, GC bgc, int screen, struct info *info)
 {
     double xdistance = abs((double)x-(double)lastx);
     double ydistance = abs((double)y-(double)lasty);
@@ -364,310 +318,413 @@ smoothen(int x, int lastx, int y, int lasty, int size, int last_color, XColor *c
     if (distance > 2.0) {
         int newx = (int)((xdistance / distance) * slope);
         int newy = (int)((ydistance / distance) * slope);
-        if (! info->trail) {
-            XSetForeground(display, bgc, BlackPixel(display, screen));
-            XFillArc(display, window, bgc, lastx, lasty, size, size, START_ARC, END_ARC);
+        if (! st->info->trail) {
+            XSetForeground(st->dpy, st->bgc, BlackPixel(st->dpy, st->screen));
+            XFillArc(st->dpy, st->window, st->bgc, lastx, lasty, size, size, START_ARC, END_ARC);
         }
-        XSetForeground(display, bgc, colors[last_color].pixel);
-        XFillArc(display, window, bgc, newx, newy, size, size, START_ARC, END_ARC);
-        XSync(display, False);
-        smoothen(newx, x, newy, y, size, last_color, colors, display, window, bgc, screen, info);
+        XSetForeground(st->dpy, st->bgc, st->colors[last_color].pixel);
+        XFillArc(st->dpy, st->window, st->bgc, newx, newy, size, size, START_ARC, END_ARC);
+        smoothen(st, newx, x, newy, y, size, last_color, st->colors, st->dpy, st->window, st->bgc, st->screen, st->info);
     }
 }
 
 
-void
-screenhack (Display *display, Window window)
+static void *
+whirlygig_init (Display *dpy, Window window)
 {
-        /*  The following are all X related toys */
-    XGCValues gcv;      /* The structure to hold the GC data */
-    XWindowAttributes xgwa;       /*  A structure to hold window data */
-    Pixmap b=0, ba=0;  /* double-buffer to reduce flicker */
-#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-    XdbeBackBuffer backb = 0;
-#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
+  st->dpy = dpy;
+  st->window = window;
 
-    GC fgc, bgc;
-    int screen;
-    Bool dbuf = get_boolean_resource ("doubleBuffer", "Boolean");
-    Bool dbeclear_p = get_boolean_resource ("useDBEClear", "Boolean");
+  st->ncolors = NCOLORS;
 
-    unsigned long int current_time = 0; /* The global int telling the current time */
-    unsigned long int start_time = current_time;
-    struct info  *info = (struct info *)malloc(sizeof(struct info));      /* Dont forget to call free() later */
-    char *xmode_str, *ymode_str; /* holds the current mode for x and y computation */
-        /* pos is the current position x,y -- last_x contains one cell of every x coordinate
-           for every position of every whirly in every line up to 100 whirlies in 100 lines
-           -- lasy_y and last_size hold the same information for y and size respectively */
-    int pos[2], last_x[100][100], last_y[100][100], last_size[100][100];
-    int current_color;
-    int wrap;
-    int xmode, ymode;
-    double modifier;    /* for innie */
-        /* Set up the X toys that I will be using later */
-    screen = DefaultScreen(display);
-    XGetWindowAttributes (display, window, &xgwa);
-    if (dbuf)
+    st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean");
+
+# ifdef HAVE_COCOA     /* Don't second-guess Quartz's double-buffering */
+    st->dbuf = False;
+# endif
+
+    st->start_time = st->current_time;
+    st->info = (struct info *)malloc(sizeof(struct info));
+
+    st->screen = DefaultScreen(st->dpy);
+    XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+    if (st->dbuf)
       {
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-       if (dbeclear_p)
-         b = xdbe_get_backbuffer (display, window, XdbeBackground);
-       else
-         b = xdbe_get_backbuffer (display, window, XdbeUndefined);
-       backb = b;
+        if (get_boolean_resource(st->dpy,"useDBE","Boolean"))
+          {
+            st->dbeclear_p = get_boolean_resource (st->dpy, "useDBEClear",
+                                                   "Boolean");
+            if (st->dbeclear_p)
+              st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeBackground);
+            else
+              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 (display, 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->b = st->ba;
          }
       }
     else
       {
-       b = window;
+       st->b = st->window;
       }
 
-    gcv.foreground = get_pixel_resource("foreground", "Foreground", display, xgwa.colormap);
-    fgc = XCreateGC (display, b, GCForeground, &gcv);
-    gcv.foreground = get_pixel_resource("background", "Background", display, xgwa.colormap);
-    bgc = XCreateGC (display, b, GCForeground, &gcv);
+    st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "foreground", "Foreground");
+    st->fgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv);
+    st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "background", "Background");
+    st->bgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv);
+
+#ifdef HAVE_COCOA  /* #### should turn off double-buffering instead */
+    jwxyz_XSetAntiAliasing (dpy, st->fgc, False);
+    jwxyz_XSetAntiAliasing (dpy, st->bgc, False);
+#endif
+
     {
       Bool writable_p = False;
-    make_uniform_colormap (display, xgwa.visual, xgwa.colormap, colors, &ncolors, True, &writable_p, True);
+    make_uniform_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap, st->colors, &st->ncolors, True, &writable_p, True);
     }
 
-    if (ba) XFillRectangle (display, ba, bgc, 0, 0, xgwa.width, xgwa.height);
+    if (st->ba) XFillRectangle (st->dpy, st->ba, st->bgc, 0, 0, st->xgwa.width, st->xgwa.height);
 
         /* info is a structure holding all the random pieces of information I may want to 
            pass to my baby functions -- much of it I may never use, but it is nice to
            have around just in case I want it to make a funky function funkier */
-/*    info->writable = get_boolean_resource ("cycle", "Boolean"); */
-    info->xspeed = get_float_resource("xspeed" , "Float");
-    info->yspeed = get_float_resource("yspeed" , "Float");
-    info->xamplitude = get_float_resource("xamplitude", "Float");
-    info->yamplitude = get_float_resource("yamplitude", "Float");
-    info->offset_period = get_float_resource("offset_period", "Float");
-    info->whirlies = get_integer_resource("whirlies", "Integer");
-    info->nlines = get_integer_resource("nlines", "Integer");
-    info->half_width = xgwa.width / 2;
-    info->half_height = xgwa.height / 2;
-    info->speed = get_integer_resource("speed" , "Integer");
-    info->trail = get_integer_resource("trail", "Integer");
-    info->color_modifier = get_integer_resource("color_modifier", "Integer");
-    info->xoffset = get_float_resource("xoffset", "Float");
-    info->yoffset = get_float_resource("yoffset", "Float");
-    xmode_str = get_string_resource("xmode", "Mode");
-    ymode_str = get_string_resource("ymode", "Mode");
-    wrap = get_integer_resource("wrap", "Integer");
-    modifier = 3000.0 + frand(1500.0);
-    if (! xmode_str) xmode = spin_mode;
-    else if (! strcmp (xmode_str, "spin")) xmode = spin_mode;
-    else if (! strcmp (xmode_str, "funky")) xmode = funky_mode;
-    else if (! strcmp (xmode_str, "circle")) xmode = circle_mode;
-    else if (! strcmp (xmode_str, "linear")) xmode = linear_mode;
-    else if (! strcmp (xmode_str, "test")) xmode = test_mode;
-    else if (! strcmp (xmode_str, "fun")) xmode = fun_mode;
-    else if (! strcmp (xmode_str, "innie")) xmode = innie_mode;
-    else if (! strcmp (xmode_str, "lissajous")) xmode = lissajous_mode;
+/*    info->writable = get_boolean_resource (dpy, "cycle", "Boolean"); */
+    st->info->xspeed = get_float_resource(st->dpy, "xspeed" , "Float");
+    st->info->yspeed = get_float_resource(st->dpy, "yspeed" , "Float");
+    st->info->xamplitude = get_float_resource(st->dpy, "xamplitude", "Float");
+    st->info->yamplitude = get_float_resource(st->dpy, "yamplitude", "Float");
+    st->info->offset_period = get_float_resource(st->dpy, "offset_period", "Float");
+    st->info->whirlies = get_integer_resource(st->dpy, "whirlies", "Integer");
+    st->info->nlines = get_integer_resource(st->dpy, "nlines", "Integer");
+    st->info->half_width = st->xgwa.width / 2;
+    st->info->half_height = st->xgwa.height / 2;
+    st->info->speed = get_integer_resource(st->dpy, "speed" , "Integer");
+    st->info->trail = get_integer_resource(st->dpy, "trail", "Integer");
+    st->info->color_modifier = get_integer_resource(st->dpy, "color_modifier", "Integer");
+    st->info->xoffset = get_float_resource(st->dpy, "xoffset", "Float");
+    st->info->yoffset = get_float_resource(st->dpy, "yoffset", "Float");
+    st->xmode_str = get_string_resource(st->dpy, "xmode", "Mode");
+    st->ymode_str = get_string_resource(st->dpy, "ymode", "Mode");
+    st->wrap = get_boolean_resource(st->dpy, "wrap", "Boolean");
+    st->modifier = 3000.0 + frand(1500.0);
+    if (! st->xmode_str) st->xmode = spin_mode;
+    else if (! strcmp (st->xmode_str, "spin")) st->xmode = spin_mode;
+    else if (! strcmp (st->xmode_str, "funky")) st->xmode = funky_mode;
+    else if (! strcmp (st->xmode_str, "circle")) st->xmode = circle_mode;
+    else if (! strcmp (st->xmode_str, "linear")) st->xmode = linear_mode;
+    else if (! strcmp (st->xmode_str, "test")) st->xmode = test_mode;
+    else if (! strcmp (st->xmode_str, "fun")) st->xmode = fun_mode;
+    else if (! strcmp (st->xmode_str, "innie")) st->xmode = innie_mode;
+    else if (! strcmp (st->xmode_str, "lissajous")) st->xmode = lissajous_mode;
     else {
-        xmode = spin_mode;
+        st->xmode = random() % (int) lissajous_mode;
     }
-    if (! ymode_str) ymode = spin_mode;
-    else if (! strcmp (ymode_str, "spin")) ymode = spin_mode;
-    else if (! strcmp (ymode_str, "funky")) ymode = funky_mode;
-    else if (! strcmp (ymode_str, "circle")) ymode = circle_mode;
-    else if (! strcmp (ymode_str, "linear")) ymode = linear_mode;
-    else if (! strcmp (ymode_str, "test")) ymode = test_mode;
-    else if (! strcmp (ymode_str, "fun")) ymode = fun_mode;
-    else if (! strcmp (ymode_str, "innie")) ymode = innie_mode;
-    else if (! strcmp (ymode_str, "lissajous")) ymode = lissajous_mode;
+    if (! st->ymode_str) st->ymode = spin_mode;
+    else if (! strcmp (st->ymode_str, "spin")) st->ymode = spin_mode;
+    else if (! strcmp (st->ymode_str, "funky")) st->ymode = funky_mode;
+    else if (! strcmp (st->ymode_str, "circle")) st->ymode = circle_mode;
+    else if (! strcmp (st->ymode_str, "linear")) st->ymode = linear_mode;
+    else if (! strcmp (st->ymode_str, "test")) st->ymode = test_mode;
+    else if (! strcmp (st->ymode_str, "fun")) st->ymode = fun_mode;
+    else if (! strcmp (st->ymode_str, "innie")) st->ymode = innie_mode;
+    else if (! strcmp (st->ymode_str, "lissajous")) st->ymode = lissajous_mode;
     else {
-        ymode = spin_mode;
+        st->ymode = random() % (int) lissajous_mode;
     }
 
-    if (get_integer_resource("start_time", "Integer") == -1)
-        current_time = (unsigned long int)(random());
+    if (get_integer_resource(st->dpy, "start_time", "Integer") == -1)
+        st->current_time = (unsigned long int)(random());
     else
-        current_time = get_integer_resource("start_time", "Integer");
-    if (info->whirlies == -1)
-        info->whirlies = 1 + (random() % 15);
-    if (info->nlines == -1)
-        info->nlines = 1 + (random() % 5);
-    if (info->color_modifier == -1)
-        info->color_modifier = 1 + (random() % 25);
-    if (get_boolean_resource("explain", "Integer"))
-        explain(xmode, ymode, info, display, window, fgc);
-    current_color = 1 + (random() % NCOLORS);
-        /* Now that info is full, lets play! */
-    
-    while (1) {
-        int wcount;  /* wcount is a counter incremented for every whirly take note of
-                        internal_time before you mess with it */
-        int change_time = 4000;
-        if (! strcmp (xmode_str, "change") && ! strcmp (ymode_str, "change")) {
-            if ((current_time - start_time) > change_time) {
-                start_time = current_time;
-                xmode = 1 + (random() % 4);
-                ymode = 1 + (random() % 4);
-            }
+        st->current_time = get_integer_resource(st->dpy, "start_time", "Integer");
+    if (st->info->whirlies == -1)
+        st->info->whirlies = 1 + (random() % 15);
+    if (st->info->nlines == -1)
+        st->info->nlines = 1 + (random() % 5);
+    if (st->info->color_modifier == -1)
+        st->info->color_modifier = 1 + (random() % 25);
+    if (get_boolean_resource(st->dpy, "explain", "Integer"))
+      st->explaining = 1;
+    st->current_color = 1 + (random() % NCOLORS);
+
+  return st;
+}
+
+static unsigned long
+whirlygig_draw (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  int wcount;  /* wcount is a counter incremented for every whirly take note of
+                  internal_time before you mess with it */
+  int change_time = 4000;
+
+  if (st->explaining == 1) {
+    XClearWindow (st->dpy, st->window);
+    draw_explain_string(st, st->xmode, st->info->half_height-100, 
+                        st->dpy, st->window, st->fgc);
+    st->explaining++;
+    return 3000000;
+  } else if (st->explaining == 2) {
+    XClearWindow (st->dpy, st->window);
+    st->explaining = 0;
+  }
+
+  if (! strcmp (st->xmode_str, "change") && ! strcmp (st->ymode_str, "change")) {
+    if ((st->current_time - st->start_time) > change_time) {
+      st->start_time = st->current_time;
+      st->xmode = 1 + (random() % 4);
+      st->ymode = 1 + (random() % 4);
+    }
+  }
+  else if (! strcmp (st->xmode_str, "change")) {
+    if ((st->current_time - st->start_time) > change_time) {
+      st->start_time = st->current_time;
+      st->xmode = 1 + (random() % 4);
+    }
+  }
+  else if (! strcmp (st->ymode_str, "change")) {
+    if ((st->current_time - st->start_time) > change_time) {
+      st->start_time = st->current_time;
+      st->ymode = 1 + (random() % 3);
+      printf("Changing ymode to %d\n", st->ymode);
+    }
+  }
+  if (++st->current_color >= NCOLORS)
+    st->current_color = 0;
+  for (wcount = 0; wcount < st->info->whirlies; wcount++) {
+    int lcount; /* lcount is a counter for every line -- take note of the offsets changing */
+    int internal_time = st->current_time;
+    int color_offset = (st->current_color + (st->info->color_modifier * wcount)) % NCOLORS;
+    if (st->current_time == 0)
+      internal_time = 0;
+    else
+      /* I want the distance between whirlies to increase more each whirly */
+      internal_time = st->current_time + (10 * wcount) + (wcount * wcount); 
+    switch (st->xmode) {
+      /* All these functions expect an int time, the struct info,
+         a pointer to an array of positions, and the index that the 
+         the function will fill of the array */
+    case spin_mode:
+      spin(st, internal_time, st->info, st->pos, 0);
+      break;
+    case funky_mode:
+      funky(st, internal_time, st->info, st->pos, 0);
+      break;
+    case circle_mode:
+      circle(st, internal_time, st->info, st->pos, 0);
+      break;
+    case linear_mode:
+      linear(st, internal_time, st->info, st->pos, 0);
+      break;
+    case fun_mode:
+      fun(st, internal_time, st->info, st->pos, 0);
+      break;
+    case test_mode:
+      test(st, internal_time, st->info, st->pos, 0);
+      break;
+    case innie_mode:
+      innie(st, internal_time, st->info, st->pos, 0, st->modifier);
+      break;
+    case lissajous_mode:
+      lissajous(st, internal_time, st->info, st->pos, 0);
+      break;
+    default:
+      spin(st, internal_time, st->info, st->pos, 0);
+      break;
+    }   /* End of the switch for the x position*/
+    switch (st->ymode) {
+    case spin_mode:
+      spin(st, internal_time, st->info, st->pos, 1);
+      break;
+    case funky_mode:
+      funky(st, internal_time, st->info, st->pos, 1);
+      break;
+    case circle_mode:
+      circle(st, internal_time, st->info, st->pos, 1);
+      break;
+    case linear_mode:
+      linear(st, internal_time, st->info, st->pos, 1);
+      break;
+    case fun_mode:
+      fun(st, internal_time, st->info, st->pos, 1);
+      break;
+    case test_mode:
+      test(st, internal_time, st->info, st->pos, 1);
+      break;
+    case innie_mode:
+      innie(st, internal_time, st->info, st->pos, 1, st->modifier);
+      break;
+    case lissajous_mode:
+      lissajous(st, internal_time, st->info, st->pos, 1);
+      break;
+    default:
+      spin(st, internal_time, st->info, st->pos, 1);
+      break;
+    } /* End of the switch for the y position*/
+    for (lcount = 0; lcount < st->info->nlines; lcount++) {
+      double arg = (double)((internal_time * st->info->offset_period) / 90.0); 
+      double line_offset = 20.0 * (double)lcount * sin(arg); 
+      int size;
+      size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0));
+      /* First delete the old circle... */
+      if (!st->info->trail
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+          && ( !st->dbeclear_p || !st->backb)
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+          ) {
+        XSetForeground(st->dpy, st->bgc, BlackPixel(st->dpy, st->screen));
+        XFillArc(st->dpy, st->b, st->bgc, st->last_x[wcount][lcount], st->last_y[wcount][lcount], st->last_size[wcount][lcount], st->last_size[wcount][lcount], START_ARC, END_ARC);
+      }
+      /* Now, lets draw in the new circle */
+      {  /* Starting new scope for local x_pos and y_pos */
+        int xpos, ypos;
+        if (st->wrap) {
+          xpos = preen((int)(st->info->xoffset*line_offset)+st->pos[0], st->info->half_width * 2);
+          ypos = preen((int)(st->info->yoffset*line_offset)+st->pos[1], st->info->half_height * 2);
         }
-        else if (! strcmp (xmode_str, "change")) {
-            if ((current_time - start_time) > change_time) {
-                start_time = current_time;
-                xmode = 1 + (random() % 4);
-            }
+        else {
+          xpos = (int)(st->info->xoffset*line_offset)+st->pos[0];
+          ypos = (int)(st->info->yoffset*line_offset)+st->pos[1]; 
         }
-        else if (! strcmp (ymode_str, "change")) {
-            if ((current_time - start_time) > change_time) {
-                start_time = current_time;
-                ymode = 1 + (random() % 3);
-                printf("Changing ymode to %d\n", ymode);
-            }
+        if (st->start_time == st->current_time) {
+          /* smoothen should move from one mode to another prettily... */
+
+          /* Note: smoothen has not been modified to take the double
+             buffering code into account, and needs to be hacked on
+             before uncommenting.
+          */
+          /* 
+             smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, dpy, window, bgc, screen, info);
+          */
         }
-        if (++current_color >= NCOLORS)
-            current_color = 0;
-        for (wcount = 0; wcount < info->whirlies; wcount++) {
-            int lcount; /* lcount is a counter for every line -- take note of the offsets changing */
-            int internal_time = current_time;
-            int color_offset = (current_color + (info->color_modifier * wcount)) % NCOLORS;
-            if (current_time == 0)
-                internal_time = 0;
-            else
-                    /* I want the distance between whirlies to increase more each whirly */
-                internal_time = current_time + (10 * wcount) + (wcount * wcount); 
-            switch (xmode) {
-             /* All these functions expect an int time, the struct info,
-                a pointer to an array of positions, and the index that the 
-                the function will fill of the array */
-                case spin_mode:
-                    spin(internal_time, info, pos, 0);
-                    break;
-                case funky_mode:
-                    funky(internal_time, info, pos, 0);
-                    break;
-                case circle_mode:
-                    circle(internal_time, info, pos, 0);
-                    break;
-                case linear_mode:
-                    linear(internal_time, info, pos, 0);
-                    break;
-                case fun_mode:
-                    fun(internal_time, info, pos, 0);
-                    break;
-                case test_mode:
-                    test(internal_time, info, pos, 0);
-                    break;
-                case innie_mode:
-                    innie(internal_time, info, pos, 0, modifier);
-                    break;
-                case lissajous_mode:
-                    lissajous(internal_time, info, pos, 0);
-                    break;
-                default:
-                    spin(internal_time, info, pos, 0);
-                    break;
-            }   /* End of the switch for the x position*/
-            switch (ymode) {
-                case spin_mode:
-                    spin(internal_time, info, pos, 1);
-                    break;
-                case funky_mode:
-                    funky(internal_time, info, pos, 1);
-                    break;
-                case circle_mode:
-                    circle(internal_time, info, pos, 1);
-                    break;
-                case linear_mode:
-                    linear(internal_time, info, pos, 1);
-                    break;
-                case fun_mode:
-                    fun(internal_time, info, pos, 1);
-                    break;
-                case test_mode:
-                    test(internal_time, info, pos, 1);
-                    break;
-                case innie_mode:
-                    innie(internal_time, info, pos, 1, modifier);
-                    break;
-                case lissajous_mode:
-                    lissajous(internal_time, info, pos, 1);
-                    break;
-                default:
-                    spin(internal_time, info, pos, 1);
-                    break;
-            } /* End of the switch for the y position*/
-            for (lcount = 0; lcount < info->nlines; lcount++) {
-                double arg = (double)((internal_time * info->offset_period) / 90.0); 
-                double line_offset = 20.0 * (double)lcount * sin(arg); 
-                int size;
-                size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0));
-               /* First delete the old circle... */
-                if (!info->trail && ( !dbeclear_p
+        st->last_x[wcount][lcount] = xpos;
+        st->last_y[wcount][lcount] = ypos;
+        st->last_size[wcount][lcount] = size;
+        XSetForeground(st->dpy, st->bgc, st->colors[color_offset].pixel);
+        XFillArc(st->dpy, st->b, st->bgc, xpos, ypos, size, size, START_ARC, END_ARC);
+      } /* End of my temporary scope for xpos and ypos */
+    }  /* End of the for each line in nlines */
+  } /* End of the for each whirly in whirlies */
+
+
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-                   || !backb
+  if (st->backb)
+    {
+      XdbeSwapInfo info[1];
+      info[0].swap_window = st->window;
+      info[0].swap_action = (st->dbeclear_p ? XdbeBackground : XdbeUndefined);
+      XdbeSwapBuffers (st->dpy, info, 1);
+    }
+  else
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-                   )) {
-                    XSetForeground(display, bgc, BlackPixel(display, screen));
-                    XFillArc(display, b, bgc, last_x[wcount][lcount], last_y[wcount][lcount], last_size[wcount][lcount], last_size[wcount][lcount], START_ARC, END_ARC);
-                }
-                    /* Now, lets draw in the new circle */
-                {  /* Starting new scope for local x_pos and y_pos */
-                    int xpos, ypos;
-                    if (wrap) {
-                        xpos = preen((int)(info->xoffset*line_offset)+pos[0], info->half_width * 2);
-                        ypos = preen((int)(info->yoffset*line_offset)+pos[1], info->half_height * 2);
-                    }
-                    else {
-                        xpos = (int)(info->xoffset*line_offset)+pos[0];
-                        ypos = (int)(info->yoffset*line_offset)+pos[1]; 
-                    }
-                    if (start_time == current_time) {
-                     /* smoothen should move from one mode to another prettily... */
-
-                     /* Note: smoothen has not been modified to take the double
-                        buffering code into account, and needs to be hacked on
-                        before uncommenting.
-                     */
-/* 
-   smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, display, window, bgc, screen, info);
- */
-                    }
-                    last_x[wcount][lcount] = xpos;
-                    last_y[wcount][lcount] = ypos;
-                    last_size[wcount][lcount] = size;
-                    XSetForeground(display, bgc, colors[color_offset].pixel);
-                    XFillArc(display, b, bgc, xpos, ypos, size, size, START_ARC, END_ARC);
-                } /* End of my temporary scope for xpos and ypos */
-            }  /* End of the for each line in nlines */
-        } /* End of the for each whirly in whirlies */
+    if (st->dbuf)
+      {
+        XCopyArea (st->dpy, st->b, st->window, st->bgc, 0, 0,
+                   st->xgwa.width, st->xgwa.height, 0, 0);
+      }
+
+  if (st->current_time == FULL_CYCLE)
+    st->current_time = 1;
+  else
+    st->current_time = st->current_time + st->info->speed;
+
+  return 10000;
+}
+
 
+static void
+whirlygig_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+}
 
+static Bool
+whirlygig_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  return False;
+}
 
+static void
+whirlygig_free (Display *dpy, Window window, void *closure)
+{
+}
+
+
+static const char *whirlygig_defaults [] = {
+  ".background: black",
+  ".foreground: white",
+  "*xspeed: 1.0",
+  "*yspeed: 1.0",
+  "*xamplitude: 1.0",
+  "*yamplitude: 1.0",
+  "*whirlies: -1",
+  "*nlines: -1",
+  "*xmode: change",
+  "*ymode: change",
+  "*speed: 1",
+  "*trail: 0",
+  "*color_modifier: -1",
+  "*start_time: -1",
+  "*explain: False",
+  "*xoffset: 1.0",
+  "*yoffset: 1.0",
+  "*offset_period:    1",
+  "*wrap:               False",
+  "*doubleBuffer:      True",
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-       if (backb)
-         {
-           XdbeSwapInfo info[1];
-           info[0].swap_window = window;
-           info[0].swap_action = (dbeclear_p ? XdbeBackground : XdbeUndefined);
-           XdbeSwapBuffers (display, info, 1);
-         }
-       else
+  "*useDBEClear:       True",
+  "*useDBE:            True",
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-         if (dbuf)
-           {
-             XCopyArea (display, b, window, bgc, 0, 0,
-                        xgwa.width, xgwa.height, 0, 0);
-           }
-
-        XSync(display, False);
-        if (current_time == FULL_CYCLE)
-            current_time = 1;
-        else
-            current_time = current_time + info->speed;
-        screenhack_handle_events(display);
-/*        if (!info->writable) */
-            usleep(10000);
-    }   /*  End the while loop! */
-    free(info);
-}
+  0
+};
+
+static XrmOptionDescRec whirlygig_options [] = {
+  { "-xspeed",          ".xspeed", XrmoptionSepArg, 0 },
+      /* xspeed is a modifier of the argument to cos -- changing it thus
+         changes the frequency of cos */
+  { "-yspeed",          ".yspeed", XrmoptionSepArg, 0 },
+      /*  Similiarly, yspeed changes the frequency of sin */
+  { "-xamplitude",      ".xamplitude", XrmoptionSepArg, 0 },
+      /* A factor by which to increase/decrease the amplitude of the sin */
+  { "-yamplitude",      ".yamplitude", XrmoptionSepArg, 0 },
+      /* A factor by which to increase/decrease the amplitude of the cos */
+  { "-whirlies",         ".whirlies",XrmoptionSepArg, 0 },
+      /*  whirlies defines the number of circles to draw per line */
+  { "-nlines",         ".nlines",XrmoptionSepArg, 0 },
+      /* nlines is the number of lines of whirlies to draw */
+  { "-xmode",        ".xmode", XrmoptionSepArg, 0 },
+      /*  There are a few different modes that I have written -- each mode
+          is in theory a different experiment with the possible modifiers to sin/cos */
+  { "-ymode",       ".ymode", XrmoptionSepArg, 0 },
+  { "-speed",        ".speed", XrmoptionSepArg, 0 },
+      /*  This will modify how often it should draw, changing it will probably suck */
+  { "-trail",           ".trail", XrmoptionSepArg, 0 },
+      /* Control whether or not you want the old circles to be erased */
+  { "-color_modifier",          ".color_modifier", XrmoptionSepArg, 0 },
+      /*  How many colors away from the current should the next whirly be? */
+  { "-start_time",                ".start_time", XrmoptionSepArg, 0 },
+      /*  Specify exactly at what time to start graphing...  */
+  { "-xoffset",                    ".xoffset", XrmoptionSepArg, 0 },
+      /*  Tell the whirlies to be offset by this factor of a sin */
+  { "-yoffset",                    ".yoffset", XrmoptionSepArg, 0 },
+      /*  Tell the whirlies to be offset by this factor of a cos */
+  { "-offset_period",          ".offset_period", XrmoptionSepArg, 0 },
+      /*  Change the period of an offset cycle */
+  { "-explain",                    ".explain", XrmoptionNoArg, "True" },
+      /*  Specify whether or not to print an explanation of the function used. */
+  { "-wrap",                      ".wrap", XrmoptionNoArg, "True" },
+  { "-no-wrap",                   ".wrap", XrmoptionNoArg, "False" },
+      /* Specify if you want whirlies which are out of the boundary of the screen to be
+         wrapped around to the other side */
+  { "-db",             ".doubleBuffer", XrmoptionNoArg,  "True" },
+  { "-no-db",          ".doubleBuffer", XrmoptionNoArg,  "False" },
+  { 0, 0, 0, 0 }
+};
+
+XSCREENSAVER_MODULE ("Whirlygig", whirlygig)