argv@island.uu.net (Dan Heller) (09/25/89)
Submitted-by: Patrick Naughton <naughton@sun.com> Posting-number: Volume 5, Issue 4 Archive-name: xlock/part01 [ This was posted once before, but this is a repost due to the large number of changes. Note the version number and patchlevel.h. Systems without usleep(2) may consider writing a one or two liner using select() and polling for N microseconds (see README). --argv ] #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # Imakefile # Makefile # patchlevel.h # xlock.1 # xlock.c # hopalong.c # qix.c # life.c # lifeicon.bit # XCrDynCmap.c # XCrHsbCmap.c # HSBmap.c # This archive created: Sat Sep 23 09:39:30 1989 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' This is the latest version of xlock (sccs version 22.4) This will start with patchlevel = 1.1 There were serveral minor bugfixes made after I put this on expo, but before it was posted to comp.sources.x o -display hostname:0 did not work even when hostname was the localhost. o -mode qix failed with a count < 4. o qix was using rand() shifted right some amount to get some randomness. I switched to random() and srandom() and the performance is still too fast to worry about measuring... (at least on OpenWindows on a 4/60) o I was coughing on EnterNotify and LeaveNotify, now I ignore them. o The window manager was sometimes installing the default colormap when the mouse crossed a window boundry *after* I had installed my colormap, but *before* I had my window up to block crossing events. I moved the colormap installation down to the very last moment. o a couple of gratuitous non-portable functions were used. - strtok() replaced with simple strchr() and a null store. - srand48() replaced with srandom(); - usleep() this is still used in life.c, but people can just rip it out if they don't have it, or stick in a loop polling timeofday, or use VTALRM, but usleep works nice and cleanly under SunOS, so I'm not really motivated to change it. ---------------------------------------------------------------------- There is a minimal Makefile which you may need to massage in order to get it to generate the right thing from the Imakefile. Neither of these has been tested since we don't use Imake. Changes since last version (1.8): Ability to set the nice level of the xlock process, to keep it from hogging all of the cpu. -display is parsed to be able to lock unix:1, etc... new modal interface to different lockscreen screensavers. three sample modes. -mode qix is the old spinning lines demo... -mode life is a new implementation of Conway's Life simulation. -mode hop is the "hopalong fractals" from last version. lots of bug fixes and code cleanup. ______________________________________________________________________ Patrick J. Naughton ARPA: naughton@sun.com Window Systems Group UUCP: ...!sun!naughton Sun Microsystems, Inc. AT&T: (415) 336 - 1080 SHAR_EOF fi if test -f 'Imakefile' then echo shar: "will not over-write existing file 'Imakefile'" else cat << \SHAR_EOF > 'Imakefile' # @(#)Imakefile 22.2 89/09/20 # Imakefile - xlock # # Copyright (c) 1989 by Sun Microsystems, Inc. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation. # # This file is provided AS IS with no warranties of any kind. The author # shall have no liability with respect to the infringement of copyrights, # trade secrets or any patents by this file or any part thereof. In no # event will the author be liable for any lost revenue or profits or # other special, indirect and consequential damages. # # INCLUDES = -I$(TOP) -I$(TOP)/X11 LOCAL_LIBRARIES = $(XLIB) SYS_LIBRARIES = -lm SRCS = xlock.c hopalong.c life.c qix.c \ XCrHsbCmap.c HSBmap.c XCrDynCmap.c OBJS = xlock.o hopalong.o life.o qix.o \ XCrHsbCmap.o HSBmap.o XCrDynCmap.o ComplexProgramTarget(xlock) SHAR_EOF fi if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' TOP = ./../.. MV = mv RM = rm -f UTILSRC = $(TOP)/util IMAKESRC = $(UTILSRC)/imake IRULESRC = $(UTILSRC)/imake.includes IMAKE = $(IMAKESRC)/imake IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl \ -I$(NEWTOP)$(IRULESRC) \ -s Makefile Makefile:: Imakefile -$(RM) Makefile.bak; $(MV) Makefile Makefile.bak $(IMAKE_CMD) -DTOPDIR=$(TOP) SHAR_EOF fi if test -f 'patchlevel.h' then echo shar: "will not over-write existing file 'patchlevel.h'" else cat << \SHAR_EOF > 'patchlevel.h' 1.1 SHAR_EOF fi if test -f 'xlock.1' then echo shar: "will not over-write existing file 'xlock.1'" else cat << \SHAR_EOF > 'xlock.1' .\" @(#)xlock.n 22.2 89/09/20; Copyright (c) 1989 - Sun Microsystems, Inc. .TH XLOCK 1 "20 Sep 1989" "X11R4" .SH NAME xlock \- Locks the local X display till a password is entered. .SH SYNOPSIS .B xlock [ .BI \-display " dsp" ] [ .BI \-mode " mode" ] [ .BI \-time " timeout" ] [ .BI \-count " n" ] [ .BI \-font " fontname" ] [ .BI \-nice " nicelevel" ] [ .B \-mono ] [ .B \-saver ] [ .B \-root ] [ .B \-v ] .SH DESCRIPTION .B xlock locks the X server till the user enters their password at the keyboard. While .B xlock is running, all new server connections are refused. The screen saver is disabled. The mouse cursor is turned off. The screen is blanked and a changing pattern is put on the screen. The pattern changes after .I timeout seconds. If a key or a mouse button is pressed then the user is prompted for the password of the user who started .B xlock. If the correct password is typed, then the screen is unlocked and the X server is restored. When typing the password, characters are echoed to the screen as question marks (?), and Control-U and Control-H are active as kill and erase respectively. To return to the locked screen, click in the small icon version of the changing pattern. .SH OPTIONS .TP 5 .B \-display " dsp" The .I display option sets the X11 display to lock. .B xlock will not allow one to lock another server's displays thus only .BI unix:server.screen, .BI localhost:server.screen, and .BI :server.screen are allowed for .I dsp. Where .I server is which X11 server socket to connect to and .I screen is which head to display the pattern on. .TP 5 .B \-mode " modename" As of this writing there are three display modes supported. .TP 8 .B hop Hop mode shows the "real plane fractals" from the September 1986 issue of Scientific American. .TP 8 .B life Life mode shows Conway's game of life. .TP 8 .B qix Qix mode shows the spinning lines similar to the old video game by the same name. .TP 5 .B \-time " timeout" The .I time option sets the number of seconds that each unique fractal will remain on the screen before being replaced by the next one to .I timeout. .TP 5 .B \-count " n" The .I count option sets the speed at which a mode will operate. The different modes interpret this value differently. For 'hop' and 'qix' this sets the number of pixels and lines respectively to draw in each color. These patterns are calculated in batches of .I n objects, then sent to the server in a single color. Faster machines, expecially machines with floating point hardware can set this to a higher number and still have fast changing patterns. The 'life' mode, in contrast interprets this number as the number of milliseconds to delay after each generation of the "critters". A low number here makes the pattern change rapidly, where 1000 means wait a second between generations. .TP 5 .B \-font " fontname" The .I font option sets the font to be used on the prompt screen. .TP 5 .B \-nice " nicelevel" The .I nice option sets system nicelevel of the xlock process to .I nicelevel . .TP 5 .B \-mono The .I mono option causes xlock to display monochrome, (black and white) pixels rather than the default colored ones on color displays. .TP 5 .B \-saver The .I saver option causes xlock to only draw the patterns and not lock the display. A keypress or a mouse click will terminate the screen saver. .TP 5 .B \-root The .I root option allows the root password to unlock the server as well as the user who started xlock. .TP 5 .B \-v Verbose mode, tells what options it is going to use. .SH BUGS "kill -KILL .B xlock " causes server to be unusable, since .B xlock has removed all hosts (including localhost) from the access control list to lock out all new X clients, and SIGKILL cannot be caught by any program, .B xlock will terminate before restoring the access control list. This will leave the X server in a state where \fI "you can no longer connect to that server, and this operation cannot be reversed short of resetting the server."\fP -From the X11R2 Xlib Documentation page 140. .SH SEE ALSO X(1), Xlib Documentation. .SH AUTHOR Patrick J. Naughton (naughton@sun.com) Window Systems Group Sun Microsystems, Inc. Mountain View, CA 94043 415/336-1080 .SH COPYRIGHT Copyright (c) 1988-89 by Patrick J. Naughton and Sun Microsystems, Inc. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. .SH CONTRIBUTORS milliken@heron.bbn.com karlton@wsl.dec.com dana@thumper.bellcore.com vesper@3d.dec.com flar@sun.com SHAR_EOF fi if test -f 'xlock.c' then echo shar: "will not over-write existing file 'xlock.c'" else cat << \SHAR_EOF > 'xlock.c' #ifndef lint static char sccsid[] = "@(#)xlock.c 22.4 89/09/23"; #endif /*- * xlock.c - X11 client to lock a display and show a screen saver. * * Copyright (c) 1988-89 by Patrick Naughton and Sun Microsystems, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * Comments and additions should be sent to the author: * * naughton@sun.com * * Patrick J. Naughton * Window Systems Group, MS 14-40 * Sun Microsystems, Inc. * 2550 Garcia Ave * Mountain View, CA 94043 * * Revision History: * 23-Sep-89: Added fix to allow local hostname:0 as a display. * Put empty case for Enter/Leave events. * Moved colormap installation later in startup. * 20-Sep-89: Linted and made -saver mode grab the keyboard and mouse. * Replaced SunView code for life mode with Jim Graham's version, * so I could contrib it without legal problems. * Sent to expo for X11R4 contrib. * 19-Sep-89: Added '?'s on input. * 27-Mar-89: Added -qix mode. * Fixed GContext->GC. * 20-Mar-89: Added backup font (fixed) if XQueryLoadFont() fails. * Changed default font to lucida-sans-24. * 08-Mar-89: Added -nice, -mode and -display, built vector for life and hop. * 24-Feb-89: Replaced hopalong display with life display from SunView1. * 22-Feb-89: Added fix for color servers with n < 8 planes. * 16-Feb-89: Updated calling conventions for XCreateHsbColormap(); * Added -count for number of iterations per color. * Fixed defaulting mechanism. * Ripped out VMS hacks. * Sent to expo for X11R3 contrib. * 15-Feb-89: Changed default font to pellucida-sans-18. * 20-Jan-89: Added -verbose and fixed usage message. * 19-Jan-89: Fixed monochrome gc bug. * 16-Dec-88: Added SunView style password prompting. * 19-Sep-88: Changed -color to -mono. (default is color on color displays). * Added -saver option. (just do display... don't lock.) * 31-Aug-88: Added -time option. * Removed code for fractals to separate file for modularity. * Added signal handler to restore host access. * Installs dynamic colormap with a Hue Ramp. * If grabs fail then exit. * Added VMS Hacks. (password 'iwiwuu'). * Sent to expo for X11R2 contrib. * 08-Jun-88: Fixed root password pointer problem and changed PASSLENGTH to 20. * 20-May-88: Added -root to allow root to unlock. * 12-Apr-88: Added root password override. * Added screen saver override. * Removed XGrabServer/XUngrabServer. * Added access control handling instead. * 01-Apr-88: Added XGrabServer/XUngrabServer for more security. * 30-Mar-88: Removed startup password requirement. * Removed cursor to avoid phosphor burn. * 27-Mar-88: Rotate fractal by 45 degrees clockwise. * 24-Mar-88: Added color support. [-color] * wrote the man page. * 23-Mar-88: Added HOPALONG routines from Scientific American Sept. 86 p. 14. * added password requirement for invokation * removed option for command line password * added requirement for display to be "unix:0". * 22-Mar-88: Recieved Walter Milliken's comp.windows.x posting. * * Contributors: * milliken@heron.bbn.com * karlton@wsl.dec.com * dana@thumper.bellcore.com * vesper@3d.dec.com */ #include <stdio.h> #include <signal.h> #include <sys/param.h> #include <string.h> #include <pwd.h> #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/cursorfont.h> extern char *crypt(); extern char *getenv(); typedef struct { char *cmdline_arg; int (*lp_reinit) (); void (*lp_callback) (); void (*lp_init) (); } lockProc; /* * Declare external interface routines for supported screen savers. */ extern void randomInithop(); extern int hopdone(); extern void hop(); extern void initlife(); extern int lifedone(); extern void drawlife(); extern void initqix(); extern int qixdone(); extern void drawqix(); lockProc LockProcs[] = { {"hop", hopdone, hop, randomInithop}, {"life", lifedone, drawlife, initlife}, {"qix", qixdone, drawqix, initqix} /* * New screen savers may be added here. * Refer to qix.c for simple sample screen saver. */ }; #define NUMPROCS (sizeof(LockProcs) / sizeof(lockProc)) int (*reinit) () = NULL; void (*callback) () = NULL; void (*init) () = NULL; char *pname; /* argv[0] */ Display *dsp = NULL; /* server display connection */ int screen; /* current screen */ Window w, /* window used to cover screen */ icon, /* window used during password typein */ root; /* convenience pointer to the root window */ GC gc, /* main graphics drawing graphics context */ textgc; /* graphics context used for text rendering */ XColor black, /* used for text rendering */ white; /* background of text screen */ Colormap cmap; /* colormap */ Cursor mycursor; /* blank cursor */ Pixmap lockc, lockm; /* pixmaps for cursor and mask */ char no_bits[] = {0}; /* dummy array for the blank cursor */ int passx, /* position of the ?'s */ passy; XFontStruct *font; char *fontname = NULL; /* the font used in the password screen */ int inittime = -1; /* time to iterate before calling init */ int skipRoot; /* skip root password check */ int color; /* color or mono */ int count = -1; /* number of pixels to draw in each color */ int nicelevel = -1; /* system priority at which to run process */ int lock; /* locked or just screensaver mode */ int verbose = False; /* print configuration info to stderr? */ char *display = NULL; /* X display variable */ int timeout, interval, blanking, exposures; /* screen saver parameters */ #define ICONX 300 #define ICONY 150 #define ICONW 64 #define ICONH 64 #define ICONLOOPS 600 #define DEFAULT_FONTNAME "LucidaSans-24" #define BACKUP_FONTNAME "fixed" #define DEFAULT_INITTIME 60 #define DEFAULT_SKIPROOT True #define DEFAULT_COUNT 100 #define DEFAULT_NICE 10 #define DEFAULT_DISPLAY ":0" /* VARARGS1 */ void error(s1, s2) char *s1, *s2; { fprintf(stderr, s1, pname, s2); exit(1); } int oldsigmask; void block() { oldsigmask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGFPE) | sigmask(SIGSEGV)); } void unblock() { sigsetmask(oldsigmask); } void allowsig() { unblock(); block(); } XHostAddress *XHosts; int HostAccessCount; Bool HostAccessState; void XGrabHosts(dsp) Display *dsp; { XHosts = XListHosts(dsp, &HostAccessCount, &HostAccessState); XRemoveHosts(dsp, XHosts, HostAccessCount); XEnableAccessControl(dsp); } void XUngrabHosts(dsp) Display *dsp; { XAddHosts(dsp, XHosts, HostAccessCount); XFree(XHosts); if (HostAccessState == False) XDisableAccessControl(dsp); } void GrabKeyboardAndMouse() { Status status; status = XGrabKeyboard(dsp, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); if (status != GrabSuccess) error("%s: couldn't grab keyboard! (%d)\n", status); status = XGrabPointer(dsp, w, True, -1, GrabModeAsync, GrabModeAsync, None, mycursor, CurrentTime); if (status != GrabSuccess) error("%s: couldn't grab pointer! (%d)\n", status); } void XChangeGrabbedCursor(cursor) Cursor cursor; { XGrabPointer(dsp, w, True, -1, GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime); } void finish() { XSync(dsp, 0); XUngrabHosts(dsp); XUngrabPointer(dsp, CurrentTime); XUngrabKeyboard(dsp, CurrentTime); XSetScreenSaver(dsp, timeout, interval, blanking, exposures); XDestroyWindow(dsp, w); if (color) XUninstallColormap(dsp, cmap); XFlush(dsp); XCloseDisplay(dsp); } void sigcatch() { finish(); error("%s: caught terminate signal.\nAccess control list restored.\n"); } int ReadXString(s, slen) char *s; int slen; { XEvent event; char keystr[20]; char c; int i, bp, len, loops; char *pwbuf = (char *) malloc(slen); XSetForeground(dsp, gc, BlackPixel(dsp, screen)); init(dsp, icon, gc, color, inittime, count); bp = 0; nice(-nicelevel); /* make sure we can read the keystrokes... */ while (True) { loops = 0; while (!XPending(dsp)) { allowsig(); callback(); if (reinit()) init(dsp, icon, gc, color, inittime, count); if (++loops >= ICONLOOPS) { nice(nicelevel); free(pwbuf); return 1; } } XNextEvent(dsp, &event); switch (event.type) { case KeyPress: len = XLookupString((XKeyEvent *) & event, keystr, 20, NULL, NULL); for (i = 0; i < len; i++) { c = keystr[i]; switch (c) { case 8: /* ^H */ case 127: /* DEL */ if (bp > 0) bp--; break; case 10: /* ^J */ case 13: /* ^M */ s[bp] = '\0'; nice(nicelevel); free(pwbuf); return 0; case 21: /* ^U */ bp = 0; break; default: s[bp] = c; if (bp < slen - 1) bp++; } } memset(pwbuf, '?', slen); XSetForeground(dsp, gc, white.pixel); XFillRectangle(dsp, w, gc, passx, passy - font->ascent, XTextWidth(font, pwbuf, slen), font->ascent + font->descent); XDrawString(dsp, w, textgc, passx, passy, pwbuf, bp); break; case ButtonPress: if (((XButtonEvent *) & event)->window == icon) { nice(nicelevel); free(pwbuf); return 1; } break; case KeyRelease: case ButtonRelease: case MotionNotify: case LeaveNotify: case EnterNotify: break; default: fprintf(stderr, "%s: unexpected event: %d\n", pname, event.type); break; } } } int getPassword() { #define PASSLENGTH 20 char buffer[PASSLENGTH]; char userpass[PASSLENGTH]; char rootpass[PASSLENGTH]; struct passwd *pw; XWindowAttributes xgwa; char *user = getenv("USER"); char *name = "Name: "; char *pass = "Password: "; char *info = "Enter password to unlock; select icon to lock."; char *validate = "Validating login..."; char *invalid = "Invalid login."; int y, left, done; XGetWindowAttributes(dsp, w, &xgwa); XChangeGrabbedCursor(XCreateFontCursor(dsp, XC_left_ptr)); XSetForeground(dsp, gc, WhitePixel(dsp, screen)); XFillRectangle(dsp, w, gc, 0, 0, xgwa.width, xgwa.height); XMapWindow(dsp, icon); XRaiseWindow(dsp, icon); left = ICONX + ICONW + font->max_bounds.width; y = ICONY + font->ascent; XDrawString(dsp, w, textgc, left, y, name, strlen(name)); XDrawString(dsp, w, textgc, left + 1, y, name, strlen(name)); XDrawString(dsp, w, textgc, left + XTextWidth(font, name, strlen(name)), y, user, strlen(user)); y += font->ascent + font->descent + 2; XDrawString(dsp, w, textgc, left, y, pass, strlen(pass)); XDrawString(dsp, w, textgc, left + 1, y, pass, strlen(pass)); passx = left + 1 + XTextWidth(font, pass, strlen(pass)) + XTextWidth(font, " ", 1); passy = y; y = ICONY + ICONH + font->ascent + 2; XDrawString(dsp, w, textgc, ICONX, y, info, strlen(info)); XFlush(dsp); y += font->ascent + font->descent + 2; pw = getpwuid(0); strcpy(rootpass, pw->pw_passwd); pw = getpwuid(getuid()); strcpy(userpass, pw->pw_passwd); done = False; while (!done) { if (ReadXString(buffer, PASSLENGTH)) { XChangeGrabbedCursor(mycursor); XUnmapWindow(dsp, icon); XSetForeground(dsp, gc, WhitePixel(dsp, screen)); return 1; } XSetForeground(dsp, gc, WhitePixel(dsp, screen)); XFillRectangle(dsp, w, gc, ICONX, y - font->ascent, XTextWidth(font, validate, strlen(validate)), font->ascent + font->descent + 2); XDrawString(dsp, w, textgc, ICONX, y, validate, strlen(validate)); done = !((strcmp(crypt(buffer, userpass), userpass)) && (skipRoot || strcmp(crypt(buffer, rootpass), rootpass))); if (!done) { XFlush(dsp); sleep(1); XFillRectangle(dsp, w, gc, ICONX, y - font->ascent, XTextWidth(font, validate, strlen(validate)), font->ascent + font->descent + 2); XDrawString(dsp, w, textgc, ICONX, y, invalid, strlen(invalid)); } } return 0; } void justDisplay() { XEvent event; init(dsp, w, gc, color, inittime, count); do { while (!XPending(dsp)) { callback(); if (reinit()) init(dsp, w, gc, color, inittime, count); } XNextEvent(dsp, &event); } while (event.type != ButtonPress && event.type != KeyPress); } void lockDisplay() { do { justDisplay(); } while (getPassword()); } void usage(s) char *s; { int i; fprintf(stderr, "%s\nusage: %s [-display dsp] [-mode %s", s, pname, LockProcs[0].cmdline_arg); for (i = 1; i < NUMPROCS; i++) fprintf(stderr, " | %s", LockProcs[i].cmdline_arg); fprintf(stderr, "]\n"); fprintf(stderr, "\t%s %s\n", "[-time n] [-count n] [-nice n]", "[-font f] [-mono] [-saver] [-root] [-v]"); exit(1); } void BuildPointersFromString(s) char *s; { int i; for (i = 0; i < NUMPROCS; i++) { if (!strncmp(LockProcs[i].cmdline_arg, s, strlen(s))) { reinit = LockProcs[i].lp_reinit; callback = LockProcs[i].lp_callback; init = LockProcs[i].lp_init; if (verbose) fprintf(stderr, "Mode: %s\n", s); return; } } usage("Unknown Mode."); } main(argc, argv) int argc; char *argv[]; { XSetWindowAttributes xswa; XGCValues xgcv; int i; char *s; int n; pname = argv[0]; color = True; lock = True; skipRoot = -1; for (i = 1; i < argc; i++) { s = argv[i]; n = strlen(s); if (!strncmp("-display", s, n)) { if (++i >= argc) usage(s); display = argv[i]; } else if (!strncmp("-mono", s, n)) { color = False; } else if (!strncmp("-saver", s, n)) { lock = False; } else if (!strncmp("-root", s, n)) { skipRoot = False; } else if (!strncmp("-verbose", s, n)) { verbose = True; } else if (!strncmp("-time", s, n)) { if (++i >= argc) usage(s); inittime = atoi(argv[i]); if (inittime < 1) usage("-time argument must be positive."); } else if (!strncmp("-count", s, n)) { if (++i >= argc) usage(s); count = atoi(argv[i]); if (count < 1) usage("-count argument must be positive.\n"); } else if (!strncmp("-nice", s, n)) { if (++i >= argc) usage(s); nicelevel = atoi(argv[i]); } else if (!strncmp("-font", s, n)) { if (++i >= argc) usage(s); fontname = argv[i]; } else if (!strncmp("-mode", s, n)) { if (++i >= argc) usage(s); BuildPointersFromString(argv[i]); } else { fprintf(stderr, "Bad switch: "); usage(s); } } if (display == NULL) display = getenv("DISPLAY"); if (display != NULL) { char *colon = strchr(display, ':'); int n = colon - display; char hostname[MAXHOSTNAMELEN]; if (gethostname(hostname, MAXHOSTNAMELEN)) error("%s: Can't get local hostname.\n"); if (colon == NULL) error("%s: Malformed -display argument, \"%s\"\n", display); if (n) { if (strncmp(display, "unix", n) && strncmp(display, "localhost", n) && strncmp(display, hostname, n)) { *colon = (char) 0; error("%s: can't lock %s's display\n", display); } } } else display = DEFAULT_DISPLAY; if (lock) { block(); signal(SIGINT, sigcatch); signal(SIGQUIT, sigcatch); signal(SIGSEGV, sigcatch); } if (!(dsp = XOpenDisplay(display))) error("%s: unable to open display %s.\n", display); if (fontname == NULL) fontname = XGetDefault(dsp, pname, "font"); if (fontname == NULL) fontname = DEFAULT_FONTNAME; if (count == -1) { s = XGetDefault(dsp, pname, "count"); if (s != NULL) count = atoi(s); else count = DEFAULT_COUNT; } if (nicelevel == -1) { s = XGetDefault(dsp, pname, "nice"); if (s != NULL) nicelevel = atoi(s); else nicelevel = DEFAULT_NICE; } if (inittime == -1) { s = XGetDefault(dsp, pname, "time"); if (s != NULL) inittime = atoi(s); else inittime = DEFAULT_INITTIME; } if (init == NULL) { s = XGetDefault(dsp, pname, "mode"); if (s != NULL) { BuildPointersFromString(s); } else { reinit = LockProcs[0].lp_reinit; callback = LockProcs[0].lp_callback; init = LockProcs[0].lp_init; if (verbose) fprintf(stderr, "Mode: %s\n", LockProcs[0].cmdline_arg); } } if (skipRoot == -1) { s = XGetDefault(dsp, pname, "root"); if (s != NULL) skipRoot = !(strncmp("on", s, strlen(s)) == 0); else skipRoot = DEFAULT_SKIPROOT; } if (verbose) { fprintf(stderr, "%s: Font: %s, Time: %d, Root: %s, Nice: %d\n", pname, fontname, inittime, skipRoot ? "False" : "True", nicelevel); } font = XLoadQueryFont(dsp, fontname); if (font == NULL) { fprintf(stderr, "%s: can't find font: %s, using %s...\n", pname, fontname, BACKUP_FONTNAME); font = XLoadQueryFont(dsp, BACKUP_FONTNAME); if (font == NULL) error("%s: can't even find %s!!!\n", BACKUP_FONTNAME); } screen = DefaultScreen(dsp); if (color) color = (DisplayCells(dsp, screen) > 2); root = RootWindow(dsp, screen); if (color) { if (XCreateHSBColormap(dsp, screen, &cmap, DisplayCells(dsp, screen), 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, True) != Success) error("%s: couldn't create colormap."); } else cmap = DefaultColormap(dsp, screen); black.pixel = BlackPixel(dsp, screen); XQueryColor(dsp, cmap, &black); white.pixel = WhitePixel(dsp, screen); XQueryColor(dsp, cmap, &white); lockc = XCreateBitmapFromData(dsp, root, no_bits, 1, 1); lockm = XCreateBitmapFromData(dsp, root, no_bits, 1, 1); mycursor = XCreatePixmapCursor(dsp, lockc, lockm, &black, &black, 0, 0); XFreePixmap(dsp, lockc); XFreePixmap(dsp, lockm); xswa.cursor = mycursor; xswa.override_redirect = True; xswa.background_pixel = black.pixel; xswa.event_mask = KeyPressMask | ButtonPressMask; w = XCreateWindow(dsp, root, 0, 0, DisplayWidth(dsp, screen), DisplayHeight(dsp, screen), 0, CopyFromParent, InputOutput, CopyFromParent, CWCursor | CWOverrideRedirect | CWBackPixel | CWEventMask, &xswa); xswa.cursor = XCreateFontCursor(dsp, XC_target); xswa.background_pixel = white.pixel; xswa.event_mask = ButtonPressMask; icon = XCreateWindow(dsp, w, ICONX, ICONY, ICONW, ICONH, 1, CopyFromParent, InputOutput, CopyFromParent, CWCursor | CWBackPixel | CWEventMask, &xswa); XMapWindow(dsp, w); XRaiseWindow(dsp, w); xgcv.foreground = white.pixel; xgcv.background = black.pixel; gc = XCreateGC(dsp, w, GCForeground | GCBackground, &xgcv); xgcv.foreground = black.pixel; xgcv.background = white.pixel; xgcv.font = font->fid; textgc = XCreateGC(dsp, w, GCFont | GCForeground | GCBackground, &xgcv); XGetScreenSaver(dsp, &timeout, &interval, &blanking, &exposures); XSetScreenSaver(dsp, 0, 0, 0, 0); /* disable screen saver */ GrabKeyboardAndMouse(); if (lock) { XGrabHosts(dsp); allowsig(); } nice(nicelevel); srandom(getpid()); if (color) XInstallColormap(dsp, cmap); if (lock) lockDisplay(); else justDisplay(); finish(); if (lock) unblock(); exit(0); } SHAR_EOF fi if test -f 'hopalong.c' then echo shar: "will not over-write existing file 'hopalong.c'" else cat << \SHAR_EOF > 'hopalong.c' #ifndef lint static char sccsid[] = "@(#)hopalong.c 22.2 89/09/20"; #endif /*- * hopalong.c - Real Plane Fractals for the xlock X11 terminal locker. * * Copyright (c) 1988-89 by Patrick Naughton and Sun Microsystems, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * Comments and additions should be sent to the author: * * naughton@sun.com * * Patrick J. Naughton * Window Systems Group, MS 14-40 * Sun Microsystems, Inc. * 2550 Garcia Ave * Mountain View, CA 94043 * * Revision History: * 20-Sep-89: Lint. * 31-Aug-88: Forked from xlock.c for modularity. * 23-Mar-88: Coded HOPALONG routines from Scientific American Sept. 86 p. 14. */ #include <math.h> #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/Xutil.h> static int centerx, centery; /* center of the screen */ static double a, b, c, i, j; /* hopalong parameters */ static int color; static unsigned long pix = 0; static Display *Dsp; static Window Win; static GC Gc; static XPoint *pointBuffer = 0; /* pointer for XDrawPoints */ static int Npoints = 0; static long startTime; static int timeout; static long seconds() { struct timeval foo; gettimeofday(&foo, (struct timezone *) 0); return (foo.tv_sec); } void inithop(d, w, g, c, t, n, p, x, y, A, B, C) Display *d; Window w; GC g; int c, t, n, p, x, y; double A, B, C; { i = j = 0.0; startTime = seconds(); if ((pointBuffer) || (n != Npoints)) { if (pointBuffer) free((char *) pointBuffer); pointBuffer = (XPoint *) malloc(n * sizeof(XPoint)); Npoints = n; } Dsp = d; Win = w; Gc = g; color = c; timeout = t; if (p >= 0) pix = (unsigned long) p; centerx = x; centery = y; a = A; b = B; c = C; XClearWindow(Dsp, Win); } void randomInithop(d, w, g, c, t, n) Display *d; Window w; GC g; int c, t, n; { int range; XWindowAttributes xgwa; double A, B, C; int x, y; XGetWindowAttributes(d, w, &xgwa); x = xgwa.width / 2; y = xgwa.height / 2; range = (int) sqrt((double) x * x + (double) y * y); A = random() % (range * 100) * (random() % 2 ? -1.0 : 1.0) / 100.0; B = random() % (range * 100) * (random() % 2 ? -1.0 : 1.0) / 100.0; C = random() % (range * 100) * (random() % 2 ? -1.0 : 1.0) / 100.0; if (!(random() % 3)) a /= 10.0; if (!(random() % 2)) b /= 100.0; inithop(d, w, g, c, t, n, -1, x, y, A, B, C); } int hopdone() { return (seconds() - startTime > timeout); } void hop() { register double oldj; register int k = Npoints; register XPoint *xp = pointBuffer; if (color) { XSetForeground(Dsp, Gc, pix++); pix %= 254; } while (k--) { oldj = j; j = a - i; i = oldj + (i < 0 ? sqrt(fabs(b * i - c)) : -sqrt(fabs(b * i - c))); xp->x = centerx + (int) (i + j); xp->y = centery - (int) (i - j); xp++; } XDrawPoints(Dsp, Win, Gc, pointBuffer, Npoints, CoordModeOrigin); } SHAR_EOF fi if test -f 'qix.c' then echo shar: "will not over-write existing file 'qix.c'" else cat << \SHAR_EOF > 'qix.c' #ifndef lint static char sccsid[] = "@(#)qix.c 22.4 89/09/23"; #endif /*- * qix.c - The old standby vector swirl for the xlock X11 terminal locker. * * Copyright (c) 1989 by Sun Microsystems Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * Comments and additions should be sent to the author: * * naughton@sun.com * * Patrick J. Naughton * Window Systems Group, MS 14-40 * Sun Microsystems, Inc. * 2550 Garcia Ave * Mountain View, CA 94043 * * Revision History: * 23-Sep-89: Switch to random() and fixed bug w/ less than 4 lines. * 20-Sep-89: Lint. * 24-Mar-89: Written. */ #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/Xutil.h> static Display *Dsp; static Window Win; static GC Gc, eraseGC = (GC) 0; static int timeout; static int color; static unsigned long pix = 0; static long startTime; static int first, last, dx1, dy1, dx2, dy2, x1, y1, x2, y2, offset, delta, width, height; typedef struct { int x, y; } point; static int Nlines = 0; static point *lineq = (point *) 0; static long seconds() { struct timeval foo; gettimeofday(&foo, (struct timezone *) 0); return (foo.tv_sec); } void initqix(d, w, g, c, t, n) Display *d; Window w; GC g; int c, t, n; { XWindowAttributes xgwa; XGCValues xgcv; startTime = seconds(); if (n < 4) n = 4; if (n != Nlines) { if (lineq) free((char *) lineq); lineq = (point *) malloc(n * sizeof(point)); Nlines = n; } Dsp = d; Win = w; Gc = g; color = c; timeout = t; if (eraseGC == (GC) 0) { xgcv.foreground = BlackPixel(Dsp, 0); eraseGC = XCreateGC(Dsp, Win, GCForeground, &xgcv); } if (!color) XSetForeground(Dsp, Gc, WhitePixel(Dsp, 0)); XGetWindowAttributes(Dsp, Win, &xgwa); width = xgwa.width; height = xgwa.height; if (width < 100) /* icon window */ delta = 2; else delta = 15; offset = delta / 3; last = 0; srandom(time((long *) 0)); dx1 = random() & (width - 1) + 50; dy1 = random() & (height - 1) + 50; dx2 = random() & (width - 1) + 50; dy2 = random() & (height - 1) + 50; x1 = random() & width; y1 = random() & height; x2 = random() & width; y2 = random() & height; XFillRectangle(Dsp, Win, eraseGC, 0, 0, width, height); } int qixdone() { return (seconds() - startTime > timeout); } void drawqix() { register int n = Nlines; while (n--) { first = (last + 2) % Nlines; x1 += dx1; y1 += dy1; x2 += dx2; y2 += dy2; check_bounds_x(x1, &dx1); check_bounds_y(y1, &dy1); check_bounds_x(x2, &dx2); check_bounds_y(y2, &dy2); if (color) { XSetForeground(Dsp, Gc, pix++); if (pix > 253) pix = 0; } XDrawLine(Dsp, Win, eraseGC, lineq[first].x, lineq[first].y, lineq[first + 1].x, lineq[first + 1].y); XDrawLine(Dsp, Win, Gc, x1, y1, x2, y2); lineq[last].x = x1; lineq[last].y = y1; last += 1; if (last >= Nlines) last = 0; lineq[last].x = x2; lineq[last].y = y2; last += 1; if (last >= Nlines) last = 0; } } static check_bounds_y(y, dy) int y, *dy; { if (y < 0) { *dy = (random() & delta) + offset; } else if (y > height) { *dy = -(random() & delta) - offset; } } static check_bounds_x(x, dx) int x, *dx; { if (x < 0) { *dx = (random() & delta) + offset; } else if (x > width) { *dx = -(random() & delta) - offset; } } SHAR_EOF fi if test -f 'life.c' then echo shar: "will not over-write existing file 'life.c'" else cat << \SHAR_EOF > 'life.c' #ifndef lint static char sccsid[] = "@(#)life.c 22.1 89/09/20"; #endif /*- * life.c - Conway's game of Life for the xlock X11 terminal locker. * * Copyright (c) 1989 by Sun Microsystems, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * Comments and additions should be sent to the authors: * * flar@sun.com or naughton@sun.com * * James A. Graham * Patrick J. Naughton * Window Systems Group, MS 14-40 * Sun Microsystems, Inc. * 2550 Garcia Ave * Mountain View, CA 94043 * * Revision History: * 20-Sep-89: Written. */ #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include "lifeicon.bit"; static XImage logo = { 0, 0, /* width, height */ 0, XYBitmap, 0, /* xoffset, format, data */ LSBFirst, 8, /* byte-order, bitmap-unit */ LSBFirst, 8, 1 /* bitmap-bit-order, bitmap-pad, depth */ }; static Display *Dsp; static Window Win; static GC Gc; static GC eraseGC = (GC) 0; static int timeout; static int shooter; static int delay; static int color; static int pixels; static int width, height; static int xs, ys, xb, yb; static long startTime; #define NROWS 30 #define NCOLS 38 /* Buffer stores the data for each cell. Each cell is stored as * 8 bits representing the presence of a critter in each of it's * surrounding 8 cells. There is an empty row and column around * the whole array to allow stores without bounds checking as well * as an extra row at the end for the fetches into tempbuf. */ #define UPLT 0x01 #define UP 0x02 #define UPRT 0x04 #define LT 0x08 #define RT 0x10 #define DNLT 0x20 #define DN 0x40 #define DNRT 0x80 static unsigned char buffer[(NROWS + 2) * (NCOLS + 2) + 2]; static unsigned char agebuf[(NROWS + 2) * (NCOLS + 2)]; /* Tempbuf stores the data for the next two rows so that we know * the state of those critter before he was modified by the fate * of the critters that have already been processed. */ static unsigned char tempbuf[NCOLS * 2]; /* Fates is a lookup table for the fate of a critter. The 256 * entries represent the 256 possible combinations of the 8 * neighbor cells. Each entry is one of BIRTH (create a cell * or leave one alive), SAME (leave the cell alive or dead), * or DEATH (kill anything in the cell). */ #define BIRTH 0 #define SAME 1 #define DEATH 2 static unsigned char fates[256]; static int patterns[][200] = { { /* EIGHT */ -3, -3, -2, -3, -1, -3, -3, -2, -2, -2, -1, -2, -3, -1, -2, -1, -1, -1, 0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1, 0, 2, 1, 2, 2, 2, 99 }, { /* PULSAR */ 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 1, 2, 5, 2, 99 }, { /* BARBER */ -7, -7, -6, -7, -7, -6, -5, -6, -5, -4, -3, -4, -3, -2, -1, -2, -1, 0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 4, 5, 5, 5, 99 }, { /* HERTZ */ -2, -6, -1, -6, -2, -5, -1, -5, -7, -3, -6, -3, -2, -3, -1, -3, 0, -3, 1, -3, 5, -3, 6, -3, -7, -2, -5, -2, -3, -2, 2, -2, 4, -2, 6, -2, -5, -1, -3, -1, -2, -1, 2, -1, 4, -1, -7, 0, -5, 0, -3, 0, 2, 0, 4, 0, 6, 0, -7, 1, -6, 1, -2, 1, -1, 1, 0, 1, 1, 1, 5, 1, 6, 1, -2, 3, -1, 3, -2, 4, -1, 4, 99 }, { /* TUMBLER */ -6, -6, -5, -6, 6, -6, 7, -6, -6, -5, -5, -5, 6, -5, 7, -5, -5, 5, 6, 5, -7, 6, -5, 6, 6, 6, 8, 6, -7, 7, -5, 7, 6, 7, 8, 7, -7, 8, -6, 8, 7, 8, 8, 8, 99 }, { /* PERIOD4 */ -5, -8, -4, -8, -7, -7, -5, -7, -8, -6, -2, -6, -7, -5, -3, -5, -2, -5, -5, -3, -3, -3, -4, -2, 99 }, { /* PERIOD5 */ -5, -8, -4, -8, -6, -7, -3, -7, -7, -6, -2, -6, -8, -5, -1, -5, -8, -4, -1, -4, -7, -3, -2, -3, -6, -2, -3, -2, -5, -1, -4, -1, 99 }, { /* PERIOD6 */ -4, -8, -3, -8, -8, -7, -7, -7, -5, -7, -8, -6, -7, -6, -4, -6, -1, -6, -3, -5, -1, -5, -2, -4, -3, -2, -2, -2, -3, -1, -2, -1, 99 }, { /* PINWHEEL */ -4, -8, -3, -8, -4, -7, -3, -7, -4, -5, -3, -5, -2, -5, -1, -5, -5, -4, -3, -4, 0, -4, 2, -4, 3, -4, -5, -3, -1, -3, 0, -3, 2, -3, 3, -3, -8, -2, -7, -2, -5, -2, -2, -2, 0, -2, -8, -1, -7, -1, -5, -1, 0, -1, -4, 0, -3, 0, -2, 0, -1, 0, -2, 2, -1, 2, -2, 3, -1, 3, 99 }, { /* ] */ -1, -1, 0, -1, 1, -1, 0, 0, 1, 0, -1, 1, 0, 1, 1, 1, 99 }, { /* cc: */ -3, -1, -2, -1, -1, -1, 1, -1, 2, -1, 3, -1, -3, 0, -2, 0, 1, 0, 2, 0, -3, 1, -2, 1, -1, 1, 1, 1, 2, 1, 3, 1, 99 }, { /* DOLBY */ -3, -1, -2, -1, -1, -1, 1, -1, 2, -1, 3, -1, -3, 0, -2, 0, 2, 0, 3, 0, -3, 1, -2, 1, -1, 1, 1, 1, 2, 1, 3, 1, 99 }, { /* HORIZON */ -15, 0, -14, 0, -13, 0, -12, 0, -11, 0, -10, 0, -9, 0, -8, 0, -7, 0, -6, 0, -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 4, 0, 3, 0, 2, 0, 1, 0, 0, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5, 0, 14, 0, 13, 0, 12, 0, 11, 0, 10, 0, 99 }, { /* SHEAR */ -7, -2, -6, -2, -5, -2, -4, -2, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, -5, -1, -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -3, 0, -2, 0, -1, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, -10, 1, -9, 1, -8, 1, -7, 1, -6, 1, -5, 1, -4, 1, -3, 1, -2, 1, -1, 1, -10, 2, -9, 2, -8, 2, -7, 2, -6, 2, -5, 2, -4, 2, -3, 2, -2, 2, -1, 2, 99 }, { /* VERTIGO */ 0, -7, 0, -6, 0, -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, 0, 7, 0, 6, 0, 5, 0, 4, 0, 3, 0, 2, 0, 1, 99 }, { /* CROSSBAR */ -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 4, 0, 3, 0, 2, 0, 1, 0, 0, 0, 99 }, { /* GOALPOSTS */ -8, -7, 8, -7, -8, -6, 8, -6, -8, -5, 8, -5, -8, -4, 8, -4, -8, -3, 8, -3, -8, -2, 8, -2, -8, -1, 8, -1, -8, 0, 8, 0, -8, 1, 8, 1, -8, 2, 8, 2, -8, 3, 8, 3, -8, 4, 8, 4, -8, 5, 8, 5, -8, 6, 8, 6, -8, 7, 8, 7, 99 }, { /* \ */ -8, -8, -7, -8, -7, -7, -6, -7, -6, -6, -5, -6, -5, -5, -4, -5, -4, -4, -3, -4, -3, -3, -2, -3, -2, -2, -1, -2, -1, -1, 0, -1, 0, 0, 1, 0, 1, 1, 2, 1, 2, 2, 3, 2, 3, 3, 4, 3, 4, 4, 5, 4, 5, 5, 6, 5, 6, 6, 7, 6, 7, 7, 8, 7, 99 }, { /* LABYRINTH */ -4, -4, -3, -4, -2, -4, -1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 4, -4, -4, -3, 0, -3, 4, -3, -4, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 4, -2, -4, -1, -2, -1, 2, -1, 4, -1, -4, 0, -2, 0, -1, 0, 0, 0, 1, 0, 2, 0, 4, 0, -4, 1, -2, 1, 2, 1, 4, 1, -4, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, 4, 2, -4, 3, 0, 3, 4, 3, -4, 4, -3, 4, -2, 4, -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4, 99 } }; #define NPATS (sizeof(patterns)/sizeof(patterns[0])) static void drawcell(row, col, age) unsigned char age; { if (color) XSetForeground(Dsp, Gc, (unsigned long) age); if (pixels) XFillRectangle(Dsp, Win, Gc, xb + xs * col, yb + ys * row, xs, ys); else XPutImage(Dsp, Win, Gc, &logo, 0, 0, xb + xs * col, yb + ys * row, lifeicon_width, lifeicon_height); } static void erasecell(row, col) { XFillRectangle(Dsp, Win, eraseGC, xb + xs * col, yb + ys * row, xs, ys); } static void spawn(loc) unsigned char *loc; { *(loc - NCOLS - 2 - 1) |= UPLT; *(loc - NCOLS - 2) |= UP; *(loc - NCOLS - 2 + 1) |= UPRT; *(loc - 1) |= LT; *(loc + 1) |= RT; *(loc + NCOLS + 2 - 1) |= DNLT; *(loc + NCOLS + 2) |= DN; *(loc + NCOLS + 2 + 1) |= DNRT; *(agebuf + (loc - buffer)) = 0; } static void kill(loc) unsigned char *loc; { *(loc - NCOLS - 2 - 1) &= ~UPLT; *(loc - NCOLS - 2) &= ~UP; *(loc - NCOLS - 2 + 1) &= ~UPRT; *(loc - 1) &= ~LT; *(loc + 1) &= ~RT; *(loc + NCOLS + 2 - 1) &= ~DNLT; *(loc + NCOLS + 2) &= ~DN; *(loc + NCOLS + 2 + 1) &= ~DNRT; } static void setcell(row, col) { register unsigned char *loc; loc = buffer + ((row + 1) * (NCOLS + 2)) + col + 1; spawn(loc); drawcell(row, col, 0); } static long seconds() { struct timeval foo; gettimeofday(&foo, (struct timezone *) 0); return foo.tv_sec; } void drawlife() { unsigned char *loc, *temploc; int row, col, cells = 0; unsigned char fate; loc = buffer + NCOLS + 2 + 1; temploc = tempbuf; /* copy the first 2 rows to the tempbuf */ bcopy(loc, temploc, NCOLS); bcopy(loc + NCOLS + 2, temploc + NCOLS, NCOLS); for (row = 0; row < NROWS; ++row) { for (col = 0; col < NCOLS; ++col) { fate = fates[*temploc]; *temploc = *(loc + (NCOLS + 2) * 2); switch (fate) { case BIRTH: if (!(*(loc + 1) & RT)) { spawn(loc); } /* NO BREAK */ case SAME: if (*(loc + 1) & RT) { register unsigned char *ageptr; register unsigned char age; ++cells; ageptr = agebuf + (loc - buffer); age = *ageptr; if (++age > 253) age = 0; *ageptr = age; drawcell(row, col, age); } break; case DEATH: if (*(loc + 1) & RT) { kill(loc); erasecell(row, col); } break; } loc++; temploc++; } loc += 2; if (temploc >= tempbuf + NCOLS * 2) temploc = tempbuf; } XFlush(Dsp); usleep(delay * 1000); if (!cells) startTime = 0; } static void init_fates() { int i, bits, neighbors; for (i = 0; i < 256; i++) { neighbors = 0; for (bits = i; bits; bits &= (bits - 1)) neighbors++; if (neighbors == 3) fates[i] = BIRTH; else if (neighbors == 2) fates[i] = SAME; else fates[i] = DEATH; } } void initlife(d, w, g, c, t, n) Display *d; Window w; GC g; int c, t, n; { int row, col; int *patptr; XWindowAttributes xgwa; startTime = seconds(); shooter = 0; Dsp = d; Win = w; Gc = g; color = c; timeout = t; delay = n; if (eraseGC == (GC) 0) { XGCValues xgcv; xgcv.foreground = BlackPixel(Dsp, 0); eraseGC = XCreateGC(Dsp, Win, GCForeground, &xgcv); srandom(time((long *) 0)); init_fates(); logo.data = lifeicon_bits; logo.width = lifeicon_width; logo.height = lifeicon_height; logo.bytes_per_line = 4; } if (!color) XSetForeground(Dsp, Gc, WhitePixel(Dsp, 0)); XGetWindowAttributes(Dsp, Win, &xgwa); width = xgwa.width; height = xgwa.height; xs = width / NCOLS; ys = height / NROWS; xb = (width - xs * NCOLS) / 2; yb = (height - ys * NROWS) / 2; pixels = (xs < lifeicon_width || ys < lifeicon_height); XFillRectangle(Dsp, Win, eraseGC, 0, 0, width, height); bzero(buffer, sizeof(buffer)); patptr = &patterns[(random() >> 3) % NPATS][0]; while ((col = *patptr++) != 99) { row = *patptr++; col += NCOLS / 2; row += NROWS / 2; setcell(row, col); } XFlush(Dsp); sleep(1); } int lifedone() { int elapsedTime = seconds() - startTime; if (elapsedTime > timeout) return 1; if (!shooter && elapsedTime > timeout / 2) { setcell(0, 2); setcell(1, 2); setcell(2, 2); setcell(2, 1); setcell(1, 0); shooter = 1; } return 0; } SHAR_EOF fi if test -f 'lifeicon.bit' then echo shar: "will not over-write existing file 'lifeicon.bit'" else cat << \SHAR_EOF > 'lifeicon.bit' #define lifeicon_width 29 #define lifeicon_height 29 static char lifeicon_bits[] = { 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x74, 0x07, 0x00, 0x00, 0xee, 0x0e, 0x00, 0x00, 0xdd, 0x1d, 0x00, 0x80, 0xbb, 0x3b, 0x00, 0x40, 0x77, 0x57, 0x00, 0xe0, 0xee, 0xee, 0x00, 0x70, 0xdd, 0x75, 0x01, 0xb8, 0xbb, 0xb9, 0x03, 0xdc, 0xf1, 0xdd, 0x01, 0xee, 0xee, 0xee, 0x0e, 0x77, 0x1f, 0x77, 0x1f, 0xbb, 0x1b, 0xbb, 0x1b, 0xdf, 0x1d, 0xdf, 0x1d, 0xee, 0xee, 0xee, 0x0e, 0x70, 0xf7, 0x71, 0x07, 0xb8, 0xb3, 0xbb, 0x03, 0xd0, 0x75, 0xd7, 0x01, 0xe0, 0xee, 0xee, 0x00, 0x40, 0xdd, 0x5d, 0x00, 0x80, 0xbb, 0x3b, 0x00, 0x00, 0x77, 0x17, 0x00, 0x00, 0xee, 0x0e, 0x00, 0x00, 0xdc, 0x05, 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00}; SHAR_EOF fi if test -f 'XCrDynCmap.c' then echo shar: "will not over-write existing file 'XCrDynCmap.c'" else cat << \SHAR_EOF > 'XCrDynCmap.c' #ifndef lint static char sccsid[] = "@(#)XCrDynCmap.c 22.2 89/09/20"; #endif /*- * XCrDynCmap.c - X11 library routine to create dynamic colormaps. * * Copyright (c) 1989 by Sun Microsystems, Inc. * * Author: Patrick J. Naughton * naughton@sun.com * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * */ #include <X11/X.h> #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/Xutil.h> Status XCreateDynamicColormap(dsp, screen, cmap, visual, colors, count, red, green, blue) Display *dsp; int screen; Colormap *cmap; Visual **visual; XColor *colors; int count; u_char *red, *green, *blue; { XVisualInfo vinfo; int pixels[256]; int i, ncolors, planes; unsigned long pmasks; Status allocReturn; planes = DisplayPlanes(dsp, screen); if (XMatchVisualInfo(dsp, screen, planes, PseudoColor, &vinfo)) { *visual = vinfo.visual; *cmap = XCreateColormap(dsp, RootWindow(dsp, screen), *visual, AllocNone); ncolors = vinfo.colormap_size; if (count > ncolors) return BadValue; allocReturn = XAllocColorCells(dsp, *cmap, False, &pmasks, 0, pixels, count); /* This should return Success, but it doesn't... Xlib bug? * (I'll ignore the return value for now...) */ #ifdef NOTDEF if (allocReturn != Success) return allocReturn; #endif /* NOTDEF */ for (i = 0; i < count; i++) { colors[i].pixel = pixels[i]; colors[i].red = *red++ << 8; colors[i].green = *green++ << 8; colors[i].blue = *blue++ << 8; colors[i].flags = DoRed | DoGreen | DoBlue; } XStoreColors(dsp, *cmap, colors, count); return Success; } else return BadMatch; } SHAR_EOF fi if test -f 'XCrHsbCmap.c' then echo shar: "will not over-write existing file 'XCrHsbCmap.c'" else cat << \SHAR_EOF > 'XCrHsbCmap.c' #ifndef lint static char sccsid[] = "@(#)XCrHsbCmap.c 22.2 89/09/20"; #endif /*- * XCrHsbCmap.c - X11 library routine to create an HSB ramp colormaps. * * Copyright (c) 1989 by Sun Microsystems, Inc. * * Author: Patrick J. Naughton * naughton@sun.com * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * */ #include <X11/X.h> #include <X11/Xos.h> #include <X11/Xlib.h> extern void HSBmap(); Status XCreateHSBColormap(dsp, screen, cmap, count, h1, s1, b1, h2, s2, b2, bw) Display *dsp; int screen; Colormap *cmap; /* colormap return value */ int count; /* number of entrys to use */ double h1, /* starting hue */ s1, /* starting saturation */ b1, /* starting brightness */ h2, /* ending hue */ s2, /* ending saturation */ b2; /* ending brightness */ int bw; /* Boolean: True = save black and white */ { u_char red[256]; u_char green[256]; u_char blue[256]; unsigned long pixel; Status status; Visual *visual; XColor xcolors[256]; if (count > 256) return BadValue; HSBramp(h1, s1, b1, h2, s2, b2, 0, count - 1, red, green, blue); if (bw) { pixel = WhitePixel(dsp, screen); red[pixel] = green[pixel] = blue[pixel] = 0xff; pixel = BlackPixel(dsp, screen); red[pixel] = green[pixel] = blue[pixel] = 0; } status = XCreateDynamicColormap(dsp, screen, cmap, &visual, xcolors, count, red, green, blue); return status; } SHAR_EOF fi if test -f 'HSBmap.c' then echo shar: "will not over-write existing file 'HSBmap.c'" else cat << \SHAR_EOF > 'HSBmap.c' #ifndef lint static char sccsid[] = "@(#)HSBmap.c 22.2 89/09/20"; #endif /*- * HSBmap.c - Create an HSB ramp. * * Copyright (c) 1989 by Sun Microsystems, Inc. * * Author: Patrick J. Naughton * naughton@sun.com * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * */ #include <sys/types.h> #include <math.h> void hsb2rgb(H, S, B, r, g, b) double H, S, B; u_char *r, *g, *b; { register int i; register double f, bb; register u_char p, q, t; H -= floor(H); /* remove anything over 1 */ H *= 6.0; i = floor(H); /* 0..5 */ f = H - (float) i; /* f = fractional part of H */ bb = 255.0 * B; p = (u_char) (bb * (1.0 - S)); q = (u_char) (bb * (1.0 - (S * f))); t = (u_char) (bb * (1.0 - (S * (1.0 - f)))); switch (i) { case 0: *r = (u_char) bb; *g = t; *b = p; break; case 1: *r = q; *g = (u_char) bb; *b = p; break; case 2: *r = p; *g = (u_char) bb; *b = t; break; case 3: *r = p; *g = q; *b = (u_char) bb; break; case 4: *r = t; *g = p; *b = (u_char) bb; break; case 5: *r = (u_char) bb; *g = p; *b = q; break; } } void HSBramp(h1, s1, b1, h2, s2, b2, start, end, red, green, blue) double h1, s1, b1, h2, s2, b2; int start, end; u_char *red, *green, *blue; { double dh, ds, db; register u_char *r, *g, *b; register int i; r = red; g = green; b = blue; dh = (h2 - h1) / 255.0; ds = (s2 - s1) / 255.0; db = (b2 - b1) / 255.0; for (i = start; i <= end; i++) { hsb2rgb(h1, s1, b1, r++, g++, b++); h1 += dh; s1 += ds; b1 += db; } } SHAR_EOF fi exit 0 # End of shell archive