From http://www.jwz.org/xscreensaver/xscreensaver-5.22.tar.gz
[xscreensaver] / hacks / metaballs.c
index d814a80c29cd4ddabd5e44d2e90cea825ef740d3..b79dd95d94151550f4fd346a4753791a6e410008 100644 (file)
 
 #include <math.h>
 #include "screenhack.h"
-#include <X11/Xutil.h>
 
 /*#define VERBOSE*/ 
 
-char *progclass = "Metaballs";
-
-char *defaults [] = {
-  ".background: black",
-  ".foreground: white",
-  "*color:    random",
-  "*count:    10",
-  "*cycles:   1000",
-  "*ncolors:  256",
-  "*delay:    5000",
-  "*radius:   100",
-  "*delta:   3",
-  0
-};
-
-XrmOptionDescRec options [] = {
-  { "-color",   ".color",   XrmoptionSepArg, 0 },
-  { "-ncolors", ".ncolors", XrmoptionSepArg, 0 },
-  { "-count",   ".count",   XrmoptionSepArg, 0 },
-  { "-delay",   ".delay",   XrmoptionSepArg, 0 },
-  { "-cycles",  ".cycles",  XrmoptionSepArg, 0 },
-  { "-radius",  ".radius",  XrmoptionSepArg, 0 },
-  { "-delta",  ".delta",  XrmoptionSepArg, 0 },
-  { 0, 0, 0, 0 }
-};
-
-static unsigned short iWinWidth, iWinHeight;
-static char *sColor;
-
 /*blob structure*/
 typedef struct 
 {
   short xpos,ypos;
 } BLOB;
 
-static unsigned int nBlobCount;
-static unsigned char radius;
-static unsigned char delta;
-static unsigned char dradius;
-static unsigned short sradius;
-static unsigned char **blob;
-static BLOB *blobs;
-static unsigned char **blub;
+struct state {
+  Display *dpy;
+  Window window;
+
+  unsigned short iWinWidth, iWinHeight;
+  char *sColor;
+
+  unsigned int nBlobCount;
+  unsigned char radius;
+  unsigned char delta;
+  unsigned char dradius;
+  unsigned short sradius;
+  unsigned char **blob;
+  BLOB *blobs;
+  unsigned char **blub;
+
+  int delay, cycles;
+  signed short iColorCount;
+  unsigned long *aiColorVals;
+  XImage *pImage;
+  GC gc;
+  int draw_i;
+};
+
 
-static void init_blob(BLOB *blob)
+#undef BELLRAND
+#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
+
+static void init_blob(struct state *st, BLOB *blob)
 {
-  blob->xpos =  (iWinWidth>> 1) - radius;
-  blob->ypos =  (iWinHeight >> 1) - radius;
+  blob->xpos = st->iWinWidth/4  + BELLRAND(st->iWinWidth/2)  - st->radius;
+  blob->ypos = st->iWinHeight/4 + BELLRAND(st->iWinHeight/2) - st->radius;
 }
 
-static void Execute( Display *pDisplay,
-                     Window MainWindow,
-                     GC *pGC, XImage *pImage,
-                     signed short iColorCount, unsigned long *aiColorVals )
+static void Execute( struct state *st )
 {
-       unsigned int i, j, k;
+       int i, j, k;
 
-       /* clear blub array */
-       for (i = 0; i < iWinHeight; ++i)
-         memset(blub[i], 0, iWinWidth * sizeof(unsigned char));
+       /* clear st->blub array */
+       for (i = 0; i < st->iWinHeight; ++i)
+         memset(st->blub[i], 0, st->iWinWidth * sizeof(unsigned char));
 
-       /* move blobs */
-       for (i = 0; i < nBlobCount; i++)
+       /* move st->blobs */
+       for (i = 0; i < st->nBlobCount; i++)
        {
-         blobs[i].xpos += -delta + (int)((delta + .5f) * frand(2.0));
-         blobs[i].ypos += -delta + (int)((delta + .5f) * frand(2.0));
+         st->blobs[i].xpos += -st->delta + (int)((st->delta + .5f) * frand(2.0));
+         st->blobs[i].ypos += -st->delta + (int)((st->delta + .5f) * frand(2.0));
        }
 
-       /* draw blobs to blub array */
-       for (k = 0; k < nBlobCount; ++k)
+       /* draw st->blobs to st->blub array */
+       for (k = 0; k < st->nBlobCount; ++k)
          { 
-           if (blobs[k].ypos > -dradius && blobs[k].xpos > -dradius && blobs[k].ypos < iWinHeight && blobs[k].xpos < iWinWidth)
+           if (st->blobs[k].ypos > -st->dradius && st->blobs[k].xpos > -st->dradius && st->blobs[k].ypos < st->iWinHeight && st->blobs[k].xpos < st->iWinWidth)
              {
-               for (i = 0; i < dradius; ++i)
+               for (i = 0; i < st->dradius; ++i)
                  {
-                   if (blobs[k].ypos + i >= 0 && blobs[k].ypos + i < iWinHeight)
+                   if (st->blobs[k].ypos + i >= 0 && st->blobs[k].ypos + i < st->iWinHeight)
                      {
-                       for (j = 0; j < dradius; ++j)
+                       for (j = 0; j < st->dradius; ++j)
                          {
-                           if (blobs[k].xpos + j >= 0 && blobs[k].xpos + j < iWinWidth)
+                           if (st->blobs[k].xpos + j >= 0 && st->blobs[k].xpos + j < st->iWinWidth)
                              {
-                               if (blub[blobs[k].ypos + i][blobs[k].xpos + j] < iColorCount)
+                               if (st->blub[st->blobs[k].ypos + i][st->blobs[k].xpos + j] < st->iColorCount-1)
                                  {
-                                   if (blub[blobs[k].ypos + i][blobs[k].xpos + j] + blob[i][j] > iColorCount)
-                                     blub[blobs[k].ypos + i][blobs[k].xpos + j] = iColorCount;
+                                   if (st->blub[st->blobs[k].ypos + i][st->blobs[k].xpos + j] + st->blob[i][j] > st->iColorCount-1)
+                                     st->blub[st->blobs[k].ypos + i][st->blobs[k].xpos + j] = st->iColorCount-1;
                                    else 
-                                     blub[blobs[k].ypos + i][blobs[k].xpos + j] += blob[i][j];     
+                                     st->blub[st->blobs[k].ypos + i][st->blobs[k].xpos + j] += st->blob[i][j];     
                                  }
                              }
                          }
@@ -115,59 +101,57 @@ static void Execute( Display *pDisplay,
                  }
              }
            else
-             init_blob(blobs + k);
+             init_blob(st, st->blobs + k);
          }
 
-       memset( pImage->data, 0, pImage->bytes_per_line * pImage->height);
+       memset( st->pImage->data, 0, st->pImage->bytes_per_line * st->pImage->height);
 
-       /* draw blub array to screen */
-       for (i = 0; i < iWinHeight; ++i)
+       /* draw st->blub array to screen */
+       for (i = 0; i < st->iWinHeight; ++i)
          {
-           for (j = 0; j < iWinWidth; ++j)
+           for (j = 0; j < st->iWinWidth; ++j)
              {
-               if (aiColorVals[blub[i][j]] > 0)
-                 XPutPixel( pImage, j, i, aiColorVals[blub[i][j]] );
+               if (st->aiColorVals[st->blub[i][j]] > 0)
+                 XPutPixel( st->pImage, j, i, st->aiColorVals[st->blub[i][j]] );
              }
          }
 
-       XPutImage( pDisplay, MainWindow, *pGC, pImage,
-                  0, 0, 0, 0, iWinWidth, iWinHeight );
-       XSync( pDisplay, False );
+       XPutImage( st->dpy, st->window, st->gc, st->pImage,
+                  0, 0, 0, 0, st->iWinWidth, st->iWinHeight );
 }
 
-static unsigned long * SetPalette(Display *pDisplay, Window Win, char *sColor, signed short *piColorCount )
+static unsigned long * SetPalette(struct state *st )
 {
        XWindowAttributes XWinAttribs;
        XColor Color, *aColors;
-       unsigned long *aiColorVals;
        signed short iColor;
        float nHalfColors;
        
-       XGetWindowAttributes( pDisplay, Win, &XWinAttribs );
+       XGetWindowAttributes( st->dpy, st->window, &XWinAttribs );
        
        Color.red =   random() % 0xFFFF;
        Color.green = random() % 0xFFFF;
        Color.blue =  random() % 0xFFFF;
 
-       if( strcasecmp( sColor, "random" ) && !XParseColor( pDisplay, XWinAttribs.colormap, sColor, &Color ) )
-               fprintf( stderr, "%s: color %s not found in database. Choosing to random...\n", progname, sColor );
+       if( strcasecmp( st->sColor, "random" ) && !XParseColor( st->dpy, XWinAttribs.colormap, st->sColor, &Color ) )
+               fprintf( stderr, "%s: color %s not found in database. Choosing to random...\n", progname, st->sColor );
 
 #ifdef VERBOSE
-       printf( "%s: Base color (RGB): <%d, %d, %d>\n", progclass, Color.red, Color.green, Color.blue );
+       printf( "%s: Base color (RGB): <%d, %d, %d>\n", progname, Color.red, Color.green, Color.blue );
 #endif  /*  VERBOSE */
 
-       *piColorCount = get_integer_resource( "ncolors", "Integer" );
-       if( *piColorCount <   2 )       *piColorCount = 2;
-       if( *piColorCount > 255 )       *piColorCount = 255;
+       st->iColorCount = get_integer_resource(st->dpy,  "ncolors", "Integer" );
+       if( st->iColorCount <   2 )     st->iColorCount = 2;
+       if( st->iColorCount > 255 )     st->iColorCount = 255;
 
-       aColors    = calloc( *piColorCount, sizeof(XColor) );
-       aiColorVals = calloc( *piColorCount, sizeof(unsigned long) );
+       aColors    = calloc( st->iColorCount, sizeof(XColor) );
+       st->aiColorVals = calloc( st->iColorCount, sizeof(unsigned long) );
        
-       for( iColor=0; iColor<*piColorCount; iColor++ )
+       for( iColor=0; iColor < st->iColorCount; iColor++ )
        {
-               nHalfColors = *piColorCount / 2.0F;
+               nHalfColors = st->iColorCount / 2.0F;
                /* Black -> Base Color */
-               if( iColor < (*piColorCount/2) )
+               if( iColor < (st->iColorCount/2) )
                {
                        aColors[ iColor ].red   = ( Color.red   / nHalfColors ) * iColor;
                        aColors[ iColor ].green = ( Color.green / nHalfColors ) * iColor;
@@ -181,52 +165,53 @@ static unsigned long * SetPalette(Display *pDisplay, Window Win, char *sColor, s
                        aColors[ iColor ].blue  = ( ( ( 0xFFFF - Color.blue )  / nHalfColors ) * ( iColor - nHalfColors ) ) + Color.blue;
                }
 
-               if( !XAllocColor( pDisplay, XWinAttribs.colormap, &aColors[ iColor ] ) )
+               if( !XAllocColor( st->dpy, XWinAttribs.colormap, &aColors[ iColor ] ) )
                {
                        /* start all over with less colors */   
-                       XFreeColors( pDisplay, XWinAttribs.colormap, aiColorVals, iColor, 0 );
+                       XFreeColors( st->dpy, XWinAttribs.colormap, st->aiColorVals, iColor, 0 );
                        free( aColors );
-                       free( aiColorVals );
-                       (*piColorCount)--;
+                       free( st->aiColorVals );
+                       (st->iColorCount)--;
 
-                        if (*piColorCount < 6)
+                        if (st->iColorCount < 6)
                           {
                             fprintf (stderr, "%s: insufficient colors!\n",
                                      progname);
                             exit (1);
                           }
 
-                       aColors     = calloc( *piColorCount, sizeof(XColor) );
-                       aiColorVals = calloc( *piColorCount, sizeof(unsigned long) );
+                       aColors     = calloc( st->iColorCount, sizeof(XColor) );
+                       st->aiColorVals = calloc( st->iColorCount, sizeof(unsigned long) );
                        iColor = -1;
                }
                else
-                       aiColorVals[ iColor ] = aColors[ iColor ].pixel;
+                       st->aiColorVals[ iColor ] = aColors[ iColor ].pixel;
        }
 
        free( aColors );
 
-       XSetWindowBackground( pDisplay, Win, aiColorVals[ 0 ] );
+       XSetWindowBackground( st->dpy, st->window, st->aiColorVals[ 0 ] );
 
-       return aiColorVals;
+       return st->aiColorVals;
 }
 
 
-static void Initialize( Display *pDisplay, Window Win, GC *pGC, XImage **ppImage )
+static void Initialize( struct state *st )
 {
        XGCValues gcValues;
        XWindowAttributes XWinAttribs;
-       int iBitsPerPixel, i, j;
+       int /*iBitsPerPixel,*/ i, j;
        unsigned int distance_squared;
        float fraction;
 
        /* Create the Image for drawing */
-       XGetWindowAttributes( pDisplay, Win, &XWinAttribs );
+       XGetWindowAttributes( st->dpy, st->window, &XWinAttribs );
 
        /* Find the preferred bits-per-pixel. (jwz) */
+#if 0
        {
                int pfvc = 0;
-               XPixmapFormatValues *pfv = XListPixmapFormats( pDisplay, &pfvc );
+               XPixmapFormatValues *pfv = XListPixmapFormats( st->dpy, &pfvc );
                for( i=0; i<pfvc; i++ )
                        if( pfv[ i ].depth == XWinAttribs.depth )
                        {
@@ -236,156 +221,212 @@ static void Initialize( Display *pDisplay, Window Win, GC *pGC, XImage **ppImage
                if( pfv )
                        XFree (pfv);
        }
+#endif
 
        /*  Create the GC. */
-       *pGC = XCreateGC( pDisplay, Win, 0, &gcValues );
+       st->gc = XCreateGC( st->dpy, st->window, 0, &gcValues );
 
-       *ppImage = XCreateImage( pDisplay, XWinAttribs.visual, XWinAttribs.depth, ZPixmap, 0, NULL,
-                                                         XWinAttribs.width, XWinAttribs.height, BitmapPad( pDisplay ), 0 );
-       (*ppImage)->data = calloc((*ppImage)->bytes_per_line, (*ppImage)->height);
+       st->pImage = XCreateImage( st->dpy, XWinAttribs.visual, XWinAttribs.depth, ZPixmap, 0, NULL,
+                                                         XWinAttribs.width, XWinAttribs.height, BitmapPad( st->dpy ), 0 );
+       (st->pImage)->data = calloc((st->pImage)->bytes_per_line, (st->pImage)->height);
 
-       iWinWidth = XWinAttribs.width;
-       iWinHeight = XWinAttribs.height;
+       st->iWinWidth = XWinAttribs.width;
+       st->iWinHeight = XWinAttribs.height;
 
        /*  Get the base color. */
-       sColor = get_string_resource( "color", "Color" );
-
-       /*  Get the delta. */
-       delta = get_integer_resource( "delta", "Integer" );
-       if (delta < 1)
-         delta = 1;
-       else if (delta > 20)
-         delta = 20;
+       st->sColor = get_string_resource(st->dpy,  "color", "Color" );
+
+       /*  Get the st->delta. */
+       st->delta = get_integer_resource(st->dpy,  "delta", "Integer" );
+       if (st->delta < 1)
+         st->delta = 1;
+       else if (st->delta > 20)
+         st->delta = 20;
        
-       /*  Get the radius. */
-       radius = get_integer_resource( "radius", "Integer" );
-       if (radius < 2)
-         radius = 2;
-       if (radius > 100)
-         radius = 100;
+       /*  Get the st->radius. */
+       st->radius = get_integer_resource(st->dpy,  "radius", "Integer" );
+       if (st->radius < 2)
+         st->radius = 2;
+       if (st->radius > 100)
+         st->radius = 100;
        
-       radius = (radius / 100.0) * (iWinHeight >> 3);
-        if (radius >= 128) /* should use UCHAR_MAX? */
-          radius = 127; /* dradius should fit in u_char */
+       st->radius = (st->radius / 100.0) * (st->iWinHeight >> 3);
+        if (st->radius >= 128) /* should use UCHAR_MAX? */
+          st->radius = 127; /* st->dradius should fit in u_char */
 
-       dradius = radius * 2;
-       sradius = radius * radius;
+       st->dradius = st->radius * 2;
+       st->sradius = st->radius * st->radius;
 
-       /* create blob */
-       blob = malloc ( dradius * sizeof(unsigned char*));
-       for (i = 0; i < dradius; ++i)
-         blob[i] = malloc( dradius * sizeof(unsigned char));
+       /* create st->blob */
+       st->blob = malloc ( st->dradius * sizeof(unsigned char*));
+       for (i = 0; i < st->dradius; ++i)
+         st->blob[i] = malloc( st->dradius * sizeof(unsigned char));
 
-       /* create blub array */
-       blub = malloc( iWinHeight * sizeof(unsigned char*));
-       for (i = 0; i < iWinHeight; ++i)
-         blub[i] = malloc( iWinWidth * sizeof(unsigned char));
+       /* create st->blub array */
+       st->blub = malloc( st->iWinHeight * sizeof(unsigned char*));
+       for (i = 0; i < st->iWinHeight; ++i)
+         st->blub[i] = malloc( st->iWinWidth * sizeof(unsigned char));
 
-       /* create blob */
-       for (i = -radius; i < radius; ++i)
+       /* create st->blob */
+       for (i = -st->radius; i < st->radius; ++i)
          {
-           for (j = -radius; j < radius; ++j)
+           for (j = -st->radius; j < st->radius; ++j)
              {
                distance_squared = i * i + j * j;
-               if (distance_squared <= sradius)
+               if (distance_squared <= st->sradius)
                  {
                    /* compute density */     
-                   fraction = (float)distance_squared / (float)sradius;
-                   blob[i + radius][j + radius] = pow((1.0 - (fraction * fraction)),4.0) * 255.0;
+                   fraction = (float)distance_squared / (float)st->sradius;
+                   st->blob[i + st->radius][j + st->radius] = pow((1.0 - (fraction * fraction)),4.0) * 255.0;
                  }
                else
                  {
-                   blob[i + radius][j + radius] = 0;
+                   st->blob[i + st->radius][j + st->radius] = 0;
                  }
              }    
          }
        
-       for (i = 0; i < nBlobCount; i++)
+       for (i = 0; i < st->nBlobCount; i++)
          {
-           init_blob(blobs + i);
+           init_blob(st, st->blobs + i);
          }
 }
 
-void screenhack(Display *pDisplay, Window Win )
+static void *
+metaballs_init (Display *dpy, Window window)
 {
-       GC gc;
-       signed short iColorCount = 0;
-       unsigned long *aiColorVals = NULL;
-       XImage *pImage = NULL;
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
 #ifdef VERBOSE
-       time_t nTime = time( NULL );
-       unsigned short iFrame = 0;
+  time_t nTime = time( NULL );
+  unsigned short iFrame = 0;
 #endif  /*  VERBOSE */
-       int delay, cycles, i;
 
-       nBlobCount = get_integer_resource( "count", "Integer" );
-       if( nBlobCount > 255 ) nBlobCount = 255;
-       if( nBlobCount <  2 ) nBlobCount = 2;
+  st->dpy = dpy;
+  st->window = window;
 
-       if( ( blobs = calloc( nBlobCount, sizeof(BLOB) ) ) == NULL )
-       {
-               fprintf( stderr, "%s: Could not allocate %d Blobs\n", progclass, nBlobCount );
-               return;
-       }
+  st->nBlobCount = get_integer_resource(st->dpy,  "count", "Integer" );
+  if( st->nBlobCount > 255 ) st->nBlobCount = 255;
+  if( st->nBlobCount <  2 ) st->nBlobCount = 2;
+
+  if( ( st->blobs = calloc( st->nBlobCount, sizeof(BLOB) ) ) == NULL )
+    {
+      fprintf( stderr, "%s: Could not allocate %d Blobs\n", progname, st->nBlobCount );
+      abort();
+    }
 #ifdef VERBOSE 
-       printf( "%s: Allocated %d Blobs\n", progclass, nBlobCount );
+  printf( "%s: Allocated %d Blobs\n", progname, st->nBlobCount );
 #endif  /*  VERBOSE */
 
-       Initialize( pDisplay, Win, &gc, &pImage );
+  Initialize( st );
 
-       delay = get_integer_resource( "delay", "Integer" );
-       cycles = get_integer_resource( "cycles", "Integer" );
-       i = cycles;
+  st->delay = get_integer_resource(st->dpy,  "delay", "Integer" );
+  st->cycles = get_integer_resource(st->dpy,  "cycles", "Integer" );
 
-       while( 1 )
-       {
-               screenhack_handle_events( pDisplay );
+  st->draw_i = -1;
+  return st;
+}
 
-               if( i++ >= cycles )
-               {
-                        XWindowAttributes XWinAttribs;
-                        XGetWindowAttributes( pDisplay, Win, &XWinAttribs );
-
-                       memset( pImage->data, 0, pImage->bytes_per_line * pImage->height );
-                        XFreeColors( pDisplay, XWinAttribs.colormap, aiColorVals, iColorCount, 0 );
-                       free( aiColorVals );
-                       aiColorVals = SetPalette( pDisplay, Win, sColor, &iColorCount );
-                        XClearWindow( pDisplay, Win );
-                       for (i = 0; i < nBlobCount; i++)
-                         {
-                           init_blob(blobs + i);
-                         }
-                       i = 0;
-               }
 
-               Execute( pDisplay, Win, &gc, pImage, iColorCount - 1, aiColorVals );
 
-               if( delay && !(i % 4) )
-                       usleep(delay);
+static unsigned long
+metaballs_draw (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+
+  if( st->draw_i < 0 || st->draw_i++ >= st->cycles )
+    {
+      int i;
+      XWindowAttributes XWinAttribs;
+      XGetWindowAttributes( st->dpy, st->window, &XWinAttribs );
+
+      memset( st->pImage->data, 0, st->pImage->bytes_per_line * st->pImage->height );
+      XFreeColors( st->dpy, XWinAttribs.colormap, st->aiColorVals, st->iColorCount, 0 );
+      free( st->aiColorVals );
+      st->aiColorVals = SetPalette( st );
+      XClearWindow( st->dpy, st->window );
+      for (i = 0; i < st->nBlobCount; i++)
+        {
+          init_blob(st, st->blobs + i);
+        }
+      st->draw_i = 0;
+    }
+
+  Execute( st );
 
 #ifdef VERBOSE
-               iFrame++;
-               if( nTime - time( NULL ) )
-               {
-                       printf( "%s: %d FPS\n", progclass, iFrame );
-                       nTime = time( NULL );
-                       iFrame = 0;
-               }
+  iFrame++;
+  if( nTime - time( NULL ) )
+    {
+      printf( "%s: %d FPS\n", progname, iFrame );
+      nTime = time( NULL );
+      iFrame = 0;
+    }
 #endif  /*  VERBOSE */
-       }
 
-       free( pImage->data );
-       XDestroyImage( pImage );
-       free( aiColorVals );
-       free( blobs );
-       for (i = 0; i < iWinHeight; ++i)
-         free( blub[i] );
-       free( blub );
-       for (i = 0; i < dradius; ++i)
-         free( blob[i] );
-       free( blob );
+  return st->delay;
+}
+
+
+static void
+metaballs_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+}
+
+static Bool
+metaballs_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  return False;
 }
 
+static void
+metaballs_free (Display *dpy, Window window, void *closure)
+{
+#if 0
+  struct state *st = (struct state *) closure;
+       free( st->pImage->data );
+       XDestroyImage( st->pImage );
+       free( st->aiColorVals );
+       free( st->blobs );
+       for (i = 0; i < st->iWinHeight; ++i)
+         free( st->blub[i] );
+       free( st->blub );
+       for (i = 0; i < st->dradius; ++i)
+         free( st->blob[i] );
+       free( st->blob );
+#endif
+}
+
+
+static const char *metaballs_defaults [] = {
+  ".background: black",
+  ".foreground: white",
+  "*color:    random",
+  "*count:    10",
+  "*cycles:   1000",
+  "*ncolors:  256",
+  "*delay:    10000",
+  "*radius:   100",
+  "*delta:   3",
+#ifdef USE_IPHONE
+  "*ignoreRotation: True",
+#endif
+  0
+};
+
+static XrmOptionDescRec metaballs_options [] = {
+  { "-color",   ".color",   XrmoptionSepArg, 0 },
+  { "-ncolors", ".ncolors", XrmoptionSepArg, 0 },
+  { "-count",   ".count",   XrmoptionSepArg, 0 },
+  { "-delay",   ".delay",   XrmoptionSepArg, 0 },
+  { "-cycles",  ".cycles",  XrmoptionSepArg, 0 },
+  { "-radius",  ".radius",  XrmoptionSepArg, 0 },
+  { "-delta",  ".delta",  XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+
+XSCREENSAVER_MODULE ("MetaBalls", metaballs)
 
 /* End of Module - "metaballs.c" */