From: Zygo Blaxell Date: Fri, 27 Feb 2009 19:22:48 +0000 (-0500) Subject: ftp://ftp.uniovi.es/pub/X11R6/graphics/misc/lock/xlock-2.3.tar.gz X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6cb1c12fcba2d3dd7a08ab52b9c83f81f1aeef41;p=xscreensaver ftp://ftp.uniovi.es/pub/X11R6/graphics/misc/lock/xlock-2.3.tar.gz -rw-r--r-- 1 zblaxell zblaxell 41932 May 12 1993 xlock-2.3.tar.gz 0f9372eb24359e2487ae55a8c1188e46c9d6d2c4 xlock-2.3.tar.gz --- 6cb1c12fcba2d3dd7a08ab52b9c83f81f1aeef41 diff --git a/HPUX.Install b/HPUX.Install new file mode 100644 index 00000000..3ef84bc7 --- /dev/null +++ b/HPUX.Install @@ -0,0 +1,14 @@ +Changes made to the original distribution: + +XLock.ad - default mode is now "pyro" - *much* better than "life" :-) +usleep.c - Bad #ifdef for HP-UX machines (which usually use -DSYSV), so + modified to fix the problem. +worm.c - Added a rint() function because HP-UX isn't supplied with one. +xlock.h - Fixed some bad assumptions about SYSV systems (well, bad w.r.t. + HP-UX anyway !). + +Recommendation: + +Get xautolock at the same time as this - the combination of the two together +(xautolock running xlock -nolock) makes for an excellent screen saver +replacement. diff --git a/Imakefile b/Imakefile new file mode 100644 index 00000000..6df4e452 --- /dev/null +++ b/Imakefile @@ -0,0 +1,18 @@ +# @(#)Imakefile 23.9 91/09/27 +# Imakefile - xlock +# + DEFINES = -DDEF_FILESEARCHPATH=\"$(LIBDIR)/%T/%N%S\" -DSTARSIZE=2 + DEPLIBS = $(DEPXLIB) +LOCAL_LIBRARIES = $(XLIB) + LINTLIBS = $(LINTXLIB) + SYS_LIBRARIES = -lm + SRCS = xlock.c hsbramp.c usleep.c resource.c \ + hopalong.c qix.c life.c image.c blank.c \ + swarm.c rotor.c pyro.c flame.c worm.c + OBJS = xlock.o hsbramp.o usleep.o resource.o \ + hopalong.o qix.o life.o image.o blank.o \ + swarm.o rotor.o pyro.o flame.o worm.o + +ComplexProgramTarget(xlock) +InstallAppDefaults(XLock) + diff --git a/Makefile.720 b/Makefile.720 new file mode 100644 index 00000000..2bf52c9a --- /dev/null +++ b/Makefile.720 @@ -0,0 +1,518 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $ +# +# The cpp used on this machine replaces all newlines and multiple tabs and +# spaces in a macro expansion with a single space. Imake tries to compensate +# for this, but is not always successful. +# + +########################################################################### +# Makefile generated from "Imake.tmpl" and +# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $ +# +# Platform-specific parameters may be set in the appropriate .cf +# configuration files. Site-wide parameters may be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor doesn't define any unique symbols, you'll need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make Makefile", "make Makefiles", or "make World"). +# +# If you absolutely can't get imake to work, you'll need to set the +# variables at the top of each Makefile as well as the dependencies at the +# bottom (makedepend will do this automatically). +# + +# 59 + +# 66 + +# 73 + +# 87 + +# 94 + +# 101 + +# 108 + +# 115 + +# 123 + +# 131 + +# 140 + +# 147 + +# 156 + +# 160 + +# 179 + +# 188 + +########################################################################### +# platform-specific configuration parameters - edit hp.cf to change + +# 15 + +# platform: $XConsortium: hp.cf,v 1.24 89/12/10 11:57:02 rws Exp $ +# operating system: HP-UX 7.0 + +# 57 + +# 63 + +# 67 + +########################################################################### +# site-specific configuration parameters - edit site.def to change + +# site: $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $ + +# 113 + +# 122 + +# 128 + +# 139 + +# 215 + +# 218 + +# 221 + +# 231 + +# 241 + +# 246 + +# 253 + +# 260 + +# 270 + +# 276 + +# 304 + +# 314 + +# 324 + +# 328 + +# 335 + +# 338 + +# 341 + +# 398 + +# 408 + +# 425 + +# 443 + +# 456 + +# 464 + +# 474 + +# 480 + +# 486 + +# 493 + +# 499 + +# 510 + +# 514 + +# 529 + +# 538 + + SHELL = /bin/sh + + TOP = /users/compsci/heswallA/X11R4/mit + CURRENT_DIR = . + + AR = ar cq + BOOTSTRAPCFLAGS = + CC = cc +# 558 + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = cc -E $(STD_CPP_DEFINES) + INSTALL = $(SCRIPTSRC)/bsdinst.sh + LD = ld + LINT = lint + LINTLIBFLAG = -o + LINTOPTS = -ax -Nd4000 -Ns3300 -Ne700 -Np200 -Na25000 -DSYSV -DBITMAPDIR=\"/MIT/include/X11/bitmaps\" + LN = ln -s + MAKE = make + MV = mv -f + CP = cp + RANLIB = /bin/true + RANLIBINSTFLAGS = + RM = /bin/rm -f + STD_INCLUDES = + STD_CPP_DEFINES = -DSYSV + STD_DEFINES = -Wc,-Nd4000,-Ns3300,-Ne700,-Np200 -DSYSV -DBITMAPDIR=\"/MIT/include/X11/bitmaps\" + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + TAGS = ctags + + MFLAGS = -$(MAKEFLAGS) + +# 586 + +# 589 + +# 595 + +# 602 + + PROTO_DEFINES = + + INSTPGMFLAGS = -s +# 611 + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -m 4755 + INSTLIBFLAGS = -m 0664 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -m 4755 + + DESTDIR = +# 623 + + TOP_INCLUDES = -I$(TOP) + + CDEBUGFLAGS = -O + CCOPTIONS = + COMPATFLAGS = + + ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS) + CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) + LDCOMBINEFLAGS = -X -r + + MACROFILE = hp.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = +# 650 + + IRULESRC = $(CONFIGSRC) + IMAKE_CMD = $(NEWTOP)$(IMAKE) -I$(NEWTOP)$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \ + $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \ + $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +########################################################################### +# X Window System Build Parameters +# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $ + +# 21 + +# 27 + +# 39 + +# 84 + +# 87 + +# 90 + +# 117 + +# 133 + +# 142 + +# 152 + +# 155 + +# 228 + +# 234 + +# 240 + +# 248 + +# 255 + +# 262 + +# 269 + +# 276 + +# 286 + +# 328 + +########################################################################### +# X Window System make variables; this need to be coordinated with rules +# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $ + + PATHSEP = / + USRLIBDIR = /MIT/lib + BINDIR = /MIT/bin/X11 + INCROOT = /MIT/include + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = $(DESTDIR)/usr/adm + LIBDIR = $(USRLIBDIR)/X11 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + AWMDIR = $(LIBDIR)/awm + TWMDIR = $(LIBDIR)/twm + GWMDIR = $(LIBDIR)/gwm + MANPATH = $(DESTDIR)/usr/local/man + MANSOURCEPATH = $(MANPATH)/man + MANDIR = $(MANSOURCEPATH)1 + LIBMANDIR = $(MANSOURCEPATH)3 + XAPPLOADDIR = $(LIBDIR)/app-defaults +# 376 + + FONTCFLAGS = -t + + INSTAPPFLAGS = $(INSTDATFLAGS) + +# 388 + + IMAKE = $(IMAKESRC)/imake + DEPEND = $(DEPENDSRC)/makedepend + RGB = $(RGBSRC)/rgb + FONTC = $(BDFTOSNFSRC)/bdftosnf + MKFONTDIR = $(MKFONTDIRSRC)/mkfontdir + MKDIRHIER = /bin/sh $(SCRIPTSRC)/mkdirhier.sh + + CONFIGSRC = $(TOP)/config + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + MKFONTDIRSRC = $(FONTSRC)/mkfontdir + EXTENSIONSRC = $(TOP)/extensions + +# 429 + +# 435 + + DEPEXTENSIONLIB = $(EXTENSIONSRC)/lib/libXext.a + EXTENSIONLIB = $(DEPEXTENSIONLIB) + +# 442 + + DEPXLIB = $(DEPEXTENSIONLIB) $(XLIBSRC)/libX11.a + XLIB = $(EXTENSIONLIB) $(XLIBSRC)/libX11.a + + DEPXAUTHLIB = $(XAUTHSRC)/libXau.a + XAUTHLIB = $(DEPXAUTHLIB) +# 451 + + DEPXMULIB = $(XMUSRC)/libXmu.a + XMULIB = $(DEPXMULIB) + +# 458 + + DEPOLDXLIB = $(OLDXLIBSRC)/liboldX.a + OLDXLIB = $(DEPOLDXLIB) + +# 465 + + DEPXTOOLLIB = $(TOOLKITSRC)/libXt.a + XTOOLLIB = $(DEPXTOOLLIB) + +# 472 + + DEPXAWLIB = $(AWIDGETSRC)/libXaw.a + XAWLIB = $(DEPXAWLIB) + + LINTEXTENSIONLIB = $(EXTENSIONSRC)/lib/llib-lXext.ln + LINTXLIB = $(XLIBSRC)/llib-lX11.ln + LINTXMU = $(XMUSRC)/llib-lXmu.ln + LINTXTOOL = $(TOOLKITSRC)/llib-lXt.ln + LINTXAW = $(AWIDGETSRC)/llib-lXaw.ln + +# 491 + +# 496 + +# 513 + + DEPLIBS = $(LOCAL_LIBRARIES) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +########################################################################### +# Imake rules for building libraries, programs, scripts, and data files +# rules: $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $ + +# 125 + +# 136 + +# 512 + +# 525 + +# 581 + +# 1321 + +########################################################################### +# start of Imakefile + +# @(#)Imakefile 23.9 91/09/27 +# Imakefile - xlock +# + DEFINES = -DDEF_FILESEARCHPATH=\"$(LIBDIR)/%T/%N%S\" -DSTARSIZE=2 + DEPLIBS = $(DEPXLIB) +LOCAL_LIBRARIES = /MIT/lib/libXext.a /MIT/lib/libX11.a + LINTLIBS = $(LINTXLIB) + SYS_LIBRARIES = -lm + SRCS = xlock.c hsbramp.c usleep.c resource.c \ + hopalong.c qix.c life.c image.c blank.c \ + swarm.c rotor.c pyro.c flame.c worm.c + OBJS = xlock.o hsbramp.o usleep.o resource.o \ + hopalong.o qix.o life.o image.o blank.o \ + swarm.o rotor.o pyro.o flame.o worm.o + + PROGRAM = xlock + +all:: xlock + +xlock: $(OBJS) $(DEPLIBS) + $(RM) $@; if [ -f $@ ]; then $(MV) $@ $@~; fi + $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS) + +install:: xlock + $(INSTALL) -c $(INSTPGMFLAGS) xlock $(BINDIR) + +install.man:: xlock.man + $(INSTALL) -c $(INSTMANFLAGS) xlock.man $(MANDIR)/xlock.1 + +depend:: $(DEPEND) + +$(DEPEND): + @echo "checking $@ over in $(DEPENDSRC) first..."; \ + cd $(DEPENDSRC); $(MAKE); \ + echo "okay, continuing in $(CURRENT_DIR)" + +depend:: + $(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS) + +lint: + $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS) +lint1: + $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS) + +clean:: + $(RM) $(PROGRAM) + +install:: XLock.ad + $(INSTALL) -c $(INSTAPPFLAGS) XLock.ad $(XAPPLOADDIR)/XLock + +########################################################################### +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) \#* + +Makefile:: $(IMAKE) + +$(IMAKE): + @(cd $(IMAKESRC); if [ -f Makefile ]; then \ + echo "checking $@ in $(IMAKESRC) first..."; $(MAKE) all; else \ + echo "bootstrapping $@ from Makefile.ini in $(IMAKESRC) first..."; \ + $(MAKE) -f Makefile.ini BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS); fi; \ + echo "okay, continuing in $(CURRENT_DIR)") + +Makefile:: + -@if [ -f Makefile ]; then \ + echo " $(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS +# 690 + +# 698 + +# 712 + +########################################################################### +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +########################################################################### +# dependencies generated by makedepend + diff --git a/Makefile.imake b/Makefile.imake new file mode 100644 index 00000000..fe1f617d --- /dev/null +++ b/Makefile.imake @@ -0,0 +1,14 @@ + 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) diff --git a/Makefile.shipped b/Makefile.shipped new file mode 100644 index 00000000..5f40225a --- /dev/null +++ b/Makefile.shipped @@ -0,0 +1,29 @@ +# @(#)Makefile 1.9 91/09/27 XLOCK +# Makefile for xlock on a Sun. + +C_SRCS=xlock.c hsbramp.c usleep.c resource.c \ + hopalong.c qix.c life.c image.c blank.c \ + swarm.c rotor.c pyro.c flame.c worm.c +HDRS=xlock.h +IMAGES=lifeicon.bit sunlogo.bit +SRCS=${C_SRCS} ${HDRS} ${IMAGES} xlock.man XLock.ad +OBJS=${C_SRCS:.c=.o} +COPT=-O +OWDIR=/usr/openwin +CFLAGS=${COPT} -I${OWDIR}/include +LDFLAGS=-L${OWDIR}/lib +LIBS=${LDFLAGS} -lX11 -lm + +xlock: ${OBJS} + cc -o $@ ${OBJS} ${LIBS} + +debug: xlock +debug:=COPT=-g -DDEBUG + +resource.o:=DEFINES=-DDEF_FILESEARCHPATH=\"$(LIBDIR)/%T/%N%S\" +pyro.o:=DEFINES=-DSTARSIZE=2 + +tar: + tar cvf xlock.tar ${SRCS} Makefile Makefile.imake Imakefile README + +.KEEP_STATE: diff --git a/README b/README new file mode 100644 index 00000000..36f64359 --- /dev/null +++ b/README @@ -0,0 +1,28 @@ + +This is the latest version of xlock (sccs version 23.21) patchlevel = 2.3 + +CHANGES: + o added worm mode. + o old -name and .name changed to -username and .username. + o lint cast. + o change color allocation to allow "#ffaabb" style color names. + o portability bug in flame mode fixed plus some other nits. + o white on black on monochrome screens fixed. + + Copyright (c) 1988-91 by Patrick J. Naughton. + + 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. + + ______________________________________________________________________ + Patrick J. Naughton email: naughton@sun.com + Sun Microsystems Laboratories, Inc. voice: (415) 336 - 1080 diff --git a/README.LUCS b/README.LUCS new file mode 100644 index 00000000..178da8d5 --- /dev/null +++ b/README.LUCS @@ -0,0 +1,10 @@ +Package name: xlock +Version number: 2.3 +Report bugs to: ftp@csc.liv.ac.uk +Tested on: HP 9000/720 running HP-UX 8.07 +Purpose: Locks the local X display until a password is entered. During the locking, one + of several graphics demos can be shown, including fractal generation, fireworks + or a swarm of lines. Best used in combination with xautolock as a screen saver + replacement. +Date archived: Thu 9 Jul 1992 +Special notes: Please, please, please read HPUX.Install diff --git a/XLock.ad b/XLock.ad new file mode 100644 index 00000000..92376aa6 --- /dev/null +++ b/XLock.ad @@ -0,0 +1,50 @@ +XLock.mode: pyro +XLock.font: -b&h-lucida-medium-r-normal-sans-24-*-*-*-*-*-iso8859-1 +XLock.background: White +XLock.foreground: Black +XLock.username: Name: +XLock.password: Password: +XLock.info: Enter password to unlock; select icon to lock. +XLock.validate: Validating login... +XLock.invalid: Invalid login. +XLock.nice: 10 +XLock.timeout: 30 +XLock.mono: off +XLock.nolock: off +XLock.remote: off +XLock.allowroot: off +XLock.enablesaver: off +XLock.allowaccess: off +XLock.echokeys: off +XLock.usefirst: off +XLock.verbose: off +XLock.hop.delay: 0 +XLock.hop.batchcount: 1000 +XLock.hop.saturation: 1 +XLock.qix.delay: 30000 +XLock.qix.batchcount: 64 +XLock.qix.saturation: 1 +XLock.image.delay: 2000000 +XLock.image.batchcount: 8 +XLock.image.saturation: 0.3 +XLock.life.delay: 1000000 +XLock.life.batchcount: 100 +XLock.life.saturation: 1 +XLock.swarm.delay: 10000 +XLock.swarm.batchcount: 100 +XLock.swarm.saturation: 1 +XLock.rotor.delay: 10000 +XLock.rotor.batchcount: 4 +XLock.rotor.saturation: 0.4 +XLock.pyro.delay: 15000 +XLock.pyro.batchcount: 40 +XLock.pyro.saturation: 1 +XLock.flame.delay: 10000 +XLock.flame.batchcount: 20 +XLock.flame.saturation: 1 +XLock.worm.delay: 10000 +XLock.worm.batchcount: 20 +XLock.worm.saturation: 1 +XLock.blank.delay: 5000000 +XLock.blank.batchcount: 1 +XLock.blank.saturation: 1 diff --git a/XLock.ad.cln b/XLock.ad.cln new file mode 100644 index 00000000..7f434065 --- /dev/null +++ b/XLock.ad.cln @@ -0,0 +1,50 @@ +XLock.mode: life +XLock.font: -b&h-lucida-medium-r-normal-sans-24-*-*-*-*-*-iso8859-1 +XLock.background: White +XLock.foreground: Black +XLock.username: Name: +XLock.password: Password: +XLock.info: Enter password to unlock; select icon to lock. +XLock.validate: Validating login... +XLock.invalid: Invalid login. +XLock.nice: 10 +XLock.timeout: 30 +XLock.mono: off +XLock.nolock: off +XLock.remote: off +XLock.allowroot: off +XLock.enablesaver: off +XLock.allowaccess: off +XLock.echokeys: off +XLock.usefirst: off +XLock.verbose: off +XLock.hop.delay: 0 +XLock.hop.batchcount: 1000 +XLock.hop.saturation: 1 +XLock.qix.delay: 30000 +XLock.qix.batchcount: 64 +XLock.qix.saturation: 1 +XLock.image.delay: 2000000 +XLock.image.batchcount: 8 +XLock.image.saturation: 0.3 +XLock.life.delay: 1000000 +XLock.life.batchcount: 100 +XLock.life.saturation: 1 +XLock.swarm.delay: 10000 +XLock.swarm.batchcount: 100 +XLock.swarm.saturation: 1 +XLock.rotor.delay: 10000 +XLock.rotor.batchcount: 4 +XLock.rotor.saturation: 0.4 +XLock.pyro.delay: 15000 +XLock.pyro.batchcount: 40 +XLock.pyro.saturation: 1 +XLock.flame.delay: 10000 +XLock.flame.batchcount: 20 +XLock.flame.saturation: 1 +XLock.worm.delay: 10000 +XLock.worm.batchcount: 20 +XLock.worm.saturation: 1 +XLock.blank.delay: 5000000 +XLock.blank.batchcount: 1 +XLock.blank.saturation: 1 diff --git a/blank.c b/blank.c new file mode 100644 index 00000000..8ae0b075 --- /dev/null +++ b/blank.c @@ -0,0 +1,29 @@ +#ifndef lint +static char sccsid[] = "@(#)blank.c 1.5 91/05/24 XLOCK"; +#endif +/*- + * blank.c - blank screen for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 31-Aug-90: Written. + */ + +#include "xlock.h" + +/*ARGSUSED*/ +void +drawblank(win) + Window win; +{ +} + +void +initblank(win) + Window win; +{ + XClearWindow(dsp, win); +} diff --git a/flame.c b/flame.c new file mode 100644 index 00000000..654b5ab0 --- /dev/null +++ b/flame.c @@ -0,0 +1,167 @@ +#ifndef lint +static char sccsid[] = "@(#)flame.c 1.4 91/09/27 XLOCK"; +#endif +/*- + * flame.c - recursive fractal cosmic flames. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 27-Jun-91: vary number of functions used. + * 24-Jun-91: fixed portability problem with integer mod (%). + * 06-Jun-91: Written. (received from Scott Graves, spot@cs.cmu.edu). + */ + +#include "xlock.h" +#include + +#define MAXTOTAL 10000 +#define MAXBATCH 10 +#define MAXLEV 4 + +typedef struct { + double f[2][3][MAXLEV];/* three non-homogeneous transforms */ + int max_levels; + int cur_level; + int snum; + int anum; + int width, height; + int num_points; + int total_points; + int pixcol; + Window win; + XPoint pts[MAXBATCH]; +} flamestruct; + +static flamestruct flames[MAXSCREENS]; + +static short +halfrandom(mv) + int mv; +{ + static short lasthalf = 0; + unsigned long r; + + if (lasthalf) { + r = lasthalf; + lasthalf = 0; + } else { + r = random(); + lasthalf = r >> 16; + } + return r % mv; +} + +void +initflame(win) + Window win; +{ + flamestruct *fs = &flames[screen]; + XWindowAttributes xwa; + + srandom(time((long *) 0)); + + XGetWindowAttributes(dsp, win, &xwa); + fs->width = xwa.width; + fs->height = xwa.height; + + fs->max_levels = batchcount; + fs->win = win; + + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, fs->width, fs->height); + + if (Scr[screen].npixels > 2) { + fs->pixcol = halfrandom(Scr[screen].npixels); + XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[fs->pixcol]); + } else { + XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen)); + } +} + +static Bool +recurse(fs, x, y, l) + flamestruct *fs; + register double x, y; + register int l; +{ + int xp, yp, i; + double nx, ny; + + if (l == fs->max_levels) { + fs->total_points++; + if (fs->total_points > MAXTOTAL) /* how long each fractal runs */ + return False; + + if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0) { + xp = fs->pts[fs->num_points].x = (int) ((fs->width / 2) + * (x + 1.0)); + yp = fs->pts[fs->num_points].y = (int) ((fs->height / 2) + * (y + 1.0)); + fs->num_points++; + if (fs->num_points > MAXBATCH) { /* point buffer size */ + XDrawPoints(dsp, fs->win, Scr[screen].gc, fs->pts, + fs->num_points, CoordModeOrigin); + fs->num_points = 0; + } + } + } else { + for (i = 0; i < fs->snum; i++) { + nx = fs->f[0][0][i] * x + fs->f[0][1][i] * y + fs->f[0][2][i]; + ny = fs->f[1][0][i] * x + fs->f[1][1][i] * y + fs->f[1][2][i]; + if (i < fs->anum) { + nx = sin(nx); + ny = sin(ny); + } + if (!recurse(fs, nx, ny, l + 1)) + return False; + } + } + return True; +} + + +void +drawflame(win) + Window win; +{ + flamestruct *fs = &flames[screen]; + + int i, j, k; + static alt = 0; + + if (!(fs->cur_level++ % fs->max_levels)) { + XClearWindow(dsp, fs->win); + alt = !alt; + } else { + if (Scr[screen].npixels > 2) { + XSetForeground(dsp, Scr[screen].gc, + Scr[screen].pixels[fs->pixcol]); + if (--fs->pixcol < 0) + fs->pixcol = Scr[screen].npixels - 1; + } + } + + /* number of functions */ + fs->snum = 2 + (fs->cur_level % (MAXLEV - 1)); + + /* how many of them are of alternate form */ + if (alt) + fs->anum = 0; + else + fs->anum = halfrandom(fs->snum) + 2; + + /* 6 coefs per function */ + for (k = 0; k < fs->snum; k++) { + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fs->f[i][j][k] = ((double) (random() & 1023) / 512.0 - 1.0); + } + fs->num_points = 0; + fs->total_points = 0; + (void) recurse(fs, 0.0, 0.0, 0); + XDrawPoints(dsp, win, Scr[screen].gc, + fs->pts, fs->num_points, CoordModeOrigin); +} diff --git a/hopalong.c b/hopalong.c new file mode 100644 index 00000000..0c7b37b1 --- /dev/null +++ b/hopalong.c @@ -0,0 +1,112 @@ +#ifndef lint +static char sccsid[] = "@(#)hopalong.c 23.9 91/05/24 XLOCK"; +#endif +/*- + * hopalong.c - Real Plane Fractals for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 29-Oct-90: fix bad (int) cast. + * 29-Jul-90: support for multiple screens. + * 08-Jul-90: new timing and colors and new algorithm for fractals. + * 15-Dec-89: Fix for proper skipping of {White,Black}Pixel() in colors. + * 08-Oct-89: Fixed long standing typo bug in RandomInitHop(); + * Fixed bug in memory allocation in inithop(); + * Moved seconds() to an extern. + * Got rid of the % mod since .mod is slow on a sparc. + * 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 "xlock.h" +#include + +typedef struct { + int centerx; + int centery; /* center of the screen */ + double a; + double b; + double c; + double i; + double j; /* hopalong parameters */ + int inc; + int pix; + long startTime; +} hopstruct; + +static hopstruct hops[MAXSCREENS]; +static XPoint *pointBuffer = 0; /* pointer for XDrawPoints */ + +#define TIMEOUT 30 + +void +inithop(win) + Window win; +{ + double range; + XWindowAttributes xgwa; + hopstruct *hp = &hops[screen]; + + + XGetWindowAttributes(dsp, win, &xgwa); + hp->centerx = xgwa.width / 2; + hp->centery = xgwa.height / 2; + range = sqrt((double) hp->centerx * hp->centerx + + (double) hp->centery * hp->centery) / + (10.0 + random() % 10); + + hp->pix = 0; + hp->inc = (int) ((random() / MAXRAND) * 200) - 100; + hp->a = (random() / MAXRAND) * range - range / 2.0; + hp->b = (random() / MAXRAND) * range - range / 2.0; + hp->c = (random() / MAXRAND) * range - range / 2.0; + if (!(random() % 2)) + hp->c = 0.0; + + hp->i = hp->j = 0.0; + + if (!pointBuffer) + pointBuffer = (XPoint *) malloc(batchcount * sizeof(XPoint)); + + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, + hp->centerx * 2, hp->centery * 2); + XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen)); + hp->startTime = seconds(); +} + + +void +drawhop(win) + Window win; +{ + double oldj; + int k = batchcount; + XPoint *xp = pointBuffer; + hopstruct *hp = &hops[screen]; + + hp->inc++; + if (!mono && Scr[screen].npixels > 2) { + XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[hp->pix]); + if (++hp->pix >= Scr[screen].npixels) + hp->pix = 0; + } + while (k--) { + oldj = hp->j; + hp->j = hp->a - hp->i; + hp->i = oldj + (hp->i < 0 + ? sqrt(fabs(hp->b * (hp->i + hp->inc) - hp->c)) + : -sqrt(fabs(hp->b * (hp->i + hp->inc) - hp->c))); + xp->x = hp->centerx + (int) (hp->i + hp->j); + xp->y = hp->centery - (int) (hp->i - hp->j); + xp++; + } + XDrawPoints(dsp, win, Scr[screen].gc, + pointBuffer, batchcount, CoordModeOrigin); + if (seconds() - hp->startTime > TIMEOUT) + inithop(win); +} diff --git a/hsbramp.c b/hsbramp.c new file mode 100644 index 00000000..57a927f4 --- /dev/null +++ b/hsbramp.c @@ -0,0 +1,114 @@ +#ifndef lint +static char sccsid[] = "@(#)hsbramp.c 23.5 91/05/24 XLOCK"; +#endif +/*- + * hsbramp.c - Create an HSB ramp. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 29-Jul-90: renamed hsbramp.c from HSBmap.c + * minor optimizations. + * 01-Sep-88: Written. + */ + +#include +#include + +void +hsb2rgb(H, S, B, r, g, b) + double H, + S, + B; + u_char *r, + *g, + *b; +{ + int i; + double f; + double bb; + u_char p; + u_char q; + u_char 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; + } +} + + +/* + * Input is two points in HSB color space and a count + * of how many discreet rgb space values the caller wants. + * + * Output is that many rgb triples which describe a linear + * interpolate ramp between the two input colors. + */ + +void +hsbramp(h1, s1, b1, h2, s2, b2, count, red, green, blue) + double h1, + s1, + b1, + h2, + s2, + b2; + int count; + + u_char *red, + *green, + *blue; +{ + double dh; + double ds; + double db; + + dh = (h2 - h1) / count; + ds = (s2 - s1) / count; + db = (b2 - b1) / count; + while (count--) { + hsb2rgb(h1, s1, b1, red++, green++, blue++); + h1 += dh; + s1 += ds; + b1 += db; + } +} diff --git a/image.c b/image.c new file mode 100644 index 00000000..bf8ece1a --- /dev/null +++ b/image.c @@ -0,0 +1,111 @@ +#ifndef lint +static char sccsid[] = "@(#)image.c 1.7 91/05/24 XLOCK"; +#endif +/*- + * image.c - image bouncer for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 29-Jul-90: Written. + */ + +#include "xlock.h" +#include "sunlogo.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 */ +}; + +#define MAXICONS 256 + +typedef struct { + int x; + int y; +} point; + +typedef struct { + int width; + int height; + int nrows; + int ncols; + int xb; + int yb; + int iconmode; + int iconcount; + point icons[MAXICONS]; + long startTime; +} imagestruct; + +static imagestruct ims[MAXSCREENS]; + +void +drawimage(win) + Window win; +{ + imagestruct *ip = &ims[screen]; + int i; + + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + for (i = 0; i < ip->iconcount; i++) { + if (!ip->iconmode) + XFillRectangle(dsp, win, Scr[screen].gc, + ip->xb + sunlogo_width * ip->icons[i].x, + ip->yb + sunlogo_height * ip->icons[i].y, + sunlogo_width, sunlogo_height); + + ip->icons[i].x = random() % ip->ncols; + ip->icons[i].y = random() % ip->nrows; + } + if (Scr[screen].npixels == 2) + XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen)); + for (i = 0; i < ip->iconcount; i++) { + if (Scr[screen].npixels > 2) + XSetForeground(dsp, Scr[screen].gc, + Scr[screen].pixels[random() % Scr[screen].npixels]); + + XPutImage(dsp, win, Scr[screen].gc, &logo, + 0, 0, + ip->xb + sunlogo_width * ip->icons[i].x, + ip->yb + sunlogo_height * ip->icons[i].y, + sunlogo_width, sunlogo_height); + } +} + +void +initimage(win) + Window win; +{ + XWindowAttributes xgwa; + imagestruct *ip = &ims[screen]; + + ip->startTime = seconds(); + + logo.data = (char *) sunlogo_bits; + logo.width = sunlogo_width; + logo.height = sunlogo_height; + logo.bytes_per_line = (sunlogo_width + 7) / 8; + + XGetWindowAttributes(dsp, win, &xgwa); + ip->width = xgwa.width; + ip->height = xgwa.height; + ip->ncols = ip->width / sunlogo_width; + ip->nrows = ip->height / sunlogo_height; + ip->iconmode = (ip->ncols < 2 || ip->nrows < 2); + if (ip->iconmode) { + ip->xb = 0; + ip->yb = 0; + ip->iconcount = 1; /* icon mode */ + } else { + ip->xb = (ip->width - sunlogo_width * ip->ncols) / 2; + ip->yb = (ip->height - sunlogo_height * ip->nrows) / 2; + ip->iconcount = batchcount; + } + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, ip->width, ip->height); +} diff --git a/life.c b/life.c new file mode 100644 index 00000000..3100e63e --- /dev/null +++ b/life.c @@ -0,0 +1,612 @@ +#ifndef lint +static char sccsid[] = "@(#)life.c 23.6 91/05/24 XLOCK"; +#endif +/*- + * life.c - Conway's game of Life for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 24-May-91: Added wraparound code from johnson@bugs.comm.mot.com. + * Made old cells stay blue. + * Made batchcount control the number of generations till restart. + * 29-Jul-90: support for multiple screens. + * 07-Feb-90: remove bogus semi-colon after #include line. + * 15-Dec-89: Fix for proper skipping of {White,Black}Pixel() in colors. + * 08-Oct-89: Moved seconds() to an extern. + * 20-Sep-89: Written (life algorithm courtesy of Jim Graham, flar@sun.com). + */ + +#include "xlock.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 */ +}; +#define min(a, b) ((a)<(b)?(a):(b)) +#define MAXROWS 155 +#define MAXCOLS 144 +#define TIMEOUT 30 + +typedef struct { + int pixelmode; + int xs; + int ys; + int xb; + int yb; + int generation; + long shooterTime; + int nrows; + int ncols; + int width; + int height; + unsigned char buffer[(MAXROWS + 2) * (MAXCOLS + 2) + 2]; + unsigned char tempbuf[MAXCOLS * 2]; + unsigned char lastbuf[MAXCOLS]; + unsigned char agebuf[(MAXROWS + 2) * (MAXCOLS + 2)]; +} lifestruct; + +static lifestruct lifes[MAXSCREENS]; +static int icon_width, icon_height; + +/* 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. + * + * 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. + * + * Agebuf stores the age of each critter. + */ + +#define UPLT 0x01 +#define UP 0x02 +#define UPRT 0x04 +#define LT 0x08 +#define RT 0x10 +#define DNLT 0x20 +#define DN 0x40 +#define DNRT 0x80 + +/* 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 initialized = 0; + +static int patterns[][128] = { + { /* 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(win, row, col) + Window win; + int row, col; +{ + lifestruct *lp = &lifes[screen]; + + XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen)); + if (!mono && Scr[screen].npixels > 2) { + unsigned char *loc = lp->buffer + ((row + 1) * (lp->ncols + 2)) + col + 1; + unsigned char *ageptr = lp->agebuf + (loc - lp->buffer); + unsigned char age = *ageptr; + + /* if we aren't up to blue yet, then keep aging the cell. */ + if (age < Scr[screen].npixels * 0.7) + ++age; + + XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[age]); + *ageptr = age; + } + if (lp->pixelmode) + XFillRectangle(dsp, win, Scr[screen].gc, + lp->xb + lp->xs * col, lp->yb + lp->ys * row, lp->xs, lp->ys); + else + XPutImage(dsp, win, Scr[screen].gc, &logo, + 0, 0, lp->xb + lp->xs * col, lp->yb + lp->ys * row, + icon_width, icon_height); +} + + +static void +erasecell(win, row, col) + Window win; + int row, col; +{ + lifestruct *lp = &lifes[screen]; + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, + lp->xb + lp->xs * col, lp->yb + lp->ys * row, lp->xs, lp->ys); +} + + +static void +spawn(loc) + unsigned char *loc; +{ + lifestruct *lp = &lifes[screen]; + unsigned char *ulloc, *ucloc, *urloc, *clloc, *crloc, *llloc, *lcloc, *lrloc, + *arloc; + int off, row, col, lastrow; + + lastrow = (lp->nrows) * (lp->ncols + 2); + off = loc - lp->buffer; + col = off % (lp->ncols + 2); + row = (off - col) / (lp->ncols + 2); + ulloc = loc - lp->ncols - 3; + ucloc = loc - lp->ncols - 2; + urloc = loc - lp->ncols - 1; + clloc = loc - 1; + crloc = loc + 1; + arloc = loc + 1; + llloc = loc + lp->ncols + 1; + lcloc = loc + lp->ncols + 2; + lrloc = loc + lp->ncols + 3; + if (row == 1) { + ulloc += lastrow; + ucloc += lastrow; + urloc += lastrow; + } + if (row == lp->nrows) { + llloc -= lastrow; + lcloc -= lastrow; + lrloc -= lastrow; + } + if (col == 1) { + ulloc += lp->ncols; + clloc += lp->ncols; + llloc += lp->ncols; + } + if (col == lp->ncols) { + urloc -= lp->ncols; + crloc -= lp->ncols; + lrloc -= lp->ncols; + } + *ulloc |= UPLT; + *ucloc |= UP; + *urloc |= UPRT; + *clloc |= LT; + *crloc |= RT; + *arloc |= RT; + *llloc |= DNLT; + *lcloc |= DN; + *lrloc |= DNRT; + + *(lp->agebuf + (loc - lp->buffer)) = 0; +} + + +static void +kill(loc) + unsigned char *loc; +{ + lifestruct *lp = &lifes[screen]; + + unsigned char *ulloc, *ucloc, *urloc, *clloc, *crloc, *llloc, *lcloc, + *lrloc, *arloc; + int off, row, col, lastrow; + + lastrow = (lp->nrows) * (lp->ncols + 2); + off = loc - lp->buffer; + row = off / (lp->ncols + 2); + col = off % (lp->ncols + 2); + row = (off - col) / (lp->ncols + 2); + ulloc = loc - lp->ncols - 3; + ucloc = loc - lp->ncols - 2; + urloc = loc - lp->ncols - 1; + clloc = loc - 1; + crloc = loc + 1; + arloc = loc + 1; + llloc = loc + lp->ncols + 1; + lcloc = loc + lp->ncols + 2; + lrloc = loc + lp->ncols + 3; + if (row == 1) { + ulloc += lastrow; + ucloc += lastrow; + urloc += lastrow; + } + if (row == lp->nrows) { + llloc -= lastrow; + lcloc -= lastrow; + lrloc -= lastrow; + } + if (col == 1) { + ulloc += lp->ncols; + clloc += lp->ncols; + llloc += lp->ncols; + } + if (col == lp->ncols) { + urloc -= lp->ncols; + crloc -= lp->ncols; + lrloc -= lp->ncols; + } + *ulloc &= ~UPLT; + *ucloc &= ~UP; + *urloc &= ~UPRT; + *clloc &= ~LT; + *crloc &= ~RT; + *arloc &= ~RT; + *llloc &= ~DNLT; + *lcloc &= ~DN; + *lrloc &= ~DNRT; +} + + +static void +setcell(win, row, col) + Window win; + int row; + int col; +{ + lifestruct *lp = &lifes[screen]; + unsigned char *loc; + + loc = lp->buffer + ((row + 1) * (lp->ncols + 2)) + col + 1; + spawn(loc); + drawcell(win, row, col); +} + + +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(win) + Window win; +{ + int row, col; + int *patptr; + XWindowAttributes xgwa; + lifestruct *lp = &lifes[screen]; + + lp->generation = 0; + lp->shooterTime = seconds(); + icon_width = lifeicon_width; + icon_height = lifeicon_height; + + if (!initialized) { + initialized = 1; + init_fates(); + logo.data = (char *) lifeicon_bits; + logo.width = icon_width; + logo.height = icon_height; + logo.bytes_per_line = (icon_width + 7) / 8; + } + XGetWindowAttributes(dsp, win, &xgwa); + lp->width = xgwa.width; + lp->height = xgwa.height; + lp->pixelmode = (lp->width < 4 * icon_width); + if (lp->pixelmode) { + lp->ncols = 32; + lp->nrows = 32; + } else { + lp->ncols = min(lp->width / icon_width, MAXCOLS); + lp->nrows = min(lp->height / icon_height, MAXROWS); + } + lp->xs = lp->width / lp->ncols; + lp->ys = lp->height / lp->nrows; + lp->xb = (lp->width - lp->xs * lp->ncols) / 2; + lp->yb = (lp->height - lp->ys * lp->nrows) / 2; + + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, lp->width, lp->height); + + bzero(lp->buffer, sizeof(lp->buffer)); + patptr = &patterns[random() % NPATS][0]; + while ((col = *patptr++) != 99) { + row = *patptr++; + col += lp->ncols / 2; + row += lp->nrows / 2; + setcell(win, row, col); + } +} + + +void +drawlife(win) + Window win; +{ + unsigned char *loc, *temploc, *lastloc; + int row, col; + unsigned char fate; + lifestruct *lp = &lifes[screen]; + + loc = lp->buffer + lp->ncols + 2 + 1; + temploc = lp->tempbuf; + /* copy the first 2 rows to the tempbuf */ + bcopy(loc, temploc, lp->ncols); + bcopy(loc + lp->ncols + 2, temploc + lp->ncols, lp->ncols); + + lastloc = lp->lastbuf; + /* copy the last row to another buffer for wraparound */ + bcopy(loc + ((lp->nrows - 1) * (lp->ncols + 2)), lastloc, lp->ncols); + + for (row = 0; row < lp->nrows; ++row) { + for (col = 0; col < lp->ncols; ++col) { + fate = fates[*temploc]; + *temploc = (row == (lp->nrows - 3)) ? + *(lastloc + col) : + *(loc + (lp->ncols + 2) * 2); + switch (fate) { + case BIRTH: + if (!(*(loc + 1) & RT)) { + spawn(loc); + } + /* NO BREAK */ + case SAME: + if (*(loc + 1) & RT) { + drawcell(win, row, col); + } + break; + case DEATH: + if (*(loc + 1) & RT) { + kill(loc); + erasecell(win, row, col); + } + break; + } + loc++; + temploc++; + } + loc += 2; + if (temploc >= lp->tempbuf + lp->ncols * 2) + temploc = lp->tempbuf; + } + + if (++lp->generation > batchcount) + initlife(win); + + /* + * generate a randomized shooter aimed roughly toward the center of the + * screen after timeout. + */ + + if (seconds() - lp->shooterTime > TIMEOUT) { + int hsp = random() % (lp->ncols - 5) + 3; + int vsp = random() % (lp->nrows - 5) + 3; + int hoff = 1; + int voff = 1; + if (vsp > lp->nrows / 2) + voff = -1; + if (hsp > lp->ncols / 2) + hoff = -1; + setcell(win, vsp + 0 * voff, hsp + 2 * hoff); + setcell(win, vsp + 1 * voff, hsp + 2 * hoff); + setcell(win, vsp + 2 * voff, hsp + 2 * hoff); + setcell(win, vsp + 2 * voff, hsp + 1 * hoff); + setcell(win, vsp + 1 * voff, hsp + 0 * hoff); + lp->shooterTime = seconds(); + } +} diff --git a/lifeicon.bit b/lifeicon.bit new file mode 100644 index 00000000..135d152a --- /dev/null +++ b/lifeicon.bit @@ -0,0 +1,13 @@ +#define lifeicon_width 29 +#define lifeicon_height 29 +static unsigned 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}; diff --git a/pyro.c b/pyro.c new file mode 100644 index 00000000..ae0286ff --- /dev/null +++ b/pyro.c @@ -0,0 +1,386 @@ +#ifndef lint +static char sccsid[] = "@(#)pyro.c 1.1 91/05/24 XLOCK"; +#endif +/*- + * pyro.c - Fireworks for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 16-Mar-91: Written. (received from David Brooks, brooks@osf.org). + */ + +/* The physics of the rockets is a little bogus, but it looks OK. Each is + * given an initial velocity impetus. They decelerate slightly (gravity + * overcomes the rocket's impulse) and explode as the rocket's main fuse + * gives out (we could add a ballistic stage, maybe). The individual + * stars fan out from the rocket, and they decelerate less quickly. + * That's called bouyancy, but really it's again a visual preference. + */ + +#include "xlock.h" +#include +#define TWOPI 6.2831853 + +/* Define this >1 to get small rectangles instead of points */ +#ifndef STARSIZE +#define STARSIZE 1 +#endif + +#define SILENT 0 +#define REDGLARE 1 +#define BURSTINGINAIR 2 + +#define CLOUD 0 +#define DOUBLECLOUD 1 +/* Clearly other types and other fascinating visual effects could be added...*/ + +/* P_xxx parameters represent the reciprocal of the probability... */ +#define P_IGNITE 5000 /* ...of ignition per cycle */ +#define P_DOUBLECLOUD 10 /* ...of an ignition being double */ +#define P_MULTI 75 /* ...of an ignition being several @ once */ +#define P_FUSILLADE 250 /* ...of an ignition starting a fusillade */ + +#define ROCKETW 2 /* Dimensions of rocket */ +#define ROCKETH 4 +#define XVELFACTOR 0.0025 /* Max horizontal velocity / screen width */ +#define MINYVELFACTOR 0.016 /* Min vertical velocity / screen height */ +#define MAXYVELFACTOR 0.018 +#define GRAVFACTOR 0.0002 /* delta v / screen height */ +#define MINFUSE 50 /* range of fuse lengths for rocket */ +#define MAXFUSE 100 + +#define FUSILFACTOR 10 /* Generate fusillade by reducing P_IGNITE */ +#define FUSILLEN 100 /* Length of fusillade, in ignitions */ + +#define SVELFACTOR 0.1 /* Max star velocity / yvel */ +#define BOUYANCY 0.2 /* Reduction in grav deceleration for stars */ +#define MAXSTARS 75 /* Number of stars issued from a shell */ +#define MINSTARS 50 +#define MINSFUSE 50 /* Range of fuse lengths for stars */ +#define MAXSFUSE 100 + +#define INTRAND(min,max) (random()%((max+1)-(min))+(min)) +#define FLOATRAND(min,max) ((min)+(random()/MAXRAND)*((max)-(min))) + +static void ignite(); +static void animate(); +static void shootup(); +static void burst(); + +typedef struct { + int state; + int shelltype; + int color1, color2; + int fuse; + float xvel, yvel; + float x, y; + int nstars; +#if STARSIZE > 1 + XRectangle Xpoints[MAXSTARS]; + XRectangle Xpoints2[MAXSTARS]; +#else + XPoint Xpoints[MAXSTARS]; + XPoint Xpoints2[MAXSTARS]; +#endif + float sx[MAXSTARS], sy[MAXSTARS]; /* Distance from notional + * center */ + float sxvel[MAXSTARS], syvel[MAXSTARS]; /* Relative to notional + * center */ +} rocket; + +typedef struct { + Screen *scr; + Colormap cmap; + int p_ignite; + unsigned long bgpixel; + unsigned long fgpixel; + unsigned long rockpixel; + GC bgGC; + int nflying; + int fusilcount; + int width, lmargin, rmargin, height; + float minvelx, maxvelx; + float minvely, maxvely; + float maxsvel; + float rockdecel, stardecel; + rocket *rockq; +} pyrostruct; + +static pyrostruct pyros[MAXSCREENS]; +static int orig_p_ignite; +static int just_started = True;/* Greet the user right away */ + +void +initpyro(win) + Window win; +{ + pyrostruct *pp = &pyros[screen]; + rocket *rp; + XWindowAttributes xwa; + XGCValues xgcv; + int rockn, starn, bsize; + + XGetWindowAttributes(dsp, win, &xwa); + + orig_p_ignite = P_IGNITE / batchcount; + if (orig_p_ignite <= 0) + orig_p_ignite = 1; + pp->p_ignite = orig_p_ignite; + + if (!pp->rockq) { + pp->rockq = (rocket *) malloc(batchcount * sizeof(rocket)); + } + pp->nflying = pp->fusilcount = 0; + + bsize = (xwa.height <= 64) ? 1 : STARSIZE; + for (rockn = 0, rp = pp->rockq; rockn < batchcount; rockn++, rp++) { + rp->state = SILENT; +#if STARSIZE > 1 + for (starn = 0; starn < MAXSTARS; starn++) { + rp->Xpoints[starn].width = rp->Xpoints[starn].height = + rp->Xpoints2[starn].width = rp->Xpoints2[starn].height = bsize; + } +#endif + } + + pp->width = xwa.width; + pp->lmargin = xwa.width / 16; + pp->rmargin = xwa.width - pp->lmargin; + pp->height = xwa.height; + pp->scr = ScreenOfDisplay(dsp, screen); + pp->cmap = DefaultColormapOfScreen(pp->scr); + + pp->fgpixel = WhitePixelOfScreen(pp->scr); + pp->bgpixel = BlackPixelOfScreen(pp->scr); + if (!mono && Scr[screen].npixels > 3) + pp->rockpixel = Scr[screen].pixels[3]; /* Just the right shade of + * orange */ + else + pp->rockpixel = pp->fgpixel; + + if (!pp->bgGC) { + xgcv.foreground = pp->bgpixel; + pp->bgGC = XCreateGC(dsp, win, GCForeground, &xgcv); + } +/* Geometry-dependent physical data: */ + pp->maxvelx = (float) (xwa.width) * XVELFACTOR; + pp->minvelx = -pp->maxvelx; + pp->minvely = -(float) (xwa.height) * MINYVELFACTOR; + pp->maxvely = -(float) (xwa.height) * MAXYVELFACTOR; + pp->maxsvel = pp->minvely * SVELFACTOR; + pp->rockdecel = (float) (pp->height) * GRAVFACTOR; + pp->stardecel = pp->rockdecel * BOUYANCY; + + XFillRectangle(dsp, win, pp->bgGC, 0, 0, xwa.width, xwa.height); +} + +/*ARGSUSED*/ +void +drawpyro(win) + Window win; +{ + pyrostruct *pp = &pyros[screen]; + rocket *rp; + int rockn; + + if (just_started || (random() % pp->p_ignite == 0)) { + just_started = False; + if (random() % P_FUSILLADE == 0) { + pp->p_ignite = orig_p_ignite / FUSILFACTOR; + pp->fusilcount = INTRAND(FUSILLEN * 9 / 10, FUSILLEN * 11 / 10); + } + ignite(pp); + if (pp->fusilcount > 0) { + if (--pp->fusilcount == 0) + pp->p_ignite = orig_p_ignite; + } + } + for (rockn = pp->nflying, rp = pp->rockq; rockn > 0; rp++) { + if (rp->state != SILENT) { + animate(win, pp, rp); + rockn--; + } + } +} + +static void +ignite(pp) + pyrostruct *pp; +{ + rocket *rp; + int multi, shelltype, nstars, fuse, npix, pix, color1, color2; + float xvel, yvel, x; + + x = random() % pp->width; + xvel = FLOATRAND(-pp->maxvelx, pp->maxvelx); +/* All this to stop too many rockets going offscreen: */ + if (x < pp->lmargin && xvel < 0.0 || x > pp->rmargin && xvel > 0.0) + xvel = -xvel; + yvel = FLOATRAND(pp->minvely, pp->maxvely); + fuse = INTRAND(MINFUSE, MAXFUSE); + nstars = INTRAND(MINSTARS, MAXSTARS); + if (!mono && (npix = Scr[screen].npixels) > 2) { + color1 = Scr[screen].pixels[pix = random() % npix]; + color2 = Scr[screen].pixels[(pix + (npix / 2)) % npix]; + } else { + color1 = color2 = WhitePixel(dsp, screen); + } + + multi = 1; + if (random() % P_DOUBLECLOUD == 0) + shelltype = DOUBLECLOUD; + else { + shelltype = CLOUD; + if (random() % P_MULTI == 0) + multi = INTRAND(5, 15); + } + + rp = pp->rockq; + while (multi--) { + if (pp->nflying >= batchcount) + return; + while (rp->state != SILENT) + rp++; + pp->nflying++; + rp->shelltype = shelltype; + rp->state = REDGLARE; + rp->color1 = color1; + rp->color2 = color2; + rp->xvel = xvel; + rp->yvel = FLOATRAND(yvel * 0.97, yvel * 1.03); + rp->fuse = INTRAND((fuse * 90) / 100, (fuse * 110) / 100); + rp->x = x + FLOATRAND(multi * 7.6, multi * 8.4); + rp->y = pp->height - 1; + rp->nstars = nstars; + } +} + +static void +animate(win, pp, rp) + Window win; + pyrostruct *pp; + rocket *rp; +{ + int starn; + float r, theta; + + if (rp->state == REDGLARE) { + shootup(win, pp, rp); + +/* Handle setup for explosion */ + if (rp->state == BURSTINGINAIR) { + for (starn = 0; starn < rp->nstars; starn++) { + rp->sx[starn] = rp->sy[starn] = 0.0; + rp->Xpoints[starn].x = (int) rp->x; + rp->Xpoints[starn].y = (int) rp->y; + if (rp->shelltype == DOUBLECLOUD) { + rp->Xpoints2[starn].x = (int) rp->x; + rp->Xpoints2[starn].y = (int) rp->y; + } +/* This isn't accurate solid geometry, but it looks OK. */ + + r = FLOATRAND(0.0, pp->maxsvel); + theta = FLOATRAND(0.0, TWOPI); + rp->sxvel[starn] = r * cos(theta); + rp->syvel[starn] = r * sin(theta); + } + rp->fuse = INTRAND(MINSFUSE, MAXSFUSE); + } + } + if (rp->state == BURSTINGINAIR) { + burst(win, pp, rp); + } +} + +static void +shootup(win, pp, rp) + Window win; + pyrostruct *pp; + rocket *rp; +{ + XFillRectangle(dsp, win, pp->bgGC, (int) (rp->x), (int) (rp->y), + ROCKETW, ROCKETH + 3); + + if (rp->fuse-- <= 0) { + rp->state = BURSTINGINAIR; + return; + } + rp->x += rp->xvel; + rp->y += rp->yvel; + rp->yvel += pp->rockdecel; + XSetForeground(dsp, Scr[screen].gc, pp->rockpixel); + XFillRectangle(dsp, win, Scr[screen].gc, (int) (rp->x), (int) (rp->y), + ROCKETW, ROCKETH + random() % 4); +} + +static void +burst(win, pp, rp) + Window win; + pyrostruct *pp; + rocket *rp; +{ + register int starn; + register int nstars, stype; + register float rx, ry, sd; /* Help compiler optimize :-) */ + register float sx, sy; + + nstars = rp->nstars; + stype = rp->shelltype; + +#if STARSIZE > 1 + XFillRectangles(dsp, win, pp->bgGC, rp->Xpoints, nstars); + if (stype == DOUBLECLOUD) + XFillRectangles(dsp, win, pp->bgGC, rp->Xpoints2, nstars); +#else + XDrawPoints(dsp, win, pp->bgGC, rp->Xpoints, nstars, CoordModeOrigin); + if (stype == DOUBLECLOUD) + XDrawPoints(dsp, win, pp->bgGC, rp->Xpoints2, nstars, CoordModeOrigin); +#endif + + if (rp->fuse-- <= 0) { + rp->state = SILENT; + pp->nflying--; + return; + } +/* Stagger the stars' decay */ + if (rp->fuse <= 7) { + if ((rp->nstars = nstars = nstars * 90 / 100) == 0) + return; + } + rx = rp->x; + ry = rp->y; + sd = pp->stardecel; + for (starn = 0; starn < nstars; starn++) { + sx = rp->sx[starn] += rp->sxvel[starn]; + sy = rp->sy[starn] += rp->syvel[starn]; + rp->syvel[starn] += sd; + rp->Xpoints[starn].x = (int) (rx + sx); + rp->Xpoints[starn].y = (int) (ry + sy); + if (stype == DOUBLECLOUD) { + rp->Xpoints2[starn].x = (int) (rx + 1.7 * sx); + rp->Xpoints2[starn].y = (int) (ry + 1.7 * sy); + } + } + rp->x = rx + rp->xvel; + rp->y = ry + rp->yvel; + rp->yvel += sd; + + XSetForeground(dsp, Scr[screen].gc, rp->color1); +#if STARSIZE > 1 + XFillRectangles(dsp, win, Scr[screen].gc, rp->Xpoints, nstars); + if (stype == DOUBLECLOUD) { + XSetForeground(dsp, Scr[screen].gc, rp->color2); + XFillRectangles(dsp, win, Scr[screen].gc, rp->Xpoints2, nstars); + } +#else + XDrawPoints(dsp, win, Scr[screen].gc, rp->Xpoints, nstars, CoordModeOrigin); + if (stype == DOUBLECLOUD) { + XSetForeground(dsp, Scr[screen].gc, rp->color2); + XDrawPoints(dsp, win, Scr[screen].gc, rp->Xpoints2, nstars, + CoordModeOrigin); + } +#endif +} diff --git a/qix.c b/qix.c new file mode 100644 index 00000000..fa2903dd --- /dev/null +++ b/qix.c @@ -0,0 +1,140 @@ +#ifndef lint +static char sccsid[] = "@(#)qix.c 23.8 91/05/24 XLOCK"; +#endif +/*- + * qix.c - Vector swirl for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 29-Jul-90: support for multiple screens. + * made check_bounds_?() a macro. + * fixed initial parameter setup. + * 15-Dec-89: Fix for proper skipping of {White,Black}Pixel() in colors. + * 08-Oct-89: Fixed bug in memory allocation in initqix(). + * Moved seconds() to an extern. + * 23-Sep-89: Switch to random() and fixed bug w/ less than 4 lines. + * 20-Sep-89: Lint. + * 24-Mar-89: Written. + */ + +#include "xlock.h" + +typedef struct { + int x; + int y; +} point; + +typedef struct { + int pix; + long startTime; + int first; + int last; + int dx1; + int dy1; + int dx2; + int dy2; + int x1; + int y1; + int x2; + int y2; + int offset; + int delta; + int width; + int height; + int nlines; + point *lineq; +} qixstruct; + +static qixstruct qixs[MAXSCREENS]; + +void +initqix(win) + Window win; +{ + XWindowAttributes xgwa; + qixstruct *qp = &qixs[screen]; + + qp->startTime = seconds(); + qp->nlines = (batchcount + 1) * 2; + if (!qp->lineq) { + qp->lineq = (point *) malloc(qp->nlines * sizeof(point)); + memset(qp->lineq, '\0', qp->nlines * sizeof(point)); + } + + XGetWindowAttributes(dsp, win, &xgwa); + qp->width = xgwa.width; + qp->height = xgwa.height; + qp->delta = 16; + + if (qp->width < 100) { /* icon window */ + qp->nlines /= 4; + qp->delta /= 4; + } + qp->offset = qp->delta / 3; + qp->last = 0; + qp->pix = 0; + qp->dx1 = random() % qp->delta + qp->offset; + qp->dy1 = random() % qp->delta + qp->offset; + qp->dx2 = random() % qp->delta + qp->offset; + qp->dy2 = random() % qp->delta + qp->offset; + qp->x1 = random() % qp->width; + qp->y1 = random() % qp->height; + qp->x2 = random() % qp->width; + qp->y2 = random() % qp->height; + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, qp->width, qp->height); +} + +#define check_bounds(qp, val, del, max) \ +{ \ + if ((val) < 0) { \ + *(del) = (random() % (qp)->delta) + (qp)->offset; \ + } else if ((val) > (max)) { \ + *(del) = -(random() % (qp)->delta) - (qp)->offset; \ + } \ +} + +void +drawqix(win) + Window win; +{ + qixstruct *qp = &qixs[screen]; + + qp->first = (qp->last + 2) % qp->nlines; + + qp->x1 += qp->dx1; + qp->y1 += qp->dy1; + qp->x2 += qp->dx2; + qp->y2 += qp->dy2; + check_bounds(qp, qp->x1, &qp->dx1, qp->width); + check_bounds(qp, qp->y1, &qp->dy1, qp->height); + check_bounds(qp, qp->x2, &qp->dx2, qp->width); + check_bounds(qp, qp->y2, &qp->dy2, qp->height); + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XDrawLine(dsp, win, Scr[screen].gc, + qp->lineq[qp->first].x, qp->lineq[qp->first].y, + qp->lineq[qp->first + 1].x, qp->lineq[qp->first + 1].y); + if (!mono && Scr[screen].npixels > 2) { + XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[qp->pix]); + if (++qp->pix >= Scr[screen].npixels) + qp->pix = 0; + } else + XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen)); + + XDrawLine(dsp, win, Scr[screen].gc, qp->x1, qp->y1, qp->x2, qp->y2); + + qp->lineq[qp->last].x = qp->x1; + qp->lineq[qp->last].y = qp->y1; + qp->last++; + if (qp->last >= qp->nlines) + qp->last = 0; + + qp->lineq[qp->last].x = qp->x2; + qp->lineq[qp->last].y = qp->y2; + qp->last++; + if (qp->last >= qp->nlines) + qp->last = 0; +} diff --git a/resource.c b/resource.c new file mode 100644 index 00000000..327b00ea --- /dev/null +++ b/resource.c @@ -0,0 +1,746 @@ +#ifndef lint +static char sccsid[] = "@(#)resource.c 1.20 91/09/27 XLOCK"; +#endif +/*- + * resource.c - resource management for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 25-Sep-91: added worm mode. + * 24-Jun-91: changed name to username. + * 06-Jun-91: Added flame mode. + * 24-May-91: Added -name and -usefirst and -resources. + * 16-May-91: Added random mode and pyro mode. + * 26-Mar-91: CheckResources: delay must be >= 0. + * 29-Oct-90: Added #include for missing isupper() on some OS revs. + * moved -mode option, reordered Xrm database evaluation. + * 28-Oct-90: Added text strings. + * 26-Oct-90: Fix bug in mode specific options. + * 31-Jul-90: Fix ':' handling in parsefilepath + * 07-Jul-90: Created from resource work in xlock.c + * + */ + +#include +#include "xlock.h" +#include +#include +#include + +#include + +/* + * Declare external interface routines for supported screen savers. + */ + +extern void inithop(); +extern void drawhop(); + +extern void initlife(); +extern void drawlife(); + +extern void initqix(); +extern void drawqix(); + +extern void initimage(); +extern void drawimage(); + +extern void initblank(); +extern void drawblank(); + +extern void initswarm(); +extern void drawswarm(); + +extern void initrotor(); +extern void drawrotor(); + +extern void initpyro(); +extern void drawpyro(); + +extern void initflame(); +extern void drawflame(); + +extern void initworm(); +extern void drawworm(); + +typedef struct { + char *cmdline_arg; + void (*lp_init) (); + void (*lp_callback) (); + int def_delay; + int def_batchcount; + float def_saturation; + char *desc; +} LockStruct; + +static char randomstring[] = "random"; + +static LockStruct LockProcs[] = { + {"hop", inithop, drawhop, 0, 1000, 1.0, "Hopalong iterated fractals"}, + {"qix", initqix, drawqix, 30000, 64, 1.0, "Spinning lines a la Qix(tm)"}, + {"image", initimage, drawimage, 2000000, 8, 0.3, "Random bouncing image"}, + {"life", initlife, drawlife, 1000000, 100, 1.0, "Conway's game of Life"}, + {"swarm", initswarm, drawswarm, 10000, 100, 1.0, "Swarm of bees"}, + {"rotor", initrotor, drawrotor, 10000, 4, 0.4, "Tom's Roto-Rooter"}, + {"pyro", initpyro, drawpyro, 15000, 40, 1.0, "Fireworks"}, + {"flame", initflame, drawflame, 10000, 20, 1.0, "Cosmic Flame Fractals"}, + {"worm", initworm, drawworm, 10000, 20, 1.0, "Wiggly Worms"}, + {"blank", initblank, drawblank, 5000000, 1, 1.0, "Blank screen"}, + {randomstring, NULL, NULL, 0, 0, 0.0, "Random mode"}, +}; +#define NUMPROCS (sizeof LockProcs / sizeof LockProcs[0]) + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 /* SunOS 3.5 does not define this */ +#endif + +extern char *getenv(); + +#ifndef DEF_FILESEARCHPATH +#define DEF_FILESEARCHPATH "/usr/lib/X11/%T/%N%S" +#endif +#define DEF_DISPLAY ":0" +#define DEF_MODE "life" +#define DEF_FONT "-b&h-lucida-medium-r-normal-sans-24-*-*-*-*-*-iso8859-1" +#define DEF_BG "White" +#define DEF_FG "Black" +#define DEF_NAME "Name: " +#define DEF_PASS "Password: " +#define DEF_INFO "Enter password to unlock; select icon to lock." +#define DEF_VALID "Validating login..." +#define DEF_INVALID "Invalid login." +#define DEF_TIMEOUT "30" /* secs till password entry times out */ +#define DEF_BC "100" /* vectors (or whatever) per batch */ +#define DEF_DELAY "200000"/* microseconds between batches */ +#define DEF_NICE "10" /* xlock process nicelevel */ +#define DEF_SAT "1.0" /* color ramp saturation 0->1 */ +#define DEF_CLASSNAME "XLock" + +static char *classname; +static char modename[1024]; +static char modeclass[1024]; + +static XrmOptionDescRec genTable[] = { + {"-mode", ".mode", XrmoptionSepArg, (caddr_t) NULL}, + {"-nolock", ".nolock", XrmoptionNoArg, (caddr_t) "on"}, + {"+nolock", ".nolock", XrmoptionNoArg, (caddr_t) "off"}, + {"-remote", ".remote", XrmoptionNoArg, (caddr_t) "on"}, + {"+remote", ".remote", XrmoptionNoArg, (caddr_t) "off"}, + {"-mono", ".mono", XrmoptionNoArg, (caddr_t) "on"}, + {"+mono", ".mono", XrmoptionNoArg, (caddr_t) "off"}, + {"-allowroot", ".allowroot", XrmoptionNoArg, (caddr_t) "on"}, + {"+allowroot", ".allowroot", XrmoptionNoArg, (caddr_t) "off"}, + {"-enablesaver", ".enablesaver", XrmoptionNoArg, (caddr_t) "on"}, + {"+enablesaver", ".enablesaver", XrmoptionNoArg, (caddr_t) "off"}, + {"-allowaccess", ".allowaccess", XrmoptionNoArg, (caddr_t) "on"}, + {"+allowaccess", ".allowaccess", XrmoptionNoArg, (caddr_t) "off"}, + {"-echokeys", ".echokeys", XrmoptionNoArg, (caddr_t) "on"}, + {"+echokeys", ".echokeys", XrmoptionNoArg, (caddr_t) "off"}, + {"-usefirst", ".usefirst", XrmoptionNoArg, (caddr_t) "on"}, + {"+usefirst", ".usefirst", XrmoptionNoArg, (caddr_t) "off"}, + {"-v", ".verbose", XrmoptionNoArg, (caddr_t) "on"}, + {"+v", ".verbose", XrmoptionNoArg, (caddr_t) "off"}, + {"-nice", ".nice", XrmoptionSepArg, (caddr_t) NULL}, + {"-timeout", ".timeout", XrmoptionSepArg, (caddr_t) NULL}, + {"-font", ".font", XrmoptionSepArg, (caddr_t) NULL}, + {"-bg", ".background", XrmoptionSepArg, (caddr_t) NULL}, + {"-fg", ".foreground", XrmoptionSepArg, (caddr_t) NULL}, + {"-background", ".background", XrmoptionSepArg, (caddr_t) NULL}, + {"-foreground", ".foreground", XrmoptionSepArg, (caddr_t) NULL}, + {"-username", ".username", XrmoptionSepArg, (caddr_t) NULL}, + {"-password", ".password", XrmoptionSepArg, (caddr_t) NULL}, + {"-info", ".info", XrmoptionSepArg, (caddr_t) NULL}, + {"-validate", ".validate", XrmoptionSepArg, (caddr_t) NULL}, + {"-invalid", ".invalid", XrmoptionSepArg, (caddr_t) NULL}, +}; +#define genEntries (sizeof genTable / sizeof genTable[0]) + +static XrmOptionDescRec modeTable[] = { + {"-delay", ".delay", XrmoptionSepArg, (caddr_t) NULL}, + {"-batchcount", ".batchcount", XrmoptionSepArg, (caddr_t) NULL}, + {"-saturation", ".saturation", XrmoptionSepArg, (caddr_t) NULL}, +}; +#define modeEntries (sizeof modeTable / sizeof modeTable[0]) + +static XrmOptionDescRec cmdlineTable[] = { + {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL}, + {"-nolock", ".nolock", XrmoptionNoArg, (caddr_t) "on"}, + {"+nolock", ".nolock", XrmoptionNoArg, (caddr_t) "off"}, + {"-remote", ".remote", XrmoptionNoArg, (caddr_t) "on"}, + {"+remote", ".remote", XrmoptionNoArg, (caddr_t) "off"}, +}; +#define cmdlineEntries (sizeof cmdlineTable / sizeof cmdlineTable[0]) + +static XrmOptionDescRec nameTable[] = { + {"-name", ".name", XrmoptionSepArg, (caddr_t) NULL}, +}; + + +typedef struct { + char *opt; + char *desc; +} OptionStruct; + +static OptionStruct opDesc[] = { + {"-help", "print out this message"}, + {"-resources", "print default resource file to standard output"}, + {"-display displayname", "X server to contact"}, + {"-name resourcename", "class name to use for resources (default is XLock)"}, + {"-/+mono", "turn on/off monochrome override"}, + {"-/+nolock", "turn on/off no password required mode"}, + {"-/+remote", "turn on/off remote host access"}, + {"-/+allowroot", "turn on/off allow root password mode"}, + {"-/+enablesaver", "turn on/off enable X server screen saver"}, + {"-/+allowaccess", "turn on/off allow new clients to connect"}, + {"-/+echokeys", "turn on/off echo '?' for each password key"}, + {"-/+usefirst", "turn on/off using the first char typed in password"}, + {"-/+v", "turn on/off verbose mode"}, + {"-delay usecs", "microsecond delay between screen updates"}, + {"-batchcount num", "number of things per batch"}, + {"-nice level", "nice level for xlock process"}, + {"-timeout seconds", "number of seconds before password times out"}, + {"-saturation value", "saturation of color ramp"}, + {"-font fontname", "font to use for password prompt"}, + {"-bg color", "background color to use for password prompt"}, + {"-fg color", "foreground color to use for password prompt"}, + {"-username string", "text string to use for Name prompt"}, + {"-password string", "text string to use for Password prompt"}, + {"-info string", "text string to use for instructions"}, + {"-validate string", "text string to use for validating password message"}, + {"-invalid string", "text string to use for invalid password message"}, +}; +#define opDescEntries (sizeof opDesc / sizeof opDesc[0]) + +char *display; +char *mode; +char *fontname; +char *background; +char *foreground; +char *text_name; +char *text_pass; +char *text_info; +char *text_valid; +char *text_invalid; +float saturation; +int nicelevel; +int delay; +int batchcount; +int timeout; +Bool mono; +Bool nolock; +Bool remote; +Bool allowroot; +Bool enablesaver; +Bool allowaccess; +Bool echokeys; +Bool usefirst; +Bool verbose; + +#define t_String 0 +#define t_Float 1 +#define t_Int 2 +#define t_Bool 3 + +typedef struct { + caddr_t *var; + char *name; + char *class; + char *def; + int type; +} argtype; + +static argtype genvars[] = { + {(caddr_t *) &fontname, "font", "Font", DEF_FONT, t_String}, + {(caddr_t *) &background, "background", "Background", DEF_BG, t_String}, + {(caddr_t *) &foreground, "foreground", "Foreground", DEF_FG, t_String}, + {(caddr_t *) &text_name, "username", "Username", DEF_NAME, t_String}, + {(caddr_t *) &text_pass, "password", "Password", DEF_PASS, t_String}, + {(caddr_t *) &text_info, "info", "Info", DEF_INFO, t_String}, + {(caddr_t *) &text_valid, "validate", "Validate", DEF_VALID, t_String}, + {(caddr_t *) &text_invalid, "invalid", "Invalid", DEF_INVALID, t_String}, + {(caddr_t *) &nicelevel, "nice", "Nice", DEF_NICE, t_Int}, + {(caddr_t *) &timeout, "timeout", "Timeout", DEF_TIMEOUT, t_Int}, + {(caddr_t *) &mono, "mono", "Mono", "off", t_Bool}, + {(caddr_t *) &nolock, "nolock", "NoLock", "off", t_Bool}, + {(caddr_t *) &remote, "remote", "Remote", "off", t_Bool}, + {(caddr_t *) &allowroot, "allowroot", "AllowRoot", "off", t_Bool}, + {(caddr_t *) &enablesaver, "enablesaver", "EnableSaver", "off", t_Bool}, + {(caddr_t *) &allowaccess, "allowaccess", "AllowAccess", "off", t_Bool}, + {(caddr_t *) &echokeys, "echokeys", "EchoKeys", "off", t_Bool}, + {(caddr_t *) &usefirst, "usefirst", "Usefirst", "off", t_Bool}, + {(caddr_t *) &verbose, "verbose", "Verbose", "off", t_Bool}, +}; +#define NGENARGS (sizeof genvars / sizeof genvars[0]) + +static argtype modevars[] = { + {(caddr_t *) &delay, "delay", "Delay", DEF_DELAY, t_Int}, + {(caddr_t *) &batchcount, "batchcount", "BatchCount", DEF_BC, t_Int}, + {(caddr_t *) &saturation, "saturation", "Saturation", DEF_SAT, t_Float}, +}; +#define NMODEARGS (sizeof modevars / sizeof modevars[0]) + + +static void +Syntax(badOption) + char *badOption; +{ + int col, len, i; + + fprintf(stderr, "%s: bad command line option \"%s\"\n\n", + ProgramName, badOption); + + fprintf(stderr, "usage: %s", ProgramName); + col = 8 + strlen(ProgramName); + for (i = 0; i < opDescEntries; i++) { + len = 3 + strlen(opDesc[i].opt); /* space [ string ] */ + if (col + len > 79) { + fprintf(stderr, "\n "); /* 3 spaces */ + col = 3; + } + fprintf(stderr, " [%s]", opDesc[i].opt); + col += len; + } + + len = 8 + strlen(LockProcs[0].cmdline_arg); + if (col + len > 79) { + fprintf(stderr, "\n "); /* 3 spaces */ + col = 3; + } + fprintf(stderr, " [-mode %s", LockProcs[0].cmdline_arg); + col += len; + for (i = 1; i < NUMPROCS; i++) { + len = 3 + strlen(LockProcs[i].cmdline_arg); + if (col + len > 79) { + fprintf(stderr, "\n "); /* 3 spaces */ + col = 3; + } + fprintf(stderr, " | %s", LockProcs[i].cmdline_arg); + col += len; + } + fprintf(stderr, "]\n"); + + fprintf(stderr, "\nType %s -help for a full description.\n\n", + ProgramName); + exit(1); +} + +static void +Help() +{ + int i; + + fprintf(stderr, "usage:\n %s [-options ...]\n\n", ProgramName); + fprintf(stderr, "where options include:\n"); + for (i = 0; i < opDescEntries; i++) { + fprintf(stderr, " %-28s %s\n", opDesc[i].opt, opDesc[i].desc); + } + + fprintf(stderr, " %-28s %s\n", "-mode mode", "animation mode"); + fprintf(stderr, " where mode is one of:\n"); + for (i = 0; i < NUMPROCS; i++) { + fprintf(stderr, " %-23s %s\n", + LockProcs[i].cmdline_arg, LockProcs[i].desc); + } + putc('\n', stderr); + + exit(0); +} + +static void +DumpResources() +{ + int i; + + printf("%s.mode: %s\n", classname, DEF_MODE); + + for (i = 0; i < NGENARGS; i++) + printf("%s.%s: %s\n", + classname, genvars[i].name, genvars[i].def); + + for (i = 0; i < NUMPROCS - 1; i++) { + printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg, + "delay", LockProcs[i].def_delay); + printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg, + "batchcount", LockProcs[i].def_batchcount); + printf("%s.%s.%s: %g\n", classname, LockProcs[i].cmdline_arg, + "saturation", LockProcs[i].def_saturation); + } + exit(0); +} + + +static void +LowerString(s) + char *s; +{ + + while (*s) { + if (isupper(*s)) + *s += ('a' - 'A'); + s++; + } +} + +static void +GetResource(database, parentname, parentclass, + name, class, valueType, def, valuep) + XrmDatabase database; + char *parentname; + char *parentclass; + char *name; + char *class; + int valueType; + char *def; + caddr_t *valuep; /* RETURN */ +{ + char *type; + XrmValue value; + char *string; + char buffer[1024]; + char fullname[1024]; + char fullclass[1024]; + int len; + + sprintf(fullname, "%s.%s", parentname, name); + sprintf(fullclass, "%s.%s", parentclass, class); + if (XrmGetResource(database, fullname, fullclass, &type, &value)) { + string = value.addr; + len = value.size; + } else { + string = def; + len = strlen(string); + } + (void) strncpy(buffer, string, sizeof(buffer)); + buffer[sizeof(buffer) - 1] = '\0'; + + switch (valueType) { + case t_String: + { + char *s = (char *) malloc(len + 1); + if (s == (char *) NULL) + error("%s: GetResource - couldn't allocate memory"); + (void) strncpy(s, string, len); + s[len] = '\0'; + *((char **) valuep) = s; + } + break; + case t_Bool: + LowerString(buffer); + *((int *) valuep) = (!strcmp(buffer, "true") || + !strcmp(buffer, "on") || + !strcmp(buffer, "enabled") || + !strcmp(buffer, "yes")) ? True : False; + break; + case t_Int: + *((int *) valuep) = atoi(buffer); + break; + case t_Float: + *((float *) valuep) = (float) atof(buffer); + break; + } +} + + +static XrmDatabase +parsefilepath(xfilesearchpath, TypeName, ClassName) + char *xfilesearchpath; + char *TypeName; + char *ClassName; +{ + XrmDatabase database = NULL; + char appdefaults[1024]; + char *src; + char *dst; + + src = xfilesearchpath; + appdefaults[0] = '\0'; + dst = appdefaults; + while (1) { + if (*src == '%') { + src++; + switch (*src) { + case '%': + case ':': + *dst++ = *src++; + *dst = '\0'; + break; + case 'T': + (void) strcat(dst, TypeName); + src++; + dst += strlen(TypeName); + break; + case 'N': + (void) strcat(dst, ClassName); + src++; + dst += strlen(ClassName); + break; + case 'S': + src++; + break; + default: + src++; + break; + } + } else if (*src == ':') { + database = XrmGetFileDatabase(appdefaults); + if (database == NULL) { + dst = appdefaults; + src++; + } else + break; + } else if (*src == '\0') { + database = XrmGetFileDatabase(appdefaults); + break; + } else { + *dst++ = *src++; + *dst = '\0'; + } + } + return database; +} + + +static void +open_display() +{ + if (display != NULL) { + extern char *strchr(); + char *colon = strchr(display, ':'); + int n = colon - display; + + if (colon == NULL) + error("%s: Malformed -display argument, \"%s\"\n", display); + + /* + * only restrict access to other displays if we are locking and if the + * Remote resource is not set. + */ + if (nolock) + remote = True; + if (!remote && n + && strncmp(display, "unix", n) + && strncmp(display, "localhost", n)) { + char hostname[MAXHOSTNAMELEN]; + struct hostent *host; + char **hp; + int badhost = 1; + + if (gethostname(hostname, MAXHOSTNAMELEN)) + error("%s: Can't get local hostname.\n"); + + if (!(host = gethostbyname(hostname))) + error("%s: Can't get hostbyname.\n"); + + if (strncmp(display, host->h_name, n)) { + for (hp = host->h_aliases; *hp; hp++) { + if (!strncmp(display, *hp, n)) { + badhost = 0; + break; + } + } + if (badhost) { + *colon = (char) 0; + error("%s: can't lock %s's display\n", display); + } + } + } + } else + display = ":0.0"; + if (!(dsp = XOpenDisplay(display))) + error("%s: unable to open display %s.\n", display); +} + + +void +printvar(class, var) + char *class; + argtype var; +{ + switch (var.type) { + case t_String: + fprintf(stderr, "%s.%s: %s\n", + class, var.name, *((char **) var.var)); + break; + case t_Bool: + fprintf(stderr, "%s.%s: %s\n", + class, var.name, *((int *) var.var) + ? "True" : "False"); + break; + case t_Int: + fprintf(stderr, "%s.%s: %d\n", + class, var.name, *((int *) var.var)); + break; + case t_Float: + fprintf(stderr, "%s.%s: %g\n", + class, var.name, *((float *) var.var)); + break; + } +} + + +void +GetResources(argc, argv) + int argc; + char *argv[]; +{ + XrmDatabase RDB = NULL; + XrmDatabase nameDB = NULL; + XrmDatabase modeDB = NULL; + XrmDatabase cmdlineDB = NULL; + XrmDatabase generalDB = NULL; + XrmDatabase homeDB = NULL; + XrmDatabase applicationDB = NULL; + XrmDatabase serverDB = NULL; + XrmDatabase userDB = NULL; + char userfile[1024]; + char *homeenv; + char *userpath; + char *env; + char *serverString; + int i; + + XrmInitialize(); + + for (i = 0; i < argc; i++) { + if (!strncmp(argv[i], "-help", strlen(argv[i]))) + Help(); + /* NOTREACHED */ + } + + /* + * get -name arg from command line so you can have different resource + * files for different configurations/machines etc... + */ + XrmParseCommand(&nameDB, nameTable, 1, ProgramName, + &argc, argv); + GetResource(nameDB, ProgramName, "*", "name", "Name", t_String, + DEF_CLASSNAME, &classname); + + + homeenv = getenv("HOME"); + if (!homeenv) + homeenv = ""; + + env = getenv("XFILESEARCHPATH"); + applicationDB = parsefilepath(env ? env : DEF_FILESEARCHPATH, + "app-defaults", classname); + + XrmParseCommand(&cmdlineDB, cmdlineTable, cmdlineEntries, ProgramName, + &argc, argv); + + userpath = getenv("XUSERFILESEARCHPATH"); + if (!userpath) { + env = getenv("XAPPLRESDIR"); + if (env) + sprintf(userfile, "%s/%%N:%s/%%N", env, homeenv); + else + sprintf(userfile, "%s/%%N", homeenv); + userpath = userfile; + } + userDB = parsefilepath(userpath, "app-defaults", classname); + + (void) XrmMergeDatabases(applicationDB, &RDB); + (void) XrmMergeDatabases(userDB, &RDB); + (void) XrmMergeDatabases(cmdlineDB, &RDB); + + env = getenv("DISPLAY"); + GetResource(RDB, ProgramName, classname, "display", "Display", t_String, + env ? env : DEF_DISPLAY, &display); + GetResource(RDB, ProgramName, classname, "nolock", "NoLock", t_Bool, + "off", (caddr_t *) &nolock); + GetResource(RDB, ProgramName, classname, "remote", "Remote", t_Bool, + "off", (caddr_t *) &remote); + + open_display(); + serverString = XResourceManagerString(dsp); + if (serverString) { + serverDB = XrmGetStringDatabase(serverString); + (void) XrmMergeDatabases(serverDB, &RDB); + } else { + char buf[1024]; + sprintf(buf, "%s/.Xdefaults", homeenv); + homeDB = XrmGetFileDatabase(buf); + (void) XrmMergeDatabases(homeDB, &RDB); + } + + XrmParseCommand(&generalDB, genTable, genEntries, ProgramName, &argc, argv); + (void) XrmMergeDatabases(generalDB, &RDB); + + GetResource(RDB, ProgramName, classname, "mode", "Mode", t_String, + DEF_MODE, (caddr_t *) &mode); + + /* + * if random< mode, then just grab a random entry from the table + */ + if (!strcmp(mode, randomstring)) + mode = LockProcs[random() % (NUMPROCS - 2)].cmdline_arg; + + sprintf(modename, "%s.%s", ProgramName, mode); + sprintf(modeclass, "%s.%s", classname, mode); + + XrmParseCommand(&modeDB, modeTable, modeEntries, modeclass, &argc, argv); + (void) XrmMergeDatabases(modeDB, &RDB); + + /* Parse the rest of the command line */ + for (argc--, argv++; argc > 0; argc--, argv++) { + if (**argv != '-') + Syntax(*argv); + switch (argv[0][1]) { + case 'r': + DumpResources(); + /* NOTREACHED */ + default: + Syntax(*argv); + /* NOTREACHED */ + } + } + + /* the RDB is set, now query load the variables from the database */ + + for (i = 0; i < NGENARGS; i++) + GetResource(RDB, ProgramName, classname, + genvars[i].name, genvars[i].class, + genvars[i].type, genvars[i].def, genvars[i].var); + + for (i = 0; i < NMODEARGS; i++) + GetResource(RDB, modename, modeclass, + modevars[i].name, modevars[i].class, + modevars[i].type, modevars[i].def, modevars[i].var); + + (void) XrmDestroyDatabase(RDB); + + if (verbose) { + for (i = 0; i < NGENARGS; i++) + printvar(classname, genvars[i]); + for (i = 0; i < NMODEARGS; i++) + printvar(modename, modevars[i]); + } +} + + +CheckResources() +{ + int i; + + if (batchcount < 1) + Syntax("-batchcount argument must be positive."); + if (saturation < 0.0 || saturation > 1.0) + Syntax("-saturation argument must be between 0.0 and 1.0."); + if (delay < 0) + Syntax("-delay argument must be positive."); + + for (i = 0; i < NUMPROCS; i++) { + if (!strncmp(LockProcs[i].cmdline_arg, mode, strlen(mode))) { + init = LockProcs[i].lp_init; + callback = LockProcs[i].lp_callback; + break; + } + } + if (i == NUMPROCS) { + fprintf(stderr, "Unknown mode: "); + Syntax(mode); + } +} diff --git a/rotor.c b/rotor.c new file mode 100644 index 00000000..706e2b4c --- /dev/null +++ b/rotor.c @@ -0,0 +1,249 @@ +#ifndef lint +static char sccsid[] = "@(#)rotor.c 1.6 91/05/24 XLOCK"; +#endif +/*- + * rotor.c - A swirly rotor for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 11-Nov-90: put into xlock (by Steve Zellers, zellers@sun.com) + * 16-Oct-90: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' simulator) + */ + +/* + * A 'batchcount' of 3 or 4 works best! + */ + +#include +#include +#include "xlock.h" + +#define SAVE 100 /* this is a good constant to tweak */ +#define REPS 50 + +#define MAXANGLE 10000.0 /* irrectangular */ +#define DEFAULTCOUNT 3 + +typedef unsigned char Boolean; + +#define IDENT(X) X +#ifdef __STDC__ +#define CAT(X,Y) X##Y +#else +#define CAT(X,Y) IDENT(X)Y +#endif + +struct elem { + float angle; + float radius; + float start_radius; + float end_radius; + float radius_drift_max; + float radius_drift_now; + + float ratio; + float start_ratio; + float end_ratio; + float ratio_drift_max; + float ratio_drift_now; +}; + +typedef struct flightstruct { + struct elem *elements; + int pix; + int lastx, + lasty; + int num, + rotor, + prev; + int savex[SAVE], + savey[SAVE]; + float angle; + int centerx, + centery; + Boolean firsttime; + Boolean smallscreen; /* for iconified view */ + Boolean forward; + Boolean unused; +} flightstruct; + + +static flightstruct flights[MAXSCREENS]; + +void +initrotor(win) + Window win; +{ + flightstruct *fs = &flights[screen]; + XWindowAttributes xgwa; + int x; + struct elem *pelem; + Boolean wassmall; + + XGetWindowAttributes(dsp, win, &xgwa); + fs->centerx = xgwa.width / 2; + fs->centery = xgwa.height / 2; + + /* + * sometimes, you go into small view, only to see a really whizzy pattern + * that you would like to look more closely at. Normally, clicking in the + * icon reinitializes everything - but I don't, cuz I'm that kind of guy. + * HENCE, the wassmall stuff you see here. + */ + + wassmall = fs->smallscreen; + fs->smallscreen = (xgwa.width < 100); + + if (wassmall && !fs->smallscreen) + fs->firsttime = True; + else { + if (batchcount > 12) + batchcount = DEFAULTCOUNT; + fs->num = batchcount; + + if (fs->elements == NULL) { + if ((fs->elements = (struct elem *) + malloc(sizeof(struct elem) * fs->num)) == 0) { + perror("malloc"); + exit(1); + } + } + memset(fs->savex, 0, sizeof(fs->savex)); + + pelem = fs->elements; + + for (x = fs->num; --x >= 0; pelem++) { + pelem->radius_drift_max = 1.0; + pelem->radius_drift_now = 1.0; + + pelem->end_radius = 100.0; + + pelem->ratio_drift_max = 1.0; + pelem->ratio_drift_now = 1.0; + pelem->end_ratio = 10.0; + } + + fs->rotor = 0; + fs->prev = 1; + fs->lastx = fs->centerx; + fs->lasty = fs->centery; + fs->angle = (random() % (long) MAXANGLE) / 3; + fs->forward = fs->firsttime = True; + } + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, xgwa.width, xgwa.height); +} + +void +drawrotor(win) + Window win; +{ + register flightstruct *fs = &flights[screen]; + register struct elem *pelem; + int thisx, + thisy; + int i, + rp; + int x1, + y1, + x2, + y2; + + +#define SCALE(W,N) CAT(W,N)/=12; CAT(W,N)+=(CAT(fs->center,W)-2) +#define SCALEIFSMALL() if (fs->smallscreen) { \ + SCALE(x,1); SCALE(x,2); \ + SCALE(y,1); SCALE(y,2); \ + } + + for (rp = 0; rp < REPS; rp++) { + thisx = fs->centerx; + thisy = fs->centery; + + for (i = fs->num, pelem = fs->elements; --i >= 0; pelem++) { + if (pelem->radius_drift_max <= pelem->radius_drift_now) { + pelem->start_radius = pelem->end_radius; + pelem->end_radius = + (float) (random() % 40000) / 100.0 - 200.0; + pelem->radius_drift_max = + (float) (random() % 100000) + 10000.0; + pelem->radius_drift_now = 0.0; + } + if (pelem->ratio_drift_max <= pelem->ratio_drift_now) { + pelem->start_ratio = pelem->end_ratio; + pelem->end_ratio = + (float) (random() % 2000) / 100.0 - 10.0; + pelem->ratio_drift_max = + (float) (random() % 100000) + 10000.0; + pelem->ratio_drift_now = 0.0; + } + pelem->ratio = pelem->start_ratio + + (pelem->end_ratio - pelem->start_ratio) / + pelem->ratio_drift_max * pelem->ratio_drift_now; + pelem->angle = fs->angle * pelem->ratio; + pelem->radius = pelem->start_radius + + (pelem->end_radius - pelem->start_radius) / + pelem->radius_drift_max * pelem->radius_drift_now; + + thisx += (int) (cos(pelem->angle) * pelem->radius); + thisy += (int) (sin(pelem->angle) * pelem->radius); + + pelem->ratio_drift_now += 1.0; + pelem->radius_drift_now += 1.0; + } + if (fs->firsttime) + fs->firsttime = False; + else { + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + + x1 = (int) fs->savex[fs->rotor]; + y1 = (int) fs->savey[fs->rotor]; + x2 = (int) fs->savex[fs->prev]; + y2 = (int) fs->savey[fs->prev]; + + SCALEIFSMALL(); + + XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2); + + if (!mono && Scr[screen].npixels > 2) { + XSetForeground(dsp, Scr[screen].gc, + Scr[screen].pixels[fs->pix]); + if (++fs->pix >= Scr[screen].npixels) + fs->pix = 0; + } else + XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen)); + + x1 = fs->lastx; + y1 = fs->lasty; + x2 = thisx; + y2 = thisy; + + SCALEIFSMALL(); + + XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2); + } + fs->savex[fs->rotor] = fs->lastx = thisx; + fs->savey[fs->rotor] = fs->lasty = thisy; + + ++fs->rotor; + fs->rotor %= SAVE; + ++fs->prev; + fs->prev %= SAVE; + if (fs->forward) { + fs->angle += 0.01; + if (fs->angle >= MAXANGLE) { + fs->angle = MAXANGLE; + fs->forward = False; + } + } else { + fs->angle -= 0.1; + if (fs->angle <= 0) { + fs->angle = 0.0; + fs->forward = True; + } + } + } +} diff --git a/sunlogo.bit b/sunlogo.bit new file mode 100644 index 00000000..cd83745b --- /dev/null +++ b/sunlogo.bit @@ -0,0 +1,46 @@ +#define sunlogo_width 64 +#define sunlogo_height 64 +static unsigned char sunlogo_bits[] = { + 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfe, + 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfc, 0xfd, 0x07, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xfd, 0xfb, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfb, + 0xf7, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf4, 0xf7, 0xef, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xee, 0xef, 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xdf, + 0xbf, 0xff, 0x00, 0x00, 0x00, 0x80, 0xbf, 0xbf, 0x7f, 0xff, 0x00, 0x00, + 0x00, 0x80, 0x7f, 0x7f, 0xff, 0x7e, 0x03, 0x00, 0x00, 0x60, 0xff, 0xfe, + 0xfe, 0xbd, 0x07, 0x00, 0x00, 0xf0, 0xfe, 0xfd, 0xfd, 0xdb, 0x0f, 0x00, + 0x00, 0xf8, 0xfd, 0xfb, 0xfb, 0xe7, 0x1f, 0x00, 0x00, 0xfc, 0xfb, 0xf7, + 0xf7, 0xf7, 0x2f, 0x00, 0x00, 0xfe, 0xf5, 0xef, 0xef, 0xfb, 0x77, 0x00, + 0x00, 0xff, 0xee, 0xdf, 0xcf, 0xfd, 0xfb, 0x00, 0x80, 0x7f, 0xdf, 0xbf, + 0x9f, 0xfe, 0xfd, 0x01, 0xc0, 0xbf, 0xbf, 0xff, 0x1f, 0xff, 0xfe, 0x00, + 0xe0, 0xdf, 0x1f, 0xff, 0x9f, 0x7f, 0x7f, 0x00, 0xf0, 0xef, 0x0f, 0xfe, + 0xcf, 0xbf, 0x3f, 0x07, 0xf8, 0xf7, 0xe7, 0xfc, 0xef, 0xdf, 0xdf, 0x1f, + 0xfc, 0xfb, 0xfb, 0xfb, 0xf7, 0xef, 0xef, 0x3f, 0xfe, 0xfd, 0xfd, 0xe7, + 0xf9, 0xf7, 0xf7, 0x7f, 0xfe, 0xfe, 0xfe, 0x07, 0xf8, 0xfb, 0xfb, 0x7f, + 0x7f, 0x7f, 0xff, 0x0f, 0xfc, 0xfd, 0xfd, 0xff, 0xbf, 0xbf, 0xff, 0x0f, + 0xfc, 0xfe, 0xfe, 0xff, 0xff, 0xdf, 0xdf, 0x0f, 0xfc, 0x7f, 0xff, 0xfe, + 0xff, 0xef, 0xef, 0x0f, 0xfc, 0xbf, 0x7f, 0xff, 0xfe, 0xf7, 0xf7, 0x07, + 0xf8, 0xdf, 0xbf, 0x7f, 0xfe, 0xfb, 0xfb, 0xe7, 0xf9, 0xef, 0xdf, 0x7f, + 0xfc, 0xfd, 0xfd, 0xfb, 0xf7, 0xf7, 0xef, 0x3f, 0x70, 0xfe, 0xfe, 0xfd, + 0xcf, 0xf9, 0xf7, 0x1f, 0x00, 0x7f, 0xff, 0xfc, 0x1f, 0xfc, 0xfb, 0x0f, + 0x80, 0xbf, 0x7f, 0xfe, 0x3f, 0xfe, 0xfd, 0x07, 0xc0, 0xdf, 0x3f, 0xfe, + 0x7f, 0xff, 0xfe, 0x03, 0x80, 0xef, 0x5f, 0x7e, 0xff, 0x7e, 0xff, 0x01, + 0x00, 0xf7, 0xef, 0xfc, 0xfe, 0xbd, 0xff, 0x00, 0x00, 0xfa, 0xf7, 0xfd, + 0xfd, 0xdb, 0x7f, 0x00, 0x00, 0xfc, 0xfb, 0xfb, 0xfb, 0xe7, 0x3f, 0x00, + 0x00, 0xf8, 0xf9, 0xf7, 0xf7, 0xef, 0x1f, 0x00, 0x00, 0xf0, 0xee, 0xef, + 0xef, 0xdf, 0x0f, 0x00, 0x00, 0x60, 0xdf, 0xdf, 0xdf, 0xbf, 0x07, 0x00, + 0x00, 0x80, 0xbf, 0xbf, 0xbf, 0x7f, 0x03, 0x00, 0x00, 0x80, 0x7f, 0x7f, + 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xfe, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xfd, 0xfd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfb, + 0xfb, 0x3b, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf7, 0xf7, 0x17, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xef, 0xef, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xdf, + 0xdf, 0x07, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xbf, 0x9f, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x7f, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00}; diff --git a/swarm.c b/swarm.c new file mode 100644 index 00000000..4f61b1f1 --- /dev/null +++ b/swarm.c @@ -0,0 +1,202 @@ +#ifndef lint +static char sccsid[] = "@(#)swarm.c 1.5 91/05/24 XLOCK"; +#endif +/*- + * swarm.c - swarm of bees for xlock, the X Window System lockscreen. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * Revision History: + * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org) + */ + +#include "xlock.h" + +#define TIMES 4 /* number of time positions recorded */ +#define BEEACC 3 /* acceleration of bees */ +#define WASPACC 5 /* maximum acceleration of wasp */ +#define BEEVEL 11 /* maximum bee velocity */ +#define WASPVEL 12 /* maximum wasp velocity */ +#define BORDER 50 /* wasp won't go closer than this to the edge */ + +/* Macros */ +#define X(t,b) (sp->x[(t)*sp->beecount+(b)]) +#define Y(t,b) (sp->y[(t)*sp->beecount+(b)]) +#define RAND(v) ((random()%(v))-((v)/2)) /* random number around 0 */ + +typedef struct { + int pix; + long startTime; + int width; + int height; + int beecount; /* number of bees */ + XSegment *segs; /* bee lines */ + XSegment *old_segs; /* old bee lines */ + short *x; + short *y; /* bee positions x[time][bee#] */ + short *xv; + short *yv; /* bee velocities xv[bee#] */ + short wx[3]; + short wy[3]; + short wxv; + short wyv; +} swarmstruct; + +static swarmstruct swarms[MAXSCREENS]; + +void +initswarm(win) + Window win; +{ + XWindowAttributes xgwa; + swarmstruct *sp = &swarms[screen]; + int b; + + sp->startTime = seconds(); + sp->beecount = batchcount; + + XGetWindowAttributes(dsp, win, &xgwa); + sp->width = xgwa.width; + sp->height = xgwa.height; + + /* Clear the background. */ + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, sp->width, sp->height); + + /* Allocate memory. */ + + if (!sp->segs) { + sp->segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount); + sp->old_segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount); + sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES); + sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES); + sp->xv = (short *) malloc(sizeof(short) * sp->beecount); + sp->yv = (short *) malloc(sizeof(short) * sp->beecount); + } + /* Initialize point positions, velocities, etc. */ + + /* wasp */ + sp->wx[0] = BORDER + random() % (sp->width - 2 * BORDER); + sp->wy[0] = BORDER + random() % (sp->height - 2 * BORDER); + sp->wx[1] = sp->wx[0]; + sp->wy[1] = sp->wy[0]; + sp->wxv = 0; + sp->wyv = 0; + + /* bees */ + for (b = 0; b < sp->beecount; b++) { + X(0, b) = random() % sp->width; + X(1, b) = X(0, b); + Y(0, b) = random() % sp->height; + Y(1, b) = Y(0, b); + sp->xv[b] = RAND(7); + sp->yv[b] = RAND(7); + } +} + + + +void +drawswarm(win) + Window win; +{ + swarmstruct *sp = &swarms[screen]; + int b; + + /* <=- Wasp -=> */ + /* Age the arrays. */ + sp->wx[2] = sp->wx[1]; + sp->wx[1] = sp->wx[0]; + sp->wy[2] = sp->wy[1]; + sp->wy[1] = sp->wy[0]; + /* Accelerate */ + sp->wxv += RAND(WASPACC); + sp->wyv += RAND(WASPACC); + + /* Speed Limit Checks */ + if (sp->wxv > WASPVEL) + sp->wxv = WASPVEL; + if (sp->wxv < -WASPVEL) + sp->wxv = -WASPVEL; + if (sp->wyv > WASPVEL) + sp->wyv = WASPVEL; + if (sp->wyv < -WASPVEL) + sp->wyv = -WASPVEL; + + /* Move */ + sp->wx[0] = sp->wx[1] + sp->wxv; + sp->wy[0] = sp->wy[1] + sp->wyv; + + /* Bounce Checks */ + if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) { + sp->wxv = -sp->wxv; + sp->wx[0] += sp->wxv; + } + if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) { + sp->wyv = -sp->wyv; + sp->wy[0] += sp->wyv; + } + /* Don't let things settle down. */ + sp->xv[random() % sp->beecount] += RAND(3); + sp->yv[random() % sp->beecount] += RAND(3); + + /* <=- Bees -=> */ + for (b = 0; b < sp->beecount; b++) { + int distance, + dx, + dy; + /* Age the arrays. */ + X(2, b) = X(1, b); + X(1, b) = X(0, b); + Y(2, b) = Y(1, b); + Y(1, b) = Y(0, b); + + /* Accelerate */ + dx = sp->wx[1] - X(1, b); + dy = sp->wy[1] - Y(1, b); + distance = abs(dx) + abs(dy); /* approximation */ + if (distance == 0) + distance = 1; + sp->xv[b] += (dx * BEEACC) / distance; + sp->yv[b] += (dy * BEEACC) / distance; + + /* Speed Limit Checks */ + if (sp->xv[b] > BEEVEL) + sp->xv[b] = BEEVEL; + if (sp->xv[b] < -BEEVEL) + sp->xv[b] = -BEEVEL; + if (sp->yv[b] > BEEVEL) + sp->yv[b] = BEEVEL; + if (sp->yv[b] < -BEEVEL) + sp->yv[b] = -BEEVEL; + + /* Move */ + X(0, b) = X(1, b) + sp->xv[b]; + Y(0, b) = Y(1, b) + sp->yv[b]; + + /* Fill the segment lists. */ + sp->segs[b].x1 = X(0, b); + sp->segs[b].y1 = Y(0, b); + sp->segs[b].x2 = X(1, b); + sp->segs[b].y2 = Y(1, b); + sp->old_segs[b].x1 = X(1, b); + sp->old_segs[b].y1 = Y(1, b); + sp->old_segs[b].x2 = X(2, b); + sp->old_segs[b].y2 = Y(2, b); + } + + XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen)); + XDrawLine(dsp, win, Scr[screen].gc, + sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]); + XDrawSegments(dsp, win, Scr[screen].gc, sp->old_segs, sp->beecount); + + XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen)); + XDrawLine(dsp, win, Scr[screen].gc, + sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]); + if (!mono && Scr[screen].npixels > 2) { + XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[sp->pix]); + if (++sp->pix >= Scr[screen].npixels) + sp->pix = 0; + } + XDrawSegments(dsp, win, Scr[screen].gc, sp->segs, sp->beecount); +} diff --git a/usleep.c b/usleep.c new file mode 100644 index 00000000..bdc6abed --- /dev/null +++ b/usleep.c @@ -0,0 +1,42 @@ +#ifndef lint +static char sccsid[] = "@(#)usleep.c 1.3 91/05/24 XLOCK"; +#endif +/*- + * usleep.c - OS dependant implementation of usleep(). + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * Revision History: + * 30-Aug-90: written. + * + */ + +#include "xlock.h" + +int +usleep(usec) + unsigned long usec; +{ +#ifndef hpux + poll((struct poll *) 0, (size_t) 0, usec / 1000); /* ms resolution */ +#else + struct timeval timeout; + timeout.tv_usec = usec % (unsigned long) 1000000; + timeout.tv_sec = usec / (unsigned long) 1000000; + select(0, (void *) 0, (void *) 0, (void *) 0, &timeout); +#endif + return 0; +} + +/* + * returns the number of seconds since 01-Jan-70. + * This is used to control rate and timeout in many of the animations. + */ +long +seconds() +{ + struct timeval now; + + gettimeofday(&now, (struct timezone *) 0); + return now.tv_sec; +} diff --git a/usleep.c.cln b/usleep.c.cln new file mode 100644 index 00000000..fffd7df8 --- /dev/null +++ b/usleep.c.cln @@ -0,0 +1,42 @@ +#ifndef lint +static char sccsid[] = "@(#)usleep.c 1.3 91/05/24 XLOCK"; +#endif +/*- + * usleep.c - OS dependant implementation of usleep(). + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * Revision History: + * 30-Aug-90: written. + * + */ + +#include "xlock.h" + +int +usleep(usec) + unsigned long usec; +{ +#ifdef SYSV + poll((struct poll *) 0, (size_t) 0, usec / 1000); /* ms resolution */ +#else + struct timeval timeout; + timeout.tv_usec = usec % (unsigned long) 1000000; + timeout.tv_sec = usec / (unsigned long) 1000000; + select(0, (void *) 0, (void *) 0, (void *) 0, &timeout); +#endif + return 0; +} + +/* + * returns the number of seconds since 01-Jan-70. + * This is used to control rate and timeout in many of the animations. + */ +long +seconds() +{ + struct timeval now; + + gettimeofday(&now, (struct timezone *) 0); + return now.tv_sec; +} diff --git a/wamfunction.c b/wamfunction.c new file mode 100644 index 00000000..c934b911 --- /dev/null +++ b/wamfunction.c @@ -0,0 +1,362 @@ +/* Copyright (C) 1986, SICS, Sweden. All rights reserved. */ + +#include "datadefs.h" +#include "support.h" +#include + +static char *illexp = "illegal arithmetic expression"; + +TAGGED fu1_minus(X0) + TAGGED X0; +{ + register TAGGED t,t1; + INTEGER item; + + t=X0; NDEREF(t,t1,illexp); + t1 = TaggedZero-(t-TaggedZero); + if (!(t&QMask) && TagIsSmall(t1)) + return t1; + else if (NumberIsFloat(t)) + return MakeFloat(-GetFloat(t)); + else + return (item = -GetInteger(t), MakeInteger(item)); +} + +TAGGED fu1_plus(X0) + TAGGED X0; +{ + register TAGGED t,t1; + + t=X0; NDEREF(t,t1,illexp); + return t; +} + +TAGGED fu1_integer(X0) + TAGGED X0; +{ + register TAGGED t,t1; + INTEGER item; + + t=X0; NDEREF(t,t1,illexp); + if (NumberIsFloat(t)) + item = GetInteger(t), + t = MakeInteger(item); + return t; +} + +TAGGED fu1_float(X0) + TAGGED X0; +{ + register TAGGED t,t1; + + t=X0; NDEREF(t,t1,illexp); + if (!NumberIsFloat(t)) + t = MakeFloat(GetFloat(t)); + return t; +} + +TAGGED fu1_add1(X0) + TAGGED X0; +{ + register TAGGED t,t1; + INTEGER item; + + t=X0; NDEREF(t,t1,illexp); + t1 = t+(1<> (-i) : item << i); + return MakeInteger(item); +} + +TAGGED fu2_rsh(X0,X1) + TAGGED X0,X1; +{ + register TAGGED t1,t,u; + register INTEGER i; + INTEGER item; + + t=X0; NDEREF(t,t1,illexp); + u=X1; NDEREF(u,t1,illexp); + i = GetInteger(u); + item = GetInteger(t); + item = (i<0 ? item << (-i) : item >> i); + return MakeInteger(item); +} + +/*---------------------------------------------------------------------------*/ + +TAGGED fu1_sin(X0) + TAGGED X0; +{ + register TAGGED t1,t; + + t=X0; NDEREF(t,t1,illexp); + return MakeFloat(sin(GetFloat(t))); +} + +TAGGED fu1_cos(X0) + TAGGED X0; +{ + register TAGGED t1,t; + + t=X0; NDEREF(t,t1,illexp); + return MakeFloat(cos(GetFloat(t))); +} + +TAGGED fu1_tan(X0) + TAGGED X0; +{ + register TAGGED t1,t; + + t=X0; NDEREF(t,t1,illexp); + return MakeFloat(tan(GetFloat(t))); +} + +TAGGED fu1_atan(X0) + TAGGED X0; +{ + register TAGGED t1,t; + + t=X0; NDEREF(t,t1,illexp); + return MakeFloat(atan(GetFloat(t))); +} + +TAGGED fu1_sqrt(X0) + TAGGED X0; +{ + register TAGGED t1,t; + + t=X0; NDEREF(t,t1,illexp); + return MakeFloat(sqrt(GetFloat(t))); +} + +TAGGED fu2_pow(X0,X1) + TAGGED X0,X1; +{ + register TAGGED t1,t,u; + + t=X0; NDEREF(t,t1,illexp); + u=X1; NDEREF(u,t1,illexp); + return MakeFloat(pow(GetFloat(t), GetFloat(u))); +} + +TAGGED fu1_round(X0) + TAGGED X0; +{ + register TAGGED t1,t; +#if hpux + double td ; + short sign ; +#endif + + t=X0; NDEREF(t,t1,illexp); +#if ! hpux + return MakeInteger(irint(GetFloat(t))); +#else + td = GetFloat( t ) ; + sign = td < 0 ; + return MakeInteger( ( unsigned long int )( sign ? - floor(fabs(td)+0.5) : floor(fabs(td)+0.5) ) ) ; +#endif +} + +TAGGED fu1_floor(X0) + TAGGED X0; +{ + register TAGGED t1,t; + + t=X0; NDEREF(t,t1,illexp); + return MakeInteger((INTEGER)floor(GetFloat(t))); +} + +TAGGED fu1_ceil(X0) + TAGGED X0; +{ + register TAGGED t1,t; + + t=X0; NDEREF(t,t1,illexp); + return MakeInteger((INTEGER)ceil(GetFloat(t))); +} + +TAGGED fu1_abs(X0) + TAGGED X0; +{ + register TAGGED t1,t; + INTEGER i; + FLOAT f; + + t=X0; NDEREF(t,t1,illexp); + if (IsFloat(t)) + return MakeFloat(((f=GetFloat(t))>=0 ? f : -f)); + return MakeInteger(((i=GetInteger(t))>=0 ? i : -i)); +} diff --git a/worm.c b/worm.c new file mode 100644 index 00000000..496dba5d --- /dev/null +++ b/worm.c @@ -0,0 +1,212 @@ +#ifndef lint +static char sccsid[] = "%Z%%M% %I% %E% XLOCK"; +#endif +/*- + * worm.c - draw wiggly worms. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 27-Sep-91: got rid of all malloc calls since there were no calls to free(). + * 25-Sep-91: Integrated into X11R5 contrib xlock. + * + * Adapted from a concept in the Dec 87 issue of Scientific American. + * + * SunView version: Brad Taylor (brad@sun.com) + * X11 version: Dave Lemke (lemke@ncd.com) + * xlock version: Boris Putanec (bp@cs.brown.edu) + * + * This code is a static memory pig... like almost 200K... but as contributed + * it leaked at a massive rate, so I made everything static up front... feel + * free to contribute the proper memory management code. + * + */ + +#include "xlock.h" +#include + +#define MAXCOLORS 64 +#define MAXWORMS 64 +#define CIRCSIZE 2 +#define MAXWORMLEN 50 + +#define PI 3.14159265358979323844 +#define SEGMENTS 36 +static int sintab[SEGMENTS]; +static int costab[SEGMENTS]; +static int init_table = 0; + +typedef struct { + int xcirc[MAXWORMLEN]; + int ycirc[MAXWORMLEN]; + int dir; + int tail; + int x; + int y; +} wormstuff; + +typedef struct { + int xsize; + int ysize; + int wormlength; + int monopix; + int nc; + int nw; + wormstuff worm[MAXWORMS]; + XRectangle rects[MAXCOLORS][MAXWORMS]; + int size[MAXCOLORS]; +} wormstruct; + +static wormstruct worms[MAXSCREENS]; + +#ifdef hpux +int +rint(x) + double x; +{ + if (x<0) return(-floor(fabs(x)+0.5)); + else return(floor(fabs(x)+0.5)); +} +#endif + +int +round(x) + float x; +{ + return ((int) rint((double) x)); +} + + +void +worm_doit(win, wp, which, color) + Window win; + wormstruct *wp; + int which; + unsigned long color; +{ + wormstuff *ws = &wp->worm[which]; + int x, y; + + ws->tail++; + if (ws->tail == wp->wormlength) + ws->tail = 0; + + x = ws->xcirc[ws->tail]; + y = ws->ycirc[ws->tail]; + XClearArea(dsp, win, x, y, CIRCSIZE, CIRCSIZE, False); + + if (random() & 1) { + ws->dir = (ws->dir + 1) % SEGMENTS; + } else { + ws->dir = (ws->dir + SEGMENTS - 1) % SEGMENTS; + } + + x = (ws->x + costab[ws->dir] + wp->xsize) % wp->xsize; + y = (ws->y + sintab[ws->dir] + wp->ysize) % wp->ysize; + + ws->xcirc[ws->tail] = x; + ws->ycirc[ws->tail] = y; + ws->x = x; + ws->y = y; + + wp->rects[color][wp->size[color]].x = x; + wp->rects[color][wp->size[color]].y = y; + wp->size[color]++; +} + + +void +initworm(win) + Window win; +{ + int i, j; + wormstruct *wp = &worms[screen]; + XWindowAttributes xwa; + + wp->nc = Scr[screen].npixels; + if (wp->nc > MAXCOLORS) + wp->nc = MAXCOLORS; + + wp->nw = batchcount; + if (wp->nw > MAXWORMS) + wp->nw = MAXWORMS; + + if (!init_table) { + init_table = 1; + for (i = 0; i < SEGMENTS; i++) { + sintab[i] = round(CIRCSIZE * sin(i * 2 * PI / SEGMENTS)); + costab[i] = round(CIRCSIZE * cos(i * 2 * PI / SEGMENTS)); + } + } + XGetWindowAttributes(dsp, win, &xwa); + wp->xsize = xwa.width; + wp->ysize = xwa.height; + + if (xwa.width < 100) { + wp->monopix = BlackPixel(dsp, screen); + wp->wormlength = MAXWORMLEN / 10; + } else { + wp->monopix = WhitePixel(dsp, screen); + wp->wormlength = MAXWORMLEN; + } + + for (i = 0; i < wp->nc; i++) { + for (j = 0; j < wp->nw / wp->nc + 1; j++) { + wp->rects[i][j].width = CIRCSIZE; + wp->rects[i][j].height = CIRCSIZE; + } + } + bzero(wp->size, wp->nc * sizeof(int)); + + for (i = 0; i < wp->nw; i++) { + for (j = 0; j < wp->wormlength; j++) { + wp->worm[i].xcirc[j] = wp->xsize / 2; + wp->worm[i].ycirc[j] = wp->ysize / 2; + } + wp->worm[i].dir = (unsigned) random() % SEGMENTS; + wp->worm[i].tail = 0; + wp->worm[i].x = wp->xsize / 2; + wp->worm[i].y = wp->ysize / 2; + } + + XClearWindow(dsp, win); +} + + +void +drawworm(win) + Window win; +{ + int i; + wormstruct *wp = &worms[screen]; + unsigned int wcolor; + static unsigned int chromo = 0; + + bzero(wp->size, wp->nc * sizeof(int)); + + for (i = 0; i < wp->nw; i++) { + if (!mono && wp->nc > 2) { + wcolor = (i + chromo) % wp->nc; + + worm_doit(win, wp, i, wcolor); + } else + worm_doit(win, wp, i, 0); + } + + if (!mono && wp->nc > 2) { + for (i = 0; i < wp->nc; i++) { + XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[i]); + XFillRectangles(dsp, win, Scr[screen].gc, wp->rects[i], + wp->size[i]); + } + } else { + XSetForeground(dsp, Scr[screen].gc, wp->monopix); + XFillRectangles(dsp, win, Scr[screen].gc, wp->rects[0], + wp->size[0]); + } + + if (++chromo == wp->nc) + chromo = 0; +} diff --git a/worm.c.cln b/worm.c.cln new file mode 100644 index 00000000..3139fe94 --- /dev/null +++ b/worm.c.cln @@ -0,0 +1,202 @@ +#ifndef lint +static char sccsid[] = "%Z%%M% %I% %E% XLOCK"; +#endif +/*- + * worm.c - draw wiggly worms. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + * See xlock.c for copying information. + * + * Revision History: + * 27-Sep-91: got rid of all malloc calls since there were no calls to free(). + * 25-Sep-91: Integrated into X11R5 contrib xlock. + * + * Adapted from a concept in the Dec 87 issue of Scientific American. + * + * SunView version: Brad Taylor (brad@sun.com) + * X11 version: Dave Lemke (lemke@ncd.com) + * xlock version: Boris Putanec (bp@cs.brown.edu) + * + * This code is a static memory pig... like almost 200K... but as contributed + * it leaked at a massive rate, so I made everything static up front... feel + * free to contribute the proper memory management code. + * + */ + +#include "xlock.h" +#include + +#define MAXCOLORS 64 +#define MAXWORMS 64 +#define CIRCSIZE 2 +#define MAXWORMLEN 50 + +#define PI 3.14159265358979323844 +#define SEGMENTS 36 +static int sintab[SEGMENTS]; +static int costab[SEGMENTS]; +static int init_table = 0; + +typedef struct { + int xcirc[MAXWORMLEN]; + int ycirc[MAXWORMLEN]; + int dir; + int tail; + int x; + int y; +} wormstuff; + +typedef struct { + int xsize; + int ysize; + int wormlength; + int monopix; + int nc; + int nw; + wormstuff worm[MAXWORMS]; + XRectangle rects[MAXCOLORS][MAXWORMS]; + int size[MAXCOLORS]; +} wormstruct; + +static wormstruct worms[MAXSCREENS]; + +int +round(x) + float x; +{ + return ((int) rint((double) x)); +} + + +void +worm_doit(win, wp, which, color) + Window win; + wormstruct *wp; + int which; + unsigned long color; +{ + wormstuff *ws = &wp->worm[which]; + int x, y; + + ws->tail++; + if (ws->tail == wp->wormlength) + ws->tail = 0; + + x = ws->xcirc[ws->tail]; + y = ws->ycirc[ws->tail]; + XClearArea(dsp, win, x, y, CIRCSIZE, CIRCSIZE, False); + + if (random() & 1) { + ws->dir = (ws->dir + 1) % SEGMENTS; + } else { + ws->dir = (ws->dir + SEGMENTS - 1) % SEGMENTS; + } + + x = (ws->x + costab[ws->dir] + wp->xsize) % wp->xsize; + y = (ws->y + sintab[ws->dir] + wp->ysize) % wp->ysize; + + ws->xcirc[ws->tail] = x; + ws->ycirc[ws->tail] = y; + ws->x = x; + ws->y = y; + + wp->rects[color][wp->size[color]].x = x; + wp->rects[color][wp->size[color]].y = y; + wp->size[color]++; +} + + +void +initworm(win) + Window win; +{ + int i, j; + wormstruct *wp = &worms[screen]; + XWindowAttributes xwa; + + wp->nc = Scr[screen].npixels; + if (wp->nc > MAXCOLORS) + wp->nc = MAXCOLORS; + + wp->nw = batchcount; + if (wp->nw > MAXWORMS) + wp->nw = MAXWORMS; + + if (!init_table) { + init_table = 1; + for (i = 0; i < SEGMENTS; i++) { + sintab[i] = round(CIRCSIZE * sin(i * 2 * PI / SEGMENTS)); + costab[i] = round(CIRCSIZE * cos(i * 2 * PI / SEGMENTS)); + } + } + XGetWindowAttributes(dsp, win, &xwa); + wp->xsize = xwa.width; + wp->ysize = xwa.height; + + if (xwa.width < 100) { + wp->monopix = BlackPixel(dsp, screen); + wp->wormlength = MAXWORMLEN / 10; + } else { + wp->monopix = WhitePixel(dsp, screen); + wp->wormlength = MAXWORMLEN; + } + + for (i = 0; i < wp->nc; i++) { + for (j = 0; j < wp->nw / wp->nc + 1; j++) { + wp->rects[i][j].width = CIRCSIZE; + wp->rects[i][j].height = CIRCSIZE; + } + } + bzero(wp->size, wp->nc * sizeof(int)); + + for (i = 0; i < wp->nw; i++) { + for (j = 0; j < wp->wormlength; j++) { + wp->worm[i].xcirc[j] = wp->xsize / 2; + wp->worm[i].ycirc[j] = wp->ysize / 2; + } + wp->worm[i].dir = (unsigned) random() % SEGMENTS; + wp->worm[i].tail = 0; + wp->worm[i].x = wp->xsize / 2; + wp->worm[i].y = wp->ysize / 2; + } + + XClearWindow(dsp, win); +} + + +void +drawworm(win) + Window win; +{ + int i; + wormstruct *wp = &worms[screen]; + unsigned int wcolor; + static unsigned int chromo = 0; + + bzero(wp->size, wp->nc * sizeof(int)); + + for (i = 0; i < wp->nw; i++) { + if (!mono && wp->nc > 2) { + wcolor = (i + chromo) % wp->nc; + + worm_doit(win, wp, i, wcolor); + } else + worm_doit(win, wp, i, 0); + } + + if (!mono && wp->nc > 2) { + for (i = 0; i < wp->nc; i++) { + XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[i]); + XFillRectangles(dsp, win, Scr[screen].gc, wp->rects[i], + wp->size[i]); + } + } else { + XSetForeground(dsp, Scr[screen].gc, wp->monopix); + XFillRectangles(dsp, win, Scr[screen].gc, wp->rects[0], + wp->size[0]); + } + + if (++chromo == wp->nc) + chromo = 0; +} diff --git a/xlock.c b/xlock.c new file mode 100644 index 00000000..c441f1b5 --- /dev/null +++ b/xlock.c @@ -0,0 +1,783 @@ +#ifndef lint +static char sccsid[] = "@(#)xlock.c 23.21 91/06/27 XLOCK"; +#endif +/*- + * xlock.c - X11 client to lock a display and show a screen saver. + * + * Copyright (c) 1988-91 by Patrick J. Naughton. + * + * 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@eng.sun.com + * + * Patrick J. Naughton + * MS 21-14 + * Sun Laboritories, Inc. + * 2550 Garcia Ave + * Mountain View, CA 94043 + * + * Revision History: + * 24-Jun-91: make foreground and background color get used on mono. + * 24-May-91: added -usefirst. + * 16-May-91: added pyro and random modes. + * ripped big comment block out of all other files. + * 08-Jan-91: fix some problems with password entry. + * removed renicing code. + * 29-Oct-90: added cast to XFree() arg. + * added volume arg to call to XBell(). + * 28-Oct-90: center prompt screen. + * make sure Xlib input buffer does not use up all of swap. + * make displayed text come from resource file for better I18N. + * add backward compatible signal handlers for pre 4.1 machines. + * 31-Aug-90: added blank mode. + * added swarm mode. + * moved usleep() and seconds() out to usleep.c. + * added SVR4 defines to xlock.h + * 29-Jul-90: added support for multiple screens to be locked by one xlock. + * moved global defines to xlock.h + * removed use of allowsig(). + * 07-Jul-90: reworked commandline args and resources to use Xrm. + * moved resource processing out to resource.c + * 02-Jul-90: reworked colors to not use dynamic colormap. + * 23-May-90: added autoraise when obscured. + * 15-Apr-90: added hostent alias searching for host authentication. + * 18-Feb-90: added SunOS3.5 fix. + * changed -mono -> -color, and -saver -> -lock. + * allow non-locking screensavers to display on remote machine. + * added -echokeys to disable echoing of '?'s on input. + * cleaned up all of the parameters and defaults. + * 20-Dec-89: added -xhost to allow access control list to be left alone. + * added -screensaver (don't disable screen saver) for the paranoid. + * Moved seconds() here from all of the display mode source files. + * Fixed bug with calling XUngrabHosts() in finish(). + * 19-Dec-89: Fixed bug in GrabPointer. + * Changed fontname to XLFD style. + * 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. + * + */ + +#include +#include +#include +#include + +#include "xlock.h" +#include +#include + +extern char *crypt(); +extern char *getenv(); + +char *ProgramName; /* argv[0] */ +perscreen Scr[MAXSCREENS]; +Display *dsp = NULL; /* server display connection */ +int screen; /* current screen */ +void (*callback) () = NULL; +void (*init) () = NULL; + +static int screens; /* number of screens */ +static Window win[MAXSCREENS]; /* window used to cover screen */ +static Window icon[MAXSCREENS]; /* window used during password typein */ +static Window root[MAXSCREENS]; /* convenience pointer to the root window */ +static GC textgc[MAXSCREENS]; /* graphics context used for text rendering */ +static long fgcol[MAXSCREENS]; /* used for text rendering */ +static long bgcol[MAXSCREENS]; /* background of text screen */ +static int iconx[MAXSCREENS]; /* location of left edge of icon */ +static int icony[MAXSCREENS]; /* location of top edge of icon */ +static Cursor mycursor; /* blank cursor */ +static Pixmap lockc; +static Pixmap lockm; /* pixmaps for cursor and mask */ +static char no_bits[] = {0}; /* dummy array for the blank cursor */ +static int passx; /* position of the ?'s */ +static int passy; +static XFontStruct *font; +static int sstimeout; /* screen saver parameters */ +static int ssinterval; +static int ssblanking; +static int ssexposures; + +#define PASSLENGTH 20 +#define FALLBACK_FONTNAME "fixed" +#define ICONW 64 +#define ICONH 64 + +#define AllPointerEventMask \ + (ButtonPressMask | ButtonReleaseMask | \ + EnterWindowMask | LeaveWindowMask | \ + PointerMotionMask | PointerMotionHintMask | \ + Button1MotionMask | Button2MotionMask | \ + Button3MotionMask | Button4MotionMask | \ + Button5MotionMask | ButtonMotionMask | \ + KeymapStateMask) + + +/* VARARGS1 */ +void +error(s1, s2) + char *s1, *s2; +{ + fprintf(stderr, s1, ProgramName, s2); + exit(1); +} + +/* + * Server access control support. + */ + +static XHostAddress *XHosts; /* the list of "friendly" client machines */ +static int HostAccessCount; /* the number of machines in XHosts */ +static Bool HostAccessState; /* whether or not we even look at the list */ + +static void +XGrabHosts(dsp) + Display *dsp; +{ + XHosts = XListHosts(dsp, &HostAccessCount, &HostAccessState); + if (XHosts) + XRemoveHosts(dsp, XHosts, HostAccessCount); + XEnableAccessControl(dsp); +} + +static void +XUngrabHosts(dsp) + Display *dsp; +{ + if (XHosts) { + XAddHosts(dsp, XHosts, HostAccessCount); + XFree((char *) XHosts); + } + if (HostAccessState == False) + XDisableAccessControl(dsp); +} + + +/* + * Simple wrapper to get an asynchronous grab on the keyboard and mouse. + * If either grab fails, we sleep for one second and try again since some + * window manager might have had the mouse grabbed to drive the menu choice + * that picked "Lock Screen..". If either one fails the second time we print + * an error message and exit. + */ +static void +GrabKeyboardAndMouse() +{ + Status status; + + status = XGrabKeyboard(dsp, win[0], True, + GrabModeAsync, GrabModeAsync, CurrentTime); + if (status != GrabSuccess) { + sleep(1); + status = XGrabKeyboard(dsp, win[0], True, + GrabModeAsync, GrabModeAsync, CurrentTime); + + if (status != GrabSuccess) + error("%s: couldn't grab keyboard! (%d)\n", status); + } + status = XGrabPointer(dsp, win[0], True, AllPointerEventMask, + GrabModeAsync, GrabModeAsync, None, mycursor, + CurrentTime); + if (status != GrabSuccess) { + sleep(1); + status = XGrabPointer(dsp, win[0], True, AllPointerEventMask, + GrabModeAsync, GrabModeAsync, None, mycursor, + CurrentTime); + + if (status != GrabSuccess) + error("%s: couldn't grab pointer! (%d)\n", status); + } +} + + +/* + * Assuming that we already have an asynch grab on the pointer, + * just grab it again with a new cursor shape and ignore the return code. + */ +static void +XChangeGrabbedCursor(cursor) + Cursor cursor; +{ +#ifndef DEBUG + (void) XGrabPointer(dsp, win[0], True, AllPointerEventMask, + GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime); +#endif +} + + +/* + * Restore all grabs, reset screensaver, restore colormap, close connection. + */ +static void +finish() +{ + XSync(dsp, False); + if (!nolock && !allowaccess) + XUngrabHosts(dsp); + XUngrabPointer(dsp, CurrentTime); + XUngrabKeyboard(dsp, CurrentTime); + if (!enablesaver) + XSetScreenSaver(dsp, sstimeout, ssinterval, ssblanking, ssexposures); + XFlush(dsp); + XCloseDisplay(dsp); +} + + +static int +ReadXString(s, slen) + char *s; + int slen; +{ + XEvent event; + char keystr[20]; + char c; + int i; + int bp; + int len; + int thisscreen = screen; + char pwbuf[PASSLENGTH]; + + for (screen = 0; screen < screens; screen++) + if (thisscreen == screen) + init(icon[screen]); + else + init(win[screen]); + bp = 0; + *s = 0; + while (True) { + unsigned long lasteventtime = seconds(); + while (!XPending(dsp)) { + for (screen = 0; screen < screens; screen++) + if (thisscreen == screen) + callback(icon[screen]); + else + callback(win[screen]); + XFlush(dsp); + usleep(delay); + if (seconds() - lasteventtime > timeout) { + screen = thisscreen; + return 1; + } + } + screen = thisscreen; + 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'; + return 0; + case 21: /* ^U */ + bp = 0; + break; + default: + s[bp] = c; + if (bp < slen - 1) + bp++; + else + XSync(dsp, True); /* flush input buffer */ + } + } + XSetForeground(dsp, Scr[screen].gc, bgcol[screen]); + if (echokeys) { + memset(pwbuf, '?', slen); + XFillRectangle(dsp, win[screen], Scr[screen].gc, + passx, passy - font->ascent, + XTextWidth(font, pwbuf, slen), + font->ascent + font->descent); + XDrawString(dsp, win[screen], textgc[screen], + passx, passy, pwbuf, bp); + } + /* + * eat all events if there are more than enough pending... this + * keeps the Xlib event buffer from growing larger than all + * available memory and crashing xlock. + */ + if (XPending(dsp) > 100) { /* 100 is arbitrarily big enough */ + register Status status; + do { + status = XCheckMaskEvent(dsp, + KeyPressMask | KeyReleaseMask, &event); + } while (status); + XBell(dsp, 100); + } + break; + + case ButtonPress: + if (((XButtonEvent *) & event)->window == icon[screen]) { + return 1; + } + break; + + case VisibilityNotify: + if (event.xvisibility.state != VisibilityUnobscured) { +#ifndef DEBUG + XRaiseWindow(dsp, win[screen]); +#endif + s[0] = '\0'; + return 1; + } + break; + + case KeymapNotify: + case KeyRelease: + case ButtonRelease: + case MotionNotify: + case LeaveNotify: + case EnterNotify: + break; + + default: + fprintf(stderr, "%s: unexpected event: %d\n", + ProgramName, event.type); + break; + } + } +} + + + +static int +getPassword() +{ + char buffer[PASSLENGTH]; + char userpass[PASSLENGTH]; + char rootpass[PASSLENGTH]; + char *user; + XWindowAttributes xgwa; + int y, left, done; + struct passwd *pw; + + pw = getpwnam("root"); + strcpy(rootpass, pw->pw_passwd); + + pw = getpwnam(cuserid(NULL)); + strcpy(userpass, pw->pw_passwd); + + user = pw->pw_name; + + XGetWindowAttributes(dsp, win[screen], &xgwa); + + XChangeGrabbedCursor(XCreateFontCursor(dsp, XC_left_ptr)); + + XSetForeground(dsp, Scr[screen].gc, bgcol[screen]); + XFillRectangle(dsp, win[screen], Scr[screen].gc, + 0, 0, xgwa.width, xgwa.height); + + XMapWindow(dsp, icon[screen]); + XRaiseWindow(dsp, icon[screen]); + + left = iconx[screen] + ICONW + font->max_bounds.width; + y = icony[screen] + font->ascent; + + XDrawString(dsp, win[screen], textgc[screen], + left, y, text_name, strlen(text_name)); + XDrawString(dsp, win[screen], textgc[screen], + left + 1, y, text_name, strlen(text_name)); + XDrawString(dsp, win[screen], textgc[screen], + left + XTextWidth(font, text_name, strlen(text_name)), y, + user, strlen(user)); + + y += font->ascent + font->descent + 2; + XDrawString(dsp, win[screen], textgc[screen], + left, y, text_pass, strlen(text_pass)); + XDrawString(dsp, win[screen], textgc[screen], + left + 1, y, text_pass, strlen(text_pass)); + + passx = left + 1 + XTextWidth(font, text_pass, strlen(text_pass)) + + XTextWidth(font, " ", 1); + passy = y; + + y = icony[screen] + ICONH + font->ascent + 2; + XDrawString(dsp, win[screen], textgc[screen], + iconx[screen], y, text_info, strlen(text_info)); + + XFlush(dsp); + + y += font->ascent + font->descent + 2; + + done = False; + while (!done) { + if (ReadXString(buffer, PASSLENGTH)) + break; + + /* + * we don't allow for root to have no password, but we handle the case + * where the user has no password correctly; they have to hit return + * only + */ + + done = !((strcmp(crypt(buffer, userpass), userpass)) + && (!allowroot || strcmp(crypt(buffer, rootpass), rootpass))); + + if (!done && *buffer == NULL) { + /* just hit return, and it wasn't his password */ + break; + } + if (*userpass == NULL && *buffer != NULL) { + /* + * the user has no password, but something was typed anyway. + * sounds fishy: don't let him in... + */ + done = False; + } + /* clear plaintext password so you can't grunge around /dev/kmem */ + memset(buffer, 0, sizeof(buffer)); + + XSetForeground(dsp, Scr[screen].gc, bgcol[screen]); + + XFillRectangle(dsp, win[screen], Scr[screen].gc, + iconx[screen], y - font->ascent, + XTextWidth(font, text_invalid, strlen(text_invalid)), + font->ascent + font->descent + 2); + + XDrawString(dsp, win[screen], textgc[screen], + iconx[screen], y, text_valid, strlen(text_valid)); + + if (done) + return 0; + else { + XSync(dsp, True); /* flush input buffer */ + sleep(1); + XFillRectangle(dsp, win[screen], Scr[screen].gc, + iconx[screen], y - font->ascent, + XTextWidth(font, text_valid, strlen(text_valid)), + font->ascent + font->descent + 2); + XDrawString(dsp, win[screen], textgc[screen], + iconx[screen], y, text_invalid, strlen(text_invalid)); + if (echokeys) /* erase old echo */ + XFillRectangle(dsp, win[screen], Scr[screen].gc, + passx, passy - font->ascent, + xgwa.width - passx, + font->ascent + font->descent); + } + } + XChangeGrabbedCursor(mycursor); + XUnmapWindow(dsp, icon[screen]); + return 1; +} + + +static void +justDisplay() +{ + XEvent event; + + for (screen = 0; screen < screens; screen++) + init(win[screen]); + do { + while (!XPending(dsp)) { + for (screen = 0; screen < screens; screen++) + callback(win[screen]); + XFlush(dsp); + usleep(delay); + } + XNextEvent(dsp, &event); +#ifndef DEBUG + if (event.type == VisibilityNotify) + XRaiseWindow(dsp, event.xany.window); +#endif + } while (event.type != ButtonPress && event.type != KeyPress); + for (screen = 0; screen < screens; screen++) + if (event.xbutton.root == RootWindow(dsp, screen)) + break; + if (usefirst) + XPutBackEvent(dsp, &event); +} + + +static void +sigcatch() +{ + finish(); + error("%s: caught terminate signal.\nAccess control list restored.\n"); +} + + +static void +lockDisplay() +{ + if (!allowaccess) { +#ifdef SYSV + sigset_t oldsigmask; + sigset_t newsigmask; + + sigemptyset(&newsigmask); + sigaddset(&newsigmask, SIGHUP); + sigaddset(&newsigmask, SIGINT); + sigaddset(&newsigmask, SIGQUIT); + sigaddset(&newsigmask, SIGTERM); + sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask); +#else + int oldsigmask; + + oldsigmask = sigblock(sigmask(SIGHUP) | + sigmask(SIGINT) | + sigmask(SIGQUIT) | + sigmask(SIGTERM)); +#endif + + signal(SIGHUP, (void (*) ()) sigcatch); + signal(SIGINT, (void (*) ()) sigcatch); + signal(SIGQUIT, (void (*) ()) sigcatch); + signal(SIGTERM, (void (*) ()) sigcatch); + + XGrabHosts(dsp); + +#ifdef SYSV + sigprocmask(SIG_SETMASK, &oldsigmask, &oldsigmask); +#else + sigsetmask(oldsigmask); +#endif + } + do { + justDisplay(); + } while (getPassword()); +} + + +long +allocpixel(cmap, name, def) + Colormap cmap; + char *name; + char *def; +{ + XColor col; + XColor tmp; + XParseColor(dsp, cmap, name, &col); + if (!XAllocColor(dsp, cmap, &col)) { + fprintf(stderr, "couldn't allocate: %s, using %s instead\n", + name, def); + XAllocNamedColor(dsp, cmap, def, &col, &tmp); + } + return col.pixel; +} + + +int +main(argc, argv) + int argc; + char *argv[]; +{ + XSetWindowAttributes xswa; + XGCValues xgcv; + XColor nullcolor; + + ProgramName = strrchr(argv[0], '/'); + if (ProgramName) + ProgramName++; + else + ProgramName = argv[0]; + + srandom(time((long *) 0)); /* random mode needs the seed set. */ + + GetResources(argc, argv); + + CheckResources(); + + font = XLoadQueryFont(dsp, fontname); + if (font == NULL) { + fprintf(stderr, "%s: can't find font: %s, using %s...\n", + ProgramName, fontname, FALLBACK_FONTNAME); + font = XLoadQueryFont(dsp, FALLBACK_FONTNAME); + if (font == NULL) + error("%s: can't even find %s!!!\n", FALLBACK_FONTNAME); + } + screens = ScreenCount(dsp); + if (screens > MAXSCREENS) + error("%s: can only support %d screens.\n", MAXSCREENS); + for (screen = 0; screen < screens; screen++) { + Screen *scr = ScreenOfDisplay(dsp, screen); + Colormap cmap = DefaultColormapOfScreen(scr); + + root[screen] = RootWindowOfScreen(scr); + bgcol[screen] = allocpixel(cmap, background, "White"); + fgcol[screen] = allocpixel(cmap, foreground, "Black"); + + if (mono || CellsOfScreen(scr) == 2) { + Scr[screen].pixels[0] = fgcol[screen]; + Scr[screen].pixels[1] = bgcol[screen]; + Scr[screen].npixels = 2; + } else { + int colorcount = NUMCOLORS; + u_char red[NUMCOLORS]; + u_char green[NUMCOLORS]; + u_char blue[NUMCOLORS]; + int i; + + hsbramp(0.0, saturation, 1.0, 1.0, saturation, 1.0, colorcount, + red, green, blue); + Scr[screen].npixels = 0; + for (i = 0; i < colorcount; i++) { + XColor xcolor; + + xcolor.red = red[i] << 8; + xcolor.green = green[i] << 8; + xcolor.blue = blue[i] << 8; + xcolor.flags = DoRed | DoGreen | DoBlue; + + if (!XAllocColor(dsp, cmap, &xcolor)) + break; + + Scr[screen].pixels[i] = xcolor.pixel; + Scr[screen].npixels++; + } + if (verbose) + fprintf(stderr, "%d pixels allocated\n", Scr[screen].npixels); + } + + xswa.override_redirect = True; + xswa.background_pixel = BlackPixelOfScreen(scr); + xswa.event_mask = KeyPressMask | ButtonPressMask | VisibilityChangeMask; + +#ifdef DEBUG +#define WIDTH WidthOfScreen(scr) - 100 +#define HEIGHT HeightOfScreen(scr) - 100 +#define CWMASK CWBackPixel | CWEventMask +#else +#define WIDTH WidthOfScreen(scr) +#define HEIGHT HeightOfScreen(scr) +#define CWMASK CWOverrideRedirect | CWBackPixel | CWEventMask +#endif + + win[screen] = XCreateWindow(dsp, root[screen], 0, 0, WIDTH, HEIGHT, 0, + CopyFromParent, InputOutput, CopyFromParent, + CWMASK, &xswa); + +#ifdef DEBUG + { + XWMHints xwmh; + + xwmh.flags = InputHint; + xwmh.input = True; + XChangeProperty(dsp, win[screen], + XA_WM_HINTS, XA_WM_HINTS, 32, PropModeReplace, + (unsigned char *) &xwmh, sizeof(xwmh) / sizeof(int)); + } +#endif + + iconx[screen] = (DisplayWidth(dsp, screen) - + XTextWidth(font, text_info, strlen(text_info))) / 2; + + icony[screen] = DisplayHeight(dsp, screen) / 6; + + xswa.border_pixel = fgcol[screen]; + xswa.background_pixel = bgcol[screen]; + xswa.event_mask = ButtonPressMask; +#define CIMASK CWBorderPixel | CWBackPixel | CWEventMask + icon[screen] = XCreateWindow(dsp, win[screen], + iconx[screen], icony[screen], + ICONW, ICONH, 1, CopyFromParent, + InputOutput, CopyFromParent, + CIMASK, &xswa); + + XMapWindow(dsp, win[screen]); + XRaiseWindow(dsp, win[screen]); + + xgcv.foreground = WhitePixelOfScreen(scr); + xgcv.background = BlackPixelOfScreen(scr); + Scr[screen].gc = XCreateGC(dsp, win[screen], + GCForeground | GCBackground, &xgcv); + + xgcv.foreground = fgcol[screen]; + xgcv.background = bgcol[screen]; + xgcv.font = font->fid; + textgc[screen] = XCreateGC(dsp, win[screen], + GCFont | GCForeground | GCBackground, &xgcv); + } + lockc = XCreateBitmapFromData(dsp, root[0], no_bits, 1, 1); + lockm = XCreateBitmapFromData(dsp, root[0], no_bits, 1, 1); + mycursor = XCreatePixmapCursor(dsp, lockc, lockm, + &nullcolor, &nullcolor, 0, 0); + XFreePixmap(dsp, lockc); + XFreePixmap(dsp, lockm); + + + if (!enablesaver) { + XGetScreenSaver(dsp, &sstimeout, &ssinterval, + &ssblanking, &ssexposures); + XSetScreenSaver(dsp, 0, 0, 0, 0); /* disable screen saver */ + } +#ifndef DEBUG + GrabKeyboardAndMouse(); +#endif + + nice(nicelevel); + + if (nolock) + justDisplay(); + else + lockDisplay(); + + finish(); + + return 0; +} diff --git a/xlock.h b/xlock.h new file mode 100644 index 00000000..834bd1a4 --- /dev/null +++ b/xlock.h @@ -0,0 +1,83 @@ +/*- + * @(#)xlock.h 1.9 91/05/24 XLOCK + * + * xlock.h - external interfaces for new modes and SYSV OS defines. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + */ + +#include +#include +#include + +#define MAXSCREENS 3 +#define NUMCOLORS 64 + +typedef struct { + GC gc; /* graphics context for animation */ + int npixels; /* number of valid entries in pixels */ + u_long pixels[NUMCOLORS]; /* pixel values in the colormap */ +} perscreen; + +extern perscreen Scr[MAXSCREENS]; +extern Display *dsp; +extern int screen; + +extern char *ProgramName; +extern char *display; +extern char *mode; +extern char *fontname; +extern char *background; +extern char *foreground; +extern char *text_name; +extern char *text_pass; +extern char *text_info; +extern char *text_valid; +extern char *text_invalid; +extern float saturation; +extern int nicelevel; +extern int delay; +extern int batchcount; +extern int reinittime; +extern int timeout; +extern Bool usefirst; +extern Bool mono; +extern Bool nolock; +extern Bool allowroot; +extern Bool enablesaver; +extern Bool allowaccess; +extern Bool echokeys; +extern Bool verbose; +extern void (*callback) (); +extern void (*init) (); + +extern void GetResources(); +extern void hsbramp(); +extern void error(); +extern long seconds(); +extern void usage(); + +/* System V Release 4 redefinitions of BSD functions and structures */ + +#ifdef SYSV + +#include +#ifndef hpux +#include +#include +#endif +#define srandom srand +#define random rand +#define MAXRAND (32767.0) +#ifndef hpux +#define passwd spwd +#define pw_passwd sp_pwdp +#define getpwnam getspnam +#endif + +#else + +#define MAXRAND (2147483648.0) + +#endif diff --git a/xlock.h.cln b/xlock.h.cln new file mode 100644 index 00000000..e6480bc1 --- /dev/null +++ b/xlock.h.cln @@ -0,0 +1,79 @@ +/*- + * @(#)xlock.h 1.9 91/05/24 XLOCK + * + * xlock.h - external interfaces for new modes and SYSV OS defines. + * + * Copyright (c) 1991 by Patrick J. Naughton. + * + */ + +#include +#include +#include + +#define MAXSCREENS 3 +#define NUMCOLORS 64 + +typedef struct { + GC gc; /* graphics context for animation */ + int npixels; /* number of valid entries in pixels */ + u_long pixels[NUMCOLORS]; /* pixel values in the colormap */ +} perscreen; + +extern perscreen Scr[MAXSCREENS]; +extern Display *dsp; +extern int screen; + +extern char *ProgramName; +extern char *display; +extern char *mode; +extern char *fontname; +extern char *background; +extern char *foreground; +extern char *text_name; +extern char *text_pass; +extern char *text_info; +extern char *text_valid; +extern char *text_invalid; +extern float saturation; +extern int nicelevel; +extern int delay; +extern int batchcount; +extern int reinittime; +extern int timeout; +extern Bool usefirst; +extern Bool mono; +extern Bool nolock; +extern Bool allowroot; +extern Bool enablesaver; +extern Bool allowaccess; +extern Bool echokeys; +extern Bool verbose; +extern void (*callback) (); +extern void (*init) (); + +extern void GetResources(); +extern void hsbramp(); +extern void error(); +extern long seconds(); +extern void usage(); + +/* System V Release 4 redefinitions of BSD functions and structures */ + +#ifdef SYSV + +#include +#include +#include +#define srandom srand +#define random rand +#define MAXRAND (32767.0) +#define passwd spwd +#define pw_passwd sp_pwdp +#define getpwnam getspnam + +#else + +#define MAXRAND (2147483648.0) + +#endif diff --git a/xlock.man b/xlock.man new file mode 100644 index 00000000..58d73bcb --- /dev/null +++ b/xlock.man @@ -0,0 +1,367 @@ +.\" @(#)xlock.man 1.11 91/09/27; Copyright (c) 1991 - Patrick J. Naughton +.TH XLOCK 1 "27 Sep 1991" "X11R5 Contrib" +.SH NAME +xlock \- Locks the local X display until a password is entered. + +.IX xlock#(1) "" "\fLxlock\fP(1)" +.SH SYNOPSIS +.B xlock +[ +.BI \-display " dsp" +] +[ +.BI \-help +] +[ +.BI \-name "resource-name" +] +[ +.BI \-resources +] +[ +.BI -/+remote +] +[ +.BI -/+mono +] +[ +.BI -/+nolock +] +[ +.BI -/+allowroot +] +[ +.BI -/+enablesaver +] +[ +.BI -/+allowaccess +] +[ +.BI -/+echokeys +] +[ +.BI -/+usefirst +] +[ +.BI -/+v +] +[ +.BI \-delay " usecs" +] +[ +.BI \-batchcount " num" +] +[ +.BI \-nice " level" +] +[ +.BI \-timeout " seconds" +] +[ +.BI \-saturation " value" +] +[ +.BI \-font " fontname" +] +[ +.BI \-bg " color" +] +[ +.BI \-fg " color" +] +[ +.BI \-mode " mode" +] +[ +.BI \-username " textstring" +] +[ +.BI \-password " textstring" +] +[ +.BI \-info " textstring" +] +[ +.BI \-validate " textstring" +] +[ +.BI \-invalid " textstring" +] + +.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. +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 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 +locks all available screens on a given server, +and restricts you to locking only a local server such as +.BI unix:0, +.BI localhost:0, +or +.BI :0 +unless you set the +.B \-remote +option. +.TP 5 +.B \-name " resource-name" +.I resource-name +is used instead of +.B XLock +when looking for resources to configure xlock. +.TP 5 +.B \-mode " modename" +As of this writing there are eight display modes supported +(plus one more for random selection of one of the eight). +.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 8 +.B image +Image mode shows several sun logos randomly appearing on the screen. +.TP 8 +.B swarm +Swarm mode shows a swarm of bees following a wasp. +.TP 8 +.B rotor +Rotor mode shows a swirling rotorlike thing. +.TP 8 +.B pyro +Pyro mode shows fireworks. +.TP 8 +.B flame +Flame mode shows wierd but cool cosmic flame fractals. +.TP 8 +.B worm +Worm mode shows wiggly worms... +.TP 8 +.B blank +Blank mode shows nothing but a black screen. +.TP 8 +.B random +Random mode picks a random mode from all of the above except blank mode. + +.TP 5 +.B \-delay " usecs" +The +.I delay +option sets the speed at which a mode will operate. It simply sets the +number of microseconds to delay between batches of "hopalong pixels", +"qix lines", "life generations", "image blits", and "swarm motions". In +blank mode, it is important to set this to some small number of seconds, +because the keyboard and mouse are only checked after each delay, so you +cannot set the delay too high, but a delay of zero would needlessly +consume cpu checking for mouse and keyboard input in a tight loop, since +blank mode has no work to do. +.TP 5 +.B \-batchcount " num" +The +.I batchcount +option sets number of +.I things +to do per batch to +.I num . +In hop mode this refers to the number of pixels rendered in the same color. +In life mode it is the number of generations to let each species live. +In qix mode it is the number of lines rendered in the same color. +In image mode it is the number of sunlogos on screen at once. +In swarm mode it is the number of bees. +In rotor mode it is the number of rotor thingys which whirr... +In pyro mode it is the maximum number flying rockets at one time. +In flame mode it is the number of levels to recurse (larger = more complex). +In worm mode it is the number of worms. +In blank mode it means nothing. +.TP 5 +.B \-nice " nicelevel" +The +.I nice +option sets system nicelevel of the xlock process to +.I nicelevel . +.TP 5 +.B \-timeout " seconds" +The +.I timeout +option sets the number of +.I seconds +before the password screen will time out. +.TP 5 +.B \-saturation " value" +The +.I saturation +option sets saturation of the color ramp used to +.I value . +0 is grayscale and 1 is very rich color. 0.4 is a nice pastel. +.TP 5 +.B \-font " fontname" +The +.I font +option sets the font to be used on the prompt screen. +.TP 5 +.B \-fg " color" +The +.I fg +option sets the color of the text on the password screen to +.I color . +.TP 5 +.B \-bg " color" +The +.I bg +option sets the color of the background on the password screen to +.I color . +.TP 5 +.B \-username " textstring" +.I textstring +is shown in front of user name, defaults to "Name: ". +.TP 5 +.B \-password " textstring" +.I textstring +is the password prompt string, defaults to "Password: ". +.TP 5 +.B \-info " textstring" +.I textstring +is an informational message to tell the user what to do, defaults to +"Enter password to unlock; select icon to lock.". +.TP 5 +.BI \-validate " textstring" +.I textstring +.BI \-validate " message shown while validating the password, defaults to +"Validating login..." +.TP 5 +.BI \-invalid " textstring" +.I textstring +.BI \-invalid " message shown when password is invalid, defaults to +"Invalid login." + +.TP 5 +.B \-resources +The +.I resources +option prints the default resource file for xlock to standard output. +.TP 5 +.B -/+remote +The +.I remote +option tells xlock to not stop you from locking remote X11 servers. This +option should be used with care and is intended mainly to lock X11 terminals +which cannot run +.I xlock +locally. If you lock someone else's workstation, they will have to know +.B your +password to unlock it. +.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 +/-nolock +The +.I nolock +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 -/+allowroot +The +.I allowroot +option allows the root password to unlock the server as well as the user +who started xlock. +.TP 5 +.B -/+enablesaver +By default xlock will disable the normal X server's screen saver since +it is in effect a replacement for it. Since it is possible to set delay +parameters long enough to cause phosphor burn on some displays, this +option will turn back on the default screensaver which is very careful +to keep most of the screen black. +.TP 5 +.B -/+allowaccess +This option is required for servers which do not allow clients to modify +the host access control list. It is also useful if you need to run x +clients on a server which is locked for some reason... When allowaccess +is true, the X11 server is left open for clients to attach and thus +lowers the inherent security of this lockscreen. A side effect of using +this option is that if xlock is killed -KILL, the access control list is +not lost. +.TP 5 +.B -/+echokeys +The +.I echokeys +option causes xlock to echo '?' characters for each key typed into the +password prompt. Some consider this a security risk, so the default is +to not echo anything. +.TP 5 +.B -/+usefirst +The +.I usefirst +option causes xlock to use the keystroke which got you to the password screen +as the first character in the password. The default is to ignore the first +key pressed. +.TP 5 +.B \-v +Verbose mode, tells what options it is going to use. + +.SH BUGS +"kill -KILL +.B xlock +" causes the server that was locked to be unusable, since all hosts +(including localhost) were removed from the access control list +to lock out new X clients, and since xlock couldn't catch SIGKILL, +it terminated 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 unless you reset the server."\fP + -From the X11R4 Xlib Documentation, Chapter 7. + +NCD terminals do not allow xlock to remove all the hosts from the access +control list. Therefore you will need to use the "-remote" and +"-noaccess" switches. If you happen to run without "-noaccess" on an +NCD terminal, +.B xlock +won't work and you will need to reboot the terminal, or simply go into +the SETUP menus, under 'Network Parameters', and turn off TCP/IP access +control. + +.SH SEE ALSO +X(1), Xlib Documentation. +.SH AUTHOR + Patrick J. Naughton (naughton@eng.sun.com) + Mailstop 21-14 + Sun Microsystems Laboratories, Inc. + Mountain View, CA 94043 + 415/336-1080 +.SH COPYRIGHT +Copyright (c) 1988-91 by Patrick J. Naughton + +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.