X-Git-Url: http://git.ieval.ro/?p=xfishtank.git;a=blobdiff_plain;f=xfish.c;fp=xfish.c;h=0000000000000000000000000000000000000000;hp=8c4c47a9279ace985c76a6a878df22089795e870;hb=da1c4a843de05b6ee70dc60fa1fcb4b5ec2d606e;hpb=46b872af07138bfc36763f380b876098af4a6b5d diff --git a/xfish.c b/xfish.c deleted file mode 100644 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 -#ifndef hpux -#include -#else -#include -#endif - -#include -#include -#include -#include -#ifdef sgi -#define _BSD_SIGNALS -#endif -#include -#include -#include -#include - -#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; -}