v04i091: Aquarium, Part01/02
Dan Heller
argv at island.uu.net
Fri Aug 18 06:18:57 AEST 1989
Submitted-by: uunet!umd5.umd.edu!jonnyg (Jon Greenblatt)
Posting-number: Volume 4, Issue 91
Archive-name: aquarium/part01
This is a color/monocrome living aquarium program. The original
author is unknown. The command line parsing needs to be fixed but
other than that things seem to be in good shape. After unarchiving this
and setting up the Makefile, type "make unshar" to uncompress the
bitmap file.
JonnyG.
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by rover.umd.edu!jonnyg on Wed Aug 16 10:53:04 EDT 1989
# Contents: FIRST.README Imakefile Makefile xfish.c
echo x - FIRST.README
sed 's/^@//' > "FIRST.README" <<'@//E*O*F FIRST.README//'
Ported from X10R4 to X11R3 by Jonathan Roger Greenblatt (jonnyg at rover.umd.edu)
8/10/89
Original Author of the X10 version is Unknown.
XAquarium
===========
XAquarium is an X Windows application which creates a full-screen background
window complete with color fish and translucent bubbles. This program is
not to be confused with the older 'xfish' which featured small monochrome
fish on a monochrome background. On the contrary. XAquarium features
highly detailed fish in living color, translucent bubbles, and a full color
background. With that confusion removed, the program will be referred to
as 'XFish' from this point forward.
Scientific Note: Research has shown that a moving aquarium background creates
a soothing and relaxing atmosphere, thereby reducing the stresses associated
with day-to-day workstation usage. A corresponding increase in productivity
should result, although this is yet to be shown.
XFish Creation
--------------
The package includes four files ...
* FIRST.README (this file)
* Makefile (makefile for complete compilation)
* xfish.c (application code)
* xfishy.c (fairly large file containing pixmaps and bitmaps)
After unpacking the shell archive, running 'make' is all that is required
to compile XFish.
XFish Usage
-----------
usage: xfish [-b limit][-c color][-f limit][-i mult][-r rate][-s][host:display]
XFish is designed to run efficiently on defaults alone, but like any good X
program, command line options are provided ...
* -b specifies the bubble limit (default = 32)
* -c specifies the background color (default = MediumAquamarine)
* -f specifies the fish limit (default = 2, for historical reasons)
* -i specifies the increment multipler (default = 1.0)
* -r specifies the update rate (default = 1.0 seconds)
* -s activates secure mode, raising the window for use with xsecure
* host:display is the standard X server specifier
as well as ~/.Xdefault options for all of the above ...
* xfish.BubbleLimit: 32
* xfish.Color: MediumAquamarine
* xfish.FishLimit: 2
* xfish.IncMult: 1.0
* xfish.Rate: 1.0
* xfish.Secure: No
A few notes on XFish performance ...
* Bubbles are something of a CPU drain. Overall performance can
be improved by using low bubble limits. If the bubbles appear
to be flashing, try fewer bubbles, or turn off bubbles using -b0.
* Off-screen display memory is used for fish if available. This
results in astonishing performance gains. For this reason,
fish are not much of a CPU drain, and higher fish limits can
easily be used.
* Changing the update rate is the most effective way to control
impact on system performance. The default of 1 second results
in less than a 10% CPU usage on a single user 350. Higher values
may be desirable on more burdened system.
* A zero update rate using -r0 creates some great looking displays.
Try 'xfish -r0 -f0' and 'xfish -r0 -b0 -f8' (the latter really
shows off the capabilities of the Topcat board, and is simply
astounding on the Catseye board).
* Decreasing the increment multiplier, using -i 0.1 for example, is
especially useful in conjunction with a zero update rate. If you
prefer '911 Turbo' fish, use a multiplier of greater than one.
* The aquarium window obscures most of the root window. A one pixel
border is provided around the window to allow quick access to the
root window. An alternative, which proves very useful with the
secure option, is to iconize the aquarium (until ready to xsecBure).
* Sending SIGUSR1 (16) to the XFish process (using 'kill -16 <pid>')
will toggle the raise-lower mode. Using this technique, xsecure
can be started without the need to restart XFish.
XFish Enhancements
------------------
XFish was intended to be run as a background window, and as such it was
designed to minimize CPU impact. Although enhancement requests will be
cheerfully accepted, it is unlikely that features will be added to the
detriment of overall performance. On the other hand, any recommendations
which could benefit overall performance will be utilized.
@//E*O*F FIRST.README//
chmod u=r,g=r,o=r FIRST.README
echo x - Imakefile
sed 's/^@//' > "Imakefile" <<'@//E*O*F Imakefile//'
INCLUDES = -I. -I$(TOP) -I$(TOP)/X11
LOCAL_LIBRARIES = $(XLIB)
SYS_LIBRARIES = -lm
SRCS = xfish.c xfishy.c
OBJS = xfish.o xfishy.o
ComplexProgramTarget(xfish)
# Make the export sharchive.
shar: xaqua.shar
xaqua.shar: xaqua.shar1 xaqua.shar2
xaqua.shar1: FIRST.README Imakefile Makefile xfish.c
shar FIRST.README Imakefile Makefile xfish.c >xaqua.shar1
xfishy.c.Z: xfishy.c
compress -c xfishy.c >xfishy.c.Z
xfishy.c.Z.uu: xfishy.c.Z
uuencode xfishy.c.Z xfishy.c.Z >xfishy.c.Z.uu
xaqua.shar2: xfishy.c.Z.uu
shar xfishy.c.Z.uu >xaqua.shar2
# Unpack the compressed, uuencoded, shared bitmap.
unshar:
uudecode xfishy.c.Z.uu
uncompress xfishy.c.Z
# Make the export tarchive.
tar: xaqua.tar.Z
xaqua.tar.Z: xaqua.tar
rm -f xaqua.tar.Z
compress xaqua.tar
xaqua.tar: FIRST.README Imakefile Makefile xfish.c xfishy.c
tar chf xaqua.tar FIRST.README Imakefile Makefile xfish.c xfishy.c
@//E*O*F Imakefile//
chmod u=r,g=r,o=r Imakefile
echo x - Makefile
sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
# Makefile generated by imake - do not edit!
# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $
###########################################################################
# X Window System Makefile generated from template file Imake.tmpl
# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $
#
# Do not change the body of the imake template file. Server-specific
# parameters may be set in the appropriate .macros file; site-specific
# parameters (but shared by all servers) may be set in site.def. If you
# make any changes, you'll need to rebuild the makefiles using
# "make World" (at best) or "make Makefile; make Makefiles" (at least) in
# the top level directory.
#
# If your C preprocessor doesn't define any unique symbols, you'll need
# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
# "make Makefile", "make Makefiles", or "make World").
#
# If you absolutely can't get imake to work, you'll need to set the
# variables at the top of each Makefile as well as the dependencies at the
# bottom (makedepend will do this automatically).
#
###########################################################################
# platform-specific configuration parameters - edit Rt.macros to change
# platform: $XConsortium: Rt.macros,v 1.47 88/10/25 18:39:43 keith Exp $
# platform: $XConsortium: IBM.macros,v 1.22 88/10/25 18:39:31 keith Exp $
AS = as
CPP = /lib/cpp
LD = ld
LINT = lint
MAKE = make
INSTALL = install
TAGS = ctags
RM = rm -f
MV = mv
LS = ls
CP = cp
STD_CPP_DEFINES =
STD_DEFINES =
BOOTSTRAPCFLAGS =
CC = hc
LDCOMBINEFLAGS = -X -r
LN = ln -s
RANLIB = ranlib
RANLIBINSTFLAGS = -t
AR = ar cq
LINTOPTS = -axz
LINTLIBFLAG = -C
PCC = pcc
###########################################################################
# site-specific configuration parameters - edit site.def to change
# site: $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $
###########################################################################
# definitions common to all Makefiles - do not edit
SHELL = /bin/sh
DESTDIR =
USRLIBDIR = $(DESTDIR)/usr/lib
BINDIR = $(DESTDIR)/usr/bin/X11
INCDIR = $(DESTDIR)/usr/include/X11
ADMDIR = $(DESTDIR)/usr/adm
LIBDIR = $(USRLIBDIR)/X11
LINTLIBDIR = $(USRLIBDIR)/lint
FONTDIR = $(LIBDIR)/fonts
XINITDIR = $(LIBDIR)/xinit
XDMDIR = $(LIBDIR)/xdm
UWMDIR = $(LIBDIR)/uwm
AWMDIR = $(LIBDIR)/awm
TWMDIR = $(LIBDIR)/twm
MANPATH = $(DESTDIR)/usr/man
MANSOURCEPATH = $(MANPATH)/man
MANDIR = $(MANSOURCEPATH)n
LIBMANDIR = $(MANSOURCEPATH)3
XAPPLOADDIR = $(LIBDIR)/app-defaults
INSTBINFLAGS = -m 0755
INSTUIDFLAGS = -m 4755
INSTLIBFLAGS = -m 0664
INSTINCFLAGS = -m 0444
INSTMANFLAGS = -m 0444
INSTAPPFLAGS = -m 0444
INSTKMEMFLAGS = -m 4755
FCFLAGS = -t
CDEBUGFLAGS = -O
PATHSEP = /
DEPEND = $(DEPENDSRC)/makedepend
IMAKE = $(IMAKESRC)/imake
RGB = $(RGBSRC)/rgb
FC = $(BDFTOSNFSRC)/bdftosnf
MKFONTDIR = $(MKFONTDIRSRC)/mkfontdir
MKDIRHIER = $(SCRIPTSSRC)/mkdirhier.sh
CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES)
LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT
LDFLAGS = $(CDEBUGFLAGS) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES)
TOP = ./../../..
CLIENTSRC = $(TOP)/clients
DEMOSRC = $(TOP)/demos
LIBSRC = $(TOP)/lib
FONTSRC = $(TOP)/fonts
INCLUDESRC = $(TOP)/X11
SERVERSRC = $(TOP)/server
UTILSRC = $(TOP)/util
SCRIPTSSRC = $(UTILSRC)/scripts
EXAMPLESRC = $(TOP)/examples
CONTRIBSRC = $(TOP)/contrib
DOCSRC = $(TOP)/doc
RGBSRC = $(TOP)/rgb
DEPENDSRC = $(UTILSRC)/makedepend
IMAKESRC = $(UTILSRC)/imake
IRULESRC = $(UTILSRC)/imake.includes
XLIBSRC = $(LIBSRC)/X
XMUSRC = $(LIBSRC)/Xmu
TOOLKITSRC = $(LIBSRC)/Xt
AWIDGETSRC = $(LIBSRC)/Xaw
OLDXLIBSRC = $(LIBSRC)/oldX
BDFTOSNFSRC = $(FONTSRC)/bdftosnf
MKFONTDIRSRC = $(FONTSRC)/mkfontdir
EXTENSIONSRC = $(TOP)/extensions
EXTENSIONLIB = $(EXTENSIONSRC)/lib/libXext.a
XLIB = $(XLIBSRC)/libX11.a
XMULIB = $(XMUSRC)/libXmu.a
OLDXLIB = $(OLDXLIBSRC)/liboldX.a
XTOOLLIB = $(TOOLKITSRC)/libXt.a
XAWLIB = $(AWIDGETSRC)/libXaw.a
LINTXLIB = $(XLIBSRC)/llib-lX11.ln
LINTXMU = $(XMUSRC)/llib-lXmu.ln
LINTXTOOL = $(TOOLKITSRC)/llib-lXt.ln
LINTXAW = $(AWIDGETSRC)/llib-lXaw.ln
INCLUDES = -I$(TOP)
MACROFILE = Rt.macros
ICONFIGFILES = $(IRULESRC)/Imake.tmpl \
$(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def
IMAKE_DEFINES =
IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \
-s Makefile $(IMAKE_DEFINES)
RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \
.emacs_* tags TAGS make.log MakeOut
###########################################################################
# rules: $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $
###########################################################################
# start of Imakefile
INCLUDES = -I. -I$(TOP) -I$(TOP)/X11
LOCAL_LIBRARIES = $(XLIB)
SYS_LIBRARIES = -lm
SRCS = xfish.c xfishy.c
OBJS = xfish.o xfishy.o
PROGRAM = xfish
all:: xfish
xfish: $(OBJS) $(LOCAL_LIBRARIES)
$(RM) $@
$(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES)
relink::
$(RM) $(PROGRAM)
$(MAKE) $(MFLAGS) $(PROGRAM)
install:: xfish
$(INSTALL) -c $(INSTALLFLAGS) xfish $(BINDIR)
install.man:: xfish.man
$(INSTALL) -c $(INSTMANFLAGS) xfish.man $(MANDIR)/xfish.n
depend:: $(DEPEND)
depend::
$(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS)
$(DEPEND):
@echo "making $@"; \
cd $(DEPENDSRC); $(MAKE)
clean::
$(RM) $(PROGRAM)
# Make the export sharchive.
shar: xaqua.shar
xaqua.shar: xaqua.shar1 xaqua.shar2
xaqua.shar1: FIRST.README Imakefile Makefile xfish.c
shar FIRST.README Imakefile Makefile xfish.c >xaqua.shar1
xfishy.c.Z: xfishy.c
compress -c xfishy.c >xfishy.c.Z
xfishy.c.Z.uu: xfishy.c.Z
uuencode xfishy.c.Z xfishy.c.Z >xfishy.c.Z.uu
xaqua.shar2: xfishy.c.Z.uu
shar xfishy.c.Z.uu >xaqua.shar2
# Unpack the compressed, uuencoded, shared bitmap.
unshar:
uudecode xfishy.c.Z.uu
uncompress xfishy.c.Z
# Make the export tarchive.
tar: xaqua.tar.Z
xaqua.tar.Z: xaqua.tar
rm -f xaqua.tar.Z
compress xaqua.tar
xaqua.tar: FIRST.README Imakefile Makefile xfish.c xfishy.c
tar chf xaqua.tar FIRST.README Imakefile Makefile xfish.c xfishy.c
###########################################################################
# Imake.tmpl common rules for all Makefiles - do not edit
emptyrule::
clean::
$(RM_CMD) \#*
Makefile:: $(IMAKE)
Makefile:: Imakefile \
$(IRULESRC)/Imake.tmpl \
$(IRULESRC)/Imake.rules \
$(IRULESRC)/site.def \
$(IRULESRC)/$(MACROFILE)
- at if [ -f Makefile ]; then \
echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
else exit 0; fi
$(IMAKE_CMD) -DTOPDIR=$(TOP)
$(IMAKE):
@echo "making $@"; \
cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS)
tags::
$(TAGS) -w *.[ch]
$(TAGS) -xw *.[ch] > TAGS
###########################################################################
# empty rules for directories that do not have SUBDIRS - do not edit
install::
@echo "install done"
install.man::
@echo "install.man done"
Makefiles::
###########################################################################
# dependencies generated by makedepend
# DO NOT DELETE
xfish.o: /usr/include/sys/time.h /usr/include/sys/time.h /usr/include/stdio.h
xfish.o: /usr/include/signal.h ./../../../X11/Xlib.h /usr/include/sys/types.h
xfish.o: ./../../../X11/X.h ./../../../X11/Xutil.h
xfishy.o: ./../../../X11/Xlib.h /usr/include/sys/types.h ./../../../X11/X.h
@//E*O*F Makefile//
chmod u=rw,g=rw,o=rw Makefile
echo x - xfish.c
sed 's/^@//' > "xfish.c" <<'@//E*O*F xfish.c//'
static char ident[] = "@(#)$Header: XFish release 3, revision 1, 11 Aug 1989 $";
/*
* Original Author Unknow.
* 8/10/88 - Ported from X10 to X11R3 by:
Jonathan Greenblatt (jonnyg at rover.umd.edu)
* Cleaned up by Dave Lemke (lemke at sun.com)
* Ported to monocrome by Jonathan Greenblatt (jonnyg at rover.umd.edu)
TODO:
Parameter parsing needs to be redone.
*/
#ifndef HPUX
#include <sys/time.h>
#else
#include <time.h>
#endif
#include <stdio.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
/* constants are based on rand(3C) returning an integer between 0 and 32767 */
#ifndef HPUX
#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
#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
/* externals for pixmap and bimaps from xfishy.c */
extern int rwidth,
rheight,
rcolors,
rback,
rreds[],
rgreens[],
rblues[];
extern short xfishRaster[];
extern unsigned char xbBits[9][8];
extern char fish_bits[], fishl_bits[];
int mono;
/* typedefs for bubble and fish structures, also caddr_t (not used in X.h) */
typedef struct {
int x,
y,
s,
i;
} bubble;
typedef struct {
int x,
y,
d,
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 */
int blimit = 32, /* bubble limit */
flimit = 2, /* 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 */
double rate = 1.0, /* update interval in seconds */
smooth = 1.0; /* smoothness increment multiplier */
bubble *binfo; /* bubble info structures, allocated
* dynamically */
fish *finfo; /* fish info structures, allocated dynamically */
Display *Dpy;
XImage *xfish[3]; /* fish pixmaps (1 is left-fish, 2 is
* right-fish) */
Pixmap pfish[3] = {0, 0, 0};
Pixmap xbubbles[9]; /* bubbles bitmaps (1 to 8, by size in pixels)*/
Window wid; /* aqaurium window */
unsigned long white, black,bcolor;
Colormap colormap;
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,
i;
char *p;
extern int optind;
extern char *optarg;
extern double atof();
pname = argv[0];
strcpy(sname, getenv("DISPLAY"));
strcpy(cname, "MediumAquamarine");
if ((p = XGetDefault(Dpy, pname, "BubbleLimit")) != NULL)
blimit = atoi(p);
if ((p = XGetDefault(Dpy, pname, "Color")) != NULL)
strcpy(cname, 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;
while ((c = getopt(argc, argv, "b:c:f:i:r:s")) != EOF) {
switch (c) {
case 'b':
blimit = atoi(optarg);
break;
case 'c':
strcpy(cname, optarg);
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 [-b limit][-c color][-f limit][-i mult][-r rate][-s][host:display]\n", pname);
exit(1);
}
}
if (optind < argc)
strcpy(sname, argv[optind]);
}
putfish(f)
fish *f;
{
if (pfish[f->d])
XCopyArea(Dpy, pfish[f->d], wid, gc, 0, 0, rwidth, rheight, f->x, f->y);
else
XPutImage(Dpy, wid, gc, xfish[f->d], 0, 0, f->x, f->y, rwidth, rheight);
}
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);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Initialize colormap for background color and required fish colors.
The fish colors are coded in xfishy.c as a trio of tables.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
init_colormap()
{
int i;
XColor hdef,
edef;
extern char *malloc();
colormap = XDefaultColormap(Dpy, screen);
if (colormap == NULL)
return;
cmap = (int *) malloc((rcolors + 1) * sizeof(int));
if (!mono) {
XAllocNamedColor(Dpy, colormap, cname, &hdef, &edef);
cmap[0] = hdef.pixel;
for (i = 0; i < rcolors; i++) {
hdef.red = rreds[i];
hdef.green = rgreens[i];
hdef.blue = rblues[i];
XAllocColor(Dpy, colormap, &hdef);
cmap[i + 1] = hdef.pixel;
}
bcolor = white;
}
else {
for (i = 0; i < (rcolors+1); i++)
cmap[i] = black;
cmap[0] = cmap[rback] = white;
bcolor = black;
}
cmap[rback] = cmap[0];
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Calibrate the pixmaps and bimaps. The left-fish data is coded in xfishy.c,
this is transformed to create the right-fish. The eight bubbles are coded
in xfishy.c as a two dimensional array.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
init_pixmap()
{
register caddrt p,
q,
x1,
x2;
register int i,
j;
extern char *malloc();
j = rwidth * rheight;
x1 = p = (caddrt) xfishRaster;
for (i = 0; i < j; i++, p++)
*p = cmap[*p];
x2 = (caddrt) malloc(rwidth * rheight);
for (i = 0; i < rheight; i++) {
p = x1 + i * rwidth;
q = x2 + (i + 1) * rwidth - 1;
for (j = 0; j < rwidth; j++)
*q-- = *p++;
}
xfish[1] = XCreateImage(Dpy, DefaultVisual(Dpy, screen), 8, ZPixmap,
0, x1, rwidth, rheight, 8, rwidth);
xfish[2] = XCreateImage(Dpy, DefaultVisual(Dpy, screen), 8, ZPixmap,
0, x2, rwidth, rheight, 8, rwidth);
if (!mono) { /* Color Dislay */
i = DisplayPlanes(Dpy, screen);
pfish[1] = XCreatePixmap(Dpy, wid, rwidth, rheight, i);
if (pfish[1])
pfish[2] = XCreatePixmap(Dpy, wid, rwidth, rheight, i);
if (pfish[1])
XPutImage(Dpy, pfish[1], gc, xfish[1], 0, 0, 0, 0, rwidth, rheight);
if (pfish[2])
XPutImage(Dpy, pfish[2], gc, xfish[2], 0, 0, 0, 0, rwidth, rheight);
if (pfish[1])
XDestroyImage(xfish[1]);
if (pfish[2])
XDestroyImage(xfish[2]);
xfish[1] = XCreateImage(Dpy, DefaultVisual(Dpy, screen), 8, ZPixmap,
0, x1, rwidth, rheight, 8, rwidth);
xfish[2] = XCreateImage(Dpy, DefaultVisual(Dpy, screen), 8, ZPixmap,
0, x2, rwidth, rheight, 8, rwidth);
}
else { /* Mono Display */
pfish[1] = XCreateBitmapFromData(Dpy,wid,fish_bits,rwidth,rheight);
pfish[2] = XCreateBitmapFromData(Dpy,wid,fishl_bits,rwidth,rheight);
}
for (i = 1; i <= 8; i++)
xbubbles[i] = XCreateBitmapFromData(Dpy, wid, xbBits[i], i, i);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Toggle secure mode on receipt of signal
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
toggle_secure()
{
pmode = !pmode;
if (pmode)
XLowerWindow(Dpy, wid);
else
XRaiseWindow(Dpy, wid);
XFlush(Dpy);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Initialize signal so that SIGUSR1 causes secure mode to toggle.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
init_signals()
{
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
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Variety of initialization calls, including getting the window up and running.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
initialize()
{
XWindowAttributes winfo;
XSetWindowAttributes attr;
XGCValues vals;
extern char *malloc();
XSizeHints xsh;
XGetWindowAttributes(Dpy, DefaultRootWindow(Dpy), &winfo);
width = winfo.width;
height = winfo.height;
init_colormap();
attr.override_redirect = True;
attr.background_pixel = cmap[0];
wid = XCreateWindow(Dpy, DefaultRootWindow(Dpy),
1, 1, width - 2, height - 2, 0,
CopyFromParent, CopyFromParent, CopyFromParent,
CWBackPixel | CWOverrideRedirect, &attr);
if (!wid)
msgdie("XCreateWindow failed");
vals.foreground = vals.background = cmap[0];
vals.graphics_exposures = False;
gc = XCreateGC(Dpy, wid, GCForeground | GCBackground | GCGraphicsExposures,
&vals);
bgc = XCreateGC(Dpy, wid, GCForeground | GCBackground | GCGraphicsExposures,
&vals);
init_pixmap();
init_signals();
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);
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;
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)
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);
}
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Fish collision detection. The specified fish is checked against all other
fish for overlap. The xt parameter specifies the x axis tolerance for overlap.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
collide_fish(f0, xt)
fish *f0;
int xt;
{
int i,
j;
register fish *f = f0;
for (i = 0; i < flimit; i++) {
if (&finfo[i] != f) {
j = finfo[i].y - f->y;
if ((j > -rheight) && (j < rheight)) {
j = finfo[i].x - f->x;
if ((j > -xt) && (j < xt))
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;
for (i = 0, collide = 1; (i < 16) && (collide); i++) {
f->y = (height - rheight) * (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;
}
collide = collide_fish(f, 2 * rwidth);
}
if (!collide)
putfish(f);
else
f->d = 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,
done;
register fish *f;
for (i = 0; i < flimit; i++) {
f = &finfo[i];
if (f->d) {
ofx = f->x;
ofy = f->y;
if (f->d == 1) {
done = ((f->x -= f->i) < -rwidth);
x = f->x + rwidth;
} else if (f->d == 2) {
done = ((f->x += f->i) > width);
x = f->x - f->i;
}
if (!collide_fish(f, rwidth)) {
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, rwidth)) {
f->y -= y;
y = 0;
} else {
if (y > 0) {
j = f->y - y;
} else {
j = f->y + rheight;
y *= -1;
}
}
}
putfish(f);
XClearArea(Dpy, wid, x, ofy, f->i, rheight, 0);
if (y)
XClearArea(Dpy, wid, ofx, j, rwidth, y, 0);
} else {
XClearArea(Dpy, wid, x, f->y, f->i, rheight, 0);
new_fish(f);
}
} else {
if ((f->d = 3 - f->d) == 1) {
f->x = f->x - 2 * f->i;
x = f->x + rwidth;
} else {
f->x = f->x + 2 * f->i;
x = f->x - f->i;
}
putfish(f);
XClearArea(Dpy, wid, x, f->y, f->i, rheight, 0);
}
} else {
new_fish(f);
}
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Higher-resolution sleep
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
high_res_sleep(seconds)
double seconds;
{
int fds = 0;
struct timeval timeout;
timeout.tv_sec = seconds;
timeout.tv_usec = (seconds - timeout.tv_sec) * 1000000.0;
select(0, &fds, &fds, &fds, &timeout);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
main(argc, argv)
int argc;
char **argv;
{
int i;
XEvent ev;
if ((Dpy = XOpenDisplay("")) == 0)
msgdie("XOpenDisplay failed");
screen = DefaultScreen(Dpy);
if (DisplayPlanes(Dpy,screen) < 4) mono = 1;
else mono = 0;
white = WhitePixel(Dpy, screen);
black = BlackPixel(Dpy, screen);
parse(argc, argv);
initialize();
srand((unsigned) getpid());
Init_B = 1;
for (i = 0; i < blimit; i++)
new_bubble(&binfo[i]);
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);
}
}
@//E*O*F xfish.c//
chmod u=r,g=r,o=r xfish.c
exit 0
More information about the Comp.sources.x
mailing list