From 6cb1c12fcba2d3dd7a08ab52b9c83f81f1aeef41 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Fri, 27 Feb 2009 14:22:48 -0500 Subject: [PATCH 1/1] 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 --- HPUX.Install | 14 + Imakefile | 18 ++ Makefile.720 | 518 +++++++++++++++++++++++++++++++ Makefile.imake | 14 + Makefile.shipped | 29 ++ README | 28 ++ README.LUCS | 10 + XLock.ad | 50 +++ XLock.ad.cln | 50 +++ blank.c | 29 ++ flame.c | 167 ++++++++++ hopalong.c | 112 +++++++ hsbramp.c | 114 +++++++ image.c | 111 +++++++ life.c | 612 ++++++++++++++++++++++++++++++++++++ lifeicon.bit | 13 + pyro.c | 386 +++++++++++++++++++++++ qix.c | 140 +++++++++ resource.c | 746 ++++++++++++++++++++++++++++++++++++++++++++ rotor.c | 249 +++++++++++++++ sunlogo.bit | 46 +++ swarm.c | 202 ++++++++++++ usleep.c | 42 +++ usleep.c.cln | 42 +++ wamfunction.c | 362 ++++++++++++++++++++++ worm.c | 212 +++++++++++++ worm.c.cln | 202 ++++++++++++ xlock.c | 783 +++++++++++++++++++++++++++++++++++++++++++++++ xlock.h | 83 +++++ xlock.h.cln | 79 +++++ xlock.man | 367 ++++++++++++++++++++++ 31 files changed, 5830 insertions(+) create mode 100644 HPUX.Install create mode 100644 Imakefile create mode 100644 Makefile.720 create mode 100644 Makefile.imake create mode 100644 Makefile.shipped create mode 100644 README create mode 100644 README.LUCS create mode 100644 XLock.ad create mode 100644 XLock.ad.cln create mode 100644 blank.c create mode 100644 flame.c create mode 100644 hopalong.c create mode 100644 hsbramp.c create mode 100644 image.c create mode 100644 life.c create mode 100644 lifeicon.bit create mode 100644 pyro.c create mode 100644 qix.c create mode 100644 resource.c create mode 100644 rotor.c create mode 100644 sunlogo.bit create mode 100644 swarm.c create mode 100644 usleep.c create mode 100644 usleep.c.cln create mode 100644 wamfunction.c create mode 100644 worm.c create mode 100644 worm.c.cln create mode 100644 xlock.c create mode 100644 xlock.h create mode 100644 xlock.h.cln create mode 100644 xlock.man 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. -- 2.39.5