New upstream version 3.1.1
[xfishtank.git] / xfish.c
diff --git a/xfish.c b/xfish.c
deleted file mode 100644 (file)
index 8c4c47a..0000000
--- a/xfish.c
+++ /dev/null
@@ -1,1821 +0,0 @@
-
-/*
-
-  *    Original Author Unknow.
-
-  *    8/10/88 - Ported from X10 to X11R3 by:
-
-               Jonathan Greenblatt (jonnyg@rover.umd.edu)
-
-  *    Cleaned up by Dave Lemke (lemke@sun.com)
-
-  *    Ported to monocrome by Jonathan Greenblatt (jonnyg@rover.umd.edu)
-
-  *     05/02/1996 Added TrueColor support by TJ Phan (phan@aur.alcatel.com)
-
-  TODO:
-
-       Parameter parsing needs to be redone.
-
-  *    Throughout 1991 improved for animation and color and multiple
-       fish types.  Broke monocrome in the process.
-       Eric Bina (ebina@ncsa.uiuc.edu)
-
-  *    1992 added extra color remapping control options, as well as ways
-       to let the fish swim on the root window, or an image of the users
-       choice.  Eric Bina (ebina@ncsa.uiuc.edu)
-
-*/
-
-#include <sys/types.h>
-#ifndef hpux
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#ifdef sgi
-#define _BSD_SIGNALS
-#endif
-#include <signal.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <Imlib2.h>
-
-#include "vroot.h"
-#include "xfishy.h"
-#include "bubbles.h"
-#include "medcut.h"
-
-/* constants are based on rand(3C) returning an integer between 0 and 32767 */
-
-#if defined(ultrix) || defined(sun) || defined(linux)
-#define  RAND_I_1_16   134217728
-#define  RAND_F_1_8    268435455.875
-#define  RAND_I_1_4    536870911
-#define  RAND_I_1_2   1073741823
-#define  RAND_I_3_4   1610612735
-#define  RAND_F_MAX   2147483647.0
-#elif defined(__FreeBSD__) || defined(__OpenBSD__)
-#define  RAND_I_1_16   (RAND_MAX>>4)
-#define  RAND_F_1_8    ((float)(RAND_MAX>>3))
-#define  RAND_I_1_4    (RAND_MAX>>2)
-#define  RAND_I_1_2    (RAND_MAX>>1)
-#define  RAND_I_3_4    ((RAND_MAX>>2)*3)
-#define  RAND_F_MAX    ((float)RAND_MAX)
-#else
-#define  RAND_I_1_16   2048
-#define  RAND_F_1_8    4096.0
-#define  RAND_I_1_4    8096
-#define  RAND_I_1_2   16384
-#define  RAND_I_3_4   24575
-#define  RAND_F_MAX   32767.0
-#endif
-
-
-extern unsigned char *ReadBitmap();
-
-
-/* externals for pixmap and bimaps from xfishy.h */
-
-
-/* typedefs for bubble and fish structures, also caddr_t (not used in X.h) */
-typedef struct {
-    int x, y, s, erased, i;
-} bubble;
-typedef struct {
-    int x, y, d, frame, type, i;
-} fish;
-typedef unsigned char *caddrt;
-
-
-/* bubble increment and yes check tables */
-int binc[] = { 0, 64, 56, 48, 40, 32, 24, 16, 8 };
-char *yess[] = { "yes", "Yes", "YES", "on", "On", "ON" };
-
-
-char *pname,                   /* program name from argv[0] */
-  sname[64],                   /* host:display specification */
-  cname[64];                   /* colorname specification */
-char picname[256];             /* name of the background picture file */
-int *Allocated;                        /* mark the used colors */
-int AllocCnt;                  /* count number of colors used */
-int mlimit = 0;                        /* num colors to median cut to. 0 = no limit */
-int climit = 0;                        /* limit on color use. 0 = no limit */
-int DoubleBuf = 0;             /* Should we use double buffering */
-int Overlap = 0;               /* Should fish swim over each other */
-int DoClipping = 0;            /* Should clip masks be used. */
-int blimit = 32,               /* bubble limit */
-    flimit = 10,               /* fish limit */
-    pmode = 1,                 /* pop mode, (1 for lower, 0 for raise) */
-    width,                     /* width of initial window in pixels */
-    height,                    /* height of initial window in pixels */
-    screen,                    /* Default screen of this display */
-    Init_B, *cmap;             /* Initialize bubbles with random y value */
-int Pwidth;                    /* width of background picture */
-int Pheight;                   /* height of background picture */
-int Pcnt;                      /* number of colors in background picture */
-unsigned char *Pdata;          /* data from background picture */
-double rate = 0.2,             /* update interval in seconds */
-    smooth = 0.2;              /* smoothness increment multiplier */
-bubble *binfo;                 /* bubble info structures, allocated 
-                                * dynamically  */
-fish *finfo;                   /* fish info structures, allocated dynamically */
-Display *Dpy;
-Window root_window;
-XImage *xfishA[NUM_FISH][3];   /* fish pixmaps (1 is left-fish, 2 is
-                                * right-fish) */
-XImage *xfishB[NUM_FISH][3];   /* fish pixmaps (1 is left-fish, 2 is
-                                * right-fish) */
-Pixmap pfishA[NUM_FISH][3];
-Pixmap pfishB[NUM_FISH][3];
-
-Pixmap mfishA[NUM_FISH][3];    /* masking pixmaps for fish to use as */
-Pixmap mfishB[NUM_FISH][3];    /*  clipmasks */
-
-Pixmap PicMap;                 /* pixmap for background picture */
-
-Pixmap PixBuf;                 /* Pixmap buffer for double buffering */
-Pixmap ClipBuf;                        /* Clipmask buffer for double buffering */
-
-Pixmap xbubbles[9];            /* bubbles bitmaps (1 to 8, by size in pixels) */
-Window wid;                    /* aqaurium window */
-unsigned long white, black, bcolor;
-Colormap colormap;
-GC c0gc, cpgc;                 /* GCs to operateon the Clipmask buffer */
-GC pgc;
-GC gc, bgc;
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Output desired error message and exit.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-msgdie(message)
-char *message;
-{
-    fprintf(stderr, "%s: %s\n", pname, message);
-    exit(1);
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Set up program defaults, get X defaults, parse command line using getopts.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-parse(argc, argv)
-int argc;
-char **argv;
-{
-    int c;
-    const char *display = getenv("DISPLAY");
-    extern int optind;
-    extern char *optarg;
-    extern double atof();
-
-    pname = argv[0];
-    if (display != NULL)
-       strncpy(sname, display, sizeof(sname) - 1);
-    strcpy(cname, "MediumAquamarine");
-
-    while ((c = getopt(argc, argv, "dDob:C:c:p:m:f:i:r:s")) != EOF) {
-       switch (c) {
-       case 'd':
-           DoClipping = 1;
-           break;
-       case 'D':
-           DoubleBuf = 1;
-           break;
-       case 'o':
-           Overlap = 1;
-           break;
-       case 'b':
-           blimit = atoi(optarg);
-           break;
-       case 'C':
-           climit = atoi(optarg);
-           break;
-       case 'm':
-           mlimit = atoi(optarg);
-           break;
-       case 'c':
-           strncpy(cname, optarg, sizeof(cname) - 1);
-           break;
-       case 'p':
-           strncpy(picname, optarg, sizeof(picname) - 1);
-           break;
-       case 'f':
-           flimit = atoi(optarg);
-           break;
-       case 'i':
-           smooth = atof(optarg);
-           break;
-       case 'r':
-           rate = atof(optarg);
-           break;
-       case 's':
-           pmode = 0;
-           break;
-       case '?':
-           fprintf(stderr, "usage: %s\n", pname);
-           fprintf(stderr, "\t\t[-c color]  background color\n");
-           fprintf(stderr, "\t\t[-b limit]  number of bubbles (default 32)\n");
-           fprintf(stderr, "\t\t[-f limit]  number of fish (default 10)\n");
-           fprintf(stderr, "\t\t[-i mult]   move interval (default 0.2)\n");
-           fprintf(stderr, "\t\t[-r rate]   move frequency (default 0.2)\n");
-           fprintf(stderr, "\t\t[-m num]    median cut to this many colors\n");
-           fprintf(stderr, "\t\t[-C num]    use only this many color cells\n");
-           fprintf(stderr, "\t\t[-d]        clip fish, swim on root window\n");
-           fprintf(stderr, "\t\t[-p file]   fish swim on picture in file\n");
-           fprintf(stderr, "\t\t[host:display]\n");
-           exit(1);
-       }
-    }
-
-    if (optind < argc) {
-       char *display;
-
-       strncpy(sname, argv[optind], sizeof(sname) - 1);
-       display = (char *) malloc(strlen(sname) + 9);
-       snprintf(display, sizeof(display) - 1, "DISPLAY=%s", sname);
-       putenv(display);
-    }
-}
-
-
-void
-erasefish(f, x, y, d)
-fish *f;
-int x, y, d;
-{
-    /*
-     * for something as small as a bubble, it was never worth the
-     * effort of using clipmasks to only turn of the bubble itself, so
-     * we just clear the whole rectangle.
-     */
-    XClearArea(Dpy, wid, x, y, rwidth[f->type], rheight[f->type], False);
-#if 0
-    XGCValues gcv;
-
-    if (f->frame) {
-       gcv.foreground = cmap[0];
-       gcv.fill_style = FillTiled;
-       gcv.fill_style = FillSolid;
-       gcv.tile = pfishB[f->type][d];
-       gcv.ts_x_origin = f->x;
-       gcv.ts_y_origin = f->y;
-       gcv.clip_mask = mfishB[f->type][d];
-       gcv.clip_x_origin = x;
-       gcv.clip_y_origin = y;
-       XChangeGC(Dpy, gc, GCForeground | GCClipMask |
-                 GCTile | GCTileStipXOrigin | GCTileStipYOrigin |
-                 GCFillStyle | GCClipXOrigin | GCClipYOrigin, &gcv);
-       XCopyPlane(Dpy, mfishB[f->type][d], wid, gc, 0, 0,
-                  rwidth[f->type], rheight[f->type], x, y, (unsigned long) 1);
-    } else {
-       gcv.foreground = cmap[0];
-       gcv.fill_style = FillTiled;
-       gcv.fill_style = FillSolid;
-       gcv.tile = pfishA[f->type][d];
-       gcv.ts_x_origin = f->x;
-       gcv.ts_y_origin = f->y;
-       gcv.clip_mask = mfishA[f->type][d];
-       gcv.clip_x_origin = x;
-       gcv.clip_y_origin = y;
-       XChangeGC(Dpy, gc, GCForeground | GCClipMask |
-                 GCTile | GCTileStipXOrigin | GCTileStipYOrigin |
-                 GCFillStyle | GCClipXOrigin | GCClipYOrigin, &gcv);
-       XCopyPlane(Dpy, mfishA[f->type][d], wid, gc, 0, 0,
-                  rwidth[f->type], rheight[f->type], x, y, (unsigned long) 1);
-    }
-#endif
-}
-
-
-/*
- * Just places a fish.  Normally this is all you need for animation, since
- * placeing the fish places an entire rectangle which erases most of the old
- * fish (the rest being cleaned up by the function that called putfish.
- * If DoClipping is set, this function is only called when placing a new
- * fish, otherwise newfish is called.
- */
-void
-putfish(f)
-fish *f;
-{
-    XGCValues gcv;
-
-    if (f->frame) {
-       /*
-        * If we have a pixmap of the fish use it, otherwise use
-        * the XImage of the fish.  In reality we will never use
-        * the XImage since X dies if the pixmap create failed
-        */
-       if (pfishA[f->type][f->d]) {
-           /*
-            * Clipping overrides background picture because
-            * the clipping prevents the drawing of any background
-            * anyway.
-            * DoClipping says just print a fish leaving the
-            * background unchanged.
-            * If there is a background picture, we use a buffer
-            * to prevent flashing, we combine the background
-            * picture and the fish, and then copy the
-            * whole rectangle in.
-            * Default is just copy in fish in with a background
-            * color.
-            */
-           if (DoClipping) {
-               gcv.clip_mask = mfishA[f->type][f->d];
-               gcv.clip_x_origin = f->x;
-               gcv.clip_y_origin = f->y;
-               XChangeGC(Dpy, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-               XCopyArea(Dpy, pfishA[f->type][f->d], wid, gc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x, f->y);
-           } else if (picname[0] != '\0') {
-               gcv.fill_style = FillTiled;
-               gcv.tile = PicMap;
-               gcv.ts_x_origin = -(f->x);
-               gcv.ts_y_origin = -(f->y);
-               gcv.clip_mask = None;
-               XChangeGC(Dpy, pgc, (GCFillStyle |
-                                    GCTile | GCTileStipXOrigin |
-                                    GCTileStipYOrigin | GCClipMask), &gcv);
-               XFillRectangle(Dpy, PixBuf, pgc, 0, 0, rwidth[f->type], rheight[f->type]);
-
-               gcv.clip_mask = mfishA[f->type][f->d];
-               gcv.clip_x_origin = 0;
-               gcv.clip_y_origin = 0;
-               XChangeGC(Dpy, pgc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-               XCopyArea(Dpy, pfishA[f->type][f->d], PixBuf, pgc,
-                         0, 0, rwidth[f->type], rheight[f->type], 0, 0);
-
-               XCopyArea(Dpy, PixBuf, wid, gc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x, f->y);
-           } else {
-               XCopyArea(Dpy, pfishA[f->type][f->d], wid, gc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x, f->y);
-           }
-       } else {
-           XPutImage(Dpy, wid, gc, xfishA[f->type][f->d], 0, 0,
-                     f->x, f->y, rwidth[f->type], rheight[f->type]);
-       }
-       f->frame = 0;
-    } else {
-       /*
-        * same as the above, only for the second frame of animation
-        */
-       if (pfishB[f->type][f->d]) {
-           if (DoClipping) {
-               gcv.clip_mask = mfishB[f->type][f->d];
-               gcv.clip_x_origin = f->x;
-               gcv.clip_y_origin = f->y;
-               XChangeGC(Dpy, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-               XCopyArea(Dpy, pfishB[f->type][f->d], wid, gc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x, f->y);
-           } else if (picname[0] != '\0') {
-               gcv.fill_style = FillTiled;
-               gcv.tile = PicMap;
-               gcv.ts_x_origin = -(f->x);
-               gcv.ts_y_origin = -(f->y);
-               gcv.clip_mask = None;
-               XChangeGC(Dpy, pgc, (GCFillStyle |
-                                    GCTile | GCTileStipXOrigin |
-                                    GCTileStipYOrigin | GCClipMask), &gcv);
-               XFillRectangle(Dpy, PixBuf, pgc, 0, 0, rwidth[f->type], rheight[f->type]);
-
-               gcv.clip_mask = mfishB[f->type][f->d];
-               gcv.clip_x_origin = 0;
-               gcv.clip_y_origin = 0;
-               XChangeGC(Dpy, pgc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-               XCopyArea(Dpy, pfishB[f->type][f->d], PixBuf, pgc,
-                         0, 0, rwidth[f->type], rheight[f->type], 0, 0);
-
-               XCopyArea(Dpy, PixBuf, wid, gc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x, f->y);
-           } else {
-               XCopyArea(Dpy, pfishB[f->type][f->d], wid, gc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x, f->y);
-           }
-       } else {
-           XPutImage(Dpy, wid, gc, xfishB[f->type][f->d], 0, 0,
-                     f->x, f->y, rwidth[f->type], rheight[f->type]);
-       }
-       f->frame = 1;
-    }
-}
-
-
-/*
- * This function can only be called if DoClipping is True.  It is used to
- * move a clipmasked fish.  First the area under the fish is cleared,
- * and then the new fish is masked in.
- * The parameters x, y, amd d are from the old fish that is being
- * erased before the new fish is drawn.
- */
-void
-movefish(f, x, y, d)
-fish *f;
-int x, y, d;
-{
-    XGCValues gcv;
-    int bx, by, bw, bh;
-
-    /*
-     * If we are going to double buffer, we need to find the bounding
-     * rectangle of the overlap of the bounding rectangles of the old
-     * and the new fish.
-     */
-    if (DoubleBuf) {
-       if (x < f->x) {
-           bx = x;
-           bw = f->x - x + rwidth[f->type];
-       } else {
-           bx = f->x;
-           bw = x - f->x + rwidth[f->type];
-       }
-       if (y < f->y) {
-           by = y;
-           bh = f->y - y + rheight[f->type];
-       } else {
-           by = f->y;
-           bh = y - f->y + rheight[f->type];
-       }
-    }
-
-    if (f->frame) {
-       /*
-        * If there is a pixmap use it.
-        * This branchis always taken since right now, if the pixmap
-        * allocation failed, the program dies.
-        */
-       if (pfishA[f->type][f->d]) {
-           /*
-            * A pointless if, you now only come here if
-            * DoClipping is set, I've just been too lazy to
-            * clean up my code.
-            */
-           if (DoClipping) {
-               /*
-                * Set up the masked gc for when we eventually
-                * draw the fish.  Origin is different for
-                * whether we are drawing into the buffer
-                * or into the window
-                */
-               gcv.clip_mask = mfishA[f->type][f->d];
-               if (DoubleBuf) {
-                   gcv.clip_x_origin = f->x - bx;
-                   gcv.clip_y_origin = f->y - by;
-               } else {
-                   gcv.clip_x_origin = f->x;
-                   gcv.clip_y_origin = f->y;
-               }
-               XChangeGC(Dpy, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-
-               /*
-                * If we have a background picture we want to
-                * clear to that background, otherwise we just
-                * do an XCleararea, and let the root restore
-                * the background.
-                */
-               if (picname[0] != '\0') {
-                   gcv.fill_style = FillTiled;
-                   gcv.tile = PicMap;
-                   gcv.clip_mask = mfishB[f->type][d];
-                   if (DoubleBuf) {
-                       gcv.ts_x_origin = 0 - bx;
-                       gcv.ts_y_origin = 0 - by;
-                       gcv.clip_x_origin = x - bx;
-                       gcv.clip_y_origin = y - by;
-                   } else {
-                       gcv.ts_x_origin = 0;
-                       gcv.ts_y_origin = 0;
-                       gcv.clip_x_origin = x;
-                       gcv.clip_y_origin = y;
-                   }
-                   XChangeGC(Dpy, pgc, (GCFillStyle |
-                                        GCTile | GCTileStipXOrigin |
-                                        GCTileStipYOrigin | GCClipMask |
-                                        GCClipXOrigin | GCClipYOrigin), &gcv);
-
-                   /*
-                    * if bouble buffering we clear the buffer
-                    * to the backgound picture, and then
-                    * shape the clip buffer to the shape of
-                    * the fish being erased.
-                    */
-                   if (DoubleBuf) {
-                       XFillRectangle(Dpy, PixBuf, pgc,
-                                      x - bx, y - by, rwidth[f->type], rheight[f->type]);
-                       XFillRectangle(Dpy, ClipBuf, c0gc, 0, 0, 500, 500);
-                       XCopyArea(Dpy, mfishB[f->type][d],
-                                 ClipBuf, cpgc, 0, 0,
-                                 rwidth[f->type], rheight[f->type], x - bx, y - by);
-                   } else {
-                       XFillRectangle(Dpy, wid, pgc, x, y, rwidth[f->type], rheight[f->type]);
-                   }
-               } else {
-                   XClearArea(Dpy, wid, x, y, rwidth[f->type], rheight[f->type], 0);
-               }
-           }
-           /*
-            * Now we just copy in the new fish with a clipmasked gc.
-            * But if we doublebuffered, we copy the new fish into
-            * the buffer, combine the new fishes clipmask in, and
-            * then mask the whole lot from the buffer to the window.
-            */
-           if (DoubleBuf) {
-               XCopyArea(Dpy, pfishA[f->type][f->d], PixBuf, gc, 0, 0,
-                         rwidth[f->type], rheight[f->type], f->x - bx, f->y - by);
-               XCopyArea(Dpy, mfishA[f->type][f->d], ClipBuf, cpgc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x - bx, f->y - by);
-               gcv.clip_mask = ClipBuf;
-               gcv.clip_x_origin = bx;
-               gcv.clip_y_origin = by;
-               XChangeGC(Dpy, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-               XCopyArea(Dpy, PixBuf, wid, gc, 0, 0, bw, bh, bx, by);
-           } else {
-               XCopyArea(Dpy, pfishA[f->type][f->d], wid, gc, 0, 0,
-                         rwidth[f->type], rheight[f->type], f->x, f->y);
-           }
-       } else {
-           if (DoClipping) {
-               if (picname[0] != '\0') {
-                   gcv.fill_style = FillTiled;
-                   gcv.tile = PicMap;
-                   gcv.ts_x_origin = 0;
-                   gcv.ts_y_origin = 0;
-                   gcv.clip_mask = mfishB[f->type][d];
-                   gcv.clip_x_origin = x;
-                   gcv.clip_y_origin = y;
-                   XChangeGC(Dpy, pgc, (GCFillStyle |
-                                        GCTile | GCTileStipXOrigin |
-                                        GCTileStipYOrigin | GCClipMask |
-                                        GCClipXOrigin | GCClipYOrigin), &gcv);
-                   XFillRectangle(Dpy, wid, pgc, x, y, rwidth[f->type], rheight[f->type]);
-               } else {
-                   XClearArea(Dpy, wid, x, y, rwidth[f->type], rheight[f->type], 0);
-               }
-           }
-           XPutImage(Dpy, wid, gc, xfishA[f->type][f->d], 0, 0,
-                     f->x, f->y, rwidth[f->type], rheight[f->type]);
-       }
-       f->frame = 0;
-    } else {
-       /*
-        * Same as above, only for the second frame of animation.
-        */
-       if (pfishB[f->type][f->d]) {
-           if (DoClipping) {
-               gcv.clip_mask = mfishB[f->type][f->d];
-               if (DoubleBuf) {
-                   gcv.clip_x_origin = f->x - bx;
-                   gcv.clip_y_origin = f->y - by;
-               } else {
-                   gcv.clip_x_origin = f->x;
-                   gcv.clip_y_origin = f->y;
-               }
-               XChangeGC(Dpy, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-               if (picname[0] != '\0') {
-                   gcv.fill_style = FillTiled;
-                   gcv.tile = PicMap;
-                   gcv.clip_mask = mfishA[f->type][d];
-                   if (DoubleBuf) {
-                       gcv.ts_x_origin = 0 - bx;
-                       gcv.ts_y_origin = 0 - by;
-                       gcv.clip_x_origin = x - bx;
-                       gcv.clip_y_origin = y - by;
-                   } else {
-                       gcv.ts_x_origin = 0;
-                       gcv.ts_y_origin = 0;
-                       gcv.clip_x_origin = x;
-                       gcv.clip_y_origin = y;
-                   }
-                   XChangeGC(Dpy, pgc, (GCFillStyle |
-                                        GCTile | GCTileStipXOrigin |
-                                        GCTileStipYOrigin | GCClipMask |
-                                        GCClipXOrigin | GCClipYOrigin), &gcv);
-                   if (DoubleBuf) {
-                       XFillRectangle(Dpy, PixBuf, pgc,
-                                      x - bx, y - by, rwidth[f->type], rheight[f->type]);
-                       XFillRectangle(Dpy, ClipBuf, c0gc, 0, 0, 500, 500);
-                       XCopyArea(Dpy, mfishA[f->type][d],
-                                 ClipBuf, cpgc, 0, 0,
-                                 rwidth[f->type], rheight[f->type], x - bx, y - by);
-                   } else {
-                       XFillRectangle(Dpy, wid, pgc, x, y, rwidth[f->type], rheight[f->type]);
-                   }
-               } else {
-                   XClearArea(Dpy, wid, x, y, rwidth[f->type], rheight[f->type], 0);
-               }
-           }
-           if (DoubleBuf) {
-               XCopyArea(Dpy, pfishB[f->type][f->d], PixBuf, gc, 0, 0,
-                         rwidth[f->type], rheight[f->type], f->x - bx, f->y - by);
-               XCopyArea(Dpy, mfishB[f->type][f->d], ClipBuf, cpgc,
-                         0, 0, rwidth[f->type], rheight[f->type], f->x - bx, f->y - by);
-               gcv.clip_mask = ClipBuf;
-               gcv.clip_x_origin = bx;
-               gcv.clip_y_origin = by;
-               XChangeGC(Dpy, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-               XCopyArea(Dpy, PixBuf, wid, gc, 0, 0, bw, bh, bx, by);
-           } else {
-               XCopyArea(Dpy, pfishB[f->type][f->d], wid, gc, 0, 0,
-                         rwidth[f->type], rheight[f->type], f->x, f->y);
-           }
-       } else {
-           if (DoClipping) {
-               if (picname[0] != '\0') {
-                   gcv.fill_style = FillTiled;
-                   gcv.tile = PicMap;
-                   gcv.ts_x_origin = 0;
-                   gcv.ts_y_origin = 0;
-                   gcv.clip_mask = mfishA[f->type][d];
-                   gcv.clip_x_origin = x;
-                   gcv.clip_y_origin = y;
-                   XChangeGC(Dpy, pgc, (GCFillStyle |
-                                        GCTile | GCTileStipXOrigin |
-                                        GCTileStipYOrigin | GCClipMask |
-                                        GCClipXOrigin | GCClipYOrigin), &gcv);
-                   XFillRectangle(Dpy, wid, pgc, x, y, rwidth[f->type], rheight[f->type]);
-               } else {
-                   XClearArea(Dpy, wid, x, y, rwidth[f->type], rheight[f->type], 0);
-               }
-           }
-           XPutImage(Dpy, wid, gc, xfishB[f->type][f->d], 0, 0,
-                     f->x, f->y, rwidth[f->type], rheight[f->type]);
-       }
-       f->frame = 1;
-    }
-}
-
-
-void
-erasebubble(b, s)
-bubble *b;
-int s;
-{
-    XClearArea(Dpy, wid, b->x, b->y, s, s, 0);
-}
-
-
-void
-putbubble(b, s, c)
-bubble *b;
-int s;
-unsigned long c;
-{
-    XGCValues gcv;
-
-    gcv.foreground = c;
-    gcv.clip_mask = xbubbles[s];
-    gcv.clip_x_origin = b->x;
-    gcv.clip_y_origin = b->y;
-    XChangeGC(Dpy, bgc, GCForeground | GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
-    XFillRectangle(Dpy, wid, bgc, b->x, b->y, s, s);
-}
-
-
-/*
- * Find the closest color by allocating it, or picking an already allocated
- * color
- */
-Visual(*visual_info) = NULL;
-int r_mask, g_mask, b_mask;
-int r_shift = 0, g_shift = 0, b_shift = 0;
-int r_bits = 0, g_bits = 0, b_bits = 0;
-void
-FindColor(Dpy, colormap, colr)
-Display *Dpy;
-Colormap colormap;
-XColor *colr;
-{
-    int i, match;
-    double rd, gd, bd, dist, mindist;
-    int cindx;
-    XColor def_colrs[256];
-    int NumCells;
-
-    if (visual_info == NULL && DefaultDepth(Dpy, DefaultScreen(Dpy)) > 8) {
-       visual_info = DefaultVisual(Dpy, DefaultScreen(Dpy));
-       r_mask = visual_info->red_mask;
-       while (!(r_mask & 1)) {
-           r_mask >>= 1;
-           r_shift++;
-       }
-       while (r_mask & 1) {
-           r_mask >>= 1;
-           r_bits++;
-       }
-
-       g_mask = visual_info->green_mask;
-       while (!(g_mask & 1)) {
-           g_mask >>= 1;
-           g_shift++;
-       }
-       while (g_mask & 1) {
-           g_mask >>= 1;
-           g_bits++;
-       }
-
-       b_mask = visual_info->blue_mask;
-       while (!(b_mask & 1)) {
-           b_mask >>= 1;
-           b_shift++;
-       }
-       while (b_mask & 1) {
-           b_mask >>= 1;
-           b_bits++;
-       }
-    }
-
-    if (DefaultDepth(Dpy, DefaultScreen(Dpy)) > 8) {
-       colr->red >>= 16 - r_bits;
-       colr->green >>= 16 - g_bits;
-       colr->blue >>= 16 - b_bits;
-
-       colr->pixel = ((colr->red << r_shift) & visual_info->red_mask) |
-           ((colr->green << g_shift) & visual_info->green_mask) |
-           ((colr->blue << b_shift) & visual_info->blue_mask);
-       return;
-    }
-
-    if (AllocCnt < climit) {
-       match = XAllocColor(Dpy, colormap, colr);
-    } else {
-       match = 0;
-    }
-    if (match == 0) {
-       NumCells = DisplayCells(Dpy, DefaultScreen(Dpy));
-       for (i = 0; i < NumCells; i++) {
-           def_colrs[i].pixel = i;
-       }
-       XQueryColors(Dpy, colormap, def_colrs, NumCells);
-       mindist = 65536.0 * 65536.0;
-       cindx = colr->pixel;
-       for (i = 0; i < NumCells; i++) {
-           rd = (def_colrs[i].red - colr->red) / 256.0;
-           gd = (def_colrs[i].green - colr->green) / 256.0;
-           bd = (def_colrs[i].blue - colr->blue) / 256.0;
-           dist = (rd * rd * rd * rd) + (gd * gd * gd * gd) + (bd * bd * bd * bd);
-           if (dist < mindist) {
-               mindist = dist;
-               cindx = def_colrs[i].pixel;
-           }
-       }
-       colr->pixel = cindx;
-       colr->red = def_colrs[cindx].red;
-       colr->green = def_colrs[cindx].green;
-       colr->blue = def_colrs[cindx].blue;
-    } else {
-       if (Allocated[colr->pixel] == 0) {
-           Allocated[colr->pixel] = 1;
-           AllocCnt++;
-       }
-    }
-}
-
-
-int
-ColorUsage(data, width, height, colrs)
-unsigned char *data;
-int width, height;
-struct colr_data *colrs;
-{
-    int mapping[256];
-    int i, size;
-    int cnt, indx;
-    unsigned char *ptr;
-    struct colr_data newcol[256];
-
-    for (i = 0; i < 256; i++) {
-       mapping[i] = -1;
-    }
-
-    size = width * height;
-    cnt = 0;
-    ptr = data;
-    for (i = 0; i < size; i++) {
-       indx = (int) *ptr;
-       if (mapping[indx] == -1) {
-           mapping[indx] = cnt;
-           newcol[cnt].red = colrs[indx].red;
-           newcol[cnt].green = colrs[indx].green;
-           newcol[cnt].blue = colrs[indx].blue;
-           cnt++;
-       }
-       ptr++;
-    }
-
-    ptr = data;
-    for (i = 0; i < size; i++) {
-       indx = (int) *ptr;
-       *ptr = (unsigned char) mapping[indx];
-       ptr++;
-    }
-
-    for (i = 0; i < cnt; i++) {
-       colrs[i].red = newcol[i].red;
-       colrs[i].green = newcol[i].green;
-       colrs[i].blue = newcol[i].blue;
-    }
-    for (i = cnt; i < 256; i++) {
-       colrs[i].red = 0;
-       colrs[i].green = 0;
-       colrs[i].blue = 0;
-    }
-
-    return (cnt);
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Initialize colormap for background color and required fish colors.
-The fish colors are coded in xfishy.h as a trio of tables.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-init_colormap()
-{
-    int i, j, cnt;
-    int NumCells;
-    XColor hdef, edef;
-    struct colr_data *cdp;
-    struct colr_data colrs[256];
-
-    colormap = XDefaultColormap(Dpy, screen);
-
-    NumCells = DisplayCells(Dpy, DefaultScreen(Dpy));
-    Allocated = (int *) malloc(NumCells * sizeof(int));
-    for (i = 0; i < NumCells; i++) {
-       Allocated[i] = 0;
-    }
-    AllocCnt = 0;
-    if ((climit <= 0) || (climit > NumCells)) {
-       climit = NumCells;
-    }
-
-    Pcnt = 0;
-    if (picname[0] != '\0') {
-       Imlib_Image image = imlib_load_image(picname);
-       if (image == NULL) {
-           fprintf(stderr, "Cannot load image %s\n", picname);
-           picname[0] = 0;
-       } else {
-           imlib_context_set_image(image);
-           imlib_context_set_display(Dpy);
-           imlib_context_set_visual(DefaultVisual(Dpy, screen));
-           Pwidth = imlib_image_get_width();
-           Pheight = imlib_image_get_height();
-           DATA32 *image_data = imlib_image_get_data_for_reading_only();
-           Pdata = malloc(4 * Pwidth * Pheight);
-           for (i = 0; i < Pwidth * Pheight; i++) {
-               Pdata[4 * i] = image_data[i] & 0xFF;
-               Pdata[4 * i + 1] = image_data[i] & 0xFF00;
-               Pdata[4 * i + 2] = image_data[i] & 0xFF0000;
-               Pdata[4 * i + 3] = image_data[i] & 0xFF000000;
-           }
-           Pcnt = ColorUsage(Pdata, Pwidth, Pheight, colrs);
-       }
-    }
-
-    cnt = 0;
-    cnt += Pcnt;
-    for (i = 0; i < NUM_FISH; i++) {
-       cnt += rcolors[i];
-    }
-    cmap = (int *) malloc((cnt + 1) * sizeof(int));
-
-    XLookupColor(Dpy, colormap, cname, &hdef, &edef);
-    hdef.flags = DoRed | DoGreen | DoBlue;
-    FindColor(Dpy, colormap, &hdef);
-    cmap[0] = hdef.pixel;
-
-    if (mlimit > 0) {
-       MedianInit();
-    }
-
-    if (mlimit > 0) {
-       if (picname[0] != '\0') {
-           MedianCount(Pdata, Pwidth, Pheight, colrs);
-       }
-       for (j = 0; j < NUM_FISH; j++) {
-           int *rp, *gp, *bp;
-
-           cdp = (struct colr_data *) malloc(rcolors[j] * sizeof(struct colr_data));
-           rp = rreds[j];
-           gp = rgreens[j];
-           bp = rblues[j];
-           for (i = 0; i < rcolors[j]; i++) {
-               cdp[i].red = *rp++;
-               cdp[i].green = *gp++;
-               cdp[i].blue = *bp++;
-           }
-           MedianCount((unsigned char *) xfishRasterA[j],
-                       (int) rwidth[j], (int) rheight[j], cdp);
-           free((char *) cdp);
-       }
-       MedianSplit(mlimit);
-    }
-
-    cnt = 1;
-    if (picname[0] != '\0') {
-       for (i = 0; i < Pcnt; i++) {
-           int rv, gv, bv;
-
-           rv = colrs[i].red;
-           gv = colrs[i].green;
-           bv = colrs[i].blue;
-
-           if (mlimit > 0) {
-               ConvertColor(&rv, &gv, &bv);
-           }
-
-           hdef.red = rv;
-           hdef.green = gv;
-           hdef.blue = bv;
-           hdef.flags = DoRed | DoGreen | DoBlue;
-           FindColor(Dpy, colormap, &hdef);
-           cmap[cnt] = hdef.pixel;
-           cnt++;
-       }
-    }
-    for (j = 0; j < NUM_FISH; j++) {
-       int *rp, *gp, *bp;
-
-       rp = rreds[j];
-       gp = rgreens[j];
-       bp = rblues[j];
-       for (i = 0; i < rcolors[j]; i++) {
-           int rv, gv, bv;
-
-           rv = *rp++;
-           gv = *gp++;
-           bv = *bp++;
-
-           if (mlimit > 0) {
-               ConvertColor(&rv, &gv, &bv);
-           }
-
-           hdef.red = rv;
-           hdef.green = gv;
-           hdef.blue = bv;
-           hdef.flags = DoRed | DoGreen | DoBlue;
-           FindColor(Dpy, colormap, &hdef);
-           cmap[cnt] = hdef.pixel;
-           if (i == rback[j]) {
-               cmap[cnt] = cmap[0];
-           }
-           cnt++;
-       }
-    }
-
-    bcolor = white;
-}
-
-
-/*
- * Make am image of appropriate depth for display from image data.
- */
-XImage *
-MakeImage(data, width, height)
-unsigned char *data;
-int width, height;
-{
-    int linepad, shiftnum;
-    int shiftstart, shiftstop, shiftinc;
-    int bytesperline;
-    int depth, temp;
-    int w, h;
-    XImage *newimage;
-    unsigned char *bit_data, *bitp, *datap;
-
-    depth = DefaultDepth(Dpy, DefaultScreen(Dpy));
-    if ((depth != 1) && (depth != 2) && (depth != 4) && (depth != 8)) {
-       fprintf(stderr, "Don't know how to format image for display of depth %d\n", depth);
-       exit(1);
-    }
-
-    if (BitmapBitOrder(Dpy) == LSBFirst) {
-       shiftstart = 0;
-       shiftstop = 8;
-       shiftinc = depth;
-    } else {
-       shiftstart = 8 - depth;
-       shiftstop = -depth;
-       shiftinc = -depth;
-    }
-    linepad = 8 - (width % 8);
-    bit_data = (unsigned char *) malloc(((width + linepad) * height) + 1);
-    bitp = bit_data;
-    datap = data;
-    *bitp = 0;
-    shiftnum = shiftstart;
-    for (h = 0; h < height; h++) {
-       for (w = 0; w < width; w++) {
-           temp = *datap++ << shiftnum;
-           *bitp = *bitp | temp;
-           shiftnum = shiftnum + shiftinc;
-           if (shiftnum == shiftstop) {
-               shiftnum = shiftstart;
-               bitp++;
-               *bitp = 0;
-           }
-       }
-       for (w = 0; w < linepad; w++) {
-           shiftnum = shiftnum + shiftinc;
-           if (shiftnum == shiftstop) {
-               shiftnum = shiftstart;
-               bitp++;
-               *bitp = 0;
-           }
-       }
-    }
-
-    bytesperline = (width * depth / 8 + linepad);
-    newimage = XCreateImage(Dpy, DefaultVisual(Dpy, screen), depth,
-                           ZPixmap, 0, (char *) bit_data,
-                           (width + linepad), height, 8, bytesperline);
-
-    return (newimage);
-}
-
-
-
-static unsigned char bits[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Calibrate the pixmaps and bimaps.  The right-fish data is coded in xfishy.h,
-this is transformed to create the left-fish.  The eight bubbles are coded
-in bubbles.h as a two dimensional array.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-init_pixmap()
-{
-    register caddrt p, q, x1A, x1B, x2A, x2B;
-    unsigned char *data;
-    register int i, j, k;
-    int cnt, wcnt;
-
-    cnt = 1;
-    cnt += Pcnt;
-    for (k = 0; k < NUM_FISH; k++) {
-
-       /*
-        * The clipmasks must be created before we remap colors.
-        * otherwise an opaque color might get remapped to a 
-        * transparent color.
-        */
-       if ((DoClipping) || (picname[0] != '\0')) {
-           data = (unsigned char *) malloc((rwidth[k] + 7) / 8 * rheight[k]);
-
-           p = (caddrt) xfishRasterA[k];
-           q = data;
-           wcnt = 0;
-           for (i = 0; i < ((rwidth[k] + 7) / 8 * rheight[k]); i++) {
-               unsigned char bt = 0x00;
-               for (j = 0; j < 8; j++) {
-                   if (*p != rback[k]) {
-                       bt = bt | bits[j];
-                   }
-                   wcnt++;
-                   p++;
-                   if (wcnt == rwidth[k]) {
-                       wcnt = 0;
-                       break;
-                   }
-               }
-               *q++ = bt;
-           }
-           mfishA[k][2] = XCreateBitmapFromData(Dpy, wid,
-                                                (char *) data, rwidth[k], rheight[k]);
-
-           p = (caddrt) xfishRasterA[k];
-           p = p + rwidth[k] - 1;
-           q = data;
-           wcnt = 0;
-           for (i = 0; i < ((rwidth[k] + 7) / 8 * rheight[k]); i++) {
-               unsigned char bt = 0x00;
-               for (j = 0; j < 8; j++) {
-                   if (*p != rback[k]) {
-                       bt = bt | bits[j];
-                   }
-                   wcnt++;
-                   p--;
-                   if (wcnt == rwidth[k]) {
-                       wcnt = 0;
-                       p = p + (2 * rwidth[k]);
-                       break;
-                   }
-               }
-               *q++ = bt;
-           }
-           mfishA[k][1] = XCreateBitmapFromData(Dpy, wid,
-                                                (char *) data, rwidth[k], rheight[k]);
-
-           p = (caddrt) xfishRasterB[k];
-           q = data;
-           wcnt = 0;
-           for (i = 0; i < ((rwidth[k] + 7) / 8 * rheight[k]); i++) {
-               unsigned char bt = 0x00;
-               for (j = 0; j < 8; j++) {
-                   if (*p != rback[k]) {
-                       bt = bt | bits[j];
-                   }
-                   wcnt++;
-                   p++;
-                   if (wcnt == rwidth[k]) {
-                       wcnt = 0;
-                       break;
-                   }
-               }
-               *q++ = bt;
-           }
-           mfishB[k][2] = XCreateBitmapFromData(Dpy, wid,
-                                                (char *) data, rwidth[k], rheight[k]);
-
-           p = (caddrt) xfishRasterB[k];
-           p = p + rwidth[k] - 1;
-           q = data;
-           wcnt = 0;
-           for (i = 0; i < ((rwidth[k] + 7) / 8 * rheight[k]); i++) {
-               unsigned char bt = 0x00;
-               for (j = 0; j < 8; j++) {
-                   if (*p != rback[k]) {
-                       bt = bt | bits[j];
-                   }
-                   wcnt++;
-                   p--;
-                   if (wcnt == rwidth[k]) {
-                       wcnt = 0;
-                       p = p + (2 * rwidth[k]);
-                       break;
-                   }
-               }
-               *q++ = bt;
-           }
-           mfishB[k][1] = XCreateBitmapFromData(Dpy, wid,
-                                                (char *) data, rwidth[k], rheight[k]);
-
-           free((char *) data);
-       }
-
-       if (DisplayPlanes(Dpy, screen) < 8) {
-
-           j = rwidth[k] * rheight[k];
-           x1A = (caddrt) malloc(rwidth[k] * rheight[k]);
-           p = (caddrt) xfishRasterA[k];
-
-
-           q = x1A;
-           for (i = 0; i < j; i++) {
-               *q = cmap[cnt + (int) (*p)];
-               p++;
-               q++;
-           }
-
-           x1B = (caddrt) malloc(rwidth[k] * rheight[k]);
-           p = (caddrt) xfishRasterB[k];
-           q = x1B;
-           for (i = 0; i < j; i++) {
-               *q = cmap[cnt + (int) (*p)];
-               p++;
-               q++;
-           }
-
-           x2A = (caddrt) malloc(rwidth[k] * rheight[k]);
-           for (i = 0; i < rheight[k]; i++) {
-               p = x1A + i * rwidth[k];
-               q = x2A + (i + 1) * rwidth[k] - 1;
-               for (j = 0; j < rwidth[k]; j++) {
-                   *q-- = *p++;
-               }
-           }
-
-           x2B = (caddrt) malloc(rwidth[k] * rheight[k]);
-           for (i = 0; i < rheight[k]; i++) {
-               p = x1B + i * rwidth[k];
-               q = x2B + (i + 1) * rwidth[k] - 1;
-               for (j = 0; j < rwidth[k]; j++) {
-                   *q-- = *p++;
-               }
-           }
-
-           xfishA[k][2] = MakeImage(x1A, rwidth[k], rheight[k]);
-           xfishA[k][1] = MakeImage(x2A, rwidth[k], rheight[k]);
-           xfishB[k][2] = MakeImage(x1B, rwidth[k], rheight[k]);
-           xfishB[k][1] = MakeImage(x2B, rwidth[k], rheight[k]);
-
-           free((char *) x1A);
-           free((char *) x2A);
-           free((char *) x1B);
-           free((char *) x2B);
-       } else {
-           i = DisplayPlanes(Dpy, screen);
-
-           xfishA[k][2] =
-               XGetImage(Dpy, root_window, 0, 0, rwidth[k], rheight[k], 0, ZPixmap);
-
-           p = (caddrt) xfishRasterA[k];
-
-           for (j = 0; j < rheight[k]; j++) {
-               for (i = 0; i < rwidth[k]; i++) {
-                   XPutPixel(xfishA[k][2], i, j, cmap[cnt + (int) (*p)]);
-                   p++;
-               }
-           }
-
-           xfishB[k][2] =
-               XGetImage(Dpy, root_window, 0, 0, rwidth[k], rheight[k], 0, ZPixmap);
-
-           p = (caddrt) xfishRasterB[k];
-
-           for (j = 0; j < rheight[k]; j++) {
-               for (i = 0; i < rwidth[k]; i++) {
-                   XPutPixel(xfishB[k][2], i, j, cmap[cnt + (int) (*p)]);
-                   p++;
-               }
-           }
-
-           xfishA[k][1] =
-               XGetImage(Dpy, root_window, 0, 0, rwidth[k], rheight[k], 0, ZPixmap);
-
-           for (j = 0; j < rheight[k]; j++) {
-               for (i = 0; i < rwidth[k]; i++) {
-                   XPutPixel(xfishA[k][1], i, j,
-                             XGetPixel(xfishA[k][2], rwidth[k] - i - 1, j));
-               }
-           }
-
-           xfishB[k][1] =
-               XGetImage(Dpy, root_window, 0, 0, rwidth[k], rheight[k], 0, ZPixmap);
-
-           for (j = 0; j < rheight[k]; j++) {
-               for (i = 0; i < rwidth[k]; i++) {
-                   XPutPixel(xfishB[k][1], i, j,
-                             XGetPixel(xfishB[k][2], rwidth[k] - i - 1, j));
-               }
-           }
-
-       }
-
-
-       i = DisplayPlanes(Dpy, screen);
-
-       pfishA[k][1] = XCreatePixmap(Dpy, wid, rwidth[k], rheight[k], i);
-       pfishA[k][2] = XCreatePixmap(Dpy, wid, rwidth[k], rheight[k], i);
-       pfishB[k][1] = XCreatePixmap(Dpy, wid, rwidth[k], rheight[k], i);
-       pfishB[k][2] = XCreatePixmap(Dpy, wid, rwidth[k], rheight[k], i);
-
-       if (pfishA[k][1]) {
-           XPutImage(Dpy, pfishA[k][1], gc, xfishA[k][1], 0, 0, 0, 0, rwidth[k], rheight[k]);
-       }
-       if (pfishA[k][2]) {
-           XPutImage(Dpy, pfishA[k][2], gc, xfishA[k][2], 0, 0, 0, 0, rwidth[k], rheight[k]);
-       }
-       if (pfishB[k][1]) {
-           XPutImage(Dpy, pfishB[k][1], gc, xfishB[k][1], 0, 0, 0, 0, rwidth[k], rheight[k]);
-       }
-       if (pfishB[k][2]) {
-           XPutImage(Dpy, pfishB[k][2], gc, xfishB[k][2], 0, 0, 0, 0, rwidth[k], rheight[k]);
-       }
-
-       cnt += rcolors[k];
-    }
-
-    for (i = 1; i <= 8; i++) {
-       xbubbles[i] = XCreateBitmapFromData(Dpy, wid, (char *) xbBits[i], i, i);
-    }
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Toggle secure mode on receipt of signal
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#ifdef sgi
-int
-#else
-void
-#endif
-toggle_secure()
-{
-    pmode = !pmode;
-    if (pmode)
-       XLowerWindow(Dpy, wid);
-    else
-       XRaiseWindow(Dpy, wid);
-    XFlush(Dpy);
-#ifdef sgi
-    return (1);
-#endif
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Initialize signal so that SIGUSR1 causes secure mode to toggle.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-init_signals()
-{
-#if defined(linux)
-    signal(SIGUSR1, toggle_secure);
-#elif defined(MOTOROLA) || defined(SCO)
-    sigset(SIGUSR1, toggle_secure);
-#else
-    struct sigvec vec;
-
-    vec.sv_handler = toggle_secure;
-    vec.sv_mask = 0;
-    vec.sv_onstack = 0;
-
-#ifndef hpux
-    sigvec(SIGUSR1, &vec, &vec);
-#else
-    sigvector(SIGUSR1, &vec, &vec);
-#endif
-#endif
-}
-
-
-void
-set_window_type_desktop(Display *dpy, Window wid)
-{
-    Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DESKTOP;
-
-    _NET_WM_WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
-    _NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
-
-    XChangeProperty(dpy, wid, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
-                   PropModeReplace, (unsigned char *) &_NET_WM_WINDOW_TYPE_DESKTOP, 1);
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Variety of initialization calls, including getting the window up and running.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-initialize()
-{
-    XWindowAttributes winfo;
-    XSetWindowAttributes attr;
-    XGCValues vals;
-    XSizeHints xsh;
-    int i;
-    char *p;
-
-    root_window = VirtualRootWindowOfScreen(DefaultScreenOfDisplay(Dpy));
-
-    XGetWindowAttributes(Dpy, root_window, &winfo);
-    width = winfo.width;
-    height = winfo.height;
-
-    if ((p = XGetDefault(Dpy, pname, "BubbleLimit")) != NULL)
-       blimit = atoi(p);
-    if ((p = XGetDefault(Dpy, pname, "ColorLimit")) != NULL)
-       climit = atoi(p);
-    if ((p = XGetDefault(Dpy, pname, "MedianCutLimit")) != NULL)
-       mlimit = atoi(p);
-    if ((p = XGetDefault(Dpy, pname, "DoClipping")) != NULL)
-       DoClipping = atoi(p);
-    if ((p = XGetDefault(Dpy, pname, "DoubleBuffer")) != NULL)
-       DoubleBuf = atoi(p);
-    if ((p = XGetDefault(Dpy, pname, "Overlap")) != NULL)
-       Overlap = atoi(p);
-    if ((p = XGetDefault(Dpy, pname, "Color")) != NULL)
-       strcpy(cname, p);
-    if ((p = XGetDefault(Dpy, pname, "Picture")) != NULL)
-       strcpy(picname, p);
-    if ((p = XGetDefault(Dpy, pname, "FishLimit")) != NULL)
-       flimit = atoi(p);
-    if ((p = XGetDefault(Dpy, pname, "IncMult")) != NULL)
-       smooth = atof(p);
-    if ((p = XGetDefault(Dpy, pname, "Rate")) != NULL)
-       rate = atof(p);
-    if ((p = XGetDefault(Dpy, pname, "Secure")) != NULL)
-       for (i = 0; i < 6; i++)
-           if (strcmp(p, yess[i]) == 0)
-               pmode = 0;
-
-    /*
-     * DoubleBuf is only useful if we are doing clipping on our
-     * own background picture, otherwise turn it off.
-     */
-    if ((DoubleBuf) && ((!DoClipping) || (picname[0] == '\0'))) {
-       DoubleBuf = 0;
-    }
-
-    init_colormap();
-
-    if (picname[0] != '\0') {
-       imlib_context_set_colormap(colormap);
-       PicMap = XCreatePixmap(Dpy, root_window, Pwidth, Pheight, DisplayPlanes(Dpy, screen));
-       imlib_context_set_drawable(PicMap);
-       imlib_render_image_on_drawable(0, 0);
-
-    }
-
-    if ((DoubleBuf) || (picname[0] != '\0')) {
-       i = DisplayPlanes(Dpy, screen);
-       PixBuf = XCreatePixmap(Dpy, root_window, 500, 500, i);
-       ClipBuf = XCreatePixmap(Dpy, root_window, 500, 500, 1);
-       c0gc = XCreateGC(Dpy, ClipBuf, 0, NULL);
-       XSetForeground(Dpy, c0gc, (unsigned long) 0);
-       XSetFunction(Dpy, c0gc, GXcopy);
-       cpgc = XCreateGC(Dpy, ClipBuf, 0, NULL);
-       XSetFunction(Dpy, cpgc, GXor);
-    }
-
-    attr.override_redirect = True;
-    attr.background_pixel = cmap[0];
-
-    if (!DoClipping || picname[0] != '\0') {
-       wid = XCreateWindow(Dpy, root_window,
-                           1, 1, width - 2, height - 2, 0,
-                           CopyFromParent, CopyFromParent, CopyFromParent,
-                           CWBackPixel | CWOverrideRedirect, &attr);
-
-       if (!wid)
-           msgdie("XCreateWindow failed");
-       set_window_type_desktop(Dpy, wid);
-    } else {
-       wid = root_window;
-       XClearArea(Dpy, wid, 0, 0, 0, 0, False);
-    }
-
-    vals.foreground = vals.background = cmap[0];
-    vals.graphics_exposures = False;
-    gc = XCreateGC(Dpy, wid, GCForeground | GCBackground | GCGraphicsExposures, &vals);
-    pgc = XCreateGC(Dpy, wid, GCForeground | GCBackground | GCGraphicsExposures, &vals);
-    bgc = XCreateGC(Dpy, wid, GCForeground | GCBackground | GCGraphicsExposures, &vals);
-
-    for (i = 0; i < NUM_FISH; i++) {
-       pfishA[i][0] = 0;
-       pfishA[i][1] = 0;
-       pfishA[i][2] = 0;
-       pfishB[i][0] = 0;
-       pfishB[i][1] = 0;
-       pfishB[i][2] = 0;
-
-       mfishA[i][0] = 0;
-       mfishA[i][1] = 0;
-       mfishA[i][2] = 0;
-       mfishB[i][0] = 0;
-       mfishB[i][1] = 0;
-       mfishB[i][2] = 0;
-    }
-
-    init_pixmap();
-    init_signals();
-
-    if (!DoClipping || picname[0] != '\0') {
-       XStoreName(Dpy, wid, pname);
-
-       xsh.flags = USSize | USPosition | PPosition | PSize;
-       xsh.x = xsh.y = 0;
-       xsh.width = width;
-       xsh.height = height;
-       XSetNormalHints(Dpy, wid, &xsh);
-
-       if (picname[0] != '\0') {
-           XSetWindowBackgroundPixmap(Dpy, wid, PicMap);
-       }
-
-       XMapWindow(Dpy, wid);
-    }
-
-    binfo = (bubble *) malloc(blimit * sizeof(bubble));
-    finfo = (fish *) malloc(flimit * sizeof(fish));
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Create a new bubble.  Placement along the x axis is random, as is the size of
-the bubble.  Increment value is determined by speed.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-new_bubble(b0)
-bubble *b0;
-{
-    register int s;
-    register bubble *b = b0;
-
-    b->x = width * (rand() / RAND_F_MAX);
-    if (Init_B)
-       b->y = (height / 16) * (rand() / RAND_I_1_16 + 1) - 1;
-    else
-       b->y = height - 1;
-    b->s = s = 1.0 + rand() / RAND_F_1_8;
-    if ((b->i = smooth * height / (float) binc[s]) == 0)
-       b->i = 1;
-    b->erased = 0;
-    putbubble(b, s, bcolor);
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Erase old bubbles, move and draw new bubbles.  Random left-right factor
-can move bubble one size-unit in either direction.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-step_bubbles()
-{
-    register int i, j, s;
-    register bubble *b;
-
-    for (i = 0; i < blimit; i++) {
-       b = &binfo[i];
-       s = b->s;
-       /* clear */
-       if ((b->y > 0) && (b->erased == 0)) {
-           if ((DoClipping) || (picname[0] != '\0')) {
-               erasebubble(b, s);
-           } else {
-               putbubble(b, s, cmap[0]);
-           }
-       }
-       if ((b->y -= b->i) > 0) {
-           j = rand();
-           if (j < RAND_I_1_4) {
-               b->x -= s;
-           } else if (j > RAND_I_3_4) {
-               b->x += s;
-           }
-           putbubble(b, s, bcolor);
-       } else {
-           if (rand() < RAND_I_1_4) {
-               new_bubble(b);
-           }
-       }
-       b->erased = 0;
-    }
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Fish over bubble collision detection.  The specified fish is checked against
-all bubbles for overlap.  This way we don't try and erase bubbles that are
-already gone.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-collide_bubbles(f0, ofx, ofy)
-fish *f0;
-int ofx, ofy;
-{
-    int i, delta;
-    register fish *f = f0;
-    register bubble *b;
-
-    for (i = 0; i < blimit; i++) {
-       b = &binfo[i];
-       delta = b->x - ofx;
-       if ((delta >= 0) && (delta <= (rwidth[f->type] - b->s))) {
-           delta = b->y - ofy;
-           if ((delta >= 0) && (delta <= (rheight[f->type] - b->s))) {
-               b->erased = 1;
-               continue;
-           }
-       }
-       delta = b->x - f->x;
-       if ((delta >= 0) && (delta <= (rwidth[f->type] - b->s))) {
-           delta = b->y - f->y;
-           if ((delta >= 0) && (delta <= (rheight[f->type] - b->s))) {
-               b->erased = 1;
-               continue;
-           }
-       }
-    }
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Fish collision detection.  The specified fish is checked against all other
-fish for overlap.  The xt parameter specifies a x axis multiplier for overlap.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-int
-collide_fish(f0, xt)
-fish *f0;
-int xt;
-{
-    int i, j;
-    register fish *f = f0;
-
-    if (Overlap) {
-       return (0);
-    }
-
-    for (i = 0; i < flimit; i++) {
-       if (&finfo[i] != f) {
-           j = finfo[i].y - f->y;
-           if ((j > -rheight[finfo[i].type]) && (j < rheight[f->type])) {
-               j = finfo[i].x - f->x;
-               if ((j > -xt * rwidth[finfo[i].type]) && (j < xt * rwidth[f->type])) {
-                   return (1);
-               }
-           }
-       }
-    }
-    return (0);
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Create a new fish.   Placement along the y axis is random, as is the side
->from which the fish appears.  Direction is determined from side.  Increment
-is also random.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-new_fish(f0)
-fish *f0;
-{
-    int i, collide;
-    fish *f = f0;
-
-    f->type = rand() % NUM_FISH;
-    for (i = 0, collide = 1; (i < 16) && (collide); i++) {
-       f->y = (height - rheight[f->type]) * (rand() / RAND_F_MAX);
-       if ((f->i = smooth * width / (8.0 * (1.0 + rand() / RAND_F_1_8))) == 0) {
-           f->i = 1;
-       }
-       if (rand() < RAND_I_1_2) {
-           f->d = 1;
-           f->x = width;
-       } else {
-           f->d = 2;
-           f->x = -rwidth[f->type];
-       }
-       collide = collide_fish(f, 2);
-    }
-
-    if (!collide) {
-       putfish(f);
-    } else {
-       f->d = 0;
-    }
-
-    f->frame = 0;
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Move all the fish.  Clearing old fish is accomplished by masking only the
-exposed areas of the old fish.  Random up-down factor can move fish 1/4 a
-fish height in either direction, if no collisions are caused.
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-move_fish()
-{
-    register int i, j, x, y, ofx, ofy, ofd, done;
-    register fish *f;
-
-    for (i = 0; i < flimit; i++) {
-       f = &finfo[i];
-       if (f->d) {
-           ofx = f->x;
-           ofy = f->y;
-           ofd = f->d;
-
-           if (f->d == 1) {
-               done = ((f->x -= f->i) < -rwidth[f->type]);
-               x = f->x + rwidth[f->type];
-           } else if (f->d == 2) {
-               done = ((f->x += f->i) > width);
-               x = f->x - f->i;
-           }
-
-           if (!collide_fish(f, 1)) {
-               if (!done) {
-                   j = rand();
-                   if (j < RAND_I_1_4) {
-                       y = f->i / 4;
-                   } else if (j > RAND_I_3_4) {
-                       y = f->i / -4;
-                   } else {
-                       y = 0;
-                   }
-
-                   if (y) {
-                       f->y += y;
-                       if (collide_fish(f, 1)) {
-                           f->y -= y;
-                           y = 0;
-                       } else {
-                           if (y > 0) {
-                               j = f->y - y;
-                           } else {
-                               j = f->y + rheight[f->type];
-                               y *= -1;
-                           }
-                       }
-                   }
-                   if (DoClipping) {
-                       movefish(f, ofx, ofy, ofd);
-                   } else {
-                       putfish(f);
-                       XClearArea(Dpy, wid, x, ofy, f->i, rheight[f->type], 0);
-                       if (y) {
-                           XClearArea(Dpy, wid, ofx, j, rwidth[f->type], y, 0);
-                       }
-                   }
-
-               } else {
-                   XClearArea(Dpy, wid, x, f->y, f->i, rheight[f->type], 0);
-                   new_fish(f);
-               }
-           } else {
-               if ((f->d = 3 - f->d) == 1) {
-                   f->x = f->x - 2 * f->i;
-                   x = f->x + rwidth[f->type];
-               } else {
-                   f->x = f->x + 2 * f->i;
-                   x = f->x - f->i;
-               }
-               if (DoClipping) {
-                   movefish(f, ofx, ofy, ofd);
-               } else {
-                   putfish(f);
-                   XClearArea(Dpy, wid, x, f->y, f->i, rheight[f->type], 0);
-               }
-           }
-           if ((!DoClipping) || (picname[0] == '\0')) {
-               collide_bubbles(f, ofx, ofy);
-           }
-       } else {
-           new_fish(f);
-       }
-    }
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Higher-resolution sleep
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-void
-high_res_sleep(seconds)
-double seconds;
-{
-    struct timeval timeout;
-
-    timeout.tv_sec = seconds;
-    timeout.tv_usec = (seconds - timeout.tv_sec) * 1000000.0;
-    select(0, NULL, NULL, NULL, &timeout);
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-int
-main(argc, argv)
-int argc;
-char **argv;
-{
-    int i;
-    XEvent ev;
-
-    parse(argc, argv);
-    if ((Dpy = XOpenDisplay(sname)) == 0)
-       msgdie("XOpenDisplay failed");
-    screen = DefaultScreen(Dpy);
-
-    white = WhitePixel(Dpy, screen);
-    black = BlackPixel(Dpy, screen);
-    initialize();
-
-    srand((unsigned) getpid());
-
-    Init_B = 1;
-    for (i = 0; i < blimit; i++)
-       new_bubble(&binfo[i]);
-    for (i = 0; i < flimit; i++) {
-       finfo[i].x = 0;
-       finfo[i].y = 0;
-       finfo[i].type = 0;
-    }
-    for (i = 0; i < flimit; i++)
-       new_fish(&finfo[i]);
-    if (pmode)
-       XLowerWindow(Dpy, wid);
-    else
-       XRaiseWindow(Dpy, wid);
-    XFlush(Dpy);
-
-    Init_B = 0;
-
-    for (;;) {
-       if (XPending(Dpy))
-           XNextEvent(Dpy, &ev);
-
-       high_res_sleep(rate);
-
-       move_fish();
-
-       step_bubbles();
-
-       if (pmode)
-           XLowerWindow(Dpy, wid);
-       else
-           XRaiseWindow(Dpy, wid);
-    }
-
-    return 0;
-}
This page took 0.031421 seconds and 4 git commands to generate.