http://ftp.x.org/contrib/applications/xscreensaver-2.21.tar.gz
authorZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:25 +0000 (00:42 -0500)
committerZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:25 +0000 (00:42 -0500)
-rw-r--r-- 1 zblaxell zblaxell 805015 Jun 14  1998 xscreensaver-2.21.tar.gz
09413484d69da650e73f09e928977a27696655df  xscreensaver-2.21.tar.gz

67 files changed:
README
README.debugging
configure.in
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/demo.c
driver/lock.c
driver/stderr.c
driver/subprocs.c
driver/timers.c
driver/windows.c
driver/xscreensaver-command.c
driver/xscreensaver-command.man
driver/xscreensaver.c
driver/xscreensaver.h
driver/xscreensaver.man
hacks/Makefile.in
hacks/ant.c
hacks/attraction.c
hacks/blitspin.c
hacks/bsod.c [new file with mode: 0644]
hacks/bubbles.c
hacks/compile_axp.com
hacks/compile_decc.com
hacks/cynosure.c
hacks/deco.c
hacks/epicycle.c [new file with mode: 0644]
hacks/epicycle.man [new file with mode: 0644]
hacks/flame.c
hacks/glx/Makefile.in
hacks/goop.c
hacks/greynetic.c
hacks/halo.c
hacks/helix.c
hacks/hypercube.c
hacks/ifs.c
hacks/images/amiga.xpm [new file with mode: 0644]
hacks/images/mac.xbm [new file with mode: 0644]
hacks/imsmap.c
hacks/interference.c [new file with mode: 0644]
hacks/jigsaw.c
hacks/kaleidescope.c
hacks/maze.c
hacks/moire.c
hacks/moire2.c
hacks/munch.c
hacks/noseguy.c
hacks/pedal.c
hacks/pyro.c
hacks/qix.c
hacks/rd-bomb.c
hacks/rocks.c
hacks/rorschach.c
hacks/screenhack.c
hacks/starfish.c
hacks/truchet.c [new file with mode: 0644]
hacks/vidwhacker
hacks/xjack.c
hacks/xlockmore.c
hacks/xlyap.c
setup.com
utils/Makefile.in
utils/spline.c
utils/spline.h
utils/version.h
xscreensaver.lsm

diff --git a/README b/README
index bc6809766612b7a306548cb0776862fec1f99f51..b2204503e1f3cb4bd1a634d2bc52645f107ab148 100644 (file)
--- a/README
+++ b/README
@@ -26,15 +26,31 @@ If you think you've found a bug, please let me know; but first, read
 the enlosed `README.debugging' file to find out what kind of information
 would be most helpful to include in your bug report.
 
+Getting Started:
+
+You can try out xscreensaver like so:
+
+       xscreensaver &
+       xscreensaver-command -demo
+
+After a few seconds, the screen should go black, and a dialog box should
+appear in the upper right corner.  This is "Demo Mode".
+
+Note: unlike `xlock', xscreensaver has a client-server model: the
+`xscreensaver' process is a daemon that runs in the background; it is
+controlled by the foreground `xscreensaver-command' program.
+
+xscreensaver has an extensive manual -- please read it!
+
                               ============
 
 The xscreensaver program waits until the keyboard and mouse have been idle
 for a period, and then runs a graphics demo chosen at random.  It turns off
 as soon as there is any mouse or keyboard activity.
 
-The purpose of xscreensaver is to display pretty pictures on your screen 
-when it is not in use, in keeping with the philosophy that unattended 
-monitors should always be doing something interesting, just like they do 
+The purpose of xscreensaver is to display pretty pictures on your screen
+when it is not in use, in keeping with the philosophy that unattended
+monitors should always be doing something interesting, just like they do
 in the movies.
 
 However, xscreensaver can also be used as a screen locker, to prevent
@@ -52,10 +68,10 @@ about what it means to be a screensaver.
 The XIDLE, MIT-SCREEN-SAVER, and/or SGI SCREEN_SAVER server extensions
 will be used if you have them.
 
-The dialog boxes (for locking and demo-mode) look best using Motif, but
-can be configured to use Athena widgets instead.
+The dialog boxes (for locking and demo-mode) look best using Motif or
+Lesstif, but can be configured to use Athena widgets instead.
 
-Also included are several graphics hacks for use as screensavers.  There's
+Also included are numerous graphics hacks for use as screensavers.  There's
 nothing magic about these: they're just programs that draw on the root
 window, which are pointed at by the screensaver's default resource settings.
 
@@ -123,6 +139,10 @@ window, which are pointed at by the screensaver's default resource settings.
    xjack       - Simulates a schizophrenic typist.
    xlyap       - Calculates and displays Lyapunov exponents.
    flow                - More strange attractors.
+   epicycle    - Spiral patterns based on pre-Copernican cosmologies.
+   interference        - More groovy colored fields.
+   truchet     - Nonrepeating planar tilings.
+   bsod                - Simulates the system crashes of various other OSes.
    gears       - Draws interlocking rotating gears (GLX only.)
    morph3d     - Draws shiny shape-changing 3d forms (GLX only.)
    superquadrics - More shiny shape-changing 3d forms (GLX only.)
@@ -135,7 +155,7 @@ window, which are pointed at by the screensaver's default resource settings.
    atlantis    - Draws swimming mammals (GLX only.)
 
 All of these will pop up their own window unless given that -root option.
-See their man pages for more details.
+See their respective man pages for more details.
 
 Other reasonable things to use as screensavers, if you have them, are
 
@@ -165,214 +185,256 @@ http://people.netscape.com/jwz/xscreensaver/.
        -- Jamie Zawinski <jwz@netscape.com>
 
 \f
-Changes since 2.16:    Added a -window-id argument to most hacks, so that they
+Changes since 2.20:   * Made "xscreensaver-command -time" use different words.
+                       (It now describes the two states as "screen blanked
+                       since..."  and "screen non-blanked since..." instead of
+                       "active since..." and "inactive since..." which a lot
+                       of people interpreted as meaning the opposite of what
+                       was intended.)
+                     * Improved some error messages, in the hopes of making
+                       the distinction between the xscreensaver and
+                       xscreensaver-command programs more obvious.
+                     * Rewrote (and reorganized) parts of the xscreensaver and
+                       xscreensaver-command manual pages.
+                     * Renamed xscreensaver's "-lock" command-line option to
+                       be "-lock-mode", to avoid confusion with the "-lock"
+                       option to xscreensaver-command, which does a totally
+                       different thing.
+                     * Removed xscreensaver's "-demo" command-line option for
+                       a similar reason; use "xscreensaver-command -demo"
+                       instead.
+                     * Disabled SGI's "scheme" nonsense in a better way than
+                       fully-qualifying the background colors in every single
+                       hack.
+                     * Fixed some other minor cosmetic problems when *sgiMode
+                       is turned on.
+                     * Fixed an X error in `bsod -root' (how ironic...)
+Changes since 2.19:   * Fixed a bug that caused the mouse to sometimes not be
+                       grabbed properly (meaning the window manager menu could
+                       pop up over the demo-mode display.)
+                     * Fixed a bug that made the stderr output sometimes get
+                       printed twice.
+                     * Fixed a bug that made the demo-mode scrollbar move too
+                       fast.
+                     * Protected against a possible buffer overflow.
+                     * Made `vidwhacker' not leave stray xv windows around.
+                     * New version of `ant' so that Bagley doesn't calve.
+                     * Make configure on AIX get XShm from the right library.
+Changes since 2.18:   * One file was missing from the tar file.         Fixed.
+Changes since 2.17:   * Oops, atlantis wasn't being built by default.  Fixed.
+                     * Added `epicycle' hack.
+                     * Added `interference' hack.
+                     * Added `truchet' hack.
+                     * Added `bsod' hack.
+                     * Added some new modes to `vidwhacker'.
+Changes since 2.16:   * Added a -window-id argument to most hacks, so that they
                        can draw on arbitrary externally-provided windows.
-                       Synched with xlockmore 4.11a01.
-                       Added `flow' hack.
-                       Added `atlantis' GL hack.
-                       Renamed `puzzle' hack to `jigsaw', since xlock already
+                     * Synched with xlockmore 4.11a01.
+                     * Added `flow' hack.
+                     * Added `atlantis' GL hack.
+                     * Renamed `puzzle' hack to `jigsaw', since xlock already
                        had a different mode called `puzzle'.
-                       Made it self-configure properly when Motif 2.1.0 is
+                     * Made it self-configure properly when Motif 2.1.0 is
                        being used (requires -lXp now, sigh...)
-Changes since 2.15:    Made `flag' able to do XPM images.
-                       New look for the xscreensaver logo (`xroger').
-                       Fixed compilation error on Suns with adjunct passwords.
-                       Got multi-architecture builds working again.
-                       Some configure tweaks for building on HPUX and Solaris.
-                       Fixed bug in decayscreen.
-                       Fixed typo in passwd.c.
-                       Made `cynosure' not die when colormap is full.
-Changes since 2.14:    Added `cynosure' hack.
-                       Added `moire2' hack.
-                       Tweaked `erase.c' some more.
-                       Made unfading a bit smoother.
-                       Added `vidwhacker' hack (not installed by default.)
-                       Added `stairs' hack.
-                       Split `escher' into `cage' and `moebius', as per
+Changes since 2.15:   * Made `flag' able to do XPM images.
+                     * New look for the xscreensaver logo (`xroger').
+                     * Fixed compilation error on Suns with adjunct passwords.
+                     * Got multi-architecture builds working again.
+                     * Some configure tweaks for building on HPUX and Solaris.
+                     * Fixed bug in decayscreen.
+                     * Fixed typo in passwd.c.
+                     * Made `cynosure' not die when colormap is full.
+Changes since 2.14:   * Added `cynosure' hack.
+                     * Added `moire2' hack.
+                     * Tweaked `erase.c' some more.
+                     * Made unfading a bit smoother.
+                     * Added `vidwhacker' hack (not installed by default.)
+                     * Added `stairs' hack.
+                     * Split `escher' into `cage' and `moebius', as per
                        xlockmore.
-                       Changed subprocess handling to use sigaction() instead
+                     * Changed subprocess handling to use sigaction() instead
                        of signal() if it's available (this is necessary for
                        SCO but should work fine on other systems too.)
-                       Various other tweaks.
-Changes since 2.13:    Better fix for the Motif drag-and-die lossage.
-                       Put in some kludges to work around a LessTif bug.
-                       XScreenSaver is known to work with LessTif 0.82 now.
-                       Made fading work on high-end SGI video hardware.
-                       Fixed another SGI-specific bug in screen grabbing;
+                     * Various other tweaks.
+Changes since 2.13:   * Better fix for the Motif drag-and-die lossage.
+                     * Put in some kludges to work around a LessTif bug.
+                     * XScreenSaver is known to work with LessTif 0.82 now.
+                     * Made fading work on high-end SGI video hardware.
+                     * Fixed another SGI-specific bug in screen grabbing;
                        will the madness never cease?
-                       Fixed another crash in `xlyap'.
-Changes since 2.12:    Made `decayscreen' do directions other than down.
-                       Improved `puzzle'.
-                       Fixed a crash in `xlyap'.
-                       Added CDE info to the man page, removed `cde.txt'.
-                       Configure tweaks for Zippy.
-                       Turned off the signal handling in `bubbles' because
+                     * Fixed another crash in `xlyap'.
+Changes since 2.12:   * Made `decayscreen' do directions other than down.
+                     * Improved `puzzle'.
+                     * Fixed a crash in `xlyap'.
+                     * Added CDE info to the man page, removed `cde.txt'.
+                     * Configure tweaks for Zippy.
+                     * Turned off the signal handling in `bubbles' because
                        it was sometimes failing to die.
-                       Added `hacks/xscreensaver-sgigl.c' to make it possible
+                     * Added `hacks/xscreensaver-sgigl.c' to make it possible
                        to run SGI's ElectroPaint hack (/usr/demos/bin/ep)
                        with xscreensaver.  Finally!
-                       Fixed a buffer overrun in the locking code that some
+                     * Fixed a buffer overrun in the locking code that some
                        wily, malicious cracker must have slipped in.
-                       Disabled Motif drag-and-drool in the dialog box
+                     * Disabled Motif drag-and-drool in the dialog box
                        buttons, since it's broken in some old versions of
                        Motif.
-Changes since 2.11:    Added `README.debugging'.
-                       Added `puzzle' hack.
-                       Added `xlyap' hack.
-                       Added "default-n" as a visual name, so that one can
+Changes since 2.11:   * Added `README.debugging'.
+                     * Added `puzzle' hack.
+                     * Added `xlyap' hack.
+                     * Added "default-n" as a visual name, so that one can
                        have -install on by default, but turn it off for
                        certain poorly-behaved hacks (like xv.)
-                       Added support for grabbing frames of external video
+                     * Added support for grabbing frames of external video
                        (on SGI) to the screen-grabbing hacks (decayscreen,
                        slidescreen, slip, blitspin, and puzzle.)
-                       Improved look of tiles in `slidescreen'; fixed its
+                     * Improved look of tiles in `slidescreen'; fixed its
                        color allocation problem.
-Changes since 2.10:    Tweaked `blitspin', added it to the default list.
-                       Added `lissie', `mountain', `triangle', `worm',
+Changes since 2.10:   * Tweaked `blitspin', added it to the default list.
+                     * Added `lissie', `mountain', `triangle', `worm',
                        `rotor', and `ant' from xlockmore.
-                       Updated `sierpinski', `galaxy', and `lisa'.
-                       Thickened the lines in `braid' and `lmorph'.
-                       Updated VMS makefiles.
-                       Renamed `fract' to `vines'.
-                       Added `xjack' hack.
-                       Made a few more hacks use erase.c, and added a few
+                     * Updated `sierpinski', `galaxy', and `lisa'.
+                     * Thickened the lines in `braid' and `lmorph'.
+                     * Updated VMS makefiles.
+                     * Renamed `fract' to `vines'.
+                     * Added `xjack' hack.
+                     * Made a few more hacks use erase.c, and added a few
                        more wipe styles.
-                       Fixed compilation problem with Sun's version of OpenGL.
-                       Added ability to use sigaction() instead of signal()
+                     * Fixed compilation problem with Sun's version of OpenGL.
+                     * Added ability to use sigaction() instead of signal()
                        to work around a SCO kernel bug.
-Changes since 2.09:    Fixed colormap bugs in `rd-bomb'; sped up `coral'.
-                       Configure tweaks for *BSD.
-Changes since 2.07:    New hacks `rd-bomb' and `coral'.
-                       New version of `maze' with some new algorithms.
-                       New colorized version of `rocks'.
-                       Fixed a bug in qix on 64-bit machines.
-                       Fixed a bug in the -time option.
-                       Fixed a bug in configure related to LessTif.
-Changes since 2.06:    Minor header tweaks in windows.c and flag.c.
-                       Made multi-architecture (VPATH) builds work properly.
-                       Merged new GL stuff from xlockmore (rubik, morph3d.)
-                       Fixed intermittent crashes in `imsmap' and `munch'.
-                       Added `fadeplot' hack from xlockmore.
-Changes since 2.05:    Merged in VMS support from Patrick Moreau.
-Changes since 2.04:    Fixed a MIT-SCREEN-SAVER-related crash, and tweaked 
+Changes since 2.09:   * Fixed colormap bugs in `rd-bomb'; sped up `coral'.
+                     * Configure tweaks for *BSD.
+Changes since 2.07:   * New hacks `rd-bomb' and `coral'.
+                     * New version of `maze' with some new algorithms.
+                     * New colorized version of `rocks'.
+                     * Fixed a bug in qix on 64-bit machines.
+                     * Fixed a bug in the -time option.
+                     * Fixed a bug in configure related to LessTif.
+Changes since 2.06:   * Minor header tweaks in windows.c and flag.c.
+                     * Made multi-architecture (VPATH) builds work properly.
+                     * Merged new GL stuff from xlockmore (rubik, morph3d.)
+                     * Fixed intermittent crashes in `imsmap' and `munch'.
+                     * Added `fadeplot' hack from xlockmore.
+Changes since 2.05:   * Merged in VMS support from Patrick Moreau.
+Changes since 2.04:   * Fixed a MIT-SCREEN-SAVER-related crash, and tweaked
                        configure to detect the extra-random -Xss library.
-Changes since 2.03:    HP configure tweaks.  Detect and warn about LessTif.
-                       Fixed low-color behavior of `goop', `pyro', `starfish',
+Changes since 2.03:   * HP configure tweaks.  Detect and warn about LessTif.
+                     * Fixed low-color behavior of `goop', `pyro', `starfish',
                        `greynetic', `flame', `halo', and `moire'.
-Changes since 2.02:    Fixed flicker in `pipes'.  Fixed 3d in `bouboule'.
-                       Added `munch' hack.
-                       Added basic dependencies to the Makefile.in files.
-Changes since 2.01:    Fixes for compiling with the MIT saver extension.
-                       Made the yow/fortune program be a configure option.
-                       Various configure tweaks.
-Changes since 2.00:    Added `goop' and `starfish' hacks.
-                       Added colomap cycling to `halo'.
-                       Made `attraction' use the new colormap allocator.
-                       Added better $PATH diagnostics.
-                       There was a bug in frand!  Color selection should be
+Changes since 2.02:   * Fixed flicker in `pipes'.  Fixed 3d in `bouboule'.
+                     * Added `munch' hack.
+                     * Added basic dependencies to the Makefile.in files.
+Changes since 2.01:   * Fixes for compiling with the MIT saver extension.
+                     * Made the yow/fortune program be a configure option.
+                     * Various configure tweaks.
+Changes since 2.00:   * Added `goop' and `starfish' hacks.
+                     * Added colomap cycling to `halo'.
+                     * Made `attraction' use the new colormap allocator.
+                     * Added better $PATH diagnostics.
+                     * There was a bug in frand!  Color selection should be
                        much improved now.
-Changes since 1.34:     Converted to use `configure' instead of `imake'.
-                        ANSI C is now required.
-                       Added Kerberos locking support, from Nat Lanza.
-                       Made the stderr text use overlay planes, if possible.
-                       Reworked the xlockmore compatibility stuff again.
-                       Added `gears', `superquadrics', `escher', `pipes',
+Changes since 1.34:   * Converted to use `configure' instead of `imake'.
+                     * ANSI C is now required.
+                     * Added Kerberos locking support, from Nat Lanza.
+                     * Made the stderr text use overlay planes, if possible.
+                     * Reworked the xlockmore compatibility stuff again.
+                     * Added `gears', `superquadrics', `escher', `pipes',
                        and `sproingies' hacks (depend on OpenGL.)
-Changes since 1.33:    Fixed some bugs, made fading be a little smoother.
-Changes since 1.32:    Made it work with multi-headed displays.
-                       Generalized sub-process management (Unix sucks!)
-                       Added interactive mouse frobbing to Julia.
-                       Added (untested) support for HPUX shadow passwords.
-                       Made normal non-shadow passwords be checked if the
+Changes since 1.33:   * Fixed some bugs, made fading be a little smoother.
+Changes since 1.32:   * Made it work with multi-headed displays.
+                     * Generalized sub-process management (Unix sucks!)
+                     * Added interactive mouse frobbing to Julia.
+                     * Added (untested) support for HPUX shadow passwords.
+                     * Made normal non-shadow passwords be checked if the
                        shadow passwords aren't accessible for some reason.
-Changes since 1.31:    Removed *colorPrograms and *monoPrograms resources:
+Changes since 1.31:   * Removed *colorPrograms and *monoPrograms resources:
                        made it possible to specify the desired visual on a
                        per-hack basis.
-                       Cleaned up / restructured the driver: no more globals.
-                       Made the Motif and Athena dialogs share more code.
-                       Probably fixed some Athena colormap-installation bugs.
-                       Fixed screen grabbing (cmap) on SGI 12-bit PseudoColor.
-                       Fixed divide-by-zero in bright random colormaps.
-                       Added an improved version of xlock's `flag' hack.
-                       Made unfading work better, and not flicker on SGIs.
-                       Added `sphere', `forest', `lisa' hacks from xlockmore.
-                       Added (untested) support for SunOS Adjunct passwords.
-Changes since 1.30:    Improved colors and colormap cycling of many hacks.
-                       Cleaned up xlockmore compatibility layer.
-                       Made `blitspin' able to grab an image off the screen.
-                       Ported `swirl' and `bouboule' hacks from xlockmore.
-                       Made the driver more careful about not leaving bits on
-                       the screen, or allowing other windows to raise 
+                     * Cleaned up / restructured the driver: no more globals.
+                     * Made the Motif and Athena dialogs share more code.
+                     * Probably fixed some Athena colormap-installation bugs.
+                     * Fixed screen grabbing (cmap) on SGI 12-bit PseudoColor.
+                     * Fixed divide-by-zero in bright random colormaps.
+                     * Added an improved version of xlock's `flag' hack.
+                     * Made unfading work better, and not flicker on SGIs.
+                     * Added `sphere', `forest', `lisa' hacks from xlockmore.
+                     * Added (untested) support for SunOS Adjunct passwords.
+Changes since 1.30:   * Improved colors and colormap cycling of many hacks.
+                     * Cleaned up xlockmore compatibility layer.
+                     * Made `blitspin' able to grab an image off the screen.
+                     * Ported `swirl' and `bouboule' hacks from xlockmore.
+                     * Made the driver more careful about not leaving bits on
+                       the screen, or allowing other windows to raise
                        themselves: it now re-blanks the screen every so often.
-                       Added `-time' option to `xscreensaver-command'.
-                       Improved SGI screen-grabbing some more: now it can grab
+                     * Added `-time' option to `xscreensaver-command'.
+                     * Improved SGI screen-grabbing some more: now it can grab
                        TrueColor screens into PseudoColor windows and have the
                        colors still come out semi-reasonably.
-Changes since 1.29:    Made `slidescreen' and `decayscreen' work better on
+Changes since 1.29:   * Made `slidescreen' and `decayscreen' work better on
                        SGIs when windows of different visuals are present, by
                        using the XReadDisplay() extension to get a true 24-bit
                        image out of the frame buffer.
-                       Made `noseguy' be in color, if compiled with XPM.
-                       Ported `braid', `drift', `fract', `galaxy', `grav', 
+                     * Made `noseguy' be in color, if compiled with XPM.
+                     * Ported `braid', `drift', `fract', `galaxy', `grav',
                        `ifs', `julia', `laser', `lightning', `penrose',
                        `sierpinski', `slip', `spiral', and `strange' hacks
                        from xlockmore.
-                       Merged `hopalong' hack with a more recent version.
-                       Added `cde.txt'.
-Changes since 1.27:    Added `deco', `moire', and `kaleidescope' hacks.
-                       Merged in support for non-Motif locking and demo mode.
-                       Made `blitspin' and `bubbles' work in TrueColor.
-                       Fixed a stupid bug I introduced in `imsmap'.
-                       Added `poly' and `gravity' options to `qix'.
-Changes since 1.26:    Added support for SGI SCREEN_SAVER extension.
-                       Made `fade' and `unfade' work on 8-bit SGIs.
-                       Made the dialog boxes more Motify.
-                       Added `bubbles' hack.
-Changes since 1.25:    Added `lmorph' hack.
-                       Added viscosity and mouse-control to attraction.
-                       Fixed possible bad color choices in qix and attraction.
-                       Added ramp-mode to halo.
-                       Added a new RNG, which is faster and more portable
+                     * Merged `hopalong' hack with a more recent version.
+                     * Added `cde.txt'.
+Changes since 1.27:   * Added `deco', `moire', and `kaleidescope' hacks.
+                     * Merged in support for non-Motif locking and demo mode.
+                     * Made `blitspin' and `bubbles' work in TrueColor.
+                     * Fixed a stupid bug I introduced in `imsmap'.
+                     * Added `poly' and `gravity' options to `qix'.
+Changes since 1.26:   * Added support for SGI SCREEN_SAVER extension.
+                     * Made `fade' and `unfade' work on 8-bit SGIs.
+                     * Made the dialog boxes more Motify.
+                     * Added `bubbles' hack.
+Changes since 1.25:   * Added `lmorph' hack.
+                     * Added viscosity and mouse-control to attraction.
+                     * Fixed possible bad color choices in qix and attraction.
+                     * Added ramp-mode to halo.
+                     * Added a new RNG, which is faster and more portable
                        than using the RNG in libc.
-                       Made locking work on SCO.
-                       Various other minor tweaks that I don't remember.
-Changes since 1.24:    Made it capture the stdout/stderr of its subprocesses
+                     * Made locking work on SCO.
+                     * Various other minor tweaks that I don't remember.
+Changes since 1.24:   * Made it capture the stdout/stderr of its subprocesses
                        and present them on the screensaver window itself.
-                       Made demo mode work correctly with non-default visuals
+                     * Made demo mode work correctly with non-default visuals
                        and color maps, instead of always using the defaults.
-                       Added -visual argument to all included screenhacks.
-                       Support for the R6 MIT-SCREEN-SAVER server extension.
-                       Made the demo mode list scroll properly.
-                       Added `pedal' hack.
-Changes since 1.23:    Fixed some private-colormap oddities in slidescreen,
+                     * Added -visual argument to all included screenhacks.
+                     * Support for the R6 MIT-SCREEN-SAVER server extension.
+                     * Made the demo mode list scroll properly.
+                     * Added `pedal' hack.
+Changes since 1.23:   * Fixed some private-colormap oddities in slidescreen,
                        decayscreen, and xroger.  Fixed apparent conservation-
                        of-mass problem in pyro; made the shrapnel round.
-Changes since 1.22:    Minor tweaks for IRIX5; fixed locking race condition.
-Changes since 1.21:    Minor tweaks for X11R6.
-                       Fixes for non-default visuals.
-Changes since 1.20:    Fixed bug in color blitspin; added default image.
-                       Added diagnostics to noseguy.  Fixed off-by-one
-                       error in flame.  Added some missing casts.
-Changes since 1.18:    Added `flame' hack.
-                       Fixed a minor Motif dialog text field bug.
-                       Fixed yet another XPointer-not-defined-in-R4 bug.
-Changes since 1.17:    Added support for shadow password files.
-                       Fixed some Motif-related locking bugs.
-                       Added diagnostics when locking is disabled.
-                       Made blitspin able to use the XPM library.
-                       Added `decayscreen' hack.
-Changes since 1.16:    Added `halo' hack.
-Changes since 1.15:    Portability fixes.
-Changes since 1.14:    Broke the driver up into more source files.
-                       Moved the hacks into their own directory.
-                       Made all `time' parameters accept the 00:00:00 syntax,
+Changes since 1.22:   * Minor tweaks for IRIX5; fixed locking race condition.
+Changes since 1.21:   * Minor tweaks for X11R6.
+                     * Fixes for non-default visuals.
+Changes since 1.20:   * Fixed bug in color blitspin; added default image.
+                     * Added diagnostics to noseguy.  Fixed off-by-one
+                       error in flame.  Added some missing casts.
+Changes since 1.18:   * Added `flame' hack.
+                     * Fixed a minor Motif dialog text field bug.
+                     * Fixed yet another XPointer-not-defined-in-R4 bug.
+Changes since 1.17:   * Added support for shadow password files.
+                     * Fixed some Motif-related locking bugs.
+                     * Added diagnostics when locking is disabled.
+                     * Made blitspin able to use the XPM library.
+                     * Added `decayscreen' hack.
+Changes since 1.16:   * Added `halo' hack.
+Changes since 1.15:   * Portability fixes.
+Changes since 1.14:   * Broke the driver up into more source files.
+                     * Moved the hacks into their own directory.
+                     * Made all `time' parameters accept the 00:00:00 syntax,
                        so that even the parameters which are normally read as
                        minutes can be specified in seconds.
-                       Added colormap cycling to `imsmap'.
-                       Made hyper work with K&R compilers.
-Changes since 1.13:    Added `orbit' option to `attraction' hack.
-                       Added `lock-timeout' option.
-                       Cleaned up options of `maze' hack.
-Changes since 1.8:     Added demo mode, and locking.
-                       Added `maze' hack.
-                       Added `norotate' option to `rocks' hack.
+                     * Added colormap cycling to `imsmap'.
+                     * Made hyper work with K&R compilers.
+Changes since 1.13:   * Added `orbit' option to `attraction' hack.
+                     * Added `lock-timeout' option.
+                     * Cleaned up options of `maze' hack.
+Changes since 1.8:    * Added demo mode, and locking.
+                     * Added `maze' hack.
+                     * Added `norotate' option to `rocks' hack.
index cf147893f6958c4edc430a21fc5d976349c6c7f4..f1a26220abf91b63d8916b3abac7851035a1d1cd 100644 (file)
@@ -51,7 +51,7 @@ BUILDING:
                csh:  setenv CC cc ; ./configure
                sh:   CC=cc ; ./configure
 
-    After doing this, you'll need to nuke `config.cache'.
+    Before doing this, you'll need to nuke `config.cache'.
 
     If you get errors about not being able to find Motif or Athena (the
     Xm/ or Xaw/ header files), and you can't find them on your system,
index 7071cacae60b09bac17761805914ea4148d6ff79..145ea610bf11167d6aad2f1b4928f2f49b669587 100644 (file)
@@ -535,6 +535,20 @@ if test $with_xshm = yes; then
     AC_CHECK_X_HEADER(sys/shm.h, [have_xshm=yes])
   fi
 
+  # AIX is pathological, as usual: apparently it's normal for the Xshm headers
+  # to exist, but the library code to not exist.  And even better, the library
+  # code is in its own library: libXextSam.a.  So, if we're on AIX, and that
+  # lib doesn't exist, give up.
+  #
+  case "$host" in
+    *-aix*)
+      have_xshm=no
+      AC_CHECK_X_LIB(XextSam, XShmQueryExtension,
+                    [have_xshm=yes; SAVER_LIBS="$SAVER_LIBS -lXextSam"],
+                      [], -lX11 -lXext -lm)
+    ;;
+  esac
+
   # if that succeeded, then we've really got it.
   if test $have_xshm = yes; then
     AC_DEFINE(HAVE_XSHM_EXTENSION)
index 56b7f6182a76d7e8a4a2c4ab5c42541f72cfabb9..ae4f62bf1a1fb40d73beec59ad96cd0957bab068 100644 (file)
@@ -45,7 +45,7 @@ AD_DIR                = @APPDEFAULTS@
 UTILS_SRC      = $(srcdir)/../utils
 UTILS_BIN      = ../utils
 
-INCLUDES       = -I. -I$(srcdir) -I$(srcdir)/.. -I$(UTILS_SRC) -I.. @INCLUDES@
+INCLUDES       = -I. -I$(srcdir) -I$(UTILS_SRC) -I.. @INCLUDES@
 
 PASSWD_LIBS    = @PASSWD_LIBS@
 MOTIF_SRCS     = dialogs-Xm.c
@@ -187,7 +187,7 @@ depend: XScreenSaver_ad.h
 # close.  This excludes dependencies on files in /usr/include, etc.  It tries
 # to include only dependencies on files which are themselves a part of this
 # package.
-distdepend: update_ad_version XScreenSaver_ad.h
+distdepend: update_ad_version update_man_version XScreenSaver_ad.h
        @echo updating dependencies in `pwd`/Makefile.in... ;               \
        $(DEPEND) -w 0 -f -                                                 \
        -s '# DO NOT DELETE: updated by make distdepend' $(DEPEND_FLAGS) -- \
@@ -212,9 +212,11 @@ update_ad_version::
        @S=XScreenSaver.ad.in ;                                             \
        U=$(UTILS_SRC)/version.h ;                                          \
        V=`sed -n 's/.*\([0-9][0-9]*\.[0-9]*\).*/\1/p' < $$U` ;             \
-       echo -n "Updating version number in $$S to $$V... " ;               \
+       D=`date '+%d-%b-%y'` ;                                              \
+       echo -n "Updating version number in $$S to $$V $$D... " ;           \
        T=/tmp/xs.$$$$ ;                                                    \
-       sed "s/\(.*version \)[0-9][0-9]*\.[0-9]*\(.*\)/\1$$V\2/"            \
+       sed -e "s/\(.*version \)[0-9][0-9]*\.[0-9]*\(.*\)/\1$$V\2/"         \
+           -e "s/\([0-9][0-9]-[A-Z][a-z][a-z]-[0-9][0-9]\)/$$D/"           \
          < $$S > $$T ;                                                     \
        if cmp -s $$S $$T ; then                                            \
          echo "unchanged." ;                                               \
@@ -224,6 +226,23 @@ update_ad_version::
        fi ;                                                                \
        rm $$T
 
+update_man_version::
+       @for S in $(MEN); do                                                \
+       U=$(UTILS_SRC)/version.h ;                                          \
+       V=`sed -n 's/.*\([0-9][0-9]*\.[0-9]*\).*/\1/p' < $$U` ;             \
+       V="`date '+%d-%b-%y'` ($$V)" ;                                      \
+       echo -n "Updating footer in $$S to \"$$V\"... " ;                   \
+       T=/tmp/xs.$$$$ ;                                                    \
+       sed "s/^\(\.TH[^\"]*\)\"[^\"]*\"\(.*\)/\1\"$$V\"\2/"                \
+         < $$S > $$T ;                                                     \
+       if cmp -s $$S $$T ; then                                            \
+         echo "unchanged." ;                                               \
+       else                                                                \
+         cat $$T > $$S ;                                                   \
+         echo "done." ;                                                    \
+       fi ;                                                                \
+       rm $$T ;                                                            \
+       done
 
 TAGS: tags
 tags:
@@ -260,7 +279,7 @@ $(UTIL_OBJS):
 # How we build the default app-defaults file into the program.
 #
 XScreenSaver_ad.h: XScreenSaver.ad
-       $(SHELL) $(UTILS_SRC)/ad2c XScreenSaver.ad > $@
+       $(SHELL) $(UTILS_SRC)/ad2c XScreenSaver.ad > XScreenSaver_ad.h
 
 # The executables linked in this directory.
 #
index 98d2e5d05342d084e1dcee6b9e651de1f54ffbb7..a4b78fb3c53041315df68685457e463d9586e879 100644 (file)
@@ -4,7 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 2.17
+!                              version 2.21
+!                                15-Jun-98
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://people.netscape.com/jwz/xscreensaver/
@@ -23,8 +24,8 @@
 
 *captureStderr:        True
 *captureStdout:        True
-*textForeground:       Yellow
-*textBackground:       Black
+*overlayTextForeground:        Yellow
+*overlayTextBackground:        Black
 *overlayStderr:                True
 *font:                 *-medium-r-*-140-*-m-*
 
                vines -root                                             \n\
                kaleidescope -root                                      \n\
                xjack -root                                             \n\
-               xlyap -root -random                                     \n\
+               xlyap -root -randomize                                  \n\
                cynosure -root                                          \n\
                flow -root                                              \n\
+               epicycle -root                                          \n\
+               interference -root                                      \n\
+               truchet -root -randomize                                \n\
+               bsod -root                                              \n\
                                                                          \
        mono:   rocks -root                                             \n\
        color:  rocks -root -fg darksalmon                              \n\
 *fontList:                       *-helvetica-medium-r-*-*-*-120-*-*-*-iso8859-1
 *demoDialog*label1.fontList:     *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1
 *passwdDialog*fontList:          *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1
-*XmList.fontList:                  *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1
 *XmTextField.fontList:             *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1
 *passwdDialog.passwdText.fontList: *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1
+XScreenSaver*XmList.fontList:      *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1
+! Need to fully-qualify the preceeding in the case of of *sgiMode.
 
 *XmDialogShell*foreground:             black
 *XmDialogShell*background:             gray90
 *XmDialogShell*XmTextField.background: white
 *XmDialogShell*demoList.foreground:    black
 *XmDialogShell*demoList.background:    white
-*XmDialogShell*rogerLabel.foreground:  red3
-*XmDialogShell*rogerLabel.background:  white
+
+! Need to fully-qualify the following in the case of of *sgiMode.
+XScreenSaver*XmDialogShell*rogerLabel.foreground:      red3
+XScreenSaver*XmDialogShell*rogerLabel.background:      white
 
 *XmDialogShell.title:          XScreenSaver
 *allowShellResize:             True
 *demoList.automaticSelection:  True
 *next.labelString:             Run Next
 *prev.labelString:             Run Previous
-*edit.labelString:             Edit Parameters
+*edit.labelString:             Preferences
 *done.labelString:             Exit Demo Mode
 *restart.labelString:          Reinitialize
 
@@ -379,7 +387,7 @@ XScreenSaver*dragReceiverProtocolStyle:  DRAG_NONE
 
 *demo_dialog*next.label:                       Run Next
 *demo_dialog*prev.label:                       Run Previous
-*demo_dialog*edit.label:                       Edit Parameters
+*demo_dialog*edit.label:                       Preferences
 *demo_dialog*done.label:                       Exit Demo Mode
 *demo_dialog*restart.label:                    Reinitialize
 
@@ -417,8 +425,7 @@ XScreenSaver*dragReceiverProtocolStyle:  DRAG_NONE
 ! You probably won't need to change these.  They are only used if no server
 ! extension is in use.
 !
-*pointerPollTime:      5
-*initialDelay:         30
-*windowCreationTimeout:        30
-
-*bourneShell:          /bin/sh
+XScreenSaver.pointerPollTime:          5
+XScreenSaver.initialDelay:             0
+XScreenSaver.windowCreationTimeout:    30
+XScreenSaver.bourneShell:              /bin/sh
index 73028d5f2d58388e2cf16cfc19b88b7bd7267d89..4c6497306fe8a44e665d63316ad733fc141c016b 100644 (file)
@@ -11,8 +11,8 @@
 "*fadeTicks:           20",
 "*captureStderr:       True",
 "*captureStdout:       True",
-"*textForeground:      Yellow",
-"*textBackground:      Black",
+"*overlayTextForeground:       Yellow",
+"*overlayTextBackground:       Black",
 "*overlayStderr:               True",
 "*font:                        *-medium-r-*-140-*-m-*",
 "*installColormap:     True",
                vines -root                                             \\n\
                kaleidescope -root                                      \\n\
                xjack -root                                             \\n\
-               xlyap -root -random                                     \\n\
+               xlyap -root -randomize                                  \\n\
                cynosure -root                                          \\n\
                flow -root                                              \\n\
+               epicycle -root                                          \\n\
+               interference -root                                      \\n\
+               truchet -root -randomize                                \\n\
+               bsod -root                                              \\n\
                                                                          \
        mono:   rocks -root                                             \\n\
        color:  rocks -root -fg darksalmon                              \\n\
 "*fontList:                       *-helvetica-medium-r-*-*-*-120-*-*-*-iso8859-1",
 "*demoDialog*label1.fontList:     *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1",
 "*passwdDialog*fontList:          *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1",
-"*XmList.fontList:                  *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1",
 "*XmTextField.fontList:             *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1",
 "*passwdDialog.passwdText.fontList: *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1",
+"XScreenSaver*XmList.fontList:      *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1",
 "*XmDialogShell*foreground:            black",
 "*XmDialogShell*background:            gray90",
 "*XmDialogShell*XmTextField.foreground:        black",
 "*XmDialogShell*XmTextField.background:        white",
 "*XmDialogShell*demoList.foreground:   black",
 "*XmDialogShell*demoList.background:   white",
-"*XmDialogShell*rogerLabel.foreground: red3",
-"*XmDialogShell*rogerLabel.background: white",
+"XScreenSaver*XmDialogShell*rogerLabel.foreground:     red3",
+"XScreenSaver*XmDialogShell*rogerLabel.background:     white",
 "*XmDialogShell.title:         XScreenSaver",
 "*allowShellResize:            True",
 "*autoUnmanage:                        False",
 "*demoList.automaticSelection: True",
 "*next.labelString:            Run Next",
 "*prev.labelString:            Run Previous",
-"*edit.labelString:            Edit Parameters",
+"*edit.labelString:            Preferences",
 "*done.labelString:            Exit Demo Mode",
 "*restart.labelString:         Reinitialize",
 "*resourcesLabel.labelString:  XScreenSaver Parameters",
 "*resources_dialog*Dialog.borderWidth:         0",
 "*demo_dialog*next.label:                      Run Next",
 "*demo_dialog*prev.label:                      Run Previous",
-"*demo_dialog*edit.label:                      Edit Parameters",
+"*demo_dialog*edit.label:                      Preferences",
 "*demo_dialog*done.label:                      Exit Demo Mode",
 "*demo_dialog*restart.label:                   Reinitialize",
 "*resources_dialog*timeout.label:              Saver Timeout:",
 "*passwd_dialog*roger.foreground:              red3",
 "*passwd_dialog*roger.background:              white",
 "*passwd_dialog*roger.borderWidth:             1",
-"*pointerPollTime:     5",
-"*initialDelay:                30",
-"*windowCreationTimeout:       30",
-"*bourneShell:         /bin/sh",
+"XScreenSaver.pointerPollTime:         5",
+"XScreenSaver.initialDelay:            0",
+"XScreenSaver.windowCreationTimeout:   30",
+"XScreenSaver.bourneShell:             /bin/sh",
index 0877ad4ef50b89c3a51f55effa429aa5522f604b..2c90218d487fc5603e361e7ff762a0d9a801408c 100644 (file)
@@ -226,6 +226,9 @@ select_cb (Widget button, XtPointer client_data, XtPointer call_data)
 #ifdef HAVE_ATHENA
   XawListReturnStruct *item = (XawListReturnStruct*)call_data;
   demo_mode_hack (si, item->string);
+  if (item->list_index >= 0)
+    si->default_screen->current_hack = item->list_index;
+
 #else  /* HAVE_MOTIF */
   XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data;
   char *string = 0;
@@ -233,7 +236,11 @@ select_cb (Widget button, XtPointer client_data, XtPointer call_data)
     XmStringGetLtoR (lcb->item, XmSTRING_DEFAULT_CHARSET, &string);
   set_text_string (text_line, (string ? string : ""));
   if (lcb->reason == XmCR_DEFAULT_ACTION && string)
-    demo_mode_hack (si, string);
+    {
+      demo_mode_hack (si, string);
+      if (lcb->item_position > 0)
+       si->default_screen->current_hack = lcb->item_position - 1;
+    }
   if (string)
     XtFree (string);
 #endif /* HAVE_MOTIF */
@@ -618,10 +625,8 @@ make_screenhack_dialog (saver_info *si)
                 XtNnumberStrings, si->prefs.screenhacks_count,
                 0);
   XtAddCallback (demo_list, XtNcallback, select_cb, si);
-
-  /* ####   still need to do the "select most-recently-run hack"
-     ####   thing for Athena.
-  */
+  if (ssi->current_hack > 0)
+  XawListHighlight(demo_list, ssi->current_hack);
 
 #endif /* HAVE_ATHENA */
 
@@ -629,6 +634,11 @@ make_screenhack_dialog (saver_info *si)
                    /* for debugging -- don't ask */
                    (si->prefs.debug_p ? 69 : 0) +
                    0);
+
+#ifdef HAVE_ATHENA
+  /* For Athena, have to do this after the dialog is managed. */
+  ensure_selected_item_visible (demo_list);
+#endif /* HAVE_ATHENA */
 }
 
 \f
@@ -923,7 +933,6 @@ demo_mode (saver_info *si)
 {
   saver_preferences *p = &si->prefs;
   si->dbox_up_p = True;
-  initialize_screensaver_window (si);
   raise_window (si, True, False, False);
   make_screenhack_dialog (si);
   while (si->demo_mode_p)
index 0d4c43e3ff663f5c393dad71073d48f1675ca93f..a5579a37bd10f31489bf79952f377d3b7329f333 100644 (file)
@@ -1,5 +1,5 @@
 /* lock.c --- handling the password dialog for locking-mode.
- * xscreensaver, Copyright (c) 1993-1997 Jamie Zawinski <jwz@netscape.com>
+ * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -22,6 +22,7 @@
 #include <X11/StringDefs.h>
 #include <X11/Intrinsic.h>
 #include "xscreensaver.h"
+#include "resources.h"
 
 #ifndef VMS
 # include <pwd.h>
@@ -445,6 +446,17 @@ passwd_idle_timer (XtPointer closure, XtIntervalId *id)
 
       x = (w / 2);
 
+#ifdef __sgi   /* Kludge -- SGI's Motif hacks place buttons differently. */
+      {
+       static int sgi_mode = -1;
+       if (sgi_mode == -1)
+         sgi_mode = get_boolean_resource("sgiMode", "sgiMode") ? 1 : 0;
+
+       if (sgi_mode)
+         x = d;
+      }
+#endif /* __sgi */
+
       x -= d/2;
       y += d/2;
 
index 9e536585268f1ac48d1ccdbb79c0214b689b968b..0c999e2fcfd55cdef991c2712069e15b3243b902 100644 (file)
@@ -1,5 +1,5 @@
 /* stderr.c --- capturing stdout/stderr output onto the screensaver window.
- * xscreensaver, Copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>
+ * xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -90,7 +90,6 @@ static void
 print_stderr_1 (saver_screen_info *ssi, char *string)
 {
   saver_info *si = ssi->global;
-  saver_preferences *p = &si->prefs;
   Display *dpy = si->dpy;
   Screen *screen = ssi->screen;
   Window window = (ssi->stderr_overlay_window ?
@@ -101,10 +100,6 @@ print_stderr_1 (saver_screen_info *ssi, char *string)
   char *head = string;
   char *tail;
 
-  /* In verbose mode, copy it to stderr as well. */
-  if (p->verbose_p)
-    fprintf (real_stderr, "%s", string);
-
   if (! ssi->stderr_font)
     {
       char *font_name = get_string_resource ("font", "Font");
@@ -131,8 +126,8 @@ print_stderr_1 (saver_screen_info *ssi, char *string)
            cmap = ssi->stderr_cmap;
        }
 
-      fg = get_pixel_resource ("textForeground", "Foreground", dpy, cmap);
-      bg = get_pixel_resource ("textBackground", "Background", dpy, cmap);
+      fg = get_pixel_resource ("overlayTextForeground","Foreground",dpy,cmap);
+      bg = get_pixel_resource ("overlayTextBackground","Background",dpy,cmap);
       gcv.font = ssi->stderr_font->fid;
       gcv.foreground = fg;
       gcv.background = bg;
index 4126960b0bc177a0c8a48a349c6c499e569de782..97904499981d1eeb69f1deebd416e0084144f52a 100644 (file)
@@ -959,8 +959,8 @@ demo_mode_restart_process (saver_info *si)
 {
   int i;
   for (i = 0; saved_argv [i]; i++);
-  /* add the -demo switch; save_argv() left room for this. */
-  saved_argv [i] = "-demo";
+  /* add the -initial-demo-mode switch; save_argv() left room for this. */
+  saved_argv [i] = "-initial-demo-mode";
   saved_argv [i+1] = 0;
   restart_process (si);                /* shouldn't return */
   saved_argv [i] = 0;
index dcff2e4e42116e22633f57ea9e6d22a68c0a69e3..bc92893a59c357b0d45503af94e0245f6c42b3a7 100644 (file)
@@ -181,10 +181,10 @@ cycle_timer (XtPointer closure, XtIntervalId *id)
   saver_info *si = (saver_info *) closure;
   saver_preferences *p = &si->prefs;
   Time how_long = p->cycle;
-  if (si->dbox_up_p)
+  if (si->dbox_up_p || si->question_up_p)
     {
       if (p->verbose_p)
-       printf ("%s: dbox up; delaying hack change.\n", progname);
+       printf ("%s: dialog box up; delaying hack change.\n", progname);
       how_long = 30000; /* 30 secs */
     }
   else
index 37702a10ab30513adb58c7a8065d126304fac100..b91ee2a0b0c7f0366bdc52a9bbb4a63f5d6614c4 100644 (file)
@@ -65,7 +65,7 @@
 extern int kill (pid_t, int);          /* signal() is in sys/signal.h... */
 
 Atom XA_VROOT, XA_XSETROOT_ID;
-Atom XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID;
+Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID;
 Atom XA_SCREENSAVER_TIME;
 
 
@@ -90,8 +90,11 @@ grab_kbd(saver_info *si, Window w)
                                 but these seem to work... */
                              GrabModeSync, GrabModeAsync,
                              CurrentTime);
+  if (status == GrabSuccess)
+    si->keyboard_grab_window = w;
+
   if (p->debug_p)
-    fprintf(real_stderr, "%s: XGrabKeyboard(... 0x%x ...) ==> %s\n",
+    fprintf(stderr, "%s: XGrabKeyboard(... 0x%x ...) ==> %s\n",
            progname, (unsigned long) w,
            (status == GrabSuccess ? "GrabSuccess" :
             status == AlreadyGrabbed ? "AlreadyGrabbed" :
@@ -103,6 +106,26 @@ grab_kbd(saver_info *si, Window w)
   return status;
 }
 
+static const char *
+grab_string(int status)
+{
+  switch (status)
+    {
+    case GrabSuccess:     return "GrabSuccess";     break;
+    case AlreadyGrabbed:  return "AlreadyGrabbed";  break;
+    case GrabInvalidTime: return "GrabInvalidTime"; break;
+    case GrabNotViewable: return "GrabNotViewable"; break;
+    case GrabFrozen:      return "GrabFrozen";      break;
+    default:
+      {
+       static char foo[255];
+       sprintf(foo, "unknown status: %d", status);
+       return foo;
+      }
+    }
+}
+
+
 static int
 grab_mouse (saver_info *si, Window w, Cursor cursor)
 {
@@ -110,19 +133,41 @@ grab_mouse (saver_info *si, Window w, Cursor cursor)
   int status = XGrabPointer (si->dpy, w, True, ALL_POINTER_EVENTS,
                             GrabModeAsync, GrabModeAsync, None,
                             cursor, CurrentTime);
+  if (status == GrabSuccess)
+    si->mouse_grab_window = w;
+
   if (p->debug_p)
-    fprintf(real_stderr, "%s: XGrabPointer(... 0x%x, 0x%x ...) ==> %s\n",
+    fprintf(stderr, "%s: XGrabPointer(... 0x%x, 0x%x ...) ==> %s\n",
            progname, (unsigned long) w, (unsigned long) cursor,
-           (status == GrabSuccess ? "GrabSuccess" :
-            status == AlreadyGrabbed ? "AlreadyGrabbed" :
-            status == GrabInvalidTime ? "GrabInvalidTime" :
-            status == GrabNotViewable ? "GrabNotViewable" :
-            status == GrabFrozen ? "GrabFrozen" :
-            "???"));
+           grab_string(status));
   return status;
 }
 
 
+static void
+ungrab_kbd(saver_info *si)
+{
+  saver_preferences *p = &si->prefs;
+  XUngrabKeyboard(si->dpy, CurrentTime);
+  if (p->debug_p)
+    fprintf(stderr, "%s: XUngrabKeyboard (was 0x%x)\n", progname,
+           (unsigned long) si->keyboard_grab_window);
+  si->keyboard_grab_window = 0;
+}
+
+
+static void
+ungrab_mouse(saver_info *si)
+{
+  saver_preferences *p = &si->prefs;
+  XUngrabPointer(si->dpy, CurrentTime);
+  if (p->debug_p)
+    fprintf(stderr, "%s: XUngrabPointer (was 0x%x)\n", progname,
+           (unsigned long) si->mouse_grab_window);
+  si->mouse_grab_window = 0;
+}
+
+
 void
 grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor)
 {
@@ -135,36 +180,35 @@ grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor)
       sleep (1);
       status = grab_kbd (si, window);
       if (status != GrabSuccess)
-       fprintf (stderr, "%s: couldn't grab keyboard!  (%d)\n",
-                progname, status);
+       fprintf (stderr, "%s: couldn't grab keyboard!  (%s)\n",
+                progname, grab_string(status));
     }
+
   status = grab_mouse (si, window, cursor);
   if (status != GrabSuccess)
     {  /* try again in a second */
       sleep (1);
       status = grab_mouse (si, window, cursor);
       if (status != GrabSuccess)
-       fprintf (stderr, "%s: couldn't grab pointer!  (%d)\n",
-                progname, status);
+       fprintf (stderr, "%s: couldn't grab pointer!  (%s)\n",
+                progname, grab_string(status));
     }
 }
 
 void
 ungrab_keyboard_and_mouse (saver_info *si)
 {
-  saver_preferences *p = &si->prefs;
-
-  XUngrabPointer (si->dpy, CurrentTime);
-  XUngrabKeyboard (si->dpy, CurrentTime);
-
-  if (p->debug_p)
-    fprintf(real_stderr, "%s: XungrabPointer / XUngrabKeyboard\n", progname);
+  ungrab_mouse (si);
+  ungrab_kbd (si);
 }
 
 
-void
+/* Prints an error message to stderr and returns True if there is another
+   xscreensaver running already.  Silently returns False otherwise. */
+Bool
 ensure_no_screensaver_running (Display *dpy, Screen *screen)
 {
+  Bool status = 0;
   int i;
   Window root = RootWindowOfScreen (screen);
   Window root2, parent, *kids;
@@ -201,13 +245,14 @@ ensure_no_screensaver_running (Display *dpy, Screen *screen)
          fprintf (stderr,
       "%s: already running on display %s (window 0x%x)\n from process %s.\n",
                   progname, DisplayString (dpy), (int) kids [i], id);
-         exit (1);
+         status = True;
        }
     }
 
   if (kids) XFree ((char *) kids);
   XSync (dpy, False);
   XSetErrorHandler (old_handler);
+  return status;
 }
 
 
@@ -870,8 +915,17 @@ raise_window (saver_info *si,
 
       if (p->verbose_p) fprintf (stderr, "%s: fading... ", progname);
 
-      XGrabServer (si->dpy);
+      XGrabServer (si->dpy);                   /* ############ DANGER! */
 
+      /* Clear the stderr layer on each screen.
+        Grab the mouse on the first screen on which the mouse is grabbable
+        (if there are multiple heads, I think you might only be able to
+        grab the mouse on the screen that currently has the mouse?  Anyway,
+        we only grab the mouse once, and don't try again after the grab
+        has succeeded.)  We grab the mouse on the root window of the screen,
+        not on the screensaver window, since the screensaver window is not
+        yet mapped.
+       */
       for (i = 0; i < si->nscreens; i++)
        {
          saver_screen_info *ssi = &si->screens[i];
@@ -879,8 +933,11 @@ raise_window (saver_info *si,
          /* grab and blacken mouse on the root window (saver not mapped yet)
           */
          if (grabbed != GrabSuccess)
-           grabbed = grab_mouse (si, ssi->screensaver_window,
-                                 (si->demo_mode_p ? 0 : ssi->cursor));
+           {
+             Window root = RootWindowOfScreen(ssi->screen);
+             grabbed = grab_mouse (si, root,
+                                   (si->demo_mode_p ? 0 : ssi->cursor));
+           }
 
          if (!dont_clear || ssi->stderr_overlay_window)
            /* Do this before the fade, since the stderr cmap won't fade
@@ -888,8 +945,11 @@ raise_window (saver_info *si,
            clear_stderr (ssi);
        }
 
+      /* Note!  The server is grabbed, and this will take several seconds
+        to complete! */
       fade_screens (si->dpy, current_maps, current_windows,
                    p->fade_seconds, p->fade_ticks, True, !dont_clear);
+
       free(current_maps);
       free(current_windows);
       current_maps = 0;
@@ -907,9 +967,12 @@ raise_window (saver_info *si,
        }
 #endif /* HAVE_MIT_SAVER_EXTENSION */
 
+      /* If we had successfully grabbed the mouse, let it go now. */
       if (grabbed == GrabSuccess)
-       XUngrabPointer (si->dpy, CurrentTime);
+       ungrab_mouse (si);
+
       XUngrabServer (si->dpy);
+      XSync (si->dpy, False);                  /* ###### (danger over) */
     }
   else
     {
@@ -952,9 +1015,16 @@ blank_screen (saver_info *si)
     }
   store_activate_time (si, si->screen_blanked_p);
   raise_window (si, False, False, False);
-  /* #### */
-  grab_keyboard_and_mouse (si, si->screens[0].screensaver_window,
+
+  /* Note: we do our grabs on the root window, not on the screensaver window.
+     If we grabbed on the saver window, then the demo mode and lock dialog
+     boxes wouldn't get any events.
+   */
+  grab_keyboard_and_mouse (si,
+                          /*si->screens[0].screensaver_window,*/
+                          RootWindowOfScreen(si->screens[0].screen),
                           (si->demo_mode_p ? 0 : si->screens[0].cursor));
+
 #ifdef HAVE_XHPDISABLERESET
   if (si->locked_p && !hp_locked_p)
     {
@@ -998,6 +1068,13 @@ unblank_screen (saver_info *si)
       XGrabServer (si->dpy);                   /* ############ DANGER! */
       XSync (si->dpy, False);
 
+      /* Clear the stderr layer on each screen.
+        Grab the mouse on the first screen on which the mouse is grabbable
+        (if there are multiple heads, I think you might only be able to
+        grab the mouse on the screen that currently has the mouse?  Anyway,
+        we only grab the mouse once, and don't try again after the grab
+        has succeeded.)
+       */
       for (i = 0; i < si->nscreens; i++)
        {
          saver_screen_info *ssi = &si->screens[i];
@@ -1019,8 +1096,10 @@ unblank_screen (saver_info *si)
       current_windows = 0;
 
       if (p->verbose_p) fprintf (stderr, "unfading done.\n");
+
+      /* If we had successfully grabbed the mouse, let it go now. */
       if (grabbed == GrabSuccess)
-       XUngrabPointer (si->dpy, CurrentTime);
+       ungrab_mouse (si);
     }
   else
     {
@@ -1181,7 +1260,50 @@ select_visual (saver_screen_info *ssi, const char *visual_name)
                            ssi->screensaver_window, ssi->screensaver_window);
       store_activate_time (si, True);
 
+
+
+      /* Transfer the grabs from the old window to the new.
+        Actually I think none of this is necessary, since we always
+        hold our grabs on the root window, but I wrote this before
+        re-discovering that...
+       */
+
+
+      /* If we're destroying the window that holds our mouse grab,
+        transfer the grab to the new window.  (Grab the server while
+        so doing, to avoid a race condition.)
+       */
+      if (old_w == si->mouse_grab_window)
+       {
+         XGrabServer (si->dpy);                /* ############ DANGER! */
+         ungrab_mouse(si);
+         grab_mouse(si, ssi->screensaver_window,
+                    (si->demo_mode_p ? 0 : ssi->cursor));
+         XUngrabServer (si->dpy);
+         XSync (si->dpy, False);               /* ###### (danger over) */
+       }
+
+      /* If we're destroying the window that holds our keyboard grab,
+        transfer the grab to the new window.  (Grab the server while
+        so doing, to avoid a race condition.)
+       */
+      if (old_w == si->keyboard_grab_window)
+       {
+         XGrabServer (si->dpy);                /* ############ DANGER! */
+         ungrab_kbd(si);
+         grab_kbd(si, ssi->screensaver_window);
+         XUngrabServer (si->dpy);
+         XSync (si->dpy, False);               /* ###### (danger over) */
+       }
+
+      /* Now we can destroy this window without horking our grabs. */
+
       XDestroyWindow (si->dpy, old_w);
+
+      if (p->verbose_p)
+       fprintf (stderr, "%s: destroyed old saver window 0x%lx.\n",
+                progname, (unsigned long) old_w);
+
       if (old_c &&
          old_c != DefaultColormapOfScreen (ssi->screen) &&
          old_c != ssi->demo_cmap)
index 2d7f3326064d97916b44782cf7530bed434d2e14..8ace1506e486b32ef318ec98c9597f65db571915 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver-command, Copyright (c) 1991-1997
+/* xscreensaver-command, Copyright (c) 1991-1998
  *  by Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * implied warranty.
  */
 
+#define STANDALONE
+
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 
 #include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
 #include <X11/Xproto.h>                /* for CARD32 */
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include <X11/Xutil.h>         /* for XGetClassHint() */
 #include <X11/Xos.h>
-#include <stdlib.h>
+
+#include <X11/Intrinsic.h>     /* only needed to get through xscreensaver.h */
 
 #include "version.h"
 
+#ifdef STANDALONE
+  static char *progname;
+  static Atom XA_VROOT;
+  static Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_TIME;
+#else  /* !STANDALONE */
+# include "xscreensaver.h"
+#endif /* !STANDALONE */
+
+
 #ifdef _VROOT_H_
 ERROR! you must not include vroot.h in this file
 #endif
 
-static char *screensaver_version;
-static char *usage = "usage: %s -<switch>\n\
-\n\
-  This program provides external control of a running xscreensaver process.\n\
-  Version %s, copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>.\n\
-\n\
-  -demo         Enter interactive demo mode.\n\
-  -deactivate   Turns off the screensaver if it is on, as user input would.\n\
-  -activate     Turns it on as if the user had been idle for long enough.\n\
-  -cycle        Stops the current graphics hack and runs a new one.\n\
-  -next         Like either -activate or -cycle, depending on which is more\n\
-                appropriate, except that the screenhack that will be run is\n\
-                the next one in the list of hacks, instead of a randomly-\n\
-                chosen one.  This option could be used for looking at a demo\n\
-                of each of the configured hacks.\n\
-  -prev         Like -next, but goes in the other direction.\n\
-  -exit         Causes the screensaver process to exit.  This is the same as\n\
-                killing the process with `kill', but it's easier, since you\n\
-                don't need to first figure out the pid.  (Note that one\n\
-                must *never* kill xscreensaver with -9!)\n\
-  -restart      Causes the screensaver process to exit and then restart with\n\
-                the same command line arguments.  Do this after you've\n\
-                changed the resource database, to cause the screensaver to\n\
-                notice the changes.\n\
-  -lock         Same as -activate, but with immediate locking.\n\
-  -version      Prints the version of XScreenSaver that is currently running\n\
-                on the display.\n\
-  -time         Prints the time at which the screensaver last activated or\n\
-                deactivated (roughly, how long the user has been idle or\n\
-                non-idle.)\n\
-\n\
-  See the man page for more details.\n\
-  For updates, check http://people.netscape.com/jwz/xscreensaver/\n\
-\n";
-
 static Window
-find_screensaver_window (Display *dpy, char *progname, char **version)
+find_screensaver_window (Display *dpy, char **version)
 {
   int i;
   Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
@@ -89,7 +72,7 @@ find_screensaver_window (Display *dpy, char *progname, char **version)
       char *v;
 
       if (XGetWindowProperty (dpy, kids[i],
-                             XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
+                             XA_SCREENSAVER_VERSION,
                              0, 200, False, XA_STRING,
                              &type, &format, &nitems, &bytesafter,
                              (unsigned char **) &v)
@@ -107,79 +90,21 @@ find_screensaver_window (Display *dpy, char *progname, char **version)
 }
 
 
-#define USAGE() \
- { fprintf (stderr, usage, argv[0], screensaver_version); exit (1); }
-
-int
-main (int argc, char **argv)
+void
+xscreensaver_command (Display *dpy, Atom command)
 {
-  Display *dpy;
-  Window window;
-  int i;
-  int query = 0;
-#define Q_version 1
-#define Q_time    2
-  char *message = 0, *dpyname = 0;
   char *v = 0;
+  Window window = find_screensaver_window (dpy, &v);
 
-  screensaver_version = (char *) malloc (5);
-  memcpy (screensaver_version, screensaver_id + 17, 4);
-  screensaver_version [4] = 0;
-  for (i = 1; i < argc; i++)
-    {
-      char *s = argv [i];
-      int L = strlen (s);
-      if (L < 2) USAGE ();
-      if (!strncmp (s, "-display", L))         dpyname = argv [++i];
-      else if (message) USAGE ()
-      else if (!strncmp (s, "-activate", L))   message = "ACTIVATE";
-      else if (!strncmp (s, "-deactivate", L)) message = "DEACTIVATE";
-      else if (!strncmp (s, "-cycle", L))      message = "CYCLE";
-      else if (!strncmp (s, "-next", L))       message = "NEXT";
-      else if (!strncmp (s, "-prev", L))       message = "PREV";
-      else if (!strncmp (s, "-exit", L))       message = "EXIT";
-      else if (!strncmp (s, "-restart", L))    message = "RESTART";
-      else if (!strncmp (s, "-demo", L))       message = "DEMO";
-      else if (!strncmp (s, "-lock", L))       message = "LOCK";
-      else if (!strncmp (s, "-version", L))    query   = Q_version;
-      else if (!strncmp (s, "-time", L))       query   = Q_time;
-      else USAGE ();
-    }
-  if (!message && !query) USAGE ();
-  if (!dpyname) dpyname = (char *) getenv ("DISPLAY");
-  dpy = XOpenDisplay (dpyname);
-  if (!dpy)
-    {
-      fprintf (stderr, "%s: can't open display %s\n", argv[0],
-              (dpyname ? dpyname : "(null)"));
-      exit (1);
-    }
-  window = find_screensaver_window (dpy, argv[0], &v);
-
-  if (message)
-    {
-      XEvent event;
-      event.xany.type = ClientMessage;
-      event.xclient.display = dpy;
-      event.xclient.window = window;
-      event.xclient.message_type = XInternAtom (dpy, "SCREENSAVER", False);
-      event.xclient.format = 32;
-      event.xclient.data.l[0] = (long) XInternAtom (dpy, message, False);
-      if (! XSendEvent (dpy, window, False, 0L, &event))
-       {
-         fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n", argv [0],
-                  (unsigned int) window);
-         exit (1);
-       }
-    }
-  else if (query)
+  if (command == XA_SCREENSAVER_TIME ||
+      command == XA_SCREENSAVER_VERSION)
     {
       XClassHint hint;
       memset (&hint, 0, sizeof(hint));
       if (!v || !*v)
        {
          fprintf (stderr, "%s: version property not set on window 0x%x?\n",
-                  argv [0], (unsigned int) window);
+                  progname, (unsigned int) window);
          exit (1);
        }
 
@@ -187,13 +112,13 @@ main (int argc, char **argv)
       if (!hint.res_class)
        {
          fprintf (stderr, "%s: class hints not set on window 0x%x?\n",
-                  argv [0], (unsigned int) window);
+                  progname, (unsigned int) window);
          exit (1);
        }
 
       fprintf (stdout, "%s %s", hint.res_class, v);
 
-      if (query != Q_time)
+      if (command != XA_SCREENSAVER_TIME)
        {
          fprintf (stdout, "\n");
        }
@@ -209,8 +134,7 @@ main (int argc, char **argv)
          xgwa.map_state = IsViewable;
          XGetWindowAttributes (dpy, window, &xgwa);
 
-         if (XGetWindowProperty (dpy, window,
-                                 XInternAtom (dpy, "__SWM_VROOT", False),
+         if (XGetWindowProperty (dpy, window, XA_VROOT,
                                  0, 0, False, XA_WINDOW,
                                  &type, &format, &nitems, &bytesafter,
                                  &data)
@@ -222,7 +146,7 @@ main (int argc, char **argv)
          data = 0;
 
          if (XGetWindowProperty (dpy, window,
-                                 XInternAtom (dpy, "_SCREENSAVER_TIME",False),
+                                 XA_SCREENSAVER_TIME,
                                  0, 1, False, XA_INTEGER,
                                  &type, &format, &nitems, &bytesafter,
                                  &data)
@@ -234,9 +158,10 @@ main (int argc, char **argv)
              time_t tt = (time_t) time32;
 
              if (active_p)
-               fprintf (stdout, ": active since ");
+               fprintf (stdout, ": screen blanked since ");
              else
-               fprintf (stdout, ": inactive since ");
+               /* suggestions for a better way to phrase this are welcome. */
+               fprintf (stdout, ": screen non-blanked since ");
              fprintf (stdout, "%s", ctime(&tt));
              if (data) free (data);
            }
@@ -246,15 +171,169 @@ main (int argc, char **argv)
              fprintf (stdout, "\n");
              fflush (stdout);
              fprintf (stderr, "%s: no time on window 0x%x (%s %s).\n",
-                      argv[0], (unsigned int) window,
+                      progname, (unsigned int) window,
                       hint.res_class, (v ? v : "???"));
              exit (1);
            }
        }
     }
-
+  else
+    {
+      XEvent event;
+      event.xany.type = ClientMessage;
+      event.xclient.display = dpy;
+      event.xclient.window = window;
+      event.xclient.message_type = XA_SCREENSAVER;
+      event.xclient.format = 32;
+      event.xclient.data.l[0] = (long) command;
+      if (! XSendEvent (dpy, window, False, 0L, &event))
+       {
+         fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n",
+                  progname, (unsigned int) window);
+         exit (1);
+       }
+    }
   XSync (dpy, 0);
+}
+
+
+\f
+#ifdef STANDALONE
+static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV;
+static Atom XA_EXIT, XA_RESTART, XA_DEMO, XA_LOCK;
+
+static char *progname;
+static char *screensaver_version;
+static char *usage = "\n\
+usage: %s -<switch>\n\
+\n\
+  This program provides external control of a running xscreensaver process.\n\
+  Version %s, copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>.\n\
+\n\
+  The xscreensaver program is a daemon that runs in the background.\n\
+  You control a running xscreensaver process by sending it messages\n\
+  with this program, xscreensaver-command.  See the man pages for\n\
+  details.  These are the arguments understood by xscreensaver-command:\n\
+\n\
+  -demo         Ask the xscreensaver process to enter interactive demo mode.\n\
+\n\
+  -activate     Turn on the screensaver (blank the screen), as if the user\n\
+                had been idle for long enough.\n\
+\n\
+  -deactivate   Turns off the screensaver (un-blank the screen), as if user\n\
+                activity had been detected.\n\
+\n\
+  -cycle        If the screensaver is active (the screen is blanked), then\n\
+                stop the current graphics demo and run a new one (chosen\n\
+                randomly.)\n\
+\n\
+  -next         Like either -activate or -cycle, depending on which is more\n\
+                appropriate, except that the graphics hack that will be run\n\
+                is the next one in the list, instead of a randomly-chosen\n\
+                one.  In other words, repeatedly executing -next will cause\n\
+                the xscreensaver process to invoke each graphics demo\n\
+                sequentially.  (Though using the -demo option is probably\n\
+                an easier way to accomplish that.)\n\
+\n\
+  -prev         Like -next, but goes in the other direction.\n\
+\n\
+  -exit         Causes the xscreensaver process to exit gracefully.  This is\n\
+                roughly the same as killing the process with `kill', but it\n\
+                is easier, since you don't need to first figure out the pid.\n\
+                (Note that one must *never* kill xscreensaver with -9!)\n\
+\n\
+  -restart      Causes the screensaver process to exit and then restart with\n\
+                the same command line arguments as last time.  Do this after\n\
+                you've changed your X resource settings, to cause\n\
+                xscreensaver to notice the changes.\n\
+\n\
+  -lock         Tells the running xscreensaver process to lock the screen\n\
+                immediately.  This is like -activate, but forces locking as\n\
+                well, even if locking is not the default.\n\
+\n\
+  -version      Prints the version of xscreensaver that is currently running\n\
+                on the display -- that is, the actual version number of the\n\
+                running xscreensaver background process, rather than the\n\
+                version number of xscreensaver-command.\n\
+\n\
+  -time         Prints the time at which the screensaver last activated or\n\
+                deactivated (roughly, how long the user has been idle or\n\
+                non-idle -- but not quite, since it only tells you when the\n\
+                screen became blanked or un-blanked.)\n\
+\n\
+  See the man page for more details.\n\
+  For updates, check http://people.netscape.com/jwz/xscreensaver/\n\
+\n";
+
+#define USAGE() \
+ { fprintf (stderr, usage, progname, screensaver_version); exit (1); }
+
+int
+main (int argc, char **argv)
+{
+  Display *dpy;
+  int i;
+  char *dpyname = 0;
+  Atom *cmd = 0;
+
+  progname = argv[0];
+  screensaver_version = (char *) malloc (5);
+  memcpy (screensaver_version, screensaver_id + 17, 4);
+  screensaver_version [4] = 0;
+
+  for (i = 1; i < argc; i++)
+    {
+      const char *s = argv [i];
+      int L;
+      if (s[0] == '-' && s[1] == '-') s++;
+      L = strlen (s);
+      if (L < 2) USAGE ();
+      if (!strncmp (s, "-display", L))         dpyname = argv [++i];
+      else if (cmd) USAGE ()
+      else if (!strncmp (s, "-activate", L))   cmd = &XA_ACTIVATE;
+      else if (!strncmp (s, "-deactivate", L)) cmd = &XA_DEACTIVATE;
+      else if (!strncmp (s, "-cycle", L))      cmd = &XA_CYCLE;
+      else if (!strncmp (s, "-next", L))       cmd = &XA_NEXT;
+      else if (!strncmp (s, "-prev", L))       cmd = &XA_PREV;
+      else if (!strncmp (s, "-exit", L))       cmd = &XA_EXIT;
+      else if (!strncmp (s, "-restart", L))    cmd = &XA_RESTART;
+      else if (!strncmp (s, "-demo", L))       cmd = &XA_DEMO;
+      else if (!strncmp (s, "-lock", L))       cmd = &XA_LOCK;
+      else if (!strncmp (s, "-version", L))    cmd = &XA_SCREENSAVER_VERSION;
+      else if (!strncmp (s, "-time", L))       cmd = &XA_SCREENSAVER_TIME;
+      else USAGE ();
+    }
+  if (!cmd)
+    USAGE ();
+
+  if (!dpyname) dpyname = (char *) getenv ("DISPLAY");
+  dpy = XOpenDisplay (dpyname);
+  if (!dpy)
+    {
+      fprintf (stderr, "%s: can't open display %s\n", progname,
+              (dpyname ? dpyname : "(null)"));
+      exit (1);
+    }
+
+  XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False);
+  XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False);
+  XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False);
+  XA_SCREENSAVER_TIME = XInternAtom (dpy, "_SCREENSAVER_TIME", False);
+  XA_ACTIVATE = XInternAtom (dpy, "ACTIVATE", False);
+  XA_DEACTIVATE = XInternAtom (dpy, "DEACTIVATE", False);
+  XA_RESTART = XInternAtom (dpy, "RESTART", False);
+  XA_CYCLE = XInternAtom (dpy, "CYCLE", False);
+  XA_NEXT = XInternAtom (dpy, "NEXT", False);
+  XA_PREV = XInternAtom (dpy, "PREV", False);
+  XA_EXIT = XInternAtom (dpy, "EXIT", False);
+  XA_DEMO = XInternAtom (dpy, "DEMO", False);
+  XA_LOCK = XInternAtom (dpy, "LOCK", False);
+
+  xscreensaver_command(dpy, *cmd);
+
   fflush (stdout);
   fflush (stderr);
   exit (0);
 }
+
+#endif /* STANDALONE */
index 1416fe8cd83ace5eb90edcf9959040e07598a209..cc3de5869511073732e9aac68204db1894805b1e 100644 (file)
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "31-May-97" "X Version 11"
+.TH XScreenSaver 1 "15-Jun-98 (2.21)" "X Version 11"
 .SH NAME
 xscreensaver-command - control a running xscreensaver process
 .SH SYNOPSIS
 .B xscreensaver-command
-[\-help] [\-demo] [\-activate] [\-deactivate] [\-lock] [\-cycle] [\-next] [\-prev] [\-exit] [\-restart] [\-version] [\-time]
+[\-help] \
+[\-demo] \
+[\-activate] \
+[\-deactivate] \
+[\-cycle] \
+[\-next] \
+[\-prev] \
+[\-exit] \
+[\-restart] \
+[\-lock] \
+[\-version] \
+[\-time]
 .SH DESCRIPTION
 The \fIxscreensaver\-command\fP program controls a running \fIxscreensaver\fP
 process by sending it client-messages.
+
+.BR xscreensaver (1)
+has a client-server model: the xscreensaver process is a
+daemon that runs in the background; it is controlled by the 
+foreground \fIxscreensaver-command\fP program.
 .SH OPTIONS
 .I xscreensaver-command
-accepts the following options:
+accepts the following command-line options:
 .TP 8
 .B \-help
 Prints a brief summary of command-line options.
 .TP 8
 .B \-demo
 Cause the screensaver to enter its interactive demo mode, in which one
-can experiment with the various graphics hacks available.  See 
+can experiment with the various graphics hacks available.  See
 .BR xscreensaver (1)
 for details.
 .TP 8
 .B \-activate
-Tell the screensaver to turn on immediately (that is, pretend that the 
-user been idle for long enough.)  It will turn off as soon as there is
-any user activity, as usual.
+Tell xscreensaver to turn on immediately (that is, blank the screen, as if
+the user had been idle for long enough.)  The screensaver will deactivate as
+soon as there is any user activity, as usual.
 
 It is useful to run this from a menu; you may wish to run it as
 .EX
 sleep 5 ; xscreensaver-command -activate
 .EE
 to be sure that you have time to remove your hand from the mouse before
-the screensaver comes on.
+the screensaver comes on.  (Because if you jiggle the mouse, xscreensaver
+will notice, and deactivate.)
 .TP 8
 .B \-deactivate
-Tell the screensaver to turn off, as if there had been user activity.
+If the screensaver is active (the screen is blanked), this command will
+deactivate it just as if there had been keyboard or mouse activity.  
 If locking is enabled, then the screensaver will prompt for a password
 as usual.
 .TP 8
-.B \-lock
-Like \fI\-activate\fP, but a password will be required before the screensaver
-turns off, even if the screensaver's \fIlock\fP resource is false.  The 
-display will be locked immediately even if the screensaver's \fIlockTimeout\fP
-resource is non-zero.
-.TP 8
 .B \-cycle
-Tell the screensaver to change which graphics hack it is running, just
-as if the ``cycle'' timer had expired.  A new hack will be chosen randomly.
+If the screensaver is active (the screen is blanked), then stop the current
+graphics demo and run a new one (chosen randomly.)
 .TP 8
 .B \-next
 This is like either \fI\-activate\fP or \fI\-cycle\fP, depending on which is
-more appropriate, except that the screenhack that will be run is the next
-one in the list of programs, instead of a randomly-chosen one.  Repeatedly
-executing this will cycle through each hack in turn (though using 
-the \fI\-demo\fP option is probably an easier way to accomplish that.)
+more appropriate, except that the graphics hack that will be run is the next
+one in the list, instead of a randomly-chosen one.  In other words, 
+repeatedly executing -next will cause the xscreensaver process to invoke each
+graphics demo sequentially.  (Though using the \fI\-demo\fP option is probably
+an easier way to accomplish that.)
 .TP 8
 .B \-prev
 This is like \fI\-next\fP, but cycles in the other direction.
 .TP 8
 .B \-exit
-Causes the screensaver process to exit gracefully.  This is a safer and
-easier way to kill the screensaver than by using \fIkill\fP.  
+Causes the xscreensaver process to exit gracefully.  This is roughly the same
+as killing the process with
+.BR kill (1),
+but it is easier, since you don't need to first figure out the pid.  
 
 .B Warning:
 never use \fIkill -9\fP with \fIxscreensaver\fP while the screensaver is
@@ -82,26 +97,32 @@ manager to repair the damage.
 .TP 8
 .B \-restart
 Causes the screensaver process to exit and then restart with the same command
-line arguments.  This is a good way of causing the screensaver to re-read the
-resource database.
+line arguments as last time.  Do this after you've changed the resource
+database, to cause xscreensaver to notice the changes.
 
 If the screensaver is run from \fIxdm(1)\fP (that is, it is already running
-before you log in) then you may want to issue the ``restart'' command from 
+before you log in) then you may want to issue the \fI\-restart\fP command from
 one of your startup scripts, so that the screensaver gets your resource
 settings instead of the default ones.
 .TP 8
+.B \-lock
+Tells the running xscreensaver process to lock the screen immediately.  
+This is like \fI\-activate\fP, but forces locking as well, even if locking
+is not the default (that is, even if xscreensaver's \fIlock\fP resource is
+false, and even if the \fIlockTimeout\fP resource is non-zero.)
+.TP 8
 .B \-version
-Print (on stdout) the version number of the xscreensaver program that is 
-running on $DISPLAY.  (To see the version number of \fIxscreensaver-command\fP
-itself, use the \fI\-help\fP option.)
+Prints the version of xscreensaver that is currently running on the display:
+that is, the actual version number of the running xscreensaver background 
+process, rather than the version number of xscreensaver-command.  (To see
+the version number of \fIxscreensaver-command\fP itself, use 
+the \fI\-help\fP option.)
 .TP 8
 .B \-time
-This option prints on stdout the time at which the screensaver last activated
-(blanked the screen) or deactivated (restored the screen.)  Note that the
-activation-time is not the last time at which the user was active, but is
-some time later (it is the time at which either: xscreensaver decided that
-the user has been idle long enough; or, the user explicitly activated the
-screensaver or locker.)
+Prints the time at which the screensaver last activated or 
+deactivated (roughly, how long the user has been idle or non-idle: but 
+not quite, since it only tells you when the screen became blanked or
+un-blanked.)
 .SH ENVIRONMENT
 .PP
 .TP 8
@@ -113,6 +134,11 @@ to be manipulated.
 to find the executable to restart (for the \fI\-restart\fP command).  
 Note that this variable is consulted in the environment of 
 the \fIxscreensaver\fP process, not the \fIxscreensaver-command\fP process.
+.SH UPGRADES
+The latest version of
+.BR xscreensaver (1)
+and \fIxscreensaver\-command\fP can always be found at 
+http://people.netscape.com/jwz/xscreensaver/
 .SH "SEE ALSO"
 .BR X (1),
 .BR xscreensaver (1)
@@ -121,12 +147,15 @@ Some diagnostics are reported on the stderr of the \fIxscreensaver\fP
 process, not this process, so the caller of \fIxscreensaver-command\fP
 may not see the error messages.
 .SH COPYRIGHT
-Copyright \(co 1992, 1993, 1997 by Jamie Zawinski.  
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting documentation.  No
-representations are made about the suitability of this software for any
-purpose.  It is provided "as is" without express or implied warranty.
+Copyright \(co 1992, 1993, 1997, 1998
+by Jamie Zawinski.  Permission to use, copy, modify, distribute, and sell
+this software and its documentation for any purpose is hereby granted without
+fee, provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in supporting
+documentation.  No representations are made about the suitability of this
+software for any purpose.  It is provided "as is" without express or implied
+warranty.
 .SH AUTHOR
 Jamie Zawinski <jwz@netscape.com>, 13-aug-92.
+
+Please let me know if you find any bugs or make any improvements.
index 07633112d2a4022bea5c30c8fcd6d68f48f3b8f6..7f4b0bd8a816a99b39582ba3c61248fc34ac85ce 100644 (file)
@@ -158,7 +158,6 @@ char *progclass = 0;
 XrmDatabase db = 0;
 
 
-static Atom XA_SCREENSAVER;
 static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV;
 static Atom XA_EXIT, XA_RESTART, XA_DEMO, XA_LOCK;
 
@@ -166,10 +165,10 @@ static Atom XA_EXIT, XA_RESTART, XA_DEMO, XA_LOCK;
 static XrmOptionDescRec options [] = {
   { "-timeout",                   ".timeout",          XrmoptionSepArg, 0 },
   { "-cycle",             ".cycle",            XrmoptionSepArg, 0 },
-  { "-idelay",            ".initialDelay",     XrmoptionSepArg, 0 },
-  { "-nice",              ".nice",             XrmoptionSepArg, 0 },
-  { "-visual",            ".visualID",         XrmoptionSepArg, 0 },
+  { "-lock-mode",         ".lock",             XrmoptionNoArg, "on" },
+  { "-no-lock-mode",      ".lock",             XrmoptionNoArg, "off" },
   { "-lock-timeout",      ".lockTimeout",      XrmoptionSepArg, 0 },
+  { "-visual",            ".visualID",         XrmoptionSepArg, 0 },
   { "-install",                   ".installColormap",  XrmoptionNoArg, "on" },
   { "-no-install",        ".installColormap",  XrmoptionNoArg, "off" },
   { "-verbose",                   ".verbose",          XrmoptionNoArg, "on" },
@@ -180,8 +179,8 @@ static XrmOptionDescRec options [] = {
   { "-no-mit-extension",   ".mitSaverExtension",XrmoptionNoArg, "off" },
   { "-sgi-extension",     ".sgiSaverExtension",XrmoptionNoArg, "on" },
   { "-no-sgi-extension",   ".sgiSaverExtension",XrmoptionNoArg, "off" },
-  { "-lock",              ".lock",             XrmoptionNoArg, "on" },
-  { "-no-lock",                   ".lock",             XrmoptionNoArg, "off" }
+  { "-idelay",            ".initialDelay",     XrmoptionSepArg, 0 },
+  { "-nice",              ".nice",             XrmoptionSepArg, 0 }
 };
 
 static char *defaults[] = {
@@ -198,29 +197,29 @@ The standard Xt command-line options are accepted; other options include:\n\
 \n\
     -timeout <minutes>         When the screensaver should activate.\n\
     -cycle <minutes>           How long to let each hack run.\n\
-    -idelay <seconds>          How long to sleep before startup.\n\
+    -lock-mode                 Require a password before deactivating.\n\
+    -no-lock-mode              Don't.\n\
+    -lock-timeout <minutes>    Grace period before locking; default 0.\n\
     -visual <id-or-class>      Which X visual to run on.\n\
-    -demo                      Enter interactive demo mode on startup.\n\
     -install                   Install a private colormap.\n\
     -no-install                Don't.\n\
     -verbose                   Be loud.\n\
     -silent                    Don't.\n\
-    -xidle-extension           Use the R5 XIdle server extension.\n\
-    -no-xidle-extension        Don't.\n\
     -mit-extension             Use the R6 MIT_SCREEN_SAVER server extension.\n\
     -no-mit-extension          Don't.\n\
     -sgi-extension             Use the SGI SCREEN-SAVER server extension.\n\
     -no-sgi-extension          Don't.\n\
-    -lock                      Require a password before deactivating.\n\
-    -no-lock                   Don't.\n\
-    -lock-timeout <minutes>    Grace period before locking; default 0.\n\
+    -xidle-extension           Use the R5 XIdle server extension.\n\
+    -no-xidle-extension        Don't.\n\
     -help                      This message.\n\
 \n\
-Use the `xscreensaver-command' program to control a running screensaver.\n\
+The `xscreensaver' program should be left running in the background.\n\
+Use the `xscreensaver-command' program to manipulate a running xscreensaver.\n\
+\n\
+The `*programs' resource controls which graphics demos will be launched by\n\
+the screensaver.  See `man xscreensaver' or the web page for more details.\n\
 \n\
-The *programs resource controls which graphics demos will be launched by the\n\
-screensaver.  See the man page for more details.  For updates, check\n\
-http://people.netscape.com/jwz/xscreensaver/\n\n",
+For updates, check http://people.netscape.com/jwz/xscreensaver/\n\n",
          si->version);
 
 #ifdef NO_LOCKING
@@ -299,7 +298,7 @@ get_screenhacks (saver_info *si)
 
   d = get_string_resource ("programs", "Programs");
 
-  size = strlen (d);
+  size = d ? strlen (d) : 0;
   p->screenhacks = (char **) malloc (sizeof (char *) * hacks_size);
   p->screenhacks_count = 0;
 
@@ -541,6 +540,8 @@ initialize_connection (saver_info *si, int argc, char **argv)
   si->db = XtDatabase (si->dpy);
   XtGetApplicationNameAndClass (si->dpy, &progname, &progclass);
 
+  if(strlen(progname)  > 100) progname [99] = 0;  /* keep it short. */
+
   db = si->db; /* resources.c needs this */
 
   if (argc == 2 && !strcmp (argv[1], "-help"))
@@ -551,7 +552,39 @@ initialize_connection (saver_info *si, int argc, char **argv)
 
   else if (argc > 1)
     {
-      fprintf (stderr, "%s: unknown option %s\n", progname, argv [1]);
+      const char *s = argv[1];
+      fprintf (stderr, "%s: unknown option \"%s\".  Try \"-help\".\n",
+              progname, s);
+
+      if (s[0] == '-' && s[1] == '-') s++;
+      if (!strcmp (s, "-activate") ||
+         !strcmp (s, "-deactivate") ||
+         !strcmp (s, "-cycle") ||
+         !strcmp (s, "-next") ||
+         !strcmp (s, "-prev") ||
+         !strcmp (s, "-exit") ||
+         !strcmp (s, "-restart") ||
+         !strcmp (s, "-demo") ||
+         !strcmp (s, "-lock") ||
+         !strcmp (s, "-version") ||
+         !strcmp (s, "-time"))
+       {
+         fprintf (stderr, "\n\
+    However, %s is an option to the `xscreensaver-command' program.\n\
+    The `xscreensaver' program is a daemon that runs in the background.\n\
+    You control a running xscreensaver process by sending it messages\n\
+    with `xscreensaver-command'.  See the man pages for details,\n\
+    or check the web page: http://people.netscape.com/jwz/xscreensaver/\n\n",
+                  s);
+
+         /* Since version 1.21 renamed the "-lock" option to "-lock-mode",
+            suggest that explicitly. */
+         if (!strcmp (s, "-lock"))
+           fprintf (stderr, "\
+    Or perhaps you meant either the \"-lock-mode\" or the\n\
+    \"-lock-timeout <minutes>\" options to xscreensaver?\n\n");
+       }
+
       exit (1);
     }
   get_resources (si);
@@ -621,6 +654,8 @@ initialize (saver_info *si, int argc, char **argv)
   si->version [4] = 0;
   progname = argv[0]; /* reset later; this is for the benefit of lock_init() */
 
+  if(strlen(progname) > 100) progname[99] = 0;  /* keep it short. */
+
 #ifdef NO_LOCKING
   si->locking_disabled_p = True;
   si->nolock_reason = "not compiled with locking support";
@@ -644,9 +679,9 @@ initialize (saver_info *si, int argc, char **argv)
 
   progclass = "XScreenSaver";
 
-  /* remove -demo switch before saving argv */
+  /* remove -initial-demo-mode switch before saving argv */
   for (i = 1; i < argc; i++)
-    while (!strcmp ("-demo", argv [i]))
+    while (!strcmp ("-initial-demo-mode", argv [i]))
       {
        int j;
        initial_demo_mode_p = True;
@@ -666,7 +701,8 @@ initialize (saver_info *si, int argc, char **argv)
 
   
   for (i = 0; i < si->nscreens; i++)
-    ensure_no_screensaver_running (si->dpy, si->screens[i].screen);
+    if (ensure_no_screensaver_running (si->dpy, si->screens[i].screen))
+      exit (1);
 
   si->demo_mode_p = initial_demo_mode_p;
   srandom ((int) time ((time_t *) 0));
index 1082c46050fe0aa5769c78976ef122242595bb28..347963a8cd211a07a1274c0616f4d904a01d7677 100644 (file)
@@ -112,6 +112,8 @@ struct saver_info {
      ======================================================================= */
 
   Bool screen_blanked_p;       /* Whether the saver is currently active. */
+  Window mouse_grab_window;    /* Window holding our mouse grab */
+  Window keyboard_grab_window; /* Window holding our keyboard grab */
 
 
   /* =======================================================================
@@ -124,7 +126,6 @@ struct saver_info {
   Bool dbox_up_p;              /* Whether the demo-mode or passwd dialogs
                                   are currently visible */
 
-
   /* =======================================================================
      demoing
      ======================================================================= */
@@ -134,6 +135,15 @@ struct saver_info {
                                   dialog box, which should be run next. */
 
 
+  /* =======================================================================
+     asking questions
+     ======================================================================= */
+
+  Bool question_up_p;          /* Whether the question dialog is currently
+                                  visible. */
+  Widget question_dialog;      /* The question dialog, if any. */
+
+
   /* =======================================================================
      timers
      ======================================================================= */
@@ -248,7 +258,7 @@ struct saver_screen_info {
 
 extern void restore_real_vroot (saver_info *si);
 extern void disable_builtin_screensaver (saver_info *si, Bool turn_off_p);
-extern void ensure_no_screensaver_running (Display *, Screen *);
+extern Bool ensure_no_screensaver_running (Display *, Screen *);
 
 #ifdef HAVE_MIT_SAVER_EXTENSION
 extern Bool query_mit_saver_extension (saver_info *);
@@ -370,7 +380,7 @@ extern Bool window_exists_p (Display *dpy, Window window);
 extern char *timestring (void);
 
 extern Atom XA_VROOT, XA_XSETROOT_ID;
-extern Atom XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID;
+extern Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID;
 extern Atom XA_SCREENSAVER_TIME;
 
 #endif /* __XSCREENSAVER_H__ */
index 54cc9ee4ff885a93ae5497724b44a5f4f8caa95d..ce5756bb6b5b8c59a7e0917994d95430e8aec24a 100644 (file)
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "16-Jan-98" "X Version 11"
+.TH XScreenSaver 1 "15-Jun-98 (2.21)" "X Version 11"
 .SH NAME
 xscreensaver - graphics hack and screen locker, launched when the user is idle
 .SH SYNOPSIS
 .B xscreensaver
-[\-display \fIhost:display.screen\fP] [\-timeout \fIint\fP] [\-cycle \fIint\fP] [\-nice \fIint\fP] [\-lock] [\-no\-lock] [\-lock\-timeout \fIint\fP] [\-demo] [\-visual \fIvisual\fP] [\-install] [\-no\-install] [\-verbose] [\-silent] [\-xidle\-extension] [\-no\-xidle\-extension] [\-sgi\-extension] [\-no\-sgi\-extension] [\-mit\-extension] [\-no\-mit\-extension] [\-xrm \fIresources\fP]
+[\-display \fIhost:display.screen\fP] \
+[\-timeout \fIint\fP] \
+[\-cycle \fIint\fP] \
+[\-lock\-mode] \
+[\-no\-lock\-mode] \
+[\-lock\-timeout \fIint\fP] \
+[\-visual \fIvisual\fP] \
+[\-install] \
+[\-no\-install] \
+[\-verbose] \
+[\-silent] \
+[\-nice \fIint\fP] \
+[\-mit\-extension] \
+[\-no\-mit\-extension] \
+[\-sgi\-extension] \
+[\-no\-sgi\-extension] \
+[\-xidle\-extension] \
+[\-no\-xidle\-extension] \
+[\-xrm \fIresources\fP]
 .SH DESCRIPTION
 The \fIxscreensaver\fP program waits until the keyboard and mouse have been 
 idle for a period, and then runs a graphics demo chosen at random.  It 
@@ -36,11 +54,19 @@ mode.
 .SH GETTING STARTED
 For the impatient, try this:
 .EX
-        xscreensaver &
-        xscreensaver-command -demo
+xscreensaver &
+xscreensaver-command -demo
 .EE
 After a few seconds, the screen should go black, and a dialog box should
 appear in the upper right corner.  This is \fIDemo Mode\fP.
+
+.B Note:
+unlike
+.BR xlock (1),
+xscreensaver has a client-server model: the xscreensaver process is a
+daemon that runs in the background; it is controlled by the foreground
+.BR xscreensaver-command (1)
+program.
 .SH DEMO MODE
 If \fIxscreensaver\fP receives the \fBDEMO\fP ClientMessage, which is done
 by running the
@@ -72,13 +98,13 @@ the bottom.
 .B Run Previous
 Opposite of Run Next; at the top, it scrolls around to the bottom.
 .TP 8
-.B Edit Parameters
+.B Preferences
 This pops up a second dialog box, in which you have the option to 
 interactively change most of the screensaver's operational parameters,
 such as its timeouts, and whether it should lock the screen.  Changing 
-these parameters here will affect only the running \fIxscreensaver\fP 
+these parameters here will affect only the running \fIxscreensaver\fP
 process; to make the changes permanent, you need to edit your X resource
-file.  (See below.)
+file.  (See the \fIConfiguration\fP section, below.)
 .TP 8
 .B Exit Demo Mode
 Returns to normal screensaver operation.
@@ -90,60 +116,79 @@ and then restart itself with the same command-line arguments.  This is just
 like the \fI\-restart\fP argument to 
 .BR xscreensaver\-command (1)
 except that when executed from this button, the screensaver will 
-automatically return to demo mode after restarting.
-.SH OPTIONS
-.I xscreensaver
-accepts the following command line options:
+automatically return to Demo Mode after restarting.
+.SH CONFIGURATION
+\fIxscreensaver\fP understands the following X resources.  The best way
+to specify these parameters is to set them in your X resource file, 
+which is usually called \fI~/.Xdefaults\fP.  For example, to set the
+default value of the \fItimeout\fP resource, you would add the following
+line to your .Xdefaults file:
+.EX
+xscreensaver.timeout: 5
+.EE
+To make the system notice this change, you might also need to run
+.BR xrdb (1):
+.EX
+xrdb < ~/.Xdefaults
+.EE
+And if xscreensaver was already running, and you would like it to notice
+your changes, you'll also have to tell the running xscreensaver process
+to re-initialize itself, like so:
+.EX
+xscreensaver-command -restart
+.EE
+If you want to set the system-wide defaults, then make your edits to
+the xscreensaver app-defaults file, which should have been installed
+when xscreensaver itself was installed.  The app-defaults file will
+usually be named /usr/lib/X11/app-defaults/XScreenSaver, but different
+systems might keep it in a different place (for example,
+/usr/openwin/lib/app-defaults/XScreenSaver on Solaris.)
+.PP
 .TP 8
-.B \-timeout \fIminutes\fP
-The screensaver will activate after the keyboard and mouse have been idle
-for this many minutes.  Default 10.
+.B timeout\fP (class \fBTime\fP)
+The screensaver will activate (blank the screen) after the keyboard and
+mouse have been idle for this many minutes.  Default 10 minutes.
 .TP 8
-.B \-cycle \fIminutes\fP
+.B cycle\fP (class \fBTime\fP)
 After the screensaver has been running for this many minutes, the currently
-running graphics hack sub-process will be killed (with \fBSIGTERM\fP), and a
-new one started.  If this is 0, then the graphics hack will not be changed:
+running graphics-hack sub-process will be killed (with \fBSIGTERM\fP), and a
+new one started.  If this is 0, then the graphics hack will never be changed:
 only one demo will run until the screensaver is deactivated by user activity.
-Default 10.
+Default 10 minutes.
 .TP 8
-.B \-nice \fIinteger\fP
-The sub-processes created by \fIxscreensaver\fP will be ``niced'' to this
-level, so that they are given lower priority than other processes on the
-system, and don't increase the load unnecessarily.  The default is 20.  
-
-(Higher numbers mean lower priority; see 
-.BR nice (1)
-for details.)
-.TP 8
-.B \-lock
-Enable locking: before the screensaver will turn off, it requires you to
-type the password of the person who launched the screensaver, or the root
-password.  (Note: this doesn't work if the screensaver is launched
-by
+.B lock\fP (class \fBBoolean\fP)
+Enable locking: before the screensaver will turn off, it will require you 
+to type the password of the logged-in user (really, the person who ran
+xscreensaver), or the root password.  (\fBNote:\fP this doesn't work if the
+screensaver is launched by
 .BR xdm (1)
-because it can't know the user-id of the logged-in user.)
+because it can't know the user-id of the logged-in user.  See 
+the ``\fIUsing XDM(1)\fP'' section, below.
 .TP 8
-.B \-no\-lock
-Disable locking.  This is the default.
-.TP 8
-.B \-lock\-timeout \fIminutes\fP
-This is how long after the screensaver activates that locking is enabled.
+.B lockTimeout\fP (class \fBTime\fP)
+If locking is enabled, this controls the length of the ``grace period''
+between when the screensaver activates, and when the screen becomes locked.
 For example, if this is 5, and \fI\-timeout\fP is 10, then after 10 minutes,
 the screen would blank.  If there was user activity at 12 minutes, no password
-would be required.  But, if there was user activity at 15 minutes or later 
-(\fI\-lock\-timeout\fP minutes after activation) then a password would be
-required.  The default is 0, meaning that if locking is enabled, then
-a password will be required as soon as the screensaver activates.
-.TP 8
-.B \-demo
-Enter the interactive demo mode immediately after startup.  Normally
-demo mode is invoked via the
-.BR xscreensaver\-command (1)
-program, but this is a shortcut for new users.  See below for a description
-of how demo-mode works.
+would be required to un-blank the screen.  But, if there was user activity
+at 15 minutes or later (that is, \fI\-lock\-timeout\fP minutes after 
+activation) then a password would be required.  The default is 0, meaning
+that if locking is enabled, then a password will be required as soon as the 
+screen blanks.
 .TP 8
-.B \-visual \fIvisual\fP
-Specify which X visual to use by default.  Legal values are:
+.B passwdTimeout\fP (class \fBTime\fP)
+If the screen is locked, then this is how many seconds the password dialog box
+should be left on the screen before giving up (default 30 seconds.)  This
+should not be too large: the X server is grabbed for the duration that the
+password dialog box is up (for security purposes) and leaving the server 
+grabbed for too long can cause problems.
+.TP 8
+.B visualID\fP (class \fBVisualID\fP)
+Specify which X visual to use by default.  (Note carefully that this resource
+is called \fBvisualID\fP, not merely \fBvisual\fP; if you set the \fBvisual\fP
+resource instead, things will malfunction in obscure ways for obscure reasons.)
+
+Legal values for the \fBVisualID\fP resource are:
 .RS 8
 .TP 8
 .B default
@@ -186,7 +231,7 @@ be used: the visual used may be overridden on a program-by-program basis.
 See the description of the \fBprograms\fP resource, below.
 .RE
 .TP 8
-.B \-install
+.B installColormap\fP (class \fBBoolean\fP)
 Install a private colormap while the screensaver is active, so that the
 graphics hacks can get as many colors as possible.  This is the 
 default.  (This only applies when the screen's default visual is being
@@ -194,81 +239,51 @@ used, since non-default visuals get their own colormaps automatically.)
 This can also be overridden on a per-hack basis: see the discussion of
 the \fBdefault\-n\fP name in the section about the \fBprograms\fP resource.
 .TP 8
-.B \-no\-install
-Use the default colormap.
-.TP 8
-.B \-verbose
-Print diagnostics.
-.TP 8
-.B \-silent
-
-.TP 8
-.B \-xidle\-extension
-Use the \fBXIDLE\fP server extension to decide whether the user is idle.
-This is the default if \fIxscreensaver\fP has been compiled with support
-for this extension.  On X11R4 or X11R5 systems, the XIdle method is faster 
-and more reliable than what will be done otherwise, so use it if you can.
-.TP 8
-.B \-no\-xidle\-extension
-Don't use the \fBXIDLE\fP server extension.
-.TP 8
-.B \-sgi\-extension
-Use the SGI \fBSCREEN_SAVER\fP server extension to decide whether the user
-is idle.  This is the default if \fIxscreensaver\fP has been compiled with
-support for this extension (which is the default on SGI systems.).  If it
-is available, the \fBSCREEN_SAVER\fP method is faster and more reliable than
-what will be done otherwise, so use it if you can.
-.TP 8
-.B \-no\-sgi\-extension
-Don't use the SGI \fBSCREEN_SAVER\fP server extension.
-.TP 8
-.B \-mit\-extension
-Use the \fBMIT\-SCREEN\-SAVER\fP server extension to decide whether the user
-is idle.  This is the default if \fIxscreensaver\fP has been compiled with
-support for this extension.  However, this extension is flaky, so it's use 
-is not really recommended.  (It also makes the \fIfade\fP option not work
-properly.)
-.TP 8
-.B \-no\-mit\-extension
-Don't use the \fBMIT\-SCREEN\-SAVER\fP server extension.
-.SH X RESOURCES
-\fIxscreensaver\fP understands the following resources:
-.PP
-.TP 8
-.B timeout\fP (class \fBTime\fP)
-Same as the \fI\-timeout\fP command-line option.  Default 10 minutes.
-.TP 8
-.B cycle\fP (class \fBTime\fP)
-Same as the \fI\-cycle\fP command-line option.  Default 10 minutes.
+.B verbose\fP (class \fBBoolean\fP)
+Whether to print diagnostics.  Default false.
 .TP 8
 .B nice\fP (class \fBNice\fP)
-Same as the \fI\-nice\fP command-line option.  Default 10.
-.TP 8
-.B lock\fP (class \fBBoolean\fP)
-Same as the \fI\-lock\fP command-line option.
-.TP 8
-.B lockTimeout\fP (class \fBTime\fP)
-Same as the \fI\-lock\-timeout\fP command-line option.
-.TP 8
-.B passwdTimeout\fP (class \fBTime\fP)
-If the screen is locked, then this is how many seconds the password dialog box
-should be left on the screen before giving up (default 30.)  This should not
-be too large: the X server is grabbed for the duration that the password
-dialog box is up (for security purposes) and leaving the server grabbed for
-too long can cause problems.
-.TP 8
-.B verbose\fP (class \fBBoolean\fP)
-Same as the \fI\-verbose\fP command-line option.
+The sub-processes created by \fIxscreensaver\fP will be ``niced'' to this
+level, so that they are given lower priority than other processes on the
+system, and don't increase the load unnecessarily.  The default is 20.  
+
+(Higher numbers mean lower priority; see 
+.BR nice (1)
+for details.)
 .TP 8
-.B xidle\fP (class \fBBoolean\fP)
-Same as the \fI\-xidle\fP command-line option.
+.B sgiSaverExtension\fP (class \fBBoolean\fP)
+There are a number of different X server extensions which can make
+xscreensaver's job easier.  The next few resources specify whether these
+extensions should be utilized if they are available.
+
+This resource controls whether the SGI \fBSCREEN_SAVER\fP server extension
+will be used to decide whether the user is idle.  This is the default 
+if \fIxscreensaver\fP has been compiled with support for this 
+extension (which is the default on SGI systems.).  If it is available, 
+the \fBSCREEN_SAVER\fP method is faster and more reliable than what will
+be done otherwise, so use it if you can.  (This extension is only available
+on Silicon Graphics systems, unfortunately.)
+.TP 8
+.B mitSaverExtension\fP (class \fBBoolean\fP)
+This resource controls whether the \fBMIT\-SCREEN\-SAVER\fP server extension
+will be used to decide whether the user is idle.  However, the default for
+this resource is \fIfalse\fP, because even if this extension is available,
+it is flaky (and it also makes the \fBfade\fP option not work properly.)
+Use of this extension is not recommended.
+.TP 8
+.B xidleExtension\fP (class \fBBoolean\fP)
+This resource controls whether the \fBXIDLE\fP server extension will be
+used to decide whether the user is idle.  This is the default 
+if \fIxscreensaver\fP has been compiled with support for this extension.
+(This extension is only available for X11R4 and X11R5 systems, unfortunately.)
 .TP 8
 .B fade\fP (class \fBBoolean\fP)
 If this is true, then when the screensaver activates, the current contents
 of the screen will fade to black instead of simply winking out.  This only
 works on displays with writable colormaps, that is, if the screen's default
-visual is a PseudoColor visual.  Default true.  A fade will also be done when
+visual is a PseudoColor visual.  A fade will also be done when
 switching graphics hacks (when the \fIcycle\fP timer expires.)
+Default: true.  
 .TP 8
 .B unfade\fP (class \fBBoolean\fP)
 If this is true, then when the screensaver deactivates, the original contents
@@ -278,7 +293,7 @@ as well.  Default false.
 .TP 8
 .B fadeSeconds\fP (class \fBTime\fP)
 If \fIfade\fP is true, this is how long the fade will be in 
-seconds (default 3.)
+seconds (default 3 seconds.)
 .TP 8
 .B fadeTicks\fP (class \fBInteger\fP)
 If \fIfade\fP is true, this is how many times a second the colormap will
@@ -286,19 +301,13 @@ be changed to effect a fade.  Higher numbers yield smoother fades, but
 may make the fades take longer than the specified \fIfadeSeconds\fP if
 your server isn't fast enough to keep up.  Default 20.
 .TP 8
-.B visualID\fP (class \fBVisualID\fP)
-Same as the \fI\-visual\fP command-line option.  Default \fBdefault\fP.
-.TP 8
-.B installColormap\fP (class \fBBoolean\fP)
-Same as the \fI\-install\fP command-line option.  Default true.
-.TP 8
 .B captureStderr\fP (class \fBBoolean\fP)
 Whether \fIxscreensaver\fP should redirect its standard-error stream to the
 window itself.  Since its nature is to take over the screen, you would not
-normally see error messages generated by the screensaver or the programs it
+normally see error messages generated by xscreensaver or the sub-programs it
 runs; this resource will cause the output of all relevant programs to be
-drawn on the screensaver window itself instead of written to the controlling
-terminal of the screensaver driver process.  Default true.
+drawn on the screensaver window itself, as well as being written to the
+controlling terminal of the screensaver driver process.  Default true.
 .TP 8
 .B captureStdout\fP (class \fBBoolean\fP)
 Like \fBcaptureStderr\fP but for the standard-output stream.  Default true.
@@ -308,18 +317,18 @@ The font used for the stdout/stderr text, if \fBcaptureStdout\fP or
 \fBcaptureStderr\fP are true.  Default \fB*\-medium\-r\-*\-140\-*\-m\-*\fP
 (a 14 point fixed-width font.)
 .TP 8
-.B textForeground\fP (class \fBForeground\fP)
+.B overlayTextForeground\fP (class \fBForeground\fP)
 The foreground color used for the stdout/stderr text, if \fBcaptureStdout\fP 
 or \fBcaptureStderr\fP are true.  Default: Yellow.
 .TP 8
-.B textBackground\fP (class \fBBackground\fP)
+.B overlayTextBackground\fP (class \fBBackground\fP)
 The background color used for the stdout/stderr text, if \fBcaptureStdout\fP 
 or \fBcaptureStderr\fP are true.  Default: Black.
 .TP 8
 .B programs\fP (class \fBPrograms\fP)
 The graphics hacks which \fIxscreensaver\fP runs when the user is idle.
 The value of this resource is a string, one \fIsh\fP-syntax command per line.  
-Each line must contain exactly one command -- no semicolons, no ampersands.
+Each line must contain exactly one command: no semicolons, no ampersands.
 
 When the screensaver starts up, one of these is selected at random, and
 run.  After the \fIcycle\fP period expires, it is killed, and another
@@ -328,11 +337,11 @@ is selected and run.
 If the value of this resource is empty, then no programs will be run; the
 screen will simply be made black.
 
-If the display has multiple screens, then a different program will be run 
-for each screen.
+If the display has multiple screens, then a different program will be run
+for each screen.  (All screens are blanked and unblanked simultaniously.)
 
 Note that you must escape the newlines; here is an example of how you
-might set this in your \fI.Xdefaults\fP file:
+might set this in your \fI~/.Xdefaults\fP file:
 
 .RS 8
 .EX
@@ -360,8 +369,8 @@ display, and others that you want to run only when using a monochrome
 display, you can specify that like this:
 
 .EX
-        mono:   mono-program  -root        \\n\\
-        color:  color-program -root        \\n\\
+    mono:   mono-program  -root        \\n\\
+    color:  color-program -root        \\n\\
 .EE
 .RE
 .RS 8
@@ -371,8 +380,8 @@ program works best if it has a colormap, but another works best if it has
 a 24-bit visual, both can be accommodated:
 
 .EX
-        PseudoColor: cmap-program  -root   \\n\\
-        TrueColor:   24bit-program -root   \\n\\
+    PseudoColor: cmap-program  -root   \\n\\
+    TrueColor:   24bit-program -root   \\n\\
 .EE
 .RE
 .RS 8
@@ -380,9 +389,9 @@ a 24-bit visual, both can be accommodated:
 and \fImonoPrograms\fP resources, but those resources have now been removed;
 a warning will be issued if they are used.)
 
-In addition to the symbolic visual names described above (in the section
-about the \fI\-visual\fP command-line option) one other visual name is
-supported in the \fIprograms\fP list:
+In addition to the symbolic visual names described above (in the discussion
+of the \fIvisualID\fP resource) one other visual name is supported in
+the \fIprograms\fP list:
 .RS 1
 .TP 4
 .B default-n
@@ -390,8 +399,12 @@ This is like \fBdefault\fP, but also requests the use of the default colormap,
 instead of a private colormap.  (That is, it behaves as if 
 the \fI\-no\-install\fP command-line option was specified, but only for
 this particular hack.)  This is provided because some third-party programs
-that draw on the root window make assumptions about the visual and colormap
-of that window: assumptions which xscreensaver can violate.
+that draw on the root window (notably: 
+.BR xv (1),
+and
+.BR xearth (1))
+make assumptions about the visual and colormap of the root window: 
+assumptions which xscreensaver can violate.
 
 .RE
 If you specify a particular visual for a program, and that visual does not
@@ -408,7 +421,7 @@ Normally you won't need to change the following resources:
 .TP 8
 .B bourneShell\fP (class \fBBourneShell\fP)
 The pathname of the shell that \fIxscreensaver\fP uses to start subprocesses.
-This must be whatever your local variant of \fB/bin/sh\fP is -- in particular,
+This must be whatever your local variant of \fB/bin/sh\fP is: in particular,
 it must not be \fBcsh\fP.
 .TP 8
 .B windowCreationTimeout\fP (class \fBTime\fP)
@@ -425,13 +438,82 @@ have changed.  Default 5 seconds.
 When server extensions are not in use, \fIxscreensaver\fP will wait this many
 seconds before selecting events on existing windows, under the assumption that 
 \fIxscreensaver\fP is started during your login procedure, and the window 
-state may be in flux.  Default 30 seconds.
+state may be in flux.  Default 0.  (This used to default to 30, but that was
+back in the days when slow machines and X terminals were more common...)
 .TP 8
 .B overlayStderr\fP (class \fBBoolean\fP)
 If \fBcaptureStderr\fP or \fBcaptureStdout\fP are True, and your server 
 supports ``overlay'' visuals, then the text will be written into one of
 the higher layers instead of into the same layer as the running screenhack.
 Set this to False to disable that (though you shouldn't need to.)
+.SH COMMAND-LINE OPTIONS
+.I xscreensaver
+also accepts the following command line options.  Except for 
+the \fI\-display\fP option, these command-line options are all 
+simply shorthand for the X resources described in 
+the \fIConfiguration\fP section, above.
+.TP 8
+.B \-display \fIhost:display.screen\fP
+The X display to use.  For displays with multiple screens, XScreenSaver 
+will manage all screens on the display simultaniously; the \fIscreen\fP 
+argument (the ``default'' screen) says which screen should be used for
+dialog boxes (the password window, \fIDemo Mode\fP, etc.)
+.TP 8
+.B \-timeout \fIminutes\fP
+Same as the \fItimeout\fP resource.
+.TP 8
+.B \-cycle \fIminutes\fP
+Same as the \fIcycle\fP resource.
+.TP 8
+.B \-lock\-mode
+Same as setting the \fIlock\fP resource to \fItrue\fP.
+.TP 8
+.B \-no\-lock\-mode
+Same as setting the \fIlock\fP resource to \fIfalse\fP.
+.TP 8
+.B \-lock\-timeout \fIminutes\fP
+Same as the \fIlockTimeout\fP resource.
+.TP 8
+.B \-visual \fIvisual\fP
+Same as the \fIvisualID\fP resource.
+.TP 8
+.B \-install
+Same as setting the \fIinstallColormap\fP resource to \fItrue\fP.
+.TP 8
+.B \-no\-install
+Same as setting the \fIinstallColormap\fP resource to \fIfalse\fP.
+.TP 8
+.B \-verbose
+Same as setting the \fIverbose\fP resource to \fItrue\fP.
+.TP 8
+.B \-silent
+Same as setting the \fIverbose\fP resource to \fIfalse\fP.
+.TP 8
+.B \-nice \fIinteger\fP
+Same as the \fInice\fP resource.
+.TP 8
+.B \-sgi\-extension
+Same as setting the \fIsgiSaverExtension\fP resource to \fItrue\fP.
+.TP 8
+.B \-no\-sgi\-extension
+Same as setting the \fIsgiSaverExtension\fP resource to \fIfalse\fP.
+.TP 8
+.B \-mit\-extension
+Same as setting the \fImitSaverExtension\fP resource to \fItrue\fP.
+.TP 8
+.B \-no\-mit\-extension
+Same as setting the \fImitSaverExtension\fP resource to \fIfalse\fP.
+.TP 8
+.B \-xidle\-extension
+Same as setting the \fIxidleExtension\fP resource to \fItrue\fP.
+.TP 8
+.B \-no\-xidle\-extension
+Same as setting the \fIxidleExtension\fP resource to \fIfalse\fP.
+.TP 8
+.B \-xrm \fIresource-specification\fP
+As with all other Xt programs, you can specify X resources on the command-line
+using the \fI\-xrm\fP argument.  Most of the interesting resources have 
+command-line equivalents, however.
 .SH HOW IT WORKS
 When it is time to activate the screensaver, a full-screen black window is
 created on each screen of the display.  The window or windows is given the
@@ -476,15 +558,16 @@ Make sure you have \fB$PATH\fP set up correctly in the Xsetup script, or
 won't be able to find its graphics hacks.
 
 (If your system does not seem to be executing the \fIXsetup\fP file, you
-may need to configure it to do so -- the traditional way to do this is
+may need to configure it to do so: the traditional way to do this is
 to make that file the value of the \fIDisplayManager*setup\fP resource
-in the \fIxdm-config\fP file.  See the man page for
+in the \fI/usr/lib/X11/xdm/xdm-config\fP file.  See the man page for
 .BR xdm (1)
 for more details.)
 
 Users may want to add \fB"xscreensaver-command -restart"\fP to their 
 startup scripts, so that the screensaver will be reinitialized with
-their private resource settings when they log in.
+their private resource settings when they log in.  Users who don't do
+this will get the system-wide defaults instead.
 
 It is safe to run this program as root (as \fIxdm\fP is likely to do.)  If 
 run as root, \fIxscreensaver\fP changes its effective user and group ids to
@@ -497,7 +580,8 @@ and kill and restart it from your personal X startup script to enable
 locking; for example, by using this pair of commands:
 
 .EX
-        xscreensaver-command -exit ; xscreensaver
+xscreensaver-command -exit
+xscreensaver
 .EE
 .SH USING CDE (COMMON DESKTOP ENVIRONMENT)
 The easiest way to use \fIxscreensaver\fP on a system with CDE is to simply
@@ -517,7 +601,7 @@ Screen section of the Style Manager.
 Edit the file \fI~/.dt/sessions/sessionetc\fP and add to it the line
 
 .EX
-    xscreensaver &
+xscreensaver &
 .EE
 This will cause \fIxscreensaver\fP to be launched when you log in.
 (As always, make sure that xscreensaver and the graphics demos are on
@@ -581,7 +665,7 @@ Screen section of the Style Manager.
 Edit the file \fI~/.vue/sessions/home/vue.session\fP and add to it
 the line
 .EX
-    vuesmcmd -screen 0 -cmd "xscreensaver"
+vuesmcmd -screen 0 -cmd "xscreensaver"
 .EE
 This will cause \fIxscreensaver\fP to be launched when you log in.
 (As always, make sure that xscreensaver and the graphics demos are on
@@ -603,11 +687,61 @@ This associates the VUE front panel ``Lock'' icon with the xscreensaver
 lock command.
 .RE
 .PP
+.SH ADDING TO MENUS
+The
+.BR xscreensaver-command (1)
+program is a perfect candidate for something to add to your window manager's
+popup menus.  If you use 
+.BR mwm (1),
+.BR 4Dwm (1),
+.BR twm (1),
+or (probably) any of \fItwm\fP's many descendants, you can do it like this:
+.RS 0
+.TP 3
+\fB1. Create ~/.mwmrc (or ~/.twmrc or ...)\fP
+If you don't have a \fI~/.mwmrc\fP file (or, on SGIs, a \fI~/.4Dwmrc\fP file;
+or, with TWM, a \fI~/.twmrc\fP file) then create one by making a copy of
+the \fI/usr/lib/X11/system.mwmrc\fP 
+file (or \fI/usr/lib/X11/twm/system.twmrc\fP, and so on.)
+.TP 3
+\fB2. Add a menu definition.\fP
+Something like this:
+.EX
+menu XScreenSaver
+{
+ "Blank Screen Now" !"sleep 3; xscreensaver-command -activate"
+ "Lock Screen Now"  !"sleep 3; xscreensaver-command -lock"
+ "Screen Saver Demo"         !"xscreensaver-command -demo"
+ "Reinitialize Screen Saver" !"xscreensaver-command -restart"
+ "Kill Screen Saver"         !"xscreensaver-command -exit"
+ "Launch Screen Saver"       !"xscreensaver &"
+}
+.EE
+.TP 3
+\fB3. Add the menu\fP
+For
+.BR mwm (1)
+and
+.BR 4Dwm (1),
+find the section of the file that says \fIMenu DefaultRootMenu\fP.
+For
+.BR twm (1),
+it will probably be \fImenu "defops"\fP.  If you add a line somewhere 
+in that menu definition that reads
+.EX
+  "XScreenSaver"        f.menu XScreenSaver
+.EE
+then this will add an XScreenSaver sub-menu to your default root-window
+popup menu.  Alternately, you could just put the \fIxscreensaver-command\fP
+menu items directly into the root menu.
+.RE
+
+Other window managers might (and probably do) do things differently.
 .SH BUGS
 (This is not a bug, but) note that as of release 1.32, the \fBcolorPrograms\fP 
 and \fBmonoPrograms\fP resources are no longer used: they have been 
 supplanted by the extended syntax of the \fBprograms\fP resource (which is
-described above, in the \fIX Resources\fP section.)
+described in the \fIConfiguration\fP section, above.)
 .TP 8
 .B Extensions
 If you are not making use of one of the server extensions (\fBXIDLE\fP,
@@ -655,29 +789,33 @@ in code intended for use as a screensaver.  This prevents too much graphics
 activity from being buffered up.
 .TP 8
 .B Locking and XDM
-Locking doesn't work if the screensaver is launched by \fIxdm\fP.
-The reason for this is that when it is launched by \fIxdm\fP, the
-screensaver process is owned by some standard user id (such as \fIroot\fP
-or \fIdaemon\fP) instead of the user who is logged in on the console:
-because the screensaver was started \fIbefore\fP anyone was logged in.
-In order for the screensaver to prompt for the password of the person
-who had logged in from \fIxdm\fP, it would need to know who that user was, 
-and there is no reliable and safe way to figure that out.  (And even if 
-there was, there would be some other security issues here as well.)
+If xscreensaver has been launched from XDM, you will need to cause the
+xscreensaver daemon to exit and restart in order to lock the screen.
+
+The reason for this is, if xscreensaver has been launched by XDM, that
+means it was launched \fIbefore\fP you logged in: so it has no way of
+knowing who the logged-in user is, and therefore, whose password it
+should prompt for.
 
 So if you want to use it as a locker, you must start it with your user id.
-If it has already been started by \fIxdm\fP, you can kill it with
-\fBxscreensaver\-command -exit\fP, and then start it again as you.
+If it has already been started by \fIxdm\fP, you can kill it by sending
+it the \fBexit\fP command, and then re-launching it as you, by putting
+something like the following in your personal X startup script:
+.EX
+xscreensaver-command -exit
+xscreensaver &
+.EE
 .TP 8
 .B Locking and root logins
 An implication of the above is that if you log in as \fIroot\fP on the
 console, xscreensaver will refuse to lock the screen (because it can't tell
 the difference between \fIroot\fP being logged in on the console, and a
 normal user being logged in on the console but xscreensaver having been run
-by \fIxdm\fP.)
+by
+.BR xdm (1)).
 
 The solution to this is simple: you shouldn't be logging in on the console
-as \fIroot\fP in the first place (what, are you crazy or something?)  You 
+as \fIroot\fP in the first place!  (What, are you crazy or something?)  You 
 should log in as you, and
 .BR su (1)
 to \fIroot\fP as necessary.  People who spend their day logged in 
@@ -697,8 +835,11 @@ some options with \fIconfigure\fP and recompile.
 
 If you change your password after xscreensaver has been launched, it will
 continue using your old password to unlock the screen until xscreensaver
-is restarted.  This turns out to be kind of hard to fix.  (But remember,
-kids!  Unix security doesn't do much more than keep honest people honest...)
+is restarted.  So, after you change your password, you'll have to do
+.EX
+xscreensaver-command -restart
+.EE
+to make \fIxscreensaver\fP notice.
 .TP 8
 .B Colormap lossage: TWM
 The \fBinstallColormap\fP option doesn't work very well with the
@@ -728,9 +869,9 @@ from another console.  Any thoughts on this problem are welcome...
 .B Colormap lossage: XV, XAnim, XEarth
 Some programs don't operate properly on visuals other than the default one,
 or with colormaps other than the default one.  See the discussion of the
-magic "default-n" visual name in the section about the \fBprograms\fP 
-resource.  When programs only work with the default colormap, you need to
-use a syntax like this:
+magic "default-n" visual name in the description of the \fBprograms\fP 
+resource in the \fIConfiguration\fP section.  When programs only work with
+the default colormap, you need to use a syntax like this:
 .EX
     default-n: xv -root image-1.gif -quit  \\n\\
     default-n: xearth -nostars -wait 0     \\n\\
@@ -757,10 +898,14 @@ it tells the \fIxscreensaver\fP process to activate.  The \fIxscreensaver\fP
 process immediately unmaps that window, but this results in a flicker.  I 
 haven't figured a way  to get around this; it seems to be a fundamental
 property of the (mis-) design of this server extension.
+
+It sure would be nice if someone would implement the \fBSGI SCREEN_SAVER\fP
+extension in XFree86; it's dead simple, and works far better than the 
+overengineered and broken \fBMIT-SCREEN-SAVER\fP extension.
 .TP 8
 .B Lesstif (Motif clone)
-Demo mode is buggy if XScreenSaver was compiled against really old versions
-Lesstif; if you use Lesstif, use version 0.82 or newer.
+\fIDemo Mode\fP is buggy if XScreenSaver was compiled against really old 
+versions Lesstif; if you use Lesstif, make sure you use version 0.82 or newer.
 .TP 8
 .B Athena Widgets
 If you compiled against the Athena widget toolkit, the dialog boxes are
@@ -772,6 +917,38 @@ If you're running Irix 6.3, you might find that your monitor is powering down
 after an hour or two even if you've told it not to.  This is fixed by SGI
 patches 2447 and 2537.
 .TP 8
+.B OpenGL Programs and Visuals
+Some of the graphics demos included with xscreensaver make use of the 
+OpenGL (or MesaGL) 3D library, if it is available.  It is possible (even 
+likely) that \fIxscreensaver\fP's notion of the ``\fIbest\fP'' visual is 
+not quite right for these GL programs.  
+
+The odd thing about GL programs is that, unlike normal X11 programs, they
+tend to work best on a visual \fIhalf\fP as deep as the depth of the screen,
+since that way, they can do double-buffering.  Try it and see, but you will
+probably find that, for these particular programs, you should specify the
+deepest visual that is half as deep as the screen.  (See the discussion
+of the \fBprograms\fP resource in the \fIConfiguration\fP section, above.)
+
+For example, on a screen that supports both 24-bit TrueColor and 12-bit
+PseudoColor visuals, the 12-bit visual will probably work best (this is true
+of base-model SGI Indys: the 0x29 visual is the one you want.)  Oddly, on 
+SGI O2s (machines that have serious hardware support for GL), the 12-bit
+PseudoColor visual looks awful (you get a black and white, flickery image.)
+On these machines, the visual you want turns out to be 0x31.  However, 0x31
+is but \fIone\fP of the \fIeight\fP 15-bit TrueColor visuals (yes, 8, and 
+yes, 15) that the O2 X server provides.  This is the only visual that works
+properly: as far as 
+.BR xdpyinfo (1)
+is concerned, all of the 15-bit TrueColor visuals are identical, but some
+flicker like mad, and some have deeply weird artifacts (such as hidden 
+surfaces that show through, as if depth worked backwards!)  
+
+I suppose these other visuals must be tied to some arcane hardware feature...
+If anyone would care to explain it to me, that would be great.
+
+Your mileage, therefore, may vary dramatically.
+.TP 8
 .B Red Hot Lava
 There need to be a lot more graphics hacks.  In particular, there should be
 a simulation of a Lavalite (tm).
@@ -801,6 +978,7 @@ http://people.netscape.com/jwz/xscreensaver/
 .BR blitspin (1),
 .BR bouboule (1),
 .BR braid (1),
+.BR bsod (1),
 .BR bubbles (1),
 .BR cage (1),
 .BR coral (1),
@@ -808,6 +986,7 @@ http://people.netscape.com/jwz/xscreensaver/
 .BR decayscreen (1),
 .BR deco (1),
 .BR drift (1),
+.BR epicycle (1),
 .BR fadeplot (1),
 .BR flag (1),
 .BR flame (1),
@@ -823,6 +1002,7 @@ http://people.netscape.com/jwz/xscreensaver/
 .BR hypercube (1),
 .BR ifs (1),
 .BR imsmap (1),
+.BR interference (1),
 .BR jigsaw (1),
 .BR julia (1),
 .BR kaleidescope (1),
@@ -861,6 +1041,7 @@ http://people.netscape.com/jwz/xscreensaver/
 .BR superquadrics (1),
 .BR swirl (1),
 .BR triangle (1),
+.BR truchet (1),
 .BR vines (1),
 .BR worm (1),
 .BR xjack (1),
index 198906dd7094fb56a4ee4fb457c62989dc52d16f..5f299ce5753d0e4dbedd18d035a06269ceb3004b 100644 (file)
@@ -48,7 +48,7 @@ SGI_VIDEO_LIBS  = @SGI_VIDEO_LIBS@
 UTILS_SRC      = $(srcdir)/../utils
 UTILS_BIN      = ../utils
 
-INCLUDES       = -I$(srcdir) -I$(srcdir)/.. -I$(UTILS_SRC) -I.. @INCLUDES@
+INCLUDES       = -I$(srcdir) -I$(UTILS_SRC) -I.. @INCLUDES@
 
 UTIL_SRCS      = $(UTILS_SRC)/alpha.c $(UTILS_SRC)/colors.c \
                  $(UTILS_SRC)/grabscreen.c $(UTILS_SRC)/hsv.c \
@@ -74,7 +74,8 @@ SRCS          = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
                  xroger-hack.c goop.c starfish.c munch.c fadeplot.c \
                  rd-bomb.c coral.c mountain.c triangle.c lissie.c worm.c \
                  rotor.c ant.c xjack.c xlyap.c jigsaw.c xscreensaver-sgigl.c \
-                 cynosure.c moire2.c flow.c
+                 cynosure.c moire2.c flow.c epicycle.c interference.c \
+                 truchet.c bsod.c
 
 OBJS           = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  bubbles-default.o decayscreen.o deco.o drift.o flag.o \
@@ -87,7 +88,8 @@ OBJS          = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  xroger-hack.o goop.o starfish.o munch.o fadeplot.o \
                  rd-bomb.o coral.o mountain.o triangle.o lissie.o worm.o \
                  rotor.o ant.o xjack.o xlyap.o jigsaw.o xscreensaver-sgigl.o \
-                 cynosure.o moire2.o flow.o
+                 cynosure.o moire2.o flow.o epicycle.o interference.o \
+                 truchet.o bsod.o
 
 EXES           = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
@@ -96,7 +98,8 @@ EXES          = attraction blitspin bouboule braid bubbles decayscreen deco \
                  penrose pyro qix rocks rorschach sierpinski slidescreen \
                  slip sphere spiral strange swirl xroger goop starfish munch \
                  fadeplot rd-bomb coral mountain triangle lissie worm rotor \
-                 ant xjack xlyap jigsaw cynosure moire2 flow
+                 ant xjack xlyap jigsaw cynosure moire2 flow epicycle \
+                 interference truchet bsod
 
 HACK_OBJS_1    = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
@@ -118,11 +121,12 @@ MEN               = attraction.man blitspin.man bouboule.man braid.man \
                  rocks.man rorschach.man sierpinski.man slidescreen.man \
                  slip.man sphere.man spiral.man strange.man swirl.man \
                  xroger.man goop.man starfish.man munch.man rd-bomb.man \
-                 xjack.man xlyap.man jigsaw.man
+                 xjack.man xlyap.man jigsaw.man epicycle.man
 STAR           = *
 EXTRAS         = README Makefile.in xlock_23.h .gdbinit \
                  vidwhacker \
                  images/$(STAR).xbm \
+                 images/$(STAR).xpm \
                  images/bubbles/$(STAR).pov \
                  images/bubbles/$(STAR).xpm \
                  images/noseguy/$(STAR).xbm \
@@ -422,6 +426,18 @@ jigsaw: $(HACK_OBJS) jigsaw.o $(GRAB)
 cynosure: $(HACK_OBJS) cynosure.o $(COL)
        $(CC_HACK) -o $@ $(HACK_OBJS) cynosure.o $(COL) $(HACK_LIBS)
 
+epicycle: $(HACK_OBJS) epicycle.o $(COL) $(ERASE)
+       $(CC_HACK) -o $@ $(HACK_OBJS) epicycle.o $(COL) $(ERASE) $(HACK_LIBS)
+
+interference: $(HACK_OBJS) interference.o $(COL)
+       $(CC_HACK) -o $@ $(HACK_OBJS) interference.o $(COL) $(HACK_LIBS)
+
+truchet: $(HACK_OBJS) truchet.o $(COL)
+       $(CC_HACK) -o $@ $(HACK_OBJS) truchet.o $(COL) $(HACK_LIBS)
+
+bsod: $(HACK_OBJS) bsod.o $(COL)
+       $(CC_HACK) -o $@ $(HACK_OBJS) bsod.o $(COL) $(HACK_LIBS) $(XPM_LIBS)
+
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
@@ -1269,4 +1285,43 @@ flow.o: $(UTILS_SRC)/colors.h
 flow.o: $(UTILS_SRC)/grabscreen.h
 flow.o: $(UTILS_SRC)/visual.h
 flow.o: $(UTILS_SRC)/erase.h
+epicycle.o: $(srcdir)/screenhack.h
+epicycle.o: ../config.h
+epicycle.o: $(UTILS_SRC)/yarandom.h
+epicycle.o: $(UTILS_SRC)/usleep.h
+epicycle.o: $(UTILS_SRC)/resources.h
+epicycle.o: $(UTILS_SRC)/hsv.h
+epicycle.o: $(UTILS_SRC)/colors.h
+epicycle.o: $(UTILS_SRC)/grabscreen.h
+epicycle.o: $(UTILS_SRC)/visual.h
+epicycle.o: $(UTILS_SRC)/erase.h
+interference.o: $(srcdir)/screenhack.h
+interference.o: ../config.h
+interference.o: $(UTILS_SRC)/yarandom.h
+interference.o: $(UTILS_SRC)/usleep.h
+interference.o: $(UTILS_SRC)/resources.h
+interference.o: $(UTILS_SRC)/hsv.h
+interference.o: $(UTILS_SRC)/colors.h
+interference.o: $(UTILS_SRC)/grabscreen.h
+interference.o: $(UTILS_SRC)/visual.h
+truchet.o: $(srcdir)/screenhack.h
+truchet.o: ../config.h
+truchet.o: $(UTILS_SRC)/yarandom.h
+truchet.o: $(UTILS_SRC)/usleep.h
+truchet.o: $(UTILS_SRC)/resources.h
+truchet.o: $(UTILS_SRC)/hsv.h
+truchet.o: $(UTILS_SRC)/colors.h
+truchet.o: $(UTILS_SRC)/grabscreen.h
+truchet.o: $(UTILS_SRC)/visual.h
+bsod.o: $(srcdir)/screenhack.h
+bsod.o: ../config.h
+bsod.o: $(UTILS_SRC)/yarandom.h
+bsod.o: $(UTILS_SRC)/usleep.h
+bsod.o: $(UTILS_SRC)/resources.h
+bsod.o: $(UTILS_SRC)/hsv.h
+bsod.o: $(UTILS_SRC)/colors.h
+bsod.o: $(UTILS_SRC)/grabscreen.h
+bsod.o: $(UTILS_SRC)/visual.h
+bsod.o: $(srcdir)/images/amiga.xpm
+bsod.o: $(srcdir)/images/mac.xbm
 
index cf019b62b71a4eafd3d7569ce22a17f470d31243..d5070d24a0305a6445abd1857c891da376973ba6 100644 (file)
@@ -69,7 +69,7 @@ static const char sccsid[] = "@(#)ant.c       4.04 97/07/28 xlockmore";
 
 #endif /* STANDALONE */
 
-#define DEF_TRUCHET  "False"
+#define DEF_TRUCHET  "True"
 
 #ifdef STANDALONE
 static int neighbors;
@@ -119,7 +119,7 @@ ModeSpecOpt ant_opts =
 #define MINGRIDSIZE 24
 #define MINSIZE 1
 #define ANGLES 360
-#define NEIGHBORKINDS 3
+#define NEIGHBORKINDS 2
 
 #ifdef STANDALONE
 static XPoint hexagonUnit[6] =
@@ -199,7 +199,7 @@ typedef struct {
 } antfarmstruct;
 
 static int  initVal[NEIGHBORKINDS] =
-{3, 4, 6};                     /* Neighborhoods, 8 just makes a mess */
+{3, 6};                        /* Neighborhoods, 8 just makes a mess */
 
 
 /* Relative ant moves */
@@ -501,11 +501,9 @@ fillcell(ModeInfo * mi, GC gc, int col, int row)
                        XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
                              ap->hexagonList, 6, Convex, CoordModePrevious);
 
-#if 0 /* jwz sez: this looks like crap */
        } else if (ap->neighbors == 4 || ap->neighbors == 8) {
                XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
                ap->xb + ap->xs * col, ap->yb + ap->ys * row, ap->xs, ap->ys);
-#endif
 
        } else {                /* TRI */
                int         orient = (col + row) % 2;   /* O left 1 right */
index 42930046acc350997deab5cdca33de6ef5e0876e..667a67b0ffd249558b86014a04debb93b5038868 100644 (file)
@@ -612,8 +612,8 @@ run_balls (Display *dpy, Window window)
 char *progclass = "Attraction";
 
 char *defaults [] = {
-  "Attraction.background:      black",         /* to placate SGI */
-  "Attraction.foreground:      white",
+  "*background:        black",
+  "*foreground:        white",
   "*mode:      balls",
   "*points:    0",
   "*size:      0",
index 5b66f7d6e57172f3f9229b6762071b920c43e8e8..5a58062637dc7ed4b9dd680a78ad70ca52bb3e6e 100644 (file)
@@ -333,8 +333,8 @@ display (Pixmap pixmap)
 char *progclass = "BlitSpin";
 
 char *defaults [] = {
-  "BlitSpin.background:        black",         /* to placate SGI */
-  "BlitSpin.foreground:        white",
+  "*background:        black",
+  "*foreground:        white",
   "*delay:     500000",
   "*delay2:    500000",
   "*bitmap:    (default)",
diff --git a/hacks/bsod.c b/hacks/bsod.c
new file mode 100644 (file)
index 0000000..e3c0994
--- /dev/null
@@ -0,0 +1,543 @@
+/* xscreensaver, Copyright (c) 1998 Jamie Zawinski <jwz@netscape.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * Blue Screen of Death: the finest in personal computer emulation.
+ * Concept cribbed from Stephen Martin <smartin@mks.com>;
+ * this version written by jwz, 4-Jun-98.
+ *
+ *   TODO:
+ *      -  Should have a "macsbug" mode.
+ *      -  Should simulate a Unix kernel panic and reboot.
+ *      -  Making various boot noises would be fun, too.
+ *      -  Maybe scatter some random bits across the screen,
+ *         to simulate corruption of video ram?
+ *      -  Should randomize the various hex numbers printed.
+ */
+
+#include "screenhack.h"
+#include <stdio.h>
+#include <X11/Xutil.h>
+
+#ifdef HAVE_XPM
+# include <X11/xpm.h>
+# include "images/amiga.xpm"
+#endif
+
+#include "images/mac.xbm"
+
+
+static void
+draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv,
+            XFontStruct *font, int win_width, int win_height,
+            const char *string, int delay)
+{
+  int x, y;
+  int width = 0, height = 0, cw = 0;
+  int char_width, line_height;
+
+  const char *s = string;
+  const char *se = string;
+
+  /* This pretty much assumes fixed-width fonts */
+  char_width = (font->per_char
+               ? font->per_char['n'-font->min_char_or_byte2].width
+               : font->min_bounds.width);
+  line_height = font->ascent + font->descent + 1;
+
+  while (1)
+    {
+      if (*s == '\n' || !*s)
+       {
+         height++;
+         if (cw > width) width = cw;
+         cw = 0;
+         if (!*s) break;
+       }
+      else
+       cw++;
+      s++;
+    }
+
+  x = (win_width - (width * char_width)) / 2;
+  y = (win_height - (height * line_height)) / 2;
+
+  if (x < char_width) x = char_width;
+  if (y < line_height) y = line_height;
+
+  se = s = string;
+  while (1)
+    {
+      if (*s == '\n' || !*s)
+       {
+         int off = 0;
+         Bool flip = False;
+
+         if (*se == '@' || *se == '_')
+           {
+             if (*se == '@') flip = True;
+             se++;
+             off = (char_width * (width - (s - se))) / 2;
+           }
+
+         if (flip)
+           {
+             XSetForeground(dpy, gc, gcv->background);
+             XSetBackground(dpy, gc, gcv->foreground);
+           }
+
+         if (s != se)
+           XDrawImageString(dpy, window, gc, x+off, y+font->ascent, se, s-se);
+
+         if (flip)
+           {
+             XSetForeground(dpy, gc, gcv->foreground);
+             XSetBackground(dpy, gc, gcv->background);
+           }
+
+         se = s;
+         y += line_height;
+         if (!*s) break;
+         se = s+1;
+
+         if (delay)
+           {
+             XSync(dpy, False);
+             usleep(delay);
+           }
+       }
+      s++;
+    }
+}
+
+
+static Pixmap
+double_pixmap(Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap,
+            int pix_w, int pix_h)
+{
+  int x, y;
+  Pixmap p2 = XCreatePixmap(dpy, pixmap, pix_w*2, pix_h*2, depth);
+  XImage *i1 = XGetImage(dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, ZPixmap);
+  XImage *i2 = XCreateImage(dpy, visual, depth, ZPixmap, 0, 0,
+                           pix_w*2, pix_h*2, 8, 0);
+  i2->data = (unsigned char *) calloc(i2->height, i2->bytes_per_line);
+  for (y = 0; y < pix_h; y++)
+    for (x = 0; x < pix_w; x++)
+      {
+       unsigned long p = XGetPixel(i1, x, y);
+       XPutPixel(i2, x*2,   y*2,   p);
+       XPutPixel(i2, x*2+1, y*2,   p);
+       XPutPixel(i2, x*2,   y*2+1, p);
+       XPutPixel(i2, x*2+1, y*2+1, p);
+      }
+  free(i1->data); i1->data = 0;
+  XDestroyImage(i1);
+  XPutImage(dpy, p2, gc, i2, 0, 0, 0, 0, i2->width, i2->height);
+  free(i2->data); i2->data = 0;
+  XDestroyImage(i2);
+  XFreePixmap(dpy, pixmap);
+  return p2;
+}
+
+
+/* Sleep for N seconds and return False.  But if a key or mouse event is
+   seen, discard all pending key or mouse events, and return True.
+ */
+static Bool
+bsod_sleep(Display *dpy, int seconds)
+{
+  XEvent event;
+  int q = seconds * 4;
+  int mask = KeyPressMask|ButtonPressMask;
+  while (q > 0)
+    {
+      XSync(dpy, False);
+      if (XCheckMaskEvent(dpy, mask, &event))
+       {
+         while (XCheckMaskEvent(dpy, mask, &event))
+           ;
+         return True;
+       }
+      q--;
+      usleep(250000);
+    }
+  return False; 
+}
+
+
+static void
+windows (Display *dpy, Window window, int delay, Bool w95p)
+{
+  XGCValues gcv;
+  XWindowAttributes xgwa;
+  char *fontname;
+  const char *def_font = "fixed";
+  XFontStruct *font;
+  GC gc;
+
+  const char *w95 =
+    ("@Windows\n"
+     "A fatal exception 0E has occured at F0AD:42494C4C\n"
+     "the current application will be terminated.\n"
+     "\n"
+     "* Press any key to terminate the current application.\n"
+     "* Press CTRL+ALT+DELETE again to restart your computer.\n"
+     "  You will lose any unsaved information in all applications.\n"
+     "\n"
+     "\n"
+     "_Press any key to continue");
+
+  const char *wnt =
+    ("*** STOP: 0x0000001E (0x80000003,0x80106fc0,0x8025ea21,0xfd6829e8)\n"
+   "Unhandled Kernel exception c0000047 from fa8418b4 (8025ea21,fd6829e8)\n"
+   "\n"
+   "Dll Base Date Stamp - Name             Dll Base Date Stamp - Name\n"
+   "80100000 2be154c9 - ntoskrnl.exe       80400000 2bc153b0 - hal.dll\n"
+   "80258000 2bd49628 - ncrc710.sys        8025c000 2bd49688 - SCSIPORT.SYS \n"
+   "80267000 2bd49683 - scsidisk.sys       802a6000 2bd496b9 - Fastfat.sys\n"
+   "fa800000 2bd49666 - Floppy.SYS         fa810000 2bd496db - Hpfs_Rec.SYS\n"
+   "fa820000 2bd49676 - Null.SYS           fa830000 2bd4965a - Beep.SYS\n"
+   "fa840000 2bdaab00 - i8042prt.SYS       fa850000 2bd5a020 - SERMOUSE.SYS\n"
+   "fa860000 2bd4966f - kbdclass.SYS       fa870000 2bd49671 - MOUCLASS.SYS\n"
+   "fa880000 2bd9c0be - Videoprt.SYS       fa890000 2bd49638 - NCC1701E.SYS\n"
+   "fa8a0000 2bd4a4ce - Vga.SYS            fa8b0000 2bd496d0 - Msfs.SYS\n"
+   "fa8c0000 2bd496c3 - Npfs.SYS           fa8e0000 2bd496c9 - Ntfs.SYS\n"
+   "fa940000 2bd496df - NDIS.SYS           fa930000 2bd49707 - wdlan.sys\n"
+   "fa970000 2bd49712 - TDI.SYS            fa950000 2bd5a7fb - nbf.sys\n"
+   "fa980000 2bd72406 - streams.sys        fa9b0000 2bd4975f - ubnb.sys\n"
+   "fa9c0000 2bd5bfd7 - usbser.sys         fa9d0000 2bd4971d - netbios.sys\n"
+   "fa9e0000 2bd49678 - Parallel.sys       fa9f0000 2bd4969f - serial.SYS\n"
+   "faa00000 2bd49739 - mup.sys            faa40000 2bd4971f - SMBTRSUP.SYS\n"
+   "faa10000 2bd6f2a2 - srv.sys            faa50000 2bd4971a - afd.sys\n"
+   "faa60000 2bd6fd80 - rdr.sys            faaa0000 2bd49735 - bowser.sys\n"
+   "\n"
+   "Address dword dump Dll Base                                      - Name\n"
+   "801afc20 80106fc0 80106fc0 00000000 00000000 80149905 : "
+     "fa840000 - i8042prt.SYS\n"
+   "801afc24 80149905 80149905 ff8e6b8c 80129c2c ff8e6b94 : "
+     "8025c000 - SCSIPORT.SYS\n"
+   "801afc2c 80129c2c 80129c2c ff8e6b94 00000000 ff8e6b94 : "
+     "80100000 - ntoskrnl.exe\n"
+   "801afc34 801240f2 80124f02 ff8e6df4 ff8e6f60 ff8e6c58 : "
+     "80100000 - ntoskrnl.exe\n"
+   "801afc54 80124f16 80124f16 ff8e6f60 ff8e6c3c 8015ac7e : "
+     "80100000 - ntoskrnl.exe\n"
+   "801afc64 8015ac7e 8015ac7e ff8e6df4 ff8e6f60 ff8e6c58 : "
+     "80100000 - ntoskrnl.exe\n"
+   "801afc70 80129bda 80129bda 00000000 80088000 80106fc0 : "
+     "80100000 - ntoskrnl.exe\n"
+   "\n"
+   "Kernel Debugger Using: COM2 (Port 0x2f8, Baud Rate 19200)\n"
+   "Restart and set the recovery options in the system control panel\n"
+   "or the /CRASHDEBUG system start option. If this message reappears,\n"
+   "contact your system administrator or technical support group."
+     );
+
+  XGetWindowAttributes (dpy, window, &xgwa);
+
+  fontname = get_string_resource ((xgwa.height > 600
+                                  ? (w95p
+                                     ? "windows95.font2"
+                                     : "windowsNT.font2")
+                                  : (w95p
+                                     ? "windows95.font"
+                                     : "windowsNT.font")),
+                                 "Windows.Font");
+  if (!fontname || !*fontname) fontname = (char *)def_font;
+  font = XLoadQueryFont (dpy, fontname);
+  if (!font) font = XLoadQueryFont (dpy, def_font);
+  if (!font) exit(-1);
+  if (fontname && fontname != def_font)
+    free (fontname);
+
+  gcv.font = font->fid;
+  gcv.foreground = get_pixel_resource((w95p
+                                      ? "windows95.foreground"
+                                      : "windowsNT.foreground"),
+                                     "Windows.Foreground",
+                                     dpy, xgwa.colormap);
+  gcv.background = get_pixel_resource((w95p
+                                      ? "windows95.background"
+                                      : "windowsNT.background"),
+                                     "Windows.Background",
+                                     dpy, xgwa.colormap);
+  XSetWindowBackground(dpy, window, gcv.background);
+  XClearWindow(dpy, window);
+
+  gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
+
+  if (w95p)
+    draw_string(dpy, window, gc, &gcv, font, xgwa.width, xgwa.height, w95, 0);
+  else
+    draw_string(dpy, window, gc, &gcv, font, 10, 10, wnt, 750);
+
+  XFreeGC(dpy, gc);
+  XSync(dpy, False);
+  bsod_sleep(dpy, delay);
+  XClearWindow(dpy, window);
+  XFreeFont(dpy, font);
+}
+
+static void
+amiga (Display *dpy, Window window, int delay)
+{
+  XGCValues gcv;
+  XWindowAttributes xgwa;
+  char *fontname;
+  const char *def_font = "fixed";
+  XFontStruct *font;
+  GC gc, gc2;
+  int height;
+  unsigned long fg, bg, bg2;
+  Pixmap pixmap = 0;
+  int pix_w, pix_h;
+
+  const char *string =
+    ("_Software failure.  Press left mouse button to continue.\n"
+     "_Guru Meditation #00000003.00C01570");
+
+  XGetWindowAttributes (dpy, window, &xgwa);
+
+  fontname = get_string_resource ((xgwa.height > 600
+                                  ? "amiga.font2" : "amiga.font"),
+                                 "Amiga.Font");
+  if (!fontname || !*fontname) fontname = (char *)def_font;
+  font = XLoadQueryFont (dpy, fontname);
+  if (!font) font = XLoadQueryFont (dpy, def_font);
+  if (!font) exit(-1);
+  if (fontname && fontname != def_font)
+    free (fontname);
+
+  gcv.font = font->fid;
+  fg = gcv.foreground = get_pixel_resource("amiga.foreground",
+                                          "Amiga.Foreground",
+                                          dpy, xgwa.colormap);
+  bg = gcv.background = get_pixel_resource("amiga.background",
+                                          "Amiga.Background",
+                                          dpy, xgwa.colormap);
+  bg2 = get_pixel_resource("amiga.background2", "Amiga.Background",
+                          dpy, xgwa.colormap);
+  XSetWindowBackground(dpy, window, bg2);
+  XClearWindow(dpy, window);
+
+  gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
+  gcv.background = fg; gcv.foreground = bg;
+  gc2 = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
+
+  height = (font->ascent + font->descent) * 6;
+
+#ifdef HAVE_XPM
+  {
+    XpmAttributes xpmattrs;
+    int result;
+    xpmattrs.valuemask = 0;
+
+# ifdef XpmCloseness
+    xpmattrs.valuemask |= XpmCloseness;
+    xpmattrs.closeness = 40000;
+# endif
+# ifdef XpmVisual
+    xpmattrs.valuemask |= XpmVisual;
+    xpmattrs.visual = xgwa.visual;
+# endif
+# ifdef XpmDepth
+    xpmattrs.valuemask |= XpmDepth;
+    xpmattrs.depth = xgwa.depth;
+# endif
+# ifdef XpmColormap
+    xpmattrs.valuemask |= XpmColormap;
+    xpmattrs.colormap = xgwa.colormap;
+# endif
+
+    result = XpmCreatePixmapFromData(dpy, window, amiga_hand,
+                                    &pixmap, 0 /* mask */, &xpmattrs);
+    if (!pixmap || (result != XpmSuccess && result != XpmColorError))
+      pixmap = 0;
+    pix_w = xpmattrs.width;
+    pix_h = xpmattrs.height;
+  }
+#endif /* HAVE_XPM */
+
+  if (pixmap && xgwa.height > 600)     /* scale up the bitmap */
+    {
+      pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
+                            pixmap, pix_w, pix_h);
+      pix_w *= 2;
+      pix_h *= 2;
+    }
+
+  if (pixmap)
+    {
+      int x = (xgwa.width - pix_w) / 2;
+      int y = ((xgwa.height - pix_h) / 2);
+      XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
+
+      XSync(dpy, False);
+      bsod_sleep(dpy, 2);
+
+      XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y + height);
+      XClearArea(dpy, window, 0, 0, xgwa.width, y + height, False);
+      XFreePixmap(dpy, pixmap);
+    }
+
+  XFillRectangle(dpy, window, gc2, 0, 0, xgwa.width, height);
+  draw_string(dpy, window, gc, &gcv, font, xgwa.width, height, string, 0);
+
+  {
+    GC gca = gc;
+    while (delay > 0)
+      {
+       XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, font->ascent);
+       XFillRectangle(dpy, window, gca, 0, 0, font->ascent, height);
+       XFillRectangle(dpy, window, gca, xgwa.width-font->ascent, 0,
+                      font->ascent, height);
+       XFillRectangle(dpy, window, gca, 0, height-font->ascent, xgwa.width,
+                      font->ascent);
+       gca = (gca == gc ? gc2 : gc);
+       XSync(dpy, False);
+       if (bsod_sleep(dpy, 1))
+         break;
+       delay--;
+      }
+  }
+
+  XFreeGC(dpy, gc);
+  XFreeGC(dpy, gc2);
+  XSync(dpy, False);
+  XClearWindow(dpy, window);
+  XFreeFont(dpy, font);
+}
+
+
+static void
+mac (Display *dpy, Window window, int delay)
+{
+  XGCValues gcv;
+  XWindowAttributes xgwa;
+  char *fontname;
+  const char *def_font = "fixed";
+  XFontStruct *font;
+  GC gc;
+  Pixmap pixmap = 0;
+  int pix_w = mac_width;
+  int pix_h = mac_height;
+  int offset = mac_height * 4;
+  int i;
+
+  const char *string = ("0 0 0 0 0 0 0 F\n"
+                       "0 0 0 0 0 0 0 3");
+
+  XGetWindowAttributes (dpy, window, &xgwa);
+
+  fontname = get_string_resource ("mac.font", "Mac.Font");
+  if (!fontname || !*fontname) fontname = (char *)def_font;
+  font = XLoadQueryFont (dpy, fontname);
+  if (!font) font = XLoadQueryFont (dpy, def_font);
+  if (!font) exit(-1);
+  if (fontname && fontname != def_font)
+    free (fontname);
+
+  gcv.font = font->fid;
+  gcv.foreground = get_pixel_resource("mac.foreground", "Mac.Foreground",
+                                     dpy, xgwa.colormap);
+  gcv.background = get_pixel_resource("mac.background", "Mac.Background",
+                                     dpy, xgwa.colormap);
+  XSetWindowBackground(dpy, window, gcv.background);
+  XClearWindow(dpy, window);
+
+  gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
+
+  pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) mac_bits,
+                                      mac_width, mac_height,
+                                      gcv.foreground,
+                                      gcv.background,
+                                      xgwa.depth);
+
+  draw_string(dpy, window, gc, &gcv, font, xgwa.width, xgwa.height + offset,
+             string, 0);
+
+  for(i = 0; i < 2; i++)
+    {
+      pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
+                            pixmap, pix_w, pix_h);
+      pix_w *= 2; pix_h *= 2;
+    }
+
+  {
+    int x = (xgwa.width - pix_w) / 2;
+    int y = (((xgwa.height + offset) / 2) -
+            pix_h -
+            (font->ascent + font->descent) * 2);
+    if (y < 0) y = 0;
+    XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
+    XFreePixmap(dpy, pixmap);
+  }
+
+  XFreeGC(dpy, gc);
+  XSync(dpy, False);
+  bsod_sleep(dpy, delay);
+  XClearWindow(dpy, window);
+  XFreeFont(dpy, font);
+}
+
+\f
+char *progclass = "BSOD";
+
+char *defaults [] = {
+  "*delay:                     30",
+
+  "BSOD.Windows.font:          -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
+  "BSOD.Windows.font2:         -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
+  "BSOD.Windows.foreground:    White",
+  "BSOD.Windows.background:    Blue",
+
+  "BSOD.Amiga.font:            -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
+  "BSOD.Amiga.font2:           -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
+  "BSOD.Amiga.foreground:      Red",
+  "BSOD.Amiga.background:      Black",
+  "BSOD.Amiga.background2:     White",
+
+  "BSOD.Mac.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
+  "BSOD.Mac.foreground:                PaleTurquoise1",
+  "BSOD.Mac.background:                Black",
+  0
+};
+
+XrmOptionDescRec options [] = {
+  { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+void
+screenhack (Display *dpy, Window window)
+{
+  int i = -1;
+  int j = -1;
+  int delay = get_integer_resource ("delay", "Integer");
+  if (delay < 3) delay = 3;
+
+  if (!get_boolean_resource ("root", "Boolean"))
+    XSelectInput(dpy, window, KeyPressMask|ButtonPressMask);
+
+  while (1)
+    {
+      while (i == j) i = random() % 4;
+      j = i;
+
+      switch (i)
+       {
+       case 0: windows(dpy, window, delay, True); break;
+       case 1: windows(dpy, window, delay, False); break;
+       case 2: amiga(dpy, window, delay); break;
+       case 3: mac(dpy, window, delay); break;
+       default: abort(); break;
+       }
+      XSync (dpy, True);
+    }
+}
index 99e64b10d1b3cbb2e34f4b9568242d1fc96ac26a..7b4fdd56911ae8d52f9acf87976b23266437c48a 100644 (file)
@@ -1,6 +1,6 @@
 /* bubbles.c - frying pan / soft drink in a glass simulation */
 
-/*$Id: bubbles.c,v 1.13 1998/02/21 21:55:14 jwz Exp $*/
+/*$Id: bubbles.c,v 1.14 1998/06/04 22:55:09 jwz Exp $*/
 
 /*
  *  Copyright (C) 1995-1996 James Macnicol
@@ -506,8 +506,8 @@ size. */
   }
   rv->visible = 0;
   rv->magic = BUBBLE_MAGIC;
-  rv->x = ya_random() % screen_width;
-  rv->y = ya_random() % screen_height;
+  rv->x = random() % screen_width;
+  rv->y = random() % screen_height;
   rv->cell_index = pixel_to_mesh(rv->x, rv->y);
 
   return rv;
@@ -837,7 +837,7 @@ merge_bubbles(Bubble *b1, Bubble *b2)
       break;
     }
   } else {
-    if ((ya_random() % 2) == 0) {
+    if ((random() % 2) == 0) {
       switch (bubble_eat(b1, b2)) {
       case 0:
        return 0;
@@ -1218,8 +1218,6 @@ init_bubbles (Display *dpy, Window window)
   defdsp = dpy;
   defwin = window;
 
-  ya_rand_init(0);
-
   get_resources(dpy, window);
 
   XGetWindowAttributes (dpy, window, &xgwa);
index daf56fafb0e839d03b236e63c8b5c77a01b910ee..d6421375493ee5b345ad7dceb5a8a040ccc35796 100644 (file)
@@ -3,6 +3,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLITSPIN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BOUBOULE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BRAID.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BSOD.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES-DEFAULT.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CORAL.C
@@ -10,6 +11,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECAYSCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECO.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DRIFT.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) EPICYCLE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FADEPLOT.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAG.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAME.C
@@ -25,6 +27,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) HYPERCUBE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) IFS.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) IMSMAP.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) INTERFERENCE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JIGSAW.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JULIA.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) KALEIDESCOPE.C
@@ -57,6 +60,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STRANGE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SWIRL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRIANGLE.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRUCHET.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) VINES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WORM.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XJACK.C
index daf56fafb0e839d03b236e63c8b5c77a01b910ee..d6421375493ee5b345ad7dceb5a8a040ccc35796 100644 (file)
@@ -3,6 +3,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLITSPIN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BOUBOULE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BRAID.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BSOD.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES-DEFAULT.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CORAL.C
@@ -10,6 +11,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECAYSCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECO.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DRIFT.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) EPICYCLE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FADEPLOT.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAG.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAME.C
@@ -25,6 +27,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) HYPERCUBE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) IFS.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) IMSMAP.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) INTERFERENCE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JIGSAW.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JULIA.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) KALEIDESCOPE.C
@@ -57,6 +60,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STRANGE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SWIRL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRIANGLE.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRUCHET.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) VINES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WORM.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XJACK.C
index 6a2be2df46d0eb0a292a964a44f9deac43cdb13d..3a837126dd7e060e96bee9ad24f6ebf0d4dc8464 100644 (file)
@@ -119,7 +119,8 @@ static int gridSize;
 
 char *progclass = "Cynosure";
 char *defaults [] = {
-  "Cynosure.background:        black",         /* to placate SGI */
+  "*background:                black",
+  "*foreground:                white",
   "*delay:             500000",
   "*colors:            128",
   "*iterations:                100",
@@ -200,6 +201,7 @@ void screenhack(Display *d, Window w)
   delay = get_integer_resource ("delay", "Delay");
   iterations = get_integer_resource ("iterations", "Iterations");
 
+  i = 0;
   while (1)
     {
       if (iterations > 0 && ++i >= iterations)
index bd9e62d886b6d7f1f36e68c45e3fb4ed9f890ae4..63ca3aead71674281d1f301aca49c36731740f43 100644 (file)
@@ -59,8 +59,8 @@ deco (Display *dpy,
 char *progclass = "Deco";
 
 char *defaults [] = {
-  "Deco.background:    black",         /* to placate SGI */
-  "Deco.foreground:    white",
+  "*background:                black",
+  "*foreground:                white",
   "*maxDepth:          12",
   "*minWidth:          20",
   "*minHeight:         20",
diff --git a/hacks/epicycle.c b/hacks/epicycle.c
new file mode 100644 (file)
index 0000000..addaaaa
--- /dev/null
@@ -0,0 +1,833 @@
+/* epicycle --- The motion of a body with epicycles, as in the pre-Copernican
+ * cosmologies.
+ *
+ * Copyright (c) 1998  James Youngman <jay@gnu.org>
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
+
+/* Standard C headers; screenhack.h assumes that these have already
+ * been included if required -- for example, it defines M_PI if not
+ * already defined.
+ */
+#include <float.h>
+#include <math.h>
+
+
+#include "screenhack.h"
+#include "erase.h"
+
+/* MIT-SHM headers omitted; this screenhack doesn't use it */
+
+
+
+/*********************************************************/
+/******************** MAGIC CONSTANTS ********************/
+/*********************************************************/
+#define MIN_RADIUS (5)         /* smallest allowable circle radius */
+#define FILL_PROPORTION (0.9)  /* proportion of screen to fill by scaling. */
+/*********************************************************/
+/***************** END OF MAGIC CONSTANTS ****************/
+/*********************************************************/
+
+
+
+#define FULLCIRCLE (2.0 * M_PI)        /* radians in a circle. */
+
+
+/* Name of the Screensaver hack */
+char *progclass="Epicycle";
+
+/* Some of these resource values here are hand-tuned to give a
+ * pleasing variety of interesting shapes.  These are not the only
+ * good settings, but you may find you need to change some as a group
+ * to get pleasing figures.
+ */
+char *defaults [] = {
+  "*background:        black",
+  "*foreground:        white",
+  "*colors:    100",
+  "*color0:    red",
+  "*delay:     1000",
+  "*holdtime:  2",
+  "*lineWidth: 4",
+  "*minCircles:  2",
+  "*maxCircles:  10",
+  "*minSpeed:  0.003",
+  "*maxSpeed:  0.005",
+  "*harmonics: 8",
+  "*timestep:  1.0",
+  "*timestepCoarseFactor: 1.0", /* no option for this resource. */
+  "*divisorPoisson: 0.4",
+  "*sizeFactorMin: 1.05",
+  "*sizeFactorMax: 2.05",
+  0
+};
+
+/* options passed to this program */
+XrmOptionDescRec options [] = {
+  { "-color0",         ".color0",        XrmoptionSepArg, 0 },
+  { "-colors",         ".colors",        XrmoptionSepArg, 0 },
+  { "-colours",                ".colors",        XrmoptionSepArg, 0 },
+  { "-foreground",     ".foreground",    XrmoptionSepArg, 0 },
+  { "-delay",          ".delay",         XrmoptionSepArg, 0 },
+  { "-holdtime",       ".holdtime",      XrmoptionSepArg, 0 },
+  { "-linewidth",      ".lineWidth",     XrmoptionSepArg, 0 },
+  { "-min_circles",    ".minCircles",    XrmoptionSepArg, 0 },
+  { "-max_circles",    ".maxCircles",    XrmoptionSepArg, 0 },
+  { "-min_speed",      ".minSpeed",      XrmoptionSepArg, 0 },
+  { "-max_speed",      ".maxSpeed",      XrmoptionSepArg, 0 },
+  { "-harmonics",      ".harmonics",     XrmoptionSepArg, 0 },
+  { "-timestep",       ".timestep",      XrmoptionSepArg, 0 },
+  { "-divisor_poisson",".divisorPoisson",XrmoptionSepArg, 0 },
+  { "-size_factor_min", ".sizeFactorMin", XrmoptionSepArg, 0 },
+  { "-size_factor_max", ".sizeFactorMax", XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+
+static Display *dpy;
+static Window window;
+static GC color0;
+static int width, height;
+static int x_offset, y_offset;
+static int unit_pixels;
+static unsigned long bg;
+static Colormap cmap;
+static int restart = 0;
+static int stop = 0;
+static double wdot_max;
+static XColor *colors = NULL;
+static int ncolors = 2;
+static int color_shift_pos=0;  /* how far we are towards that. */
+static double colour_cycle_rate = 1.0;
+static int harmonics = 8;
+static double divisorPoisson = 0.4;
+static double sizeFactorMin = 1.05;
+static double sizeFactorMax = 2.05;
+static int minCircles;
+static int maxCircles;
+
+/* Each circle is centred on a point on the rim of another circle.
+ */
+struct tagCircle
+{
+  long radius;                 /* in pixels */
+  double w;                    /* position (radians ccw from x-axis) */
+  double initial_w;            /* starting position */
+  double wdot;                 /* rotation rate (change in w per iteration) */
+  int    divisor;
+
+  struct tagCircle *pchild;
+};
+typedef struct tagCircle Circle;
+
+
+struct tagBody                 /* a body that moves on a system of circles. */
+{
+  int x_origin, y_origin;
+  int x, y;
+  int old_x, old_y;
+  int current_color;           /* pixel index into colors[] */
+  Circle *epicycles;           /* system of circles on which it moves. */
+  struct tagBody *next;                /* next in list. */
+};
+typedef struct tagBody Body;
+
+
+/* Determine the GCD of two numbers using Euclid's method.  The other
+ * possible algorighm is Stein's method, but it's probably only going
+ * to be much faster on machines with no divide instruction, like the
+ * ARM and the Z80.  The former is very fast anyway and the latter
+ * probably won't run X clients; in any case, this calculation is not
+ * the bulk of the computational expense of the program.  I originally
+ * tried using Stein's method, but I wanted to remove the gotos.  Not
+ * wanting to introduce possible bugs, I plumped for Euclid's method
+ * instead.  Lastly, Euclid's algorithm is preferred to the
+ * generalisation for N inputs.
+ *
+ * See Knuth, section 4.5.2.
+ */
+static int
+gcd(int u, int v)              /* Euclid's Method */
+{
+  /* If either operand of % is negative, the sign of the result is
+   * implementation-defined.  See section 6.3.5 "Multiplicative
+   * Operators" of the ANSI C Standard (page 46 [LEFT HAND PAGE!] of
+   * "Annotated C Standard", Osborne, ISBN 0-07-881952-0).
+   */
+  if (u < 0) u = -u;
+  if (v < 0) v = -v;
+  
+  while (0 != v)
+    {
+      int r;
+      r = u % v;
+      u = v;
+      v = r;
+    }
+  return u;
+}
+
+/* Determine the Lowest Common Multiple of two integers, using
+ * Euclid's Proposition 34, as explained in Knuth's The Art of
+ * Computer Programming, Vol 2, section 4.5.2.
+ */
+static int
+lcm(int u, int v)
+{
+  return u / gcd(u,v) * v;
+}
+
+static long 
+random_radius(double scale)    
+{
+  long r;
+
+  r = frand(scale) * unit_pixels/2; /* for frand() see utils/yarandom.h */
+  if (r < MIN_RADIUS)
+    r = MIN_RADIUS;
+  return r;
+}
+
+
+static long
+random_divisor(void)
+{
+  int divisor = 1;
+  int sign;
+
+  while (frand(1.0) < divisorPoisson && divisor <= harmonics)
+    {
+      ++divisor;
+    }
+  sign = (frand(1.0) < 0.5) ? +1 : -1;
+  return sign * divisor;
+}
+
+
+static void
+oom(void)
+{
+  fprintf(stderr, "Failed to allocate memory!\n");
+  exit(-1);
+}
+
+
+/* Construct a circle or die.
+ */
+Circle *
+new_circle(double scale)
+{
+  Circle *p = malloc(sizeof(Circle));
+  
+  p->radius = random_radius(scale);
+  p->w = p->initial_w = 0.0;
+  p->divisor = random_divisor();
+  p->wdot = wdot_max / p->divisor;
+  p->pchild = NULL;
+  
+  return p;
+}
+
+static void delete_circle(Circle *p)
+{
+  free(p);
+}
+
+static void 
+delete_circle_chain(Circle *p)
+{
+  while (p)
+    {
+      Circle *q = p->pchild;
+      delete_circle(p);
+      p = q;
+    }
+}
+
+Circle *
+new_circle_chain(void)
+{
+  Circle *head;
+  double scale = 1.0, factor;
+  int n;
+
+  /* Parent circles are larger than their children by a factor of at
+   * least FACTOR_MIN and at most FACTOR_MAX.
+   */
+  factor = sizeFactorMin + frand(sizeFactorMax - sizeFactorMin);
+  
+  /* There are between minCircles and maxCircles in each figure.
+   */
+  n = minCircles + rand() % (maxCircles - minCircles);
+  
+  head = NULL;
+  while (n--)
+    {
+      Circle *p = new_circle(scale);
+      p->pchild = head;
+      head = p;
+
+      scale /= factor;
+    }
+  return head;
+}
+
+static void
+assign_random_common_w(Circle *p)
+{
+  double w_common = frand(FULLCIRCLE); /* anywhere on the circle */
+  while (p)
+    {
+      p->initial_w = w_common;
+      p = p->pchild;
+    }
+}
+
+static Body *
+new_body(void)
+{
+  Body *p = malloc(sizeof(Body));
+  if (NULL == p)
+    oom();
+  p->epicycles = new_circle_chain();
+  p->current_color = 0;                /* ?? start them all on different colors? */
+  p->next = NULL;
+  p->x = p->y = 0;
+  p->old_x = p->old_y = 0;
+  p->x_origin = p->y_origin = 0;
+
+  /* Start all the epicycles at the same w value to make it easier to
+   * figure out at what T value the cycle is closed.   We don't just fix
+   * the initial W value because that makes all the patterns tend to 
+   * be symmetrical about the X axis.
+   */
+  assign_random_common_w(p->epicycles);
+  return p;
+}
+
+static void
+delete_body(Body *p)
+{
+  delete_circle_chain(p->epicycles);
+  free(p);
+}
+
+
+static void 
+draw_body(Body *pb, GC gc)
+{
+  XDrawLine(dpy, window, gc, pb->old_x, pb->old_y, pb->x, pb->y);
+}
+
+static long
+compute_divisor_lcm(Circle *p)
+{
+  long l = 1;
+  
+  while (p)
+    {
+      l = lcm(l, p->divisor);
+      p = p->pchild;
+    }
+  return l;
+}
+
+             
+/* move_body()
+ *
+ * Calculate the position for the body at time T.  We work in double 
+ * rather than int to avoid the cumulative errors that would be caused
+ * by the rounding implicit in an assignment to int.
+ */
+static void
+move_body(Body *pb, double t)
+{
+  Circle *p;
+  double x, y;
+
+  pb->old_x = pb->x;
+  pb->old_y = pb->y;
+  
+  x = pb->x_origin;
+  y = pb->y_origin;
+  
+  for (p=pb->epicycles; NULL != p; p=p->pchild)
+    {
+      /* angular pos = initial_pos + time * angular speed */
+      /* but this is an angular position, so modulo FULLCIRCLE. */
+      p->w = fmod(p->initial_w + (t * p->wdot), FULLCIRCLE);
+      
+      x += (p->radius * cos(p->w));
+      y += (p->radius * sin(p->w));
+    }
+  
+  pb->x = (int)x;
+  pb->y = (int)y;
+}
+
+static int
+colour_init(XWindowAttributes *pxgwa)
+{
+  XGCValues gcv;
+
+#if 0
+  int H = random() % 360;      /* colour choice from attraction.c. */
+  double S1 = 0.25;
+  double S2 = 1.00;
+  double V = frand(0.25) + 0.75;
+  int line_width = 0;
+#endif
+
+  int retval = 1;
+  unsigned long valuemask = 0L;
+  unsigned long fg;
+  
+  /* Free any already allocated colors...
+   */
+  if (colors)
+    {
+      free_colors(dpy, cmap, colors, ncolors);
+      colors = 0;
+      ncolors = 0;
+    }
+       
+  ncolors = get_integer_resource ("colors", "Colors");
+  if (0 == ncolors)            /* English spelling? */
+    ncolors = get_integer_resource ("colours", "Colors");
+  
+  if (ncolors < 2)
+    ncolors = 2;
+  if (ncolors <= 2)
+    mono_p = True;
+  colors = 0;
+
+  if (!mono_p)
+    {
+      colors = (XColor *) malloc(sizeof(*colors) * (ncolors+1));
+      if (!colors)
+       oom();
+         
+      make_smooth_colormap (dpy, pxgwa->visual, cmap, colors, &ncolors,
+                           True, /* allocate */
+                           False, /* not writable */
+                           True); /* verbose (complain about failure) */
+      if (ncolors <= 2)
+       {
+         if (colors)
+           free (colors);
+         colors = 0;
+         mono_p = True;
+       }
+    }
+
+  
+  bg = get_pixel_resource ("background", "Background", dpy, cmap);
+
+  /* Set the line width
+   */
+  gcv.line_width = get_integer_resource ("lineWidth", "Integer");
+  if (gcv.line_width)
+    {
+      valuemask |= GCLineWidth;
+
+      gcv.join_style = JoinRound;
+      gcv.cap_style = CapRound;
+         
+      valuemask |= (GCCapStyle | GCJoinStyle);
+    }
+  
+
+  /* Set the drawing function.
+   */
+  gcv.function = GXcopy;
+  valuemask |= GCFunction;
+  
+  /* Set the foreground.
+   */
+  if (mono_p)
+    fg = get_pixel_resource ("foreground", "Foreground", dpy, cmap);
+  else
+    fg = bg ^ get_pixel_resource (("color0"), "Foreground", dpy, cmap); 
+  gcv.foreground = fg;
+  valuemask |= GCForeground;
+
+  /* Actually create the GC.
+   */
+  color0 = XCreateGC (dpy, window, valuemask, &gcv);
+  
+  return retval;
+}
+
+
+/* check_events(); originally from XScreensaver: hacks/maze.c,
+ * but now quite heavily modified.
+ *
+ * Reaction to events:-
+ *
+ * Mouse 1 -- new figure }
+ *       2 -- new figure }-- ignored when running on root window.
+ *       3 -- exit       }
+ *
+ * Window resized or exposed -- new figure.
+ * Window iconised -- wait until it's re-mapped, then start a new figure.
+ */
+static int
+check_events (void)                        /* X event handler [ rhess ] */
+{
+  XEvent e;
+  int unmapped = 0;
+       
+  while (unmapped || XPending(dpy))
+    {
+      XNextEvent(dpy, &e);
+               
+      switch (e.type)
+       {
+       case ButtonPress:
+         switch (e.xbutton.button)
+           {
+           case 3:
+             exit (0);
+             break;
+                               
+           case 2:
+           case 1:
+           default:
+             restart = 1 ;
+             stop = 0 ;
+             break;
+           }
+         break;
+                       
+       case ConfigureNotify:
+         restart = 1;
+         break;
+                       
+       case UnmapNotify:
+         printf("unmapped!\n");
+         unmapped = 1;
+         restart = 1;                  /* restart with new fig. when re-mapped. */
+         break;
+                       
+       case Expose:            
+         if (0 == e.xexpose.count)
+           {
+                               /* We can get several expose events in the queue.
+                                * Only the last one has a zero count.  We eat
+                                * events in this function so as to avoid restarting
+                                * the screensaver many times in quick succession.
+                                */
+             restart = 1;
+           }
+         /* If we had been unmapped and are now waiting to be re-mapped,
+          * indicate that we condition we are waiting for is now met.
+          */
+         if (unmapped)
+           printf("re-mapped!\n");
+         unmapped = 0;
+         break;
+       }
+               
+      /* If we're unmapped, don't return to the caller.  This
+       * prevents us wasting CPU, calculating new positions for
+       * things that will never be plotted.   This is a real CPU
+       * saver.
+       */
+      if (!unmapped)
+       return 1;
+    }
+  return 0;
+}
+
+
+static void
+setup(void)
+{
+  XWindowAttributes xgwa;
+  int root;
+  
+  XGetWindowAttributes (dpy, window, &xgwa);
+  cmap = xgwa.colormap;
+
+  width = xgwa.width;
+  height = xgwa.height;
+  x_offset = width / 2;
+  y_offset = height / 2;
+  unit_pixels = width < height ? width : height;
+
+  {
+    static Bool done = False;
+    if (!done)
+      {
+       colour_init(&xgwa);
+       done = True;
+      }
+  }
+  
+  root = get_boolean_resource("root", "Boolean");
+  
+  if (root)
+    {
+      XSelectInput(dpy, window, ExposureMask);
+    }
+  else
+    {
+      XSelectInput(dpy, window,
+                  ExposureMask|ButtonPressMask|StructureNotifyMask);
+    }
+  
+}
+static void
+color_step(Body *pb, double frac)
+{
+  if (!mono_p)
+    {
+      int newshift = ncolors * fmod(frac * colour_cycle_rate, 1.0);
+      if (newshift != color_shift_pos)
+       {
+         pb->current_color = newshift;
+         XSetForeground (dpy, color0, colors[pb->current_color].pixel);
+         color_shift_pos = newshift;
+       }
+    }
+}
+
+
+long
+distance(long x1, long y1, long x2, long y2)
+{
+  long dx, dy;
+
+  dx = x2 - x1;
+  dy = y2 - y1;
+  return dx*dx + dy*dy;
+}
+
+#if 0
+static int poisson_irand(double p)
+{
+  int r = 1;
+  while (fabs(frand(1.0)) < p)
+    ++r;
+  return r < 1 ? 1 : r;
+}
+#endif
+
+static void
+precalculate_figure(Body *pb,
+                   double xtime, double step,
+                   int *x_max, int *y_max,
+                   int *x_min, int *y_min)
+{
+  double t;
+  
+  move_body(pb, 0.0); /* move once to avoid initial line from origin */
+  *x_min = *x_max = pb->x;
+  *y_min = *y_max = pb->y;
+  
+  for (t=0.0; t<xtime; t += step)
+    {
+      move_body(pb, t); /* move once to avoid initial line from origin */
+      if (pb->x > *x_max)
+       *x_max = pb->x;
+      if (pb->x < *x_min)
+       *x_min = pb->x;
+      if (pb->y > *y_max)
+       *y_max = pb->y;
+      if (pb->y < *y_min)
+       *y_min = pb->y;
+    }
+}
+
+static int i_max(int a, int b)
+{
+  return (a>b) ? a : b;
+}
+
+static void rescale_circles(Body *pb,
+                           int x_max, int y_max,
+                           int x_min, int y_min)
+{
+  double xscale, yscale, scale;
+  double xm, ym;
+  
+  x_max -= x_offset;
+  x_min -= x_offset;
+  y_max -= y_offset;
+  y_min -= y_offset;
+
+  x_max = i_max(x_max, -x_min);
+  y_max = i_max(y_max, -y_min);
+
+
+  xm = width / 2.0;
+  ym = height / 2.0;
+  if (x_max > xm)
+    xscale = xm / x_max;
+  else
+    xscale = 1.0;
+  if (y_max > ym)
+    yscale = ym / y_max;
+  else
+    yscale = 1.0;
+
+  if (xscale < yscale)         /* wider than tall */
+    scale = xscale;            /* ensure width fits onscreen */
+  else
+    scale = yscale;            /* ensure height fits onscreen */
+
+
+  scale *= FILL_PROPORTION;    /* only fill FILL_PROPORTION of screen */
+  if (scale < 1.0)             /* only reduce, don't enlarge. */
+    {
+      Circle *p;
+      for (p=pb->epicycles; p; p=p->pchild)
+       {
+         p->radius *= scale;
+       }
+    }
+  else
+    {
+      printf("enlarge by x%.2f skipped...\n", scale);
+    }
+}
+
+
+/* angular speeds of the circles are harmonics of a fundamental
+ * value.  That should please the Pythagoreans among you... :-)
+ */
+static double 
+random_wdot_max(void)
+{
+  /* Maximum and minimum values for the choice of wdot_max.  Possible
+   * epicycle speeds vary from wdot_max to (wdot_max * harmonics).
+   */
+  double minspeed, maxspeed;
+  minspeed = get_float_resource("minSpeed", "Double");
+  maxspeed = get_float_resource("maxSpeed", "Double");
+  return harmonics * (minspeed + FULLCIRCLE * frand(maxspeed-minspeed));
+}
+
+/* this is the function called for your screensaver */
+/*GLOBAL*/ void
+screenhack(Display *disp, Window win)
+{
+  Body *pb = NULL;
+  long l;
+  double t, timestep, circle, xtime, timestep_coarse;
+  int delay;
+  int uncleared = 1;
+  int xmax, xmin, ymax, ymin;
+  int holdtime = get_integer_resource ("holdtime", "Integer");
+
+  dpy = disp;
+  window = win;
+
+  circle = FULLCIRCLE;
+  
+  XClearWindow(dpy, window);
+  uncleared = 0;
+  
+  delay = get_integer_resource ("delay", "Integer");
+  harmonics = get_integer_resource("harmonics", "Integer");
+  divisorPoisson = get_float_resource("divisorPoisson", "Double");
+  
+  timestep = get_float_resource("timestep", "Double");
+  timestep_coarse = timestep *
+    get_float_resource("timestepCoarseFactor", "Double");
+  
+  sizeFactorMin = get_float_resource("sizeFactorMin", "Double");
+  sizeFactorMax = get_float_resource("sizeFactorMax", "Double");
+
+  minCircles = get_integer_resource ("minCircles", "Integer");
+  maxCircles = get_integer_resource ("maxCircles", "Integer");
+
+  xtime = 0; /* is this right? */
+  while (0 == stop)
+    {
+      setup(); /* do this inside the loop to cope with any window resizing */
+      restart = 0;
+
+      /* Flush any outstanding events; this has the side effect of
+       * reducing the number of "false restarts"; resdtarts caused by
+       * one event (e.g. ConfigureNotify) followed by another
+       * (e.g. Expose).
+       */
+      XSync(dpy, True);
+         
+      wdot_max = random_wdot_max();
+         
+      if (pb)
+       {
+         delete_body(pb);
+         pb = NULL;
+       }
+      pb = new_body();
+      pb->x_origin = pb->x = x_offset;
+      pb->y_origin = pb->y = y_offset;
+         
+      
+      if (uncleared)
+       {
+         erase_full_window(dpy, window);
+         uncleared = 0;
+       }
+
+      fflush(stdout);
+      precalculate_figure(pb, xtime, timestep_coarse,
+                         &xmax, &ymax, &xmin, &ymin);
+
+      rescale_circles(pb, xmax, ymax, xmin, ymin);
+      
+      move_body(pb, 0.0); /* move once to avoid initial line from origin */
+      move_body(pb, 0.0); /* move once to avoid initial line from origin */
+
+      
+      t = 0.0;                 /* start at time zero. */
+
+      l = compute_divisor_lcm(pb->epicycles);
+      
+      colour_cycle_rate = fabs(l);
+      
+      xtime = fabs(l * circle / wdot_max);
+
+      if (colors)                              /* (colors==NULL) if mono_p */
+       XSetForeground (dpy, color0, colors[pb->current_color].pixel);
+
+      while (0 == restart)
+       {
+         color_step(pb, t/xtime );
+         draw_body(pb, color0);
+         uncleared = 1;
+
+         
+         /* Check if the figure is complete...*/
+         if (t > xtime)
+           {
+             XSync (dpy, False);
+
+             if (holdtime)
+               sleep(holdtime); /* show complete figure for a bit. */
+
+             restart = 1;      /* begin new figure. */
+           }
+         
+         
+         if (delay)
+           usleep (delay);
+         
+         t += timestep;
+         move_body(pb, t);
+         check_events();
+       }
+    }
+}
+
diff --git a/hacks/epicycle.man b/hacks/epicycle.man
new file mode 100644 (file)
index 0000000..bbe905a
--- /dev/null
@@ -0,0 +1,200 @@
+.de EX         \"Begin example
+.ne 5
+.if n .sp 1
+.if t .sp .5
+.nf
+.in +.5i
+..
+.de EE
+.fi
+.in -.5i
+.if n .sp 1
+.if t .sp .5
+..
+.TH XScreenSaver 1 "27-Apr-97" "X Version 11"
+.SH NAME
+qix - bounce colored lines around a window
+.SH SYNOPSIS
+.B epicycle 
+[\-display \fIhost:display.screen\fP] [\-root] [\-window] [\-mono] [\-install] [\-noinstall] [\-visual \fIviz\fP] [\-colors \fIN\fP] [\-foreground \fIname\fP] [\-color\-shift \fIN\fP] [\-delay \fImicroseconds\fP] [\-holdtime \fIseconds\fP] [\-linewidth \fIN\fP] [\-min_circles \fIN\fP] [\-max_circles \fIN\fP] [\-min_speed \fInumber\fP] [\-max_speed \fInumber\fP] [\-harmonics \fIN\fP] [\-timestep \fInumber\fP] [\-divisor_poisson \fIprobability\fP] [\-size_factor_min \fInumber\fP] [\-size_factor_max \fInumber\fP]
+.SH DESCRIPTION
+The epicycle program draws the path traced out by a point on the edge
+of a circle.  That circle rotates around a point on the rim of another
+circle, and so on, several times.  The random curves produced can be
+simple or complex, convex or concave, but they are always closed
+curves (they never go in indefinitely).
+
+You can configure both the way the curves are drawn and the way in
+which the random sequence of circles is generated, either with
+command-line options or X resources.
+.SH OPTIONS
+.TP 8
+.B \-display \fIhost:display.screen\fP
+Specifies which X display we should use (see the section DISPLAY NAMES in
+.BR X (1)
+for more information about this option).
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-mono
+If on a color display, pretend we're on a monochrome display.
+If we're on a mono display, we have no choice.
+.TP 8
+.B \-install
+Install a private colormap for the window.
+.TP 8
+.B \-noinstall
+Don't install a private colormap for the window.
+.TP 8
+.B \-visual \fIviz\fP
+Specify which visual to use.  Legal values are the name of a visual
+class, or the id number (decimal or hex) of a specific visual.
+Possible choices include
+
+.RS
+default, best, mono, monochrome, gray, grey, color, staticgray, staticcolor, 
+truecolor, grayscale, greyscale, pseudocolor, directcolor, \fInumber\fP
+
+If a decimal or hexadecimal number is used, 
+.BR XGetVisualInfo (3X)
+is consulted to obtain the required visual.
+.RE
+.TP 8
+.B \-colors \fIN\fP
+How many colors should be used (if possible).  The colors are chosen
+randomly.
+.TP 8
+.B \-foreground \fIname\fP
+With 
+.BR \-mono ,
+this option selects the foreground colour.   
+.TP 8
+.B \-delay \fImicroseconds\fP
+Specifies the delay between drawing successive line segments of the
+path.   If you do not specify 
+.BR -sync ,
+some X servers may batch up several drawing operations together,
+producing a less smooth effect.   This is more likely to happen 
+in monochrome mode (on monochrome servers or when 
+.B \-mono 
+is specified).
+.TP 8
+.B \-holdtime \fIseconds\fP
+When the figure is complete, 
+.I epicycle
+pauses this number of seconds.
+.TP 8
+.B \-linewidth \fIN\fP
+Width in pixels of the body's track.   Specifying values greater than
+one may cause slower drawing.   The fastest value is usually zero,
+meaning one pixel.   
+.TP 8
+.B \-min_circles \fIN\fP
+Smallest number of epicycles in the figure.
+.TP 8
+.B \-max_circles \fIN\fP
+Largest number of epicycles in the figure.
+.TP 8
+.B \-min_speed \fInumber\fP
+Smallest possible value for the base speed of revolution of the
+epicycles.  The actual speeds of the epicycles vary from this down
+to
+.IB "min_speed / harmonics" .
+.TP 8
+.B \-max_speed \fInumber\fP
+Smallest possible value for the base speed of revolution of the 
+epicycles.
+.TP 8
+.B \-harmonics \fIN\fP
+Number of possible harmonics; the larger this value is, the greater
+the possible variety of possible speeds of epicycle.
+.TP 8
+.B \-timestep \fInumber\fP
+Decreasing this value will reduce the distance the body moves for
+each line segment, possibly producing a smoother figure.  Increasing
+it may produce faster results.  
+.TP 8
+.B \-divisor_poisson \fIprobability\fP
+Each epicycle rotates at a rate which is a factor of the base speed.
+The speed of each epicycle is the base speed divided by some integer
+between 1 and the value of the 
+.B \-harmonics 
+option.  This integer is decided by starting at 1 and tossing 
+a biased coin.  For each consecutive head, the value is incremented by
+one.  The integer will not be incremented above the value of the 
+.B \-harmonics
+option.  The argument of this option decides the bias of the coin; it
+is the probability that that coin will produce a head at any given toss.
+.TP 8
+.B \-size_factor_min \fInumber\fP
+Epicycles are always at least this factor smaller than their
+parents.  
+.TP 8
+.B \-size_factor_max \fInumber\fP
+Epicycles are never more than this factor smaller than their parents.
+.SH RESOURCES
+.EX
+Option            Resource               Default Value
+------            --------               -------------
+-colors           .colors                100
+-delay            .delay                 1000
+-holdtime         .holdtime              2
+-linewidth        .lineWidth             4
+-min_circles      .minCircles            2
+-max_circles      .maxCircles            10
+-min_speed        .minSpeed              0.003
+-max_speed        .maxSpeed              0.005
+-harmonics        .harmonics             8
+-timestep         .timestep              1.0
+-divisor_poisson  .divisorPoisson        0.4
+-size_factor_min  .sizeFactorMin         1.05
+-size_factor_max  .sizeFactorMax         2.05
+                  .timestepCoarseFactor  1.0
+.EE
+Before the drawing of the figure is begun, a preliminary calculation
+of the path is done in order to scale the radii of the epicycles so
+as to fit the figure on the screen or window.  For the sake of speed,
+This calculation is done with a larger timestep than the actual
+drawing.  The time-step used is the value of the
+.B \-timestep 
+option multiplied by the timestepCoarseFactor resource.  The default
+value of 1 will almost always work fast enough and so this resource
+is not available as a command-line option.
+.SH USER INTERFACE
+The program runs mostly without user interaction.  When running on the
+root window, no input is accepted.  When running in its own window,
+the program will exit if mouse button 3 is pressed.  If any other
+mouse button is pressed, the current figure will be abandoned and
+another will be started.
+.SH HISTORY
+The geometry of epicycles was perfected by Hipparchus of Rhodes at
+some time around 125 B.C., 185 years after the birth of Aristarchus of
+Samos, the inventor of the heliocentric universe model.  Hipparchus
+applied epicycles to the Sun and the Moon.  Ptolemy of Alexandria went
+on to apply them to what was then the known universe, at around 150
+A.D.  Copernicus went on to apply them to the heliocentric model at
+the beginning of the sixteenth century.  Johannes Kepler discovered
+that the planets actually move in elliptical orbits in about 1602.
+The inverse-square law of gravity was suggested by Boulliau in 1645.
+Isaac Newton's 
+.I Principia Mathematica
+was published in 1687, and proved that Kepler's laws derived from
+Newtonian gravitation.
+.SH BUGS
+The colour selection is re-done for every figure.  This may 
+generate too much network traffic for this program to work well 
+over slow or long links.   
+.SH COPYRIGHT
+Copyright \(co 1998, James Youngman.  Permission to use, copy, modify,
+distribute, and sell this software and its documentation for any purpose is
+hereby granted without fee, provided that the above copyright notice appear
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation.  No representations are made about the
+suitability of this software for any purpose.  It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+James Youngman <jay@gnu.org>, April 1998.
index 6b243f59d769002924237ca4afbe5176ce9b5503..bbdbfdec93437ad43a22c508d85d101938615054 100644 (file)
@@ -381,8 +381,8 @@ int matherr(x)
 char *progclass = "Flame";
 
 char *defaults [] = {
-  "Flame.background:   black",         /* to placate SGI */
-  "Flame.foreground:   white",
+  "*background:        black",
+  "*foreground:        white",
   "*colors:    64",
   "*iterations:        25",
   "*delay:     50000",
index 21e6de83529e2ae8d33f4d461c2fc19c553220bf..18df9f6ea31f1af0b9401eee92e79701be7db62c 100644 (file)
@@ -45,8 +45,7 @@ HACK_BIN      = ..
 UTILS_SRC      = $(HACK_SRC)/../utils
 UTILS_BIN      = $(HACK_BIN)/../utils
 
-INCLUDES       = -I$(srcdir) -I$(UTILS_SRC) -I$(HACK_SRC) \
-                 -I$(HACK_SRC)/.. @INCLUDES@
+INCLUDES       = -I$(srcdir) -I$(UTILS_SRC) -I$(HACK_SRC) -I../.. @INCLUDES@
 
 UTIL_SRCS      = $(UTILS_SRC)/colors.c $(UTILS_SRC)/hsv.c \
                  $(UTILS_SRC)/resources.c $(UTILS_SRC)/usleep.c \
@@ -68,7 +67,7 @@ OBJS          = atlantis.o buildlwo.o cage.o dolphin.o gears.o moebius.o \
                  xlock-gl.o
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
-                 morph3d rubik
+                 morph3d rubik atlantis
 EXES           = @GL_EXES@
 
 HACK_OBJS      = screenhack-gl.o xlock-gl.o $(HACK_BIN)/xlockmore.o \
@@ -150,7 +149,8 @@ distdepend:
              -e 's@\.\./glx/@@g'                                           \
              -e 's@ \.\./@ $$(HACK_SRC)/@g'                                \
              -e 's@ \([^$$]\)@ $$(srcdir)/\1@g'                            \
-             -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' ;                     \
+             -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g'                       \
+             -e 's@ $$(HACK_SRC)/\(.*config.h\)@ ../\1@g' ;                \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
        mv Makefile.in Makefile.in.bak &&                                   \
@@ -196,7 +196,7 @@ screenhack-gl.o: $(HACK_SRC)/screenhack.c
 
 CC_HACK                = $(CC) $(LDFLAGS)
 
-atlantis:      atlantis.o      $(HACK_OBJS)
+atlantis:      atlantis.o      $(HACK_OBJS) dolphin.o shark.o swim.o whale.o
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) dolphin.o shark.o swim.o whale.o \
                                $(HACK_LIBS)
 
@@ -236,7 +236,7 @@ sproingies: sproingies.o $(HACK_OBJS) $(SPROINGIES)
 # DO NOT DELETE: updated by make distdepend
 
 atlantis.o: $(HACK_SRC)/xlockmore.h
-atlantis.o: $(HACK_SRC)/../config.h
+atlantis.o: ../../config.h
 atlantis.o: $(HACK_SRC)/xlockmoreI.h
 atlantis.o: $(HACK_SRC)/screenhack.h
 atlantis.o: $(UTILS_SRC)/yarandom.h
@@ -249,7 +249,7 @@ atlantis.o: $(UTILS_SRC)/visual.h
 atlantis.o: $(srcdir)/atlantis.h
 buildlwo.o: $(srcdir)/buildlwo.h
 cage.o: $(HACK_SRC)/xlockmore.h
-cage.o: $(HACK_SRC)/../config.h
+cage.o: ../../config.h
 cage.o: $(HACK_SRC)/xlockmoreI.h
 cage.o: $(HACK_SRC)/screenhack.h
 cage.o: $(UTILS_SRC)/yarandom.h
@@ -262,7 +262,7 @@ cage.o: $(UTILS_SRC)/visual.h
 cage.o: $(srcdir)/e_textures.h
 dolphin.o: $(srcdir)/atlantis.h
 gears.o: $(HACK_SRC)/xlockmore.h
-gears.o: $(HACK_SRC)/../config.h
+gears.o: ../../config.h
 gears.o: $(HACK_SRC)/xlockmoreI.h
 gears.o: $(HACK_SRC)/screenhack.h
 gears.o: $(UTILS_SRC)/yarandom.h
@@ -273,7 +273,7 @@ gears.o: $(UTILS_SRC)/colors.h
 gears.o: $(UTILS_SRC)/grabscreen.h
 gears.o: $(UTILS_SRC)/visual.h
 moebius.o: $(HACK_SRC)/xlockmore.h
-moebius.o: $(HACK_SRC)/../config.h
+moebius.o: ../../config.h
 moebius.o: $(HACK_SRC)/xlockmoreI.h
 moebius.o: $(HACK_SRC)/screenhack.h
 moebius.o: $(UTILS_SRC)/yarandom.h
@@ -285,7 +285,7 @@ moebius.o: $(UTILS_SRC)/grabscreen.h
 moebius.o: $(UTILS_SRC)/visual.h
 moebius.o: $(srcdir)/e_textures.h
 morph3d.o: $(HACK_SRC)/xlockmore.h
-morph3d.o: $(HACK_SRC)/../config.h
+morph3d.o: ../../config.h
 morph3d.o: $(HACK_SRC)/xlockmoreI.h
 morph3d.o: $(HACK_SRC)/screenhack.h
 morph3d.o: $(UTILS_SRC)/yarandom.h
@@ -297,7 +297,7 @@ morph3d.o: $(UTILS_SRC)/grabscreen.h
 morph3d.o: $(UTILS_SRC)/visual.h
 pipeobjs.o: $(srcdir)/buildlwo.h
 pipes.o: $(HACK_SRC)/xlockmore.h
-pipes.o: $(HACK_SRC)/../config.h
+pipes.o: ../../config.h
 pipes.o: $(HACK_SRC)/xlockmoreI.h
 pipes.o: $(HACK_SRC)/screenhack.h
 pipes.o: $(UTILS_SRC)/yarandom.h
@@ -309,7 +309,7 @@ pipes.o: $(UTILS_SRC)/grabscreen.h
 pipes.o: $(UTILS_SRC)/visual.h
 pipes.o: $(srcdir)/buildlwo.h
 rubik.o: $(HACK_SRC)/xlockmore.h
-rubik.o: $(HACK_SRC)/../config.h
+rubik.o: ../../config.h
 rubik.o: $(HACK_SRC)/xlockmoreI.h
 rubik.o: $(HACK_SRC)/screenhack.h
 rubik.o: $(UTILS_SRC)/yarandom.h
@@ -329,7 +329,7 @@ s1_b.o: $(srcdir)/buildlwo.h
 shark.o: $(srcdir)/atlantis.h
 sproingies.o: $(HACK_SRC)/xlockmoreI.h
 sproingies.o: $(HACK_SRC)/screenhack.h
-sproingies.o: $(HACK_SRC)/../config.h
+sproingies.o: ../../config.h
 sproingies.o: $(UTILS_SRC)/yarandom.h
 sproingies.o: $(UTILS_SRC)/usleep.h
 sproingies.o: $(UTILS_SRC)/resources.h
@@ -339,7 +339,7 @@ sproingies.o: $(UTILS_SRC)/grabscreen.h
 sproingies.o: $(UTILS_SRC)/visual.h
 sproingies.o: $(srcdir)/buildlwo.h
 sproingiewrap.o: $(HACK_SRC)/xlockmore.h
-sproingiewrap.o: $(HACK_SRC)/../config.h
+sproingiewrap.o: ../../config.h
 sproingiewrap.o: $(HACK_SRC)/xlockmoreI.h
 sproingiewrap.o: $(HACK_SRC)/screenhack.h
 sproingiewrap.o: $(UTILS_SRC)/yarandom.h
@@ -350,7 +350,7 @@ sproingiewrap.o: $(UTILS_SRC)/colors.h
 sproingiewrap.o: $(UTILS_SRC)/grabscreen.h
 sproingiewrap.o: $(UTILS_SRC)/visual.h
 stairs.o: $(HACK_SRC)/xlockmore.h
-stairs.o: $(HACK_SRC)/../config.h
+stairs.o: ../../config.h
 stairs.o: $(HACK_SRC)/xlockmoreI.h
 stairs.o: $(HACK_SRC)/screenhack.h
 stairs.o: $(UTILS_SRC)/yarandom.h
@@ -362,7 +362,7 @@ stairs.o: $(UTILS_SRC)/grabscreen.h
 stairs.o: $(UTILS_SRC)/visual.h
 stairs.o: $(srcdir)/e_textures.h
 superquadrics.o: $(HACK_SRC)/xlockmore.h
-superquadrics.o: $(HACK_SRC)/../config.h
+superquadrics.o: ../../config.h
 superquadrics.o: $(HACK_SRC)/xlockmoreI.h
 superquadrics.o: $(HACK_SRC)/screenhack.h
 superquadrics.o: $(UTILS_SRC)/yarandom.h
@@ -374,7 +374,7 @@ superquadrics.o: $(UTILS_SRC)/grabscreen.h
 superquadrics.o: $(UTILS_SRC)/visual.h
 swim.o: $(HACK_SRC)/xlockmoreI.h
 swim.o: $(HACK_SRC)/screenhack.h
-swim.o: $(HACK_SRC)/../config.h
+swim.o: ../../config.h
 swim.o: $(UTILS_SRC)/yarandom.h
 swim.o: $(UTILS_SRC)/usleep.h
 swim.o: $(UTILS_SRC)/resources.h
@@ -385,7 +385,7 @@ swim.o: $(UTILS_SRC)/visual.h
 swim.o: $(srcdir)/atlantis.h
 whale.o: $(srcdir)/atlantis.h
 xlock-gl.o: $(HACK_SRC)/screenhack.h
-xlock-gl.o: $(HACK_SRC)/../config.h
+xlock-gl.o: ../../config.h
 xlock-gl.o: $(UTILS_SRC)/yarandom.h
 xlock-gl.o: $(UTILS_SRC)/usleep.h
 xlock-gl.o: $(UTILS_SRC)/resources.h
index 079ebc617f825b537f463355543b0d285347016b..f31f9b91e235ab3632cecf3a1341df448a1afcba 100644 (file)
@@ -488,8 +488,8 @@ run_goop (Display *dpy, Window window, struct goop *goop)
 char *progclass = "Goop";
 
 char *defaults [] = {
-  "Goop.background:    black",         /* to placate SGI */
-  "Goop.foreground:    white",
+  "*background:                black",
+  "*foreground:                white",
   "*delay:             12000",
   "*transparent:       true",
   "*additive:          true",
index c3f5fbaf0c22b322ba14d9bcadb0ff29c0f729ba..6018d125a4623aeff3bf071825e6869eda8dc08e 100644 (file)
@@ -159,8 +159,8 @@ greynetic (Display *dpy, Window window)
 char *progclass = "Greynetic";
 
 char *defaults [] = {
-  "Greynetic.background:       black",         /* to placate SGI */
-  "Greynetic.foreground:       white",
+  "*background:        black",
+  "*foreground:        white",
   "*delay:     0",
   0
 };
index 470a9e90c11143e7af1ac8cf0f74a7e291e780f6..80166335b6235c4d0adf0cfb83840acdc4796f72 100644 (file)
@@ -417,8 +417,8 @@ run_circles (Display *dpy, Window window)
 char *progclass = "Halo";
 
 char *defaults [] = {
-  "Halo.background:    black",         /* to placate SGI */
-  "Halo.foreground:    white",
+  "*background:                black",
+  "*foreground:                white",
   "*colorMode:         random",
   "*colors:            100",
   "*cycle:             true",
index 1fe62e47da58abba7bc19929a9bb05df58ae3d30..3a26984ea8d9084333bea03746f6a54977b811f6 100644 (file)
@@ -282,7 +282,7 @@ random_helix_or_trig (Display *dpy, Window window)
 char *progclass = "Helix";
 
 char *defaults [] = {
-  "Helix.background: black",           /* to placate SGI */
+  "*background: black",
   "*delay:      5",
   0
 };
index 04b1560a9feaad9ed7d65930f23cea2fb0a70d38..3fef0e6a8ba0a15fb89a62840ff5db8f3e238ef4 100644 (file)
@@ -219,8 +219,8 @@ hyper (double xy, double xz, double yz, double xw, double yw, double zw)
 char *progclass = "Hypercube";
 
 char *defaults [] = {
-  "Hypercube.background:       black",         /* to placate SGI */
-  "Hypercube.foreground:       white",
+  "*background:        black",
+  "*foreground:        white",
   "*color0:    red",
   "*color1:    orange",
   "*color2:    yellow",
index 7e55af5167d1210589b011678f5efd52cea779c5..b29f8e349d4671e05f011facfbcb55ab07c9cbe7 100644 (file)
@@ -257,6 +257,7 @@ init_ifs(ModeInfo * mi)
 /***************************************************************/
 
 #ifndef __GNUC__
+# undef inline
 # define inline /* */
 #endif
 
diff --git a/hacks/images/amiga.xpm b/hacks/images/amiga.xpm
new file mode 100644 (file)
index 0000000..ed31447
--- /dev/null
@@ -0,0 +1,269 @@
+/* XPM */
+static char *amiga_hand[] = {
+/* width height num_colors chars_per_pixel */
+"   209   258        4            1",
+/* colors */
+". c #000000",
+"# c #6666cc",
+"a c #cccccc",
+"b c #ffffff",
+/* pixels */
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.......................................................................................................................................................bbbbbbbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.......................................................................................................................................................bbbbbbbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.........................................................................................................................................................bbbbbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.........................................................................................................................................................bbbbbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....###################.....bbbbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....###################.....bbbbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....#####################.....bbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....#####################.....bbbbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....#######################.....bbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....#######################.....bbbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....########################.....bbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....########################.....bbbbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....##########################.....bbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....##########################.....bbbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....############################....bbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....############################....bbbbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....#############################.....bbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....#############################.....bbbbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....###############################.....bbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....###############################.....bbbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....################################.....bbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....################################.....bbb",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....##################################.....b",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....##################################.....b",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....##########.....aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................aaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################.....aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.....####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################..........................................................................................####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################..........................................................................................####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################..........................................................................................####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....###################################..........................................................................................####################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#################################################################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.......#########################..................######################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.......#########################..................######################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..........#########################..bbbbb.............####################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..........#########################..bbbbb.............####################################################################################################################....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbb.....##############.............bbbbbbbbbbb..bbb.........................................................................................................#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbb.....##############.............bbbbbbbbbbb..bbb.........................................................................................................#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbb......bbbbb.....##############...........bbbbbbbbbbbbbbb..bbbb......................................................................................................#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbbbb......bbbbb.....##############...........bbbbbbbbbbbbbbb..bbbb......................................................................................................#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbb.....##############.....bbb...bbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbb.....##############.....bbb...bbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbb.....##############.....bbb...bbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbb.....##############.....bbb...bbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbb.....##############.....bb...bbbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbb.....##############.....bb...bbbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbb.....##############..........bbbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbb.....##############..........bbbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbb.....##############...........bbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbb.....##############...........bbbbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbb.....##############.............bbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbb.....##############.............bbbbbbbbbbbbb...bbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbb.....##############..........b....bbbbbbbbbbb...bbb....bbbb####bbbb#####bbbbb########bbbbb###bbbbb###bbbbb########bbbbbbb########bbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbb.....##############..........b....bbbbbbbbbbb...bbb....bbbb####bbbb#####bbbbb########bbbbb###bbbbb###bbbbb########bbbbbbb########bbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbb.....##############........bbbbb................bbb....bbbb####bbbb####bbbb####bbbbb###bbb###bbbbb###bbbbbbbbbbb####bbb###bbbbb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbb.....##############........bbbbb................bbb....bbbb####bbbb####bbbb####bbbbb###bbb###bbbbb###bbbbbbbbbbb####bbb###bbbbb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbb.....###########........bbbbbbbbbb.............bbbb....bbbb####bbbb####bbbbbbbbbbbbb###bbb###bbbbb###bbb############bbb###bbbbb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbb.....###########........bbbbbbbbbb.............bbbb....bbbb####bbbb####bbbbbbbbbbbbb###bbb###bbbbb###bbb############bbb###bbbbb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbb.bbbbbbbbbbbbbbbbbb.....#########........bbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbb####bbb#####bbbb####bbbbb###bbb###bbbbb###bbb####bbbb####bbb###bbb#####bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbbbb.bbbbbbbbbbbbbbbbbb.....#########........bbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbb####bbb#####bbbb####bbbbb###bbb###bbbbb###bbb####bbbb####bbb###bbb#####bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....########........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbb#####b####bbbbbb########bbbbbbb#########bbbbb########bbbbbbb####bb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....########........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbb#####b####bbbbbb########bbbbbbb#########bbbbb########bbbbbbb####bb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....#####........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbb####bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....#####........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbb####bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb.....###........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbb#####bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#####bbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb.....###........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbb#####bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#####bbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbb...bbbbb.bbbbbbbbbbbbbbb..............bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbbbbb...bbbbb.bbbbbbbbbbbbbbb..............bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbb....bbbbbbbb....bbbbbbbbbbb.....bbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbbbb....bbbbbbbb....bbbbbbbbbbb.....bbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbb...bbbbbbbbbbbbb.....bbbbb...........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbbbb...bbbbbbbbbbbbb.....bbbbb...........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbbb....bbbbbbbbbbbbbbbb................bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb###bbbbb#####bbbbbbbb######bbbbb########bbbbb###bbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbb...bbbbbbbbbbbbbbbbbbbbbb.........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbb####bbb###bbbbbbbbbbb####bbbb####bbbb####bbb#####bbb#####bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbbbb...bbbbbbbbbbbbbbbbbbbbbb.........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbb####bbb###bbbbbbbbbbb####bbbb####bbbb####bbb#####bbb#####bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbb...bbbbbbbbbbbbbbbbbbbbbbb......bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbb########bbb####bbbb####bbbb####bbbb####bbb#############bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbb...bbbbbbbbbbbbbbbbbbbbbbb......bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbb########bbb####bbbb####bbbb####bbbb####bbb#############bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbb...bbbbbbbbbbbbbbbbbbbbb..b..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbb####bbb###bbb####bbb#####bbbb####bbbb####bbb###bb###bb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbbb...bbbbbbbbbbbbbbbbbbbbb..b..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbb####bbb###bbb####bbb#####bbbb####bbbb####bbb###bb###bb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbb...bbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbb###bbbbb#####b#####bbbbb########bbbbb###bbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bbbb...bbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbb###bbbbb#####b#####bbbbb########bbbbb###bbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bb...bbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bb...bbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bb...bbbbbbbbbbbbbbbbbb.bb..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#####bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"bb...bbbbbbbbbbbbbbbbbb.bb..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#####bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb###bbbbbbb###bbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbb..bb.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbb..bb.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbaa........bbb.......aaa........abbbbbaa..........a..........baa..abb................bbb.......abbbbbbbbbb.....#############....",
+"....bbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbaa........bbb.......aaa........abbbbbaa..........a..........baa..abb................bbb.......abbbbbbbbbb.....#############....",
+"....bbbbbbbbbbb.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...bbbbbbb.aabbbaa...bba.....aabbbbba...aabbbbba....abbb....abbbbb...aabba...bbbbbbb.aabbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbb.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...bbbbbbb.aabbbaa...bba.....aabbbbba...aabbbbba....abbb....abbbbb...aabba...bbbbbbb.aabbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba..........abbbbb...aabbbaa.....abbbba...bbbbbbba....bbba....abbb....bbbbba..........abbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba..........abbbbb...aabbbaa.....abbbba...bbbbbbba....bbba....abbb....bbbbba..........abbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...bbbb.aabbbbb......aabbb.....abbbb...abbbbbbb...aabaa.....abb...bbbbbbba...bbbb.aabbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...bbbb.aabbbbb......aabbb.....abbbb...abbbbbbb...aabaa.....abb...bbbbbbba...bbbb.aabbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...bb..abbbbbbbbbbbbbbbbbb.....abbaa...bbbbbbaa...aaa..a....a...bbbbbbbbba...bb..abbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...bb..abbbbbbbbbbbbbbbbbb.....abbaa...bbbbbbaa...aaa..a....a...bbbbbbbbba...bb..abbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba.....aabbbbbbbbb..bbbbbbaa...aabbb...aabbbbbb...aa...aab.......bbbbbbbbbba.....aabbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba.....aabbbbbbbbb..bbbbbbaa...aabbb...aabbbbbb...aa...aab.......bbbbbbbbbba.....aabbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...aabbbbbbbbbbb..abbbba...aabbaaa...bbbbbbba.......abbb.....aabbbbbbbbbba...aabbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba...aabbbbbbbbbbb..abbbba...aabbaaa...bbbbbbba.......abbb.....aabbbbbbbbbba...aabbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba..abbbbbbbbbbbbb........aaabbaa........aaaaa......aabbbb.......abbbbbbbbba..abbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbba..abbbbbbbbbbbbb........aaabbaa........aaaaa......aabbbb.......abbbbbbbbba..abbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....#############....",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.............................................................................................................................................",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.............................................................................................................................................",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb............................................................................................................................................",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb............................................................................................................................................",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....b....bbbbbbbbbbbbbbbbbbbbbbbbb........bbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....b....bbbbbbbbbbbbbbbbbbbbbbbbb........bbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbb...bbbbbbbbbbbbbbbbbbbbb........bbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbb...bbbbbbbbbbbbbbbbbbbbb........bbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbb........bbbbbbbbbbbbbbbb........bbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbb........bbbbbbbbbbbbbbbb........bbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.................bbbbbbbbbbbb........bbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.................bbbbbbbbbbbb........bbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.........bbbbbb...bbbbbbbbbb........bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbb........bbb............bbbbbbbb.....bbbbbbbbbbbbbbbb.........bbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.........bbbbbb...bbbbbbbbbb........bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbb........bbb............bbbbbbbb.....bbbbbbbbbbbbbbbb.........bbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb.bbbbbbbbbbbb...bbbbbb........bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....bbbbbbbb.....bbbbbbbbb.......bbbbbbbbbbbbbb.............bbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb.bbbbbbbbbbbb...bbbbbb........bbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....bbbbbbbb.....bbbbbbbbb.......bbbbbbbbbbbbbb.............bbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb.bbbbbbbbbbbbb...bbbb........bbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....bbbbbb.....bbbbbbbbbb........bbbbbbbbbbbb.......bbb.......bbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb.bbbbbbbbbbbbb...bbbb........bbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbb.....bbbbbb.....bbbbbbbbbb........bbbbbbbbbbbb.......bbb.......bbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb.bbbbbbbbbbbbbbb...........bbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb.....bbbb.....bbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbb.....bbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb.bbbbbbbbbbbbbbb...........bbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb.....bbbb.....bbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbb.....bbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb...bbbbbbbbbbb...........bbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb.....bbb.....bbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbb......bbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..bb...bbbbbbbbbbb...........bbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb.....bbb.....bbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbb......bbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbb......bbbbb..........bbb.....bbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb.....b.....bbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbb......bbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbb......bbbbb..........bbb.....bbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb.....b.....bbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbb......bbbbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.......bbbbbb..................bbbbb...bbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb.........bbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbb.....bbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.......bbbbbb..................bbbbb...bbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb.........bbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbb.....bbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbb.....................bbbbbbbbbbb..bbbbbb...bbbbbbbbbbbbbbbbbbbbbbb........bbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbb.......bbb.......bbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbb.bbbbb...bbbbbbbbbbbbbbbbbbbbbbb......bbbbbbbbbbbbbbbbbbbb...........bbb...bbbbb.............bbbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbb.bbbbb...bbbbbbbbbbbbbbbbbbbbbbb......bbbbbbbbbbbbbbbbbbbb...........bbb...bbbbb.............bbbbbb",
+".....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbb.bbb....bbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbb...........bbb...bbbbbbb.........bbbbbbbb",
+".....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbb.bbb....bbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbb...........bbb...bbbbbbb.........bbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb..b...bbbbbbbbbb..bbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbb..b...bbbbbbbbbb..bbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbb....bbbbbbb.....bbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbb....bbbbbbb.....bbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbb.bb........bbb......bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbb.bb........bbb......bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbb..b..........bbb..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbb..b..........bbb..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbb........bbbbb.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbb........bbbbb.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..b....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..b....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb................bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb................bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...............bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...............bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb......bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb......bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb........bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb.....bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb..................................................................................bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb..................................................................................bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+"bb..................................................................................bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+};
diff --git a/hacks/images/mac.xbm b/hacks/images/mac.xbm
new file mode 100644 (file)
index 0000000..b4fe876
--- /dev/null
@@ -0,0 +1,10 @@
+#define mac_width 19
+#define mac_height 25
+static unsigned char mac_bits[] = {
+   0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x06, 0x00, 0x03, 0xfa, 0xff, 0x02,
+   0xaa, 0xaf, 0x02, 0xda, 0xdf, 0x02, 0xaa, 0xaf, 0x02, 0xfa, 0xf8, 0x02,
+   0xfa, 0xff, 0x02, 0x7a, 0xf0, 0x02, 0xba, 0xef, 0x02, 0xda, 0xdf, 0x02,
+   0xfa, 0xff, 0x02, 0x06, 0x00, 0x03, 0xfe, 0xff, 0x03, 0xfe, 0xff, 0x03,
+   0xfe, 0xff, 0x03, 0xf2, 0x07, 0x02, 0xfe, 0xff, 0x03, 0xfe, 0xff, 0x03,
+   0x00, 0x00, 0x00, 0xfc, 0xff, 0x01, 0xfc, 0xff, 0x01, 0xfc, 0xff, 0x01,
+   0x00, 0x00, 0x00};
index 54e8a77409eff781728f5d9e2d4f02655c063a65..a6b53cd6912bdfdb779fa3e028e5934a79281b49 100644 (file)
@@ -453,8 +453,8 @@ draw_map (Display *dpy, Window window)
 char *progclass = "Imsmap";
 
 char *defaults [] = {
-  "Imsmap.background:  black",         /* to placate SGI */
-  "Imsmap.foreground:  black",
+  "*background:        black",
+  "*foreground:        black",
   "*mode:      random",
   "*ncolors:   50",
   "*iterations:        7",
diff --git a/hacks/interference.c b/hacks/interference.c
new file mode 100644 (file)
index 0000000..d436ebb
--- /dev/null
@@ -0,0 +1,472 @@
+/* interference.c --- colored fields via decaying sinusoidal waves.
+ * An entry for the RHAD Labs Screensaver Contest.
+ *
+ * Author: Hannu Mallat <hmallat@cs.hut.fi>
+ *
+ * Copyright (C) 1998 Hannu Mallat.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * decaying sinusoidal waves, which extend spherically from their
+ * respective origins, move around the plane. a sort of interference
+ * between them is calculated and the resulting twodimensional wave
+ * height map is plotted in a grid, using softly changing colours.
+ *
+ * not physically (or in any sense) accurate, but fun to look at for 
+ * a while. you may tune the speed/resolution/interestingness tradeoff 
+ * with X resources, see below.
+ *
+ * Created      : Wed Apr 22 09:30:30 1998, hmallat
+ * Last modified: Wed Apr 22 09:30:30 1998, hmallat
+ *
+ * TODO:
+ *
+ *    This really needs to be sped up.
+ *
+ *    I've tried making it use XPutPixel/XPutImage instead of XFillRectangle,
+ *    but that doesn't seem to help (it's the same speed at gridsize=1, and
+ *    it actually makes it slower at larger sizes.)
+ *
+ *    I played around with shared memory, but clearly I still don't know how
+ *    to use the XSHM extension properly, because it doesn't work yet.
+ *
+ *    Hannu had put in code to use the double-buffering extension, but that
+ *    code didn't work for me on Irix.  I don't think it would help anyway,
+ *    since it's not the swapping of frames that is the bottleneck (or a source
+ *    of visible flicker.)
+ *
+ *     -- jwz, 4-Jun-98
+ */
+
+#include <math.h>
+
+#include "screenhack.h"
+
+# include <X11/Xutil.h>
+
+#ifdef HAVE_XDBE
+# include <X11/extensions/Xdbe.h>
+#endif /* HAVE_XDBE */
+
+
+/* I haven't gotten the shm stuff to work yet... and I'm not sure it would
+   help much anyway.  -- jwz */
+#undef HAVE_XSHM_EXTENSION
+
+#ifdef HAVE_XSHM_EXTENSION
+# include <sys/ipc.h>
+# include <sys/shm.h>
+# include <X11/extensions/XShm.h>
+#endif /*  HAVE_XSHM_EXTENSION */
+
+
+/* I thought it would be faster this way, but it turns out not to be... -jwz */
+/* #define USE_XIMAGE */
+
+char *progclass="Interference";
+
+char *defaults [] = {
+  "*count:       3",     /* number of waves */
+  "*gridsize:    4",     /* pixel size, smaller values for better resolution */
+  "*ncolors:     128",   /* number of colours used */
+  "*speed:       30",    /* speed of wave origins moving around */
+  "*delay:       30000", /* or something */
+  "*color-shift: 60",    /* h in hsv space, smaller values for smaller
+                         * color gradients */
+  "*radius:      800",   /* wave extent */
+  "*gray:        false", /* color or grayscale */
+  "*mono:        false", /* monochrome, not very much fun */
+
+#ifdef HAVE_XDBE
+  "*nodb:        true", /* don't use double buffering */
+#endif /* HAVE_XDBE */
+
+#ifdef HAVE_XSHM_EXTENSION
+  "*noshm:        false", /* don't use shared memory */
+#endif /*  HAVE_XSHM_EXTENSION */
+  0
+};
+
+XrmOptionDescRec options [] = {
+  { "-count",       ".count",       XrmoptionSepArg, 0 }, 
+  { "-ncolors",     ".ncolors",     XrmoptionSepArg, 0 }, 
+  { "-gridsize",    ".gridsize",    XrmoptionSepArg, 0 }, 
+  { "-speed",       ".speed",       XrmoptionSepArg, 0 },
+  { "-delay",       ".delay",       XrmoptionSepArg, 0 },
+  { "-color-shift", ".color-shift", XrmoptionSepArg, 0 },
+  { "-radius",      ".radius",      XrmoptionSepArg, 0 },
+  { "-gray",        ".gray",        XrmoptionNoArg,  "True" },
+  { "-mono",        ".mono",        XrmoptionNoArg,  "True" },
+#ifdef HAVE_XDBE
+  { "-nodb",        ".nodb",        XrmoptionNoArg,  "True" },
+#endif /* HAVE_XDBE */
+#ifdef HAVE_XSHM_EXTENSION
+  { "-noshm",        ".noshm",      XrmoptionNoArg,  "True" },
+#endif /*  HAVE_XSHM_EXTENSION */
+  { 0, 0, 0, 0 }
+};
+
+int options_size = (sizeof (options) / sizeof (XrmOptionDescRec));
+
+struct inter_source {
+  int x; 
+  int y;
+  double x_theta;
+  double y_theta;
+};
+
+struct inter_context {
+  /*
+   * Display-related entries 
+   */
+  Display* dpy;
+  Window   win;
+
+  Pixmap   dbuf;
+  GC       copy_gc;
+#ifdef USE_XIMAGE
+  XImage  *ximage;
+#endif /* USE_XIMAGE */
+
+#ifdef HAVE_XDBE
+  Status   has_dbe;
+#endif /* HAVE_XDBE */
+
+#ifdef HAVE_XSHM_EXTENSION
+  int use_shm;
+  XShmSegmentInfo shm_info;
+#endif /* HAVE_XSHM_EXTENSION */
+
+  /*
+   * Resources
+   */
+  int count;
+  int grid_size;
+  int colors;
+  int speed;
+  int delay;
+  int shift;
+  int radius;
+
+  /*
+   * Drawing-related entries
+   */
+  int w;
+  int h;
+  Colormap cmap;
+  XColor* pal;
+#ifdef HAVE_XDBE
+  XdbeBackBuffer buf;
+#endif /* HAVE_XDBE */
+  GC* gcs;
+
+  /*
+   * lookup tables
+   */
+  int* wave_height;
+    
+  /*
+   * Interference sources
+   */
+  struct inter_source* source;
+};
+
+#ifdef HAVE_XDBE
+# define TARGET(c) ((c)->has_dbe ? (c)->buf : (c)->dbuf)
+#else  /* HAVE_XDBE */
+# define TARGET(c) ((c)->dbuf)
+#endif /* !HAVE_XDBE */
+
+void inter_init(Display* dpy, Window win, struct inter_context* c) 
+{
+  XWindowAttributes xgwa;
+  double H[3], S[3], V[3];
+  int i;
+  int mono;
+  int gray;
+#ifdef HAVE_XDBE
+  int major, minor;
+  int nodb;
+#endif /* HAVE_XDBE */
+
+  XGCValues val;
+  unsigned long valmask = 0;
+
+  c->dpy = dpy;
+  c->win = win;
+
+  XGetWindowAttributes(c->dpy, c->win, &xgwa);
+  c->w = xgwa.width;
+  c->h = xgwa.height;
+  c->cmap = xgwa.colormap;
+
+#ifdef HAVE_XDBE
+  nodb = get_boolean_resource("nodb", "Boolean");
+  if(nodb) {
+    c->has_dbe = False;
+  } else {
+    c->has_dbe = XdbeQueryExtension(dpy, &major, &minor);
+  }
+#endif /* HAVE_XDBE */
+
+#ifdef HAVE_XSHM_EXTENSION
+  c->use_shm = !get_boolean_resource("noshm", "Boolean");
+#endif /*  HAVE_XSHM_EXTENSION */
+
+#ifdef HAVE_XDBE
+  if (!c->has_dbe)
+#endif /* HAVE_XDBE */
+    {
+      c->dbuf = XCreatePixmap(dpy, win, xgwa.width, xgwa.height, xgwa.depth);
+      val.function = GXcopy;
+    }
+
+  c->copy_gc = XCreateGC(c->dpy, c->dbuf, GCFunction, &val);
+
+  c->count = get_integer_resource("count", "Integer");
+  if(c->count < 1)
+    c->count = 1;
+  c->grid_size = get_integer_resource("gridsize", "Integer");
+  if(c->grid_size < 1)
+    c->grid_size = 1;
+  mono = get_boolean_resource("mono", "Boolean");
+  if(!mono) {
+    c->colors = get_integer_resource("ncolors", "Integer");
+    if(c->colors < 2)
+      c->colors = 2;
+  }
+  c->speed = get_integer_resource("speed", "Integer");
+  c->shift = get_float_resource("color-shift", "Float");
+  while(c->shift >= 360.0)
+    c->shift -= 360.0;
+  while(c->shift <= -360.0)
+    c->shift += 360.0;
+  c->radius = get_integer_resource("radius", "Integer");;
+  if(c->radius < 1)
+    c->radius = 1;
+
+#ifdef USE_XIMAGE
+
+# ifdef HAVE_XSHM_EXTENSION
+
+  if (c->use_shm)
+    {
+      c->ximage = XShmCreateImage(dpy, xgwa.visual, xgwa.depth,
+                                 ZPixmap, 0, &c->shm_info,
+                                 xgwa.width, c->grid_size);
+      c->shm_info.shmid = shmget(IPC_PRIVATE,
+                                c->ximage->height * c->ximage->bytes_per_line,
+                                IPC_CREAT | 0777);
+      if (c->shm_info.shmid == -1)
+       printf ("shmget failed!");
+      c->shm_info.readOnly = False;
+      c->ximage->data = shmat(c->shm_info.shmid, 0, 0);
+      printf("data=0x%X %d %d\n", c->ximage->data,
+            c->ximage->height, c->ximage->bytes_per_line);
+      XShmAttach(dpy, &c->shm_info);
+      XSync(dpy, False);
+    }
+  else
+# endif /* HAVE_XSHM_EXTENSION */
+    {
+      c->ximage =
+       XCreateImage (dpy, xgwa.visual,
+                     xgwa.depth, ZPixmap, 0, 0, /* depth, fmt, offset, data */
+                     xgwa.width, c->grid_size,  /* width, height */
+                     8, 0);                     /* pad, bpl */
+      c->ximage->data = (unsigned char *)
+       calloc(c->ximage->height, c->ximage->bytes_per_line);
+    }
+#endif /* USE_XIMAGE */
+
+  if(!mono) {
+    c->pal = calloc(c->colors, sizeof(XColor));
+
+    srand48(time(NULL));
+
+    gray = get_boolean_resource("gray", "Boolean");
+    if(!gray) {
+      H[0] = drand48()*360.0; 
+      H[1] = H[0] + c->shift < 360.0 ? H[0]+c->shift : H[0] + c->shift-360.0; 
+      H[2] = H[1] + c->shift < 360.0 ? H[1]+c->shift : H[1] + c->shift-360.0; 
+      S[0] = S[1] = S[2] = 1.0;
+      V[0] = V[1] = V[2] = 1.0;
+    } else {
+      H[0] = H[1] = H[2] = 0.0;
+      S[0] = S[1] = S[2] = 0.0;
+      V[0] = 1.0; V[1] = 0.5; V[2] = 0.0;
+    }
+
+    make_color_loop(c->dpy, c->cmap, 
+                   H[0], S[0], V[0], 
+                   H[1], S[1], V[1], 
+                   H[2], S[2], V[2], 
+                   c->pal, &(c->colors), 
+                   True, False);
+    if(c->colors < 2) { /* color allocation failure */
+      mono = 1;
+      free(c->pal);
+    }
+  }
+
+  if(mono) { /* DON'T else this with the previous if! */
+    c->colors = 2;
+    c->pal = calloc(2, sizeof(XColor));
+    c->pal[0].pixel = BlackPixel(c->dpy, DefaultScreen(c->dpy));
+    c->pal[1].pixel = WhitePixel(c->dpy, DefaultScreen(c->dpy));
+  }    
+
+#ifdef HAVE_XDBE
+  if(c->has_dbe)
+    c->buf = XdbeAllocateBackBufferName(c->dpy, c->win, XdbeUndefined);
+#endif /* HAVE_XDBE */
+
+  valmask = GCForeground;
+  c->gcs = calloc(c->colors, sizeof(GC));
+  for(i = 0; i < c->colors; i++) {
+    val.foreground = c->pal[i].pixel;    
+    c->gcs[i] = XCreateGC(c->dpy, TARGET(c), valmask, &val);
+  }
+
+  c->wave_height = calloc(c->radius, sizeof(int));
+  for(i = 0; i < c->radius; i++) {
+    float max = 
+      ((float)c->colors) * 
+      ((float)c->radius - (float)i) /
+      ((float)c->radius);
+    c->wave_height[i] = 
+      (int)
+      ((max + max*cos((double)i/50.0)) / 2.0);
+  }
+
+  c->source = calloc(c->count, sizeof(struct inter_source));
+  for(i = 0; i < c->count; i++) {
+    c->source[i].x_theta = drand48()*2.0*3.14159;
+    c->source[i].y_theta = drand48()*2.0*3.14159;
+  }
+
+}
+
+#define source_x(c, i) \
+  (c->w/2 + ((int)(cos(c->source[i].x_theta)*((float)c->w/2.0))))
+#define source_y(c, i) \
+  (c->h/2 + ((int)(cos(c->source[i].y_theta)*((float)c->h/2.0))))
+
+/*
+ * this is rather suboptimal. the sqrt() doesn't seem to be a big
+ * performance hit, but all those separate XFillRectangle()'s are.
+ * hell, it's just a quick hack anyway -- if someone wishes to tune
+ * it, go ahead! 
+ */
+
+void do_inter(struct inter_context* c) 
+{
+  int i, j, k;
+  int result;
+  int dist;
+#ifdef HAVE_XDBE
+  XdbeSwapInfo info[1];
+#endif /* HAVE_XDBE */
+  int g;
+
+  int dx, dy;
+
+  for(i = 0; i < c->count; i++) {
+    c->source[i].x_theta += (c->speed/1000.0);
+    if(c->source[i].x_theta > 2.0*3.14159)
+      c->source[i].x_theta -= 2.0*3.14159;
+    c->source[i].y_theta += (c->speed/1000.0);
+    if(c->source[i].y_theta > 2.0*3.14159)
+      c->source[i].y_theta -= 2.0*3.14159;
+    c->source[i].x = source_x(c, i);
+    c->source[i].y = source_y(c, i);
+  }
+
+  g = c->grid_size;
+
+  for(j = 0; j < c->h/g; j++) {
+    for(i = 0; i < c->w/g; i++) {
+      result = 0;
+      for(k = 0; k < c->count; k++) {
+       dx = i*g + g/2 - c->source[k].x;
+       dy = j*g + g/2 - c->source[k].y;
+       dist = sqrt(dx*dx + dy*dy); /* what's the performance penalty here? */
+       result += (dist > c->radius ? 0 : c->wave_height[dist]);
+      }
+      result %= c->colors;
+
+#ifdef USE_XIMAGE
+      /* Fill in these `gridsize' horizontal bits in the scanline */
+      for(k = 0; k < g; k++)
+       XPutPixel(c->ximage, (g*i)+k, 0, c->pal[result].pixel);
+
+#else  /* !USE_XIMAGE */
+      XFillRectangle(c->dpy, TARGET(c), c->gcs[result], g*i, g*j, g, g); 
+#endif /* !USE_XIMAGE */
+    }
+
+#ifdef USE_XIMAGE
+
+    /* Only the first scanline of the image has been filled in; clone that
+       scanline to the rest of the `gridsize' lines in the ximage */
+    for(k = 0; k < (g-1); k++)
+      memcpy(c->ximage->data + (c->ximage->bytes_per_line * (k + 1)),
+            c->ximage->data + (c->ximage->bytes_per_line * k),
+            c->ximage->bytes_per_line);
+
+    /* Move the bits for this horizontal stripe to the server. */
+#ifdef HAVE_XSHM_EXTENSION
+    if (c->use_shm)
+      {
+       /* wtf? we get a badmatch unless ximage->data == 0 ? */
+       char *d = c->ximage->data;
+       c->ximage->data = 0;
+       XShmPutImage(c->dpy, TARGET(c), c->copy_gc, c->ximage,
+                    0, 0, 0, g*j, c->ximage->width, c->ximage->height,
+                    False);
+       c->ximage->data = d;
+      }
+    else
+#endif /*  HAVE_XSHM_EXTENSION */
+      XPutImage(c->dpy, TARGET(c), c->copy_gc, c->ximage,
+               0, 0, 0, g*j, c->ximage->width, c->ximage->height);
+
+#endif /* USE_XIMAGE */
+  }
+
+#ifdef HAVE_XDBE
+  if(c->has_dbe)
+    {
+      info[0].swap_window = c->win;
+      info[0].swap_action = XdbeUndefined;
+      XdbeSwapBuffers(c->dpy, info, 1);
+    }
+  else
+#endif /* HAVE_XDBE */
+    {
+      XCopyArea (c->dpy, c->dbuf, c->win, c->copy_gc,
+                0, 0, c->w, c->h, 0, 0);
+    }
+  XSync(c->dpy, False);
+}
+
+void screenhack(Display *dpy, Window win) 
+{
+  struct inter_context c;
+  int delay;
+
+  delay = get_integer_resource("delay", "Integer");
+
+  inter_init(dpy, win, &c);
+  while(1) {
+    do_inter(&c); 
+    if(delay) 
+      usleep(delay);
+  }
+}
index 07e9303da3fef7ccd8e5f16e4d47038b6d48fa80..892315e73036268966985e6f4ae3c8976ba4f8cb 100644 (file)
@@ -533,8 +533,8 @@ done(void)
 char *progclass = "Jigsaw";
 
 char *defaults [] = {
-  "Jigsaw.background:  Black",         /* to placate SGI */
-  "Jigsaw.foreground:  Gray40",
+  "*background:                Black",
+  "*foreground:                Gray40",
   "*delay:             70000",
   "*delay2:            5",
   0
index c6d7a98189bb26eac24cf1be7319e90c2f28ac8c..22f4a9b0319917d9f317883aa70dfe05fd5b69cf 100644 (file)
@@ -83,8 +83,8 @@ OBJECT *objects;
 
 char *progclass = "Kaleidescope";
 char *defaults [] = {
-  "Kaleidescope.background:    black",         /* to placate SGI */
-  "Kaleidescope.foreground:    white",
+  "*background:             black",
+  "*foreground:             white",
   "*color_mode:      nice",
   "*symmetry:         11",
   "*ntrails:         100",
@@ -126,13 +126,13 @@ static void
 krandom_color(XColor *color)
 {
   int r;
-  r = ya_random() % 3;
+  r = random() % 3;
 
   if((g.color_mode == 0) || (g.color_mode == 1)) {
 
-    color->blue  = ((r = ya_random()) % g.bluerange) + g.bluemin;
-    color->green = ((r = ya_random()) % g.greenrange) + g.greenmin;
-    color->red   = ((r = ya_random()) % g.redrange) + g.redmin;
+    color->blue  = ((r = random()) % g.bluerange) + g.bluemin;
+    color->green = ((r = random()) % g.greenrange) + g.greenmin;
+    color->red   = ((r = random()) % g.redrange) + g.redmin;
 
     if(!XAllocColor(g.dpy, g.cmap, color)) {
       color->pixel = g.default_fg_pixel;
@@ -227,10 +227,10 @@ init_ksegment (OBJECT *obj)
 {
 
   /* Give the segment some random values */
-  ((Ksegment *)obj->cur)->x1 = ya_random() % g.xoff;
-  ((Ksegment *)obj->cur)->y1 = ya_random() % g.yoff;
-  ((Ksegment *)obj->cur)->x2 = ya_random() % g.xoff;
-  ((Ksegment *)obj->cur)->y2 = ya_random() % g.yoff;
+  ((Ksegment *)obj->cur)->x1 = random() % g.xoff;
+  ((Ksegment *)obj->cur)->y1 = random() % g.yoff;
+  ((Ksegment *)obj->cur)->x2 = random() % g.xoff;
+  ((Ksegment *)obj->cur)->y2 = random() % g.yoff;
 }
 
 
@@ -434,20 +434,9 @@ init_g (Display *dpy, Window window)
   g.erase_gc     = XCreateGC (dpy, (Drawable) window, GCForeground|GCLineWidth|GCCapStyle,&gcv);
 }
 
-static void
-init_rand (void)
-{
-  time_t t;
-  time(&t);
-
-/*   ya_rand_init(((unsigned int) t) % 3600 ); */
-  ya_rand_init(((unsigned int) t));
-}
-
 void
 screenhack (Display *dpy, Window window)
 {
-  init_rand();
   init_g (dpy, window);
   create_objects();
   init_objects ();
index 9150bb299718efa34653c889005b9af237851068..a037f3db3eac2762420f676560738ae42812eb30 100644 (file)
@@ -1324,8 +1324,8 @@ enter_square (int n)                      /* move into a neighboring square */
 char *progclass = "Maze";
 
 char *defaults[] = {
-  "Maze.background:    black",         /* to placate SGI */
-  "Maze.foreground:    white",         /* to placate SGI */
+  "*background:        black",
+  "*foreground:        white",
   "*gridSize:  0",
   "*solveDelay:        5000",
   "*preDelay:  2000000",
index 7d9798c212907af04c98dd22d579d32a156b9ac7..9ce9097d8c0320e8a764efb0d8748b07e3176ce3 100644 (file)
@@ -161,8 +161,8 @@ moire (Display *dpy, Window window, int offset, XColor *colors, int ncolors)
 char *progclass = "Moire";
 
 char *defaults [] = {
-  "Moire.background:   blue",          /* to placate SGI */
-  "Moire.foreground:   red",
+  "*background:                blue",
+  "*foreground:                red",
   "*random:            true",
   "*delay:             5",
   "*ncolors:           64",
index 463478c674a6429287cf4e92dd2c131e646ec5e7..61d68c7081c5f425aa3a17c55b8c0a5e04f249d1 100644 (file)
@@ -13,7 +13,7 @@
 #include <X11/Xutil.h>
 #include <stdio.h>
 
-static int ncolors, color_shift;
+static int ncolors;
 static XColor *colors = 0;
 static int fg_pixel, bg_pixel;
 static Pixmap p0 = 0, p1 = 0, p2 = 0, p3 = 0;
@@ -207,8 +207,8 @@ moire2 (Display *dpy, Window window)
 char *progclass = "Moire2";
 
 char *defaults [] = {
-  "Moire2.background:  black",         /* to placate SGI */
-  "Moire2.foreground:  white",
+  "*background:                black",
+  "*foreground:                white",
   "*delay:             50000",
   "*thickness:         0",
   "*colors:            150",
index d1f2ea6b68a33da6b22204afb3a5d81f8a2fdd30..b686b95a245c8eab4bcb21c0db216fdb81d3a7af 100644 (file)
@@ -44,8 +44,8 @@
 char *progclass = "Munch";
 
 char *defaults [] = {
-    "Munch.background: black",         /* to placate SGI */
-    "Munch.foreground: white",
+    "*background:      black",
+    "*foreground:      white",
     "*delay:           5000",
     "*hold:            100000",
     "*clear:           50",
index aa0f1c6c39765bedbce1d44bcb65842e4f9eaf86..606e9fef37a26c796bdad0026e19dd2945da7b2a 100644 (file)
@@ -610,8 +610,8 @@ get_words (void)
 char *progclass = "Noseguy";
 
 char *defaults [] = {
-  "Noseguy.background: black",         /* to placate SGI */
-  "Noseguy.foreground: gray80",
+  "*background:                black",
+  "*foreground:                gray80",
 #ifndef VMS
   "*mode:              program",
 #else
index ab9dccb037027e21e684159dae35b704bcb5ca83..5d11097da502fc5c272a9dbe94fad3c98846dd2a 100644 (file)
@@ -351,8 +351,8 @@ char *progclass = "Pedal";
  * should be dark.
  */
 char *defaults [] = {
-  "Pedal.background:           black",         /* to placate SGI */
-  "Pedal.foreground:           white",
+  "*background:                        black",
+  "*foreground:                        white",
   "*delay:                     5",
   "*fadedelay:                 200000",
   "*maxlines:                  1000",
index 3b0a1d2dbbec5e305e3ee9f211323dc6c465b2e3..4aa71da73800995b4fcd2a5398d2c2f65fa98546 100644 (file)
@@ -223,8 +223,8 @@ pyro (Display *dpy, Window window, Colormap cmap)
 char *progclass = "Pyro";
 
 char *defaults [] = {
-  "Pyro.background:    black",         /* to placate SGI */
-  "Pyro.foreground:    white",
+  "*background:        black",
+  "*foreground:        white",
   "*count:     100",
   "*frequency: 30",
   "*scatter:   20",
index 24ea10bafbe078983767d16c9746b722449ff21e..c86bf646265c5e8b37481ea40389de9e15ce292f 100644 (file)
@@ -454,8 +454,8 @@ qix1 (Display *dpy, Window window, struct qix *qix)
 char *progclass = "Qix";
 
 char *defaults [] = {
-  "Qix.background:     black",         /* to placate SGI */
-  "Qix.foreground:     white",
+  "*background:        black",
+  "*foreground:        white",
   "*count:     1",
   "*segments:  50",
   "*poly:      2",
index f3d04c21afe5ecda853a30cbf179b615e4d77e5c..65295710ba6d5624f5c791b2c58888b3584a8f54 100644 (file)
@@ -282,8 +282,8 @@ char *progclass = "RD";
 
 
 char *defaults [] = {
-  "RD.background:      black",         /* to placate SGI */
-  "RD.foreground:      white",
+  "*background:        black",
+  "*foreground:        white",
   "*width:     0",                     /* tried to use -1 but it complained */
   "*height:    0",
   "*epoch:     40000",
@@ -441,7 +441,7 @@ screenhack (Display *dpy, Window win)
     int i, di;
     mc = (unsigned char *) malloc(1<<16);
     for (i = 0; i < (1<<16); i++) {
-      di = (i + (ya_random()&255))>>8;
+      di = (i + (random()&255))>>8;
       if (di > 255) di = 255;
       mc[i] = di;
     }
index 8b12fa76d8d4a61521530e6aa8af1971a8511c1e..fa5e504840ceeb8da2c9a6c32225852f558bfbf9 100644 (file)
@@ -488,8 +488,8 @@ init_rocks (Display *d, Window w)
 char *progclass = "Rocks";
 
 char *defaults [] = {
-  "Rocks.background:   Black",         /* to placate SGI */
-  "Rocks.foreground:   #E9967A",
+  "*background:        Black",
+  "*foreground:        #E9967A",
   "*colors:    5",
   "*count:     100",
   "*delay:     50000",
index 627f1eb636b112baa5e444ae4c500921d4eae621..d6e0e2252c69a3cf82d0173f956bb5015ea78306 100644 (file)
@@ -108,8 +108,8 @@ hurm (Display *dpy, Window window)
 char *progclass = "Rorschach";
 
 char *defaults [] = {
-  "Rorschach.background:       black",         /* to placate SGI */
-  "Rorschach.foreground:       white",
+  "*background:        black",
+  "*foreground:        white",
   "*xsymmetry: true",
   "*ysymmetry: false",
   "*iterations:        4000",
index ace18c57e88e58660854bed43c8c641a44e1504b..86789e4800a594caa72e63c0cd4dd1060f5ed7fc 100644 (file)
 #include <X11/CoreP.h>
 #include <X11/Shell.h>
 #include <X11/StringDefs.h>
+
+#ifdef __sgi
+# include <X11/SGIScheme.h>    /* for SgiUseSchemes() */
+#endif /* __sgi */
+
 #ifdef HAVE_XMU
 # ifndef VMS
 #  include <X11/Xmu/Error.h>
@@ -165,6 +170,19 @@ main (int argc, char **argv)
   pre_merge_options ();
 #endif
   merge_options ();
+
+#ifdef __sgi
+  /* We have to do this on SGI to prevent the background color from being
+     overridden by the current desktop color scheme (we'd like our backgrounds
+     to be black, thanks.)  This should be the same as setting the
+     "*useSchemes: none" resource, but it's not -- if that resource is
+     present in the `default_defaults' above, it doesn't work, though it
+     does work when passed as an -xrm arg on the command line.  So screw it,
+     turn them off from C instead.
+   */
+  SgiUseSchemes ("none"); 
+#endif /* __sgi */
+
   toplevel = XtAppInitialize (&app, progclass, merged_options,
                              merged_options_size, &argc, argv,
                              merged_defaults, 0, 0);
index fa5a7124c26f09a2af648abeffbadaa03d058d8d..75880b5b7da4e36a1b7b33ce16f97d7db3036273 100644 (file)
@@ -422,8 +422,8 @@ run_starfish (Display *dpy, Window window, struct starfish *s)
 char *progclass = "Starfish";
 
 char *defaults [] = {
-  "Starfish.background:        black",         /* to placate SGI */
-  "Starfish.foreground:        white",
+  "*background:                black",
+  "*foreground:                white",
   "*delay:             10000",
   "*cycleDelay:                100000",
   "*thickness:         0",             /* pixels, 0 = random */
diff --git a/hacks/truchet.c b/hacks/truchet.c
new file mode 100644 (file)
index 0000000..66cec3d
--- /dev/null
@@ -0,0 +1,525 @@
+/* truchet --- curved and straight tilings
+ * Copyright (c) 1998 Adrian Likins <adrian@gimp.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
+
+/* This screensaver draws two varieties of truchet patterns, a curved one and
+   a straight one. There are lots and lots of command line options to play
+   with.
+
+   If your running remotely or on a slow machine or slow xserver, some of the
+   settings will be way too much. The default settings should be okay though. 
+
+   This screensaver doesnt use anything bizarre or special at all, just a few
+   standard xlib calls.
+
+   A few suggested commandline combos..All these were tested on a k6-200
+   running XFree86 3.3 on a ark2000, so your mileage may vary...
+
+      truchet -delay 200 -no-curves
+      truchet -delay 500 -no-curves -square -no-erase
+      truchet -delay 500 -no-erase -square -erase-count 5
+      truchet -scroll
+      truchet -scroll -no-erase -anim-step-size 9
+      truchet -delay 200 -no-angles -min-width 36 -max-width 36
+      truchet -delay 200 -no-curves -min-width 12 -max-width 12
+      truchet -delay 200 -no-curves -min-width 36 -max-width 36 -no-erase
+      truchet -delay 100 -min-width 256 -max-width 512 -no-erase \
+              -min-linewidth 96 -root
+      truchet -min-width 64 -max-width 128 -no-erase -max-linewidth 4 \
+              -root -no-angles
+      truchet -min-width 64 -max-width 128 -no-erase -max-linewidth 4 \
+              -root -no-curves -delay 25
+ */
+
+#include "screenhack.h"
+
+#define MAXRATIO 2
+
+
+char *progclass="Truchet";
+
+char *defaults [] = {
+  "*minWidth:                 40",
+  "*minHeight:                40",
+  "*max-Width:                150",
+  "*max-Height:               150",
+  "*maxLineWidth:             25",
+  "*minLineWidth:             2",
+  "*erase:                    True",
+  "*eraseCount:               25",        
+  "*square:                   True",
+  "*delay:                    1000",
+  "*curves:                   True",
+  "*angles:                   True",
+  "*angles-and-curves:        True",
+  "*scroll:                   False",
+  "*scroll-overlap:           400",
+  "*anim-delay:               100",
+  "*anim-step-size:           3",
+  "*randomize:               false",
+   0
+};
+
+/* options passed to this program */
+XrmOptionDescRec options [] = {
+  { "-min-width",      ".minWidth",       XrmoptionSepArg, 0 },
+  { "-max-height",     ".max-Height",      XrmoptionSepArg, 0 },
+  { "-max-width",      ".max-Width",       XrmoptionSepArg, 0 },
+  { "-min-height",     ".minHeight",      XrmoptionSepArg, 0 },
+  { "-max-linewidth",  ".maxLineWidth",   XrmoptionSepArg, 0 },
+  { "-min-linewidth",  ".minLineWidth",   XrmoptionSepArg, 0 },
+  { "-erase",          ".erase",          XrmoptionNoArg, "True" },
+  { "-no-erase",       ".erase",          XrmoptionNoArg, "False" },
+  { "-erase-count",    ".eraseCount",     XrmoptionSepArg, 0 },
+  { "-square",         ".square",         XrmoptionNoArg, "True" },
+  { "-not-square",     ".square",         XrmoptionNoArg, "False" },
+  { "-curves",         ".curves",         XrmoptionNoArg, "True" },
+  { "-angles",         ".angles",         XrmoptionNoArg,  "True" },
+  { "-no-angles",      ".angles",         XrmoptionNoArg,  "False" },
+  { "-no-curves",      ".curves",         XrmoptionNoArg, "False" },
+  { "-delay",          ".delay",          XrmoptionSepArg, 0 },
+  { "-scroll",         ".scroll",         XrmoptionNoArg, "True" },
+  { "-scroll-overlap", ".scroll-overlap", XrmoptionSepArg, 0 },
+  { "-anim-delay",     ".anim-delay",     XrmoptionSepArg, 0 },
+  { "-anim-step-size",  ".anim-step-size", XrmoptionSepArg, 0 },
+  { "-randomize",      ".randomize",     XrmoptionNoArg, "True" },
+  { 0, 0, 0, 0 }
+};
+
+static GC agc, bgc;
+static int linewidth;
+static int width, height;
+static XWindowAttributes xgwa;
+static Pixmap frame;
+static int overlap;
+
+static void draw_truchet(Display *disp, Window win);
+static void draw_angles(Display *disp, Window win);
+static void scroll_area(Display *disp, Window win, int delay, int step_size);
+
+static void draw_angles(Display *disp, Window win)
+{
+  int countX;
+  int countY;
+
+  countX=0;
+  countY=0;
+  
+  while((xgwa.height+overlap) > countY*height)
+       {
+         while((xgwa.width+overlap) > countX*width)
+           {
+             if(random()%2)
+             {
+               /* block1 */
+               XDrawLine(disp,frame,agc,
+                         (countX*width)+(width/2),
+                         (countY*height), 
+                         (countX*width)+(width),
+                         (countY*height)+(height/2));
+               XDrawLine(disp,frame,agc,
+                         (countX*width), 
+                         (countY*height)+(height/2),
+                         (countX*width)+(width/2),
+                         (countY*height)+(height));
+             }
+           else
+             {
+               /* block 2 */
+               XDrawLine(disp,frame,agc, 
+                         (countX*width)+(width/2),
+                         (countY*height),
+                         (countX*width),
+                         (countY*height)+(height/2));
+               XDrawLine(disp,frame,agc,
+                         (countX*width)+(width),
+                         (countY*height)+(height/2),
+                         (countX*width)+(width/2),
+                         (countY*height)+(height)); 
+             }
+             countX++;
+           }
+         countY++;
+         countX=0;
+       }
+
+  countX=0;
+  countY=0;
+}
+  
+
+static void draw_truchet(Display *disp, Window win)
+{
+  int countX;
+  int countY;
+
+
+  countX=0;
+  countY=0;
+
+
+  while(xgwa.height+overlap > countY*height)
+       {
+         while(xgwa.width+overlap > countX*width)
+           {
+             if(random()%2)
+             {
+               /* block1 */
+               XDrawArc(disp, frame, agc,
+                        ((countX*width)-(width/2)),
+                        ((countY*height)-(height/2)),
+                        width,
+                        height,
+                        0, -5760);
+               XDrawArc(disp,frame, agc,
+                        ((countX*width)+(width/2)),
+                        ((countY*height)+(height/2)),
+                        width,
+                        height,
+                        11520,
+                        -5760);
+             }
+           else
+             {
+               /* block 2 */
+               XDrawArc(disp,frame,agc,
+                        ((countX*width)+(width/2)),
+                        ((countY*height)-(height/2)),
+                        width,
+                        height,
+                        17280,
+                        -5760);
+               XDrawArc(disp,frame,agc,
+                        ((countX*width)-(width/2)),
+                        ((countY*height)+(height/2)),
+                        width,
+                        height,
+                        0,
+                        5760);
+             }
+             countX++;
+           }
+         countY++;
+         countX=0;
+       }
+   countX=0;
+   countY=0;
+}
+/* this is the function called for your screensaver */
+void screenhack(Display *disp, Window win)
+{
+  XGCValues gcv;
+  int countX;
+  int countY;
+  int maxlinewidth;
+  int minlinewidth;
+  int minwidth;
+  int minheight;
+  int max_height; 
+  int max_width; 
+  int delay;
+  int count;
+  int anim_delay;
+  int anim_step_size;
+
+
+  Colormap cmap;
+  XColor fgc;
+  Bool curves;
+  Bool square;
+  Bool angles;
+  Bool erase;
+  Bool eraseCount;
+  Bool scroll;
+  
+
+  maxlinewidth = get_integer_resource ("maxLineWidth", "Integer");
+  minlinewidth = get_integer_resource ("minLineWidth", "Integer");
+  minwidth = get_integer_resource ("minWidth", "Integer");
+  minheight = get_integer_resource ("minHeight", "Integer");
+  max_width = get_integer_resource ("max-Width", "Integer"); 
+  max_height = get_integer_resource ("max-Height", "Integer" ); 
+  delay = get_integer_resource ("delay", "Integer");
+  eraseCount = get_integer_resource ("eraseCount", "Integer");
+  square = get_boolean_resource ("square", "Boolean");
+  curves = get_boolean_resource ("curves", "Boolean");
+  angles = get_boolean_resource ("angles", "Boolean");
+  erase = get_boolean_resource ("erase", "Boolean");
+  scroll = get_boolean_resource ("scroll", "Boolean");
+  overlap = get_integer_resource ("scroll-overlap", "Integer");
+  anim_delay = get_integer_resource ("anim-delay", "Integer");
+  anim_step_size = get_integer_resource ("anim-step-size", "Integer");
+
+  if (get_boolean_resource("randomize", "Randomize"))
+    {
+      int i = (random() % 12);
+      switch(i) {
+      case 0:
+       break;
+      case 1:
+       curves = False;
+       break;
+      case 2:
+       curves = False;
+       square = True;
+       erase = False;
+       break;
+      case 3:
+       square = True;
+       erase = False;
+       eraseCount = 5;
+       break;
+      case 4:
+       scroll = True;
+       break;
+      case 5:
+       scroll = True;
+       erase = False;
+       anim_step_size = 9;
+       break;
+      case 6:
+       angles = False;
+       minwidth = max_width = 36;
+       break;
+      case 7:
+       curves = False;
+       minwidth = max_width = 12;
+       break;
+      case 8:
+       curves = False;
+       erase = False;
+       minwidth = max_width = 36;
+       break;
+      case 9:
+       erase = False;
+       minwidth = 256;
+       max_width = 512;
+       minlinewidth = 96;
+       break;
+      case 10:
+       angles = False;
+       minwidth = 64;
+       max_width = 128;
+       maxlinewidth = 4;
+       break;
+      case 11:
+       curves = False;
+       minwidth = 64;
+       max_width = 128;
+       maxlinewidth = 4;
+       break;
+      default:
+       abort();
+       break;
+      }
+    }
+
+  XGetWindowAttributes (disp, win, &xgwa);
+  gcv.foreground = BlackPixel(disp,0);
+  gcv.background = WhitePixel(disp,0);
+  gcv.line_width = 25;
+  cmap = xgwa.colormap;
+
+  gcv.foreground = get_pixel_resource("background", "Background",
+                                     disp, xgwa.colormap);
+
+  bgc = XCreateGC (disp, win, GCForeground, &gcv);
+  agc = XCreateGC(disp, win, GCForeground, &gcv);
+
+  XFillRectangle(disp, win, bgc, 0, 0, xgwa.width, xgwa.height);
+
+  width=60;
+  height=60;
+  linewidth=1;
+  countX=0;
+  countY=0;
+  count=0;
+  XSetForeground(disp, agc, gcv.background);
+  
+  
+  frame = XCreatePixmap(disp,win, xgwa.width+overlap, xgwa.height+overlap, xgwa.depth); 
+  
+
+  while(1)
+    {
+      if (!mono_p)
+       {
+       /* XXX there are probably bugs with this. */
+        /* could be...I just borrowed this code from munch */
+
+       fgc.red = random() % 65535;
+       fgc.green = random() % 65535;
+       fgc.blue = random() % 65535;
+       
+       if (XAllocColor(disp, cmap, &fgc)) 
+         {
+           XSetForeground(disp, agc, fgc.pixel);
+         }
+       else
+         {
+           /* use white if all else fails  */
+           XSetForeground(disp,agc, gcv.background);
+         }
+      }
+
+      
+      
+
+      /* generate a random line width */
+      linewidth=(random()% maxlinewidth);
+
+      /* check for lower bound */
+      if(linewidth < minlinewidth)
+       linewidth = minlinewidth;
+
+      /* try to get an odd linewidth as it seem to work a little better */
+      if(linewidth%2)
+       linewidth++;
+
+      /* grab a random height and width */ 
+      width=(random()%max_width);
+      height=(random()%max_height);
+
+      /* make sure we dont get a 0 height or width */
+      if(width == 0 || height == 0)
+       {
+         height=max_height;
+         width=max_width;
+       }
+
+
+      /* check for min height and width */
+      if(height < minheight)
+       {
+         height=minheight;
+       }
+      if(width < minwidth)
+       {
+         width=minwidth;
+       }
+
+      /* if tiles need to be square, fix it... */
+      if(square)
+       height=width;
+
+      /* check for sane aspect ratios */
+      if((width/height) > MAXRATIO) 
+       height=width;
+      if((height/width) > MAXRATIO)
+       width=height;
+      
+      /* to avoid linewidths of zero */
+      if(linewidth == 0 || linewidth < minlinewidth)
+       linewidth = minlinewidth;
+
+      /* try to keep from getting line widths that would be too big */
+      if(linewidth > 0 && linewidth >= (height/5))
+       linewidth = height/5;
+  
+      XSetLineAttributes(disp, agc, linewidth, LineSolid, CapRound, JoinRound);
+
+      if(erase || (count >= eraseCount))
+       {
+         /*  XClearWindow(disp,win); */
+         XFillRectangle(disp, frame, bgc, 0, 0, xgwa.width+overlap, xgwa.height+overlap);
+         count=0;
+       }
+            
+      if(!scroll)
+       overlap=0;
+            
+      /* do the fun stuff...*/
+      if(curves && angles)
+       {
+         if(random()%2)
+           draw_truchet(disp,win);
+         else
+           draw_angles(disp,win);
+       }
+      else if(curves && !angles)
+       draw_truchet(disp,win);
+      else if(!curves && angles)
+       draw_angles(disp,win);
+
+   
+      XCopyArea(disp,frame,win,agc,0,0,xgwa.width,xgwa.height,0,0);
+      if(scroll)
+       {
+         scroll_area(disp,win,anim_delay,anim_step_size);
+         delay = 0;
+       }
+      else
+       XSync(disp,True);
+      
+      /* the delay to try to minimize seizures */
+      usleep((delay*1000)); 
+      count++;
+      
+    }
+
+}
+
+static void scroll_area(Display *disp, Window win, int delay, int step_size)
+{
+
+  int scrollcount_x;
+  int scrollcount_y;
+  int offset;
+  int scroll;
+  /* note local delay overirdes static delay cause... */
+
+
+  scrollcount_x=0;
+  scrollcount_y=0;
+
+  offset=overlap/2;
+  scroll=overlap/4;
+  
+      /* if anyone knows a good way to generate a more random scrolling motion... */
+  while(scrollcount_x <= scroll)
+    {
+      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
+      XSync(disp,True);
+      scrollcount_x=scrollcount_x+step_size;
+      scrollcount_y=scrollcount_y+step_size;
+      usleep(1000*delay); 
+    }
+  while(scrollcount_x >= 0)
+    {
+      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
+      XSync(disp,True);
+      scrollcount_y=scrollcount_y+step_size;
+      scrollcount_x=scrollcount_x-step_size;
+      usleep(1000*delay); 
+    }
+  while(scrollcount_y >= scroll)
+    {
+      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
+      XSync(disp,True);
+      scrollcount_x=scrollcount_x-step_size;
+      scrollcount_y=scrollcount_y-step_size;
+      usleep(1000*delay); 
+    }
+  while(scrollcount_y > 0)
+    {
+      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
+      XSync(disp,True);
+      scrollcount_y=scrollcount_y-step_size;
+      scrollcount_x=scrollcount_x+step_size;
+      usleep(1000*delay); 
+    }
+  
+  XSync(disp,True);
+  scrollcount_x=0;
+  scrollcount_y=0;
+  
+}
index 445219637485f95e68a6643a36f4264348b28a3a..7bbc4079b920fbadd506fa1d78107ad44e8fed9e 100755 (executable)
 onroot=false
 verbose=false
 delay=3
+use_stdin=false
 
-if [ "$1" = "-root" ]; then
-  onroot=true
-  shift
-fi
-
-if [ "$1" = "-verbose" ]; then
-  verbose=true
-  shift
-fi
-
-if [ "$1" != "" ]; then
-  echo "usage: $0 [-root] [-verbose]" >&2
-  exit 1
-fi
-
-
-xvargs="-quick24"
-
-if [ "$onroot" = true ]; then
-  xvargs="$xvargs -root -rmode 5 -quit"
-else
-  xvargs="$xvargs -geom +0+0"
-fi
-
-screen_width=`xdpyinfo | sed -n 's/.* dimensions: *\([0-9]*\).*/\1/p'`
-
-# global vars...
-
+pid=""
 tmp=/tmp/vd$$
 tmp_rgb=$tmp-00000.rgb
-tmp_ppm=$tmp.ppm
+tmp_ppm0=$tmp-0.ppm
+tmp_ppm1=$tmp-1.ppm
 tmp_ppm2=$tmp-2.ppm
 tmp_ppm3=$tmp-3.ppm
+tmp_ppm4=$tmp-4.ppm
+
+
+getargs() {
+
+  while [ $# != 0 ]; do
+    case "$1" in
+    -root )
+      onroot=true
+      ;;
+    -verbose )
+      verbose=true
+      ;;
+    -stdin )
+      use_stdin=true
+      ;;
+    * )
+      echo "usage: $0 [ -root | -verbose | -stdin ]" >&2
+      exit 1
+      ;;
+    esac
+    shift
+  done
+
+  xvargs="-quick24"
+
+  if [ "$onroot" = true ]; then
+    xvargs="$xvargs -root -rmode 5 -noresetroot -rfg black -rbg black -viewonly"
+  else
+    xvargs="$xvargs -geom +0+0"
+  fi
+
+  screen_width=`xdpyinfo | sed -n 's/.* dimensions: *\([0-9]*\).*/\1/p'`
+}
+
 
 clean() {
-  rm -f $tmp_rgb $tmp_ppm $tmp_ppm2 $tmp_ppm3
+  rm -f $tmp_rgb $tmp_ppm1 $tmp_ppm2 $tmp_ppm3 $tmp_ppm4
+}
+
+clean2() {
+  clean
+  rm -f $tmp_ppm0
 }
 
 
 # Grab a frame of video.
 #
 grab() {
-  if [ `uname` = IRIX ]; then
+  uname=`uname`
+  if [ $uname = IRIX ]; then
     #
     # SGI's "vidtomem" returns an SGI RGB image of the default video input,
     # and has stupid non-overridable ouput-file-naming conventions.  So, let 
     # it write its file; and then convert it to a pgm.
     #
+    
     vidtomem -f $tmp
-    sgitopnm $tmp_rgb > $tmp_ppm
+    sgitopnm $tmp_rgb > $tmp_ppm1
+
     # Cut off the close-captioning blips in the NTSC overscan region.  YMMV.
     #  | pnmcut 12 7 695 477 
 
+  elif [ $uname = Linux ]; then
+
+    # Marcus Herbert says the following works with his Connectix Qcam.
+    # Don't have qcam?  Well, do something else then...  and send me a patch.
+
+    qcam > $tmp_ppm1
+
   else
     echo "$0: don't know how to grab video on this OS." >&2
-    clean
+    clean2
     exit 1
   fi
-
-
-  # I got this message from Marcus Herbert <rhoenie@chillout.org>.
-  # I'm not sure of the best way to make the presence of qcam be
-  #  auto-detected, but here's what he said, FYI...
-  #
-  #    i am using a black/white Connectix Qcam on linux and its very simple
-  #    to adept the script:
-  #
-  #    # qcam: Version 0.91
-  #    #   Options:
-  #    #   O  -x width   Set width
-  #    #   O  y height   Setheight
-  #    #   O  B bpp      Setbits per pixel
-  #    #   O  W         Auto-set white balance
-  #    #   O  E "vals"  Autoexposure mode, parameters required
-  #    #   O  D         Remove dark speckling
-  #    #   O  s val     Set scaling factor (1, 2, or 4)
-  #    #
-  #    qcam -x 320 -y 240 -B 6 -W -E 1 -D -s 1 > $tmp_ppm
-  #
-  #   You dont really need the parameters for qcam as it reads out a system
-  #   config file where you store the values for brightnes, contrast and
-  #   white balance.  But with this parameters you are independant of the
-  #   light ratios at the place the cam is set up.
-  #
-  #   Other versions of qcam (0.7, 0.96..) don't support the autoexposure and
-  #   auto- whitebalance commandline parameters. On such systems (and on
-  #   color-qcam systems) a simple qcam > $tmp_ppm (or cqcam > $tmp_ppm) is
-  #   enough.
-  #
-  #   I dont know about other systems but afaik fBSD uses the Qcam in this way:
-  #
-  #     qcamcontrol -bla -foo -bar > picture.pgm    
-  #
 }
 
 
@@ -130,135 +120,208 @@ randcolor() {
 #
 frob() {
 
-  N=`perl -e 'srand; print int(rand() * 10)'`
+  w_h=`head -2 $tmp_ppm1 | tail -1`
+  width=`echo $w_h | awk '{print $1}'`
+  height=`echo $w_h | awk '{print $2}'`
+
+  N=`perl -e 'srand; print int(rand() * 17)'`
 
   if [ "$verbose" = true ]; then
     echo "mode $N..." >&2
   fi
 
   if   [ $N = 0 ]; then
-    ppmtopgm $tmp_ppm | pgmedge | pgmtoppm `randcolor` | ppmnorm
+    ppmtopgm $tmp_ppm1 | pgmedge | pgmtoppm `randcolor` | ppmnorm
 
   elif [ $N = 1 ]; then
-    ppmtopgm $tmp_ppm | 
+    ppmtopgm $tmp_ppm1 | 
     pgmenhance | 
     pgmtoppm `randcolor`
 
   elif [ $N = 2 ]; then
-    ppmtopgm $tmp_ppm | pgmoil | pgmtoppm `randcolor`
+    ppmtopgm $tmp_ppm1 | pgmoil | pgmtoppm `randcolor`
 
   elif [ $N = 3 ]; then 
-    ppmrelief $tmp_ppm | ppmtopgm | pgmedge | ppmrelief | ppmtopgm |
+    ppmrelief $tmp_ppm1 | ppmtopgm | pgmedge | ppmrelief | ppmtopgm |
       pgmedge | pnminvert | pgmtoppm `randcolor`
 
   elif [ $N = 4 ]; then
-    ppmspread 71 $tmp_ppm > $tmp_ppm2
-    pnmarith -add $tmp_ppm $tmp_ppm2
+    ppmspread 71 $tmp_ppm1 > $tmp_ppm2
+    pnmarith -add $tmp_ppm1 $tmp_ppm2
 
   elif [ $N = 5 ]; then
-    pnmflip -lr $tmp_ppm > $tmp_ppm2
-    pnmarith -multiply $tmp_ppm $tmp_ppm2 > $tmp_ppm3
+    pnmflip -lr $tmp_ppm1 > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2 > $tmp_ppm3
     pnmflip -tb $tmp_ppm3 | ppmnorm > $tmp_ppm2
-    pnmarith -multiply $tmp_ppm $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2
 
   elif [ $N = 6 ]; then
     N2=`perl -e 'srand; print int(rand() * 3)'`
     if [ $N2 = 0 ]; then
-      pnmflip -lr $tmp_ppm > $tmp_ppm2
+      pnmflip -lr $tmp_ppm1 > $tmp_ppm2
     elif [ $N2 = 1 ]; then
-      pnmflip -tb $tmp_ppm > $tmp_ppm2
+      pnmflip -tb $tmp_ppm1 > $tmp_ppm2
     else
-      pnmflip -lr $tmp_ppm > $tmp_ppm2
+      pnmflip -lr $tmp_ppm1 > $tmp_ppm2
       pnmflip -tb $tmp_ppm2 > $tmp_ppm3
       cp $tmp_ppm3 $tmp_ppm2
     fi
 
-    pnmarith -difference $tmp_ppm $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2
 
   elif [ $N = 7 ]; then
 
     for i in 1 2 3 ; do
-      ppmtopgm $tmp_ppm | pgmedge > $tmp_ppm2
-      pnmarith -difference $tmp_ppm $tmp_ppm2 > $tmp_ppm3
-      cp $tmp_ppm3 $tmp_ppm
+      ppmtopgm $tmp_ppm1 | pgmedge > $tmp_ppm2
+      pnmarith -difference $tmp_ppm1 $tmp_ppm2 > $tmp_ppm3
+      cp $tmp_ppm3 $tmp_ppm1
     done
-    ppmnorm < $tmp_ppm
+    ppmnorm < $tmp_ppm1
 
   elif [ $N = 8 ]; then
-    pnmflip -lr $tmp_ppm > $tmp_ppm2
-    pnmarith -multiply $tmp_ppm $tmp_ppm2 | ppmrelief | ppmnorm | pnminvert
+    pnmflip -lr $tmp_ppm1 > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2 | ppmrelief | ppmnorm | pnminvert
 
   elif [ $N = 9 ]; then
-    pnmflip -lr $tmp_ppm > $tmp_ppm2
-    pnmarith -subtract $tmp_ppm $tmp_ppm2 | ppmrelief | ppmtopgm | pgmedge
+    pnmflip -lr $tmp_ppm1 > $tmp_ppm2
+    pnmarith -subtract $tmp_ppm1 $tmp_ppm2 | ppmrelief | ppmtopgm | pgmedge
+
+  elif [ $N = 10 ]; then
+    ppmtopgm $tmp_ppm1 | pgmbentley | pgmtoppm `randcolor`
 
-  else cat $tmp_ppm
+  elif [ $N = 11 ]; then
+    pgmcrater -number 20000 -height $height -width $width | pgmtoppm `randcolor` > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2 > $tmp_ppm3
+    pnmflip -tb $tmp_ppm3 | ppmnorm > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2
+
+  elif [ $N = 12 ]; then
+    ppmshift 30 $tmp_ppm1 | ppmtopgm | pgmoil | pgmedge |  pgmtoppm `randcolor` > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2 
+
+ elif [ $N = 13 ]; then
+    ppmpat -madras $width $height | pnmdepth 255 > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2
+  elif [ $N = 14 ]; then
+    ppmpat -tartan $width $height | pnmdepth 255 > $tmp_ppm2
+    pnmarith -difference  $tmp_ppm1 $tmp_ppm2 
+  
+  elif [ $N = 15 ]; then
+    ppmpat -camo $width $height | pnmdepth 255 | ppmshift 50 > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2
+  
+  elif [ $N = 16 ]; then
+    pgmnoise $width $height | pgmedge | pgmtoppm `randcolor` > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2 | pnmdepth 255 | pnmsmooth
+
+  else cat $tmp_ppm1
   fi
 }
 
 
-
 # Grab a frame and frob it.  leave it in $tmp_ppm3.
 #
 whack() {
   clean
 
-  while [ ! -f $tmp_ppm ]; do
-   grab
+  while [ ! -f $tmp_ppm1 ]; do
+    if [ "$use_stdin" != true ]; then
+      grab
+    else
+      cp $tmp_ppm0 $tmp_ppm1
+    fi
   done
 
   rm -f $tmp_rgb
   frob | pnmscale -width $screen_width > $tmp_ppm3
-  rm -f $tmp_ppm $tmp_ppm2
+  rm -f $tmp_ppm1 $tmp_ppm2
 }
 
 
-pid=""
+# Kill off the xv subprocess, if it's running
+#
+kill_pid() {
+  if [ "$pid" != "" ]; then
 
-if [ "$onroot" != true ]; then
-  trap "kill \$pid; clean; exit 1" 2 15
-fi
+    if [ "$verbose" = true ]; then
+      echo "killing pid $pid..." >&2
+    fi
 
-while true; do
+    # need to do this to avoid "6898 Terminated" messages!
+    # apparently one can't redirect the output of the builtin `kill' command.
+#    ( sh -c "kill $pid" ) >/dev/null 2>/dev/null </dev/null
 
-  # Loop grabbing and frobbing images.
-  #
-  # If we're running on the root, run xv in the foreground (with -exit)
-  # and then wait.
-  #
-  # If we're running in a window, spawn xv in the background; then when
-  # it's time to put up the new image, kill off the currently-running xv.
+    # wtf?  that doesn't work either.  Is it writing to /dev/tty??
+    kill $pid >&- >&-
 
+    pid=""
+  fi
+}
+
+# called when this process is signalled (for cleanup)
+#
+my_trap() {
   if [ "$verbose" = true ]; then
-    whack
-  else
-    whack >&- 2>&-
+    echo "trapped signal!" >&2
   fi
+  kill_pid
+  clean2
+  exit 1
+}
 
-  if [ "$pid" != "" ]; then
-    kill $pid
-    pid=""
+main() {
+
+  getargs $@
+
+  trap my_trap 0 1 2 3 6 9 13
+
+  if [ "$use_stdin" = true ]; then
+   cat > $tmp_ppm0
   fi
 
-  if [ ! -s $tmp_ppm3 ]; then
-    echo "$0: no image grabbed" >&2
-  else
+  while true; do
 
-    pnmtosgi < $tmp_ppm3 > $tmp_ppm2
-    rm -f $tmp_ppm3
+    # Loop grabbing and frobbing images.
+    #
+    # If we're running on the root, run xv in the foreground (with -exit)
+    # and then wait.
+    #
+    # If we're running in a window, spawn xv in the background; then when
+    # it's time to put up the new image, kill off the currently-running xv.
 
-    if [ "$onroot" = true ]; then
-      xv $xvargs $tmp_ppm2
+    if [ "$verbose" = true ]; then
+      whack
     else
-      xv $xvargs $tmp_ppm2 &
-      pid=$!
+      whack >&- 2>&-
     fi
 
-    #xv -geom =320x220 $tmp_ppm3 &
-    #pid=
-  fi
+    kill_pid
 
-  clean
-  sleep $delay
+    if [ ! -s $tmp_ppm3 ]; then
+      echo "$0: no image grabbed" >&2
+    else
+
+      pnmtosgi < $tmp_ppm3 > $tmp_ppm2
+      rm -f $tmp_ppm3
+
+      if [ -s $tmp_ppm2 ]; then
+        if [ "$verbose" = true ]; then
+          echo "launching xv $xvargs $tmp_ppm2" >&2
+        fi
+        xv $xvargs $tmp_ppm2 &
+        pid=$!
+      fi
+    fi
+
+    clean
+    sleep $delay
+
+  done
+  exit 1
+}
+
+main $@
 
-done
+# to find stray xv data:
+# xwininfo -root -children|grep 'xv image comments' | awk '{print $1}'
index 986491993787e9b1002037e0782550fc7dc42796..6bc76ff27c43af1bbd9df24fe39c39ecac4acc3b 100644 (file)
@@ -23,8 +23,8 @@
 char *progclass = "XJack";
 
 char *defaults [] = {
-  "XJack.background:   black",         /* to placate SGI */
-  "XJack.foreground:   #00EE00",
+  "*background:                black",
+  "*foreground:                #00EE00",
   "XJack.font:         -*-courier-medium-r-*-*-*-240-*-*-m-*-*-*",
   "*delay:             50000",
   0
index a1e71aa2e1f449809f7a42fdee5a690b0607d747..f84f4919a6c3448734bea58c60348d5629bd430f 100644 (file)
@@ -1,5 +1,5 @@
 /* xlockmore.c --- xscreensaver compatibility layer for xlockmore modules.
- * xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@netscape.com>
+ * xscreensaver, Copyright (c) 1997, 1998 Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -75,7 +75,7 @@ pre_merge_options (void)
              new->value = "True";
              new = &options[i++];
              new->option = "-no-wireframe";
-             new->specifier = options[i-1].specifier;
+             new->specifier = options[i-2].specifier;
              new->argKind = XrmoptionNoArg;
              new->value = "False";
            }
@@ -86,7 +86,7 @@ pre_merge_options (void)
              new->value = "True";
              new = &options[i++];
              new->option = "-no-3d";
-             new->specifier = options[i-1].specifier;
+             new->specifier = options[i-2].specifier;
              new->argKind = XrmoptionNoArg;
              new->value = "False";
            }
index 26dae592c499d87217cdfe71559c2c54d9e72c09..a343cfff4759176ddd169b117aa5c9e49a329625 100644 (file)
@@ -47,7 +47,8 @@
 char *progclass = "XLyap";
 
 char *defaults [] = {
-  "XLyap.background:   black",         /* to placate SGI */
+  "*background:                black",
+  "*foreground:                white",
   "*randomize:         false",
   "*builtin:           -1",
   "*minColor:          1",
@@ -785,7 +786,6 @@ init_data(void)
   if (show)
     show_defaults();
   InitBuffer();
-  ya_rand_init(0);
 }
 
 static void
@@ -1969,5 +1969,5 @@ setforcing(void)
 {
   static int i;
   for (i=0;i<MAXINDEX;i++)
-    forcing[i] = (ya_random() > prob) ? 0 : 1;
+    forcing[i] = (random() > prob) ? 0 : 1;
 }
index b76d47d12060ad979b47dc2d98bcb499a48a3fba..ec5cd5dced3d2b1bcd9d1f8bf1971eeff622a7d4 100644 (file)
--- a/setup.com
+++ b/setup.com
@@ -8,12 +8,14 @@ $ attraction  :== $'mydir'attraction
 $ blitspin     :== $'mydir'blitspin
 $ bouboule     :== $'mydir'bouboule
 $ braid                :== $'mydir'braid
+$ bsod         :== $'mydir'bsod
 $ bubbles      :== $'mydir'bubbles
 $ coral                :== $'mydir'coral
 $ cynosure     :== $'mydir'cynosure
 $ decayscreen  :== $'mydir'decayscreen
 $ deco         :== $'mydir'deco
 $ drift                :== $'mydir'drift
+$ epicycle     :== $'mydir'epicycle
 $ fadeplot     :== $'mydir'fadeplot
 $ flag         :== $'mydir'flag
 $ flame                :== $'mydir'flame
@@ -29,6 +31,7 @@ $ hopalong    :== $'mydir'hopalong
 $ hypercube    :== $'mydir'hypercube
 $ ifs          :== $'mydir'ifs
 $ imsmap       :== $'mydir'imsmap
+$ interference :== $'mydir'interference
 $ jigsaw       :== $'mydir'jigsaw
 $ julia                :== $'mydir'julia
 $ kaleidescope :== $'mydir'kaleidescope
@@ -60,6 +63,7 @@ $ starfish    :== $'mydir'starfish
 $ strange      :== $'mydir'strange
 $ swirl                :== $'mydir'swirl
 $ triangle     :== $'mydir'triangle
+$ truchet      :== $'mydir'truchet
 $ vines                :== $'mydir'vines
 $ worm         :== $'mydir'worm
 $ xjack                :== $'mydir'xjack
index 663ba2c93eeb8eb8f4312c46d008ada3922a8524..ef96cd5f64bb0e7a1da93f77e52c3ac8e8fc97ac 100644 (file)
@@ -21,7 +21,7 @@ SHELL         = /bin/sh
 
 X_CFLAGS       = @X_CFLAGS@
 
-INCLUDES       = -I$(srcdir) -I$(srcdir)/.. -I.. @INCLUDES@
+INCLUDES       = -I$(srcdir) -I.. @INCLUDES@
 
 SRCS           = alpha.c colors.c fade.c grabscreen.c hsv.c overlay.c \
                  resources.c spline.c usleep.c visual.c xmu.c xroger.c \
index 84de1cb47eb7581e56ed834aa77ea415eef9107a..ed3d31cbca13308270d339d4c46cd11e2884d284 100644 (file)
@@ -53,7 +53,7 @@ no_more_memory (void)
 }
 
 spline*
-make_spline (u_int size)
+make_spline (unsigned int size)
 {
   spline* s = (spline*)calloc (1, sizeof (spline));
   if (!s)
@@ -319,3 +319,12 @@ spline_bounding_box (spline *s, XRectangle *rectangle_out)
   rectangle_out->width = max_x - min_x;
   rectangle_out->height = max_y - min_y;
 }
+
+void
+free_spline(spline * s)
+{
+  free ((void *) s->control_x);
+  free ((void *) s->control_y);
+  free ((void *) s->points);
+  free ((void *) s);
+}
index 998c049d5af5834a0a6d2cddaa0838e457acb0b7..a5a366cbd977e50c7d7e70edbda224661a29b71a 100644 (file)
 #ifndef _SPLINE_H_
 #define _SPLINE_H_
 
-#ifdef VMS
-# ifndef __DECC
-   typedef unsigned int u_int;
-# else
-#  if __DECC_VER < 50200000
-    typedef unsigned int u_int;
-#  endif
-# endif
-#endif
-
 typedef struct _spline
 {
   /* input */
-  u_int                n_controls;
+  unsigned int n_controls;
   double*      control_x;
   double*      control_y;
 
   /* output */
-  u_int                n_points;
+  unsigned int         n_points;
   XPoint*      points;
-  u_int                allocated_points;
+  unsigned int         allocated_points;
 } spline;
 
-spline* make_spline (u_int size);
+spline* make_spline (unsigned int size);
 void compute_spline (spline* s);
 void compute_closed_spline (spline* s);
 void just_fill_spline (spline* s);
 void append_spline_points (spline* s1, spline* s2);
 void spline_bounding_box (spline* s, XRectangle* rectangle_out);
+void free_spline(spline *s);
 
 #endif /* _SPLINE_H_ */
index 5a6b2f671c1409062a70b25d899c8586cf582329..9fbd8af3545de120685f46127cb6df3af935606e 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
-       "@(#)xscreensaver 2.17, by Jamie Zawinski (jwz@netscape.com)";
+       "@(#)xscreensaver 2.21, by Jamie Zawinski (jwz@netscape.com)";
index 7368528e6262dc9f94af3dbfd85ed10642284733..6e20d120bde72fe0b627f8458918846d9e13cc4a 100644 (file)
@@ -1,7 +1,7 @@
 Begin3
 Title:          xscreensaver
-Version:        2.17
-Entered-date:   02JUN98
+Version:        2.21
+Entered-date:   15JUN98
 Description:    A modular screen saver and locker for the X Window System.
                 Highly customizable: allows the use of any program that
                 can draw on the root window as a display mode.
@@ -11,12 +11,12 @@ Keywords:       screen saver, screen lock, lock, xlock, X11
 Author:         jwz@netscape.com (Jamie Zawinski)
 Maintained-by:  jwz@netscape.com (Jamie Zawinski)
 Primary-site:   ftp.x.org /contrib/applications/
-                776K xscreensaver-2.17.tar.gz
-                17K  xscreensaver.README
+                805K xscreensaver-2.21.tar.gz
+                21K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
-                776K xscreensaver-2.17.tar.gz
-                17K  xscreensaver.README
+                805K xscreensaver-2.21.tar.gz
+                21K  xscreensaver.README
                 1K   xscreensaver.lsm
 Platforms:      Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
                 BSDI, SCO, OSF1, Ultrix, VMS.