[comp.sources.x] v10i068: xlock, Part02/03

naughton@Eng (Patrick Naughton) (11/14/90)

Submitted-by: naughton@Eng (Patrick Naughton)
Posting-number: Volume 10, Issue 68
Archive-name: xlock/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 3)."
# Contents:  life.c resource.c
# Wrapped by naughton@wind on Tue Oct 30 11:26:50 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'life.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'life.c'\"
else
echo shar: Extracting \"'life.c'\" \(12699 characters\)
sed "s/^X//" >'life.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char sccsid[] = "@(#)life.c	23.5 90/10/28 XLOCK SMI";
X#endif
X/*-
X * life.c - Conway's game of Life for the xlock X11 terminal locker.
X *
X * Copyright (c) 1989,90 by Sun Microsystems, Inc.
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.
X *
X * This file is provided AS IS with no warranties of any kind.	The author
X * shall have no liability with respect to the infringement of copyrights,
X * trade secrets or any patents by this file or any part thereof.  In no
X * event will the author be liable for any lost revenue or profits or
X * other special, indirect and consequential damages.
X *
X * Comments and additions should be sent to the authors:
X *
X *		       flar@eng.sun.com and naughton@eng.sun.com
X *
X *		       James A. Graham
X *		       Patrick J. Naughton
X *		       MS 14-01
X *		       Windows and Graphics Group
X *		       Sun Microsystems, Inc.
X *		       2550 Garcia Ave
X *		       Mountain View, CA  94043
X *
X * Revision History:
X * 29-Jul-90: support for multiple screens.
X * 07-Feb-90: remove bogus semi-colon after #include line.
X * 15-Dec-89: Fix for proper skipping of {White,Black}Pixel() in colors.
X * 08-Oct-89: Moved seconds() to an extern.
X * 20-Sep-89: Written.
X */
X
X#include "xlock.h"
X#include "lifeicon.bit"
X
Xstatic XImage logo = {
X    0, 0,			/* width, height */
X    0, XYBitmap, 0,		/* xoffset, format, data */
X    LSBFirst, 8,		/* byte-order, bitmap-unit */
X    LSBFirst, 8, 1		/* bitmap-bit-order, bitmap-pad, depth */
X};
X#define min(a, b) ((a)<(b)?(a):(b))
X#define	MAXROWS	55
X#define MAXCOLS	44
X
Xtypedef struct {
X    int         shooter;
X    int         pixelmode;
X    int         xs;
X    int         ys;
X    int         xb;
X    int         yb;
X    long        startTime;
X    long        elapsedTime;
X    int         nrows;
X    int         ncols;
X    int         width;
X    int         height;
X    unsigned char buffer[(MAXROWS + 2) * (MAXCOLS + 2) + 2];
X    unsigned char tempbuf[MAXCOLS * 2];
X    unsigned char agebuf[(MAXROWS + 2) * (MAXCOLS + 2)];
X}           lifestruct;
X
Xstatic lifestruct lifes[MAXSCREENS];
Xstatic int  icon_width,
X            icon_height;
X
X/* Buffer stores the data for each cell. Each cell is stored as
X * 8 bits representing the presence of a critter in each of it's
X * surrounding 8 cells. There is an empty row and column around
X * the whole array to allow stores without bounds checking as well
X * as an extra row at the end for the fetches into tempbuf.
X *
X * Tempbuf stores the data for the next two rows so that we know
X * the state of those critter before he was modified by the fate
X * of the critters that have already been processed.
X *
X * Agebuf stores the age of each critter.
X */
X
X#define	UPLT	0x01
X#define UP	0x02
X#define UPRT	0x04
X#define LT	0x08
X#define RT	0x10
X#define DNLT	0x20
X#define DN	0x40
X#define DNRT	0x80
X
X/* Fates is a lookup table for the fate of a critter. The 256
X * entries represent the 256 possible combinations of the 8
X * neighbor cells. Each entry is one of BIRTH (create a cell
X * or leave one alive), SAME (leave the cell alive or dead),
X * or DEATH (kill anything in the cell).
X */
X#define BIRTH	0
X#define SAME	1
X#define DEATH	2
Xstatic unsigned char fates[256];
Xstatic int  initialized = 0;
X
Xstatic int  patterns[][128] = {
X    {				/* EIGHT */
X	-3, -3, -2, -3, -1, -3,
X	-3, -2, -2, -2, -1, -2,
X	-3, -1, -2, -1, -1, -1,
X	0, 0, 1, 0, 2, 0,
X	0, 1, 1, 1, 2, 1,
X	0, 2, 1, 2, 2, 2,
X	99
X    },
X    {				/* PULSAR */
X	1, 1, 2, 1, 3, 1, 4, 1, 5, 1,
X	1, 2, 5, 2,
X	99
X    },
X    {				/* BARBER */
X	-7, -7, -6, -7,
X	-7, -6, -5, -6,
X	-5, -4, -3, -4,
X	-3, -2, -1, -2,
X	-1, 0, 1, 0,
X	1, 2, 3, 2,
X	3, 4, 5, 4,
X	4, 5, 5, 5,
X	99
X    },
X    {				/* HERTZ */
X	-2, -6, -1, -6,
X	-2, -5, -1, -5,
X	-7, -3, -6, -3, -2, -3, -1, -3, 0, -3, 1, -3, 5, -3, 6, -3,
X	-7, -2, -5, -2, -3, -2, 2, -2, 4, -2, 6, -2,
X	-5, -1, -3, -1, -2, -1, 2, -1, 4, -1,
X	-7, 0, -5, 0, -3, 0, 2, 0, 4, 0, 6, 0,
X	-7, 1, -6, 1, -2, 1, -1, 1, 0, 1, 1, 1, 5, 1, 6, 1,
X	-2, 3, -1, 3,
X	-2, 4, -1, 4,
X	99
X    },
X    {				/* TUMBLER */
X	-6, -6, -5, -6, 6, -6, 7, -6,
X	-6, -5, -5, -5, 6, -5, 7, -5,
X	-5, 5, 6, 5,
X	-7, 6, -5, 6, 6, 6, 8, 6,
X	-7, 7, -5, 7, 6, 7, 8, 7,
X	-7, 8, -6, 8, 7, 8, 8, 8,
X	99
X    },
X    {				/* PERIOD4 */
X	-5, -8, -4, -8,
X	-7, -7, -5, -7,
X	-8, -6, -2, -6,
X	-7, -5, -3, -5, -2, -5,
X	-5, -3, -3, -3,
X	-4, -2,
X	99
X    },
X    {				/* PERIOD5 */
X	-5, -8, -4, -8,
X	-6, -7, -3, -7,
X	-7, -6, -2, -6,
X	-8, -5, -1, -5,
X	-8, -4, -1, -4,
X	-7, -3, -2, -3,
X	-6, -2, -3, -2,
X	-5, -1, -4, -1,
X	99
X    },
X    {				/* PERIOD6 */
X	-4, -8, -3, -8,
X	-8, -7, -7, -7, -5, -7,
X	-8, -6, -7, -6, -4, -6, -1, -6,
X	-3, -5, -1, -5,
X	-2, -4,
X	-3, -2, -2, -2,
X	-3, -1, -2, -1,
X	99
X    },
X    {				/* PINWHEEL */
X	-4, -8, -3, -8,
X	-4, -7, -3, -7,
X	-4, -5, -3, -5, -2, -5, -1, -5,
X	-5, -4, -3, -4, 0, -4, 2, -4, 3, -4,
X	-5, -3, -1, -3, 0, -3, 2, -3, 3, -3,
X	-8, -2, -7, -2, -5, -2, -2, -2, 0, -2,
X	-8, -1, -7, -1, -5, -1, 0, -1,
X	-4, 0, -3, 0, -2, 0, -1, 0,
X	-2, 2, -1, 2,
X	-2, 3, -1, 3,
X	99
X    },
X    {				/* ] */
X	-1, -1, 0, -1, 1, -1,
X	0, 0, 1, 0,
X	-1, 1, 0, 1, 1, 1,
X	99
X    },
X    {				/* cc: */
X	-3, -1, -2, -1, -1, -1, 1, -1, 2, -1, 3, -1,
X	-3, 0, -2, 0, 1, 0, 2, 0,
X	-3, 1, -2, 1, -1, 1, 1, 1, 2, 1, 3, 1,
X	99
X    },
X    {				/* DOLBY */
X	-3, -1, -2, -1, -1, -1, 1, -1, 2, -1, 3, -1,
X	-3, 0, -2, 0, 2, 0, 3, 0,
X	-3, 1, -2, 1, -1, 1, 1, 1, 2, 1, 3, 1,
X	99
X    },
X    {				/* HORIZON */
X	-15, 0, -14, 0, -13, 0, -12, 0, -11, 0,
X	-10, 0, -9, 0, -8, 0, -7, 0, -6, 0,
X	-5, 0, -4, 0, -3, 0, -2, 0, -1, 0,
X	4, 0, 3, 0, 2, 0, 1, 0, 0, 0,
X	9, 0, 8, 0, 7, 0, 6, 0, 5, 0,
X	14, 0, 13, 0, 12, 0, 11, 0, 10, 0,
X	99
X    },
X    {				/* SHEAR */
X	-7, -2, -6, -2, -5, -2, -4, -2, -3, -2,
X	-2, -2, -1, -2, 0, -2, 1, -2, 2, -2,
X	-5, -1, -4, -1, -3, -1, -2, -1, -1, -1,
X	0, -1, 1, -1, 2, -1, 3, -1, 4, -1,
X	-3, 0, -2, 0, -1, 0, 0, 0, 1, 0,
X	2, 0, 3, 0, 4, 0, 5, 0, 6, 0,
X	-10, 1, -9, 1, -8, 1, -7, 1, -6, 1,
X	-5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
X	-10, 2, -9, 2, -8, 2, -7, 2, -6, 2,
X	-5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
X	99
X    },
X    {				/* VERTIGO */
X	0, -7,
X	0, -6,
X	0, -5,
X	0, -4,
X	0, -3,
X	0, -2,
X	0, -1,
X	0, 0,
X	0, 7,
X	0, 6,
X	0, 5,
X	0, 4,
X	0, 3,
X	0, 2,
X	0, 1,
X	99
X    },
X    {				/* CROSSBAR */
X	-5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 4, 0, 3, 0, 2, 0, 1, 0, 0, 0,
X	99
X    },
X    {				/* GOALPOSTS */
X	-8, -7, 8, -7,
X	-8, -6, 8, -6,
X	-8, -5, 8, -5,
X	-8, -4, 8, -4,
X	-8, -3, 8, -3,
X	-8, -2, 8, -2,
X	-8, -1, 8, -1,
X	-8, 0, 8, 0,
X	-8, 1, 8, 1,
X	-8, 2, 8, 2,
X	-8, 3, 8, 3,
X	-8, 4, 8, 4,
X	-8, 5, 8, 5,
X	-8, 6, 8, 6,
X	-8, 7, 8, 7,
X	99
X    },
X    {				/* \ */
X	-8, -8, -7, -8,
X	-7, -7, -6, -7,
X	-6, -6, -5, -6,
X	-5, -5, -4, -5,
X	-4, -4, -3, -4,
X	-3, -3, -2, -3,
X	-2, -2, -1, -2,
X	-1, -1, 0, -1,
X	0, 0, 1, 0,
X	1, 1, 2, 1,
X	2, 2, 3, 2,
X	3, 3, 4, 3,
X	4, 4, 5, 4,
X	5, 5, 6, 5,
X	6, 6, 7, 6,
X	7, 7, 8, 7,
X	99
X    },
X    {				/* LABYRINTH */
X	-4, -4, -3, -4, -2, -4, -1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 4, -4,
X	-4, -3, 0, -3, 4, -3,
X	-4, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 4, -2,
X	-4, -1, -2, -1, 2, -1, 4, -1,
X	-4, 0, -2, 0, -1, 0, 0, 0, 1, 0, 2, 0, 4, 0,
X	-4, 1, -2, 1, 2, 1, 4, 1,
X	-4, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, 4, 2,
X	-4, 3, 0, 3, 4, 3,
X	-4, 4, -3, 4, -2, 4, -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4,
X	99
X    }
X};
X
X#define NPATS	(sizeof patterns / sizeof patterns[0])
X
Xstatic void
Xdrawcell(win, row, col)
X    Window      win;
X    int         row,
X                col;
X{
X    lifestruct *lp = &lifes[screen];
X
X    XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen));
X    if (!mono && Scr[screen].npixels > 2) {
X	unsigned char *loc = lp->buffer + ((row + 1) * (lp->ncols + 2)) + col + 1;
X	unsigned char *ageptr = lp->agebuf + (loc - lp->buffer);
X	unsigned char age = *ageptr;
X
X	if (++age >= Scr[screen].npixels)
X	    age = 0;
X	XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[age]);
X	*ageptr = age + 1;
X    }
X    if (lp->pixelmode)
X	XFillRectangle(dsp, win, Scr[screen].gc,
X	       lp->xb + lp->xs * col, lp->yb + lp->ys * row, lp->xs, lp->ys);
X    else
X	XPutImage(dsp, win, Scr[screen].gc, &logo,
X		  0, 0, lp->xb + lp->xs * col, lp->yb + lp->ys * row,
X		  icon_width, icon_height);
X}
X
Xstatic void
Xerasecell(win, row, col)
X    Window      win;
X    int         row,
X                col;
X{
X    lifestruct *lp = &lifes[screen];
X    XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
X    XFillRectangle(dsp, win, Scr[screen].gc,
X	       lp->xb + lp->xs * col, lp->yb + lp->ys * row, lp->xs, lp->ys);
X}
X
Xstatic void
Xspawn(loc)
X    unsigned char *loc;
X{
X    lifestruct *lp = &lifes[screen];
X    *(loc - lp->ncols - 2 - 1) |= UPLT;
X    *(loc - lp->ncols - 2) |= UP;
X    *(loc - lp->ncols - 2 + 1) |= UPRT;
X    *(loc - 1) |= LT;
X    *(loc + 1) |= RT;
X    *(loc + lp->ncols + 2 - 1) |= DNLT;
X    *(loc + lp->ncols + 2) |= DN;
X    *(loc + lp->ncols + 2 + 1) |= DNRT;
X    *(lp->agebuf + (loc - lp->buffer)) = 0;
X}
X
Xstatic void
Xkill(loc)
X    unsigned char *loc;
X{
X    lifestruct *lp = &lifes[screen];
X    *(loc - lp->ncols - 2 - 1) &= ~UPLT;
X    *(loc - lp->ncols - 2) &= ~UP;
X    *(loc - lp->ncols - 2 + 1) &= ~UPRT;
X    *(loc - 1) &= ~LT;
X    *(loc + 1) &= ~RT;
X    *(loc + lp->ncols + 2 - 1) &= ~DNLT;
X    *(loc + lp->ncols + 2) &= ~DN;
X    *(loc + lp->ncols + 2 + 1) &= ~DNRT;
X}
X
Xstatic void
Xsetcell(win, row, col)
X    Window      win;
X    int         row;
X    int         col;
X{
X    lifestruct *lp = &lifes[screen];
X    unsigned char *loc;
X
X    loc = lp->buffer + ((row + 1) * (lp->ncols + 2)) + col + 1;
X    spawn(loc);
X    drawcell(win, row, col);
X}
X
Xvoid
Xdrawlife(win)
X    Window      win;
X{
X    unsigned char *loc,
X               *temploc;
X    int         row,
X                col,
X                cells = 0;
X    unsigned char fate;
X    lifestruct *lp = &lifes[screen];
X
X    loc = lp->buffer + lp->ncols + 2 + 1;
X    temploc = lp->tempbuf;
X    /* copy the first 2 rows to the tempbuf */
X    bcopy(loc, temploc, lp->ncols);
X    bcopy(loc + lp->ncols + 2, temploc + lp->ncols, lp->ncols);
X    for (row = 0; row < lp->nrows; ++row) {
X	for (col = 0; col < lp->ncols; ++col) {
X	    fate = fates[*temploc];
X	    *temploc = *(loc + (lp->ncols + 2) * 2);
X	    switch (fate) {
X	    case BIRTH:
X		if (!(*(loc + 1) & RT)) {
X		    spawn(loc);
X		}
X		/* NO BREAK */
X	    case SAME:
X		if (*(loc + 1) & RT) {
X		    ++cells;
X		    drawcell(win, row, col);
X		}
X		break;
X	    case DEATH:
X		if (*(loc + 1) & RT) {
X		    kill(loc);
X		    erasecell(win, row, col);
X		}
X		break;
X	    }
X	    loc++;
X	    temploc++;
X	}
X	loc += 2;
X	if (temploc >= lp->tempbuf + lp->ncols * 2)
X	    temploc = lp->tempbuf;
X    }
X    if (!cells)
X	lp->startTime = 0;
X    lp->elapsedTime = seconds() - lp->startTime;
X
X    if (!lp->shooter && lp->elapsedTime > timeout / 2) {
X	setcell(win, 0, 2);
X	setcell(win, 1, 2);
X	setcell(win, 2, 2);
X	setcell(win, 2, 1);
X	setcell(win, 1, 0);
X	lp->shooter = 1;
X    }
X}
X
Xstatic void
Xinit_fates()
X{
X    int         i,
X                bits,
X                neighbors;
X
X    for (i = 0; i < 256; i++) {
X	neighbors = 0;
X	for (bits = i; bits; bits &= (bits - 1))
X	    neighbors++;
X	if (neighbors == 3)
X	    fates[i] = BIRTH;
X	else if (neighbors == 2)
X	    fates[i] = SAME;
X	else
X	    fates[i] = DEATH;
X    }
X}
X
X
Xvoid
Xinitlife(win)
X    Window      win;
X{
X    int         row,
X                col;
X    int        *patptr;
X    XWindowAttributes xgwa;
X    lifestruct *lp = &lifes[screen];
X
X    lp->startTime = seconds();
X    lp->shooter = 0;
X    icon_width = lifeicon_width;
X    icon_height = lifeicon_height;
X
X    if (!initialized) {
X	initialized = 1;
X	srandom(time((long *) 0));
X	init_fates();
X	logo.data = lifeicon_bits;
X	logo.width = icon_width;
X	logo.height = icon_height;
X	logo.bytes_per_line = (icon_width + 7) / 8;
X    }
X    XGetWindowAttributes(dsp, win, &xgwa);
X    lp->width = xgwa.width;
X    lp->height = xgwa.height;
X    lp->pixelmode = (lp->width < 4 * icon_width);
X    if (lp->pixelmode) {
X	lp->ncols = 32;
X	lp->nrows = 32;
X    } else {
X	lp->ncols = min(lp->width / icon_width, MAXCOLS);
X	lp->nrows = min(lp->height / icon_height, MAXROWS);
X    }
X    lp->xs = lp->width / lp->ncols;
X    lp->ys = lp->height / lp->nrows;
X    lp->xb = (lp->width - lp->xs * lp->ncols) / 2;
X    lp->yb = (lp->height - lp->ys * lp->nrows) / 2;
X
X    XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
X    XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, lp->width, lp->height);
X
X    bzero(lp->buffer, sizeof(lp->buffer));
X    patptr = &patterns[random() % NPATS][0];
X    while ((col = *patptr++) != 99) {
X	row = *patptr++;
X	col += lp->ncols / 2;
X	row += lp->nrows / 2;
X	setcell(win, row, col);
X    }
X}
END_OF_FILE
if test 12699 -ne `wc -c <'life.c'`; then
    echo shar: \"'life.c'\" unpacked with wrong size!
fi
# end of 'life.c'
fi
if test -f 'resource.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'resource.c'\"
else
echo shar: Extracting \"'resource.c'\" \(19605 characters\)
sed "s/^X//" >'resource.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char sccsid[] = "@(#)resource.c	1.12 90/10/30 XLOCK SMI";
X#endif
X/*-
X * resource.c - resource management for xlock.
X *
X * Copyright (c) 1988-90 by Patrick Naughton and Sun Microsystems, Inc.
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.
X *
X * This file is provided AS IS with no warranties of any kind.  The author
X * shall have no liability with respect to the infringement of copyrights,
X * trade secrets or any patents by this file or any part thereof.  In no
X * event will the author be liable for any lost revenue or profits or
X * other special, indirect and consequential damages.
X *
X * Comments and additions should be sent to the author:
X *
X *		       naughton@eng.sun.com
X *
X *		       Patrick J. Naughton
X *		       MS 14-01
X *		       Windows and Graphics Group
X *		       Sun Microsystems, Inc.
X *		       2550 Garcia Ave
X *		       Mountain View, CA  94043
X *
X * Revision History:
X * 29-Oct-90: Added #include <ctype.h> for missing isupper() on some OS revs.
X *	      moved -mode option, reordered Xrm database evaluation.
X * 28-Oct-90: Added text strings.
X * 26-Oct-90: Fix bug in mode specific options.
X * 31-Jul-90: Fix ':' handling in parsefilepath
X * 07-Jul-90: Created from resource work in xlock.c
X *
X */
X
X#include <stdio.h>
X#include "xlock.h"
X#include <netdb.h>
X#include <math.h>
X#include <ctype.h>
X
X#include <X11/Xresource.h>
X
X/*
X * Declare external interface routines for supported screen savers.
X */
X
Xextern void inithop();
Xextern void drawhop();
X
Xextern void initlife();
Xextern void drawlife();
X
Xextern void initqix();
Xextern void drawqix();
X
Xextern void initimage();
Xextern void drawimage();
X
Xextern void initblank();
Xextern void drawblank();
X
Xextern void initswarm();
Xextern void drawswarm();
X
Xtypedef struct {
X    char       *cmdline_arg;
X    void        (*lp_init) ();
X    void        (*lp_callback) ();
X    char       *desc;
X}           LockStruct;
X
Xstatic LockStruct LockProcs[] = {
X    {"hop", inithop, drawhop, "Hopalong iterated fractals"},
X    {"qix", initqix, drawqix, "Spinning lines a la Qix(tm)"},
X    {"image", initimage, drawimage, "Random bouncing image"},
X    {"life", initlife, drawlife, "Conway's game of Life"},
X    {"swarm", initswarm, drawswarm, "Swarm of bees"},
X    {"blank", initblank, drawblank, "Blank screen"},
X};
X#define NUMPROCS (sizeof LockProcs / sizeof LockProcs[0])
X
X#ifndef MAXHOSTNAMELEN
X#define MAXHOSTNAMELEN 64	/* SunOS 3.5 does not define this */
X#endif
X
Xextern char *getenv();
X
X#ifndef DEF_FILESEARCHPATH
X#define DEF_FILESEARCHPATH "/usr/lib/X11/%T/%N%S"
X#endif
X#define DEF_DISPLAY	":0"
X#define DEF_MODE	"hop"
X#define DEF_FONT	"-*-lucida-medium-r-normal-sans-24-*-*-*-*-*-*-*"
X#define DEF_BG		"White"
X#define DEF_FG		"Black"
X#define DEF_NAME	"Name: "
X#define DEF_PASS	"Password: "
X#define DEF_INFO	"Enter password to unlock; select icon to lock."
X#define DEF_VALID	"Validating login..."
X#define DEF_INVALID	"Invalid login."
X#define DEF_TIMEOUT	"30"	/* secs till password entry times out */
X#define DEF_BC		"100"	/* vectors (or whatever) per batch */
X#define DEF_DELAY	"1000"	/* microseconds between batches */
X#define DEF_NICE	"10"	/* xlock process nicelevel */
X#define DEF_SAT		"1.0"	/* color ramp saturation 0->1 */
X#define CLASSNAME	"XLock"
X
Xstatic XrmOptionDescRec genTable[] = {
X    {"-mode", ".mode", XrmoptionSepArg, (caddr_t) NULL},
X    {"-nolock", ".nolock", XrmoptionNoArg, (caddr_t) "on"},
X    {"+nolock", ".nolock", XrmoptionNoArg, (caddr_t) "off"},
X    {"-remote", ".remote", XrmoptionNoArg, (caddr_t) "on"},
X    {"+remote", ".remote", XrmoptionNoArg, (caddr_t) "off"},
X    {"-mono", ".mono", XrmoptionNoArg, (caddr_t) "on"},
X    {"+mono", ".mono", XrmoptionNoArg, (caddr_t) "off"},
X    {"-allowroot", ".allowroot", XrmoptionNoArg, (caddr_t) "on"},
X    {"+allowroot", ".allowroot", XrmoptionNoArg, (caddr_t) "off"},
X    {"-enablesaver", ".enablesaver", XrmoptionNoArg, (caddr_t) "on"},
X    {"+enablesaver", ".enablesaver", XrmoptionNoArg, (caddr_t) "off"},
X    {"-allowaccess", ".allowaccess", XrmoptionNoArg, (caddr_t) "on"},
X    {"+allowaccess", ".allowaccess", XrmoptionNoArg, (caddr_t) "off"},
X    {"-echokeys", ".echokeys", XrmoptionNoArg, (caddr_t) "on"},
X    {"+echokeys", ".echokeys", XrmoptionNoArg, (caddr_t) "off"},
X    {"-v", ".verbose", XrmoptionNoArg, (caddr_t) "on"},
X    {"+v", ".verbose", XrmoptionNoArg, (caddr_t) "off"},
X    {"-nice", ".nice", XrmoptionSepArg, (caddr_t) NULL},
X    {"-timeout", ".timeout", XrmoptionSepArg, (caddr_t) NULL},
X    {"-font", ".font", XrmoptionSepArg, (caddr_t) NULL},
X    {"-bg", ".background", XrmoptionSepArg, (caddr_t) NULL},
X    {"-fg", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
X    {"-background", ".background", XrmoptionSepArg, (caddr_t) NULL},
X    {"-foreground", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
X    {"-name", ".name", XrmoptionSepArg, (caddr_t) NULL},
X    {"-password", ".password", XrmoptionSepArg, (caddr_t) NULL},
X    {"-info", ".info", XrmoptionSepArg, (caddr_t) NULL},
X    {"-validate", ".validate", XrmoptionSepArg, (caddr_t) NULL},
X    {"-invalid", ".invalid", XrmoptionSepArg, (caddr_t) NULL},
X};
X#define genEntries (sizeof genTable / sizeof genTable[0])
X
Xstatic XrmOptionDescRec modeTable[] = {
X    {"-delay", ".delay", XrmoptionSepArg, (caddr_t) NULL},
X    {"-batchcount", ".batchcount", XrmoptionSepArg, (caddr_t) NULL},
X    {"-saturation", ".saturation", XrmoptionSepArg, (caddr_t) NULL},
X};
X#define modeEntries (sizeof modeTable / sizeof modeTable[0])
X
Xstatic XrmOptionDescRec cmdlineTable[] = {
X    {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
X    {"-nolock", ".nolock", XrmoptionNoArg, (caddr_t) "on"},
X    {"+nolock", ".nolock", XrmoptionNoArg, (caddr_t) "off"},
X    {"-remote", ".remote", XrmoptionNoArg, (caddr_t) "on"},
X    {"+remote", ".remote", XrmoptionNoArg, (caddr_t) "off"},
X};
X#define cmdlineEntries (sizeof cmdlineTable / sizeof cmdlineTable[0])
X
X
Xtypedef struct {
X    char       *opt;
X    char       *desc;
X}           OptionStruct;
X
Xstatic OptionStruct opDesc[] = {
X    {"-help", "print out this message"},
X    {"-display displayname", "X server to contact"},
X    {"-/+mono", "turn on/off monochrome override"},
X    {"-/+nolock", "turn on/off no password required mode"},
X    {"-/+remote", "turn on/off remote host access"},
X    {"-/+allowroot", "turn on/off allow root password mode"},
X    {"-/+enablesaver", "turn on/off enable X server screen saver"},
X    {"-/+allowaccess", "turn on/off allow new clients to connect"},
X    {"-/+echokeys", "turn on/off echo '?' for each password key"},
X    {"-/+v", "turn on/off verbose mode"},
X    {"-delay usecs", "microsecond delay between screen updates"},
X    {"-batchcount num", "number of things per batch"},
X    {"-nice level", "nice level for xlock process"},
X    {"-timeout seconds", "number of seconds before password times out"},
X    {"-saturation value", "saturation of color ramp"},
X    {"-font fontname", "font to use for password prompt"},
X    {"-bg color", "background color to use for password prompt"},
X    {"-fg color", "foreground color to use for password prompt"},
X    {"-name string", "text string to use for Name prompt"},
X    {"-password string", "text string to use for Password prompt"},
X    {"-info string", "text string to use for instructions"},
X    {"-validate string", "text string to use for validating password message"},
X    {"-invalid string", "text string to use for invalid password message"},
X};
X#define opDescEntries (sizeof opDesc / sizeof opDesc[0])
X
Xchar       *display;
Xchar       *mode;
Xchar       *fontname;
Xchar       *background;
Xchar       *foreground;
Xchar       *text_name;
Xchar       *text_pass;
Xchar       *text_info;
Xchar       *text_valid;
Xchar       *text_invalid;
Xfloat       saturation;
Xint         nicelevel;
Xint         delay;
Xint         batchcount;
Xint         timeout;
XBool        mono;
XBool        nolock;
XBool        remote;
XBool        allowroot;
XBool        enablesaver;
XBool        allowaccess;
XBool        echokeys;
XBool        verbose;
X
X#define t_String	0
X#define t_Float		1
X#define t_Int		2
X#define t_Bool		3
X
Xtypedef struct {
X    caddr_t    *var;
X    char       *name;
X    char       *class;
X    char       *def;
X    int         type;
X}           argtype;
X
Xstatic argtype genvars[] = {
X    {(caddr_t *) &fontname, "font", "Font", DEF_FONT, t_String},
X    {(caddr_t *) &background, "background", "Background", DEF_BG, t_String},
X    {(caddr_t *) &foreground, "foreground", "Foreground", DEF_FG, t_String},
X    {(caddr_t *) &text_name, "name", "Name", DEF_NAME, t_String},
X    {(caddr_t *) &text_pass, "password", "Password", DEF_PASS, t_String},
X    {(caddr_t *) &text_info, "info", "Info", DEF_INFO, t_String},
X    {(caddr_t *) &text_valid, "validate", "Validate", DEF_VALID, t_String},
X    {(caddr_t *) &text_invalid, "invalid", "Invalid", DEF_INVALID, t_String},
X    {(caddr_t *) &nicelevel, "nice", "Nice", DEF_NICE, t_Int},
X    {(caddr_t *) &timeout, "timeout", "Timeout", DEF_TIMEOUT, t_Int},
X    {(caddr_t *) &mono, "mono", "Mono", "off", t_Bool},
X    {(caddr_t *) &nolock, "nolock", "NoLock", "off", t_Bool},
X    {(caddr_t *) &remote, "remote", "Remote", "off", t_Bool},
X    {(caddr_t *) &allowroot, "allowroot", "AllowRoot", "off", t_Bool},
X    {(caddr_t *) &enablesaver, "enablesaver", "EnableSaver", "off", t_Bool},
X    {(caddr_t *) &allowaccess, "allowaccess", "AllowAccess", "off", t_Bool},
X    {(caddr_t *) &echokeys, "echokeys", "EchoKeys", "off", t_Bool},
X    {(caddr_t *) &verbose, "verbose", "Verbose", "off", t_Bool},
X};
X#define NGENARGS (sizeof genvars / sizeof genvars[0])
X
Xstatic argtype modevars[] = {
X    {(caddr_t *) &saturation, "saturation", "Saturation", DEF_SAT, t_Float},
X    {(caddr_t *) &delay, "delay", "Delay", DEF_DELAY, t_Int},
X    {(caddr_t *) &batchcount, "batchcount", "BatchCount", DEF_BC, t_Int},
X};
X#define NMODEARGS (sizeof modevars / sizeof modevars[0])
X
X
Xstatic void
XSyntax(badOption)
X    char       *badOption;
X{
X    int         col,
X                len,
X                i;
X
X    fprintf(stderr, "%s:  bad command line option \"%s\"\n\n",
X	    ProgramName, badOption);
X
X    fprintf(stderr, "usage:  %s", ProgramName);
X    col = 8 + strlen(ProgramName);
X    for (i = 0; i < opDescEntries; i++) {
X	len = 3 + strlen(opDesc[i].opt);	/* space [ string ] */
X	if (col + len > 79) {
X	    fprintf(stderr, "\n   ");	/* 3 spaces */
X	    col = 3;
X	}
X	fprintf(stderr, " [%s]", opDesc[i].opt);
X	col += len;
X    }
X
X    len = 8 + strlen(LockProcs[0].cmdline_arg);
X    if (col + len > 79) {
X	fprintf(stderr, "\n   ");	/* 3 spaces */
X	col = 3;
X    }
X    fprintf(stderr, " [-mode %s", LockProcs[0].cmdline_arg);
X    col += len;
X    for (i = 1; i < NUMPROCS; i++) {
X	len = 3 + strlen(LockProcs[i].cmdline_arg);
X	if (col + len > 79) {
X	    fprintf(stderr, "\n   ");	/* 3 spaces */
X	    col = 3;
X	}
X	fprintf(stderr, " | %s", LockProcs[i].cmdline_arg);
X	col += len;
X    }
X    fprintf(stderr, "]\n");
X
X    fprintf(stderr, "\nType %s -help for a full description.\n\n",
X	    ProgramName);
X    exit(1);
X}
X
Xstatic void
XHelp()
X{
X    int         i;
X
X    fprintf(stderr, "usage:\n        %s [-options ...]\n\n", ProgramName);
X    fprintf(stderr, "where options include:\n");
X    for (i = 0; i < opDescEntries; i++) {
X	fprintf(stderr, "    %-28s %s\n", opDesc[i].opt, opDesc[i].desc);
X    }
X
X    fprintf(stderr, "    %-28s %s\n", "-mode mode", "animation mode");
X    fprintf(stderr, "    where mode is one of:\n");
X    for (i = 0; i < NUMPROCS; i++) {
X	fprintf(stderr, "          %-23s %s\n",
X		LockProcs[i].cmdline_arg, LockProcs[i].desc);
X    }
X    putc('\n', stderr);
X
X    exit(0);
X}
X
X
Xstatic void
XLowerString(s)
X    char       *s;
X{
X
X    while (*s) {
X	if (isupper(*s))
X	    *s += ('a' - 'A');
X	s++;
X    }
X}
X
Xstatic void
XGetResource(database, parentname, parentclass,
X	    name, class, valueType, def, valuep)
X    XrmDatabase database;
X    char       *parentname;
X    char       *parentclass;
X    char       *name;
X    char       *class;
X    int         valueType;
X    char       *def;
X    caddr_t    *valuep;		/* RETURN */
X{
X    char       *type;
X    XrmValue    value;
X    char       *string;
X    char        buffer[1024];
X    char        fullname[1024];
X    char        fullclass[1024];
X    int         len;
X
X    sprintf(fullname, "%s.%s", parentname, name);
X    sprintf(fullclass, "%s.%s", parentclass, class);
X    if (XrmGetResource(database, fullname, fullclass, &type, &value)) {
X	string = value.addr;
X	len = value.size;
X    } else {
X	string = def;
X	len = strlen(string);
X    }
X    (void) strncpy(buffer, string, sizeof(buffer));
X    buffer[sizeof(buffer) - 1] = '\0';
X
X    switch (valueType) {
X    case t_String:
X	{
X	    char       *s = (char *) malloc(len + 1);
X	    if (s == (char *) NULL)
X		error("%s: GetResource - couldn't allocate memory");
X	    (void) strncpy(s, string, len);
X	    s[len] = '\0';
X	    *((char **) valuep) = s;
X	}
X	break;
X    case t_Bool:
X	LowerString(buffer);
X	*((int *) valuep) = (!strcmp(buffer, "true") ||
X			     !strcmp(buffer, "on") ||
X			     !strcmp(buffer, "enabled") ||
X			     !strcmp(buffer, "yes")) ? True : False;
X	break;
X    case t_Int:
X	*((int *) valuep) = atoi(buffer);
X	break;
X    case t_Float:
X	*((float *) valuep) = (float) atof(buffer);
X	break;
X    }
X}
X
X
Xstatic      XrmDatabase
Xparsefilepath(xfilesearchpath, TypeName, ClassName)
X    char       *xfilesearchpath;
X    char       *TypeName;
X    char       *ClassName;
X{
X    XrmDatabase database = NULL;
X    char        appdefaults[1024];
X    char       *src;
X    char       *dst;
X
X    src = xfilesearchpath;
X    appdefaults[0] = '\0';
X    dst = appdefaults;
X    while (1) {
X	if (*src == '%') {
X	    src++;
X	    switch (*src) {
X	    case '%':
X	    case ':':
X		*dst++ = *src++;
X		*dst = '\0';
X		break;
X	    case 'T':
X		(void) strcat(dst, TypeName);
X		src++;
X		dst += strlen(TypeName);
X		break;
X	    case 'N':
X		(void) strcat(dst, ClassName);
X		src++;
X		dst += strlen(ClassName);
X		break;
X	    case 'S':
X		src++;
X		break;
X	    default:
X		src++;
X		break;
X	    }
X	} else if (*src == ':') {
X	    database = XrmGetFileDatabase(appdefaults);
X	    if (database == NULL) {
X		dst = appdefaults;
X		src++;
X	    } else
X		break;
X	} else if (*src == '\0') {
X	    database = XrmGetFileDatabase(appdefaults);
X	    break;
X	} else {
X	    *dst++ = *src++;
X	    *dst = '\0';
X	}
X    }
X    return database;
X}
X
X
Xstatic void
Xopen_display()
X{
X    if (display != NULL) {
X	extern char *strchr();
X	char       *colon = strchr(display, ':');
X	int         n = colon - display;
X
X	if (colon == NULL)
X	    error("%s: Malformed -display argument, \"%s\"\n", display);
X
X	/*
X	 * only restrict access to other displays if we are locking and if the
X	 * Remote resource is not set.
X	 */
X	if (nolock)
X	    remote = True;
X	if (!remote && n
X		&& strncmp(display, "unix", n)
X		&& strncmp(display, "localhost", n)) {
X	    char        hostname[MAXHOSTNAMELEN];
X	    struct hostent *host;
X	    char      **hp;
X	    int         badhost = 1;
X
X	    if (gethostname(hostname, MAXHOSTNAMELEN))
X		error("%s: Can't get local hostname.\n");
X
X	    if (!(host = gethostbyname(hostname)))
X		error("%s: Can't get hostbyname.\n");
X
X	    if (strncmp(display, host->h_name, n)) {
X		for (hp = host->h_aliases; *hp; hp++) {
X		    if (!strncmp(display, *hp, n)) {
X			badhost = 0;
X			break;
X		    }
X		}
X		if (badhost) {
X		    *colon = (char) 0;
X		    error("%s: can't lock %s's display\n", display);
X		}
X	    }
X	}
X    } else
X	display = ":0.0";
X    if (!(dsp = XOpenDisplay(display)))
X	error("%s: unable to open display %s.\n", display);
X}
X
Xvoid
Xprintvar(class, var)
X    char       *class;
X    argtype     var;
X{
X    switch (var.type) {
X    case t_String:
X	fprintf(stderr, "%s.%s: %s\n",
X		class, var.name, *((char **) var.var));
X	break;
X    case t_Bool:
X	fprintf(stderr, "%s.%s: %s\n",
X		class, var.name, *((int *) var.var)
X		? "True" : "False");
X	break;
X    case t_Int:
X	fprintf(stderr, "%s.%s: %d\n",
X		class, var.name, *((int *) var.var));
X	break;
X    case t_Float:
X	fprintf(stderr, "%s.%s: %f\n",
X		class, var.name, *((float *) var.var));
X	break;
X    }
X}
X
X
Xvoid
XGetResources(argc, argv)
X    int         argc;
X    char       *argv[];
X{
X    XrmDatabase RDB = NULL;
X    XrmDatabase modeDB = NULL;
X    XrmDatabase cmdlineDB = NULL;
X    XrmDatabase generalDB = NULL;
X    XrmDatabase homeDB = NULL;
X    XrmDatabase applicationDB = NULL;
X    XrmDatabase serverDB = NULL;
X    char        modename[1024];
X    char        modeclass[1024];
X    char       *env;
X    char       *serverString;
X    int         i;
X
X    XrmInitialize();
X
X    env = getenv("XFILESEARCHPATH");
X    applicationDB = parsefilepath(env ? env : DEF_FILESEARCHPATH,
X				  "app-defaults", CLASSNAME);
X
X    XrmParseCommand(&cmdlineDB, cmdlineTable, cmdlineEntries, ProgramName,
X		    &argc, argv);
X
X    (void) XrmMergeDatabases(applicationDB, &RDB);
X    (void) XrmMergeDatabases(cmdlineDB, &RDB);
X
X    env = getenv("DISPLAY");
X    GetResource(RDB, ProgramName, CLASSNAME, "display", "Display", t_String,
X		env ? env : DEF_DISPLAY, &display);
X    GetResource(RDB, ProgramName, CLASSNAME, "nolock", "NoLock", t_Bool,
X		"off", (caddr_t *) &nolock);
X    GetResource(RDB, ProgramName, CLASSNAME, "remote", "Remote", t_Bool,
X		"off", (caddr_t *) &remote);
X
X    open_display();
X    serverString = XResourceManagerString(dsp);
X    if (serverString) {
X	serverDB = XrmGetStringDatabase(serverString);
X	(void) XrmMergeDatabases(serverDB, &RDB);
X    } else {
X	char        buf[1024];
X	env = getenv("HOME");
X	sprintf(buf, "%s/.Xdefaults", env ? env : "");
X	homeDB = XrmGetFileDatabase(buf);
X	(void) XrmMergeDatabases(homeDB, &RDB);
X    }
X
X    XrmParseCommand(&generalDB, genTable, genEntries, ProgramName, &argc, argv);
X    (void) XrmMergeDatabases(generalDB, &RDB);
X
X    GetResource(RDB, ProgramName, CLASSNAME, "mode", "Mode", t_String,
X		DEF_MODE, (caddr_t *) &mode);
X    sprintf(modename, "%s.%s", ProgramName, mode);
X    sprintf(modeclass, "%s.%s", CLASSNAME, mode);
X
X    XrmParseCommand(&modeDB, modeTable, modeEntries, modeclass, &argc, argv);
X    (void) XrmMergeDatabases(modeDB, &RDB);
X
X    /* Parse the rest of the command line */
X    for (argc--, argv++; argc > 0; argc--, argv++) {
X	if (**argv != '-')
X	    Syntax(*argv);
X	switch (argv[0][1]) {
X	case 'h':
X	    Help();
X	    /* NOTREACHED */
X	default:
X	    Syntax(*argv);
X	    /* NOTREACHED */
X	}
X    }
X
X    /* the RDB is set, now query load the variables from the database */
X
X    for (i = 0; i < NGENARGS; i++)
X	GetResource(RDB, ProgramName, CLASSNAME,
X		    genvars[i].name, genvars[i].class,
X		    genvars[i].type, genvars[i].def, genvars[i].var);
X
X    for (i = 0; i < NMODEARGS; i++)
X	GetResource(RDB, modename, modeclass,
X		    modevars[i].name, modevars[i].class,
X		    modevars[i].type, modevars[i].def, modevars[i].var);
X
X    (void) XrmDestroyDatabase(RDB);
X
X    if (verbose) {
X	for (i = 0; i < NGENARGS; i++)
X	    printvar(ProgramName, genvars[i]);
X	for (i = 0; i < NMODEARGS; i++)
X	    printvar(modename, modevars[i]);
X    }
X}
X
X
XCheckResources()
X{
X    int         i;
X
X    if (batchcount < 1)
X	Syntax("-batchcount argument must be positive.");
X    if (saturation < 0.0 || saturation > 1.0)
X	Syntax("-saturation argument must be between 0.0 and 1.0.");
X
X    for (i = 0; i < NUMPROCS; i++) {
X	if (!strncmp(LockProcs[i].cmdline_arg, mode, strlen(mode))) {
X	    init = LockProcs[i].lp_init;
X	    callback = LockProcs[i].lp_callback;
X	    break;
X	}
X    }
X    if (i == NUMPROCS) {
X	fprintf(stderr, "Unknown mode: ");
X	Syntax(mode);
X    }
X}
END_OF_FILE
if test 19605 -ne `wc -c <'resource.c'`; then
    echo shar: \"'resource.c'\" unpacked with wrong size!
fi
# end of 'resource.c'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.
--
dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.