v05i004: xlock -- lockscreen for X displays, Part01/01
Dan Heller
argv at island.uu.net
Mon Sep 25 03:49:29 AEST 1989
Submitted-by: Patrick Naughton <naughton at 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 at 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 at 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 at heron.bbn.com karlton at wsl.dec.com
dana at thumper.bellcore.com vesper at 3d.dec.com flar at 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 at 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 at heron.bbn.com
* karlton at wsl.dec.com
* dana at thumper.bellcore.com
* vesper at 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 at 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 at 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 at sun.com or naughton at 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 at 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 at 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 at 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
More information about the Comp.sources.x
mailing list