Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!cs.utexas.edu!sun-barr!newstop!exodus!prodnet.la.locus.com From: jta@prodnet.la.locus.com (JT Anderson) Newsgroups: comp.sources.x Subject: v12i051: xroach, Part01/01 Message-ID: <10510@exodus.Eng.Sun.COM> Date: 26 Mar 91 22:52:40 GMT Sender: news@exodus.Eng.Sun.COM Lines: 1528 Approved: argv@sun.com Submitted-by: JT Anderson Posting-number: Volume 12, Issue 51 Archive-name: xroach/part01 ------- Xroach displays disgusting cockroaches on your root window. These creapy crawlies scamper around until they find a window to hide under. Whenever you move or iconify a window, the exposed beetles again scamper for cover. # This is a shar archive. Extract with sh, not csh. # The rest of this file will extract: # xroach.man xroach.c patchlevel.h roachmap.h roach000.xbm roach015.xbm roach030.xbm roach045.xbm roach060.xbm roach075.xbm roach090.xbm roach105.xbm roach120.xbm roach135.xbm roach150.xbm roach165.xbm roach180.xbm roach195.xbm roach210.xbm roach225.xbm roach240.xbm roach255.xbm roach270.xbm roach285.xbm roach300.xbm roach315.xbm roach330.xbm roach345.xbm Imakefile # ----------------< cut here >---------------------- echo extracting - xroach.man sed 's/^X//' > xroach.man << '~FUNKY STUFF~' X.TH XROACH 1 "Release 4" "X Version 11" X.SH NAME Xxroach \- cockroaches hide under your windows X.SH SYNOPSIS X.B xroach X[-option .,..] X.SH DESCRIPTION X.I Xroach Xdisplays disgusting cockroaches on your root window. These creapy crawlies Xscamper Xaround until they find a window to hide under. Whenever you move or iconify Xa window, the exposed beetles again scamper for cover. X.SH OPTIONS X.TP 8 X.B \-display \fIdisplay_name\fB XDrop the roaches on the given display. Make sure the display is nearby, so you Xcan hear the screams. X.TP 8 X.B \-rc \fIroach_color\fB XUse the given string as the color for the bugs instead of the default "black". X.TP 8 X.B \-speed \fIroach_speed\fB XUse the given speed for the insects instead of the default 20.0. For example, Xin winter the speed should be set to 5.0. In summer, 30.0 might be about Xright. X.TP 8 X.B \-roaches \fInum_roaches\fB XThis is the number of the little critters. Default is 10. X.SH BUGS XAs given by the -roaches option. Default is 10. X.SH COPYRIGHT XCopyright 1991 by J.T. Anderson X.SH AUTHORS XJ.T. Anderson X(jta@locus.com) X.SH DEDICATION XGreg McFarlane X(gregm@otc.otca.oz.au) X.SH "SEE ALSO" Xxroachmotel(1), xddt(1) X ~FUNKY STUFF~ echo extracting - xroach.c sed 's/^X//' > xroach.c << '~FUNKY STUFF~' X/* X Xroach - A game of skill. Try to find the roaches under your windows. X X Copyright 1991 by J.T. Anderson X X jta@locus.com X X This program may be freely distributed provided that all X copyright notices are retained. X X To build: X cc -o xroach roach.c -lX11 [-lsocketorwhatever] [-lm] [-l...] X X Dedicated to Greg McFarlane. (gregm@otc.otca.oz.au) X*/ X#include X#include X#include X X#include X#include X#include X#include X X#if __STDC__ X#include X#else Xlong strtol(); Xdouble strtod(); Xchar *getenv(); X#endif X Xchar Copyright[] = "Xroach\nCopyright 1991 J.T. Anderson"; X X#include "roachmap.h" X Xtypedef unsigned long Pixel; Xtypedef int ErrorHandler(); X X#define SCAMPER_EVENT (LASTEvent + 1) X X#if !defined(GRAB_SERVER) X#define GRAB_SERVER 0 X#endif X XDisplay *display; Xint screen; XWindow rootWin; Xunsigned int display_width, display_height; Xint center_x, center_y; XGC gc; Xchar *display_name = NULL; XPixel black, white; X Xint done = 0; Xint eventBlock = 0; Xint errorVal = 0; X Xtypedef struct Roach { X RoachMap *rp; X int index; X float x; X float y; X int intX; X int intY; X int hidden; X int turnLeft; X int steps; X} Roach; X XRoach *roaches; Xint maxRoaches = 10; Xint curRoaches = 0; Xfloat roachSpeed = 20.0; X XRegion rootVisible = NULL; X Xvoid Usage(); Xvoid SigHandler(); Xvoid AddRoach(); Xvoid MoveRoach(); Xvoid DrawRoaches(); Xvoid CoverRoot(); Xint CalcRootVisible(); Xint MarkHiddenRoaches(); XPixel AllocNamedColor(); X Xvoid Xmain(ac, av) Xint ac; Xchar *av[]; X{ X XGCValues xgcv; X int ax; X char *arg; X RoachMap *rp; X int rx; X float angle; X XEvent ev; X char *roachColor = "black"; X int nVis; X int needCalc; X X /* X Process command line options. X */ X for (ax=1; axpixmap = XCreateBitmapFromData(display, rootWin, X rp->roachBits, rp->width, rp->height); X rp->sine = sin(angle); X rp->cosine = cos(angle); X } X X roaches = (Roach *)malloc(sizeof(Roach) * maxRoaches); X X gc = XCreateGC(display, rootWin, 0L, &xgcv); X XSetForeground(display, gc, AllocNamedColor(roachColor, black)); X XSetFillStyle(display, gc, FillStippled); X X while (curRoaches < maxRoaches) X AddRoach(); X X XSelectInput(display, rootWin, ExposureMask | SubstructureNotifyMask); X X needCalc = 1; X while (!done) { X if (XPending(display)) { X XNextEvent(display, &ev); X } X else { X if (needCalc) { X needCalc = CalcRootVisible(); X } X nVis = MarkHiddenRoaches(); X if (nVis) { X ev.type = SCAMPER_EVENT; X } X else { X DrawRoaches(); X eventBlock = 1; X XNextEvent(display, &ev); X eventBlock = 0; X } X } X X switch (ev.type) { X X case SCAMPER_EVENT: X for (rx=0; rxrp->width) > (x + width)) return 0; X if (ry < y) return 0; X if ((ry + roach->rp->height) > (y + height)) return 0; X X return 1; X} X X/* X Check for roach overlapping specified rectangle. X*/ Xint XRoachOverRect(roach, rx, ry, x, y, width, height) XRoach *roach; Xint rx; Xint ry; Xint x; Xint y; Xunsigned int width; Xunsigned int height; X{ X if (rx >= (x + width)) return 0; X if ((rx + roach->rp->width) <= x) return 0; X if (ry >= (y + height)) return 0; X if ((ry + roach->rp->height) <= y) return 0; X X return 1; X} X X/* X Give birth to a roach. X*/ Xvoid XAddRoach() X{ X Roach *r; X X if (curRoaches < maxRoaches) { X r = &roaches[curRoaches++]; X r->index = RandInt(ROACH_HEADINGS); X r->rp = &roachPix[r->index]; X r->x = RandInt(display_width - r->rp->width); X r->y = RandInt(display_height - r->rp->height); X r->intX = -1; X r->intY = -1; X r->hidden = 0; X r->steps = RandInt(200); X r->turnLeft = RandInt(100) >= 50; X } X} X X/* X Turn a roach. X*/ Xvoid XTurnRoach(roach) XRoach *roach; X{ X if (roach->index != (roach->rp - roachPix)) return; X X if (roach->turnLeft) { X roach->index += (RandInt(30) / 10) + 1; X if (roach->index >= ROACH_HEADINGS) X roach->index -= ROACH_HEADINGS; X } X else { X roach->index -= (RandInt(30) / 10) + 1; X if (roach->index < 0) X roach->index += ROACH_HEADINGS; X } X} X X/* X Move a roach. X*/ Xvoid XMoveRoach(rx) Xint rx; X{ X Roach *roach; X Roach *r2; X float newX; X float newY; X int ii; X X roach = &roaches[rx]; X newX = roach->x + (roachSpeed * roach->rp->cosine); X newY = roach->y - (roachSpeed * roach->rp->sine); X X if (RoachInRect(roach, (int)newX, (int)newY, X 0, 0, display_width, display_height)) { X X roach->x = newX; X roach->y = newY; X X if (roach->steps-- <= 0) { X TurnRoach(roach); X roach->steps = RandInt(200); X } X X for (ii=rx+1; iiintX, r2->intY, r2->rp->width, r2->rp->height)) { X X TurnRoach(roach); X } X } X } X else { X TurnRoach(roach); X } X} X X/* X Draw all roaches. X*/ Xvoid XDrawRoaches() X{ X Roach *roach; X int rx; X X for (rx=0; rxintX >= 0) { X XClearArea(display, rootWin, roach->intX, roach->intY, X roach->rp->width, roach->rp->height, False); X } X } X X for (rx=0; rxhidden) { X roach->intX = roach->x; X roach->intY = roach->y; X roach->rp = &roachPix[roach->index]; X X XSetStipple(display, gc, roach->rp->pixmap); X XSetTSOrigin(display, gc, roach->intX, roach->intY); X XFillRectangle(display, rootWin, gc, X roach->intX, roach->intY, roach->rp->width, roach->rp->height); X } X else { X roach->intX = -1; X } X } X} X X/* X Cover root window to erase roaches. X*/ Xvoid XCoverRoot() X{ X XSetWindowAttributes xswa; X long wamask; X Window roachWin; X X xswa.background_pixmap = ParentRelative; X xswa.override_redirect = True; X wamask = CWBackPixmap | CWOverrideRedirect; X roachWin = XCreateWindow(display, rootWin, 0, 0, X display_width, display_height, 0, CopyFromParent, X InputOutput, CopyFromParent, wamask, &xswa); X XLowerWindow(display, roachWin); X XMapWindow(display, roachWin); X XFlush(display); X} X X#if !GRAB_SERVER X Xint XRoachErrors(dpy, err) XDisplay *dpy; XXErrorEvent *err; X{ X errorVal = err->error_code; X X return 0; X} X X#endif /* GRAB_SERVER */ X X/* X Calculate Visible region of root window. X*/ Xint XCalcRootVisible() X{ X Region covered; X Region visible; X Window *children; X int nChildren; X Window dummy; X XWindowAttributes wa; X int wx; X XRectangle rect; X int winX, winY; X unsigned int winHeight, winWidth; X unsigned int borderWidth; X unsigned int depth; X X /* X If we don't grab the server, the XGetWindowAttribute or XGetGeometry X calls can abort us. On the other hand, the server grabs can make for X some annoying delays. X */ X#if GRAB_SERVER X XGrabServer(display); X#else X XSetErrorHandler(RoachErrors); X#endif X X /* X Get children of root. X */ X XQueryTree(display, rootWin, &dummy, &dummy, &children, &nChildren); X X /* X For each mapped child, add the window rectangle to the covered X region. X */ X covered = XCreateRegion(); X for (wx=0; wx