From: Zygo Blaxell Date: Mon, 2 Mar 2009 05:42:36 +0000 (-0500) Subject: ftp://ftp.smr.ru/pub/0/FreeBSD/releases/distfiles/xscreensaver-3.16.tar.gz X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=commitdiff_plain;h=df7adbee81405e2849728a24b498ad2117784b1f ftp://ftp.smr.ru/pub/0/FreeBSD/releases/distfiles/xscreensaver-3.16.tar.gz -rw-r--r-- 1 zblaxell zblaxell 1135909 Jun 20 1999 xscreensaver-3.16.tar.gz a527b196243af5b99d0e0c26e2be40bdfa87f610 xscreensaver-3.16.tar.gz --- diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..50dbe439 --- /dev/null +++ b/INSTALL @@ -0,0 +1,183 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 00000000..00a5d99d --- /dev/null +++ b/Makefile.in @@ -0,0 +1,288 @@ +# Makefile.in --- xscreensaver, Copyright (c) 1999 Jamie Zawinski. +# the `../configure' script generates `Makefile' from this file. + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +SHELL = /bin/sh +SUBDIRS = utils driver hacks hacks/glx +TARFILES = README README.VMS README.debugging INSTALL xscreensaver.lsm \ + configure configure.in Makefile.in config.h.in \ + config.h-vms install-sh setup.com config.guess \ + config.sub makevms.com screenblank.txt \ + xscreensaver.lsm.sh xscreensaver.spec +TAR = tar +COMPRESS = gzip --verbose --best +COMPRESS_EXT = gz +# COMPRESS = compress +# COMPRESS_EXT = Z + +MAKE_SUBDIR = for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) $@) || exit 5; done + +default:: + @$(MAKE_SUBDIR) +all:: + @$(MAKE_SUBDIR) +install: + @$(MAKE_SUBDIR) +install-program: + @$(MAKE_SUBDIR) +install-man: + @$(MAKE_SUBDIR) +install-strip: + @$(MAKE_SUBDIR) +uninstall: + @$(MAKE_SUBDIR) +uninstall-program: + @$(MAKE_SUBDIR) +uninstall-man: + @$(MAKE_SUBDIR) +depend: + @$(MAKE_SUBDIR) +distdepend: + @$(MAKE) update_spec_version + @$(MAKE_SUBDIR) +TAGS: tags +tags: + @$(MAKE_SUBDIR) +clean: + @$(MAKE_SUBDIR) +distclean: clean + -rm -f config.h Makefile config.status config.cache config.log TAGS *~ "#"* + @$(MAKE_SUBDIR) + +dist: tar + +# This really makes me sick... +tar: + @ \ + sh config.status ; \ + rm -f configure ; \ + $(MAKE) configure ; \ + $(MAKE) distdepend ; \ + sh xscreensaver.lsm.sh > xscreensaver.lsm.$$$$ ; \ + mv xscreensaver.lsm.$$$$ xscreensaver.lsm ; \ + NAME=`sed -n \ + 's/[^0-9]*\([0-9]\.[0-9][0-9]*\).*/xscreensaver-\1/p' utils/version.h` ; \ + rm -rf $$NAME ; ln -s . $$NAME ; \ + FILES= ; \ + for subdir in $(SUBDIRS) ; do \ + d=`pwd` ; \ + cd $$subdir ; \ + FILES="$$FILES `$(MAKE) echo_tarfiles \ + | grep -v '^.*make\[' \ + | sed \"s|^|$$subdir/|g;s| | $$subdir/|g\" \ + ` "; \ + cd $$d ; done ; \ + echo creating tar file $${NAME}.tar.$(COMPRESS_EXT)... ; \ + $(TAR) -vchf - \ + `echo $(TARFILES) $$FILES | sed "s|^|$$NAME/|g; s| | $$NAME/|g" ` \ + | $(COMPRESS) > $${NAME}.tar.$(COMPRESS_EXT) ; \ + rm $$NAME + + +# This also makes me sick... +# autoconf generates a configure script that begins with a very hard to read, +# nearly impossible to customize --help blurb. This horrid set of regexps +# go through and clean up the help text, by inserting whitespace and ripping +# out options we don't use. Odds are good that this will fail with any version +# of autoconf other than the ones I've tried (2.12 and 2.13.) +# +configure:: + autoconf + @TMP=configure.$$$$ ; \ + echo "munging configure's --help message..." ; \ + ( perl -e ' \ + my $$file=""; \ + while (<>) { $$file .= $$_; } \ + $$_ = $$file; \ + \ + s/^(Configuration:)$$/\n$$1\n/m; \ + s/^(Directory and file names:)$$/\n$$1\n/m; \ + s/^ --sbindir=.*\n//m; \ + s/^ --libexecdir.*\n//m; \ + s/^ --datadir.*\n.*\n//m; \ + s/^ --sysconfdir.*\n//m; \ + s/^ --sharedstatedir.*\n.*\n//m; \ + s/^ --localstatedir.*\n//m; \ + s/^ --infodir.*\n//m; \ + s/^(Host type:)$$/\n$$1\n/m; \ + s/\nFeatures and packages:\n.*library files are in DIR\n/\n/s;\ + s/--enable and --with options recognized://m; \ + s/\n --with-x .*?(["\n])/$$1/s; \ + s/\n(Installation options:\n)/$$1/s; \ + \ + s/^ --oldincludedir=.*$$/ \ + --x-includes=DIR X include files are in DIR\n \ + --x-libraries=DIR X library files are in DIR/m; \ + \ + print;' \ + < configure \ + > $$TMP && \ + cat $$TMP > configure ) ; \ + rm -f $$TMP + +bump-version:: + @ \ + SRC=utils/version.h ; \ + VERS=`sed -n 's/[^0-9]*\([0-9]\)\.\([0-9][0-9]*\).*/\1 \2/p' $$SRC` ; \ + set - $$VERS ; \ + MAJOR="$$1"; MINOR="$$2"; \ + NEW=`echo $$MINOR + 1 | bc` ; \ + NEW=`echo $$NEW | sed 's/^\([0-9]\)$$/0\1/'` ; \ + D=`date '+%d-%b-%y'`; \ + if [ ! -f xscreensaver-$$MAJOR.$$MINOR.tar.gz ]; then \ + echo "WARNING: xscreensaver-$$MAJOR.$$MINOR.tar.gz does not exist."; \ + fi ; \ + if [ -f xscreensaver-$$MAJOR.$$NEW.tar.gz ]; then \ + echo "WARNING: xscreensaver-$$MAJOR.$$NEW.tar.gz already exists."; \ + fi ; \ + echo -n "Bumping $$MAJOR.$$MINOR to $$MAJOR.$$NEW ($$D), ok? "; \ + read line; \ + if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \ + exit 1 ; \ + fi ; \ + TMP=/tmp/bv.$$ ; \ + sed -e "s/\([0-9]\.[0-9][0-9]*\)/$$MAJOR.$$NEW/" \ + -e "s/\(([0-9][0-9]*-[A-Za-z][a-z][a-z]-[0-9][0-9][0-9]*\))/($$D)/" \ + $$SRC > $$TMP ; \ + echo -n "New version and date are "; \ + sed -n "s/[^0-9]*\([0-9]\.[0-9][0-9]*\) (\([-A-Za-z0-9]*\)).*/\1, \2./p" \ + $$TMP; \ + cat $$TMP > $$SRC ; \ + rm -f $$TMP; \ + echo "overwrote $$SRC"; \ + ls -lFd $$SRC + +update_spec_version:: + @S=$(srcdir)/xscreensaver.spec ; \ + U=$(srcdir)/utils/version.h ; \ + V=`sed -n 's/.*\([0-9][0-9]*\.[0-9]*\).*/\1/p' < $$U` ; \ + echo -n "Updating version number in $$S to \"$$V\"... " ; \ + T=/tmp/xs.$$$$ ; \ + sed "s/^\(Version:[^0-9]*\)\(.*\)/\1$$V/" \ + < $$S > $$T ; \ + if cmp -s $$S $$T ; then \ + echo "unchanged." ; \ + else \ + cat $$T > $$S ; \ + echo "done." ; \ + fi ; \ + rm $$T + +rpm:: + @ \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][0-9]*\).*/\1/p' utils/version.h` ; \ + DIR=/usr/src/redhat ; \ + cp -p xscreensaver-$$VERS.tar.gz $$DIR/SOURCES/ ; \ + rpm -ba xscreensaver.spec ; \ + rm -f $$DIR/xscreensaver-$$VERS.tar.gz ; \ + rm -rf $$DIR/BUILD/xscreensaver-$$VERS ; \ + mv $$DIR/RPMS/i386/xscreensaver-$$VERS-*.rpm . ; \ + mv $$DIR/SRPMS/xscreensaver-$$VERS-*.rpm . ; \ + echo '' ; \ + ls -lFG xscreensaver-$$VERS-*.rpm + +test-tar:: + @ \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][0-9]*\).*/\1/p' utils/version.h` ; \ + D=xscreensaver-$$VERS ; \ + NAME="$$D.tar.gz" ; \ + if [ ! -f $$NAME ]; then \ + echo "$$NAME does not exist! Did you forget to \`make tar'?" ; \ + exit 1 ; \ + fi ; \ + \ + set -e ; \ + set -x ; \ + \ + if [ -d $$D ]; then \ + chmod -R u+w $$D ; \ + fi ; \ + rm -rf $$D ; \ + zcat $$D.tar.gz | tar -xf - ; \ + cd $$D ; \ + chmod -R a-w . ; \ + chmod u+w . ; \ + mkdir BIN ; \ + mkdir BIN/motif ; \ + mkdir BIN/lesstif ; \ + chmod a-w . ; \ + \ + ( cd BIN/motif ; \ + CC=cc ; \ + export CC ; \ + ../../configure --without-xpm --without-xdbe --without-xshm \ + --with-motif=/usr/local/motif ; \ + echo --------------------------------------------------------------- ; \ + gmake all ; \ + ( cd driver; gmake tests ) ; \ + echo --------------------------------------------------------------- ); \ + \ + ( cd BIN/lesstif ; \ + CC=cc ; \ + export CC ; \ + ../../configure --with-motif=/usr/local/lesstif ; \ + echo --------------------------------------------------------------- ; \ + ( cd utils; gmake all ) ; \ + ( cd driver; gmake all ) ; \ + echo --------------------------------------------------------------- ); \ + \ + chmod -R u+w . + + +www:: + @ \ + DEST=$$HOME/www/xscreensaver ; \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][0-9]*\).*/\1/p' utils/version.h` ; \ + HEAD="xscreensaver-$$VERS" ; \ + NAME="$$HEAD.tar.gz" ; \ + \ + if [ ! -f $$NAME ]; then \ + echo "$$NAME does not exist! Did you forget to \`make tar'?" ; \ + exit 1 ; \ + fi ; \ + chmod a-w $$NAME ; \ + if [ -f $$DEST/$$NAME ]; then \ + echo -n "WARNING: $$DEST/$$NAME already exists! Overwrite? "; \ + read line; \ + if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \ + exit 1 ; \ + fi ; \ + fi ; \ + cp -p $$NAME $$DEST/$$NAME ; \ + chmod u+w $$DEST/$$NAME ; \ + cd $$DEST ; \ + \ + TMP=/tmp/xd.$$$$ ; \ + sed "s/xscreensaver-[0-9]\.[0-9][0-9]*/$$HEAD/g" download.html > $$TMP ; \ + echo '' ; \ + diff -u0 download.html $$TMP ; \ + echo '' ; \ + \ + OLDEST=`ls xscreensaver*.tar.gz | head -1` ; \ + echo -n "Delete $$DEST/$$OLDEST? "; \ + read line; \ + if [ "x$$line" = "xyes" -o "x$$line" = "xy" ]; then \ + set -x ; \ + rm $$OLDEST ; \ + cvs remove $$OLDEST ; \ + else \ + set -x ; \ + fi ; \ + cvs add -kb $$NAME ; \ + cat $$TMP > download.html ; \ + rm -f $$TMP ; \ + \ + (cd ..; $(MAKE) xscreensaver/changelog.html ); \ + cvs diff -u0 changelog.html ; \ + set +x ; \ + \ + echo -n "Ok? "; \ + read line; \ + if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \ + exit 1 ; \ + fi ; \ + \ + cvs commit -m "$$VERS" diff --git a/README b/README new file mode 100644 index 00000000..561e0cc0 --- /dev/null +++ b/README @@ -0,0 +1,646 @@ + + XScreenSaver + + a screen saver and locker for the X window system + by Jamie Zawinski + + http://www.jwz.org/xscreensaver/ + +To build on Unix: + + - ./configure + - make + - make install + +The `configure' shell script will attempt to figure out which options are +appropriate for your system, and will create config.h and the various +Makefiles for you. Run `configure --help' to see how to override these +choices, or to specify things like the default installation directory. +The file `INSTALL' gives a general overview of use of these sorts of +configure scripts (those generated by the GNU autoconf system.) +The most important hint is probably this: + + ./configure --with-motif=/opt/Motif --with-xpm=/usr/local + +To build on VMS, see README.VMS. + +If you are upgrading, you might want to delete your ~/.xscreensaver file. +If you don't, you might not see the new graphics modes. If you are upgrading +from version 2.* to version 3.*, definitely do delete your .xscreensaver file. + +If you think you've found a bug, please let me know! No bug report is too +small. But first, please read the enclosed `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 daemon waits until the keyboard and mouse have been idle +for a period, and then runs a graphics demo chosen at random. The demo is +terminated as soon as there is any mouse or keyboard activity (or, in +locking mode, when the proper password is typed.) + +It is trivially easy to add new display modes to xscreensaver: any program +which can be invoked in such a way that it draws on the root window of the +screen can be used as a screensaver. You just change a config file -- +there's no need to recompile or reinstall anything. + + ============ + +Along with the xscreensaver daemon itself, this package also includes +numerous graphics hacks for use as screensavers. There is nothing magic +about these: they are just programs that draw on the root window. + +More than 100 such programs are included. For details, see the xscreensaver +web page, or the enclosed manual pages. There are also some helpful hints +on customization in the xscreensaver app-defaults file (normally installed +in /usr/lib/X11/app-defaults/XScreenSaver.) + +The latest version of xscreensaver is always available on the web at +http://www.jwz.org/xscreensaver/. + + ============ + +Changes since 3.15: * New version of `shadebobs'. + * Improved image selection in `webcollage', and sped it + up slightly. + * Made configure find the right version of perl. + * Rewrote the CGI part of `webcollage'. + * `make clean' was deleting some things it shouldn't. + * Fixed a typo in the default programs list. +Changes since 3.14: * Added `webcollage' and `shadebobs' hacks. + * Added a `-stdout' arg to `vidwhacker' so that it can + be used in a pipeline. + * Made `petri' use less memory. +Changes since 3.13: * Various improvements to the Gtk port. + * Turned off PAM by default on Solaris, since PAM seems + generally to be misconfigured out-of-the-box. + * Made the `--without-gtk' configure option work. + * Made configure check the Gtk version number, since it + requires 1.2. + * Fixed a bug in the code that attempted to prevent + changes of screen resolution while the screen is + locked. + * Fixed a race condition in `xscreensaver-demo' that + could cause an X error at startup. + * Added `-transparent' option to `deluxe'. + * Added `petri' hack. +Changes since 3.12: * Ported `xscreensaver-demo' to Gtk. + * Made it possible to build Motif, Gtk, and Athena + versions of `xscreensaver-demo' in the same directory + without reconfiguring. + * Made `xscreensaver-demo' chase symlinks before writing + the .xscreensaver file, so that if .xscreensaver is + itself a symlink, the underlying file will be replaced + instead. + * Some Makefile and configure tweaks for Solaris and + FreeBSD. + * Made it possible to set the fire color in `xflame'. + * Made transparency work in TrueColor (for `goop' and + `qix'.) + * Fixed a multi-head bug introduced by the virtual + viewports stuff. +Changes since 3.11: * Made it so that you can't scroll the screen while the + lock dialog is up (with XFree86 virtual viewports.) + * Fixed a bug in `flag' that caused bob's chin to get cut + off after a few iterations. +Changes since 3.10: * Made `xjack' be black-on-white-ish, so that it looks + less like a computer screen and more like the + typewritten paper it's supposed to be. + * New version of `pulsar'. + * Fixed Solaris compilation problem in `phosphor'. + * Made xscreensaver notice XFree86's virtual root window + hack, so that if the X server's root window is larger + than the monitor's displayable resolution, the screen + saver will limit itself to the area that actually + appears on the screen. + * Made the xscreensaver daemon do a better job of + picking the visual class that should be used for GL + programs. Less user intervention should be needed + now: you can use the logical visual name `GL' instead + of having to figure out by hand which one to use. + * Oops, the visual was defaulting to "best" instead of + "default", because the .xscreensaver file was not being + loaded quite early enough. + * Made configure figure out how to build icmp ping + support into the `sonar' hack automatically. + * Made warnings about not being able to read shadow + passwords not be printed if compiled with PAM support. + * Improved PAM startup diagnostics. + * Worked around the Solaris PAM bug that was causing + crashes there, so now PAM is turned on by default. + * Made configure detect the number of arguments that + pam_strerror() takes, since on Linux, this apparently + changed between 2.0 and 2.2, sigh. + * Made the /proc/interrupts kludge look for "PS/2 Mouse" + as well as "keyboard". + * Made xscreensaver notice when there has been a sudden + large jump in wall-clock time, and if so, lock right + away, instead of waiting for "lockTimeout" to expire + first. (Laptops need this for safer recovery from + ``hibernation.'') + * Added `-throttle' option to `xscreensaver-command'. +Changes since 3.09: * Added `phosphor', `xmatrix', and `pulsar' hacks. + * Fixed a bug in the color allocator that sometimes + caused `starfish' to fall back to monochrome. + * Reduced the amount of code that runs before root + privileges are disavowed: "normal" and "shadow" + passwords now do some initialization as root, but the + PAM and Kerberos authorization schemes will be + initialized while running as "nobody". Supposedly + this closes a potential security hole when using + Kerberos. + * Added some more sanity checking to configure. +Changes since 3.08: * Added `compass', `squiral', `xflame', `wander', + `spotlight', and `critical' hacks. + * Added some new modes to `decayscreen'. + * Made `deluxe' work in monochrome. + * Generalized usage of the Double-Buffer server extension + in several hacks (`compass', `deluxe', `interference', + `kumppa', and `moire2'.) + * Fixed another visual-depth problem in `rd-bomb'. + * The screen saver will now defer blanking if neither + the keyboard nor the mouse could be grabbed. Instead, + it will just try again in a few minutes. This fixes + a bad interaction between xscreensaver and programs + like VMware that hold the mouse and keyboard grabbed + for a long time. + * Added a new erase mode (expanding spiral.) +Changes since 3.07: * Fixed some bugs in my port of `t3d'. + * Added `penetrate' and `deluxe' hacks. + * When linking against Motif 2.x, also link against XPM. + * Added support for using /proc/interrupts for idle + detection on Linux. Now xscreensaver shouldn't kick + in when the user is active on a non-X virtual console. + * Upgraded to autoconf 2.13. +Changes since 3.06: * Configure tweaks (sometimes -lXmu wasn't getting linked + in properly; check for _Xsetlocale in -lXintl.) + * Portability fixes for sonar.c. + * Fixed a compilation problem when you have GL but don't + have XPM. + * Made configure notice when MesaGL requires -lpthread. + * Made `flame' ignore SIGFPE (not sure if this is the + right fix; it seems only to be needed on FreeBSD.) + * Kludged `rd-bomb' work on visuals that are of depth 24 + but that *do not* support pixmaps of depth 32. + * Fixed `halo' to work properly in TrueColor. + * Changed `xscreensaver.spec' to install the hacks in + /usr/X11R6/lib/xscreensaver/ by default, since that's + where recent Red Hat distributions put them. + * Added `t3d' hack. + * Updated versions of `crystal', `hopalong', and `flow' + from xlockmore. + * Imported `demon' and `loop' modes from xlockmore. +Changes since 3.05: * Oops, the "default-n" visual descriptor was broken; + it was always installing a colormap if the + `installColormap' preference was set, meaning that + `xearth', `xv' and friends were using the wrong + colors on 8-bit systems. + * Turned off HAVE_PING in `sonar', since it compiles + on some Linux systems, but not others of similar + vintage... +Changes since 3.04: * Fixed an off-by-1 in `distort'. + * Added `sonar' hack. + * New version of `glplanet' (with stars.) + * Made all hacks exit when you type `q' or `ESC' at them, + and made them obey the WM_DELETE_WINDOW ClientMessage. + * Fixed a nonfatal buffer overrun in lament (note: + lament still doesn't work with MesaGL 3.0: it dies in + lambda_textured_triangle1(), which is Mesa's bug, not + mine.) +Changes since 3.03: * Added an `xscreensaver.spec' file, to make it easier + for other folks to generate RPMs. + * Made the password code work on HPUX in the situation + where: ``enhanced security'' is available; but not + used; but the user typed a password more than 8 + characters long anyway. FTSOHPUX. +Changes since 3.02: * Made locking work when passwd aging is enabled. + * Added support for PAM (Pluggable Authentication + Modules.) It is still turned off by default, though, + since it doesn't seem to work on Solaris 2.6, and has + been behaving erratically on Red Hat 5.1. + * Made each possible authentication method be tried in + turn until one succeeds; this means that Kerberos is + being used, we will first check Kerberos, and if that + fails, will then consult the local password file. + Likewise with PAM. + * Save and restore the bits under the passwd dialog, + to avoid leaving a black rectangle behind when + unlocking is cancelled. +Changes since 3.01: * Not everyone has sys/select.h, sigh... +Changes since 3.00: * Some fixes to `reflect'. + * Configure tweaks. + * Made it log unsuccessful attempts to unlock the screen + to syslog. + * Fixed a bug where `xscreensaver-demo' could be seeing + a different programs list than `xscreensaver' did. +Changes since 2.34: * The xscreensaver daemon no longer links against Motif + or Athena: demo-mode and the preferences panel are no + longer built in to the daemon, but are now handled by + an external program, `xscreensaver-demo'. + (I decided that this, along with the recent addition + of the `.xscreensaver' config file, justified bumping + the version number to 3.00, since this is a fairly + major architectural change.) + * Lines in the `*programs' resource may now begin with + the character "-", meaning "don't run this hack." + In this way, it's possible to disable a hack without + throwing away the information about it (making it + easier to change your mind later.) Eventually the + preferences/demo mode GUI should represent this as a + checkbox or something. + * Fixed a short race condition where it was possible for + xscreensaver to die with a BadWindow error if it was + blanking the screen just as another window was being + deleted. + * Made it possible to disable specific modes in `bsod'. +Changes since 2.33: * Fixed a bug that was making `pipes' generate way too + many valves. Made the viewpoint in `pipes' be selected + randomly instead of always being -10 degrees. + * Fixed a bug in the XSHM code, in the case where the + server supports the XSHM extension but is not the same + machine as the client. + * Made `rd-bomb' default to taking up the whole screen. + * Made it not try to do fading/unfading if no PseudoColor + visuals exist. + * Initial attempt at supporting VT-locking (doesn't work + yet.) + * Eliminated the `captureStdout' resource; now + `captureStderr' controls both streams. + * Added `-capture-stderr' and `-no-capture-stderr' + command-line arguments. + * Added `glplanet' hack. + * When a hack is selected with `xscreensaver-command + -select', that hack will be used until further notice + (until the saver turns off, or another activation + command is issued.) +Changes since 2.32: * Made `xscreensaver-command' print error messages: + the xscreensaver daemon now responds to ClientMessage + events by writing a response message on a window + property, instead of just writing to its stderr. + * Made the ~/.xscreensaver file be automatically reloaded + when the file date changes. + * The password dialog and splash screen no longer depend + on Motif or Athena. This should clear up a number of + focus problems, and is the first step on the path + toward moving all of the Motif/Athena/whatever code + out of the xscreensaver daemon, and into external + processes. + * Don't complain about LessTif 0.86 any more, since the + new password dialog makes that problem go away. + * Configure tweaks for Irix 6.5, SunOS 5.something. + * New `-reflect' option to `distort'. +Changes since 2.31: * Added reading and writing of a ~/.xscreensaver file, + so that the Preferences panel can save its settings. + * New version of `rubik'. + * Added `-select N' argument to `xscreensaver-command'. + * Oops, left out some of the `bubbles3d' files... +Changes since 2.30: * The cursor was invisible in the password dialog. Fixed. + * Made configure warn against MesaGL 2.6. + * Fixed X error at startup when using non-default visual. + * New version of `crystal', `ant', and `atlantis' from + xlockmore. + * New hack, `bubble3d'. + * Added some new modes to `bsod'. +Changes since 2.29: * Changed the order in which -lSM and -lICE are linked + to be after Motif instead of before (Lesstif on Irix + needs this.) +Changes since 2.28: * Work around a bash bug in configure. + * Tweaked HPUX paths again. FTSOHPUX. + * Made configure recommend against LessTif 0.86, due + to a bug in that version that causes a security hole + in the screen locking code. LessTif 0.87 will fix it. + * Made all of the `--with' options to `configure' accept + a directory option as well (so that --with-motif=/FOO + will add -I/FOO/include -L/FOO/lib). I believe this is + the Configure Party Line of how do to such things. + * Fixed a bug where the mouse was left un-grabbed + after the first time the graphics hack was changed + (simplified all of the mouse-grabbing logic.) + * Maybe possibly perhaps made `vidwhacker' really not + leave stray xv windows around. This time for sure. + * Added a new erase mode (random dots fizzling out.) + * Added `-prefs' argument to `xscreensaver-command', + that brings up the Preferences dialog directly (it + seems that nobody ever noticed the `Preferences' button + on the Demo Mode dialog, maybe this will help.) + * Added a splash screen. Turn it off with *splash:false. +Changes since 2.27: * Better macsbug text in `bsod'. + * New version of `distort' with many new modes. + * Plugged a leak in `coral'. + * Tweaked configure for HPUX. + * Removed some compiler warnings. + * More consistent usage of stderr versus stdout. + * More diagnostics should an X error occur. + * Fixed a possible crash in SGI-specific unfading code. +Changes since 2.26: * Improved version of `distort'. + * Made `lament' compile against OpenGL 1.0 (though it + still requires 1.1 to work properly.) + * Updated my email address and home page. +Changes since 2.24: * Improved motion in `rd-bomb'. + * Added XSHM (shared memory extension) support to the + `distort', `interference', `moire', `rd-bomb', and + `swirl' hacks, which speeds them up a bit. + * Added `lament' hack. +Changes since 2.23: * Tweaked the order of the -L options again. + * Cleaned up configure's `--help' message. + * Added `kumppa' hack. + * Smarter maze-solving algorithm in `maze'. + * Took `xlyap' out of the default list of hacks, since + it's just incredibly buggy (and slow.) Maybe someday + someone will fix it... + * Added `distort' hack, but didn't add it to the default + list (yet) because it's still too slow. + * Made the Athena demo dialog look more like the Motif + version; it has a text-entry field now, too. + * Made the Athena password dialog echo asterisks, like + Motif does, instead of using a flyspeck font. + * Some random configure tweaks. + * Added a `timestamp' resource that makes the `-verbose' + messages include the time at which they were printed. +Changes since 2.22: * The fix for SGI's ``scheme'' nonsense broke things, and + let the user's "*background" resource show through. + Fixed it in a different way. +Changes since 2.21: * Added support for the DPMS server extension (Display + Power Management System.) + * Made configure advertize the `--enable-subdir' option a + little more, since that seemed to cause some people + stress. Also, made that directory be built into the + xscreensaver executable, as a hardcoded prefix to + $PATH. (Might help, shouldn't hurt.) + * Made configure prefer the two-arg gettimeofday to the + one-arg version, since AIX doesn't have any prototypes. + * Made it work with Xaw3d (the 3D Athena library.) + * Made `make install' create directories as necessary. + * New version of lmorph from Sverre. + * Added `crystal' and `discreet' hacks from xlockmore. + * Added a new mode to `bsod'. +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 + had a different mode called `puzzle'. + * 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 + xlockmore. + * 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; + 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 + it was sometimes failing to die. + * 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 + wily, malicious cracker must have slipped in. + * 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 + have -install on by default, but turn it off for + certain poorly-behaved hacks (like xv.) + * 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 + color allocation problem. +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 + more wipe styles. + * 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 + 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', + `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 + 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', + 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 + shadow passwords aren't accessible for some reason. +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 + 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 + 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 + 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', + `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 + 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 + and present them on the screensaver window itself. + * 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, + 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, + 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. diff --git a/README.VMS b/README.VMS new file mode 100644 index 00000000..d1903443 --- /dev/null +++ b/README.VMS @@ -0,0 +1,57 @@ +OpenVMS port of Xscreensavser version 2.10 October 1997 +========================================== + +Xscreensaver distribution can be found in 3 subdirectories: + +[.DRIVER] The Xscreensaver and Xscreensaver-command programs. +[.HACKS] Graphic demos ,can be run either through the xscreensaver program + or standalone. +[.UTILS] A small libraries of various utilities. + +This port has been tested with VAX VMS 6.1 (compiled with DEC 5 5.0 and +Motif 1.2) and AXP VMS 6.2 (compiled with DEC C 5.0 and Motif 1.2-4). + +To rebuild, you need to rebuild [.UTILS] directory first and create the +object library (look at the end of COMPILE*.COM procedure). + +You can now build the [.HACKS] directory and the [.DRIVER] directory. + +A one-step build is now available via the MAKEVMS.COM script. + +WARNING : before building [.HACKS], you may need to correct some of the +DECwindows bitmap files. Some files are bogus !! (they have a long line of +null chars at the end). These files are under +SYS$COMMON:[DECW$INCLUDE.BITMAPS] directory: + +STIPPLE.XBM +HLINES2.XBM +LIGHT_GRAY.XBM +ROOT_WEAVES.XBM +VLINES2.XBM + +These files are all used by Greynetic demo. + +Nota: link procedure automagically select appropriate X and Motif Libraries +(X11R4/Motif 1.1 - X11R5/Motif 1.2). + +The SETUP.COM procedure gives you a definition of all DCL foreign command +symbols needed to run Xscreensaver and all the graphic hacks. You need to +modify this procedure if you install these programs in another directory tree. + +You can easily add new graphic demos without recompiling Xscreensaver. You just +need to add them in resource file XSCREENSAVER.DAT. This file (originally +present in [.DRIVER] directory ) can be installed under your SYS$LOGIN +directory for a per-user customization basis. You can also install it under +the system-wide user resource directory SYS$COMMON:[DECW$DEFAULT.USER] +(with (W:RE) protections). The new graphics hack must be run in root-window +mode to be accepted by Xscreensaver. + +The graphic demos are spawn into subprocess created by the system() call (in +the Unix version the execvp() call is used). + +The VMS passord checking programs were picked up in the Xlock distribution. + +Enjoy, + +Patrick MOREAU - CENA/Athis-Mons - FRANCE (pmoreau@cena.dgac.fr) + (moreau_p@decus.decus.fr) diff --git a/README.debugging b/README.debugging new file mode 100644 index 00000000..31364dbf --- /dev/null +++ b/README.debugging @@ -0,0 +1,164 @@ + + XScreenSaver + + a handy guide for creating useful bug reports + + -------- + + It's hard to imagine, but sometimes, xscreensaver has bugs. This + document gives some hints for isolating them; the more information + you can give me about the problem, the better the odds that I'll be + able to fix it. But, if you don't have time to go through these + steps, please report the bug anyway -- even vague bug reports can + be better than no bug report at all. + + -------- +STEP ZERO: + + What are you doing here? Go read README, and then the man page. + +STEP ZERO, PART TWO: + + Do you have the most recent version? Go make sure. + http://www.jwz.org/xscreensaver/. + +COMPILATION PROBLEMS: + + If you get an error running the `configure' script, the first thing + you should try is deleting the `config.cache' file, and running again. + If that doesn't fix it, the information I'll need to see to make + sense of the problem is the following: + + * everything printed to stderr/stdout when you first ran + ./configure; + + * the contents of the `config.log' file. + + Make sure you blow away the config.cache file before regenerating + this info, or else the `config.log' file will be mostly empty/useless. + + Experience seems to show that the most common configure problem is + that sites have gcc installed, but installed improperly. The + configure script will always try to use gcc in preference to another + compiler if gcc exists, so if gcc exists but is broken, it won't + work. Your options are: + + * get someone to fix the gcc installation; + + * rearrange your $PATH so that the broken gcc is not on it; + + * or pass $CC in the environment, like so: + + csh: setenv CC cc ; ./configure + sh: CC=cc ; ./configure + + 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, + then your system is horked and your vendor is lame. Perhaps the + problem is that you don't have some kind of ``development option'' + installed. Xt/ and Xaw/ (Athena) are free and available on all + systems; Xm/ (Motif) is available on all commercial systems except + SunOS 4.x and some early releases of Solaris. For Linux and other + free Unixes systems, a Motif clone is available from + http://www.lesstif.org/. + +RUN-TIME PROBLEMS: + + For runtime errors, it's important to keep in mind that there are + two parts to xscreensaver: there is the screensaver driver process + (the daemon that detects idleness, deals with locking, and launches + the demos); and there are the demos themselves (independent programs + that draw pretty pictures.) + + * Compile with `make CFLAGS=-g' (so that if you get a core + dump, there will be debugging info in it.) + + * What platform are you running on? What does the included + `./config.guess' shell script print? + + * Is the problem in the driver (`xscreensaver'), the GUI + (`xscreensaver-demo'), or in the graphics hacks? + + * If the problem is in the GUI, was the it built using + Motif, Lesstif, or Athena? Which version? + + * If the problem is in one (or more) of the hacks, which ones? + If you're not sure, try running `xscreensaver-demo' to go + through the list of them and see which work and which don't. + + * Does the problem occur when running that hack by hand, in + its own window (i.e., when started with no command-line args)? + + * Does the problem occur when running that hack by hand, on + the root window (i.e., when started with the `-root' option)? + + * IMPORTANT: What visual are you using? Send the output of + the `xdpyinfo' command. + + * Does the problem go away if you give the program a different + `-visual' argument? (For example, `-visual pseudocolor' or + `-visual truecolor'.) + + * IMPORTANT: What exactly goes wrong? No, I don't know what + you mean by "crash". Does it print an "X Error" and exit? + Does it dump core? Does it go into a loop? + + * If it dumps core, what does the core file say? Run the + program under a debugger, and show me the stack trace. + To extract a stack trace from a core file with gdb, do this: + + gdb ./the-program ./core + bt + + To extract a stack trace from a core file with dbx, do this: + + dbx ./the-program ./core + where + + If the bottom few lines of the output don't include the functions + `main_loop()' and `main()', then something's wrong: are you sure + the core file came from that program? + + * If it gets an X error, where did it come from? Run + xscreensaver with the `-sync' command-line option. When `-sync' + is used, X errors will cause xscreensaver to dump a core file. + Look at the core file with a debugger and show me the stack trace, + as above: I need to know where in xscreensaver that X error came + from. + + If the problem is with the xscreensaver process itself, or if you + can't figure out which demo is causing the problem, or if you can't + reproduce the problem in isolation, then you will need to turn on + and examine the debugging output of the driver process. + + * Start `xscreensaver' with the command-line arguments + + -verbose -no-capture + + This will cause it to write a lot of debugging info to the stderr + of the xscreensaver process (the `-verbose' option turns on the + diagnostics; the `-no-capture' option prevents the data from being + displayed on the screensaver window as well.) + + You also might want to use the `-timestamp' option, which will + cause the xscreensaver messages to include the time at which + they were printed. + + * If the problem is intermittent, you might want to capture the + log information to a file and examine it later. For example, + you could start it from your login script like this (csh syntax): + + ( cd ~/src/xscreensaver/ ; \ + xscreensaver -sync -verbose -timestamp -no-capture \ + >>&LOG & ) + + * Hackers only: If you're feeling adventurous enough to run gdb + on the xscreensaver driver process itself, make sure you've + read the commentary at the top of xscreensaver.c. + +----------------------------------------------------------------------------- + http://www.jwz.org/xscreensaver/ + Jamie Zawinski +----------------------------------------------------------------------------- diff --git a/config.guess b/config.guess new file mode 100755 index 00000000..e9e44559 --- /dev/null +++ b/config.guess @@ -0,0 +1,693 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-cbm-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-atari-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-sun-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-apple-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >dummy.c + int main (argc, argv) int argc; char **argv; { + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + ${CC-cc} dummy.c -o dummy \ + && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp3[0-9][05]:OpenBSD:*:*) + echo m68k-hp-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo i386-pc-cygwin32 + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin32 + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then + echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then + echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then + echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then + echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 + elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then + echo "powerpc-unknown-linux-gnu" ; exit 0 + elif test "${UNAME_MACHINE}" = "alpha" ; then + echo alpha-unknown-linux-gnu ; exit 0 + elif test "${UNAME_MACHINE}" = "sparc" ; then + echo sparc-unknown-linux-gnu ; exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us + # useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout. + test ! -d /usr/lib/ldscripts/. \ + && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + # Determine whether the default compiler is a.out or elf + cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.h-vms b/config.h-vms new file mode 100644 index 00000000..5dd8158b --- /dev/null +++ b/config.h-vms @@ -0,0 +1,298 @@ +/* This is a config.h file that has been pregenerated (from config.h.in) + * with settings that are correct for VMS. + */ + + + +/* config.h.in --- xscreensaver, Copyright (c) 1998 Jamie Zawinski. + * + * The best way to set these parameters is by running the included `configure' + * script. That examines your system, and generates `config.h' from + * `config.h.in'. + * + * If something goes very wrong, you can edit `config.h' directly, but beware + * that your changes will be lost if you ever run `configure' again. + */ + + +/* ************************************************************************* + CONFIGURING SERVER EXTENSIONS + ************************************************************************* */ + +/* Define this if you have the XReadDisplay extension (I think this is an + SGI-only thing; it's in .) A few of the + screenhacks will take advantage of this if it's available. + */ +#undef HAVE_READ_DISPLAY_EXTENSION + +/* Define this if you have the Iris Video Library (dmedia/vl.h on SGI.) + A few of the screenhacks will take advantage of this if it's available. + */ +#undef HAVE_SGI_VIDEO + +/* Define this if you have the XHPDisableReset function (an HP only thing.) + */ +#undef HAVE_XHPDISABLERESET + +/* First, some background: there are three distinct server extensions which + * are useful to a screen saver program: they are XIDLE, MIT-SCREEN-SAVER, + * and SCREEN_SAVER. + * + * The XIDLE extension resides in .../contrib/extensions/xidle/ on the X11R5 + * contrib tape. This extension lets the client get accurate idle-time + * information from the X server in a potentially more reliable way than by + * simply watching for keyboard and mouse activity. However, the XIDLE + * extension has apparently not been ported to X11R6. + * + * The SCREEN_SAVER extension is found (as far as I know) only in the SGI + * X server, and it exists in all releases since (at least) Irix 5. The + * relevant header file is /usr/include/X11/extensions/XScreenSaver.h. + * + * The similarly-named MIT-SCREEN-SAVER extension came into existence long + * after the SGI SCREEN_SAVER extension was already in use, and resides in + * .../contrib/extensions/screensaver/ on the X11R6 contrib tape. It is + * also found in certain recent X servers built in to NCD X terminals. + * + * The MIT extension does basically the same thing that the XIDLE extension + * does, but there are two things wrong with it: first, because of the way + * the extension was designed, the `fade' option to XScreenSaver will be + * uglier: just before the screen fades out, there will be an unattractive + * flicker to black, because this extension blanks the screen *before* + * telling us that it is time to do so. Second, this extension is known to + * be buggy; on the systems I use, it works, but some people have reported + * X server crashes as a result of using it. XScreenSaver uses this + * extension rather conservatively, because when I tried to use any of its + * more complicated features, I could get it to crash the server at the + * drop of a hat. + * + * In short, the MIT-SCREEN-SAVER extension is a piece of junk. The older + * SGI SCREEN_SAVER extension works great, as does XIDLE. It would be nice + * If those two existed on more systems, that is, would be adopted by the + * X Consortium in favor of their inferior "not-invented-here" entry. + */ + +/* Define this if you have the XIDLE extension installed. If you have the + * XIDLE extension, this is recommended. (You have this extension if the + * file /usr/include/X11/extensions/xidle.h exists.) Turning on this flag + * lets XScreenSaver work better with servers which support this extension; + * but it will still work with servers which do not suport it, so it's a good + * idea to compile in support for it if you can. + */ +#undef HAVE_XIDLE_EXTENSION + +/* Define this if you have the MIT-SCREEN-SAVER extension installed. See the + * caveats about this extension, above. (It's available if the file + * /usr/include/X11/extensions/scrnsaver.h exists.) + */ +#undef HAVE_MIT_SAVER_EXTENSION + +/* Define this if you have the SGI SCREEN_SAVER extension. This is standard + * on Irix systems, and not available elsewhere. + */ +#undef HAVE_SGI_SAVER_EXTENSION + +/* Define this if you have the SGI-VIDEO-CONTROL extension. This is standard + * on Irix systems, and not available elsewhere. + */ +#undef HAVE_SGI_VC_EXTENSION + +/* Define this if you have the XDPMS extension. This is standard on + * sufficiently-recent XFree86 systems, and possibly elsewhere. (It's + * available if the file /usr/include/X11/extensions/dpms.h exists.) + */ +#define HAVE_DPMS_EXTENSION 1 + + +/* ************************************************************************* + CONFIGURING GRAPHICS TOOLKITS + ************************************************************************* */ + +/* Define this if you have Motif. + */ +#define HAVE_MOTIF 1 + +/* Define this if you don't have Motif, but you have Athena (-Xaw). + */ +#undef HAVE_ATHENA + +/* Define this if you have Athena, and the version you have includes the + * XawViewportSetCoordinates function in Viewport.h (some old versions of + * the library didn't have this function.) + */ +#undef HAVE_XawViewportSetCoordinates + +/* Define this if you have the XPM library installed. Some of the demos can + * make use of this if it is available. + */ +#define HAVE_XPM 1 + +/* Define this if you have the Xmu library. This is standard part of X, and + * if your vendor doesn't ship it, you should report that as a bug. + */ +#define HAVE_XMU 1 + +/* Define this if you have OpenGL. Some of the demos require it, so if you + * don't have it, then those particular demos won't be built. (This won't + * affect the screen saver as a whole.) + */ +#undef HAVE_GL + +/* Define this if you have OpenGL, but it's the MesaGL variant. (The + libraries have different names.) (HAVE_GL should be defined too.) + */ +#undef HAVE_MESA_GL + +/* Define this if your version of OpenGL has the glBindTexture() routine. + This is the case for OpenGL 1.1, but not for OpenGL 1.0. + */ +#undef HAVE_GLBINDTEXTURE + +/* Define this if you have the X Shared Memory Extension. + */ +#undef HAVE_XSHM_EXTENSION + +/* Some screenhacks like to run an external program to generate random pieces + of text; set this to the one you like ("yow" and "fortune" are the most + likely prospects.) Note that this is just the default; X resources can + be used to override it. + */ +#define ZIPPY_PROGRAM "fortune" + + + +/* ************************************************************************* + CONFIGURING PASSWORD AUTHENTICATION + ************************************************************************* */ + +/* Define this to remove the option of locking the screen at all. + */ +#undef NO_LOCKING + +/* Define this if you want to use Kerberos authentication to lock/unlock the + * screen instead of your local password. This currently uses Kerberos V4, + * but a V5 server with V4 compatibility will work. WARNING: DO NOT USE AFS + * string-to-key passwords with this option. This option currently *only* + * works with standard Kerberos des_string_to_key. If your password is an + * AFS password and not a kerberos password, it will not authenticate + * properly. See the comments in driver/kpasswd.c for more information if you + * need it. + */ +#undef HAVE_KERBEROS + + +/* Define this if your system uses `shadow' passwords, that is, the passwords + * live in /etc/shadow instead of /etc/passwd, and one reads them with + * getspnam() instead of getpwnam(). (Note that SCO systems do some random + * other thing; others might as well. See the ifdefs in driver/passwd.c if + * you're having trouble related to reading passwords.) + */ +#undef HAVE_SHADOW_PASSWD + +/* Define this if your system is Digital or SCO Unix with so-called ``Enhanced + Security'', that is, the passwords live in /tcb/files/auth// + instead of in /etc/passwd, and one reads them with getprpwnam() instead + of getpwnam(). + */ +#undef HAVE_ENHANCED_PASSWD + +/* Define this if your system is Solaris with ``adjunct'' passwords (this is + the version where one gets at the passwords with getpwanam() instead of + getpwnam().) I haven't tested this one, let me know if it works. + */ +#undef HAVE_ADJUNCT_PASSWD + +/* Define this if you are running HPUX with so-called ``Secure Passwords'' + (if you have /usr/include/hpsecurity.h, you probably have this.) I + haven't tested this one, let me know if it works. + */ +#undef HAVE_HPUX_PASSWD + +/* Define this if you are on a system that supports the VT_LOCKSWITCH and + VT_UNLOCKSWITCH ioctls. If this is defined, then when the screen is + locked, switching to another virtual terminal will also be prevented. + That is, the whole console will be locked, rather than just the VT on + which X is running. + */ +#define HAVE_VT_LOCKSWITCH 1 + + +/* ************************************************************************* + OTHER C ENVIRONMENT JUNK + ************************************************************************* */ + +/* Define this to void* if you're using X11R4 or earlier. */ +#undef XPointer + +/* Define if you have the nice function. */ +#undef HAVE_NICE + +/* Define if you have the setpriority function. */ +#undef HAVE_SETPRIORITY + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `int' if doesn't define. */ +#undef mode_t + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if gettimeofday requires two arguments. */ +#undef GETTIMEOFDAY_TWO_ARGS + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the select function. */ +#undef HAVE_SELECT + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getcwd function. */ +#undef HAVE_GETWD + +/* Define if you have the uname function. */ +#undef HAVE_UNAME +#if (__VMS_VER >= 70000000) +# define HAVE_UNAME 1 +#endif + +/* Define if you have the fcntl function. */ +#undef HAVE_FCNTL + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_CRYPT_H + +/* Define to use sigaction() instead of signal() for SIGCHLD-related activity. + This is necessary at least on SCO OpenServer 5, due to a Unix kernel bug. + */ +#undef USE_SIGACTION diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..318e2bfc --- /dev/null +++ b/config.h.in @@ -0,0 +1,357 @@ +/* config.h.in --- xscreensaver, Copyright (c) 1998 Jamie Zawinski. + * + * The best way to set these parameters is by running the included `configure' + * script. That examines your system, and generates `config.h' from + * `config.h.in'. + * + * If something goes very wrong, you can edit `config.h' directly, but beware + * that your changes will be lost if you ever run `configure' again. + */ + + +/* ************************************************************************* + CONFIGURING SERVER EXTENSIONS + ************************************************************************* */ + +/* Define this if you have the XReadDisplay extension (I think this is an + SGI-only thing; it's in .) A few of the + screenhacks will take advantage of this if it's available. + */ +#undef HAVE_READ_DISPLAY_EXTENSION + +/* Define this if you have the Iris Video Library (dmedia/vl.h on SGI.) + A few of the screenhacks will take advantage of this if it's available. + */ +#undef HAVE_SGI_VIDEO + +/* Define this if you have the XHPDisableReset function (an HP only thing.) + */ +#undef HAVE_XHPDISABLERESET + +/* First, some background: there are three distinct server extensions which + * are useful to a screen saver program: they are XIDLE, MIT-SCREEN-SAVER, + * and SCREEN_SAVER. + * + * The XIDLE extension resides in .../contrib/extensions/xidle/ on the X11R5 + * contrib tape. This extension lets the client get accurate idle-time + * information from the X server in a potentially more reliable way than by + * simply watching for keyboard and mouse activity. However, the XIDLE + * extension has apparently not been ported to X11R6. + * + * The SCREEN_SAVER extension is found (as far as I know) only in the SGI + * X server, and it exists in all releases since (at least) Irix 5. The + * relevant header file is /usr/include/X11/extensions/XScreenSaver.h. + * + * The similarly-named MIT-SCREEN-SAVER extension came into existence long + * after the SGI SCREEN_SAVER extension was already in use, and resides in + * .../contrib/extensions/screensaver/ on the X11R6 contrib tape. It is + * also found in certain recent X servers built in to NCD X terminals. + * + * The MIT extension does basically the same thing that the XIDLE extension + * does, but there are two things wrong with it: first, because of the way + * the extension was designed, the `fade' option to XScreenSaver will be + * uglier: just before the screen fades out, there will be an unattractive + * flicker to black, because this extension blanks the screen *before* + * telling us that it is time to do so. Second, this extension is known to + * be buggy; on the systems I use, it works, but some people have reported + * X server crashes as a result of using it. XScreenSaver uses this + * extension rather conservatively, because when I tried to use any of its + * more complicated features, I could get it to crash the server at the + * drop of a hat. + * + * In short, the MIT-SCREEN-SAVER extension is a piece of junk. The older + * SGI SCREEN_SAVER extension works great, as does XIDLE. It would be nice + * If those two existed on more systems, that is, would be adopted by the + * X Consortium in favor of their inferior "not-invented-here" entry. + */ + +/* Define this if you have the XIDLE extension installed. If you have the + * XIDLE extension, this is recommended. (You have this extension if the + * file /usr/include/X11/extensions/xidle.h exists.) Turning on this flag + * lets XScreenSaver work better with servers which support this extension; + * but it will still work with servers which do not suport it, so it's a good + * idea to compile in support for it if you can. + */ +#undef HAVE_XIDLE_EXTENSION + +/* Define this if you have the MIT-SCREEN-SAVER extension installed. See the + * caveats about this extension, above. (It's available if the file + * /usr/include/X11/extensions/scrnsaver.h exists.) + */ +#undef HAVE_MIT_SAVER_EXTENSION + +/* Define this if you have the SGI SCREEN_SAVER extension. This is standard + * on Irix systems, and not available elsewhere. + */ +#undef HAVE_SGI_SAVER_EXTENSION + +/* Define this if you have the SGI-VIDEO-CONTROL extension. This is standard + * on Irix systems, and not available elsewhere. + */ +#undef HAVE_SGI_VC_EXTENSION + +/* Define this if you have the XDPMS extension. This is standard on + * sufficiently-recent XFree86 systems, and possibly elsewhere. (It's + * available if the file /usr/include/X11/extensions/dpms.h exists.) + */ +#undef HAVE_DPMS_EXTENSION + +/* Define this if you have the functions XF86VidModeGetModeLine() and + * XF86VidModeGetViewPort(), in support of virtual desktops where the + * X server's root window is bigger than the actual screen. This is + * an XFree86 thing, and probably doesn't exist elsewhere. (It's + * available if the file /usr/include/X11/extensions/xf86vmode.h exists.) + */ +#undef HAVE_XF86VMODE + +/* Define this if you have a Linux-like /proc/interrupts file which can be + * examined to determine when keyboard activity has occurred. + */ +#undef HAVE_PROC_INTERRUPTS + + + +/* ************************************************************************* + CONFIGURING GRAPHICS TOOLKITS + ************************************************************************* */ + +/* Define this if you have Motif. + */ +#undef HAVE_MOTIF + +/* Define this if you have Gtk. + */ +#undef HAVE_GTK + +/* Define this if you have Athena (-Xaw). + */ +#undef HAVE_ATHENA + +/* Define this if you have Athena, and the version you have includes the + * XawViewportSetCoordinates function in Viewport.h (some old versions of + * the library didn't have this function.) + */ +#undef HAVE_XawViewportSetCoordinates + +/* Define this if you have the XPM library installed. Some of the demos can + * make use of this if it is available. + */ +#undef HAVE_XPM + +/* Define this if you have the Xmu library. This is standard part of X, and + * if your vendor doesn't ship it, you should report that as a bug. + */ +#undef HAVE_XMU + +/* Define this if you have OpenGL. Some of the demos require it, so if you + * don't have it, then those particular demos won't be built. (This won't + * affect the screen saver as a whole.) + */ +#undef HAVE_GL + +/* Define this if you have OpenGL, but it's the MesaGL variant. (The + libraries have different names.) (HAVE_GL should be defined too.) + */ +#undef HAVE_MESA_GL + +/* Define this if your version of OpenGL has the glBindTexture() routine. + This is the case for OpenGL 1.1, but not for OpenGL 1.0. + */ +#undef HAVE_GLBINDTEXTURE + +/* Define this if the `xscreensaver' process itself (the driver process) + should be linked against GL. Most systems won't want this (in particular, + if you're using Linux and/or Mesa, you don't want this) but SGI systems + do want this. It may also be useful on other systems that have serious + GL support -- you only need this if you have a lot of different visuals, + not all of which work with GL programs. + */ +#undef DAEMON_USE_GL + +/* Define this if you have the X Shared Memory Extension. + */ +#undef HAVE_XSHM_EXTENSION + +/* Define this if you have the X Double Buffer Extension. + */ +#undef HAVE_DOUBLE_BUFFER_EXTENSION + +/* Some screenhacks like to run an external program to generate random pieces + of text; set this to the one you like ("yow" and "fortune" are the most + likely prospects.) Note that this is just the default; X resources can + be used to override it. + */ +#define ZIPPY_PROGRAM "fortune" + + + +/* ************************************************************************* + CONFIGURING PASSWORD AUTHENTICATION + ************************************************************************* */ + +/* Define this to remove the option of locking the screen at all. + */ +#undef NO_LOCKING + +/* Define this if you want to use Kerberos authentication to lock/unlock the + * screen instead of your local password. This currently uses Kerberos V4, + * but a V5 server with V4 compatibility will work. WARNING: DO NOT USE AFS + * string-to-key passwords with this option. This option currently *only* + * works with standard Kerberos des_string_to_key. If your password is an + * AFS password and not a kerberos password, it will not authenticate + * properly. See the comments in driver/kpasswd.c for more information if you + * need it. + */ +#undef HAVE_KERBEROS + +/* Define this if you want to use PAM (Pluggable Authentication Modules) + * to lock/unlock the screen, instead of standard /etc/passwd authentication. + */ +#undef HAVE_PAM + +/* If PAM is being used, this is the name of the PAM service that xscreensaver + * will authenticate as. The default is "xscreensaver", which means that the + * PAM library will look for an "xscreensaver" line in /etc/pam.conf, or (on + * recent Linux systems) will look for a file called /etc/pam.d/xscreensaver. + * Some systems might already have a PAM installation that is configured for + * xlock, so setting this to "xlock" would also work in that case. + */ +#define PAM_SERVICE_NAME "xscreensaver" + +/* Define if you have PAM and pam_strerror() requires two arguments. */ +#undef PAM_STRERROR_TWO_ARGS + +/* Define this if your system uses `shadow' passwords, that is, the passwords + * live in /etc/shadow instead of /etc/passwd, and one reads them with + * getspnam() instead of getpwnam(). (Note that SCO systems do some random + * other thing; others might as well. See the ifdefs in driver/passwd-pwent.c + * if you're having trouble related to reading passwords.) + */ +#undef HAVE_SHADOW_PASSWD + +/* Define this if your system is Digital or SCO Unix with so-called ``Enhanced + Security'', that is, the passwords live in /tcb/files/auth// + instead of in /etc/passwd, and one reads them with getprpwnam() instead + of getpwnam(). + */ +#undef HAVE_ENHANCED_PASSWD + +/* Define this if your system is Solaris with ``adjunct'' passwords (this is + the version where one gets at the passwords with getpwanam() instead of + getpwnam().) I haven't tested this one, let me know if it works. + */ +#undef HAVE_ADJUNCT_PASSWD + +/* Define this if you are running HPUX with so-called ``Secure Passwords'' + (if you have /usr/include/hpsecurity.h, you probably have this.) I + haven't tested this one, let me know if it works. + */ +#undef HAVE_HPUX_PASSWD + +/* Define this if you are on a system that supports the VT_LOCKSWITCH and + VT_UNLOCKSWITCH ioctls. If this is defined, then when the screen is + locked, switching to another virtual terminal will also be prevented. + That is, the whole console will be locked, rather than just the VT on + which X is running. (Well, that's the theory anyway -- in practice, + I haven't yet figured out how to make that work.) + */ +#undef HAVE_VT_LOCKSWITCH + + +/* Define this if you the openlog(), syslog(), and closelog() functions. + This is used for logging failed login attempts. + */ +#undef HAVE_SYSLOG + + +/* ************************************************************************* + OTHER C ENVIRONMENT JUNK + ************************************************************************* */ + +/* Define this to void* if you're using X11R4 or earlier. */ +#undef XPointer + +/* Define if you have the nice function. */ +#undef HAVE_NICE + +/* Define if you have the setpriority function. */ +#undef HAVE_SETPRIORITY + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `int' if doesn't define. */ +#undef mode_t + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if gettimeofday requires two arguments. */ +#undef GETTIMEOFDAY_TWO_ARGS + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the select function. */ +#undef HAVE_SELECT + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getcwd function. */ +#undef HAVE_GETWD + +/* Define if you have the realpath function. */ +#undef HAVE_REALPATH + +/* Define if you have the uname function. */ +#undef HAVE_UNAME + +/* Define if you have the fcntl function. */ +#undef HAVE_FCNTL + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_CRYPT_H + +/* Define if you have that defines fd_set and FD_SET. */ +#undef HAVE_SYS_SELECT_H + +/* Define to use sigaction() instead of signal() for SIGCHLD-related activity. + This is necessary at least on SCO OpenServer 5, due to a Unix kernel bug. + */ +#undef USE_SIGACTION + +/* Define this if you do pings with a `struct icmp' and a `icmp_id' slot. + */ +#undef HAVE_ICMP + +/* Define this if you do pings with a `struct icmphdr' and a `un.echo.id' slot. + */ +#undef HAVE_ICMPHDR diff --git a/config.sub b/config.sub new file mode 100755 index 00000000..04325249 --- /dev/null +++ b/config.sub @@ -0,0 +1,927 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \ + | arme[lb] | pyramid \ + | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ + | alpha | we32k | ns16k | clipper | i370 | sh \ + | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \ + | pdp11 | mips64el | mips64orion | mips64orionel \ + | sparc | sparclet | sparclite | sparc64) + basic_machine=$basic_machine-unknown + ;; + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[3456]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ + | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ + | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ + | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ + | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* | f301-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigados) + basic_machine=m68k-cbm + os=-amigados + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[3456]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[3456]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[3456]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[3456]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5) + basic_machine=i586-intel + ;; + pentiumpro | p6) + basic_machine=i686-intel + ;; + pentium-* | p5-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + k5) + # We don't have specific support for AMD's K5 yet, so just call it a Pentium + basic_machine=i586-amd + ;; + nexen) + # We don't have specific support for Nexgen yet, so just call it a Pentium + basic_machine=i586-nexgen + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + basic_machine=mips-mips + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware* | svr4*) + os=-sysv4 + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -linux-gnu* | -uxpv*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigados + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100755 index 00000000..74d889e6 --- /dev/null +++ b/configure @@ -0,0 +1,9361 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help" +ac_help="$ac_help +Installation options: + + --enable-subdir=DIR Put the demo programs in a subdirectory of \`bindir', + instead of putting them in bindir itself. You can + specify the name of the subdirectory. For example, + \`--exec-prefix=/usr/local --enable-subdir=demos' + would put xscreensaver in /usr/local/bin/, and would + put the demos in /usr/local/bin/demos/. (If DIR + begins with /, then bindir will not be prepended.) + + --disable-subdir Just put the demos in \`bindir' (this is the default.) +" +ac_help="$ac_help +Except where noted, all of the --with options below can also take a +directory argument: for example, \`--with-motif=/opt/Motif'. That would +cause /opt/Motif/include/ to be added to the -I list, and /opt/Motif/lib/ +to be added to the -L list, assuming those directories exist. + +By default, support for each of these options will be built in, if the +relevant library routines exist. At run time, they will then be used +only if the X server being used supports them. Each --with option has +a corresponding --without option, to override building support for them +at all. + +Screen blanking and idle-detection options: + + --with-sgi-ext Include support for the SGI SCREEN_SAVER extension." +ac_help="$ac_help + --with-mit-ext Include support for the MIT-SCREEN-SAVER extension." +ac_help="$ac_help + --with-xidle-ext Include support for the XIDLE extension." +ac_help="$ac_help + --with-sgivc-ext Include support for the SGI-VIDEO-CONTROL extension." +ac_help="$ac_help + --with-dpms-ext Include support for the DPMS extension." +ac_help="$ac_help + --with-xf86vmode-ext Include support for XFree86 virtual screens." +ac_help="$ac_help + --with-proc-interrupts Include support for consulting the /proc/interrupts + file to notice keyboard activity." +ac_help="$ac_help + +Screen locking options: + + --enable-locking Compile in support for locking the display. + --disable-locking Do not allow locking at all. +" +ac_help="$ac_help + --with-pam Include support for PAM (Pluggable Auth Modules.)" +ac_help="$ac_help + --with-kerberos Include support for Kerberos authentication." +ac_help="$ac_help + --with-shadow Include support for shadow password authentication." +ac_help="$ac_help + +User interface options: + + --with-motif Use the Motif toolkit for the user interface." +ac_help="$ac_help + --with-gtk Use the Gtk toolkit for the user interface." +ac_help="$ac_help + --with-athena Use the Athena toolkit for the user interface." +ac_help="$ac_help + +Graphics options: + + --with-gl Build those demos which depend on OpenGL." +ac_help="$ac_help + --with-xpm Include support for XPM files in some demos." +ac_help="$ac_help + --with-xshm-ext Include support for the XSHM extension." +ac_help="$ac_help + --with-xdbe-ext Include support for the DOUBLE-BUFFER extension." +ac_help="$ac_help + --with-readdisplay Include support for the XReadDisplay extension." +ac_help="$ac_help + --with-sgivideo Include support for SGI's Iris Video Library." +ac_help="$ac_help + + --with-zippy=PROGRAM Some demos are able to run an external program and + display its text; this names the program to use by + default (though it can be overridden with X + resources.) If you don't specify this, the default + is to use \"yow\" from the Emacs distribution (if you + have it) or else to use \"fortune\". +" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] + +Configuration: + + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure + +Directory and file names: + + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF + +Host type: + + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +EOF + if test -n "$ac_help"; then + echo "$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=driver/subprocs.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +echo "current directory: `pwd`" +echo "command line was: $0 $@" + + +# After checking to see that --srcdir is correct (which AC_INIT does) +# check for some random other files that come later in the tar file, +# to make sure everything is here. +# +for d in driver utils hacks hacks/glx ; do + f=$srcdir/$d/Makefile.in + if test \! -r $f ; then + echo "" + echo "ERROR: The package is incomplete: $f does not exist." + echo " This probably means that your download was truncated." + echo "" + exit 1 + fi +done + + +############################################################################### +# +# Function to figure out how to run the compiler. +# +############################################################################### + + + + +############################################################################### +# +# Function to figure out how to create directory trees. +# +############################################################################### + + + + +############################################################################### +# +# Function to check whether gettimeofday() exists, and how to call it. +# This may define HAVE_GETTIMEOFDAY and GETTIMEOFDAY_TWO_ARGS. +# +############################################################################### + + + + +############################################################################### +# +# Function to find perl5 (defines PERL and PERL_VERSION.) +# +############################################################################### + +# M4 sucks!! perl sucks too!! + +perl_version_cmd='print $]' + + + + + +############################################################################### +# +# Functions to check how to do ICMP PING requests. +# +############################################################################### + + + + + + +############################################################################### +# +# Functions to check for various X11 crap. +# +############################################################################### + +# Try and find the app-defaults directory. +# It sucks that autoconf doesn't do this already... +# + + + + + + + + + + +# Random special-cases for X on certain pathological OSes. +# You know who you are. +# + + + + +############################################################################### +# +# Some utility functions to make checking for X things easier. +# +############################################################################### + +# Like AC_CHECK_HEADER, but it uses the already-computed -I directories. +# + + +# Like AC_EGREP_HEADER, but it uses the already-computed -I directories. +# + + +# Like AC_TRY_COMPILE, but it uses the already-computed -I directories. +# + + + +# Like AC_CHECK_LIB, but it uses the already-computed -I and -L directories. +# Use this sparingly; it probably doesn't work very well on X programs. +# + + +# Like AC_TRY_RUN, but it uses the already-computed -I directories. +# (But not the -L directories!) +# + + + + +# Usage: HANDLE_X_PATH_ARG([variable_name], +# [--command-line-option], +# [descriptive string]) +# +# All of the --with options take three forms: +# +# --with-foo (or --with-foo=yes) +# --without-foo (or --with-foo=no) +# --with-foo=/DIR +# +# This function, HANDLE_X_PATH_ARG, deals with the /DIR case. When it sees +# a directory (string beginning with a slash) it checks to see whether +# /DIR/include and /DIR/lib exist, and adds them to $X_CFLAGS and $X_LIBS +# as appropriate. +# + + + + +############################################################################### +############################################################################### +# +# End of function definitions. Now start actually executing stuff. +# +############################################################################### +############################################################################### + +# random compiler setup +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:801: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:824: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:854: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:905: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:937: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 948 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:953: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:979: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:984: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1012: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + + if test -z "$GCC"; then + echo $ac_n "checking how to request ANSI compilation""... $ac_c" 1>&6 +echo "configure:1046: checking how to request ANSI compilation" >&5 + case "$host" in + *-hpux* ) + echo "$ac_t""HPUX: adding -Ae" 1>&6 + CC="$CC -Ae" + ;; + *-aix* ) + echo "$ac_t""AIX: adding -qlanglvl=ansi -qhalt=e" 1>&6 + CC="$CC -qlanglvl=ansi -qhalt=e" + ;; + + *-dec-* ) + echo "$ac_t""DEC: adding -std1" 1>&6 + CC="$CC -std1" + ;; + + *) + echo "$ac_t""no idea" 1>&6 + ;; + esac + fi + + echo $ac_n "checking whether the compiler works on ANSI C""... $ac_c" 1>&6 +echo "configure:1069: checking whether the compiler works on ANSI C" >&5 + if test "$cross_compiling" = yes; then + { echo "configure: error: Couldn't build even a trivial ANSI C program: check CC." 1>&2; exit 1; } +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + echo "$ac_t""no" 1>&6 + { echo "configure: error: Couldn't build even a trivial ANSI C program: check CC." 1>&2; exit 1; } +fi +rm -fr conftest* +fi + + + if test -n "$GCC"; then + echo "$ac_t""Turning on gcc compiler warnings." 1>&6 + CC="$CC -Wall -Wstrict-prototypes -Wnested-externs -Wno-format" + else + case "$host" in + *-irix5* |*-irix6.0-3* ) + echo "$ac_t""Turning on SGI compiler warnings." 1>&6 + CC="$CC -fullwarn -use_readonly_const -rdata_shared -g3" + ;; +# *-dec-osf* ) +# if test -z "$GCC"; then +# AC_MSG_RESULT(Turning on DEC C compiler warnings.) +# CC="$CC -migrate -w0 -verbose -warnprotos" +# fi +# ;; + esac + fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1111: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1132: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1149: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:1191: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:1245: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:1266: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <&6 +echo "configure:1319: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether \"\${INSTALL} -d\" creates intermediate directories""... $ac_c" 1>&6 +echo "configure:1372: checking whether \"\${INSTALL} -d\" creates intermediate directories" >&5 +if eval "test \"`echo '$''{'ac_cv_install_d_creates_dirs'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_install_d_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir >&- + ${INSTALL} -d `pwd`/dir1/dir2 >&- 2>&- + if test -d dir1/dir2/. ; then + ac_cv_install_d_creates_dirs=yes + fi + cd .. >&- + rm -rf conftestdir + fi + +fi + +echo "$ac_t""$ac_cv_install_d_creates_dirs" 1>&6 + + if test "$ac_cv_install_d_creates_dirs" = no ; then + echo $ac_n "checking whether \"mkdir -p\" creates intermediate directories""... $ac_c" 1>&6 +echo "configure:1394: checking whether \"mkdir -p\" creates intermediate directories" >&5 +if eval "test \"`echo '$''{'ac_cv_mkdir_p_creates_dirs'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_mkdir_p_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir >&- + mkdir -p dir1/dir2 >&- 2>&- + if test -d dir1/dir2/. ; then + ac_cv_mkdir_p_creates_dirs=yes + fi + cd .. >&- + rm -rf conftestdir + fi + +fi + +echo "$ac_t""$ac_cv_mkdir_p_creates_dirs" 1>&6 + fi + + if test "$ac_cv_install_d_creates_dirs" = yes ; then + INSTALL_DIRS='${INSTALL} -d' + elif test "$ac_cv_mkdir_p_creates_dirs" = yes ; then + INSTALL_DIRS='mkdir -p' + else + # any other ideas? + INSTALL_DIRS='${INSTALL} -d' + fi + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:1425: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +# random libc stuff +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1454: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1467: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1561: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1571: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking for mode_t""... $ac_c" 1>&6 +echo "configure:1598: checking for mode_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_mode_t=yes +else + rm -rf conftest* + ac_cv_type_mode_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_mode_t" 1>&6 +if test $ac_cv_type_mode_t = no; then + cat >> confdefs.h <<\EOF +#define mode_t int +EOF + +fi + +echo $ac_n "checking for pid_t""... $ac_c" 1>&6 +echo "configure:1631: checking for pid_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_pid_t=yes +else + rm -rf conftest* + ac_cv_type_pid_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_pid_t" 1>&6 +if test $ac_cv_type_pid_t = no; then + cat >> confdefs.h <<\EOF +#define pid_t int +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:1664: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +echo "configure:1697: checking return type of signal handlers" >&5 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { +int i; +; return 0; } +EOF +if { (eval echo configure:1719: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1738: checking whether time.h and sys/time.h may both be included" >&5 +if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +int main() { +struct tm *tp; +; return 0; } +EOF +if { (eval echo configure:1752: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_header_time=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_time=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_time" 1>&6 +if test $ac_cv_header_time = yes; then + cat >> confdefs.h <<\EOF +#define TIME_WITH_SYS_TIME 1 +EOF + +fi + +echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 +echo "configure:1773: checking for sys/wait.h that is POSIX.1 compatible" >&5 +if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#ifndef WEXITSTATUS +#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif +int main() { +int s; +wait (&s); +s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; +; return 0; } +EOF +if { (eval echo configure:1794: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_header_sys_wait_h=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_sys_wait_h=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 +if test $ac_cv_header_sys_wait_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_WAIT_H 1 +EOF + +fi + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 +echo "configure:1819: checking for $ac_hdr that defines DIR" >&5 +if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include <$ac_hdr> +int main() { +DIR *dirp = 0; +; return 0; } +EOF +if { (eval echo configure:1832: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then +echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 +echo "configure:1857: checking for opendir in -ldir" >&5 +ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldir $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ldir" +else + echo "$ac_t""no" 1>&6 +fi + +else +echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 +echo "configure:1898: checking for opendir in -lx" >&5 +ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lx $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lx" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking how to call gettimeofday""... $ac_c" 1>&6 +echo "configure:1940: checking how to call gettimeofday" >&5 + if eval "test \"`echo '$''{'ac_cv_gettimeofday_args'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < + #include +int main() { +struct timeval tv; struct timezone tzp; + gettimeofday(&tv, &tzp); +; return 0; } +EOF +if { (eval echo configure:1954: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_gettimeofday_args=2 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext < + #include +int main() { +struct timeval tv; gettimeofday(&tv); +; return 0; } +EOF +if { (eval echo configure:1970: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_gettimeofday_args=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_gettimeofday_args=0 +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_gettimeofday_args=$ac_gettimeofday_args +fi + + ac_gettimeofday_args=$ac_cv_gettimeofday_args + if test "$ac_gettimeofday_args" = 1 ; then + cat >> confdefs.h <<\EOF +#define HAVE_GETTIMEOFDAY 1 +EOF + + echo "$ac_t""one argument" 1>&6 + elif test "$ac_gettimeofday_args" = 2 ; then + cat >> confdefs.h <<\EOF +#define HAVE_GETTIMEOFDAY 1 +EOF + + cat >> confdefs.h <<\EOF +#define GETTIMEOFDAY_TWO_ARGS 1 +EOF + + echo "$ac_t""two arguments" 1>&6 + else + echo "$ac_t""unknown" 1>&6 + fi + +for ac_func in select fcntl uname nice setpriority getcwd getwd putenv +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2009: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2037: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + +for ac_func in sigaction syslog realpath +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2065: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2093: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking for struct icmp""... $ac_c" 1>&6 +echo "configure:2118: checking for struct icmp" >&5 +if eval "test \"`echo '$''{'ac_cv_have_icmp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +int main() { +struct icmp i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.icmp_type = ICMP_ECHO; + i.icmp_code = 0; + i.icmp_cksum = 0; + i.icmp_id = 0; + i.icmp_seq = 0; + si.sin_family = AF_INET; + ip.ip_hl = 0; +; return 0; } +EOF +if { (eval echo configure:2158: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_icmp=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_icmp=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_have_icmp" 1>&6 + if test "$ac_cv_have_icmp" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_ICMP 1 +EOF + + fi +echo $ac_n "checking for struct icmphdr""... $ac_c" 1>&6 +echo "configure:2178: checking for struct icmphdr" >&5 +if eval "test \"`echo '$''{'ac_cv_have_icmphdr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +int main() { +struct icmphdr i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.type = ICMP_ECHO; + i.code = 0; + i.cksum = 0; + i.un.echo.id = 0; + i.un.echo.sequence = 0; + si.sin_family = AF_INET; + ip.ip_hl = 0; +; return 0; } +EOF +if { (eval echo configure:2218: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_icmphdr=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_icmphdr=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_have_icmphdr" 1>&6 + if test "$ac_cv_have_icmphdr" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_ICMPHDR 1 +EOF + + fi +for ac_hdr in crypt.h sys/select.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2241: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +PERL='' + for ac_prog in perl5 perl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2283: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PERL" in + /*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PERL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PERL="$ac_cv_path_PERL" +if test -n "$PERL"; then + echo "$ac_t""$PERL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$PERL" && break +done + + if test -z "$PERL" ; then + PERL_VERSION=0 + else + echo $ac_n "checking perl version""... $ac_c" 1>&6 +echo "configure:2322: checking perl version" >&5 +if eval "test \"`echo '$''{'ac_cv_perl_version'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_perl_version=`$PERL -e "$perl_version_cmd"` +fi + +echo "$ac_t""$ac_cv_perl_version" 1>&6 + PERL_VERSION=$ac_cv_perl_version + fi + + +if test -z "$PERL" ; then + # don't let it be blank... + PERL=/usr/local/bin/perl5 +fi + +# If we find X, set shell vars x_includes and x_libraries to the +# paths, otherwise set no_x=yes. +# Uses ac_ vars as temps to allow command line to override cache and checks. +# --without-x overrides everything else, but does not touch the cache. +echo $ac_n "checking for X""... $ac_c" 1>&6 +echo "configure:2344: checking for X" >&5 + +# Check whether --with-x or --without-x was given. +if test "${with_x+set}" = set; then + withval="$with_x" + : +fi + +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then + # Both variables are already set. + have_x=yes + else +if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=NO ac_x_libraries=NO +rm -fr conftestdir +if mkdir conftestdir; then + cd conftestdir + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' +EOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && + test -f $ac_im_libdir/libX11.$ac_extension; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case "$ac_im_incroot" in + /usr/include) ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; + esac + case "$ac_im_usrlibdir" in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; + esac + fi + cd .. + rm -fr conftestdir +fi + +if test "$ac_x_includes" = NO; then + # Guess where to find include files, by looking for this one X11 .h file. + test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h + + # First, try using that file with no special directory specified. +cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2411: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + # We can compile using X headers with no special include directory. +ac_x_includes= +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + # Look for the header file in a standard set of common directories. +# Check X11 before X11Rn because it is often a symlink to the current release. + for ac_dir in \ + /usr/X11/include \ + /usr/X11R6/include \ + /usr/X11R5/include \ + /usr/X11R4/include \ + \ + /usr/include/X11 \ + /usr/include/X11R6 \ + /usr/include/X11R5 \ + /usr/include/X11R4 \ + \ + /usr/local/X11/include \ + /usr/local/X11R6/include \ + /usr/local/X11R5/include \ + /usr/local/X11R4/include \ + \ + /usr/local/include/X11 \ + /usr/local/include/X11R6 \ + /usr/local/include/X11R5 \ + /usr/local/include/X11R4 \ + \ + /usr/X386/include \ + /usr/x386/include \ + /usr/XFree86/include/X11 \ + \ + /usr/include \ + /usr/local/include \ + /usr/unsupported/include \ + /usr/athena/include \ + /usr/local/x11r5/include \ + /usr/lpp/Xamples/include \ + \ + /usr/openwin/include \ + /usr/openwin/share/include \ + ; \ + do + if test -r "$ac_dir/$x_direct_test_include"; then + ac_x_includes=$ac_dir + break + fi + done +fi +rm -f conftest* +fi # $ac_x_includes = NO + +if test "$ac_x_libraries" = NO; then + # Check for the libraries. + + test -z "$x_direct_test_library" && x_direct_test_library=Xt + test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc + + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS="$LIBS" + LIBS="-l$x_direct_test_library $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + LIBS="$ac_save_LIBS" +# We can link X programs with no special library path. +ac_x_libraries= +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + LIBS="$ac_save_LIBS" +# First see if replacing the include by lib works. +# Check X11 before X11Rn because it is often a symlink to the current release. +for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ + /usr/X11/lib \ + /usr/X11R6/lib \ + /usr/X11R5/lib \ + /usr/X11R4/lib \ + \ + /usr/lib/X11 \ + /usr/lib/X11R6 \ + /usr/lib/X11R5 \ + /usr/lib/X11R4 \ + \ + /usr/local/X11/lib \ + /usr/local/X11R6/lib \ + /usr/local/X11R5/lib \ + /usr/local/X11R4/lib \ + \ + /usr/local/lib/X11 \ + /usr/local/lib/X11R6 \ + /usr/local/lib/X11R5 \ + /usr/local/lib/X11R4 \ + \ + /usr/X386/lib \ + /usr/x386/lib \ + /usr/XFree86/lib/X11 \ + \ + /usr/lib \ + /usr/local/lib \ + /usr/unsupported/lib \ + /usr/athena/lib \ + /usr/local/x11r5/lib \ + /usr/lpp/Xamples/lib \ + /lib/usr/lib/X11 \ + \ + /usr/openwin/lib \ + /usr/openwin/share/lib \ + ; \ +do + for ac_extension in a so sl; do + if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f conftest* +fi # $ac_x_libraries = NO + +if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" +else + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" +fi +fi + fi + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + echo "$ac_t""$have_x" 1>&6 + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + cat >> confdefs.h <<\EOF +#define X_DISPLAY_MISSING 1 +EOF + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + case "`(uname -sr) 2>/dev/null`" in + "SunOS 5"*) + echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 +echo "configure:2593: checking whether -R must be followed by a space" >&5 + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_nospace=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_nospace=no +fi +rm -f conftest* + if test $ac_R_nospace = yes; then + echo "$ac_t""no" 1>&6 + X_LIBS="$X_LIBS -R$x_libraries" + else + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_space=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_space=no +fi +rm -f conftest* + if test $ac_R_space = yes; then + echo "$ac_t""yes" 1>&6 + X_LIBS="$X_LIBS -R $x_libraries" + else + echo "$ac_t""neither works" 1>&6 + fi + fi + LIBS="$ac_xsave_LIBS" + esac + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And karl@cs.umb.edu says + # the Alpha needs dnet_stub (dnet does not exist). + echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 +echo "configure:2658: checking for dnet_ntoa in -ldnet" >&5 +ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 +echo "configure:2699: checking for dnet_ntoa in -ldnet_stub" >&5 +ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet_stub $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to dickey@clark.net. + echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +echo "configure:2747: checking for gethostbyname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +gethostbyname(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gethostbyname=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_gethostbyname = no; then + echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:2796: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says simon@lia.di.epfl.ch: it contains + # gethostby* variants that don't use the nameserver (or something). + # -lsocket must be given before -lnsl if both are needed. + # We assume that if connect needs -lnsl, so does gethostbyname. + echo $ac_n "checking for connect""... $ac_c" 1>&6 +echo "configure:2845: checking for connect" >&5 +if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +connect(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_connect=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_connect=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_connect = no; then + echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 +echo "configure:2894: checking for connect in -lsocket" >&5 +ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. + echo $ac_n "checking for remove""... $ac_c" 1>&6 +echo "configure:2937: checking for remove" >&5 +if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char remove(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_remove) || defined (__stub___remove) +choke me +#else +remove(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2965: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_remove=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_remove=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_remove = no; then + echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 +echo "configure:2986: checking for remove in -lposix" >&5 +ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lposix $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + echo $ac_n "checking for shmat""... $ac_c" 1>&6 +echo "configure:3029: checking for shmat" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shmat(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shmat) || defined (__stub___shmat) +choke me +#else +shmat(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shmat=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shmat=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_shmat = no; then + echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 +echo "configure:3078: checking for shmat in -lipc" >&5 +ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lipc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +else + echo "$ac_t""no" 1>&6 +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS="$LDFLAGS" + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. + echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 +echo "configure:3130: checking for IceConnectionNumber in -lICE" >&5 +ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lICE $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +else + echo "$ac_t""no" 1>&6 +fi + + LDFLAGS="$ac_save_LDFLAGS" + +fi + + +if test "$have_x" != yes; then + { echo "configure: error: Couldn't find X11 headers/libs. Try \`$0 --help'." 1>&2; exit 1; } +fi + + + echo $ac_n "checking for X app-defaults directory""... $ac_c" 1>&6 +echo "configure:3180: checking for X app-defaults directory" >&5 +if eval "test \"`echo '$''{'ac_cv_x_app_defaults'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + rm -fr conftestdir + if mkdir conftestdir; then + cd conftestdir >&- + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_x_app_defaults="${XAPPLOADDIR}"' +EOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which'd confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + fi + cd .. >&- + rm -fr conftestdir + fi + if test x"$ac_x_app_defaults" = x; then + + # Look for the directory under a standard set of common directories. + # Check X11 before X11Rn because it's often a symlink to the current release. + for ac_dir in \ + /usr/X11/lib/app-defaults \ + /usr/X11R6/lib/app-defaults \ + /usr/X11R6/lib/X11/app-defaults \ + /usr/X11R5/lib/app-defaults \ + /usr/X11R5/lib/X11/app-defaults \ + /usr/X11R4/lib/app-defaults \ + /usr/X11R4/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/lib/X11R6/app-defaults \ + /usr/lib/X11R5/app-defaults \ + /usr/lib/X11R4/app-defaults \ + \ + /usr/local/X11/lib/app-defaults \ + /usr/local/X11R6/lib/app-defaults \ + /usr/local/X11R5/lib/app-defaults \ + /usr/local/X11R4/lib/app-defaults \ + \ + /usr/local/lib/X11/app-defaults \ + /usr/local/lib/X11R6/app-defaults \ + /usr/local/lib/X11R6/X11/app-defaults \ + /usr/local/lib/X11R5/app-defaults \ + /usr/local/lib/X11R5/X11/app-defaults \ + /usr/local/lib/X11R4/app-defaults \ + /usr/local/lib/X11R4/X11/app-defaults \ + \ + /usr/X386/lib/X11/app-defaults \ + /usr/x386/lib/X11/app-defaults \ + /usr/XFree86/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/local/lib/X11/app-defaults \ + /usr/unsupported/lib/X11/app-defaults \ + /usr/athena/lib/X11/app-defaults \ + /usr/local/x11r5/lib/X11/app-defaults \ + /usr/lpp/Xamples/lib/X11/app-defaults \ + /lib/usr/lib/X11/app-defaults \ + \ + /usr/openwin/lib/app-defaults \ + /usr/openwin/lib/X11/app-defaults \ + /usr/openwin/share/lib/app-defaults \ + /usr/openwin/share/lib/X11/app-defaults \ + \ + /X11R6/lib/app-defaults \ + /X11R5/lib/app-defaults \ + /X11R4/lib/app-defaults \ + ; \ + do + if test -d "$ac_dir"; then + ac_x_app_defaults=$ac_dir + break + fi + done + + fi + if test x"$ac_x_app_defaults" = x; then + ac_cv_x_app_defaults="/usr/lib/X11/app-defaults" + else + # Record where we found app-defaults for the cache. + ac_cv_x_app_defaults="$ac_x_app_defaults" + fi +fi + +echo "$ac_t""$ac_cv_x_app_defaults" 1>&6 + eval ac_x_app_defaults="$ac_cv_x_app_defaults" +case "$host" in + *-hpux*) + + # The following arcana was gleaned from conversations with + # Eric Schwartz : + # + # On HPUX 10.x, the parts of X that HP considers "standard" live in + # /usr/{include,lib}/X11R6/. The parts that HP doesn't consider + # "standard", notably, Xaw and Xmu, live in /usr/contrib/X11R6/. + # Yet /usr/contrib/X11R6/ comes preinstalled on all HPUX systems. + # Also, there are symlinks from /usr/include/ and /usr/lib/ into + # /usr/{include,lib}/X11R6/, so that (if you don't use Xmu at all) + # you don't need any -I or -L arguments. + # + # On HPUX 9.x, /usr/{include,lib}/X11R5/ and /usr/contrib/X11R5/ + # are the same division as 10.x. However, there are no symlinks to + # the X stuff from /usr/include/ and /usr/lib/, so -I and -L + # arguments are always necessary. + # + # However, X11R6 was available on HPUX 9.x as a patch: if that + # patch was installed, then all of X11R6 went in to + # /usr/contrib/X11R6/ (there was no /usr/{include,lib}/X11R6/.) + # + # HPUX 8.x was the same as 9.x, but was X11R4 instead (I don't know + # whether R5 was available as a patch; R6 undoubtedly was not.) + # + # So. We try and use the highest numbered pair of + # /usr/{include,lib}/X11R?/ and /usr/contrib/X11R?/{include,lib}/ + # that are available. We do not mix and match different versions + # of X. + # + # Question I still don't know the answer to: (do you?) + # + # * On HPUX 9.x, where /usr/include/X11R5/ was standard, and + # /usr/contrib/X11R6/ could be installed as a patch, what was in + # that contrib directory? Did it contain so-called "standard" + # X11R6, or did it include Xaw and Xmu as well? If the former, + # where did one find Xaw and Xmu on 9.x R6 systems? Would this + # be a situation where one had to reach into the R5 headers and + # libs to find Xmu? That is, must both R6 and R5 directories + # be on the -I and -L lists in that case? + # + for version in X11R6 X11R5 X11R4 ; do + # if either pair of directories exists... + if test -d /usr/lib/$version || test -d /usr/contrib/$version/lib + then + # if contrib exists, use it... + if test -d /usr/contrib/$version/lib ; then + X_CFLAGS="$X_CFLAGS -I/usr/contrib/$version/include" + X_LIBS="$X_LIBS -L/usr/contrib/$version/lib" + fi + # if the "standard" one exists, use it. + if test -d /usr/lib/$version ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/$version" + X_LIBS="$X_LIBS -L/usr/lib/$version" + fi + # since at least one of the pair exists, go no farther. + break + fi + done + + # Now find Motif. Thanks for not making xmkmf find this by + # default, you losers. + # + if test -d /usr/lib/Motif1.2 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.2" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.2" + elif test -d /usr/lib/Motif1.1 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.1" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.1" + fi + + # Now let's check for the pseudo-standard locations for OpenGL and XPM. + # + if test -d /opt/Mesa/lib ; then + X_CFLAGS="-I/opt/Mesa/include $X_CFLAGS" + X_LIBS="-L/opt/Mesa/lib $X_LIBS" + fi + + if test -d /opt/xpm/lib/X11 ; then + X_CFLAGS="-I/opt/xpm/include $X_CFLAGS" + X_LIBS="-L/opt/xpm/lib/X11 $X_LIBS" + fi + + # On HPUX, default to installing in /opt/xscreensaver/ instead of + # in /usr/local/, unless there is already an xscreensaver in + # /usr/local/bin/. This can be overridden with the --prefix arg + # to configure. I'm not sure this is the right thing to do, but + # Richard Lloyd says so... + # + if test \! -x /usr/local/bin/xscreensaver ; then + ac_default_prefix=/opt/xscreensaver + fi + + ;; + *-solaris*) + + # Thanks for not making xmkmf find this by default, pinheads. + # And thanks for moving things around again, too. Is this + # really the standard location now? What happened to the + # joke that this kind of thing went in /opt? + # cthomp says "answer: CDE (Common Disorganized Environment)" + # + if test -f /usr/dt/include/Xm/Xm.h ; then + X_CFLAGS="$X_CFLAGS -I/usr/dt/include" + X_LIBS="$X_LIBS -L/usr/dt/lib -R:/usr/dt/lib" + + # Some versions of Slowlaris Motif require -lgen. But not all. Why? + echo $ac_n "checking for regcmp in -lgen""... $ac_c" 1>&6 +echo "configure:3379: checking for regcmp in -lgen" >&5 +ac_lib_var=`echo gen'_'regcmp | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgen $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_LIBS="$X_LIBS -lgen" +else + echo "$ac_t""no" 1>&6 +fi + + fi + ;; + esac +echo $ac_n "checking for XPointer""... $ac_c" 1>&6 +echo "configure:3422: checking for XPointer" >&5 +if eval "test \"`echo '$''{'ac_cv_xpointer'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < +int main() { +XPointer foo = (XPointer) 0; +; return 0; } +EOF +if { (eval echo configure:3440: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_xpointer=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_xpointer=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_xpointer" 1>&6 + if test "$ac_cv_xpointer" != yes; then + cat >> confdefs.h <<\EOF +#define XPointer char* +EOF + + fi + + + +############################################################################### +# +# Check for -lXmu (some fucked up vendors don't ship it...) +# +############################################################################### + +have_xmu=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/Xmu/Error.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/Xmu/Error.h""... $ac_c" 1>&6 +echo "configure:3478: checking for X11/Xmu/Error.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3488: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xmu=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +if test "$have_xmu" = no ; then + XMU_SRCS='$(UTILS_SRC)/xmu.c' + XMU_OBJS='$(UTILS_BIN)/xmu.o' +else + XMU_SRCS='' + XMU_OBJS='' + SAVER_LIBS="-lXmu $SAVER_LIBS" + HACK_LIBS="-lXmu $HACK_LIBS" + MOTIF_LIBS="-lXmu $MOTIF_LIBS" + GTK_LIBS="-lXmu $GTK_LIBS" + ATHENA_LIBS="-lXmu $ATHENA_LIBS" + ATHENA3D_LIBS="-lXmu $ATHENA3D_LIBS" + cat >> confdefs.h <<\EOF +#define HAVE_XMU 1 +EOF + +fi + + +############################################################################### +# +# Check for the SunOS 4.1.x _get_wmShellWidgetClass bug. +# See comp.windows.x FAQ question 124. The right fix is to +# get OpenWindows 3.0 patches 100512-02 and 100573-03. +# +############################################################################### + +if test "$have_xmu" = yes ; then + case "$host" in + *-sunos4*) + echo $ac_n "checking for the SunOS 4.1.x _get_wmShellWidgetClass bug""... $ac_c" 1>&6 +echo "configure:3541: checking for the SunOS 4.1.x _get_wmShellWidgetClass bug" >&5 +if eval "test \"`echo '$''{'ac_cv_sunos_xmu_bug'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LDFLAGS="$LDFLAGS" + if test \! -z "$x_libraries" ; then + LDFLAGS="$LDFLAGS -L$x_libraries" + fi + # Note: this trick never works! (Generally.) + # We're only getting away with using AC_TRY_LINK + # with X libraries because we know it's SunOS. + LDFLAGS="$LDFLAGS -lXmu -lXt -lX11 -lXext -lm" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_sunos_xmu_bug=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_sunos_xmu_bug=yes +fi +rm -f conftest* + LDFLAGS="$ac_save_LDFLAGS" +fi + +echo "$ac_t""$ac_cv_sunos_xmu_bug" 1>&6 + if test "$ac_cv_sunos_xmu_bug" = yes ; then + echo $ac_n "checking whether the compiler understands -static""... $ac_c" 1>&6 +echo "configure:3577: checking whether the compiler understands -static" >&5 +if eval "test \"`echo '$''{'ac_cv_ld_static'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -static" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_ld_static=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_ld_static=no +fi +rm -f conftest* + LDFLAGS="$ac_save_LDFLAGS" +fi + +echo "$ac_t""$ac_cv_ld_static" 1>&6 + if test "$ac_cv_ld_static" = yes ; then + LDFLAGS="$LDFLAGS -static" + else + LDFLAGS="$LDFLAGS -Bstatic" + fi + fi + ;; + esac +fi + + +############################################################################### +# +# Handle the --enable-subdir option +# +############################################################################### + +# Check whether --enable-subdir or --disable-subdir was given. +if test "${enable_subdir+set}" = set; then + enableval="$enable_subdir" + enable_subdir="$enableval" +else + enable_subdir=no +fi + +if test x"$enable_subdir" = xno; then + HACKDIR='${bindir}' +elif test x"$enable_subdir" = xyes -o x"$enable_subdir" = x ; then + echo "error: must be a subdirectory name: --enable-subdir=$enable_subdir" + exit 1 +else + # there must be a better way than this... + if test -z "`echo $enable_subdir | sed 's@^/.*@@'`" ; then + # absolute path + HACKDIR=$enable_subdir + else + # relative path + HACKDIR='${bindir}/'$enable_subdir + fi +fi + +# canonicalize slashes. +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` + + +############################################################################### +# +# Check for the SGI SCREEN_SAVER server extension. +# +############################################################################### + +have_sgi=no +with_sgi_req=unspecified +# Check whether --with-sgi-ext or --without-sgi-ext was given. +if test "${with_sgi_ext+set}" = set; then + withval="$with_sgi_ext" + with_sgi="$withval"; with_sgi_req="$withval" +else + with_sgi=yes +fi + + + + case "$with_sgi" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for SGI SCREEN_SAVER headers""... $ac_c" 1>&6 +echo "configure:3674: checking for SGI SCREEN_SAVER headers" >&5 + d=$with_sgi/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for SGI SCREEN_SAVER libs""... $ac_c" 1>&6 +echo "configure:3684: checking for SGI SCREEN_SAVER libs" >&5 + d=$with_sgi/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_sgi_req="yes" + with_sgi=$with_sgi_req + ;; + + *) + echo "" + echo "error: argument to --with-sgi-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_sgi" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/XScreenSaver.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/XScreenSaver.h""... $ac_c" 1>&6 +echo "configure:3717: checking for X11/extensions/XScreenSaver.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3727: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_sgi=yes + cat >> confdefs.h <<\EOF +#define HAVE_SGI_SAVER_EXTENSION 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + +elif test "$with_sgi" != no; then + echo "error: must be yes or no: --with-sgi-ext=$with_sgi" + exit 1 +fi + + +############################################################################### +# +# Check for the MIT-SCREEN-SAVER server extension. +# +############################################################################### + +have_mit=no +with_mit_req=unspecified +# Check whether --with-mit-ext or --without-mit-ext was given. +if test "${with_mit_ext+set}" = set; then + withval="$with_mit_ext" + with_mit="$withval"; with_mit_req="$withval" +else + with_mit=yes +fi + + + + case "$with_mit" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for MIT-SCREEN-SAVER headers""... $ac_c" 1>&6 +echo "configure:3784: checking for MIT-SCREEN-SAVER headers" >&5 + d=$with_mit/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for MIT-SCREEN-SAVER libs""... $ac_c" 1>&6 +echo "configure:3794: checking for MIT-SCREEN-SAVER libs" >&5 + d=$with_mit/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_mit_req="yes" + with_mit=$with_mit_req + ;; + + *) + echo "" + echo "error: argument to --with-mit-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_mit" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/scrnsaver.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/scrnsaver.h""... $ac_c" 1>&6 +echo "configure:3827: checking for X11/extensions/scrnsaver.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3837: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_mit=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + + # Now check to see if it's really in the library; XF86Free-3.3 ships + # scrnsaver.h, but doesn't include the code in libXext.a, the idiots! + # + if test "$have_mit" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for XScreenSaverRegister in -lXext""... $ac_c" 1>&6 +echo "configure:3882: checking for XScreenSaverRegister in -lXext" >&5 +ac_lib_var=`echo Xext'_'XScreenSaverRegister | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + true +else + echo "$ac_t""no" 1>&6 +have_mit=no +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + if test "$have_mit" = no; then + # Fuck! Looks like XF86Free-3.3 actually puts it in XExExt instead + # of in Xext. Thank you master, may I have another. + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for XScreenSaverRegister in -lXExExt""... $ac_c" 1>&6 +echo "configure:3948: checking for XScreenSaverRegister in -lXExExt" >&5 +ac_lib_var=`echo XExExt'_'XScreenSaverRegister | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXExExt -lX11 -lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_mit=yes; SAVER_LIBS="$SAVER_LIBS -lXExExt" +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + if test "$have_mit" = no; then + # Double fuck! Looks like some versions of XFree86 (whichever version + # it is that comes with RedHat Linux 2.0 -- I can't find a version + # number) put this garbage in Xss instead of Xext. Thank you master, + # may I have another. + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for XScreenSaverRegister in -lXss""... $ac_c" 1>&6 +echo "configure:4017: checking for XScreenSaverRegister in -lXss" >&5 +ac_lib_var=`echo Xss'_'XScreenSaverRegister | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXss -lX11 -lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_mit=yes; SAVER_LIBS="$SAVER_LIBS -lXss" +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + if test "$have_mit" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MIT_SAVER_EXTENSION 1 +EOF + + fi + + fi + +elif test "$with_mit" != no; then + echo "error: must be yes or no: --with-mit-ext=$with_mit" + exit 1 +fi + + +############################################################################### +# +# Check for the XIDLE server extension. +# +############################################################################### + +have_xidle=no +with_xidle_req=unspecified +# Check whether --with-xidle-ext or --without-xidle-ext was given. +if test "${with_xidle_ext+set}" = set; then + withval="$with_xidle_ext" + with_xidle="$withval"; with_xidle_req="$withval" +else + with_xidle=yes +fi + + + + case "$with_xidle" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for XIDLE headers""... $ac_c" 1>&6 +echo "configure:4102: checking for XIDLE headers" >&5 + d=$with_xidle/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for XIDLE libs""... $ac_c" 1>&6 +echo "configure:4112: checking for XIDLE libs" >&5 + d=$with_xidle/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_xidle_req="yes" + with_xidle=$with_xidle_req + ;; + + *) + echo "" + echo "error: argument to --with-xidle-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xidle" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/xidle.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/xidle.h""... $ac_c" 1>&6 +echo "configure:4145: checking for X11/extensions/xidle.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xidle=yes + cat >> confdefs.h <<\EOF +#define HAVE_XIDLE_EXTENSION 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +elif test "$with_xidle" != no; then + echo "error: must be yes or no: --with-xidle-ext=$with_xidle" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI-VIDEO-CONTROL server extension. +# +############################################################################### + +have_sgivc=no +with_sgivc_req=unspecified +# Check whether --with-sgivc-ext or --without-sgivc-ext was given. +if test "${with_sgivc_ext+set}" = set; then + withval="$with_sgivc_ext" + with_sgivc="$withval"; with_sgivc_req="$withval" +else + with_sgivc=yes +fi + + + + case "$with_sgivc" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for SGI-VIDEO-CONTROL headers""... $ac_c" 1>&6 +echo "configure:4211: checking for SGI-VIDEO-CONTROL headers" >&5 + d=$with_sgivc/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for SGI-VIDEO-CONTROL libs""... $ac_c" 1>&6 +echo "configure:4221: checking for SGI-VIDEO-CONTROL libs" >&5 + d=$with_sgivc/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_sgivc_req="yes" + with_sgivc=$with_sgivc_req + ;; + + *) + echo "" + echo "error: argument to --with-sgivc-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_sgivc" = yes; then + + # first check for XSGIvc.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/XSGIvc.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/XSGIvc.h""... $ac_c" 1>&6 +echo "configure:4256: checking for X11/extensions/XSGIvc.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_sgivc=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for the -lXsgivc + if test "$have_sgivc" = yes; then + have_sgivc=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for XSGIvcQueryGammaMap in -lXsgivc""... $ac_c" 1>&6 +echo "configure:4310: checking for XSGIvcQueryGammaMap in -lXsgivc" >&5 +ac_lib_var=`echo Xsgivc'_'XSGIvcQueryGammaMap | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXsgivc -lXext -lX11 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_sgivc=yes; SAVER_LIBS="$SAVER_LIBS -lXsgivc" +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + # if that succeeded, then we've really got it. + if test "$have_sgivc" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_SGI_VC_EXTENSION 1 +EOF + + fi + +elif test "$with_sgivc" != no; then + echo "error: must be yes or no: --with-sgivc-ext=$with_sgivc" + exit 1 +fi + + +############################################################################### +# +# Check for the DPMS server extension. +# +############################################################################### + +have_dpms=no +with_dpms_req=unspecified +# Check whether --with-dpms-ext or --without-dpms-ext was given. +if test "${with_dpms_ext+set}" = set; then + withval="$with_dpms_ext" + with_dpms="$withval"; with_dpms_req="$withval" +else + with_dpms=yes +fi + + + + case "$with_dpms" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for DPMS headers""... $ac_c" 1>&6 +echo "configure:4394: checking for DPMS headers" >&5 + d=$with_dpms/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for DPMS libs""... $ac_c" 1>&6 +echo "configure:4404: checking for DPMS libs" >&5 + d=$with_dpms/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_dpms_req="yes" + with_dpms=$with_dpms_req + ;; + + *) + echo "" + echo "error: argument to --with-dpms-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_dpms" = yes; then + + # first check for dpms.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/dpms.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/dpms.h""... $ac_c" 1>&6 +echo "configure:4439: checking for X11/extensions/dpms.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4449: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_dpms=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for the -lXdpms + if test "$have_dpms" = yes; then + have_dpms=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for DPMSInfo in -lXdpms""... $ac_c" 1>&6 +echo "configure:4493: checking for DPMSInfo in -lXdpms" >&5 +ac_lib_var=`echo Xdpms'_'DPMSInfo | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXdpms -lXext -lX11 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_dpms=yes; SAVER_LIBS="$SAVER_LIBS -lXdpms" +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + # if that succeeded, then we've really got it. + if test "$have_dpms" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_DPMS_EXTENSION 1 +EOF + + fi + +elif test "$with_dpms" != no; then + echo "error: must be yes or no: --with-dpms-ext=$with_dpms" + exit 1 +fi + + +############################################################################### +# +# Check for the XF86VMODE server extension. +# +############################################################################### + +have_xf86vmode=no +with_xf86vmode_req=unspecified +# Check whether --with-xf86vmode-ext or --without-xf86vmode-ext was given. +if test "${with_xf86vmode_ext+set}" = set; then + withval="$with_xf86vmode_ext" + with_xf86vmode="$withval"; with_xf86vmode_req="$withval" +else + with_xf86vmode=yes +fi + + + + case "$with_xf86vmode" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for xf86vmode headers""... $ac_c" 1>&6 +echo "configure:4577: checking for xf86vmode headers" >&5 + d=$with_xf86vmode/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for xf86vmode libs""... $ac_c" 1>&6 +echo "configure:4587: checking for xf86vmode libs" >&5 + d=$with_xf86vmode/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_xf86vmode_req="yes" + with_xf86vmode=$with_xf86vmode_req + ;; + + *) + echo "" + echo "error: argument to --with-xf86vmode-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xf86vmode" = yes; then + + # first check for xf86vmode.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/xf86vmode.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/xf86vmode.h""... $ac_c" 1>&6 +echo "configure:4622: checking for X11/extensions/xf86vmode.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4632: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xf86vmode=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for the -lXxf86vm + if test "$have_xf86vmode" = yes; then + have_xf86vmode=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for XF86VidModeGetViewPort in -lXxf86vm""... $ac_c" 1>&6 +echo "configure:4676: checking for XF86VidModeGetViewPort in -lXxf86vm" >&5 +ac_lib_var=`echo Xxf86vm'_'XF86VidModeGetViewPort | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXxf86vm -lXext -lX11 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xf86vmode=yes; SAVER_LIBS="$SAVER_LIBS -lXxf86vm" +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + # if that succeeded, then we've really got it. + if test "$have_xf86vmode" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_XF86VMODE 1 +EOF + + fi + +elif test "$with_xf86vmode" != no; then + echo "error: must be yes or no: --with-xf86vmode-ext=$with_xf86vmode" + exit 1 +fi + + +############################################################################### +# +# Check for HP XHPDisableReset and XHPEnableReset. +# +############################################################################### + + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "XHPDisableReset" >/dev/null 2>&1; then + rm -rf conftest* + cat >> confdefs.h <<\EOF +#define HAVE_XHPDISABLERESET 1 +EOF + + SAVER_LIBS="-lXhp11 $SAVER_LIBS" +fi +rm -f conftest* + + CPPFLAGS="$ac_save_CPPFLAGS" + + +############################################################################### +# +# Check for /proc/interrupts. +# +############################################################################### + +have_proc_interrupts=no +with_proc_interrupts_req=unspecified +# Check whether --with-proc-interrupts or --without-proc-interrupts was given. +if test "${with_proc_interrupts+set}" = set; then + withval="$with_proc_interrupts" + with_proc_interrupts="$withval"; with_proc_interrupts_req="$withval" +else + with_proc_interrupts=yes +fi + + +if test "$with_proc_interrupts" = yes; then + + echo $ac_n "checking whether /proc/interrupts contains keyboard data""... $ac_c" 1>&6 +echo "configure:4787: checking whether /proc/interrupts contains keyboard data" >&5 +if eval "test \"`echo '$''{'ac_cv_have_proc_interrupts'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_have_proc_interrupts=no + if grep keyboard /proc/interrupts >/dev/null 2>&1 ; then + ac_cv_have_proc_interrupts=yes + fi + +fi + +echo "$ac_t""$ac_cv_have_proc_interrupts" 1>&6 + have_proc_interrupts=$ac_cv_have_proc_interrupts + + if test "$have_proc_interrupts" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_PROC_INTERRUPTS 1 +EOF + + fi + +elif test "$with_proc_interrupts" != no; then + echo "error: must be yes or no: --with-proc-interrupts=$with_proc_interrupts" + exit 1 +fi + + +############################################################################### +# +# The --enable-locking option +# +############################################################################### + +# Check whether --enable-locking or --disable-locking was given. +if test "${enable_locking+set}" = set; then + enableval="$enable_locking" + enable_locking="$enableval" +else + enable_locking=yes +fi + +if test "$enable_locking" = yes; then + true +elif test "$enable_locking" = no; then + cat >> confdefs.h <<\EOF +#define NO_LOCKING 1 +EOF + +else + echo "error: must be yes or no: --enable-locking=$enable_locking" + exit 1 +fi + + + +############################################################################### +# +# The --enable-vt-locking option +# +############################################################################### + +#ac_vt_lockswitch=no +#AC_ARG_ENABLE(vt-locking,[ +# --enable-vt-locking Compile in support for locking Virtual Terminals. +# This is the default if the system supports it, and +# if locking support is included (--enable-locking.) +# --disable-vt-locking Do not allow locking of VTs, even if locking is +# enabled.], +# [enable_vt_locking="$enableval"],[enable_vt_locking=yes]) +#if test "$enable_vt_locking" = yes; then +# +# AC_CACHE_CHECK([for the VT_LOCKSWITCH ioctl], ac_cv_vt_lockswitch, +# [AC_TRY_COMPILE([#include +# #include +# #include ], +# [int x = VT_LOCKSWITCH; int y = VT_UNLOCKSWITCH;], +# [ac_cv_vt_lockswitch=yes], +# [ac_cv_vt_lockswitch=no])]) +# ac_vt_lockswitch=$ac_cv_vt_lockswitch +# +#elif test "$enable_vt_locking" = no; then +# true +#else +# echo "error: must be yes or no: --enable-vt-locking=$enable_vt_locking" +# exit 1 +#fi +# +#if test "$ac_vt_lockswitch" = yes; then +# AC_DEFINE(HAVE_VT_LOCKSWITCH) +# # the VT_LOCKSWITCH ioctl can only be used when running as root. +# # #### but it doesn't work yet, so don't worry about that for now. +## need_setuid=yes +#fi + + + +############################################################################### +# +# Check for PAM. +# +############################################################################### + +case "$host" in + *-solaris*) + # Solaris systems tend to come with PAM misconfigured. + # Don't build it by default, even if the headers exist. + with_pam_default=no + ;; + *) + # Default to building PAM support on all other systems, if it exists. + with_pam_default=yes + ;; +esac + +have_pam=no +with_pam_req=unspecified + +# Check whether --with-pam or --without-pam was given. +if test "${with_pam+set}" = set; then + withval="$with_pam" + with_pam="$withval"; with_pam_req="$withval" +else + with_pam=$with_pam_default +fi + + + + case "$with_pam" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for PAM headers""... $ac_c" 1>&6 +echo "configure:4920: checking for PAM headers" >&5 + d=$with_pam/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for PAM libs""... $ac_c" 1>&6 +echo "configure:4930: checking for PAM libs" >&5 + d=$with_pam/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_pam_req="yes" + with_pam=$with_pam_req + ;; + + *) + echo "" + echo "error: argument to --with-pam must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$enable_locking" = yes -a "$with_pam" = yes; then + echo $ac_n "checking for PAM""... $ac_c" 1>&6 +echo "configure:4956: checking for PAM" >&5 +if eval "test \"`echo '$''{'ac_cv_pam'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < +int main() { + +; return 0; } +EOF +if { (eval echo configure:4974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_pam=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_pam=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_pam" 1>&6 + if test "$ac_cv_pam" = yes ; then + have_pam=yes + cat >> confdefs.h <<\EOF +#define HAVE_PAM 1 +EOF + + PASSWD_LIBS="${PASSWD_LIBS} -lpam" + + # libpam typically requires dlopen and dlsym. On FreeBSD, + # those are in libc. On Linux and Solaris, they're in libdl. + echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "configure:4999: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + PASSWD_LIBS="${PASSWD_LIBS} -ldl" +else + echo "$ac_t""no" 1>&6 +fi + + + echo $ac_n "checking how to call pam_strerror""... $ac_c" 1>&6 +echo "configure:5040: checking how to call pam_strerror" >&5 + if eval "test \"`echo '$''{'ac_cv_pam_strerror_args'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < + #include + #include +int main() { +pam_handle_t *pamh = 0; + char *s = pam_strerror(pamh, PAM_SUCCESS); +; return 0; } +EOF +if { (eval echo configure:5055: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_pam_strerror_args=2 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext < + #include + #include +int main() { +char *s = + pam_strerror(PAM_SUCCESS); +; return 0; } +EOF +if { (eval echo configure:5073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_pam_strerror_args=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_pam_strerror_args=0 +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_pam_strerror_args=$ac_pam_strerror_args +fi + + ac_pam_strerror_args=$ac_cv_pam_strerror_args + if test "$ac_pam_strerror_args" = 1 ; then + echo "$ac_t""one argument" 1>&6 + elif test "$ac_pam_strerror_args" = 2 ; then + cat >> confdefs.h <<\EOF +#define PAM_STRERROR_TWO_ARGS 1 +EOF + + echo "$ac_t""two arguments" 1>&6 + else + echo "$ac_t""unknown" 1>&6 + fi + fi +fi + + +############################################################################### +# +# Check for Kerberos. +# +############################################################################### + +have_kerberos=no +with_kerberos_req=unspecified + +# Check whether --with-kerberos or --without-kerberos was given. +if test "${with_kerberos+set}" = set; then + withval="$with_kerberos" + with_kerberos="$withval"; with_kerberos_req="$withval" +else + with_kerberos=yes +fi + + + + case "$with_kerberos" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for Kerberos headers""... $ac_c" 1>&6 +echo "configure:5129: checking for Kerberos headers" >&5 + d=$with_kerberos/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for Kerberos libs""... $ac_c" 1>&6 +echo "configure:5139: checking for Kerberos libs" >&5 + d=$with_kerberos/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_kerberos_req="yes" + with_kerberos=$with_kerberos_req + ;; + + *) + echo "" + echo "error: argument to --with-kerberos must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$enable_locking" = yes -a "$with_kerberos" = yes; then + echo $ac_n "checking for Kerberos""... $ac_c" 1>&6 +echo "configure:5165: checking for Kerberos" >&5 +if eval "test \"`echo '$''{'ac_cv_kerberos'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < +int main() { + +; return 0; } +EOF +if { (eval echo configure:5183: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_kerberos=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_kerberos=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_kerberos" 1>&6 + if test "$ac_cv_kerberos" = yes ; then + have_kerberos=yes + cat >> confdefs.h <<\EOF +#define HAVE_KERBEROS 1 +EOF + + + # from Tim Showalter + PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes" + echo $ac_n "checking for res_search""... $ac_c" 1>&6 +echo "configure:5207: checking for res_search" >&5 +if eval "test \"`echo '$''{'ac_cv_func_res_search'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char res_search(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_res_search) || defined (__stub___res_search) +choke me +#else +res_search(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5235: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_res_search=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_res_search=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'res_search`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for res_search in -lresolv""... $ac_c" 1>&6 +echo "configure:5253: checking for res_search in -lresolv" >&5 +ac_lib_var=`echo resolv'_'res_search | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + PASSWD_LIBS="${PASSWD_LIBS} -lresolv" +else + echo "$ac_t""no" 1>&6 +echo "configure: warning: Can't find DNS resolver libraries needed for Kerberos" 1>&2 + +fi + +fi + + + fi +fi + + +############################################################################### +# +# Check for the nine billion variants of shadow passwords... +# +############################################################################### + +need_setuid=no + +have_shadow=no +with_shadow_req=unspecified + +# Check whether --with-shadow or --without-shadow was given. +if test "${with_shadow+set}" = set; then + withval="$with_shadow" + with_shadow="$withval"; with_shadow_req="$withval" +else + with_shadow=yes +fi + + + + case "$with_shadow" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for shadow password headers""... $ac_c" 1>&6 +echo "configure:5328: checking for shadow password headers" >&5 + d=$with_shadow/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for shadow password libs""... $ac_c" 1>&6 +echo "configure:5338: checking for shadow password libs" >&5 + d=$with_shadow/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_shadow_req="yes" + with_shadow=$with_shadow_req + ;; + + *) + echo "" + echo "error: argument to --with-shadow must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$enable_locking" = no ; then + with_shadow_req=no + with_shadow=no +fi + + +############################################################################### +# +# Check for Sun "adjunct" passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + echo $ac_n "checking for Sun-style shadow passwords""... $ac_c" 1>&6 +echo "configure:5376: checking for Sun-style shadow passwords" >&5 +if eval "test \"`echo '$''{'ac_cv_sun_adjunct'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < + #include + #include + #include + #include + #include +int main() { +struct passwd_adjunct *p = getpwanam("nobody"); + const char *pw = p->pwa_passwd; +; return 0; } +EOF +if { (eval echo configure:5400: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_sun_adjunct=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_sun_adjunct=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_sun_adjunct" 1>&6 + if test "$ac_cv_sun_adjunct" = yes; then + have_shadow_adjunct=yes + have_shadow=yes + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for DEC and SCO so-called "enhanced" security. +# +############################################################################### + +if test "$with_shadow" = yes ; then + echo $ac_n "checking for DEC-style shadow passwords""... $ac_c" 1>&6 +echo "configure:5430: checking for DEC-style shadow passwords" >&5 +if eval "test \"`echo '$''{'ac_cv_enhanced_passwd'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < + #include + #include + #include + #include + #include +int main() { +struct pr_passwd *p; + const char *pw; + set_auth_parameters(0, 0); + check_auth_parameters(); + p = getprpwnam("nobody"); + pw = p->ufld.fd_encrypt; +; return 0; } +EOF +if { (eval echo configure:5458: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_enhanced_passwd=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_enhanced_passwd=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_enhanced_passwd" 1>&6 + if test $ac_cv_enhanced_passwd = yes; then + have_shadow_enhanced=yes + have_shadow=yes + need_setuid=yes + + # On SCO, getprpwnam() is in -lprot (which uses nap() from -lx) + # (I'm told it needs -lcurses too, but I don't understand why.) + # But on DEC, it's in -lsecurity. + # + echo $ac_n "checking for getprpwnam in -lprot""... $ac_c" 1>&6 +echo "configure:5482: checking for getprpwnam in -lprot" >&5 +ac_lib_var=`echo prot'_'getprpwnam | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lprot -lx $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + PASSWD_LIBS="$PASSWD_LIBS -lprot -lcurses -lx" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 +echo "configure:5520: checking for getprpwnam in -lsecurity" >&5 +ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsecurity $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + PASSWD_LIBS="$PASSWD_LIBS -lsecurity" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + fi +fi + +############################################################################### +# +# Check for HP's entry in the "Not Invented Here" Sweepstakes. +# +############################################################################### + +if test "$with_shadow" = yes ; then + echo $ac_n "checking for HP-style shadow passwords""... $ac_c" 1>&6 +echo "configure:5572: checking for HP-style shadow passwords" >&5 +if eval "test \"`echo '$''{'ac_cv_hpux_passwd'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < + #include + #include + #include + #include + #include +int main() { +struct s_passwd *p = getspwnam("nobody"); + const char *pw = p->pw_passwd; +; return 0; } +EOF +if { (eval echo configure:5596: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_hpux_passwd=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_hpux_passwd=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_hpux_passwd" 1>&6 + if test "$ac_cv_hpux_passwd" = yes; then + have_shadow_hpux=yes + have_shadow=yes + need_setuid=yes + + # on HPUX, bigcrypt is in -lsec + echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6 +echo "configure:5617: checking for bigcrypt in -lsec" >&5 +ac_lib_var=`echo sec'_'bigcrypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsec $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + PASSWD_LIBS="$PASSWD_LIBS -lsec" +else + echo "$ac_t""no" 1>&6 +fi + + fi +fi + + +############################################################################### +# +# Check for FreeBSD-style shadow passwords. +# +# On FreeBSD, getpwnam() and friends work just like on non-shadow- +# password systems -- except you only get stuff in the pw_passwd field +# if the running program is setuid. So, guess that we've got this +# lossage to contend with if /etc/master.passwd exists, and default to +# a setuid installation. +# +############################################################################### + +if test "$with_shadow" = yes ; then + echo $ac_n "checking for FreeBSD-style shadow passwords""... $ac_c" 1>&6 +echo "configure:5674: checking for FreeBSD-style shadow passwords" >&5 +if eval "test \"`echo '$''{'ac_cv_master_passwd'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -f /etc/master.passwd ; then + ac_cv_master_passwd=yes + else + ac_cv_master_passwd=no + fi +fi + +echo "$ac_t""$ac_cv_master_passwd" 1>&6 + if test "$ac_cv_master_passwd" = yes; then + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for traditional (ha!) shadow passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + echo $ac_n "checking for generic shadow passwords""... $ac_c" 1>&6 +echo "configure:5700: checking for generic shadow passwords" >&5 +if eval "test \"`echo '$''{'ac_cv_shadow'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < + #include + #include + #include + #include +int main() { +struct spwd *p = getspnam("nobody"); + const char *pw = p->sp_pwdp; +; return 0; } +EOF +if { (eval echo configure:5723: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_shadow=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_shadow=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_shadow" 1>&6 + if test "$ac_cv_shadow" = yes; then + have_shadow=yes + need_setuid=yes + + # On some systems (UnixWare 2.1), getspnam() is in -lgen instead of -lc. + have_getspnam=no + echo $ac_n "checking for getspnam in -lc""... $ac_c" 1>&6 +echo "configure:5744: checking for getspnam in -lc" >&5 +ac_lib_var=`echo c'_'getspnam | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_getspnam=yes +else + echo "$ac_t""no" 1>&6 +fi + + if test "$have_getspnam" = no ; then + echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6 +echo "configure:5785: checking for getspnam in -lgen" >&5 +ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgen $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_getspnam=yes; PASSWD_LIBS="$PASSWD_LIBS -lgen" +else + echo "$ac_t""no" 1>&6 +fi + + fi + fi +fi + + +############################################################################### +# +# Check for other libraries needed for non-shadow passwords. +# +############################################################################### + +if test "$enable_locking" = yes ; then + + # On some systems (UnixWare 2.1), crypt() is in -lcrypt instead of -lc. + have_crypt=no + echo $ac_n "checking for crypt in -lc""... $ac_c" 1>&6 +echo "configure:5840: checking for crypt in -lc" >&5 +ac_lib_var=`echo c'_'crypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_crypt=yes +else + echo "$ac_t""no" 1>&6 +fi + + if test "$have_crypt" = no ; then + echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 +echo "configure:5881: checking for crypt in -lcrypt" >&5 +ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrypt $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_crypt=yes; PASSWD_LIBS="$PASSWD_LIBS -lcrypt" +else + echo "$ac_t""no" 1>&6 +fi + + fi +fi + + +# Most of the above shadow mechanisms will have set need_setuid to yes, +# if they were found. But, on some systems, we need setuid even when +# using plain old vanilla passwords. +# +if test "$enable_locking" = yes ; then + case "$host" in + *-hpux* | *-aix* | *-netbsd* | *-freebsd* | *-openbsd* ) + need_setuid=yes + ;; + esac +fi + + +if test "$have_shadow_adjunct" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_ADJUNCT_PASSWD 1 +EOF + +elif test "$have_shadow_enhanced" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_ENHANCED_PASSWD 1 +EOF + +elif test "$have_shadow_hpux" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_HPUX_PASSWD 1 +EOF + +elif test "$have_shadow" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_SHADOW_PASSWD 1 +EOF + +fi + + +############################################################################### +# +# Check for -lXm. +# +############################################################################### + +have_motif=no +with_motif_req=unspecified +# Check whether --with-motif or --without-motif was given. +if test "${with_motif+set}" = set; then + withval="$with_motif" + with_motif="$withval"; with_motif_req="$withval" +else + with_motif=yes +fi + + + + case "$with_motif" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for Motif headers""... $ac_c" 1>&6 +echo "configure:5984: checking for Motif headers" >&5 + d=$with_motif/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for Motif libs""... $ac_c" 1>&6 +echo "configure:5994: checking for Motif libs" >&5 + d=$with_motif/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_motif_req="yes" + with_motif=$with_motif_req + ;; + + *) + echo "" + echo "error: argument to --with-motif must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_motif" != yes -a "$with_motif" != no ; then + echo "error: must be yes or no: --with-motif=$with_motif" + exit 1 +fi + +if test "$with_motif" = yes; then + have_motif=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "Xm/Xm.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for Xm/Xm.h""... $ac_c" 1>&6 +echo "configure:6033: checking for Xm/Xm.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6043: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_motif=yes + cat >> confdefs.h <<\EOF +#define HAVE_MOTIF 1 +EOF + + MOTIF_LIBS="$MOTIF_LIBS -lXm" +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +fi + + +############################################################################### +# +# Check for -lgtk. +# +############################################################################### + +have_gtk=no +with_gtk_req=unspecified +# Check whether --with-gtk or --without-gtk was given. +if test "${with_gtk+set}" = set; then + withval="$with_gtk" + with_gtk="$withval"; with_gtk_req="$withval" +else + with_gtk=yes +fi + + +# if --with-gtk=/directory/ was specified, remember that directory so that +# we can also look for the `gtk-config' program in that directory. +case "$with_gtk" in + /*) + gtk_dir="$with_gtk" + ;; + *) + gtk_dir="" + ;; +esac + + + case "$with_gtk" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for Gtk headers""... $ac_c" 1>&6 +echo "configure:6108: checking for Gtk headers" >&5 + d=$with_gtk/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for Gtk libs""... $ac_c" 1>&6 +echo "configure:6118: checking for Gtk libs" >&5 + d=$with_gtk/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_gtk_req="yes" + with_gtk=$with_gtk_req + ;; + + *) + echo "" + echo "error: argument to --with-gtk must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_gtk" != yes -a "$with_gtk" != no ; then + echo "error: must be yes or no: --with-gtk=$with_gtk" + exit 1 +fi + +jurassic_gtk=no +if test "$with_gtk" = yes; then + have_gtk=no + + # if the user specified --with-gtk=/foo/ then look in /foo/bin/ + # for glib-config and gtk-config. + # + gtk_path="$PATH" + + if test ! -z "$gtk_dir"; then + # canonicalize slashes. + gtk_dir=`echo "${gtk_dir}/bin" | sed 's@//*@/@g'` + gtk_path="$gtk_dir:$gtk_dir:$gtk_path" + fi + + for ac_prog in glib-config +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6167: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_glib_config'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$glib_config" in + /*) + ac_cv_path_glib_config="$glib_config" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_glib_config="$glib_config" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$gtk_path" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_glib_config="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +glib_config="$ac_cv_path_glib_config" +if test -n "$glib_config"; then + echo "$ac_t""$glib_config" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$glib_config" && break +done + + for ac_prog in gtk-config +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6207: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_gtk_config'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$gtk_config" in + /*) + ac_cv_path_gtk_config="$gtk_config" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_gtk_config="$gtk_config" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$gtk_path" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_gtk_config="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +gtk_config="$ac_cv_path_gtk_config" +if test -n "$gtk_config"; then + echo "$ac_t""$gtk_config" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$gtk_config" && break +done + + + if test -n "$glib_config" -a -n "gtk_config" ; then + have_gtk=yes + fi + if test "$have_gtk" = yes; then + echo $ac_n "checking Gtk version number""... $ac_c" 1>&6 +echo "configure:6248: checking Gtk version number" >&5 +if eval "test \"`echo '$''{'ac_cv_gtk_version_string'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_gtk_version_string=`$glib_config --version` +fi + +echo "$ac_t""$ac_cv_gtk_version_string" 1>&6 + ac_gtk_version_string=$ac_cv_gtk_version_string + # M4 sucks!! + + maj=`echo $ac_gtk_version_string | sed -n 's/\..*//p'` + min=`echo $ac_gtk_version_string | sed -n 's/[^.]*\.\([^.]*\).*/\1/p'` + + ac_gtk_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_gtk_version"; then + ac_gtk_version=unknown + ac_gtk_version_string=unknown + fi + if test "$ac_gtk_version" = "unknown" || test "$ac_gtk_version" -lt 1002 + then + have_gtk=no + jurassic_gtk=yes + fi + fi + if test "$have_gtk" = yes; then + echo $ac_n "checking for Gtk includes""... $ac_c" 1>&6 +echo "configure:6275: checking for Gtk includes" >&5 +if eval "test \"`echo '$''{'ac_cv_gtk_config_cflags'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_gtk_config_cflags=`$gtk_config --cflags` +fi + +echo "$ac_t""$ac_cv_gtk_config_cflags" 1>&6 + echo $ac_n "checking for Gtk libs""... $ac_c" 1>&6 +echo "configure:6284: checking for Gtk libs" >&5 +if eval "test \"`echo '$''{'ac_cv_gtk_config_libs'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_gtk_config_libs=`$gtk_config --libs` +fi + +echo "$ac_t""$ac_cv_gtk_config_libs" 1>&6 + INCLUDES="$INCLUDES $ac_cv_gtk_config_cflags" + GTK_LIBS="$GTK_LIBS $ac_cv_gtk_config_libs" + cat >> confdefs.h <<\EOF +#define HAVE_GTK 1 +EOF + + fi +fi + + +############################################################################### +# +# Check for -lXaw and -lXaw3d. +# +############################################################################### + +have_athena=no +have_athena3d=no +with_athena_req=unspecified +# Check whether --with-athena or --without-athena was given. +if test "${with_athena+set}" = set; then + withval="$with_athena" + with_athena="$withval"; with_athena_req="$withval" +else + with_athena=yes +fi + + + + case "$with_athena" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for Athena headers""... $ac_c" 1>&6 +echo "configure:6327: checking for Athena headers" >&5 + d=$with_athena/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for Athena libs""... $ac_c" 1>&6 +echo "configure:6337: checking for Athena libs" >&5 + d=$with_athena/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_athena_req="yes" + with_athena=$with_athena_req + ;; + + *) + echo "" + echo "error: argument to --with-athena must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + + +if test "$with_athena" != yes -a "$with_athena" != no ; then + echo "error: must be yes or no: --with-athena=$with_athena" + exit 1 +fi + + +if test "$with_athena" = yes; then + have_athena=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/Xaw/Dialog.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/Xaw/Dialog.h""... $ac_c" 1>&6 +echo "configure:6378: checking for X11/Xaw/Dialog.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6388: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_athena=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_athena" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for Xaw3dComputeTopShadowRGB in -lXaw3d""... $ac_c" 1>&6 +echo "configure:6429: checking for Xaw3dComputeTopShadowRGB in -lXaw3d" >&5 +ac_lib_var=`echo Xaw3d'_'Xaw3dComputeTopShadowRGB | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXaw3d -lXt -lXmu -lXext -lX11 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_athena=yes; have_athena3d=yes +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi +fi + +if test "$have_athena" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ATHENA 1 +EOF + + ATHENA_LIBS="-lXaw $ATHENA_LIBS" +fi + +if test "$have_athena3d" = yes; then + ATHENA3D_LIBS="-lXaw3d $ATHENA3D_LIBS" +fi + + +# If we have Athena, check whether it's a version that includes +# XawViewportSetCoordinates in Viewport.h (R3 (or R4?) don't.) +if test "$have_athena" = yes ; then + echo $ac_n "checking for XawViewportSetCoordinates in Viewport.h""... $ac_c" 1>&6 +echo "configure:6493: checking for XawViewportSetCoordinates in Viewport.h" >&5 +if eval "test \"`echo '$''{'ac_cv_have_XawViewportSetCoordinates'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_have_XawViewportSetCoordinates=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "XawViewportSetCoordinates" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_have_XawViewportSetCoordinates=yes +fi +rm -f conftest* + + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_have_XawViewportSetCoordinates" 1>&6 + if test "$ac_cv_have_XawViewportSetCoordinates" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_XawViewportSetCoordinates 1 +EOF + + fi +fi + + +############################################################################### +# +# Checking whether Motif is really Lesstif. +# +############################################################################### + +have_lesstif=no +if test "$have_motif" = yes ; then + echo $ac_n "checking whether Motif is really LessTif""... $ac_c" 1>&6 +echo "configure:6538: checking whether Motif is really LessTif" >&5 +if eval "test \"`echo '$''{'ac_cv_have_lesstif'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < +int main() { +long vers = LesstifVersion; +; return 0; } +EOF +if { (eval echo configure:6556: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_lesstif=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_lesstif=no +fi +rm -f conftest* + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_have_lesstif" 1>&6 + have_lesstif=$ac_cv_have_lesstif +fi + + +lesstif_version=unknown +lesstif_version_string=unknown + +if test "$have_lesstif" = yes ; then + ltv=unknown + echo unknown > conftest-lt + echo $ac_n "checking LessTif version number""... $ac_c" 1>&6 +echo "configure:6581: checking LessTif version number" >&5 +if eval "test \"`echo '$''{'ac_cv_lesstif_version_string'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + if test "$cross_compiling" = yes; then + ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown +else + cat > conftest.$ac_ext < + #include + int main() { + FILE *f = fopen("conftest-lt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", LesstifVersion, + LESSTIF_VERSION, LESSTIF_REVISION); + fclose(f); + exit(0); + } +EOF +if { (eval echo configure:6609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ltv=`cat conftest-lt` + ac_cv_lesstif_version=`echo $ltv | sed 's/ .*//'` + ac_cv_lesstif_version_string=`echo $ltv | sed 's/.* //'` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown +fi +rm -fr conftest* +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_lesstif_version_string" 1>&6 + rm -f conftest-lt + lesstif_version=$ac_cv_lesstif_version + lesstif_version_string=$ac_cv_lesstif_version_string + +fi + + +if test "$have_motif" = yes ; then + mtv=unknown + echo unknown > conftest-mt + echo $ac_n "checking Motif version number""... $ac_c" 1>&6 +echo "configure:6639: checking Motif version number" >&5 +if eval "test \"`echo '$''{'ac_cv_motif_version_string'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + if test "$cross_compiling" = yes; then + ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown +else + cat > conftest.$ac_ext < + #include + int main() { + FILE *f = fopen("conftest-mt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", XmVersion, + XmVERSION, XmREVISION); + fclose(f); + exit(0); + } +EOF +if { (eval echo configure:6667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + mtv=`cat conftest-mt` + ac_cv_motif_version=`echo $mtv | sed 's/ .*//'` + ac_cv_motif_version_string=`echo $mtv | sed 's/.* //'` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown +fi +rm -fr conftest* +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +fi + +echo "$ac_t""$ac_cv_motif_version_string" 1>&6 + rm -f conftest-mt + motif_version=$ac_cv_motif_version + motif_version_string=$ac_cv_motif_version_string + +fi + + +############################################################################### +# +# Checking whether Motif requires -lXpm. +# +# If this is Motif 2.x, and we have XPM, then link against XPM as well. +# The deal is, Motif 2.x requires XPM -- but it's a compilation option +# of the library whether to build the XPM code into libXm, or whether +# to rely on an external libXm. So the only way to tell whether XPM is +# a link-time requirement is to examine libXm.a, which is very +# difficult to do in an autoconf script. So... if it's Motif 2.x, we +# always link against XPM if the XPM lib exists (and this will be a +# no-op if libXm happens to already have the XPM code in it.) +# +############################################################################### + +motif_requires_xpm=no +if test "$have_motif" = yes ; then + echo $ac_n "checking whether Motif requires XPM""... $ac_c" 1>&6 +echo "configure:6711: checking whether Motif requires XPM" >&5 + if test "$motif_version" = "unknown" || test "$motif_version" -ge 2000 + then + motif_requires_xpm=yes + echo "$ac_t""maybe" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi +fi + + +############################################################################### +# +# Checking whether Motif requires -lXp. +# +# Some versions of Motif (2.1.0, at least) require -lXp, the "X Printing +# Extension". Why this extension isn't in -lXext with all the others, +# I have no idea. +# +############################################################################### + +have_xp_ext=no +if test "$have_motif" = yes ; then + have_xp_ext=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for XpQueryExtension in -lXp""... $ac_c" 1>&6 +echo "configure:6753: checking for XpQueryExtension in -lXp" >&5 +ac_lib_var=`echo Xp'_'XpQueryExtension | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXp -lX11 -lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xp_ext=yes; MOTIF_LIBS="$MOTIF_LIBS -lXp" +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + +fi + + +############################################################################### +# +# Checking whether Motif requires -lXintl (for _Xsetlocale.) +# +############################################################################### + +have_xintl=no +if test "$have_motif" = yes ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for _Xsetlocale in -lXintl""... $ac_c" 1>&6 +echo "configure:6826: checking for _Xsetlocale in -lXintl" >&5 +ac_lib_var=`echo Xintl'_'_Xsetlocale | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXintl -lX11 -lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xintl=yes +else + echo "$ac_t""no" 1>&6 +have_xintl=no +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + if test "$have_xintl" = yes; then + MOTIF_LIBS="$MOTIF_LIBS -lXintl" + fi +fi + + +############################################################################### +# +# Check for -lGL or -lMesa. +# +############################################################################### + +have_gl=no +ac_have_mesa_gl=no +with_gl_req=unspecified +# Check whether --with-gl or --without-gl was given. +if test "${with_gl+set}" = set; then + withval="$with_gl" + with_gl="$withval"; with_gl_req="$withval" +else + with_gl=yes +fi + + + + case "$with_gl" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for GL headers""... $ac_c" 1>&6 +echo "configure:6901: checking for GL headers" >&5 + d=$with_gl/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for GL libs""... $ac_c" 1>&6 +echo "configure:6911: checking for GL libs" >&5 + d=$with_gl/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_gl_req="yes" + with_gl=$with_gl_req + ;; + + *) + echo "" + echo "error: argument to --with-gl must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +ac_mesagl_version=unknown +ac_mesagl_version_string=unknown + +if test "$with_gl" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "GL/gl.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for GL/gl.h""... $ac_c" 1>&6 +echo "configure:6947: checking for GL/gl.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6957: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_gl=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_gl" = yes ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "GL/glx.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for GL/glx.h""... $ac_c" 1>&6 +echo "configure:6988: checking for GL/glx.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6998: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_gl=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + + # If we have the headers, try and figure out which vendor it's from. + # + if test "$have_gl" = yes ; then + + cat >> confdefs.h <<\EOF +#define HAVE_GL 1 +EOF + + + # We need to know whether it's MesaGL so that we know which libraries + # to link against. + # + echo $ac_n "checking whether GL is really MesaGL""... $ac_c" 1>&6 +echo "configure:7035: checking whether GL is really MesaGL" >&5 +if eval "test \"`echo '$''{'ac_cv_have_mesa_gl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_have_mesa_gl=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "Mesa" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_have_mesa_gl=yes +fi +rm -f conftest* + + CPPFLAGS="$ac_save_CPPFLAGS" + +fi + +echo "$ac_t""$ac_cv_have_mesa_gl" 1>&6 + ac_have_mesa_gl=$ac_cv_have_mesa_gl + + if test "$ac_have_mesa_gl" = no ; then + gl_lib_1="GL" + GL_LIBS="-lGL -lGLU" + else + cat >> confdefs.h <<\EOF +#define HAVE_MESA_GL 1 +EOF + + gl_lib_1="MesaGL" + GL_LIBS="-lMesaGL -lMesaGLU" + fi + + + # If it's MesaGL, we'd like to issue a warning if the version number + # is less than or equal to 2.6, because that version had a security bug. + # + if test "$ac_have_mesa_gl" = yes; then + + echo $ac_n "checking MesaGL version number""... $ac_c" 1>&6 +echo "configure:7084: checking MesaGL version number" >&5 +if eval "test \"`echo '$''{'ac_cv_mesagl_version_string'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +configure: MESA_MAJOR_VERSION MESA_MINOR_VERSION +EOF + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + # M4 sucks!! + + mglv=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | sed -n \ + 's/^configure:.*\([0-9][0-9]*\).*\([0-9][0-9]*\).*$/\1.\2/p'` + + + rm -f conftest.$ac_ext + + CPPFLAGS="$ac_save_CPPFLAGS" + + if test "$mglv" = ""; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + else + ac_mesagl_version_string=$mglv + maj=`echo $mglv | sed -n 's/\..*//p'` + min=`echo $mglv | sed -n 's/.*\.//p'` + ac_mesagl_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_mesagl_version"; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + fi + fi + ac_cv_mesagl_version=$ac_mesagl_version + ac_cv_mesagl_version_string=$ac_mesagl_version_string + +fi + +echo "$ac_t""$ac_cv_mesagl_version_string" 1>&6 + ac_mesagl_version=$ac_cv_mesagl_version + ac_mesagl_version_string=$ac_cv_mesagl_version_string + fi + + + # If it's MesaGL, check to see if it requires -lpthread. + # + have_pthread=no + mesa_requires_pthread=no + if test "$ac_have_mesa_gl" = yes; then + + echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 +echo "configure:7142: checking for pthread_create in -lpthread" >&5 +ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpthread $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_pthread=yes +else + echo "$ac_t""no" 1>&6 +fi + + if test "$have_pthread" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for gl_get_thread_context in -l$gl_lib_1""... $ac_c" 1>&6 +echo "configure:7200: checking for gl_get_thread_context in -l$gl_lib_1" >&5 +ac_lib_var=`echo $gl_lib_1'_'gl_get_thread_context | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-l$gl_lib_1 $GL_LIBS -lpthread -lX11 -lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + mesa_requires_pthread=yes +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + if test "$mesa_requires_pthread" = yes; then + GL_LIBS="$GL_LIBS -lpthread" + fi + fi + + # Check for OpenGL 1.1 features. + # + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for glBindTexture in -l$gl_lib_1""... $ac_c" 1>&6 +echo "configure:7271: checking for glBindTexture in -l$gl_lib_1" >&5 +ac_lib_var=`echo $gl_lib_1'_'glBindTexture | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-l$gl_lib_1 $GL_LIBS -lX11 -lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GLBINDTEXTURE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + + # Check whether the `xscreensaver' executable should link against GL. + # See comments in utils/visual-gl.c for why this is sometimes necessary. + # + echo $ac_n "checking whether drastic GL measures must be taken""... $ac_c" 1>&6 +echo "configure:7324: checking whether drastic GL measures must be taken" >&5 + case "$host" in + *-sgi*) + echo "$ac_t""yes -- hello, SGI." 1>&6 + cat >> confdefs.h <<\EOF +#define DAEMON_USE_GL 1 +EOF + + SAVER_GL_SRCS='$(UTILS_SRC)/visual-gl.c' + SAVER_GL_OBJS='$(UTILS_BIN)/visual-gl.o' + SAVER_GL_LIBS="$GL_LIBS" + ;; + *) + echo "$ac_t""no -- non-SGI." 1>&6 + SAVER_GL_SRCS='' + SAVER_GL_OBJS='' + SAVER_GL_LIBS='' + ;; + esac + + fi + +elif test "$with_gl" != no; then + echo "error: must be yes or no: --with-gl=$with_gl" + exit 1 +fi + + +############################################################################### +# +# Check for -lXpm. +# +############################################################################### + +have_xpm=no +with_xpm_req=unspecified +# Check whether --with-xpm or --without-xpm was given. +if test "${with_xpm+set}" = set; then + withval="$with_xpm" + with_xpm="$withval"; with_xpm_req="$withval" +else + with_xpm=yes +fi + + + + case "$with_xpm" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for XPM headers""... $ac_c" 1>&6 +echo "configure:7376: checking for XPM headers" >&5 + d=$with_xpm/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for XPM libs""... $ac_c" 1>&6 +echo "configure:7386: checking for XPM libs" >&5 + d=$with_xpm/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_xpm_req="yes" + with_xpm=$with_xpm_req + ;; + + *) + echo "" + echo "error: argument to --with-xpm must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xpm" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/xpm.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/xpm.h""... $ac_c" 1>&6 +echo "configure:7419: checking for X11/xpm.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7429: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xpm=yes + cat >> confdefs.h <<\EOF +#define HAVE_XPM 1 +EOF + + XPM_LIBS="-lXpm" +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +elif test "$with_xpm" != no; then + echo "error: must be yes or no: --with-xpm=$with_xpm" + exit 1 +fi + +# See comment near $motif_requires_xpm, above. +# Need to do this here, after both Motif and XPM have been checked for. +# +if test "$have_motif" = yes -a "$have_xpm" = yes ; then + if test "$motif_requires_xpm" = yes ; then + MOTIF_LIBS="$MOTIF_LIBS $XPM_LIBS" + fi +fi + + +############################################################################### +# +# Check for the XSHM server extension. +# +############################################################################### + +have_xshm=no +with_xshm_req=unspecified +# Check whether --with-xshm-ext or --without-xshm-ext was given. +if test "${with_xshm_ext+set}" = set; then + withval="$with_xshm_ext" + with_xshm="$withval"; with_xshm_req="$withval" +else + with_xshm=yes +fi + + + + case "$with_xshm" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for XSHM headers""... $ac_c" 1>&6 +echo "configure:7495: checking for XSHM headers" >&5 + d=$with_xshm/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for XSHM libs""... $ac_c" 1>&6 +echo "configure:7505: checking for XSHM libs" >&5 + d=$with_xshm/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_xshm_req="yes" + with_xshm=$with_xshm_req + ;; + + *) + echo "" + echo "error: argument to --with-xshm-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xshm" = yes; then + + # first check for Xshm.h. + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/XShm.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/XShm.h""... $ac_c" 1>&6 +echo "configure:7540: checking for X11/extensions/XShm.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7550: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xshm=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for sys/ipc.h. + if test "$have_xshm" = yes; then + have_xshm=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "sys/ipc.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for sys/ipc.h""... $ac_c" 1>&6 +echo "configure:7584: checking for sys/ipc.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7594: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xshm=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + + # if that succeeded, then check for sys/shm.h. + if test "$have_xshm" = yes; then + have_xshm=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "sys/shm.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for sys/shm.h""... $ac_c" 1>&6 +echo "configure:7629: checking for sys/shm.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7639: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xshm=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + 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. (This lib gets added to X_EXTRA_LIBS, and + # that's not quite right, but close enough.) + # + case "$host" in + *-aix*) + have_xshm=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + echo $ac_n "checking for XShmQueryExtension in -lXextSam""... $ac_c" 1>&6 +echo "configure:7690: checking for XShmQueryExtension in -lXextSam" >&5 +ac_lib_var=`echo XextSam'_'XShmQueryExtension | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lXextSam -lX11 -lXext -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xshm=yes; X_EXTRA_LIBS="$X_EXTRA_LIBS -lXextSam" +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + ;; + esac + + # if that succeeded, then we've really got it. + if test "$have_xshm" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_XSHM_EXTENSION 1 +EOF + + fi + +elif test "$with_xshm" != no; then + echo "error: must be yes or no: --with-xshm-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the DOUBLE-BUFFER server extension. +# +############################################################################### + +have_xdbe=no +with_xdbe_req=unspecified +# Check whether --with-xdbe-ext or --without-xdbe-ext was given. +if test "${with_xdbe_ext+set}" = set; then + withval="$with_xdbe_ext" + with_xdbe="$withval"; with_xdbe_req="$withval" +else + with_xdbe=yes +fi + + + + case "$with_xdbe" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for DOUBLE-BUFFER headers""... $ac_c" 1>&6 +echo "configure:7775: checking for DOUBLE-BUFFER headers" >&5 + d=$with_xdbe/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for DOUBLE-BUFFER libs""... $ac_c" 1>&6 +echo "configure:7785: checking for DOUBLE-BUFFER libs" >&5 + d=$with_xdbe/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_xdbe_req="yes" + with_xdbe=$with_xdbe_req + ;; + + *) + echo "" + echo "error: argument to --with-xdbe-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xdbe" = yes; then + + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/Xdbe.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/Xdbe.h""... $ac_c" 1>&6 +echo "configure:7819: checking for X11/extensions/Xdbe.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7829: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_xdbe=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_xdbe" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_DOUBLE_BUFFER_EXTENSION 1 +EOF + + fi + +elif test "$with_xdbe" != no; then + echo "error: must be yes or no: --with-xdbe-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI XReadDisplay server extension. +# +# Note: this has to be down here, rather than up with the other server +# extension tests, so that the output of `configure --help' is in the +# right order. Arrgh! +# +############################################################################### + +have_readdisplay=no +with_readdisplay_req=unspecified +# Check whether --with-readdisplay or --without-readdisplay was given. +if test "${with_readdisplay+set}" = set; then + withval="$with_readdisplay" + with_readdisplay="$withval"; with_readdisplay_req="$withval" +else + with_readdisplay=yes +fi + + + + case "$with_readdisplay" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for XReadDisplay headers""... $ac_c" 1>&6 +echo "configure:7892: checking for XReadDisplay headers" >&5 + d=$with_readdisplay/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for XReadDisplay libs""... $ac_c" 1>&6 +echo "configure:7902: checking for XReadDisplay libs" >&5 + d=$with_readdisplay/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_readdisplay_req="yes" + with_readdisplay=$with_readdisplay_req + ;; + + *) + echo "" + echo "error: argument to --with-readdisplay must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_readdisplay" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "X11/extensions/readdisplay.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for X11/extensions/readdisplay.h""... $ac_c" 1>&6 +echo "configure:7935: checking for X11/extensions/readdisplay.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7945: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_READ_DISPLAY_EXTENSION 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +elif test "$with_readdisplay" != no; then + echo "error: must be yes or no: --with-readdisplay=$with_readdisplay" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI Iris Video Library. +# +############################################################################### + +have_sgivideo=no +with_sgivideo_req=unspecified +# Check whether --with-sgivideo or --without-sgivideo was given. +if test "${with_sgivideo+set}" = set; then + withval="$with_sgivideo" + with_sgivideo="$withval"; with_sgivideo_req="$withval" +else + with_sgivideo=yes +fi + + + + case "$with_sgivideo" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for Iris Video headers""... $ac_c" 1>&6 +echo "configure:8000: checking for Iris Video headers" >&5 + d=$with_sgivideo/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for Iris Video libs""... $ac_c" 1>&6 +echo "configure:8010: checking for Iris Video libs" >&5 + d=$with_sgivideo/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_sgivideo_req="yes" + with_sgivideo=$with_sgivideo_req + ;; + + *) + echo "" + echo "error: argument to --with-sgivideo must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_sgivideo" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "dmedia/vl.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for dmedia/vl.h""... $ac_c" 1>&6 +echo "configure:8043: checking for dmedia/vl.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:8053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_sgivideo=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_sgivideo" = yes; then + have_sgivideo=no + echo $ac_n "checking for vlOpenVideo in -lvl""... $ac_c" 1>&6 +echo "configure:8078: checking for vlOpenVideo in -lvl" >&5 +ac_lib_var=`echo vl'_'vlOpenVideo | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lvl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_sgivideo=yes +else + echo "$ac_t""no" 1>&6 +fi + + if test "$have_sgivideo" = yes; then + SGI_VIDEO_OBJS="$(UTILS_BIN)/sgivideo.o" + SGI_VIDEO_LIBS="-lvl" + cat >> confdefs.h <<\EOF +#define HAVE_SGI_VIDEO 1 +EOF + + fi + fi +elif test "$with_sgivideo" != no; then + echo "error: must be yes or no: --with-sgivideo=$with_sgivideo" + exit 1 +fi + + +############################################################################### +# +# Check for a program to generate random text. +# +# Zippy is funnier than the idiocy generally spat out by `fortune', +# so try to find that, by invoking Emacs and asking it where its +# libexec directory is ("yow" lives in there.) +# +# If that doesn't work, see if fortune, zippy, or yow are on $PATH, +# and if so, use them. +# +# If that doesn't work, look in /usr/games, and if it's there, use +# the full pathname. +# +############################################################################### + +with_zippy_req="" +# Check whether --with-zippy or --without-zippy was given. +if test "${with_zippy+set}" = set; then + withval="$with_zippy" + with_zippy_req="$withval"; with_zippy="$withval" +else + with_zippy=yes +fi + + +if test "$with_zippy" = no || test "$with_zippy" = yes ; then + with_zippy="" + with_zippy_req="" +fi + +if test -n "$with_zippy_req" ; then + ac_cv_zippy_program="" + case "$with_zippy_req" in + /*) + echo $ac_n "checking for $with_zippy_req""... $ac_c" 1>&6 +echo "configure:8168: checking for $with_zippy_req" >&5 + if test -x "$with_zippy_req" ; then + echo "$ac_t""yes" 1>&6 + else + echo "$ac_t""no" 1>&6 + with_zippy="" + fi + ;; + *) + # don't cache + unset ac_cv_path_zip2 + # Extract the first word of "$with_zippy_req", so it can be a program name with args. +set dummy $with_zippy_req; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:8182: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_zip2'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$zip2" in + /*) + ac_cv_path_zip2="$zip2" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_zip2="$zip2" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_zip2="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +zip2="$ac_cv_path_zip2" +if test -n "$zip2"; then + echo "$ac_t""$zip2" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test "$zip2" = ""; then + with_zippy="" + fi + ;; + esac + ac_cv_zippy_program="$with_zippy" + +elif test -n "$ac_cv_zippy_program"; then + echo "$ac_t""checking for zippy... (cached) $ac_cv_zippy_program" 1>&6 +fi + +if test ! -n "$ac_cv_zippy_program"; then + + for ac_prog in emacs +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:8232: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_emacs_exe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$emacs_exe"; then + ac_cv_prog_emacs_exe="$emacs_exe" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_emacs_exe="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +emacs_exe="$ac_cv_prog_emacs_exe" +if test -n "$emacs_exe"; then + echo "$ac_t""$emacs_exe" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$emacs_exe" && break +done + + for ac_prog in xemacs +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:8266: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_xemacs_exe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$xemacs_exe"; then + ac_cv_prog_xemacs_exe="$xemacs_exe" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_xemacs_exe="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +xemacs_exe="$ac_cv_prog_xemacs_exe" +if test -n "$xemacs_exe"; then + echo "$ac_t""$xemacs_exe" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$xemacs_exe" && break +done + + + ac_cv_zippy_program="" + eargs='-batch -q -nw --eval' + + if test -n "$emacs_exe" ; then + echo $ac_n "checking for emacs yow""... $ac_c" 1>&6 +echo "configure:8301: checking for emacs yow" >&5 + # + # get emacs to tell us where the libexec directory is. + # + dir=`$emacs_exe $eargs '(princ (concat exec-directory "\n"))' \ + 2>/dev/null | tail -1` + dir=`echo "$dir" | sed 's@///*@/@g;s@/$@@'` + # + # try running libexec/yow and see if it exits without error. + # + if test x"$dir" != x -a -x "$dir/yow" ; then + if $dir/yow >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow" + echo "$ac_t""$ac_cv_zippy_program" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi + fi + fi + + if test -z "$ac_cv_zippy_program" ; then + echo $ac_n "checking for xemacs yow""... $ac_c" 1>&6 +echo "configure:8323: checking for xemacs yow" >&5 + if test -n "$xemacs_exe" ; then + # + # get xemacs to tell us where the libexec directory is. + # + dir=`$xemacs_exe $eargs '(princ (concat exec-directory "\n"))' \ + 2>/dev/null | tail -1` + dir=`echo "$dir" | sed 's@///*@/@g;s@/$@@'` + # + # try running libexec/yow and see if it exits without error. + # + if test x"$dir" != x -a -x "$dir/yow" ; then + if $dir/yow >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow" + echo "$ac_t""$ac_cv_zippy_program" 1>&6 + else + # + # in some xemacs installations, the pathname of the yow.lines file + # isn't hardcoded into the yow executable, and must be passed on + # the command line. See if it's in libexec/../etc/. + + # M4 sucks!! + + dir_up=`echo "$dir" | sed 's@/[^/]*$@@'` + + + yowlines="$dir_up/etc/yow.lines" + if $dir/yow -f $yowlines >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow -f $yowlines" + echo "$ac_t""$ac_cv_zippy_program" 1>&6 + else + # + # In newer XEmacs releases, yow.lines is in a different place, + # and the easiest way to get it is by calling the new function + # `locate-data-file'. + # + yowlines=`$xemacs_exe $eargs \ + '(princ (concat (locate-data-file "yow.lines") "\n"))' \ + 2>/dev/null | tail -1` + if $dir/yow -f $yowlines >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow -f $yowlines" + echo "$ac_t""$ac_cv_zippy_program" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi + fi + fi + fi + fi + fi + + # if that didn't work, try for some other programs... + if test -z "$ac_cv_zippy_program" ; then + fortune='' + for ac_prog in fortune zippy yow +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:8382: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_fortune'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$fortune"; then + ac_cv_prog_fortune="$fortune" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_fortune="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +fortune="$ac_cv_prog_fortune" +if test -n "$fortune"; then + echo "$ac_t""$fortune" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$fortune" && break +done + + # if that didn't work, try for those programs in /usr/games... + if test -z "$fortune" ; then + for ac_prog in fortune zippy yow +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:8418: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_fortune'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$fortune" in + /*) + ac_cv_path_fortune="$fortune" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_fortune="$fortune" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/games:/usr/local/games:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_fortune="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +fortune="$ac_cv_path_fortune" +if test -n "$fortune"; then + echo "$ac_t""$fortune" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$fortune" && break +done +test -n "$fortune" || fortune="fortune" + + fi + fi +fi + +if test -z "$ac_cv_zippy_program" ; then + ac_cv_zippy_program=fortune +fi + +cat >> confdefs.h < confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile + utils/Makefile + driver/Makefile + hacks/Makefile + hacks/glx/Makefile + driver/XScreenSaver.ad config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@SET_MAKE@%$SET_MAKE%g +s%@PERL@%$PERL%g +s%@X_CFLAGS@%$X_CFLAGS%g +s%@X_PRE_LIBS@%$X_PRE_LIBS%g +s%@X_LIBS@%$X_LIBS%g +s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g +s%@glib_config@%$glib_config%g +s%@gtk_config@%$gtk_config%g +s%@zip2@%$zip2%g +s%@emacs_exe@%$emacs_exe%g +s%@xemacs_exe@%$xemacs_exe%g +s%@fortune@%$fortune%g +s%@INCLUDES@%$INCLUDES%g +s%@PREFERRED_DEMO_PROGRAM@%$PREFERRED_DEMO_PROGRAM%g +s%@ALL_DEMO_PROGRAMS@%$ALL_DEMO_PROGRAMS%g +s%@SAVER_LIBS@%$SAVER_LIBS%g +s%@MOTIF_LIBS@%$MOTIF_LIBS%g +s%@GTK_LIBS@%$GTK_LIBS%g +s%@ATHENA_LIBS@%$ATHENA_LIBS%g +s%@ATHENA3D_LIBS@%$ATHENA3D_LIBS%g +s%@HACK_LIBS@%$HACK_LIBS%g +s%@XPM_LIBS@%$XPM_LIBS%g +s%@GL_LIBS@%$GL_LIBS%g +s%@PASSWD_LIBS@%$PASSWD_LIBS%g +s%@INSTALL_SETUID@%$INSTALL_SETUID%g +s%@INSTALL_DIRS@%$INSTALL_DIRS%g +s%@NEED_SETUID@%$NEED_SETUID%g +s%@INSTALL_PAM@%$INSTALL_PAM%g +s%@SGI_VIDEO_OBJS@%$SGI_VIDEO_OBJS%g +s%@SGI_VIDEO_LIBS@%$SGI_VIDEO_LIBS%g +s%@PASSWD_SRCS@%$PASSWD_SRCS%g +s%@PASSWD_OBJS@%$PASSWD_OBJS%g +s%@XMU_SRCS@%$XMU_SRCS%g +s%@XMU_OBJS@%$XMU_OBJS%g +s%@SAVER_GL_SRCS@%$SAVER_GL_SRCS%g +s%@SAVER_GL_OBJS@%$SAVER_GL_OBJS%g +s%@SAVER_GL_LIBS@%$SAVER_GL_LIBS%g +s%@LOCK_SRCS@%$LOCK_SRCS%g +s%@LOCK_OBJS@%$LOCK_OBJS%g +s%@GL_EXES@%$GL_EXES%g +s%@GL_MEN@%$GL_MEN%g +s%@GL_KLUDGE@%$GL_KLUDGE%g +s%@HACKDIR@%$HACKDIR%g +s%@APPDEFAULTS@%$APPDEFAULTS%g +s%@DEPEND@%$DEPEND%g +s%@DEPEND_FLAGS@%$DEPEND_FLAGS%g +s%@DEPEND_DEFINES@%$DEPEND_DEFINES%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + +############################################################################### +# +# Print some warnings at the end. +# +############################################################################### + +warn_prefix_1=" Warning:" +warn_prefix_2=" Note:" +warn_prefix="$warn_prefix_1" + +warning=no +warnsep=' #################################################################' + +warnpre() { + if test "$warning" = no ; then + echo '' ; echo "$warnsep" ; echo '' + warning=yes + fi +} + +warn() { + warnpre + if test "$warning" = long ; then echo '' ; fi + warning=yes + echo "$warn_prefix $@" +} + +warnL() { + was=$warning + warnpre + warning=yes + if test "$was" != no ; then echo '' ; fi + echo "$warn_prefix $@" +} + +warn2() { + echo " $@" + warning=long +} + +note() { + warn_prefix="$warn_prefix_2" + warn $@ + warn_prefix="$warn_prefix_1" +} + +noteL() { + warn_prefix="$warn_prefix_2" + warnL $@ + warn_prefix="$warn_prefix_1" +} + + +if test "$with_sgi_req" = yes -a "$have_sgi" = no ; then + warn 'The SGI saver extension was requested, but was not found.' +fi + +if test "$with_mit_req" = yes -a "$have_mit" = no ; then + warn 'The MIT saver extension was requested, but was not found.' +fi + +if test "$with_xidle_req" = yes -a "$have_xidle" = no ; then + warn 'The XIdle extension was requested, but was not found.' +fi + +if test "$with_xshm_req" = yes -a "$have_xshm" = no ; then + warn 'The XSHM extension was requested, but was not found.' +fi + +if test "$with_xdbe_req" = yes -a "$have_xdbe" = no ; then + warn 'The DOUBLE-BUFFER extension was requested, but was not found.' +fi + +if test "$with_sgivc_req" = yes -a "$have_sgivc" = no ; then + warn 'The SGI-VIDEO-CONTROL extension was requested, but was not found.' +fi + +if test "$with_dpms_req" = yes -a "$have_dpms" = no ; then + warn 'The DPMS extension was requested, but was not found.' +fi + +if test "$with_xf86vmode_req" = yes -a "$have_xf86vmode" = no ; then + warn 'The XF86VMODE extension was requested, but was not found.' +fi + +if test "$with_proc_interrupts_req" = yes -a "$have_proc_interrupts" = no; then + warn "Checking of /proc/interrupts was requested, but it's bogus." +fi + + +if test "$have_motif" = no -a "$have_gtk" = no -a "$have_athena" = no ; then + warnL "None of Motif, Gtk, or Athena widgets seem to be available;" + warn2 "the \`xscreensaver-demo' program requires one of these." + +elif test "$with_motif_req" = yes -a "$have_motif" = no ; then + warnL "Use of Motif was requested, but it wasn't found;" + if test "$have_gtk" = yes; then + warn2 "Gtk will be used instead." + else + warn2 "Athena will be used instead." + fi + +elif test "$jurassic_gtk" = yes ; then + + pref_gtk=1.2 + + v="$ac_gtk_version_string" + if test "$with_gtk_req" = yes -a "$ac_gtk_version" = "unknown" ; then + warnL "Use of Gtk was requested, but its version number is unknown;" + elif test "$with_gtk_req" = yes ; then + warnL "Use of Gtk was requested, but it is version $v;" + else + warnL "Gtk was found on this system, but it is version $v;" + fi + + if test "$have_motif" = yes; then + which="Motif" + else + which="Athena" + fi + + warn2 "Gtk $pref_gtk or newer is required. $which will be used instead." + +elif test "$with_gtk_req" = yes -a "$have_gtk" = no ; then + warnL "Use of Gtk was requested, but it wasn't found;" + if test "$have_motif" = yes; then + warn2 "Motif will be used instead." + else + warn2 "Athena will be used instead." + fi + +elif test "$with_athena_req" = yes -a "$have_athena" = no ; then + warnL "Use of Athena was requested, but it wasn't found;" + if test "$have_gtk" = yes; then + warn2 "Gtk will be used instead." + else + warn2 "Motif will be used instead." + fi +fi + + +if test "$have_motif" = yes -a "$have_lesstif" = yes ; then + + preferred_lesstif=0.86 + + if test "$lesstif_version" = unknown; then + warnL "Unable to determine the LessTif version number!" + warn2 "Make sure you are using version $preferred_lesstif or newer." + warn2 "See ." + + elif test \! $lesstif_version -gt 82; then + warnL "LessTif version $lesstif_version_string is being used." + warn2 "LessTif versions 0.82 and earlier are too buggy to" + warn2 "use with XScreenSaver; it is strongly recommended" + warn2 "that you upgrade to at least version $preferred_lesstif!" + warn2 "See ." + fi +fi + +if test "$have_athena" = yes -a "$have_motif" = no -a "$have_gtk" = no; then + warnL "Athena widgets are being used instead of Motif or Gtk." + warn2 "The \`xscreensaver-demo' program looks much better" + warn2 "with Motif or Gtk. Wouldn't you rather be using Motif?" + warn2 "Motif is shipped by every commercial Unix vendor," + warn2 "and there is a free implementation available as" + warn2 "well: see . Gtk is shipped" + warn2 "with most Linux and BSD distributions." +fi + + +if test "$have_xpm" = no ; then + if test "$with_xpm_req" = yes ; then + warnL 'Use of XPM was requested, but it was not found.' + elif test "$with_xpm_req" = no ; then + noteL 'The XPM library is not being used.' + else + noteL 'The XPM library was not found.' + fi + + echo '' + warn2 'Some of the demos will not be as colorful as they' + warn2 'could be. You might want to consider installing XPM' + warn2 'and re-running configure. (Remember to delete the' + warn2 'config.cache file first.) You can find XPM at most' + warn2 'X11 archive sites, such as .' +fi + + +if test "$have_gl" = yes -a "$ac_have_mesa_gl" = yes ; then + preferred_mesagl=3.0 + + if test "$ac_mesagl_version" = unknown; then + warnL "Unable to determine the MesaGL version number!" + warn2 "Make sure you are using version $preferred_mesagl or newer." + + elif test \! "$ac_mesagl_version" -gt 2006; then + warnL "MesaGL version $ac_mesagl_version_string is being used." + warn2 "MesaGL versions 2.6 and earlier have a security bug." + warn2 "It is strongly recommended that you upgrade to at" + warn2 "least version $preferred_mesagl." + fi +fi + + +if test "$have_gl" = no ; then + if test "$with_gl_req" = yes ; then + warnL 'Use of GL was requested, but it was not found.' + elif test "$with_gl_req" = no ; then + noteL 'The OpenGL 3D library is not being used.' + else + noteL 'The OpenGL 3D library was not found.' + fi + + echo '' + warn2 'Those demos which use 3D will not be built or installed.' + warn2 'You might want to consider installing OpenGL and' + warn2 're-running configure. (Remember to delete the' + warn2 "config.cache file first.) If your vendor doesn't ship" + warn2 'their own implementation of OpenGL, you can get a free' + warn2 'version at . For general OpenGL' + warn2 'info, see .' + +fi + +if test "$with_readdisplay_req" = yes -a "$have_readdisplay" = no ; then + warn 'Use of XReadDisplay was requested, but it was not found.' +fi + +if test "$with_sgivideo_req" = yes -a "$have_sgivideo" = no ; then + warn 'Use of the Iris Video Library was requested, but it was not found.' +fi + +if test -n "$with_zippy_req"; then + if test "$with_zippy_req" != "$ac_cv_zippy_program" ; then + warnL "$with_zippy_req was requested as the Zippy program," + warn2 "but was not found. The default will be used instead." + fi +fi + +if test "$with_kerberos_req" = yes -a "$have_kerberos" = no ; then + warn 'Use of Kerberos was requested, but it was not found.' +fi + +if test "$with_pam_req" = yes -a "$have_pam" = no ; then + warn 'Use of PAM was requested, but it was not found.' +fi + +if test "$with_shadow_req" = yes -a "$have_shadow" = no ; then + warn 'Use of shadow passwords was requested, but they were not found.' +fi + + +# You are in a twisty maze of namespaces and syntaxes, all alike. +# Fuck the skull of Unix. +# +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} + +# canonicalize slashes. +bindir=`echo "${bindir}" | sed 's@/$@@;s@//*@/@g'` +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` + + +# Sanity check the subdir +for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command ; do + if test "${HACKDIR}" = "${bindir}/${bad_choice}" ; then + echo "" + { echo "configure: error: \"--enable-subdir=${bindir}/${bad_choice}\" won't work. + There will be an executable installed with that name, so + that can't be the name of a directory as well. Please + re-configure with a different directory name." 1>&2; exit 1; } + fi +done + + +do_dir_warning=no + +# Now let's see if there's a previous RPM version already installed. Blargh! + +# M4 sucks!! + +rpmv=`(rpm -qv xscreensaver) 2>&- | \ + sed 's/^xscreensaver-\([0-9][0-9]*[.][0-9][0-9]*\)-[0-9][0-9]*$/\1/'` + + +if test \! -z "$rpmv" ; then + rpmbdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/xscreensaver-demo$@\1@p'` + rpmhdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/attraction$@\1@p'` + + warning=no + warnL "There is already an installed RPM of xscreensaver $rpmv" + warn2 "on this system. You might want to remove it (with" + warn2 '"rpm -ve xscreensaver") before running "make install"' + warn2 "from this directory." + echo "" + warn2 "Alternately, you could build this version of xscreensaver" + warn2 'as an RPM, and then install that. An "xscreensaver.spec"' + warn2 "file is included. See the RPM documentation for more info." + echo "" + + if test "$rpmbdir" = "$rpmhdir" ; then + warn2 "The RPM version was installed in $rpmbdir." + else + warn2 "The RPM version was installed in $rpmbdir," + warn2 "with demos in $rpmhdir." + fi + + do_dir_warning=yes +fi + + +# Warn about egregious GNOME bogosity. +# +if (rpm -qv control-center) >&- 2>&- ; then + warning=no + warnL "The Gnome Control Center seems to be installed." + echo "" + warn2 "Note that simply installing this version of xscreensaver" + warn2 "will not cause GNOME to know about the newly-added display" + warn2 "modes -- GNOME is just lame that way. Instead of using the" + warn2 "Control Center, try using the \`xscreensaver-demo' command." +fi + + +if test "${bindir}" = "${HACKDIR}" ; then + do_dir_warning=yes +fi + +if test "$do_dir_warning" = yes; then + echo "" + echo "$warnsep" + echo "" + echo ' When you run "make install", the "xscreensaver",' + echo ' "xscreensaver-demo", and "xscreensaver-command" executables' + echo " will be installed in ${bindir}." + echo "" + echo " The various graphics demos (90+ different executables) will" + echo " also be installed in ${HACKDIR}." + echo "" + echo " If you would prefer the demos to be installed elsewhere" + echo " (for example, in a dedicated directory) you should re-run" + echo " configure with the --enable-subdir=DIR option. For more" + echo " information, run $0 --help." + warning=yes +fi + +if test "$warning" != no; then + echo '' ; echo "$warnsep" ; echo '' +fi diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..07fb76e9 --- /dev/null +++ b/configure.in @@ -0,0 +1,2764 @@ +# configure.in --- xscreensaver, Copyright (c) 1997 Jamie Zawinski. +# + +AC_INIT(driver/subprocs.c) +AC_CONFIG_HEADER(config.h) + +echo "current directory: `pwd`" +echo "command line was: $0 $@" + + +# After checking to see that --srcdir is correct (which AC_INIT does) +# check for some random other files that come later in the tar file, +# to make sure everything is here. +# +for d in driver utils hacks hacks/glx ; do + f=$srcdir/$d/Makefile.in + if test \! -r $f ; then + echo "" + echo "ERROR: The package is incomplete: $f does not exist." + echo " This probably means that your download was truncated." + echo "" + exit 1 + fi +done + + +############################################################################### +# +# Function to figure out how to run the compiler. +# +############################################################################### + +AC_DEFUN(AC_PROG_CC_ANSI, + [AC_PROG_CC + + if test -z "$GCC"; then + AC_MSG_CHECKING(how to request ANSI compilation) + case "$host" in + *-hpux* ) + AC_MSG_RESULT(HPUX: adding -Ae) + CC="$CC -Ae" + ;; + *-aix* ) + AC_MSG_RESULT(AIX: adding -qlanglvl=ansi -qhalt=e) + CC="$CC -qlanglvl=ansi -qhalt=e" + ;; + + *-dec-* ) + AC_MSG_RESULT(DEC: adding -std1) + CC="$CC -std1" + ;; + + *) + AC_MSG_RESULT(no idea) + ;; + esac + fi + + AC_MSG_CHECKING([whether the compiler works on ANSI C]) + AC_TRY_RUN([ main(int ac, char **av) { return 0; } ], + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no) + AC_MSG_ERROR(Couldn't build even a trivial ANSI C program: check CC.), + AC_MSG_ERROR(Couldn't build even a trivial ANSI C program: check CC.)) + + if test -n "$GCC"; then + AC_MSG_RESULT(Turning on gcc compiler warnings.) + CC="$CC -Wall -Wstrict-prototypes -Wnested-externs -Wno-format" + else + case "$host" in + *-irix5* |*-irix6.[0-3]* ) + AC_MSG_RESULT(Turning on SGI compiler warnings.) + CC="$CC -fullwarn -use_readonly_const -rdata_shared -g3" + ;; +# *-dec-osf* ) +# if test -z "$GCC"; then +# AC_MSG_RESULT(Turning on DEC C compiler warnings.) +# CC="$CC -migrate -w0 -verbose -warnprotos" +# fi +# ;; + esac + fi +]) + + +############################################################################### +# +# Function to figure out how to create directory trees. +# +############################################################################### + +AC_DEFUN(AC_PROG_INSTALL_DIRS, + [AC_CACHE_CHECK([whether \"\${INSTALL} -d\" creates intermediate directories], + ac_cv_install_d_creates_dirs, + [ac_cv_install_d_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir >&- + ${INSTALL} -d `pwd`/dir1/dir2 >&- 2>&- + if test -d dir1/dir2/. ; then + ac_cv_install_d_creates_dirs=yes + fi + cd .. >&- + rm -rf conftestdir + fi + ]) + + if test "$ac_cv_install_d_creates_dirs" = no ; then + AC_CACHE_CHECK([whether \"mkdir -p\" creates intermediate directories], + ac_cv_mkdir_p_creates_dirs, + [ac_cv_mkdir_p_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir >&- + mkdir -p dir1/dir2 >&- 2>&- + if test -d dir1/dir2/. ; then + ac_cv_mkdir_p_creates_dirs=yes + fi + cd .. >&- + rm -rf conftestdir + fi + ]) + fi + + if test "$ac_cv_install_d_creates_dirs" = yes ; then + INSTALL_DIRS='${INSTALL} -d' + elif test "$ac_cv_mkdir_p_creates_dirs" = yes ; then + INSTALL_DIRS='mkdir -p' + else + # any other ideas? + INSTALL_DIRS='${INSTALL} -d' + fi +]) + + +############################################################################### +# +# Function to check whether gettimeofday() exists, and how to call it. +# This may define HAVE_GETTIMEOFDAY and GETTIMEOFDAY_TWO_ARGS. +# +############################################################################### + +AC_DEFUN(AC_GETTIMEOFDAY_ARGS, + [AC_MSG_CHECKING(how to call gettimeofday) + AC_CACHE_VAL(ac_cv_gettimeofday_args, + [AC_TRY_COMPILE([#include + #include ], + [struct timeval tv; struct timezone tzp; + gettimeofday(&tv, &tzp);], + [ac_gettimeofday_args=2], + [AC_TRY_COMPILE([#include + #include ], + [struct timeval tv; gettimeofday(&tv);], + [ac_gettimeofday_args=1], + [ac_gettimeofday_args=0])]) + ac_cv_gettimeofday_args=$ac_gettimeofday_args]) + ac_gettimeofday_args=$ac_cv_gettimeofday_args + if test "$ac_gettimeofday_args" = 1 ; then + AC_DEFINE(HAVE_GETTIMEOFDAY) + AC_MSG_RESULT(one argument) + elif test "$ac_gettimeofday_args" = 2 ; then + AC_DEFINE(HAVE_GETTIMEOFDAY) + AC_DEFINE(GETTIMEOFDAY_TWO_ARGS) + AC_MSG_RESULT(two arguments) + else + AC_MSG_RESULT(unknown) + fi +]) + + +############################################################################### +# +# Function to find perl5 (defines PERL and PERL_VERSION.) +# +############################################################################### + +# M4 sucks!! perl sucks too!! +changequote(X,Y) +perl_version_cmd='print $]' +changequote([,]) + +AC_DEFUN(AC_PROG_PERL, + [PERL='' + AC_PATH_PROGS(PERL, [perl5 perl],,) + if test -z "$PERL" ; then + PERL_VERSION=0 + else + AC_CACHE_CHECK([perl version], ac_cv_perl_version, + [ac_cv_perl_version=`$PERL -e "$perl_version_cmd"`]) + PERL_VERSION=$ac_cv_perl_version + fi + ]) + + +############################################################################### +# +# Functions to check how to do ICMP PING requests. +# +############################################################################### + +AC_DEFUN(AC_CHECK_ICMP, + [AC_CACHE_CHECK([for struct icmp], ac_cv_have_icmp, + [AC_TRY_COMPILE([#include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include ], + [struct icmp i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.icmp_type = ICMP_ECHO; + i.icmp_code = 0; + i.icmp_cksum = 0; + i.icmp_id = 0; + i.icmp_seq = 0; + si.sin_family = AF_INET; + ip.ip_hl = 0;], + [ac_cv_have_icmp=yes], + [ac_cv_have_icmp=no])]) + if test "$ac_cv_have_icmp" = yes ; then + AC_DEFINE(HAVE_ICMP) + fi]) + +AC_DEFUN(AC_CHECK_ICMPHDR, + [AC_CACHE_CHECK([for struct icmphdr], ac_cv_have_icmphdr, + [AC_TRY_COMPILE([#include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include ], + [struct icmphdr i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.type = ICMP_ECHO; + i.code = 0; + i.cksum = 0; + i.un.echo.id = 0; + i.un.echo.sequence = 0; + si.sin_family = AF_INET; + ip.ip_hl = 0;], + [ac_cv_have_icmphdr=yes], + [ac_cv_have_icmphdr=no])]) + if test "$ac_cv_have_icmphdr" = yes ; then + AC_DEFINE(HAVE_ICMPHDR) + fi]) + + +############################################################################### +# +# Functions to check for various X11 crap. +# +############################################################################### + +# Try and find the app-defaults directory. +# It sucks that autoconf doesn't do this already... +# +AC_DEFUN(AC_PATH_X_APP_DEFAULTS_XMKMF,[ + rm -fr conftestdir + if mkdir conftestdir; then + cd conftestdir >&- + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_x_app_defaults="${XAPPLOADDIR}"' +EOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which'd confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + fi + cd .. >&- + rm -fr conftestdir + fi]) + +AC_DEFUN(AC_PATH_X_APP_DEFAULTS_DIRECT,[ + # Look for the directory under a standard set of common directories. + # Check X11 before X11Rn because it's often a symlink to the current release. + for ac_dir in \ + /usr/X11/lib/app-defaults \ + /usr/X11R6/lib/app-defaults \ + /usr/X11R6/lib/X11/app-defaults \ + /usr/X11R5/lib/app-defaults \ + /usr/X11R5/lib/X11/app-defaults \ + /usr/X11R4/lib/app-defaults \ + /usr/X11R4/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/lib/X11R6/app-defaults \ + /usr/lib/X11R5/app-defaults \ + /usr/lib/X11R4/app-defaults \ + \ + /usr/local/X11/lib/app-defaults \ + /usr/local/X11R6/lib/app-defaults \ + /usr/local/X11R5/lib/app-defaults \ + /usr/local/X11R4/lib/app-defaults \ + \ + /usr/local/lib/X11/app-defaults \ + /usr/local/lib/X11R6/app-defaults \ + /usr/local/lib/X11R6/X11/app-defaults \ + /usr/local/lib/X11R5/app-defaults \ + /usr/local/lib/X11R5/X11/app-defaults \ + /usr/local/lib/X11R4/app-defaults \ + /usr/local/lib/X11R4/X11/app-defaults \ + \ + /usr/X386/lib/X11/app-defaults \ + /usr/x386/lib/X11/app-defaults \ + /usr/XFree86/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/local/lib/X11/app-defaults \ + /usr/unsupported/lib/X11/app-defaults \ + /usr/athena/lib/X11/app-defaults \ + /usr/local/x11r5/lib/X11/app-defaults \ + /usr/lpp/Xamples/lib/X11/app-defaults \ + /lib/usr/lib/X11/app-defaults \ + \ + /usr/openwin/lib/app-defaults \ + /usr/openwin/lib/X11/app-defaults \ + /usr/openwin/share/lib/app-defaults \ + /usr/openwin/share/lib/X11/app-defaults \ + \ + /X11R6/lib/app-defaults \ + /X11R5/lib/app-defaults \ + /X11R4/lib/app-defaults \ + ; \ + do + if test -d "$ac_dir"; then + ac_x_app_defaults=$ac_dir + break + fi + done +]) + +AC_DEFUN(AC_PATH_X_APP_DEFAULTS, + [AC_REQUIRE_CPP() + AC_CACHE_CHECK([for X app-defaults directory], ac_cv_x_app_defaults, + [AC_PATH_X_APP_DEFAULTS_XMKMF + if test x"$ac_x_app_defaults" = x; then + AC_PATH_X_APP_DEFAULTS_DIRECT + fi + if test x"$ac_x_app_defaults" = x; then + ac_cv_x_app_defaults="/usr/lib/X11/app-defaults" + else + # Record where we found app-defaults for the cache. + ac_cv_x_app_defaults="$ac_x_app_defaults" + fi]) + eval ac_x_app_defaults="$ac_cv_x_app_defaults"]) + + +AC_DEFUN(AC_XPOINTER, + [AC_CACHE_CHECK([for XPointer], ac_cv_xpointer, + [AC_TRY_X_COMPILE([#include ], + [XPointer foo = (XPointer) 0;], + [ac_cv_xpointer=yes], + [ac_cv_xpointer=no])]) + if test "$ac_cv_xpointer" != yes; then + AC_DEFINE(XPointer,[char*]) + fi]) + + +# Random special-cases for X on certain pathological OSes. +# You know who you are. +# +AC_DEFUN(AC_X_RANDOM_PATHS, + [case "$host" in + *-hpux*) + + # The following arcana was gleaned from conversations with + # Eric Schwartz : + # + # On HPUX 10.x, the parts of X that HP considers "standard" live in + # /usr/{include,lib}/X11R6/. The parts that HP doesn't consider + # "standard", notably, Xaw and Xmu, live in /usr/contrib/X11R6/. + # Yet /usr/contrib/X11R6/ comes preinstalled on all HPUX systems. + # Also, there are symlinks from /usr/include/ and /usr/lib/ into + # /usr/{include,lib}/X11R6/, so that (if you don't use Xmu at all) + # you don't need any -I or -L arguments. + # + # On HPUX 9.x, /usr/{include,lib}/X11R5/ and /usr/contrib/X11R5/ + # are the same division as 10.x. However, there are no symlinks to + # the X stuff from /usr/include/ and /usr/lib/, so -I and -L + # arguments are always necessary. + # + # However, X11R6 was available on HPUX 9.x as a patch: if that + # patch was installed, then all of X11R6 went in to + # /usr/contrib/X11R6/ (there was no /usr/{include,lib}/X11R6/.) + # + # HPUX 8.x was the same as 9.x, but was X11R4 instead (I don't know + # whether R5 was available as a patch; R6 undoubtedly was not.) + # + # So. We try and use the highest numbered pair of + # /usr/{include,lib}/X11R?/ and /usr/contrib/X11R?/{include,lib}/ + # that are available. We do not mix and match different versions + # of X. + # + # Question I still don't know the answer to: (do you?) + # + # * On HPUX 9.x, where /usr/include/X11R5/ was standard, and + # /usr/contrib/X11R6/ could be installed as a patch, what was in + # that contrib directory? Did it contain so-called "standard" + # X11R6, or did it include Xaw and Xmu as well? If the former, + # where did one find Xaw and Xmu on 9.x R6 systems? Would this + # be a situation where one had to reach into the R5 headers and + # libs to find Xmu? That is, must both R6 and R5 directories + # be on the -I and -L lists in that case? + # + for version in X11R6 X11R5 X11R4 ; do + # if either pair of directories exists... + if test -d /usr/lib/$version || test -d /usr/contrib/$version/lib + then + # if contrib exists, use it... + if test -d /usr/contrib/$version/lib ; then + X_CFLAGS="$X_CFLAGS -I/usr/contrib/$version/include" + X_LIBS="$X_LIBS -L/usr/contrib/$version/lib" + fi + # if the "standard" one exists, use it. + if test -d /usr/lib/$version ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/$version" + X_LIBS="$X_LIBS -L/usr/lib/$version" + fi + # since at least one of the pair exists, go no farther. + break + fi + done + + # Now find Motif. Thanks for not making xmkmf find this by + # default, you losers. + # + if test -d /usr/lib/Motif1.2 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.2" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.2" + elif test -d /usr/lib/Motif1.1 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.1" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.1" + fi + + # Now let's check for the pseudo-standard locations for OpenGL and XPM. + # + if test -d /opt/Mesa/lib ; then + X_CFLAGS="-I/opt/Mesa/include $X_CFLAGS" + X_LIBS="-L/opt/Mesa/lib $X_LIBS" + fi + + if test -d /opt/xpm/lib/X11 ; then + X_CFLAGS="-I/opt/xpm/include $X_CFLAGS" + X_LIBS="-L/opt/xpm/lib/X11 $X_LIBS" + fi + + # On HPUX, default to installing in /opt/xscreensaver/ instead of + # in /usr/local/, unless there is already an xscreensaver in + # /usr/local/bin/. This can be overridden with the --prefix arg + # to configure. I'm not sure this is the right thing to do, but + # Richard Lloyd says so... + # + if test \! -x /usr/local/bin/xscreensaver ; then + ac_default_prefix=/opt/xscreensaver + fi + + ;; + *-solaris*) + + # Thanks for not making xmkmf find this by default, pinheads. + # And thanks for moving things around again, too. Is this + # really the standard location now? What happened to the + # joke that this kind of thing went in /opt? + # cthomp says "answer: CDE (Common Disorganized Environment)" + # + if test -f /usr/dt/include/Xm/Xm.h ; then + X_CFLAGS="$X_CFLAGS -I/usr/dt/include" + X_LIBS="$X_LIBS -L/usr/dt/lib -R:/usr/dt/lib" + + # Some versions of Slowlaris Motif require -lgen. But not all. Why? + AC_CHECK_LIB(gen, regcmp, [X_LIBS="$X_LIBS -lgen"]) + fi + ;; + esac]) + + + +############################################################################### +# +# Some utility functions to make checking for X things easier. +# +############################################################################### + +# Like AC_CHECK_HEADER, but it uses the already-computed -I directories. +# +AC_DEFUN(AC_CHECK_X_HEADER, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + AC_CHECK_HEADER([$1], [$2]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + +# Like AC_EGREP_HEADER, but it uses the already-computed -I directories. +# +AC_DEFUN(AC_EGREP_X_HEADER, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + AC_EGREP_HEADER([$1], [$2], [$3], [$4]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + +# Like AC_TRY_COMPILE, but it uses the already-computed -I directories. +# +AC_DEFUN(AC_TRY_X_COMPILE, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + AC_TRY_COMPILE([$1], [$2], [$3], [$4]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + + +# Like AC_CHECK_LIB, but it uses the already-computed -I and -L directories. +# Use this sparingly; it probably doesn't work very well on X programs. +# +AC_DEFUN(AC_CHECK_X_LIB, [ + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS" + + AC_CHECK_LIB([$1], [$2], [$3], [$4], [$5]) + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + ]) + +# Like AC_TRY_RUN, but it uses the already-computed -I directories. +# (But not the -L directories!) +# +AC_DEFUN(AC_TRY_X_RUN, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + AC_TRY_RUN([$1], [$2], [$3], [$4]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + + + +# Usage: HANDLE_X_PATH_ARG([variable_name], +# [--command-line-option], +# [descriptive string]) +# +# All of the --with options take three forms: +# +# --with-foo (or --with-foo=yes) +# --without-foo (or --with-foo=no) +# --with-foo=/DIR +# +# This function, HANDLE_X_PATH_ARG, deals with the /DIR case. When it sees +# a directory (string beginning with a slash) it checks to see whether +# /DIR/include and /DIR/lib exist, and adds them to $X_CFLAGS and $X_LIBS +# as appropriate. +# +AC_DEFUN(HANDLE_X_PATH_ARG, [ + case "$[$1]" in + yes) ;; + no) ;; + + /*) + AC_MSG_CHECKING([for [$3] headers]) + d=$[$1]/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + AC_MSG_RESULT($d) + else + AC_MSG_RESULT(not found ($d: no such directory)) + fi + + AC_MSG_CHECKING([for [$3] libs]) + d=$[$1]/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + AC_MSG_RESULT($d) + else + AC_MSG_RESULT(not found ($d: no such directory)) + fi + + # replace the directory string with "yes". + [$1]_req="yes" + [$1]=$[$1]_req + ;; + + *) + echo "" + echo "error: argument to [$2] must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + ]) + + + +############################################################################### +############################################################################### +# +# End of function definitions. Now start actually executing stuff. +# +############################################################################### +############################################################################### + +# random compiler setup +AC_CANONICAL_HOST +AC_PROG_CC_ANSI +AC_PROG_CPP +AC_C_CONST +AC_C_INLINE + +# stuff for Makefiles +AC_PROG_INSTALL +AC_PROG_INSTALL_DIRS +AC_PROG_MAKE_SET + +# random libc stuff +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) +AC_TYPE_MODE_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SIGNAL +AC_HEADER_TIME +AC_HEADER_SYS_WAIT +AC_HEADER_DIRENT +AC_GETTIMEOFDAY_ARGS +AC_CHECK_FUNCS(select fcntl uname nice setpriority getcwd getwd putenv) + +AC_CHECK_FUNCS(sigaction syslog realpath) +AC_CHECK_ICMP +AC_CHECK_ICMPHDR +AC_CHECK_HEADERS(crypt.h sys/select.h) +AC_PROG_PERL + +if test -z "$PERL" ; then + # don't let it be blank... + PERL=/usr/local/bin/perl5 +fi + +AC_PATH_XTRA + +if test "$have_x" != yes; then + AC_MSG_ERROR(Couldn't find X11 headers/libs. Try \`$0 --help'.) +fi + +AC_PATH_X_APP_DEFAULTS +AC_X_RANDOM_PATHS +AC_XPOINTER + + + +############################################################################### +# +# Check for -lXmu (some fucked up vendors don't ship it...) +# +############################################################################### + +have_xmu=no +AC_CHECK_X_HEADER(X11/Xmu/Error.h, [have_xmu=yes]) +if test "$have_xmu" = no ; then + XMU_SRCS='$(UTILS_SRC)/xmu.c' + XMU_OBJS='$(UTILS_BIN)/xmu.o' +else + XMU_SRCS='' + XMU_OBJS='' + SAVER_LIBS="-lXmu $SAVER_LIBS" + HACK_LIBS="-lXmu $HACK_LIBS" + MOTIF_LIBS="-lXmu $MOTIF_LIBS" + GTK_LIBS="-lXmu $GTK_LIBS" + ATHENA_LIBS="-lXmu $ATHENA_LIBS" + ATHENA3D_LIBS="-lXmu $ATHENA3D_LIBS" + AC_DEFINE(HAVE_XMU) +fi + + +############################################################################### +# +# Check for the SunOS 4.1.x _get_wmShellWidgetClass bug. +# See comp.windows.x FAQ question 124. The right fix is to +# get OpenWindows 3.0 patches 100512-02 and 100573-03. +# +############################################################################### + +if test "$have_xmu" = yes ; then + case "$host" in + *-sunos4*) + AC_CACHE_CHECK([for the SunOS 4.1.x _get_wmShellWidgetClass bug], + ac_cv_sunos_xmu_bug, + [ac_save_LDFLAGS="$LDFLAGS" + if test \! -z "$x_libraries" ; then + LDFLAGS="$LDFLAGS -L$x_libraries" + fi + # Note: this trick never works! (Generally.) + # We're only getting away with using AC_TRY_LINK + # with X libraries because we know it's SunOS. + LDFLAGS="$LDFLAGS -lXmu -lXt -lX11 -lXext -lm" + AC_TRY_LINK(,, + [ac_cv_sunos_xmu_bug=no], + [ac_cv_sunos_xmu_bug=yes]) + LDFLAGS="$ac_save_LDFLAGS"]) + if test "$ac_cv_sunos_xmu_bug" = yes ; then + AC_CACHE_CHECK([whether the compiler understands -static], + ac_cv_ld_static, + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -static" + AC_TRY_LINK(,,[ac_cv_ld_static=yes],[ac_cv_ld_static=no]) + LDFLAGS="$ac_save_LDFLAGS"]) + if test "$ac_cv_ld_static" = yes ; then + LDFLAGS="$LDFLAGS -static" + else + LDFLAGS="$LDFLAGS -Bstatic" + fi + fi + ;; + esac +fi + + +############################################################################### +# +# Handle the --enable-subdir option +# +############################################################################### + +AC_ARG_ENABLE(subdir,[ +Installation options: + + --enable-subdir=DIR Put the demo programs in a subdirectory of \`bindir', + instead of putting them in bindir itself. You can + specify the name of the subdirectory. For example, + \`--exec-prefix=/usr/local --enable-subdir=demos' + would put xscreensaver in /usr/local/bin/, and would + put the demos in /usr/local/bin/demos/. (If DIR + begins with /, then bindir will not be prepended.) + + --disable-subdir Just put the demos in \`bindir' (this is the default.) +], + [enable_subdir="$enableval"],[enable_subdir=no]) +if test x"$enable_subdir" = xno; then + HACKDIR='${bindir}' +elif test x"$enable_subdir" = xyes -o x"$enable_subdir" = x ; then + echo "error: must be a subdirectory name: --enable-subdir=$enable_subdir" + exit 1 +else + # there must be a better way than this... + if test -z "`echo $enable_subdir | sed 's@^/.*@@'`" ; then + # absolute path + HACKDIR=$enable_subdir + else + # relative path + HACKDIR='${bindir}/'$enable_subdir + fi +fi + +# canonicalize slashes. +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` + + +############################################################################### +# +# Check for the SGI SCREEN_SAVER server extension. +# +############################################################################### + +have_sgi=no +with_sgi_req=unspecified +AC_ARG_WITH(sgi-ext, +[Except where noted, all of the --with options below can also take a +directory argument: for example, \`--with-motif=/opt/Motif'. That would +cause /opt/Motif/include/ to be added to the -I list, and /opt/Motif/lib/ +to be added to the -L list, assuming those directories exist. + +By default, support for each of these options will be built in, if the +relevant library routines exist. At run time, they will then be used +only if the X server being used supports them. Each --with option has +a corresponding --without option, to override building support for them +at all. + +Screen blanking and idle-detection options: + + --with-sgi-ext Include support for the SGI SCREEN_SAVER extension.], + [with_sgi="$withval"; with_sgi_req="$withval"],[with_sgi=yes]) + +HANDLE_X_PATH_ARG(with_sgi, --with-sgi-ext, SGI SCREEN_SAVER) + +if test "$with_sgi" = yes; then + AC_CHECK_X_HEADER(X11/extensions/XScreenSaver.h, + [have_sgi=yes + AC_DEFINE(HAVE_SGI_SAVER_EXTENSION)]) + +elif test "$with_sgi" != no; then + echo "error: must be yes or no: --with-sgi-ext=$with_sgi" + exit 1 +fi + + +############################################################################### +# +# Check for the MIT-SCREEN-SAVER server extension. +# +############################################################################### + +have_mit=no +with_mit_req=unspecified +AC_ARG_WITH(mit-ext, +[ --with-mit-ext Include support for the MIT-SCREEN-SAVER extension.], + [with_mit="$withval"; with_mit_req="$withval"],[with_mit=yes]) + +HANDLE_X_PATH_ARG(with_mit, --with-mit-ext, MIT-SCREEN-SAVER) + +if test "$with_mit" = yes; then + AC_CHECK_X_HEADER(X11/extensions/scrnsaver.h, [have_mit=yes]) + + # Now check to see if it's really in the library; XF86Free-3.3 ships + # scrnsaver.h, but doesn't include the code in libXext.a, the idiots! + # + if test "$have_mit" = yes; then + AC_CHECK_X_LIB(Xext, XScreenSaverRegister, [true], [have_mit=no], -lm) + + if test "$have_mit" = no; then + # Fuck! Looks like XF86Free-3.3 actually puts it in XExExt instead + # of in Xext. Thank you master, may I have another. + AC_CHECK_X_LIB(XExExt, XScreenSaverRegister, + [have_mit=yes; SAVER_LIBS="$SAVER_LIBS -lXExExt"], + [true], -lX11 -lXext -lm) + fi + + if test "$have_mit" = no; then + # Double fuck! Looks like some versions of XFree86 (whichever version + # it is that comes with RedHat Linux 2.0 -- I can't find a version + # number) put this garbage in Xss instead of Xext. Thank you master, + # may I have another. + AC_CHECK_X_LIB(Xss, XScreenSaverRegister, + [have_mit=yes; SAVER_LIBS="$SAVER_LIBS -lXss"], + [true], -lX11 -lXext -lm) + fi + + if test "$have_mit" = yes; then + AC_DEFINE(HAVE_MIT_SAVER_EXTENSION) + fi + + fi + +elif test "$with_mit" != no; then + echo "error: must be yes or no: --with-mit-ext=$with_mit" + exit 1 +fi + + +############################################################################### +# +# Check for the XIDLE server extension. +# +############################################################################### + +have_xidle=no +with_xidle_req=unspecified +AC_ARG_WITH(xidle-ext, +[ --with-xidle-ext Include support for the XIDLE extension.], + [with_xidle="$withval"; with_xidle_req="$withval"],[with_xidle=yes]) + +HANDLE_X_PATH_ARG(with_xidle, --with-xidle-ext, XIDLE) + +if test "$with_xidle" = yes; then + AC_CHECK_X_HEADER(X11/extensions/xidle.h, + [have_xidle=yes + AC_DEFINE(HAVE_XIDLE_EXTENSION)]) +elif test "$with_xidle" != no; then + echo "error: must be yes or no: --with-xidle-ext=$with_xidle" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI-VIDEO-CONTROL server extension. +# +############################################################################### + +have_sgivc=no +with_sgivc_req=unspecified +AC_ARG_WITH(sgivc-ext, +[ --with-sgivc-ext Include support for the SGI-VIDEO-CONTROL extension.], + [with_sgivc="$withval"; with_sgivc_req="$withval"],[with_sgivc=yes]) + +HANDLE_X_PATH_ARG(with_sgivc, --with-sgivc-ext, SGI-VIDEO-CONTROL) + +if test "$with_sgivc" = yes; then + + # first check for XSGIvc.h + AC_CHECK_X_HEADER(X11/extensions/XSGIvc.h, [have_sgivc=yes]) + + # if that succeeded, then check for the -lXsgivc + if test "$have_sgivc" = yes; then + have_sgivc=no + AC_CHECK_X_LIB(Xsgivc, XSGIvcQueryGammaMap, + [have_sgivc=yes; SAVER_LIBS="$SAVER_LIBS -lXsgivc"], [true], + -lXext -lX11) + fi + + # if that succeeded, then we've really got it. + if test "$have_sgivc" = yes; then + AC_DEFINE(HAVE_SGI_VC_EXTENSION) + fi + +elif test "$with_sgivc" != no; then + echo "error: must be yes or no: --with-sgivc-ext=$with_sgivc" + exit 1 +fi + + +############################################################################### +# +# Check for the DPMS server extension. +# +############################################################################### + +have_dpms=no +with_dpms_req=unspecified +AC_ARG_WITH(dpms-ext, +[ --with-dpms-ext Include support for the DPMS extension.], + [with_dpms="$withval"; with_dpms_req="$withval"],[with_dpms=yes]) + +HANDLE_X_PATH_ARG(with_dpms, --with-dpms-ext, DPMS) + +if test "$with_dpms" = yes; then + + # first check for dpms.h + AC_CHECK_X_HEADER(X11/extensions/dpms.h, [have_dpms=yes]) + + # if that succeeded, then check for the -lXdpms + if test "$have_dpms" = yes; then + have_dpms=no + AC_CHECK_X_LIB(Xdpms, DPMSInfo, + [have_dpms=yes; SAVER_LIBS="$SAVER_LIBS -lXdpms"], [true], + -lXext -lX11) + fi + + # if that succeeded, then we've really got it. + if test "$have_dpms" = yes; then + AC_DEFINE(HAVE_DPMS_EXTENSION) + fi + +elif test "$with_dpms" != no; then + echo "error: must be yes or no: --with-dpms-ext=$with_dpms" + exit 1 +fi + + +############################################################################### +# +# Check for the XF86VMODE server extension. +# +############################################################################### + +have_xf86vmode=no +with_xf86vmode_req=unspecified +AC_ARG_WITH(xf86vmode-ext, +[ --with-xf86vmode-ext Include support for XFree86 virtual screens.], + [with_xf86vmode="$withval"; with_xf86vmode_req="$withval"], + [with_xf86vmode=yes]) + +HANDLE_X_PATH_ARG(with_xf86vmode, --with-xf86vmode-ext, xf86vmode) + +if test "$with_xf86vmode" = yes; then + + # first check for xf86vmode.h + AC_CHECK_X_HEADER(X11/extensions/xf86vmode.h, [have_xf86vmode=yes]) + + # if that succeeded, then check for the -lXxf86vm + if test "$have_xf86vmode" = yes; then + have_xf86vmode=no + AC_CHECK_X_LIB(Xxf86vm, XF86VidModeGetViewPort, + [have_xf86vmode=yes; SAVER_LIBS="$SAVER_LIBS -lXxf86vm"], + [true], -lXext -lX11) + fi + + # if that succeeded, then we've really got it. + if test "$have_xf86vmode" = yes; then + AC_DEFINE(HAVE_XF86VMODE) + fi + +elif test "$with_xf86vmode" != no; then + echo "error: must be yes or no: --with-xf86vmode-ext=$with_xf86vmode" + exit 1 +fi + + +############################################################################### +# +# Check for HP XHPDisableReset and XHPEnableReset. +# +############################################################################### + +AC_EGREP_X_HEADER(XHPDisableReset, X11/XHPlib.h, + [AC_DEFINE(HAVE_XHPDISABLERESET) + SAVER_LIBS="-lXhp11 $SAVER_LIBS"]) + + +############################################################################### +# +# Check for /proc/interrupts. +# +############################################################################### + +have_proc_interrupts=no +with_proc_interrupts_req=unspecified +AC_ARG_WITH(proc-interrupts, +[ --with-proc-interrupts Include support for consulting the /proc/interrupts + file to notice keyboard activity.], + [with_proc_interrupts="$withval"; with_proc_interrupts_req="$withval"], + [with_proc_interrupts=yes]) + +if test "$with_proc_interrupts" = yes; then + + AC_CACHE_CHECK([whether /proc/interrupts contains keyboard data], + ac_cv_have_proc_interrupts, + [ac_cv_have_proc_interrupts=no + if grep keyboard /proc/interrupts >/dev/null 2>&1 ; then + ac_cv_have_proc_interrupts=yes + fi + ]) + have_proc_interrupts=$ac_cv_have_proc_interrupts + + if test "$have_proc_interrupts" = yes; then + AC_DEFINE(HAVE_PROC_INTERRUPTS) + fi + +elif test "$with_proc_interrupts" != no; then + echo "error: must be yes or no: --with-proc-interrupts=$with_proc_interrupts" + exit 1 +fi + + +############################################################################### +# +# The --enable-locking option +# +############################################################################### + +AC_ARG_ENABLE(locking,[ +Screen locking options: + + --enable-locking Compile in support for locking the display. + --disable-locking Do not allow locking at all. +], + [enable_locking="$enableval"],[enable_locking=yes]) +if test "$enable_locking" = yes; then + true +elif test "$enable_locking" = no; then + AC_DEFINE(NO_LOCKING) +else + echo "error: must be yes or no: --enable-locking=$enable_locking" + exit 1 +fi + + + +############################################################################### +# +# The --enable-vt-locking option +# +############################################################################### + +#ac_vt_lockswitch=no +#AC_ARG_ENABLE(vt-locking,[ +# --enable-vt-locking Compile in support for locking Virtual Terminals. +# This is the default if the system supports it, and +# if locking support is included (--enable-locking.) +# --disable-vt-locking Do not allow locking of VTs, even if locking is +# enabled.], +# [enable_vt_locking="$enableval"],[enable_vt_locking=yes]) +#if test "$enable_vt_locking" = yes; then +# +# AC_CACHE_CHECK([for the VT_LOCKSWITCH ioctl], ac_cv_vt_lockswitch, +# [AC_TRY_COMPILE([#include +# #include +# #include ], +# [int x = VT_LOCKSWITCH; int y = VT_UNLOCKSWITCH;], +# [ac_cv_vt_lockswitch=yes], +# [ac_cv_vt_lockswitch=no])]) +# ac_vt_lockswitch=$ac_cv_vt_lockswitch +# +#elif test "$enable_vt_locking" = no; then +# true +#else +# echo "error: must be yes or no: --enable-vt-locking=$enable_vt_locking" +# exit 1 +#fi +# +#if test "$ac_vt_lockswitch" = yes; then +# AC_DEFINE(HAVE_VT_LOCKSWITCH) +# # the VT_LOCKSWITCH ioctl can only be used when running as root. +# # #### but it doesn't work yet, so don't worry about that for now. +## need_setuid=yes +#fi + + + +############################################################################### +# +# Check for PAM. +# +############################################################################### + +case "$host" in + *-solaris*) + # Solaris systems tend to come with PAM misconfigured. + # Don't build it by default, even if the headers exist. + with_pam_default=no + ;; + *) + # Default to building PAM support on all other systems, if it exists. + with_pam_default=yes + ;; +esac + +have_pam=no +with_pam_req=unspecified + +AC_ARG_WITH(pam, +[ --with-pam Include support for PAM (Pluggable Auth Modules.)], + [with_pam="$withval"; with_pam_req="$withval"],[with_pam=$with_pam_default]) + +HANDLE_X_PATH_ARG(with_pam, --with-pam, PAM) + +if test "$enable_locking" = yes -a "$with_pam" = yes; then + AC_CACHE_CHECK([for PAM], ac_cv_pam, + [AC_TRY_X_COMPILE([#include ],, + [ac_cv_pam=yes], + [ac_cv_pam=no])]) + if test "$ac_cv_pam" = yes ; then + have_pam=yes + AC_DEFINE(HAVE_PAM) + PASSWD_LIBS="${PASSWD_LIBS} -lpam" + + # libpam typically requires dlopen and dlsym. On FreeBSD, + # those are in libc. On Linux and Solaris, they're in libdl. + AC_CHECK_LIB(dl, dlopen, [PASSWD_LIBS="${PASSWD_LIBS} -ldl"]) + + AC_MSG_CHECKING(how to call pam_strerror) + AC_CACHE_VAL(ac_cv_pam_strerror_args, + [AC_TRY_COMPILE([#include + #include + #include ], + [pam_handle_t *pamh = 0; + char *s = pam_strerror(pamh, PAM_SUCCESS);], + [ac_pam_strerror_args=2], + [AC_TRY_COMPILE([#include + #include + #include ], + [char *s = + pam_strerror(PAM_SUCCESS);], + [ac_pam_strerror_args=1], + [ac_pam_strerror_args=0])]) + ac_cv_pam_strerror_args=$ac_pam_strerror_args]) + ac_pam_strerror_args=$ac_cv_pam_strerror_args + if test "$ac_pam_strerror_args" = 1 ; then + AC_MSG_RESULT(one argument) + elif test "$ac_pam_strerror_args" = 2 ; then + AC_DEFINE(PAM_STRERROR_TWO_ARGS) + AC_MSG_RESULT(two arguments) + else + AC_MSG_RESULT(unknown) + fi + fi +fi + + +############################################################################### +# +# Check for Kerberos. +# +############################################################################### + +have_kerberos=no +with_kerberos_req=unspecified + +AC_ARG_WITH(kerberos, +[ --with-kerberos Include support for Kerberos authentication.], + [with_kerberos="$withval"; with_kerberos_req="$withval"],[with_kerberos=yes]) + +HANDLE_X_PATH_ARG(with_kerberos, --with-kerberos, Kerberos) + +if test "$enable_locking" = yes -a "$with_kerberos" = yes; then + AC_CACHE_CHECK([for Kerberos], ac_cv_kerberos, + [AC_TRY_X_COMPILE([#include ],, + [ac_cv_kerberos=yes], + [ac_cv_kerberos=no])]) + if test "$ac_cv_kerberos" = yes ; then + have_kerberos=yes + AC_DEFINE(HAVE_KERBEROS) + + # from Tim Showalter + PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes" + AC_CHECK_FUNC(res_search,, + AC_CHECK_LIB(resolv,res_search,PASSWD_LIBS="${PASSWD_LIBS} -lresolv", + AC_MSG_WARN([Can't find DNS resolver libraries needed for Kerberos]) + )) + + fi +fi + + +############################################################################### +# +# Check for the nine billion variants of shadow passwords... +# +############################################################################### + +need_setuid=no + +have_shadow=no +with_shadow_req=unspecified + +AC_ARG_WITH(shadow, +[ --with-shadow Include support for shadow password authentication.], + [with_shadow="$withval"; with_shadow_req="$withval"],[with_shadow=yes]) + +HANDLE_X_PATH_ARG(with_shadow, --with-shadow, shadow password) + +if test "$enable_locking" = no ; then + with_shadow_req=no + with_shadow=no +fi + + +############################################################################### +# +# Check for Sun "adjunct" passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for Sun-style shadow passwords], ac_cv_sun_adjunct, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include + #include ], + [struct passwd_adjunct *p = getpwanam("nobody"); + const char *pw = p->pwa_passwd;], + [ac_cv_sun_adjunct=yes], + [ac_cv_sun_adjunct=no])]) + if test "$ac_cv_sun_adjunct" = yes; then + have_shadow_adjunct=yes + have_shadow=yes + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for DEC and SCO so-called "enhanced" security. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for DEC-style shadow passwords], ac_cv_enhanced_passwd, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include + #include ], + [struct pr_passwd *p; + const char *pw; + set_auth_parameters(0, 0); + check_auth_parameters(); + p = getprpwnam("nobody"); + pw = p->ufld.fd_encrypt;], + [ac_cv_enhanced_passwd=yes], + [ac_cv_enhanced_passwd=no])]) + if test $ac_cv_enhanced_passwd = yes; then + have_shadow_enhanced=yes + have_shadow=yes + need_setuid=yes + + # On SCO, getprpwnam() is in -lprot (which uses nap() from -lx) + # (I'm told it needs -lcurses too, but I don't understand why.) + # But on DEC, it's in -lsecurity. + # + AC_CHECK_LIB(prot, getprpwnam, + [PASSWD_LIBS="$PASSWD_LIBS -lprot -lcurses -lx"], + [AC_CHECK_LIB(security, getprpwnam, + [PASSWD_LIBS="$PASSWD_LIBS -lsecurity"])], + [-lx]) + fi +fi + +############################################################################### +# +# Check for HP's entry in the "Not Invented Here" Sweepstakes. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for HP-style shadow passwords], ac_cv_hpux_passwd, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include + #include ], + [struct s_passwd *p = getspwnam("nobody"); + const char *pw = p->pw_passwd;], + [ac_cv_hpux_passwd=yes], + [ac_cv_hpux_passwd=no])]) + if test "$ac_cv_hpux_passwd" = yes; then + have_shadow_hpux=yes + have_shadow=yes + need_setuid=yes + + # on HPUX, bigcrypt is in -lsec + AC_CHECK_LIB(sec, bigcrypt, [PASSWD_LIBS="$PASSWD_LIBS -lsec"]) + fi +fi + + +############################################################################### +# +# Check for FreeBSD-style shadow passwords. +# +# On FreeBSD, getpwnam() and friends work just like on non-shadow- +# password systems -- except you only get stuff in the pw_passwd field +# if the running program is setuid. So, guess that we've got this +# lossage to contend with if /etc/master.passwd exists, and default to +# a setuid installation. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for FreeBSD-style shadow passwords], ac_cv_master_passwd, + [if test -f /etc/master.passwd ; then + ac_cv_master_passwd=yes + else + ac_cv_master_passwd=no + fi]) + if test "$ac_cv_master_passwd" = yes; then + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for traditional (ha!) shadow passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for generic shadow passwords], ac_cv_shadow, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include ], + [struct spwd *p = getspnam("nobody"); + const char *pw = p->sp_pwdp;], + [ac_cv_shadow=yes], + [ac_cv_shadow=no])]) + if test "$ac_cv_shadow" = yes; then + have_shadow=yes + need_setuid=yes + + # On some systems (UnixWare 2.1), getspnam() is in -lgen instead of -lc. + have_getspnam=no + AC_CHECK_LIB(c, getspnam, [have_getspnam=yes]) + if test "$have_getspnam" = no ; then + AC_CHECK_LIB(gen, getspnam, + [have_getspnam=yes; PASSWD_LIBS="$PASSWD_LIBS -lgen"]) + fi + fi +fi + + +############################################################################### +# +# Check for other libraries needed for non-shadow passwords. +# +############################################################################### + +if test "$enable_locking" = yes ; then + + # On some systems (UnixWare 2.1), crypt() is in -lcrypt instead of -lc. + have_crypt=no + AC_CHECK_LIB(c, crypt, [have_crypt=yes]) + if test "$have_crypt" = no ; then + AC_CHECK_LIB(crypt, crypt, + [have_crypt=yes; PASSWD_LIBS="$PASSWD_LIBS -lcrypt"]) + fi +fi + + +# Most of the above shadow mechanisms will have set need_setuid to yes, +# if they were found. But, on some systems, we need setuid even when +# using plain old vanilla passwords. +# +if test "$enable_locking" = yes ; then + case "$host" in + *-hpux* | *-aix* | *-netbsd* | *-freebsd* | *-openbsd* ) + need_setuid=yes + ;; + esac +fi + + +if test "$have_shadow_adjunct" = yes ; then + AC_DEFINE(HAVE_ADJUNCT_PASSWD) +elif test "$have_shadow_enhanced" = yes ; then + AC_DEFINE(HAVE_ENHANCED_PASSWD) +elif test "$have_shadow_hpux" = yes ; then + AC_DEFINE(HAVE_HPUX_PASSWD) +elif test "$have_shadow" = yes ; then + AC_DEFINE(HAVE_SHADOW_PASSWD) +fi + + +############################################################################### +# +# Check for -lXm. +# +############################################################################### + +have_motif=no +with_motif_req=unspecified +AC_ARG_WITH(motif,[ +User interface options: + + --with-motif Use the Motif toolkit for the user interface.], + [with_motif="$withval"; with_motif_req="$withval"],[with_motif=yes]) + +HANDLE_X_PATH_ARG(with_motif, --with-motif, Motif) + +if test "$with_motif" != yes -a "$with_motif" != no ; then + echo "error: must be yes or no: --with-motif=$with_motif" + exit 1 +fi + +if test "$with_motif" = yes; then + have_motif=no + AC_CHECK_X_HEADER(Xm/Xm.h, + [have_motif=yes + AC_DEFINE(HAVE_MOTIF) + MOTIF_LIBS="$MOTIF_LIBS -lXm"]) +fi + + +############################################################################### +# +# Check for -lgtk. +# +############################################################################### + +have_gtk=no +with_gtk_req=unspecified +AC_ARG_WITH(gtk, +[ --with-gtk Use the Gtk toolkit for the user interface.], + [with_gtk="$withval"; with_gtk_req="$withval"],[with_gtk=yes]) + +# if --with-gtk=/directory/ was specified, remember that directory so that +# we can also look for the `gtk-config' program in that directory. +case "$with_gtk" in + /*) + gtk_dir="$with_gtk" + ;; + *) + gtk_dir="" + ;; +esac + +HANDLE_X_PATH_ARG(with_gtk, --with-gtk, Gtk) + +if test "$with_gtk" != yes -a "$with_gtk" != no ; then + echo "error: must be yes or no: --with-gtk=$with_gtk" + exit 1 +fi + +jurassic_gtk=no +if test "$with_gtk" = yes; then + have_gtk=no + + # if the user specified --with-gtk=/foo/ then look in /foo/bin/ + # for glib-config and gtk-config. + # + gtk_path="$PATH" + + if test ! -z "$gtk_dir"; then + # canonicalize slashes. + gtk_dir=`echo "${gtk_dir}/bin" | sed 's@//*@/@g'` + gtk_path="$gtk_dir:$gtk_dir:$gtk_path" + fi + + AC_PATH_PROGS(glib_config, glib-config,, $gtk_path) + AC_PATH_PROGS(gtk_config, gtk-config,, $gtk_path) + + if test -n "$glib_config" -a -n "gtk_config" ; then + have_gtk=yes + fi + if test "$have_gtk" = yes; then + AC_CACHE_CHECK([Gtk version number], ac_cv_gtk_version_string, + [ac_cv_gtk_version_string=`$glib_config --version`]) + ac_gtk_version_string=$ac_cv_gtk_version_string + # M4 sucks!! + changequote(X,Y) + maj=`echo $ac_gtk_version_string | sed -n 's/\..*//p'` + min=`echo $ac_gtk_version_string | sed -n 's/[^.]*\.\([^.]*\).*/\1/p'` + changequote([,]) + ac_gtk_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_gtk_version"; then + ac_gtk_version=unknown + ac_gtk_version_string=unknown + fi + if test "$ac_gtk_version" = "unknown" || test "$ac_gtk_version" -lt 1002 + then + have_gtk=no + jurassic_gtk=yes + fi + fi + if test "$have_gtk" = yes; then + AC_CACHE_CHECK([for Gtk includes], ac_cv_gtk_config_cflags, + [ac_cv_gtk_config_cflags=`$gtk_config --cflags`]) + AC_CACHE_CHECK([for Gtk libs], ac_cv_gtk_config_libs, + [ac_cv_gtk_config_libs=`$gtk_config --libs`]) + INCLUDES="$INCLUDES $ac_cv_gtk_config_cflags" + GTK_LIBS="$GTK_LIBS $ac_cv_gtk_config_libs" + AC_DEFINE(HAVE_GTK) + fi +fi + + +############################################################################### +# +# Check for -lXaw and -lXaw3d. +# +############################################################################### + +have_athena=no +have_athena3d=no +with_athena_req=unspecified +AC_ARG_WITH(athena, +[ --with-athena Use the Athena toolkit for the user interface.], + [with_athena="$withval"; with_athena_req="$withval"],[with_athena=yes]) + +HANDLE_X_PATH_ARG(with_athena, --with-athena, Athena) + + +if test "$with_athena" != yes -a "$with_athena" != no ; then + echo "error: must be yes or no: --with-athena=$with_athena" + exit 1 +fi + + +if test "$with_athena" = yes; then + have_athena=no + AC_CHECK_X_HEADER(X11/Xaw/Dialog.h, [have_athena=yes]) + if test "$have_athena" = yes; then + AC_CHECK_X_LIB(Xaw3d, Xaw3dComputeTopShadowRGB, + [have_athena=yes; have_athena3d=yes], [true], + -lXt -lXmu -lXext -lX11) + fi +fi + +if test "$have_athena" = yes; then + AC_DEFINE(HAVE_ATHENA) + ATHENA_LIBS="-lXaw $ATHENA_LIBS" +fi + +if test "$have_athena3d" = yes; then + ATHENA3D_LIBS="-lXaw3d $ATHENA3D_LIBS" +fi + + +# If we have Athena, check whether it's a version that includes +# XawViewportSetCoordinates in Viewport.h (R3 (or R4?) don't.) +if test "$have_athena" = yes ; then + AC_CACHE_CHECK([for XawViewportSetCoordinates in Viewport.h], + ac_cv_have_XawViewportSetCoordinates, + [ac_cv_have_XawViewportSetCoordinates=no + AC_EGREP_X_HEADER(XawViewportSetCoordinates, + X11/Xaw/Viewport.h, + ac_cv_have_XawViewportSetCoordinates=yes)]) + if test "$ac_cv_have_XawViewportSetCoordinates" = yes ; then + AC_DEFINE(HAVE_XawViewportSetCoordinates) + fi +fi + + +############################################################################### +# +# Checking whether Motif is really Lesstif. +# +############################################################################### + +have_lesstif=no +if test "$have_motif" = yes ; then + AC_CACHE_CHECK([whether Motif is really LessTif], + ac_cv_have_lesstif, + [AC_TRY_X_COMPILE([#include ], + [long vers = LesstifVersion;], + [ac_cv_have_lesstif=yes], + [ac_cv_have_lesstif=no])]) + have_lesstif=$ac_cv_have_lesstif +fi + + +lesstif_version=unknown +lesstif_version_string=unknown + +if test "$have_lesstif" = yes ; then + ltv=unknown + echo unknown > conftest-lt + AC_CACHE_CHECK([LessTif version number], + ac_cv_lesstif_version_string, + [AC_TRY_X_RUN([#include + #include + int main() { + FILE *f = fopen("conftest-lt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", LesstifVersion, + LESSTIF_VERSION, LESSTIF_REVISION); + fclose(f); + exit(0); + }], + [ltv=`cat conftest-lt` + ac_cv_lesstif_version=`echo $ltv | sed 's/ .*//'` + ac_cv_lesstif_version_string=`echo $ltv | sed 's/.* //'`], + [ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown], + [ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown])]) + rm -f conftest-lt + lesstif_version=$ac_cv_lesstif_version + lesstif_version_string=$ac_cv_lesstif_version_string + +fi + + +if test "$have_motif" = yes ; then + mtv=unknown + echo unknown > conftest-mt + AC_CACHE_CHECK([Motif version number], + ac_cv_motif_version_string, + [AC_TRY_X_RUN([#include + #include + int main() { + FILE *f = fopen("conftest-mt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", XmVersion, + XmVERSION, XmREVISION); + fclose(f); + exit(0); + }], + [mtv=`cat conftest-mt` + ac_cv_motif_version=`echo $mtv | sed 's/ .*//'` + ac_cv_motif_version_string=`echo $mtv | sed 's/.* //'`], + [ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown], + [ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown])]) + rm -f conftest-mt + motif_version=$ac_cv_motif_version + motif_version_string=$ac_cv_motif_version_string + +fi + + +############################################################################### +# +# Checking whether Motif requires -lXpm. +# +# If this is Motif 2.x, and we have XPM, then link against XPM as well. +# The deal is, Motif 2.x requires XPM -- but it's a compilation option +# of the library whether to build the XPM code into libXm, or whether +# to rely on an external libXm. So the only way to tell whether XPM is +# a link-time requirement is to examine libXm.a, which is very +# difficult to do in an autoconf script. So... if it's Motif 2.x, we +# always link against XPM if the XPM lib exists (and this will be a +# no-op if libXm happens to already have the XPM code in it.) +# +############################################################################### + +motif_requires_xpm=no +if test "$have_motif" = yes ; then + AC_MSG_CHECKING(whether Motif requires XPM) + if test "$motif_version" = "unknown" || test "$motif_version" -ge 2000 + then + motif_requires_xpm=yes + AC_MSG_RESULT(maybe) + else + AC_MSG_RESULT(no) + fi +fi + + +############################################################################### +# +# Checking whether Motif requires -lXp. +# +# Some versions of Motif (2.1.0, at least) require -lXp, the "X Printing +# Extension". Why this extension isn't in -lXext with all the others, +# I have no idea. +# +############################################################################### + +have_xp_ext=no +if test "$have_motif" = yes ; then + have_xp_ext=no + AC_CHECK_X_LIB(Xp, XpQueryExtension, + [have_xp_ext=yes; MOTIF_LIBS="$MOTIF_LIBS -lXp"], + [true], -lX11 -lXext -lm) +fi + + +############################################################################### +# +# Checking whether Motif requires -lXintl (for _Xsetlocale.) +# +############################################################################### + +have_xintl=no +if test "$have_motif" = yes ; then + AC_CHECK_X_LIB(Xintl, _Xsetlocale, [have_xintl=yes], [have_xintl=no], + -lX11 -lXext -lm) + if test "$have_xintl" = yes; then + MOTIF_LIBS="$MOTIF_LIBS -lXintl" + fi +fi + + +############################################################################### +# +# Check for -lGL or -lMesa. +# +############################################################################### + +have_gl=no +ac_have_mesa_gl=no +with_gl_req=unspecified +AC_ARG_WITH(gl,[ +Graphics options: + + --with-gl Build those demos which depend on OpenGL.], + [with_gl="$withval"; with_gl_req="$withval"],[with_gl=yes]) + +HANDLE_X_PATH_ARG(with_gl, --with-gl, GL) + +ac_mesagl_version=unknown +ac_mesagl_version_string=unknown + +if test "$with_gl" = yes; then + AC_CHECK_X_HEADER(GL/gl.h, have_gl=yes, have_gl=no) + if test "$have_gl" = yes ; then + AC_CHECK_X_HEADER(GL/glx.h, have_gl=yes, have_gl=no) + fi + + # If we have the headers, try and figure out which vendor it's from. + # + if test "$have_gl" = yes ; then + + AC_DEFINE(HAVE_GL) + + # We need to know whether it's MesaGL so that we know which libraries + # to link against. + # + AC_CACHE_CHECK([whether GL is really MesaGL], ac_cv_have_mesa_gl, + [ac_cv_have_mesa_gl=no + AC_EGREP_X_HEADER(Mesa, GL/glx.h, [ac_cv_have_mesa_gl=yes]) + ]) + ac_have_mesa_gl=$ac_cv_have_mesa_gl + + if test "$ac_have_mesa_gl" = no ; then + gl_lib_1="GL" + GL_LIBS="-lGL -lGLU" + else + AC_DEFINE(HAVE_MESA_GL) + gl_lib_1="MesaGL" + GL_LIBS="-lMesaGL -lMesaGLU" + fi + + + # If it's MesaGL, we'd like to issue a warning if the version number + # is less than or equal to 2.6, because that version had a security bug. + # + if test "$ac_have_mesa_gl" = yes; then + + AC_CACHE_CHECK([MesaGL version number], ac_cv_mesagl_version_string, + [cat > conftest.$ac_ext < +configure: MESA_MAJOR_VERSION MESA_MINOR_VERSION +EOF + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + # M4 sucks!! + changequote(X,Y) + mglv=`(eval "$ac_cpp conftest.$ac_ext") 2>&AC_FD_CC | sed -n \ + 's/^configure:.*\([0-9][0-9]*\).*\([0-9][0-9]*\).*$/\1.\2/p'` + changequote([,]) + + rm -f conftest.$ac_ext + + CPPFLAGS="$ac_save_CPPFLAGS" + + if test "$mglv" = ""; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + else + ac_mesagl_version_string=$mglv + maj=`echo $mglv | sed -n 's/\..*//p'` + min=`echo $mglv | sed -n 's/.*\.//p'` + ac_mesagl_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_mesagl_version"; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + fi + fi + ac_cv_mesagl_version=$ac_mesagl_version + ac_cv_mesagl_version_string=$ac_mesagl_version_string + ]) + ac_mesagl_version=$ac_cv_mesagl_version + ac_mesagl_version_string=$ac_cv_mesagl_version_string + fi + + + # If it's MesaGL, check to see if it requires -lpthread. + # + have_pthread=no + mesa_requires_pthread=no + if test "$ac_have_mesa_gl" = yes; then + + AC_CHECK_LIB(pthread, pthread_create, [have_pthread=yes], [],) + if test "$have_pthread" = yes; then + AC_CHECK_X_LIB($gl_lib_1, gl_get_thread_context, + [mesa_requires_pthread=yes], [true], + $GL_LIBS -lpthread -lX11 -lXext -lm) + fi + + if test "$mesa_requires_pthread" = yes; then + GL_LIBS="$GL_LIBS -lpthread" + fi + fi + + # Check for OpenGL 1.1 features. + # + AC_CHECK_X_LIB($gl_lib_1, glBindTexture, [AC_DEFINE(HAVE_GLBINDTEXTURE)], + [true], $GL_LIBS -lX11 -lXext -lm) + + + # Check whether the `xscreensaver' executable should link against GL. + # See comments in utils/visual-gl.c for why this is sometimes necessary. + # + AC_MSG_CHECKING(whether drastic GL measures must be taken) + case "$host" in + *-sgi*) + AC_MSG_RESULT([yes -- hello, SGI.]) + AC_DEFINE(DAEMON_USE_GL) + SAVER_GL_SRCS='$(UTILS_SRC)/visual-gl.c' + SAVER_GL_OBJS='$(UTILS_BIN)/visual-gl.o' + SAVER_GL_LIBS="$GL_LIBS" + ;; + *) + AC_MSG_RESULT([no -- non-SGI.]) + SAVER_GL_SRCS='' + SAVER_GL_OBJS='' + SAVER_GL_LIBS='' + ;; + esac + + fi + +elif test "$with_gl" != no; then + echo "error: must be yes or no: --with-gl=$with_gl" + exit 1 +fi + + +############################################################################### +# +# Check for -lXpm. +# +############################################################################### + +have_xpm=no +with_xpm_req=unspecified +AC_ARG_WITH(xpm, +[ --with-xpm Include support for XPM files in some demos.], + [with_xpm="$withval"; with_xpm_req="$withval"],[with_xpm=yes]) + +HANDLE_X_PATH_ARG(with_xpm, --with-xpm, XPM) + +if test "$with_xpm" = yes; then + AC_CHECK_X_HEADER(X11/xpm.h, + [have_xpm=yes + AC_DEFINE(HAVE_XPM) + XPM_LIBS="-lXpm"]) +elif test "$with_xpm" != no; then + echo "error: must be yes or no: --with-xpm=$with_xpm" + exit 1 +fi + +# See comment near $motif_requires_xpm, above. +# Need to do this here, after both Motif and XPM have been checked for. +# +if test "$have_motif" = yes -a "$have_xpm" = yes ; then + if test "$motif_requires_xpm" = yes ; then + MOTIF_LIBS="$MOTIF_LIBS $XPM_LIBS" + fi +fi + + +############################################################################### +# +# Check for the XSHM server extension. +# +############################################################################### + +have_xshm=no +with_xshm_req=unspecified +AC_ARG_WITH(xshm-ext, +[ --with-xshm-ext Include support for the XSHM extension.], + [with_xshm="$withval"; with_xshm_req="$withval"],[with_xshm=yes]) + +HANDLE_X_PATH_ARG(with_xshm, --with-xshm-ext, XSHM) + +if test "$with_xshm" = yes; then + + # first check for Xshm.h. + AC_CHECK_X_HEADER(X11/extensions/XShm.h, [have_xshm=yes]) + + # if that succeeded, then check for sys/ipc.h. + if test "$have_xshm" = yes; then + have_xshm=no + AC_CHECK_X_HEADER(sys/ipc.h, [have_xshm=yes]) + fi + + # if that succeeded, then check for sys/shm.h. + if test "$have_xshm" = yes; then + have_xshm=no + 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. (This lib gets added to X_EXTRA_LIBS, and + # that's not quite right, but close enough.) + # + case "$host" in + *-aix*) + have_xshm=no + AC_CHECK_X_LIB(XextSam, XShmQueryExtension, + [have_xshm=yes; X_EXTRA_LIBS="$X_EXTRA_LIBS -lXextSam"], + [true], -lX11 -lXext -lm) + ;; + esac + + # if that succeeded, then we've really got it. + if test "$have_xshm" = yes; then + AC_DEFINE(HAVE_XSHM_EXTENSION) + fi + +elif test "$with_xshm" != no; then + echo "error: must be yes or no: --with-xshm-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the DOUBLE-BUFFER server extension. +# +############################################################################### + +have_xdbe=no +with_xdbe_req=unspecified +AC_ARG_WITH(xdbe-ext, +[ --with-xdbe-ext Include support for the DOUBLE-BUFFER extension.], + [with_xdbe="$withval"; with_xdbe_req="$withval"],[with_xdbe=yes]) + +HANDLE_X_PATH_ARG(with_xdbe, --with-xdbe-ext, DOUBLE-BUFFER) + +if test "$with_xdbe" = yes; then + + AC_CHECK_X_HEADER(X11/extensions/Xdbe.h, [have_xdbe=yes]) + if test "$have_xdbe" = yes; then + AC_DEFINE(HAVE_DOUBLE_BUFFER_EXTENSION) + fi + +elif test "$with_xdbe" != no; then + echo "error: must be yes or no: --with-xdbe-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI XReadDisplay server extension. +# +# Note: this has to be down here, rather than up with the other server +# extension tests, so that the output of `configure --help' is in the +# right order. Arrgh! +# +############################################################################### + +have_readdisplay=no +with_readdisplay_req=unspecified +AC_ARG_WITH(readdisplay, +[ --with-readdisplay Include support for the XReadDisplay extension.], + [with_readdisplay="$withval"; with_readdisplay_req="$withval"], + [with_readdisplay=yes]) + +HANDLE_X_PATH_ARG(with_readdisplay, --with-readdisplay, XReadDisplay) + +if test "$with_readdisplay" = yes; then + AC_CHECK_X_HEADER(X11/extensions/readdisplay.h, + AC_DEFINE(HAVE_READ_DISPLAY_EXTENSION)) +elif test "$with_readdisplay" != no; then + echo "error: must be yes or no: --with-readdisplay=$with_readdisplay" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI Iris Video Library. +# +############################################################################### + +have_sgivideo=no +with_sgivideo_req=unspecified +AC_ARG_WITH(sgivideo, +[ --with-sgivideo Include support for SGI's Iris Video Library.], + [with_sgivideo="$withval"; with_sgivideo_req="$withval"], + [with_sgivideo=yes]) + +HANDLE_X_PATH_ARG(with_sgivideo, --with-sgivideo, Iris Video) + +if test "$with_sgivideo" = yes; then + AC_CHECK_X_HEADER(dmedia/vl.h, have_sgivideo=yes) + if test "$have_sgivideo" = yes; then + have_sgivideo=no + AC_CHECK_LIB(vl, vlOpenVideo, [have_sgivideo=yes]) + if test "$have_sgivideo" = yes; then + SGI_VIDEO_OBJS="$(UTILS_BIN)/sgivideo.o" + SGI_VIDEO_LIBS="-lvl" + AC_DEFINE(HAVE_SGI_VIDEO) + fi + fi +elif test "$with_sgivideo" != no; then + echo "error: must be yes or no: --with-sgivideo=$with_sgivideo" + exit 1 +fi + + +############################################################################### +# +# Check for a program to generate random text. +# +# Zippy is funnier than the idiocy generally spat out by `fortune', +# so try to find that, by invoking Emacs and asking it where its +# libexec directory is ("yow" lives in there.) +# +# If that doesn't work, see if fortune, zippy, or yow are on $PATH, +# and if so, use them. +# +# If that doesn't work, look in /usr/games, and if it's there, use +# the full pathname. +# +############################################################################### + +with_zippy_req="" +AC_ARG_WITH(zippy,[ + --with-zippy=PROGRAM Some demos are able to run an external program and + display its text; this names the program to use by + default (though it can be overridden with X + resources.) If you don't specify this, the default + is to use \"yow\" from the Emacs distribution (if you + have it) or else to use \"fortune\". +], + [with_zippy_req="$withval"; with_zippy="$withval"],[with_zippy=yes]) + +if test "$with_zippy" = no || test "$with_zippy" = yes ; then + with_zippy="" + with_zippy_req="" +fi + +if test -n "$with_zippy_req" ; then + ac_cv_zippy_program="" + case "$with_zippy_req" in + /*) + AC_MSG_CHECKING([for $with_zippy_req]) + if test -x "$with_zippy_req" ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + with_zippy="" + fi + ;; + *) + # don't cache + unset ac_cv_path_zip2 + AC_PATH_PROG(zip2, $with_zippy_req, []) + if test "$zip2" = ""; then + with_zippy="" + fi + ;; + esac + ac_cv_zippy_program="$with_zippy" + +elif test -n "$ac_cv_zippy_program"; then + AC_MSG_RESULT([checking for zippy... (cached) $ac_cv_zippy_program]) +fi + +if test ! -n "$ac_cv_zippy_program"; then + + AC_CHECK_PROGS(emacs_exe, emacs) + AC_CHECK_PROGS(xemacs_exe, xemacs) + + ac_cv_zippy_program="" + eargs='-batch -q -nw --eval' + + if test -n "$emacs_exe" ; then + AC_MSG_CHECKING([for emacs yow]) + # + # get emacs to tell us where the libexec directory is. + # + dir=`$emacs_exe $eargs '(princ (concat exec-directory "\n"))' \ + 2>/dev/null | tail -1` + dir=`echo "$dir" | sed 's@///*@/@g;s@/$@@'` + # + # try running libexec/yow and see if it exits without error. + # + if test x"$dir" != x -a -x "$dir/yow" ; then + if $dir/yow >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow" + AC_MSG_RESULT($ac_cv_zippy_program) + else + AC_MSG_RESULT(no) + fi + fi + fi + + if test -z "$ac_cv_zippy_program" ; then + AC_MSG_CHECKING([for xemacs yow]) + if test -n "$xemacs_exe" ; then + # + # get xemacs to tell us where the libexec directory is. + # + dir=`$xemacs_exe $eargs '(princ (concat exec-directory "\n"))' \ + 2>/dev/null | tail -1` + dir=`echo "$dir" | sed 's@///*@/@g;s@/$@@'` + # + # try running libexec/yow and see if it exits without error. + # + if test x"$dir" != x -a -x "$dir/yow" ; then + if $dir/yow >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow" + AC_MSG_RESULT($ac_cv_zippy_program) + else + # + # in some xemacs installations, the pathname of the yow.lines file + # isn't hardcoded into the yow executable, and must be passed on + # the command line. See if it's in libexec/../etc/. + + # M4 sucks!! + changequote(X,Y) + dir_up=`echo "$dir" | sed 's@/[^/]*$@@'` + changequote([,]) + + yowlines="$dir_up/etc/yow.lines" + if $dir/yow -f $yowlines >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow -f $yowlines" + AC_MSG_RESULT($ac_cv_zippy_program) + else + # + # In newer XEmacs releases, yow.lines is in a different place, + # and the easiest way to get it is by calling the new function + # `locate-data-file'. + # + yowlines=`$xemacs_exe $eargs \ + '(princ (concat (locate-data-file "yow.lines") "\n"))' \ + 2>/dev/null | tail -1` + if $dir/yow -f $yowlines >&- 2>&- ; then + ac_cv_zippy_program="$dir/yow -f $yowlines" + AC_MSG_RESULT($ac_cv_zippy_program) + else + AC_MSG_RESULT(no) + fi + fi + fi + fi + fi + fi + + # if that didn't work, try for some other programs... + if test -z "$ac_cv_zippy_program" ; then + fortune='' + AC_CHECK_PROGS(fortune, [fortune zippy yow]) + # if that didn't work, try for those programs in /usr/games... + if test -z "$fortune" ; then + AC_PATH_PROGS(fortune, [fortune zippy yow], fortune, + /usr/games:/usr/local/games:$PATH) + fi + fi +fi + +if test -z "$ac_cv_zippy_program" ; then + ac_cv_zippy_program=fortune +fi + +AC_DEFINE_UNQUOTED(ZIPPY_PROGRAM, "$ac_cv_zippy_program") + + +############################################################################### +# +# Done testing. Now, set up the various -I and -L variables, +# and decide which GUI program to build by default. +# +############################################################################### + +DEPEND=makedepend +DEPEND_FLAGS= +DEPEND_DEFINES= + + +if test \! -z "$includedir" ; then + INCLUDES="$INCLUDES -I$includedir" +fi + +if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" +fi + + +ALL_DEMO_PROGRAMS= +if test "$have_athena3d" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Xaw3d + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi +if test "$have_athena" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Xaw + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi +if test "$have_gtk" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Gtk + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi +if test "$have_motif" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Xm + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi + + +if test "$have_kerberos" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(KERBEROS_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(KERBEROS_OBJS)" +fi +if test "$have_pam" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(PAM_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PAM_OBJS)" + INSTALL_PAM="install-pam" +fi + PASSWD_SRCS="$PASSWD_SRCS \$(PWENT_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PWENT_OBJS)" + + +if test "$enable_locking" = yes; then + LOCK_SRCS='$(LOCK_SRCS_1) $(PASSWD_SRCS)' + LOCK_OBJS='$(LOCK_OBJS_1) $(PASSWD_OBJS)' +else + LOCK_SRCS='' + LOCK_OBJS='' +fi + +if test "$need_setuid" = yes; then + NEED_SETUID=yes + INSTALL_SETUID='$(INSTALL) $(SUID_FLAGS)' +else + NEED_SETUID=no + INSTALL_SETUID='$(INSTALL_PROGRAM)' +fi + +tab=' ' +if test "$have_gl" = yes; then + GL_EXES='$(GL_EXES)' + GL_MEN='$(GL_MEN)' + GL_KLUDGE="${tab} " +else + GL_KLUDGE=" -${tab} " +fi + + +############################################################################### +# +# Perform substitutions and write Makefiles. +# +############################################################################### + +AC_SUBST(INCLUDES) + +AC_SUBST(PREFERRED_DEMO_PROGRAM) +AC_SUBST(ALL_DEMO_PROGRAMS) +AC_SUBST(SAVER_LIBS) +AC_SUBST(MOTIF_LIBS) +AC_SUBST(GTK_LIBS) +AC_SUBST(ATHENA_LIBS) +AC_SUBST(ATHENA3D_LIBS) +AC_SUBST(HACK_LIBS) +AC_SUBST(XPM_LIBS) +AC_SUBST(GL_LIBS) +AC_SUBST(PASSWD_LIBS) +AC_SUBST(INSTALL_SETUID) +AC_SUBST(INSTALL_DIRS) +AC_SUBST(NEED_SETUID) +AC_SUBST(INSTALL_PAM) +AC_SUBST(SGI_VIDEO_OBJS) +AC_SUBST(SGI_VIDEO_LIBS) + +AC_SUBST(PASSWD_SRCS) +AC_SUBST(PASSWD_OBJS) +AC_SUBST(XMU_SRCS) +AC_SUBST(XMU_OBJS) +AC_SUBST(SAVER_GL_SRCS) +AC_SUBST(SAVER_GL_OBJS) +AC_SUBST(SAVER_GL_LIBS) +AC_SUBST(LOCK_SRCS) +AC_SUBST(LOCK_OBJS) +AC_SUBST(GL_EXES) +AC_SUBST(GL_MEN) +AC_SUBST(GL_KLUDGE) +AC_SUBST(HACKDIR) + +APPDEFAULTS=$ac_x_app_defaults +AC_SUBST(APPDEFAULTS) + +AC_SUBST(DEPEND) +AC_SUBST(DEPEND_FLAGS) +AC_SUBST(DEPEND_DEFINES) +AC_SUBST(PERL) + +AC_OUTPUT(Makefile + utils/Makefile + driver/Makefile + hacks/Makefile + hacks/glx/Makefile + driver/XScreenSaver.ad) + +############################################################################### +# +# Print some warnings at the end. +# +############################################################################### + +warn_prefix_1=" Warning:" +warn_prefix_2=" Note:" +warn_prefix="$warn_prefix_1" + +warning=no +warnsep=' #################################################################' + +warnpre() { + if test "$warning" = no ; then + echo '' ; echo "$warnsep" ; echo '' + warning=yes + fi +} + +warn() { + warnpre + if test "$warning" = long ; then echo '' ; fi + warning=yes + echo "$warn_prefix $@" +} + +warnL() { + was=$warning + warnpre + warning=yes + if test "$was" != no ; then echo '' ; fi + echo "$warn_prefix $@" +} + +warn2() { + echo " $@" + warning=long +} + +note() { + warn_prefix="$warn_prefix_2" + warn $@ + warn_prefix="$warn_prefix_1" +} + +noteL() { + warn_prefix="$warn_prefix_2" + warnL $@ + warn_prefix="$warn_prefix_1" +} + + +if test "$with_sgi_req" = yes -a "$have_sgi" = no ; then + warn 'The SGI saver extension was requested, but was not found.' +fi + +if test "$with_mit_req" = yes -a "$have_mit" = no ; then + warn 'The MIT saver extension was requested, but was not found.' +fi + +if test "$with_xidle_req" = yes -a "$have_xidle" = no ; then + warn 'The XIdle extension was requested, but was not found.' +fi + +if test "$with_xshm_req" = yes -a "$have_xshm" = no ; then + warn 'The XSHM extension was requested, but was not found.' +fi + +if test "$with_xdbe_req" = yes -a "$have_xdbe" = no ; then + warn 'The DOUBLE-BUFFER extension was requested, but was not found.' +fi + +if test "$with_sgivc_req" = yes -a "$have_sgivc" = no ; then + warn 'The SGI-VIDEO-CONTROL extension was requested, but was not found.' +fi + +if test "$with_dpms_req" = yes -a "$have_dpms" = no ; then + warn 'The DPMS extension was requested, but was not found.' +fi + +if test "$with_xf86vmode_req" = yes -a "$have_xf86vmode" = no ; then + warn 'The XF86VMODE extension was requested, but was not found.' +fi + +if test "$with_proc_interrupts_req" = yes -a "$have_proc_interrupts" = no; then + warn "Checking of /proc/interrupts was requested, but it's bogus." +fi + + +if test "$have_motif" = no -a "$have_gtk" = no -a "$have_athena" = no ; then + warnL "None of Motif, Gtk, or Athena widgets seem to be available;" + warn2 "the \`xscreensaver-demo' program requires one of these." + +elif test "$with_motif_req" = yes -a "$have_motif" = no ; then + warnL "Use of Motif was requested, but it wasn't found;" + if test "$have_gtk" = yes; then + warn2 "Gtk will be used instead." + else + warn2 "Athena will be used instead." + fi + +elif test "$jurassic_gtk" = yes ; then + + pref_gtk=1.2 + + v="$ac_gtk_version_string" + if test "$with_gtk_req" = yes -a "$ac_gtk_version" = "unknown" ; then + warnL "Use of Gtk was requested, but its version number is unknown;" + elif test "$with_gtk_req" = yes ; then + warnL "Use of Gtk was requested, but it is version $v;" + else + warnL "Gtk was found on this system, but it is version $v;" + fi + + if test "$have_motif" = yes; then + which="Motif" + else + which="Athena" + fi + + warn2 "Gtk $pref_gtk or newer is required. $which will be used instead." + +elif test "$with_gtk_req" = yes -a "$have_gtk" = no ; then + warnL "Use of Gtk was requested, but it wasn't found;" + if test "$have_motif" = yes; then + warn2 "Motif will be used instead." + else + warn2 "Athena will be used instead." + fi + +elif test "$with_athena_req" = yes -a "$have_athena" = no ; then + warnL "Use of Athena was requested, but it wasn't found;" + if test "$have_gtk" = yes; then + warn2 "Gtk will be used instead." + else + warn2 "Motif will be used instead." + fi +fi + + +if test "$have_motif" = yes -a "$have_lesstif" = yes ; then + + preferred_lesstif=0.86 + + if test "$lesstif_version" = unknown; then + warnL "Unable to determine the LessTif version number!" + warn2 "Make sure you are using version $preferred_lesstif or newer." + warn2 "See ." + + elif test \! $lesstif_version -gt 82; then + warnL "LessTif version $lesstif_version_string is being used." + warn2 "LessTif versions 0.82 and earlier are too buggy to" + warn2 "use with XScreenSaver; it is strongly recommended" + warn2 "that you upgrade to at least version $preferred_lesstif!" + warn2 "See ." + fi +fi + +if test "$have_athena" = yes -a "$have_motif" = no -a "$have_gtk" = no; then + warnL "Athena widgets are being used instead of Motif or Gtk." + warn2 "The \`xscreensaver-demo' program looks much better" + warn2 "with Motif or Gtk. Wouldn't you rather be using Motif?" + warn2 "Motif is shipped by every commercial Unix vendor," + warn2 "and there is a free implementation available as" + warn2 "well: see . Gtk is shipped" + warn2 "with most Linux and BSD distributions." +fi + + +if test "$have_xpm" = no ; then + if test "$with_xpm_req" = yes ; then + warnL 'Use of XPM was requested, but it was not found.' + elif test "$with_xpm_req" = no ; then + noteL 'The XPM library is not being used.' + else + noteL 'The XPM library was not found.' + fi + + echo '' + warn2 'Some of the demos will not be as colorful as they' + warn2 'could be. You might want to consider installing XPM' + warn2 'and re-running configure. (Remember to delete the' + warn2 'config.cache file first.) You can find XPM at most' + warn2 'X11 archive sites, such as .' +fi + + +if test "$have_gl" = yes -a "$ac_have_mesa_gl" = yes ; then + preferred_mesagl=3.0 + + if test "$ac_mesagl_version" = unknown; then + warnL "Unable to determine the MesaGL version number!" + warn2 "Make sure you are using version $preferred_mesagl or newer." + + elif test \! "$ac_mesagl_version" -gt 2006; then + warnL "MesaGL version $ac_mesagl_version_string is being used." + warn2 "MesaGL versions 2.6 and earlier have a security bug." + warn2 "It is strongly recommended that you upgrade to at" + warn2 "least version $preferred_mesagl." + fi +fi + + +if test "$have_gl" = no ; then + if test "$with_gl_req" = yes ; then + warnL 'Use of GL was requested, but it was not found.' + elif test "$with_gl_req" = no ; then + noteL 'The OpenGL 3D library is not being used.' + else + noteL 'The OpenGL 3D library was not found.' + fi + + echo '' + warn2 'Those demos which use 3D will not be built or installed.' + warn2 'You might want to consider installing OpenGL and' + warn2 're-running configure. (Remember to delete the' + warn2 "config.cache file first.) If your vendor doesn't ship" + warn2 'their own implementation of OpenGL, you can get a free' + warn2 'version at . For general OpenGL' + warn2 'info, see .' + +fi + +if test "$with_readdisplay_req" = yes -a "$have_readdisplay" = no ; then + warn 'Use of XReadDisplay was requested, but it was not found.' +fi + +if test "$with_sgivideo_req" = yes -a "$have_sgivideo" = no ; then + warn 'Use of the Iris Video Library was requested, but it was not found.' +fi + +if test -n "$with_zippy_req"; then + if test "$with_zippy_req" != "$ac_cv_zippy_program" ; then + warnL "$with_zippy_req was requested as the Zippy program," + warn2 "but was not found. The default will be used instead." + fi +fi + +if test "$with_kerberos_req" = yes -a "$have_kerberos" = no ; then + warn 'Use of Kerberos was requested, but it was not found.' +fi + +if test "$with_pam_req" = yes -a "$have_pam" = no ; then + warn 'Use of PAM was requested, but it was not found.' +fi + +if test "$with_shadow_req" = yes -a "$have_shadow" = no ; then + warn 'Use of shadow passwords was requested, but they were not found.' +fi + + +# You are in a twisty maze of namespaces and syntaxes, all alike. +# Fuck the skull of Unix. +# +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval bindir=${bindir} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} +eval HACKDIR=${HACKDIR} + +# canonicalize slashes. +bindir=`echo "${bindir}" | sed 's@/$@@;s@//*@/@g'` +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` + + +# Sanity check the subdir +for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command ; do + if test "${HACKDIR}" = "${bindir}/${bad_choice}" ; then + echo "" + AC_MSG_ERROR([\"--enable-subdir=${bindir}/${bad_choice}\" won't work. + There will be an executable installed with that name, so + that can't be the name of a directory as well. Please + re-configure with a different directory name.]) + fi +done + + +do_dir_warning=no + +# Now let's see if there's a previous RPM version already installed. Blargh! + +# M4 sucks!! +changequote(X,Y) +rpmv=`(rpm -qv xscreensaver) 2>&- | \ + sed 's/^xscreensaver-\([0-9][0-9]*[.][0-9][0-9]*\)-[0-9][0-9]*$/\1/'` +changequote([,]) + +if test \! -z "$rpmv" ; then + rpmbdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/xscreensaver-demo$@\1@p'` + rpmhdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/attraction$@\1@p'` + + warning=no + warnL "There is already an installed RPM of xscreensaver $rpmv" + warn2 "on this system. You might want to remove it (with" + warn2 '"rpm -ve xscreensaver") before running "make install"' + warn2 "from this directory." + echo "" + warn2 "Alternately, you could build this version of xscreensaver" + warn2 'as an RPM, and then install that. An "xscreensaver.spec"' + warn2 "file is included. See the RPM documentation for more info." + echo "" + + if test "$rpmbdir" = "$rpmhdir" ; then + warn2 "The RPM version was installed in $rpmbdir." + else + warn2 "The RPM version was installed in $rpmbdir," + warn2 "with demos in $rpmhdir." + fi + + do_dir_warning=yes +fi + + +# Warn about egregious GNOME bogosity. +# +if (rpm -qv control-center) >&- 2>&- ; then + warning=no + warnL "The Gnome Control Center seems to be installed." + echo "" + warn2 "Note that simply installing this version of xscreensaver" + warn2 "will not cause GNOME to know about the newly-added display" + warn2 "modes -- GNOME is just lame that way. Instead of using the" + warn2 "Control Center, try using the \`xscreensaver-demo' command." +fi + + +if test "${bindir}" = "${HACKDIR}" ; then + do_dir_warning=yes +fi + +if test "$do_dir_warning" = yes; then + echo "" + echo "$warnsep" + echo "" + echo ' When you run "make install", the "xscreensaver",' + echo ' "xscreensaver-demo", and "xscreensaver-command" executables' + echo " will be installed in ${bindir}." + echo "" + echo " The various graphics demos (90+ different executables) will" + echo " also be installed in ${HACKDIR}." + echo "" + echo " If you would prefer the demos to be installed elsewhere" + echo " (for example, in a dedicated directory) you should re-run" + echo " configure with the --enable-subdir=DIR option. For more" + echo " information, run $0 --help." + warning=yes +fi + +if test "$warning" != no; then + echo '' ; echo "$warnsep" ; echo '' +fi diff --git a/driver/.gdbinit b/driver/.gdbinit new file mode 100644 index 00000000..cb7d98ab --- /dev/null +++ b/driver/.gdbinit @@ -0,0 +1,25 @@ +# If you're debugging xscreensaver and you are running a virtual root window +# manager, you'd better let the process handle these signals: it remaps the +# virtual root window when they arrive. If you don't do this, your window +# manager will be hosed. +# +# Also, gdb copes badly with breakpoints in functions that are called on the +# other side of a fork(). The Trace/BPT traps cause the spawned process to +# die. +# +#handle 1 pass nostop +#handle 3 pass nostop +#handle 4 pass nostop +#handle 6 pass nostop +#handle 7 pass nostop +#handle 8 pass nostop +#handle 9 pass nostop +#handle 10 pass nostop +#handle 11 pass nostop +#handle 12 pass nostop +#handle 13 pass nostop +#handle 15 pass nostop +#handle 19 pass nostop +b exit +set args -debug +#b purify_stop_here diff --git a/driver/Makefile.in b/driver/Makefile.in new file mode 100644 index 00000000..318ec69e --- /dev/null +++ b/driver/Makefile.in @@ -0,0 +1,576 @@ +# driver/Makefile.in --- xscreensaver, Copyright (c) 1997 Jamie Zawinski. +# the `../configure' script generates `driver/Makefile' from this file. + +@SET_MAKE@ +.SUFFIXES: +.SUFFIXES: .c .o + +srcdir = @srcdir@ +VPATH = @srcdir@ + +install_prefix = +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +mansuffix = 1 + +CC = @CC@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +DEFS = @DEFS@ +DEFS2 = $(DEFS) -DDEFAULT_PATH_PREFIX='"@HACKDIR@"' +LIBS = @LIBS@ + +DEPEND = @DEPEND@ +DEPEND_FLAGS = @DEPEND_FLAGS@ +DEPEND_DEFINES = @DEPEND_DEFINES@ + +SHELL = /bin/sh +INSTALL = @INSTALL@ +SUID_FLAGS = -o root -m 4755 +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SETUID = @INSTALL_SETUID@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_DIRS = @INSTALL_DIRS@ + +X_CFLAGS = @X_CFLAGS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ + +# Note: +# +# X_LIBS would more properly be called X_LDFLAGS (it contains the -L args.) +# X_PRE_LIBS contains extra libraries you have to link against on some systems, +# and that must come before -lX11. (e.g., -lSM and -lICE.) +# X_EXTRA_LIBS contains extra libraries needed by X that aren't a part of X. +# (e.g., -lsocket, -lnsl, etc.) +# +# I think (but am not totally sure) that LIBS is also really "LDFLAGS". +# +# SAVER_LIBS is the link line for "xscreensaver", and +# CMD_LIBS is the link line for "xscreensaver-command". + + +AD_DIR = @APPDEFAULTS@ +PAM_DIR = /etc/pam.d +PAM_CONF = /etc/pam.conf + +UTILS_SRC = $(srcdir)/../utils +UTILS_BIN = ../utils + +INCLUDES = -I. -I$(srcdir) -I$(UTILS_SRC) -I.. @INCLUDES@ + +MOTIF_SRCS = dialogs-Xm.c +MOTIF_OBJS = dialogs-Xm.o + +GTK_SRCS = dialogs-Gtk.c +GTK_OBJS = dialogs-Gtk.o + +ATHENA_SRCS = dialogs-Xaw.c +ATHENA_OBJS = dialogs-Xaw.o + +PWENT_SRCS = passwd-pwent.c +PWENT_OBJS = passwd-pwent.o + +KERBEROS_SRCS = passwd-kerberos.c +KERBEROS_OBJS = passwd-kerberos.o + +PAM_SRCS = passwd-pam.c +PAM_OBJS = passwd-pam.o + +LOCK_SRCS_1 = lock.c passwd.c +LOCK_OBJS_1 = lock.o passwd.o + +TEST_SRCS = test-passwd.c test-uid.c test-xdpms.c test-grab.c test-apm.c + +MOTIF_LIBS = @MOTIF_LIBS@ +GTK_LIBS = @GTK_LIBS@ +ATHENA_LIBS = @ATHENA_LIBS@ +ATHENA3D_LIBS = @ATHENA3D_LIBS@ + +PASSWD_SRCS = @PASSWD_SRCS@ +PASSWD_OBJS = @PASSWD_OBJS@ +PASSWD_LIBS = @PASSWD_LIBS@ + +LOCK_SRCS = @LOCK_SRCS@ +LOCK_OBJS = @LOCK_OBJS@ + +XMU_SRCS = @XMU_SRCS@ +XMU_OBJS = @XMU_OBJS@ + +GL_SRCS = @SAVER_GL_SRCS@ +GL_OBJS = @SAVER_GL_OBJS@ +GL_LIBS = @SAVER_GL_LIBS@ + +DEMO_UTIL_SRCS = $(UTILS_SRC)/resources.c $(UTILS_SRC)/usleep.c \ + $(UTILS_SRC)/visual.c +DEMO_UTIL_OBJS = $(UTILS_BIN)/resources.o $(UTILS_BIN)/usleep.o \ + $(UTILS_BIN)/visual.o + +SAVER_UTIL_SRCS = $(UTILS_SRC)/fade.c $(UTILS_SRC)/overlay.c \ + $(UTILS_SRC)/xroger.c $(UTILS_SRC)/spline.c \ + $(UTILS_SRC)/yarandom.c \ + $(DEMO_UTIL_SRCS) +SAVER_UTIL_OBJS = $(UTILS_BIN)/fade.o $(UTILS_BIN)/overlay.o \ + $(UTILS_BIN)/xroger.o $(UTILS_BIN)/spline.o \ + $(UTILS_BIN)/yarandom.o \ + $(DEMO_UTIL_OBJS) + +SAVER_SRCS_1 = xscreensaver.c windows.c timers.c subprocs.c \ + xset.c splash.c setuid.c stderr.c +SAVER_OBJS_1 = xscreensaver.o windows.o timers.o subprocs.o \ + xset.o splash.o setuid.o stderr.o + +SAVER_SRCS = $(SAVER_SRCS_1) prefs.c $(LOCK_SRCS) \ + $(SAVER_UTIL_SRCS) $(GL_SRCS) $(XMU_SRCS) +SAVER_OBJS = $(SAVER_OBJS_1) prefs.o $(LOCK_OBJS) \ + $(SAVER_UTIL_OBJS) $(GL_OBJS) $(XMU_OBJS) + +CMD_SRCS = remote.c xscreensaver-command.c +CMD_OBJS = remote.o xscreensaver-command.o + +DEMO_SRCS_1 = prefs.c demo.c $(XMU_SRCS) +DEMO_OBJS_1 = prefs.o demo-Xm.o demo-Gtk.o demo-Xaw.o $(XMU_OBJS) + +DEMO_SRCS = prefs.c remote.c $(DEMO_UTIL_SRCS) demo.c +DEMO_OBJS = prefs.o remote.o $(DEMO_UTIL_OBJS) + +SAVER_LIBS = $(LIBS) $(X_LIBS) @SAVER_LIBS@ $(GL_LIBS) \ + $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) \ + $(PASSWD_LIBS) + +CMD_LIBS = $(LIBS) $(X_LIBS) \ + $(X_PRE_LIBS) -lX11 -lXext $(X_EXTRA_LIBS) + +EXES = xscreensaver xscreensaver-command xscreensaver-demo +EXES2 = @ALL_DEMO_PROGRAMS@ + +HDRS = XScreenSaver_ad.h xscreensaver.h prefs.h remote.h +MEN = xscreensaver.man xscreensaver-demo.man \ + xscreensaver-command.man +EXTRAS = README Makefile.in XScreenSaver.ad.in xscreensaver.pam \ + .gdbinit +VMSFILES = compile_axp.com compile_decc.com link_axp.com link_decc.com \ + vms-getpwnam.c vms-pwd.h vms-hpwd.c vms-validate.c \ + vms_axp.opt vms_axp_12.opt vms_decc.opt vms_decc_12.opt + +TARFILES = $(EXTRAS) $(VMSFILES) $(SAVER_SRCS_1) \ + $(MOTIF_SRCS) $(GTK_SRCS) $(ATHENA_SRCS) $(PWENT_SRCS) \ + $(KERBEROS_SRCS) $(PAM_SRCS) $(LOCK_SRCS_1) $(DEMO_SRCS_1) \ + $(CMD_SRCS) $(HDRS) $(TEST_SRCS) $(MEN) + + +default: $(EXES) +all: $(EXES) $(EXES2) + +install: install-program install-ad install-man @INSTALL_PAM@ +uninstall: uninstall-program uninstall-ad uninstall-man + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \ + INSTALL_SETUID='$(INSTALL_SETUID) -s' \ + install + +install-program: $(EXES) + @if [ ! -d $(bindir) ]; then $(INSTALL_DIRS) $(bindir) ; fi + @inst="$(INSTALL_PROGRAM)" ; \ + if [ @NEED_SETUID@ = yes ]; then \ + me=`PATH="$$PATH:/usr/ucb" whoami` ; \ + if [ "$$me" = root ]; then \ + inst="$(INSTALL_SETUID)" ; \ + else \ + e=echo ; \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: xscreensaver has been compiled with support for shadow" ;\ + $$e " passwords. If your system actually uses shadow passwords," ;\ + $$e " then xscreensaver must be installed as a setuid root" ;\ + $$e " program in order for locking to work. To do this, you" ;\ + $$e " must run 'make install' as 'root', not as '$$me'." ;\ + $$e "" ;\ + $$e " For now, xscreensaver will be installed non-setuid, which" ;\ + $$e " means that locking might not work. (Try it and see.)" ;\ + $$e " ####################################################################";\ + $$e "" ;\ + fi ; \ + fi ; \ + echo $$inst xscreensaver $(bindir)/xscreensaver ; \ + $$inst xscreensaver $(bindir)/xscreensaver + $(INSTALL_PROGRAM) xscreensaver-command $(bindir)/xscreensaver-command + $(INSTALL_PROGRAM) xscreensaver-demo $(bindir)/xscreensaver-demo + +install-ad: XScreenSaver.ad + @if [ ! -d $(AD_DIR) ]; then $(INSTALL_DIRS) $(AD_DIR) ; fi + @-echo $(INSTALL_DATA) XScreenSaver.ad $(AD_DIR)/XScreenSaver ; \ + if $(INSTALL_DATA) XScreenSaver.ad $(AD_DIR)/XScreenSaver ; then \ + true ; \ + else \ + e=echo ; \ + if [ -f $(AD_DIR)/XScreenSaver ]; then \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: unable to install $(AD_DIR)/XScreenSaver" ;\ + $$e " That file exists, and is unwritable. It is probably from" ;\ + $$e " an older version of xscreensaver, and could cause things" ;\ + $$e " to malfunction. Please delete it!" ;\ + $$e " ####################################################################";\ + $$e "" ;\ + exit 1 ; \ + else \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: unable to install $(AD_DIR)/XScreenSaver" ;\ + $$e " The directory is unwritable. This is probably ok;" ;\ + $$e " xscreensaver should work without that file." ;\ + $$e " ####################################################################";\ + $$e "" ;\ + exit 0 ; \ + fi \ + fi + +install-man: $(MEN) + @men="$(MEN)" ; \ + if [ ! -d $(man1dir) ]; then $(INSTALL_DIRS) $(man1dir) ; fi ; \ + for man in $$men; do \ + instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ; \ + echo $(INSTALL_DATA) $(srcdir)/$$man $(man1dir)/$$instname ; \ + $(INSTALL_DATA) $(srcdir)/$$man $(man1dir)/$$instname ; \ + done + +uninstall-program: + @for program in $(EXES); do \ + echo rm -f $(bindir)/$$program ; \ + rm -f $(bindir)/$$program ; \ + done + +uninstall-ad: + rm -f $(AD_DIR)/XScreenSaver + +uninstall-man: + @men="$(MEN)" ; \ + for man in $$men; do \ + instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ; \ + echo rm -f $(man1dir)/$$instname ; \ + rm -f $(man1dir)/$$instname ; \ + done + +install-pam: + @src="$(srcdir)/xscreensaver.pam" ; \ + dest=`sed -n 's/.*PAM_SERVICE_NAME[ ]*"\([^"]*\)".*$$/\1/p' \ + < ../config.h` ; \ + dir="$(PAM_DIR)" ; \ + conf="$(PAM_CONF)" ; \ + \ + if [ -d $$dir ] ; then \ + echo $(INSTALL_DATA) $$src $$dir/$$dest ; \ + $(INSTALL_DATA) $$src $$dir/$$dest ; \ + if [ ! -f $$dir/$$dest ]; then \ + e=echo ; \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: xscreensaver has been compiled with support for Pluggable" ;\ + $$e " Authentication Modules (PAM). However, we were unable to" ;\ + $$e " install the file $$dir/$$dest. PAM is unlikely" ;\ + $$e " to work without this file (and old-style password" ;\ + $$e " authentication will be used instead, which may or may not" ;\ + $$e " work.)" ;\ + $$e " ####################################################################";\ + $$e "" ;\ + fi ; \ + elif [ -f $$conf ]; then \ + if ( grep $$dest $$conf >/dev/null ); then \ + true ; \ + else \ + e=echo ; \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: xscreensaver has been compiled with support for Pluggable" ;\ + $$e " Authentication Modules (PAM). To complete the installation";\ + $$e " of PAM support, you must add the following line to the file";\ + $$e " $$conf:" ;\ + $$e "" ;\ + $$e " $$dest auth required /usr/lib/security/pam_unix.so.1" ;\ + $$e "" ;\ + $$e " Be careful: if you mess up that file, you could completely" ;\ + $$e " hose your machine (e.g., \`login' and \`su' won't work, and";\ + $$e " you'll have to boot single-user to fix it.)" ;\ + $$e " ####################################################################";\ + echo ""; \ + fi ; \ + fi + + +clean: + -rm -f *.o a.out core $(EXES) $(EXES2) XScreenSaver_ad.h + +distclean: clean + -rm -f Makefile XScreenSaver.ad TAGS *~ "#"* + +# Adds all current dependencies to Makefile +depend: XScreenSaver_ad.h + $(DEPEND) -s '# DO NOT DELETE: updated by make depend' \ + $(DEPEND_FLAGS) -- \ + $(INCLUDES) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \ + $(SAVER_SRCS) $(CMD_SRCS) + +# Adds some dependencies to Makefile.in -- not totally accurate, but pretty +# 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 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) -- \ + $(INCLUDES) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \ + $(SAVER_SRCS_1) $(MOTIF_SRCS) $(GTK_SRCS) $(ATHENA_SRCS) \ + $(PWENT_SRCS) $(LOCK_SRCS_1) $(DEMO_SRCS_1) $(CMD_SRCS) \ + $(TEST_SRCS) | \ + ( \ + awk '/^# .*Makefile.in ---/,/^# DO .*distdepend/' < Makefile.in ; \ + sed -e 's@ \./@ @g;s@ /[^ ]*@@g;/^.*:$$/d' \ + -e 's@\.\./utils@$$(UTILS_SRC)@g' \ + -e 's@ \([^$$]\)@ $$(srcdir)/\1@g' \ + -e 's@$$.*\(XScreenSaver_ad\)@\1@g' \ + -e 's@ $$(srcdir)/\(.*config\.h\)@ \1@g' ; \ + echo '' \ + ) > /tmp/distdepend.$$$$ && \ + mv Makefile.in Makefile.in.bak && \ + mv /tmp/distdepend.$$$$ Makefile.in + +# Updates the version number in the app-defaults file to be in sync with +# the version number in version.h. This is so people can tell when they +# have a version skew between the app-defaults file and the executable. +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` ; \ + D=`date '+%d-%b-%y'` ; \ + echo -n "Updating version number in $$S to $$V $$D... " ; \ + T=/tmp/xs.$$$$ ; \ + 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." ; \ + else \ + cat $$T > $$S ; \ + echo "done." ; \ + 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: + find $(srcdir) -name '*.[chly]' -print | xargs etags -a + +echo_tarfiles: + @$(MAKE) XScreenSaver_ad.h 2>&1 >&- /dev/null + @echo $(TARFILES) + + +# Rules for noticing when the objects from the utils directory are out of +# date with respect to their sources, and going and building them according +# to the rules in their own Makefile... +# +$(UTILS_BIN)/fade.o: $(UTILS_SRC)/fade.c +$(UTILS_BIN)/overlay.o: $(UTILS_SRC)/overlay.c +$(UTILS_BIN)/resources.o: $(UTILS_SRC)/resources.c +$(UTILS_BIN)/usleep.o: $(UTILS_SRC)/usleep.c +$(UTILS_BIN)/visual.o: $(UTILS_SRC)/visual.c +$(UTILS_BIN)/xmu.o: $(UTILS_SRC)/xmu.c +$(UTILS_BIN)/xroger.o: $(UTILS_SRC)/xroger.c +$(UTILS_BIN)/spline.o: $(UTILS_SRC)/spline.c +$(UTILS_BIN)/yarandom.o: $(UTILS_SRC)/yarandom.c + +$(SAVER_UTIL_OBJS): + cd $(UTILS_BIN) ; \ + $(MAKE) $(@F) CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" + +# How we build object files in this directory. +.c.o: + $(CC) -c $(INCLUDES) $(DEFS) $(CFLAGS) $(X_CFLAGS) $< + +# subprocs is the only one that takes an extra -D option. +subprocs.o: subprocs.c + $(CC) -c $(INCLUDES) $(DEFS2) $(CFLAGS) $(X_CFLAGS) \ + $(srcdir)/subprocs.c + + +# How we build the default app-defaults file into the program. +# +XScreenSaver_ad.h: XScreenSaver.ad + $(SHELL) $(UTILS_SRC)/ad2c XScreenSaver.ad > XScreenSaver_ad.h + +# The executables linked in this directory. +# +xscreensaver: $(SAVER_OBJS) + $(CC) $(LDFLAGS) -o $@ $(SAVER_OBJS) $(SAVER_LIBS) + +xscreensaver-command: $(CMD_OBJS) + $(CC) $(LDFLAGS) -o $@ $(CMD_OBJS) $(CMD_LIBS) + + +xscreensaver-demo: @PREFERRED_DEMO_PROGRAM@ + cp -p @PREFERRED_DEMO_PROGRAM@ $@ + +xscreensaver-demo-Xm: $(DEMO_OBJS) $(MOTIF_OBJS) demo-Xm.o + $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(MOTIF_OBJS) demo-Xm.o \ + $(LIBS) $(X_LIBS) \ + $(MOTIF_LIBS) $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +xscreensaver-demo-Gtk: $(DEMO_OBJS) $(GTK_OBJS) demo-Gtk.o + $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(GTK_OBJS) demo-Gtk.o \ + $(LIBS) $(X_LIBS) \ + $(GTK_LIBS) $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +xscreensaver-demo-Xaw: $(DEMO_OBJS) $(ATHENA_OBJS) demo-Xaw.o + $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(ATHENA_OBJS) demo-Xaw.o \ + $(LIBS) $(X_LIBS) \ + $(ATHENA_LIBS) $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +xscreensaver-demo-Xaw3d: $(DEMO_OBJS) $(ATHENA_OBJS) demo-Xaw.o + $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(ATHENA_OBJS) demo-Xaw.o \ + $(LIBS) $(X_LIBS) \ + $(ATHENA3D_LIBS) $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +demo-Xm.o: demo.c XScreenSaver_ad.h + $(CC) -o $@ -c -DFORCE_MOTIF \ + $(INCLUDES) $(DEFS) $(CFLAGS) $(X_CFLAGS) $(srcdir)/demo.c +demo-Gtk.o: demo.c XScreenSaver_ad.h + $(CC) -o $@ -c -DFORCE_GTK \ + $(INCLUDES) $(DEFS) $(CFLAGS) $(X_CFLAGS) $(srcdir)/demo.c +demo-Xaw.o: demo.c XScreenSaver_ad.h + $(CC) -o $@ -c -DFORCE_ATHENA \ + $(INCLUDES) $(DEFS) $(CFLAGS) $(X_CFLAGS) $(srcdir)/demo.c + + + + +TEST_PASSWD_OBJS = test-passwd.o $(LOCK_OBJS_1) $(PASSWD_OBJS) \ + subprocs.o setuid.o splash.o prefs.o \ + $(SAVER_UTIL_OBJS) +test-passwd.o: XScreenSaver_ad.h + +tests:: test-passwd +test-passwd: $(TEST_PASSWD_OBJS) XScreenSaver_ad.h + $(CC) $(LDFLAGS) -o $@ $(TEST_PASSWD_OBJS) $(SAVER_LIBS) + +tests:: test-uid +test-uid: test-uid.o + $(CC) $(LDFLAGS) -o $@ test-uid.o + +tests:: test-xdpms +test-xdpms: test-xdpms.o + $(CC) $(LDFLAGS) -o $@ test-xdpms.o $(SAVER_LIBS) + +tests:: test-grab +test-grab: test-grab.o + $(CC) $(LDFLAGS) -o $@ test-grab.o $(SAVER_LIBS) + +tests:: test-apm +test-apm: test-apm.o + $(CC) $(LDFLAGS) -o $@ test-apm.o $(SAVER_LIBS) -lapm + + + +############################################################################## +# +# DO NOT DELETE: updated by make distdepend +# $(srcdir)/DO $(srcdir)/NOT $(srcdir)/DELETE: $(srcdir)/updated $(srcdir)/by $(srcdir)/make $(srcdir)/distdepend + +xscreensaver.o: ../config.h +xscreensaver.o: $(srcdir)/xscreensaver.h +xscreensaver.o: $(srcdir)/prefs.h +xscreensaver.o: $(UTILS_SRC)/version.h +xscreensaver.o: $(UTILS_SRC)/yarandom.h +xscreensaver.o: $(UTILS_SRC)/resources.h +xscreensaver.o: $(UTILS_SRC)/visual.h +xscreensaver.o: $(UTILS_SRC)/usleep.h +xscreensaver.o: XScreenSaver_ad.h +windows.o: ../config.h +windows.o: $(srcdir)/xscreensaver.h +windows.o: $(srcdir)/prefs.h +windows.o: $(UTILS_SRC)/visual.h +windows.o: $(UTILS_SRC)/fade.h +timers.o: ../config.h +timers.o: $(srcdir)/xscreensaver.h +timers.o: $(srcdir)/prefs.h +subprocs.o: ../config.h +subprocs.o: $(srcdir)/xscreensaver.h +subprocs.o: $(srcdir)/prefs.h +subprocs.o: $(UTILS_SRC)/yarandom.h +xset.o: ../config.h +xset.o: $(srcdir)/xscreensaver.h +xset.o: $(srcdir)/prefs.h +splash.o: ../config.h +splash.o: $(srcdir)/xscreensaver.h +splash.o: $(srcdir)/prefs.h +splash.o: $(UTILS_SRC)/resources.h +setuid.o: ../config.h +setuid.o: $(srcdir)/xscreensaver.h +setuid.o: $(srcdir)/prefs.h +stderr.o: ../config.h +stderr.o: $(srcdir)/xscreensaver.h +stderr.o: $(srcdir)/prefs.h +stderr.o: $(UTILS_SRC)/resources.h +stderr.o: $(UTILS_SRC)/visual.h +dialogs-Xm.o: ../config.h +dialogs-Xm.o: $(UTILS_SRC)/visual.h +dialogs-Gtk.o: ../config.h +dialogs-Gtk.o: $(UTILS_SRC)/resources.h +dialogs-Xaw.o: ../config.h +dialogs-Xaw.o: $(UTILS_SRC)/visual.h +passwd-pwent.o: ../config.h +lock.o: ../config.h +lock.o: $(srcdir)/xscreensaver.h +lock.o: $(srcdir)/prefs.h +lock.o: $(UTILS_SRC)/resources.h +passwd.o: ../config.h +prefs.o: ../config.h +prefs.o: $(srcdir)/prefs.h +prefs.o: $(UTILS_SRC)/resources.h +demo.o: ../config.h +demo.o: $(UTILS_SRC)/version.h +demo.o: $(srcdir)/prefs.h +demo.o: $(UTILS_SRC)/resources.h +demo.o: $(UTILS_SRC)/visual.h +demo.o: $(srcdir)/remote.h +demo.o: $(UTILS_SRC)/usleep.h +demo.o: XScreenSaver_ad.h +remote.o: ../config.h +remote.o: $(srcdir)/remote.h +xscreensaver-command.o: ../config.h +xscreensaver-command.o: $(srcdir)/remote.h +xscreensaver-command.o: $(UTILS_SRC)/version.h +test-passwd.o: ../config.h +test-passwd.o: $(srcdir)/xscreensaver.h +test-passwd.o: $(srcdir)/prefs.h +test-passwd.o: $(UTILS_SRC)/resources.h +test-passwd.o: $(UTILS_SRC)/version.h +test-passwd.o: $(UTILS_SRC)/visual.h +test-passwd.o: XScreenSaver_ad.h +test-uid.o: ../config.h +test-xdpms.o: ../config.h +test-grab.o: ../config.h +test-apm.o: ../config.h + diff --git a/driver/README b/driver/README new file mode 100644 index 00000000..df64793b --- /dev/null +++ b/driver/README @@ -0,0 +1,6 @@ + +This directory contains the source for xscreensaver and xscreensaver-command, +the screensaver driver, and the program for externally controlling it. Some +stuff from the ../utils/ directory is used here as well. + +If you have compilation problems, check the parameters in ../config.h. diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in new file mode 100644 index 00000000..160514d4 --- /dev/null +++ b/driver/XScreenSaver.ad.in @@ -0,0 +1,520 @@ +! +! XScreenSaver +! +! a screen saver and locker for the X window system +! by Jamie Zawinski +! +! version 3.16 +! 23-Jun-99 +! +! See "man xscreensaver" for more info. The latest version is always +! available at http://www.jwz.org/xscreensaver/ + + +! These resources, when placed in the system-wide app-defaults directory +! (e.g., /usr/lib/X11/app-defaults/XScreenSaver) will provide the default +! settings for new users. However, if you have a ".xscreensaver" file in +! your home directory, the settings in that file take precedence. + + +*timeout: 10 +*cycle: 10 +*lockTimeout: 0 +*passwdTimeout: 30 +*nice: 10 +*lock: False +*lockVTs: True +*verbose: False +*timestamp: False +*fade: True +*unfade: False +*fadeSeconds: 3 +*fadeTicks: 20 +*splash: True +*splashDuration: 5 +*visualID: default + +*captureStderr: True +*overlayTextForeground: #FFFF00 +*overlayTextBackground: #000000 +*overlayStderr: True +*font: *-medium-r-*-140-*-m-* + +! The default is to use these extensions if available (as noted.) +*sgiSaverExtension: True +*mitSaverExtension: False +*xidleExtension: True +*procInterrupts: True + +! This is what the "Demo" button on the splash screen runs (/bin/sh syntax.) +*demoCommand: xscreensaver-demo + +! This is what the "Prefs" button on the splash screen runs (/bin/sh syntax.) +*prefsCommand: xscreensaver-demo -prefs + +! This is the URL that the "Help" button on the splash screen loads. +*helpURL: http://www.jwz.org/xscreensaver/man.html + +! This is how the "Help" button loads URLs (/bin/sh syntax.) +! The "helpURL" will be substituted for up to two occurrences of "%s". +*loadURL: netscape -remote 'openURL(%s)' || netscape '%s' + + +! Turning on "installColormap" interacts erratically with twm and tvtwm, +! but seems to work fine with mwm and olwm. Try it and see. If your +! screen turns some color other than black, the window manager is buggy, +! and you need to set this resource to False (or get a WM that works.) +! +*installColormap: True + + +! Any program which can draw on the root window will work as a screensaver. +! The following resource enumerates them. +! +! Programs are separated by newlines (specified in resource files with \n). +! Lines may be continued with a lone \ at the end of the line. +! +! Each line is an `sh' command. +! +! If the first (non-blank) character on the line is "-", then that means +! that this command is disabled: it's still in the list, but it won't ever +! be used. (This is just to make it easy to disable and then re-enable +! them later.) +! +! If the first word on the line is the name of a visual followed by a +! colon, then that visual will be used for the program, if it is available. +! If no such visual is available, then the program will be skipped. In +! this way, you can specify that you want certain programs to run only +! on color screens, and others only on mono screens, by making use of the +! magic visual names "color" and "mono". Likewise, if some hacks prefer +! colormaps, but others prefer 24-bit windows, that also can be arranged +! (in this case, by using "PseudoColor:" versus "TrueColor:".) +! +! Some of the screenhacks are written using OpenGL. OpenGL programs are +! a bit different than normal X programs, in that they prefer visuals that +! are *half* as deep as the screen. You can tell xscreensaver to select a +! good visual for a GL program by using the magic visual name "GL". +! +! All programs must be launched in such a way that they draw on the root +! window; they should not be spawned in the background with "&". If shell +! metacharacters are used, they must be understandable to `sh', not `csh' +! (the $SHELL variable is not consulted, for unfortunate but good reasons.) +! +! Be sure to check out Demo Mode: run the `xscreensaver-demo' program to +! edit the current list of programs interactively, try out the various modes, +! and change other parameters. See the man page for details. +! +*programs: qix -root -solid -delay 0 -segments 100 \n\ + qix -root -count 4 -solid -transparent \n\ + qix -root -count 5 -solid -transparent -linear \ + -segments 250 -size 100 \n\ + attraction -root -mode balls \n\ + attraction -root -mode lines -points 3 -segments 200 \n\ + attraction -root -mode splines -segments 300 \n\ + attraction -root -mode lines -radius 300 \ + -orbit -vmult 0.5 \n\ + pyro -root \n\ + helix -root \n\ + pedal -root \n\ + rorschach -root -offset 7 \n\ + hopalong -root \n\ + greynetic -root \n\ + xroger -root \n\ + imsmap -root \n\ + slidescreen -root \n\ + decayscreen -root \n\ + jigsaw -root \n\ + blitspin -root -grab \n\ + slip -root \n\ + distort -root \n\ + spotlight -root \n\ + hypercube -root \n\ + halo -root \n\ + maze -root \n\ + noseguy -root \n\ + flame -root \n\ + lmorph -root \n\ + deco -root \n\ + moire -root \n\ + moire2 -root \n\ + lightning -root \n\ + strange -root \n\ + spiral -root \n\ + laser -root \n\ + grav -root \n\ + grav -root -trail -decay \n\ + drift -root \n\ + ifs -root \n\ + julia -root \n\ + penrose -root \n\ + sierpinski -root \n\ + braid -root \n\ + galaxy -root \n\ + bouboule -root \n\ + swirl -root \n\ + flag -root \n\ + sphere -root \n\ + forest -root \n\ + lisa -root \n\ + lissie -root \n\ + goop -root \n\ + starfish -root \n\ + starfish -root -blob \n\ + munch -root \n\ + fadeplot -root \n\ + coral -root \n\ + mountain -root \n\ + triangle -root \n\ + worm -root \n\ + rotor -root \n\ + ant -root \n\ + demon -root \n\ + loop -root \n\ + vines -root \n\ + kaleidescope -root \n\ + xjack -root \n\ + - xlyap -root -randomize \n\ + cynosure -root \n\ + flow -root \n\ + epicycle -root \n\ + interference -root \n\ + truchet -root -randomize \n\ + bsod -root \n\ + crystal -root \n\ + discrete -root \n\ + kumppa -root \n\ + rd-bomb -root \n\ + rd-bomb -root -speed 1 -size 0.1 \n\ + sonar -root \n\ + t3d -root \n\ + penetrate -root \n\ + deluxe -root \n\ + compass -root \n\ + squiral -root \n\ + xflame -root \n\ + wander -root \n\ + wander -root -advance 0 -size 10 -circles True \ + -length 10000 -reset 100000 \n\ + critical -root \n\ + phosphor -root \n\ + xmatrix -root \n\ + petri -root -size 1 -count 20 \n\ + petri -root -minlifespeed 0.02 -maxlifespeed 0.03 \ + -minlifespan 1 -maxlifespan 1 -instantdeathchan 0 \ + -minorchan 0 -anychan 0.3 \n\ + shadebobs -root \n\ + default-n: webcollage -root \n\ + - default-n: webcollage -root -filter 'vidwhacker -stdin -stdout' \n\ + - default-n: vidwhacker -root \n\ + \ + mono: rocks -root \n\ + color: rocks -root -fg darksalmon \n\ + \ + mono: qix -root -linear -count 5 -size 200 -spread 30 \ + -segments 75 -solid -xor \n\ + \ + color: attraction -root -mode polygons \n\ + color: attraction -root -mode filled-splines -segments 0 \n\ + color: attraction -root -glow -points 10 \n\ + color: bubbles -root \n\ + \ +@GL_KLUDGE@ GL: gears -root \n\ +@GL_KLUDGE@ GL: superquadrics -root \n\ +@GL_KLUDGE@ GL: morph3d -root \n\ +@GL_KLUDGE@ GL: cage -root \n\ +@GL_KLUDGE@ GL: moebius -root \n\ +@GL_KLUDGE@ GL: stairs -root \n\ +@GL_KLUDGE@ GL: pipes -root \n\ +@GL_KLUDGE@ GL: sproingies -root \n\ +@GL_KLUDGE@ GL: rubik -root \n\ +@GL_KLUDGE@ GL: atlantis -root \n\ +@GL_KLUDGE@ GL: lament -root \n\ +@GL_KLUDGE@ GL: bubble3d -root \n\ +@GL_KLUDGE@ GL: glplanet -root \n\ +@GL_KLUDGE@ GL: pulsar -root \n\ + - GL: pulsar -root -texture -mipmap -texture_quality \ + -light -fog \n + + +! Some other programs that you might want to track down (these work as +! XScreenSaver helpers, but are not distributed with it): +! +! xdaliclock -root -builtin2 \n\ +! xswarm -r 2>&- \n\ +! xwave -root \n\ +! xbouncebits ... \n\ +! ico -r -faces -sleep 1 -obj ico \n\ +! xsplinefun \n\ +! xmountains -b -M \n\ +! color: xfishtank -c black -d -r 2 \n\ +! +! xtacy is ok, but it only works on the default visual. We can satisfy +! that constraint like so: +! +! default: xtacy -root -delay 100 -funky -number 3 \n\ +! default: xtacy -root -delay 100 -gravity \n\ +! default: xtacy -root -delay 100 -mixer \n\ +! default: xtacy -root -delay 100 -taffy -pal 4 \n\ +! +! To display a randomized slideshow of images, you can do something like this: +! +! default-n: xv -root -rmode 5 -random -viewonly -wloop \ +! -wait 30 $HOME/bitmaps/*.jpg \n\ +! +! Note that we've used "default-n" as the visual name, rather than just +! "default": this means "default visual, no install", that is, it's like +! specifying the command-line arguments "-visual default -no-install". +! This is necessary because, when XV is running in "-root" mode, it always +! assumes that the default visual and colormap are being used, rather than +! examining the window it is drawing on to see what visual and colormap it +! has. If we didn't force the default visual to be used, xv would get an +! X error. If we didn't force the default colormap to be installed, the +! colors would be all wrong. "default-i" may also be used as a visual name +! (meaning, "-visual default -install") but you probably won't ever need +! to use that. +! +! XEarth is nice, too: +! +! default-n: xearth -nostars -wait 0 -timewarp 400 -pos sunrel/38/-30 +! +! +! Some of the GL demos that SGI ships work with XScreenSaver; most don't. +! XScreenSaver includes a program (not built or installed by default) +! called "xscreensaver-sgigl". To use the SGI demos with XScreenSaver, +! build that program, and use it to launch the SGI demos. For example, +! on Irix 6.2, you can do this: +! +! xscreensaver-sgigl /usr/demos/bin/ep -S +! xscreensaver-sgigl /usr/demos/bin/bongo +! +! On Irix 6.3, things have moved, so you need to do it like this: +! +! xscreensaver-sgigl /usr/sbin/ep -S +! +! You can also use the "ant" demo, but first you need to wrap a shell script +! around it that cds to its home directory, so that it can find its files; +! and also pass it the -S argument, to prevent it from forking. +! +! +! Also, since these actually end up mapping their own windows instead of +! drawing on the XScreenSaver-provided root, when they are being run from +! demo-mode, you can't pop up the demo-mode dialog just by clicking the +! mouse: you must first type ESC to make the SGI programs exit. This sucks. +! Things should work properly when they are being run by xscreensaver in +! non-demo-mode, however. +! +! Basically, the SGI demo writers went out of their way to make my life hell. + + + +!============================================================================= +! +! You probably don't want to change anything after this point. +! +!============================================================================= + + +XScreenSaver.pointerPollTime: 5 +XScreenSaver.initialDelay: 0 +XScreenSaver.windowCreationTimeout: 30 +XScreenSaver.bourneShell: /bin/sh + + +! Resources for the password and splash-screen dialog boxes of +! the "xscreensaver" daemon. +! +*Dialog.headingFont: *-times-bold-r-*-*-*-180-*-*-*-iso8859-1 +*Dialog.bodyFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +*Dialog.labelFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +*Dialog.buttonFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +*Dialog.foreground: #000000 +*Dialog.background: #BFBFBF +*Dialog.Button.foreground: #000000 +*Dialog.Button.background: #D0D0D0 +*Dialog.text.foreground: #000000 +*Dialog.text.background: #FFFFFF +*Dialog.logo.foreground: #FF0000 +*Dialog.logo.background: #FFFFFF +*Dialog.topShadowColor: #E7E7E7 +*Dialog.bottomShadowColor: #737373 +*Dialog.logo.width: 200 +*Dialog.logo.height: 200 +*Dialog.internalBorderWidth: 30 +*Dialog.borderWidth: 1 +*Dialog.shadowThickness: 4 + +*passwd.heading.label: XScreenSaver %s +*passwd.body.label: This display is locked. +*passwd.user.label: User: +*passwd.passwd.label: Password: +*passwd.passwdFont: *-courier-medium-r-*-*-*-140-*-*-*-iso8859-1 +*passwd.thermometer.width: 8 + +*splash.heading.label: XScreenSaver %s +*splash.body.label: Copyright © 1991-1999 by +*splash.body2.label: Jamie Zawinski +*splash.demo.label: Demo +*splash.prefs.label: Prefs +*splash.help.label: Help + + +! Resources for the Motif dialog boxes of the "xscreensaver-demo" program. +! +*fontList: *-helvetica-medium-r-*-*-*-120-*-*-*-iso8859-1 +*demoDialog*label1.fontList: *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1 +*XmTextField.fontList: *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1 +*label0.fontList: *-helvetica-bold-r-*-*-*-140-*-*-*-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: #000000 +*XmDialogShell*background: #E5E5E5 +*XmDialogShell*XmTextField.foreground: #000000 +*XmDialogShell*XmTextField.background: #FFFFFF +*XmDialogShell*demoList.foreground: #000000 +*XmDialogShell*demoList.background: #FFFFFF + +*XmDialogShell.title: XScreenSaver +*versionWarning_popup.title: XScreenSaver Warning +*demoForm_popup.title: XScreenSaver Demo +*preferencesForm_popup.title: XScreenSaver Preferences +*allowShellResize: True +*autoUnmanage: False + +! This doesn't work. Motif ignores it if there is a scroll-list! +*demoDialog.maxWidth: 600 + +*label1.labelString: XScreenSaver %s +*label1.label: XScreenSaver %s +*label2.labelString: Copyright © 1991-1999 by Jamie Zawinski +*label2.label: Copyright © 1991-1999 by Jamie Zawinski +*demoList.visibleItemCount: 10 +*demoList.automaticSelection: True +*next.labelString: Run Next +*prev.labelString: Run Previous +*edit.labelString: Preferences +*restart.labelString: Reinitialize +*done.labelString: Quit + +*preferencesLabel.labelString: XScreenSaver Parameters + +*timeoutLabel.labelString: Saver Timeout +*cycleLabel.labelString: Cycle Timeout +*fadeSecondsLabel.labelString: Fade Duration +*fadeTicksLabel.labelString: Fade Ticks +*lockLabel.labelString: Lock Timeout +*passwdLabel.labelString: Password Timeout +*preferencesForm*XmTextField.columns: 8 + +*verboseToggle.labelString: Verbose +*cmapToggle.labelString: Install Colormap +*fadeToggle.labelString: Fade Colormap +*unfadeToggle.labelString: Unfade Colormap +*lockToggle.labelString: Require Password +*preferencesDone.labelString: OK +*preferencesCancel.labelString: Cancel + + +! Disable Motif drag-and-drop in dialog boxes. This is kind of pathetic, but +! in some older versions of Motif, most any attempt to drag cause immediate +! flaming death from above. This *should* rip the legs off that bug. +! (But sadly, Lesstif 0.86 and earlier ignore these resources *and* have +! buggy drag-and-drop.) +! +XScreenSaver*dragInitiatorProtocolStyle: DRAG_NONE +XScreenSaver*dragReceiverProtocolStyle: DRAG_NONE + + + +! Resources for the Athena dialog boxes of the "xscreensaver-demo" program. +! +*demo_dialog.title: XScreenSaver Demo +*preferences_dialog.title: XScreenSaver Preferences +*warning_dialog.title: XScreenSaver Warning + +! For some reason, it doesn't size correctly by itself. +*demo_dialog.geometry: =640x400 + +*demo_dialog*font: *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1 +*preferences_dialog*font: *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1 +*demo_dialog*label1.font: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +*preferences_dialog*label1.font:*-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +XScreenSaver*warning_dialog*label0.font: \ + *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +XScreenSaver*warning_dialog*Label.font: \ + *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1 +XScreenSaver*warning_dialog*Command.font: \ + *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +XScreenSaver.demo_dialog*List.font: \ + *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1 +XScreenSaver.demo_dialog*Text*font: \ + *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1 + +XScreenSaver.demo_dialog*foreground: #000000 +XScreenSaver.demo_dialog*background: #E5E5E5 +XScreenSaver.demo_dialog*List.background: #FFFFFF +XScreenSaver.demo_dialog*Scrollbar.background: #D9D9D9 +XScreenSaver.demo_dialog*Command.background: #D9D9D9 +XScreenSaver.demo_dialog*Text*background: #FFFFFF + +XScreenSaver.preferences_dialog*foreground: #000000 +XScreenSaver.preferences_dialog*background: #E5E5E5 +XScreenSaver.preferences_dialog*Command.background: #D9D9D9 +XScreenSaver.preferences_dialog*Toggle.background: #D9D9D9 +XScreenSaver.preferences_dialog*Text*background: #FFFFFF + +XScreenSaver.warning_dialog*foreground: #000000 +XScreenSaver.warning_dialog*background: #E5E5E5 +XScreenSaver.warning_dialog*Command.background: #D9D9D9 + +*preferences_dialog*Dialog.value.translations: #override\n\ + Return: beginning-of-line()\n + +*demo_dialog*viewport.height: 200 +*Form.borderWidth: 0 +*Box.borderWidth: 0 +*Label.borderWidth: 0 +*preferences_dialog*Dialog.borderWidth: 0 + +*demo_dialog*run.label: Run +*demo_dialog*next.label: Run Next +*demo_dialog*prev.label: Run Previous +*demo_dialog*edit.label: Preferences +*demo_dialog*restart.label: Reinitialize +*demo_dialog*done.label: Quit +XScreenSaver.demo_dialog*Command.internalWidth: 10 +XScreenSaver.demo_dialog*Command.internalHeight: 4 + +*preferences_dialog*timeout.label: Saver Timeout: +*preferences_dialog*cycle.label: Cycle Timeout: +*preferences_dialog*fade.label: Fade Duration: +*preferences_dialog*ticks.label: Fade Ticks: +*preferences_dialog*lockTime.label: Lock Timeout: +*preferences_dialog*passwdTime.label: Password Timeout: +XScreenSaver.preferences_dialog*Command.internalWidth: 10 +XScreenSaver.preferences_dialog*Command.internalHeight: 4 + +*preferences_dialog*label1.label: XScreenSaver Parameters +*preferences_dialog*buttonbox.verbose.label: Verbose +*preferences_dialog*buttonbox.cmap.label: Install Colormap +*preferences_dialog*buttonbox.fade.label: Fade Colormap +*preferences_dialog*buttonbox.unfade.label: Unfade Colormap +*preferences_dialog*buttonbox.lock.label: Require Password +*preferences_dialog*done.label: Ok +*preferences_dialog*cancel.label: Cancel + +*warning_dialog*ok.label: Ok + +*warning_dialog*horizDistance: 30 +*warning_dialog*vertDistance: 0 + +*warning_dialog*Label.internalWidth: 1 +*warning_dialog*Label.internalHeight: 0 + +*warning_dialog*label0.horizDistance: 80 +*warning_dialog*label0.vertDistance: 20 + +*warning_dialog*Command.horizDistance: 160 +*warning_dialog*Command.vertDistance: 20 +*warning_dialog*Command.internalWidth: 20 +*warning_dialog*Command.internalHeight: 5 diff --git a/driver/XScreenSaver_ad.h b/driver/XScreenSaver_ad.h new file mode 100644 index 00000000..104a5161 --- /dev/null +++ b/driver/XScreenSaver_ad.h @@ -0,0 +1,316 @@ +"*timeout: 10", +"*cycle: 10", +"*lockTimeout: 0", +"*passwdTimeout: 30", +"*nice: 10", +"*lock: False", +"*lockVTs: True", +"*verbose: False", +"*timestamp: False", +"*fade: True", +"*unfade: False", +"*fadeSeconds: 3", +"*fadeTicks: 20", +"*splash: True", +"*splashDuration: 5", +"*visualID: default", +"*captureStderr: True", +"*overlayTextForeground: #FFFF00", +"*overlayTextBackground: #000000", +"*overlayStderr: True", +"*font: *-medium-r-*-140-*-m-*", +"*sgiSaverExtension: True", +"*mitSaverExtension: False", +"*xidleExtension: True", +"*procInterrupts: True", +"*demoCommand: xscreensaver-demo", +"*prefsCommand: xscreensaver-demo -prefs", +"*helpURL: http://www.jwz.org/xscreensaver/man.html", +"*loadURL: netscape -remote 'openURL(%s)' || netscape '%s'", +"*installColormap: True", +"*programs: qix -root -solid -delay 0 -segments 100 \\n\ + qix -root -count 4 -solid -transparent \\n\ + qix -root -count 5 -solid -transparent -linear \ + -segments 250 -size 100 \\n\ + attraction -root -mode balls \\n\ + attraction -root -mode lines -points 3 -segments 200 \\n\ + attraction -root -mode splines -segments 300 \\n\ + attraction -root -mode lines -radius 300 \ + -orbit -vmult 0.5 \\n\ + pyro -root \\n\ + helix -root \\n\ + pedal -root \\n\ + rorschach -root -offset 7 \\n\ + hopalong -root \\n\ + greynetic -root \\n\ + xroger -root \\n\ + imsmap -root \\n\ + slidescreen -root \\n\ + decayscreen -root \\n\ + jigsaw -root \\n\ + blitspin -root -grab \\n\ + slip -root \\n\ + distort -root \\n\ + spotlight -root \\n\ + hypercube -root \\n\ + halo -root \\n\ + maze -root \\n\ + noseguy -root \\n\ + flame -root \\n\ + lmorph -root \\n\ + deco -root \\n\ + moire -root \\n\ + moire2 -root \\n\ + lightning -root \\n\ + strange -root \\n\ + spiral -root \\n\ + laser -root \\n\ + grav -root \\n\ + grav -root -trail -decay \\n\ + drift -root \\n\ + ifs -root \\n\ + julia -root \\n\ + penrose -root \\n\ + sierpinski -root \\n\ + braid -root \\n\ + galaxy -root \\n\ + bouboule -root \\n\ + swirl -root \\n\ + flag -root \\n\ + sphere -root \\n\ + forest -root \\n\ + lisa -root \\n\ + lissie -root \\n\ + goop -root \\n\ + starfish -root \\n\ + starfish -root -blob \\n\ + munch -root \\n\ + fadeplot -root \\n\ + coral -root \\n\ + mountain -root \\n\ + triangle -root \\n\ + worm -root \\n\ + rotor -root \\n\ + ant -root \\n\ + demon -root \\n\ + loop -root \\n\ + vines -root \\n\ + kaleidescope -root \\n\ + xjack -root \\n\ + - xlyap -root -randomize \\n\ + cynosure -root \\n\ + flow -root \\n\ + epicycle -root \\n\ + interference -root \\n\ + truchet -root -randomize \\n\ + bsod -root \\n\ + crystal -root \\n\ + discrete -root \\n\ + kumppa -root \\n\ + rd-bomb -root \\n\ + rd-bomb -root -speed 1 -size 0.1 \\n\ + sonar -root \\n\ + t3d -root \\n\ + penetrate -root \\n\ + deluxe -root \\n\ + compass -root \\n\ + squiral -root \\n\ + xflame -root \\n\ + wander -root \\n\ + wander -root -advance 0 -size 10 -circles True \ + -length 10000 -reset 100000 \\n\ + critical -root \\n\ + phosphor -root \\n\ + xmatrix -root \\n\ + petri -root -size 1 -count 20 \\n\ + petri -root -minlifespeed 0.02 -maxlifespeed 0.03 \ + -minlifespan 1 -maxlifespan 1 -instantdeathchan 0 \ + -minorchan 0 -anychan 0.3 \\n\ + shadebobs -root \\n\ + default-n: webcollage -root \\n\ + - default-n: webcollage -root -filter 'vidwhacker -stdin -stdout' \\n\ + - default-n: vidwhacker -root \\n\ + \ + mono: rocks -root \\n\ + color: rocks -root -fg darksalmon \\n\ + \ + mono: qix -root -linear -count 5 -size 200 -spread 30 \ + -segments 75 -solid -xor \\n\ + \ + color: attraction -root -mode polygons \\n\ + color: attraction -root -mode filled-splines -segments 0 \\n\ + color: attraction -root -glow -points 10 \\n\ + color: bubbles -root \\n\ + \ + GL: gears -root \\n\ + GL: superquadrics -root \\n\ + GL: morph3d -root \\n\ + GL: cage -root \\n\ + GL: moebius -root \\n\ + GL: stairs -root \\n\ + GL: pipes -root \\n\ + GL: sproingies -root \\n\ + GL: rubik -root \\n\ + GL: atlantis -root \\n\ + GL: lament -root \\n\ + GL: bubble3d -root \\n\ + GL: glplanet -root \\n\ + GL: pulsar -root \\n\ + - GL: pulsar -root -texture -mipmap -texture_quality \ + -light -fog \\n", +" ", +"XScreenSaver.pointerPollTime: 5", +"XScreenSaver.initialDelay: 0", +"XScreenSaver.windowCreationTimeout: 30", +"XScreenSaver.bourneShell: /bin/sh", +"*Dialog.headingFont: *-times-bold-r-*-*-*-180-*-*-*-iso8859-1", +"*Dialog.bodyFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"*Dialog.labelFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"*Dialog.buttonFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"*Dialog.foreground: #000000", +"*Dialog.background: #BFBFBF", +"*Dialog.Button.foreground: #000000", +"*Dialog.Button.background: #D0D0D0", +"*Dialog.text.foreground: #000000", +"*Dialog.text.background: #FFFFFF", +"*Dialog.logo.foreground: #FF0000", +"*Dialog.logo.background: #FFFFFF", +"*Dialog.topShadowColor: #E7E7E7", +"*Dialog.bottomShadowColor: #737373", +"*Dialog.logo.width: 200", +"*Dialog.logo.height: 200", +"*Dialog.internalBorderWidth: 30", +"*Dialog.borderWidth: 1", +"*Dialog.shadowThickness: 4", +"*passwd.heading.label: XScreenSaver %s", +"*passwd.body.label: This display is locked.", +"*passwd.user.label: User:", +"*passwd.passwd.label: Password:", +"*passwd.passwdFont: *-courier-medium-r-*-*-*-140-*-*-*-iso8859-1", +"*passwd.thermometer.width: 8", +"*splash.heading.label: XScreenSaver %s", +"*splash.body.label: Copyright © 1991-1999 by", +"*splash.body2.label: Jamie Zawinski ", +"*splash.demo.label: Demo", +"*splash.prefs.label: Prefs", +"*splash.help.label: Help", +"*fontList: *-helvetica-medium-r-*-*-*-120-*-*-*-iso8859-1", +"*demoDialog*label1.fontList: *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1", +"*XmTextField.fontList: *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1", +"*label0.fontList: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"XScreenSaver*XmList.fontList: *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1", +"*XmDialogShell*foreground: #000000", +"*XmDialogShell*background: #E5E5E5", +"*XmDialogShell*XmTextField.foreground: #000000", +"*XmDialogShell*XmTextField.background: #FFFFFF", +"*XmDialogShell*demoList.foreground: #000000", +"*XmDialogShell*demoList.background: #FFFFFF", +"*XmDialogShell.title: XScreenSaver", +"*versionWarning_popup.title: XScreenSaver Warning", +"*demoForm_popup.title: XScreenSaver Demo", +"*preferencesForm_popup.title: XScreenSaver Preferences", +"*allowShellResize: True", +"*autoUnmanage: False", +"*demoDialog.maxWidth: 600", +"*label1.labelString: XScreenSaver %s", +"*label1.label: XScreenSaver %s", +"*label2.labelString: Copyright © 1991-1999 by Jamie Zawinski ", +"*label2.label: Copyright © 1991-1999 by Jamie Zawinski ", +"*demoList.visibleItemCount: 10", +"*demoList.automaticSelection: True", +"*next.labelString: Run Next", +"*prev.labelString: Run Previous", +"*edit.labelString: Preferences", +"*restart.labelString: Reinitialize", +"*done.labelString: Quit", +"*preferencesLabel.labelString: XScreenSaver Parameters", +"*timeoutLabel.labelString: Saver Timeout", +"*cycleLabel.labelString: Cycle Timeout", +"*fadeSecondsLabel.labelString: Fade Duration", +"*fadeTicksLabel.labelString: Fade Ticks", +"*lockLabel.labelString: Lock Timeout", +"*passwdLabel.labelString: Password Timeout", +"*preferencesForm*XmTextField.columns: 8", +"*verboseToggle.labelString: Verbose", +"*cmapToggle.labelString: Install Colormap", +"*fadeToggle.labelString: Fade Colormap", +"*unfadeToggle.labelString: Unfade Colormap", +"*lockToggle.labelString: Require Password", +"*preferencesDone.labelString: OK", +"*preferencesCancel.labelString: Cancel", +"XScreenSaver*dragInitiatorProtocolStyle: DRAG_NONE", +"XScreenSaver*dragReceiverProtocolStyle: DRAG_NONE", +"*demo_dialog.title: XScreenSaver Demo", +"*preferences_dialog.title: XScreenSaver Preferences", +"*warning_dialog.title: XScreenSaver Warning", +"*demo_dialog.geometry: =640x400", +"*demo_dialog*font: *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1", +"*preferences_dialog*font: *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1", +"*demo_dialog*label1.font: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"*preferences_dialog*label1.font:*-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"XScreenSaver*warning_dialog*label0.font: \ + *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"XScreenSaver*warning_dialog*Label.font: \ + *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1", +"XScreenSaver*warning_dialog*Command.font: \ + *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"XScreenSaver.demo_dialog*List.font: \ + *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1", +"XScreenSaver.demo_dialog*Text*font: \ + *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1", +"XScreenSaver.demo_dialog*foreground: #000000", +"XScreenSaver.demo_dialog*background: #E5E5E5", +"XScreenSaver.demo_dialog*List.background: #FFFFFF", +"XScreenSaver.demo_dialog*Scrollbar.background: #D9D9D9", +"XScreenSaver.demo_dialog*Command.background: #D9D9D9", +"XScreenSaver.demo_dialog*Text*background: #FFFFFF", +"XScreenSaver.preferences_dialog*foreground: #000000", +"XScreenSaver.preferences_dialog*background: #E5E5E5", +"XScreenSaver.preferences_dialog*Command.background: #D9D9D9", +"XScreenSaver.preferences_dialog*Toggle.background: #D9D9D9", +"XScreenSaver.preferences_dialog*Text*background: #FFFFFF", +"XScreenSaver.warning_dialog*foreground: #000000", +"XScreenSaver.warning_dialog*background: #E5E5E5", +"XScreenSaver.warning_dialog*Command.background: #D9D9D9", +"*preferences_dialog*Dialog.value.translations: #override\\n\ + Return: beginning-of-line()\\n", +"*demo_dialog*viewport.height: 200", +"*Form.borderWidth: 0", +"*Box.borderWidth: 0", +"*Label.borderWidth: 0", +"*preferences_dialog*Dialog.borderWidth: 0", +"*demo_dialog*run.label: Run", +"*demo_dialog*next.label: Run Next", +"*demo_dialog*prev.label: Run Previous", +"*demo_dialog*edit.label: Preferences", +"*demo_dialog*restart.label: Reinitialize", +"*demo_dialog*done.label: Quit", +"XScreenSaver.demo_dialog*Command.internalWidth: 10", +"XScreenSaver.demo_dialog*Command.internalHeight: 4", +"*preferences_dialog*timeout.label: Saver Timeout:", +"*preferences_dialog*cycle.label: Cycle Timeout:", +"*preferences_dialog*fade.label: Fade Duration:", +"*preferences_dialog*ticks.label: Fade Ticks:", +"*preferences_dialog*lockTime.label: Lock Timeout:", +"*preferences_dialog*passwdTime.label: Password Timeout:", +"XScreenSaver.preferences_dialog*Command.internalWidth: 10", +"XScreenSaver.preferences_dialog*Command.internalHeight: 4", +"*preferences_dialog*label1.label: XScreenSaver Parameters", +"*preferences_dialog*buttonbox.verbose.label: Verbose", +"*preferences_dialog*buttonbox.cmap.label: Install Colormap", +"*preferences_dialog*buttonbox.fade.label: Fade Colormap", +"*preferences_dialog*buttonbox.unfade.label: Unfade Colormap", +"*preferences_dialog*buttonbox.lock.label: Require Password", +"*preferences_dialog*done.label: Ok", +"*preferences_dialog*cancel.label: Cancel", +"*warning_dialog*ok.label: Ok", +"*warning_dialog*horizDistance: 30", +"*warning_dialog*vertDistance: 0", +"*warning_dialog*Label.internalWidth: 1", +"*warning_dialog*Label.internalHeight: 0", +"*warning_dialog*label0.horizDistance: 80", +"*warning_dialog*label0.vertDistance: 20", +"*warning_dialog*Command.horizDistance: 160", +"*warning_dialog*Command.vertDistance: 20", +"*warning_dialog*Command.internalWidth: 20", +"*warning_dialog*Command.internalHeight: 5", diff --git a/driver/compile_axp.com b/driver/compile_axp.com new file mode 100644 index 00000000..d6ed0e8a --- /dev/null +++ b/driver/compile_axp.com @@ -0,0 +1,15 @@ +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DEMO.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DIALOGS-XM.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) LOCK.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) PASSWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) STDERR.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) SUBPROCS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) TIMERS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) WINDOWS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSCREENSAVER-COMMAND.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) XSCREENSAVER.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSET.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-GETPWNAM.C +$!!! CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) GETPWUID.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-HPWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-VALIDATE.C diff --git a/driver/compile_decc.com b/driver/compile_decc.com new file mode 100644 index 00000000..d6ed0e8a --- /dev/null +++ b/driver/compile_decc.com @@ -0,0 +1,15 @@ +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DEMO.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DIALOGS-XM.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) LOCK.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) PASSWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) STDERR.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) SUBPROCS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) TIMERS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) WINDOWS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSCREENSAVER-COMMAND.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) XSCREENSAVER.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSET.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-GETPWNAM.C +$!!! CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) GETPWUID.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-HPWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-VALIDATE.C diff --git a/driver/demo.c b/driver/demo.c new file mode 100644 index 00000000..2e387460 --- /dev/null +++ b/driver/demo.c @@ -0,0 +1,1859 @@ +/* demo.c --- implements the interactive demo-mode and options dialogs. + * xscreensaver, Copyright (c) 1993-1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#ifdef FORCE_ATHENA +# undef HAVE_MOTIF +# undef HAVE_GTK +# define HAVE_ATHENA 1 +#endif +#ifdef FORCE_GTK +# undef HAVE_MOTIF +# undef HAVE_ATHENA +# define HAVE_GTK 1 +#endif +#ifdef FORCE_MOTIF +# undef HAVE_GTK +# undef HAVE_ATHENA +# define HAVE_MOTIF 1 +#endif + +/* Only one, please. */ +#ifdef HAVE_MOTIF +# undef HAVE_ATHENA +# undef HAVE_GTK +#endif +#ifdef HAVE_GTK +# undef HAVE_MOTIF +# undef HAVE_ATHENA +#endif +#ifdef HAVE_ATHENA +# undef HAVE_MOTIF +# undef HAVE_GTK +#endif + + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifndef VMS +# include /* for getpwuid() */ +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + +#ifdef HAVE_UNAME +# include /* for uname() */ +#endif /* HAVE_UNAME */ + +#include + +#include +#include + +/* We don't actually use any widget internals, but these are included + so that gdb will have debug info for the widgets... */ +#include +#include + +#ifdef HAVE_XMU +# ifndef VMS +# include +# else /* VMS */ +# include +# endif +#else +# include "xmu.h" +#endif + + +#ifdef HAVE_MOTIF +# include +# include +# include +# include +# include +# include +# include + +#elif defined(HAVE_ATHENA) + /* Athena demo code contributed by Jon A. Christopher */ + /* Copyright 1997, with the same permissions as above. */ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +#elif defined(HAVE_GTK) +# include +extern Display *gdk_display; +#endif /* HAVE_ATHENA */ + +#include "version.h" +#include "prefs.h" +#include "resources.h" /* for parse_time() */ +#include "visual.h" /* for has_writable_cells() */ +#include "remote.h" /* for xscreensaver_command() */ +#include "usleep.h" + +#include +#include +#include + +#ifdef HAVE_GTK +# define WIDGET GtkWidget * +# define POINTER gpointer +#else +# define WIDGET Widget +# define POINTER XtPointer +#endif + + + +char *progname = 0; +char *progclass = "XScreenSaver"; +XrmDatabase db; + +typedef struct { + saver_preferences *a, *b; +} prefs_pair; + + +char *blurb (void) { return progname; } + +static void run_hack (Display *dpy, int n); + +#ifdef HAVE_ATHENA +static saver_preferences *global_prefs_kludge = 0; /* I hate C so much... */ +#endif /* HAVE_ATHENA */ + +static char *short_version = 0; + +Atom XA_VROOT; +Atom XA_SCREENSAVER, XA_SCREENSAVER_RESPONSE, XA_SCREENSAVER_VERSION; +Atom XA_SCREENSAVER_TIME, XA_SCREENSAVER_ID, XA_SELECT, XA_DEMO, XA_RESTART; + +extern void create_demo_dialog (Widget, Visual *, Colormap); +extern void create_preferences_dialog (Widget, Visual *, Colormap); + +extern WIDGET demo_dialog; +extern WIDGET label1; +extern WIDGET text_line; +extern WIDGET text_activate; +extern WIDGET demo_form; +extern WIDGET demo_list; +extern WIDGET next; +extern WIDGET prev; +extern WIDGET done; +extern WIDGET restart; +extern WIDGET edit; + +extern WIDGET preferences_dialog; +extern WIDGET preferences_form; +extern WIDGET prefs_done; +extern WIDGET prefs_cancel; +extern WIDGET timeout_text; +extern WIDGET cycle_text; +extern WIDGET fade_text; +extern WIDGET fade_ticks_text; +extern WIDGET lock_timeout_text; +extern WIDGET passwd_timeout_text; +extern WIDGET verbose_toggle; +extern WIDGET install_cmap_toggle; +extern WIDGET fade_toggle; +extern WIDGET unfade_toggle; +extern WIDGET lock_toggle; + + +#ifdef HAVE_MOTIF + +# define set_toggle_button_state(toggle,state) \ + XmToggleButtonSetState ((toggle), (state), True) +# define set_text_string(text_widget,string) \ + XmTextSetString ((text_widget), (string)) +# define add_button_callback(button,cb,arg) \ + XtAddCallback ((button), XmNactivateCallback, (cb), (arg)) +# define add_toggle_callback(button,cb,arg) \ + XtAddCallback ((button), XmNvalueChangedCallback, (cb), (arg)) +# define add_text_callback add_toggle_callback +# define disable_widget(widget) \ + XtVaSetValues((widget), XtNsensitive, False, 0) +# define widget_name(widget) XtName(widget) +# define widget_display(widget) XtDisplay(widget) +# define widget_screen(widget) XtScreen(widget) +# define CB_ARGS(a,b,c) (a,b,c) + +#elif defined(HAVE_ATHENA) + +# define set_toggle_button_state(toggle,state) \ + XtVaSetValues((toggle), XtNstate, (state), 0) +# define set_text_string(text_widget,string) \ + XtVaSetValues ((text_widget), XtNvalue, (string), 0) +# define add_button_callback(button,cb,arg) \ + XtAddCallback ((button), XtNcallback, (cb), (arg)) +# define add_toggle_callback add_button_callback +# define add_text_callback(b,c,a) ERROR! +# define disable_widget(widget) \ + XtVaSetValues((widget), XtNsensitive, False, 0) +# define widget_name(widget) XtName(widget) +# define widget_display(widget) XtDisplay(widget) +# define widget_screen(widget) XtScreen(widget) +# define CB_ARGS(a,b,c) (a,b,c) + +#elif defined(HAVE_GTK) + +# define set_toggle_button_state(toggle,state) \ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(toggle),(state)) +# define set_text_string(text_widget,string) \ + gtk_entry_set_text (GTK_ENTRY (text_widget), (string)) +# define add_button_callback(button,cb,arg) \ + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", \ + GTK_SIGNAL_FUNC (cb), (arg)) +# define add_toggle_callback(button,cb,arg) \ + gtk_signal_connect_object (GTK_OBJECT (button), "toggled", \ + GTK_SIGNAL_FUNC (cb), (arg)) +# define add_text_callback(button,cb,arg) \ + gtk_signal_connect_object (GTK_OBJECT (button), "activate", \ + GTK_SIGNAL_FUNC (cb), (arg)) +# define disable_widget(widget) \ + gtk_widget_set_sensitive (GTK_WIDGET(widget), FALSE) +# define widget_name(widget) gtk_widget_get_name(GTK_WIDGET(widget)) +# define widget_display(widget) (gdk_display) +# define widget_screen(widget) (DefaultScreenOfDisplay(widget_display(widget))) +# define CB_ARGS(a,b,c) (b,a) + +#endif /* HAVE_GTK */ + + + + +static char * +get_text_string (WIDGET text_widget) +{ +#ifdef HAVE_MOTIF + return XmTextGetString (text_widget); +#elif defined(HAVE_ATHENA) + char *string = 0; + if (XtIsSubclass(text_widget, textWidgetClass)) + XtVaGetValues (text_widget, XtNstring, &string, 0); + else if (XtIsSubclass(text_widget, dialogWidgetClass)) + XtVaGetValues (text_widget, XtNvalue, &string, 0); + else + string = 0; + + return string; +#elif defined(HAVE_GTK) + return gtk_entry_get_text (GTK_ENTRY (text_widget)); +#endif /* HAVE_GTK */ +} + + +static char * +get_label_string (WIDGET label_widget) +{ +#ifdef HAVE_MOTIF + char *label = 0; + XmString xm_label = 0; + XtVaGetValues (label_widget, XmNlabelString, &xm_label, 0); + if (!xm_label) + return 0; + XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label); + return label; +#elif defined(HAVE_ATHENA) + char *label = 0; + XtVaGetValues (label_widget, XtNlabel, &label, 0); + return (label ? strdup(label) : 0); +#elif defined(HAVE_GTK) + char *label = 0; + gtk_label_get (GTK_LABEL (label_widget), &label); + return label; +#endif /* HAVE_GTK */ +} + + +static void +set_label_string (WIDGET label_widget, char *string) +{ +#ifdef HAVE_MOTIF + XmString xm_string = XmStringCreate (string, XmSTRING_DEFAULT_CHARSET); + XtVaSetValues (label_widget, XmNlabelString, xm_string, 0); + XmStringFree (xm_string); +#elif defined(HAVE_ATHENA) + XtVaSetValues (label_widget, XtNlabel, string, 0); +#elif defined(HAVE_GTK) + gtk_label_set_text (GTK_LABEL (label_widget), string); +#endif /* HAVE_GTK */ +} + + +/* Given a label widget that has a %s in it, do the printf thing. + If the label's string is obviously wrong, complain about resource lossage. + */ +static void +format_into_label (WIDGET label, const char *arg) +{ + char *text = get_label_string (label); + char *buf = (char *) malloc ((text ? strlen(text) : 0) + strlen(arg) + 100); + + if (!text || !*text || !strcmp (text, widget_name (label))) + strcpy (buf, "ERROR: RESOURCES ARE NOT INSTALLED CORRECTLY"); + else + sprintf (buf, text, arg); + + set_label_string (label, buf); + free (buf); + +# ifndef HAVE_GTK + XtFree (text); +# endif /* HAVE_GTK */ +} + + +/* Why this behavior isn't automatic in *either* toolkit, I'll never know. + */ +static void +ensure_selected_item_visible (WIDGET list) +{ +#ifdef HAVE_MOTIF + int *pos_list = 0; + int pos_count = 0; + if (XmListGetSelectedPos (list, &pos_list, &pos_count) && pos_count > 0) + { + int top = -2; + int visible = 0; + XtVaGetValues (list, + XmNtopItemPosition, &top, + XmNvisibleItemCount, &visible, + 0); + if (pos_list[0] >= top + visible) + { + int pos = pos_list[0] - visible + 1; + if (pos < 0) pos = 0; + XmListSetPos (list, pos); + } + else if (pos_list[0] < top) + { + XmListSetPos (list, pos_list[0]); + } + } + if (pos_list) + XtFree ((char *) pos_list); + +#elif defined(HAVE_ATHENA) +# ifdef HAVE_XawViewportSetCoordinates + + int margin = 16; /* should be line height or something. */ + int count = 0; + int pos; + Dimension list_h = 0, vp_h = 0; + Dimension top_margin = 4; /* I don't know where this value comes from */ + Position vp_x = 0, vp_y = 0, current_y; + double cratio; + Widget viewport = XtParent(demo_list); + Widget sb = (viewport ? XtNameToWidget(viewport, "*vertical") : 0); + float sb_top = 0, sb_size = 0; + XawListReturnStruct *current = XawListShowCurrent(demo_list); + if (!current || !sb) return; + + XtVaGetValues(demo_list, + XtNnumberStrings, &count, + XtNheight, &list_h, + 0); + if (count < 2 || list_h < 10) return; + + XtVaGetValues(viewport, XtNheight, &vp_h, XtNx, &vp_x, XtNy, &vp_y, 0); + if (vp_h < 10) return; + + XtVaGetValues(sb, XtNtopOfThumb, &sb_top, XtNshown, &sb_size, 0); + if (sb_size <= 0) return; + + pos = current->list_index; + cratio = ((double) pos) / ((double) count); + current_y = (cratio * list_h); + + if (cratio < sb_top || + cratio > sb_top + sb_size) + { + if (cratio < sb_top) + current_y -= (vp_h - margin - margin); + else + current_y -= margin; + + if ((long)current_y >= (long) list_h) + current_y = (Position) ((long)list_h - (long)vp_h); + + if ((long)current_y < (long)top_margin) + current_y = (Position)top_margin; + + XawViewportSetCoordinates (viewport, vp_x, current_y); + } +# endif /* HAVE_XawViewportSetCoordinates */ +#elif defined(HAVE_GTK) + + GtkScrolledWindow *scroller = GTK_SCROLLED_WINDOW (list); + GtkViewport *vp = GTK_VIEWPORT (GTK_BIN(scroller)->child); + GtkList *list_widget = GTK_LIST (GTK_BIN(vp)->child); + GList *kids; + int nkids = 0; + GtkWidget *selected = 0; + int which = -1; + GtkAdjustment *adj; + gint parent_h, child_y, child_h, children_h, ignore; + double ratio_t, ratio_b; + + GList *slist = list_widget->selection; + selected = (slist ? GTK_WIDGET (slist->data) : 0); + if (!selected) + return; + + which = gtk_list_child_position (list_widget, GTK_WIDGET (selected)); + + for (kids = gtk_container_children (GTK_CONTAINER (list_widget)); + kids; kids = kids->next) + nkids++; + + adj = gtk_scrolled_window_get_vadjustment (scroller); + + gdk_window_get_geometry (GTK_WIDGET(vp)->window, + &ignore, &ignore, &ignore, &parent_h, &ignore); + gdk_window_get_geometry (GTK_WIDGET(selected)->window, + &ignore, &child_y, &ignore, &child_h, &ignore); + children_h = nkids * child_h; + + ratio_t = ((double) child_y) / ((double) children_h); + ratio_b = ((double) child_y + child_h) / ((double) children_h); + + if (ratio_t < (adj->value / adj->upper) || + ratio_b > ((adj->value + adj->page_size) / adj->upper)) + { + double target; + + if (ratio_t < (adj->value / adj->upper)) + { + double ratio_w = ((double) parent_h) / ((double) children_h); + double ratio_l = (ratio_b - ratio_t); + target = ((ratio_t - ratio_w + ratio_l) * adj->upper); + } + else /* if (ratio_b > ((adj->value + adj->page_size) / adj->upper))*/ + { + target = ratio_t * adj->upper; + } + + if (target > adj->upper - adj->page_size) + target = adj->upper - adj->page_size; + if (target < 0) + target = 0; + + gtk_adjustment_set_value (adj, target); + } + + +#endif /* HAVE_GTK */ +} + + +/* Callback for the text area: + - note the text the user has entered; + - change the corresponding element in `screenhacks'; + - write the .xscreensaver file; + - tell the xscreensaver daemon to run that hack. + + (Note: in GTK, this one has a different arg list than the other callbacks.) + */ +static void +#ifdef HAVE_GTK +text_cb (WIDGET text_widget, POINTER client_data) +#else /* !HAVE_GTK */ +text_cb (WIDGET text_widget, POINTER client_data, POINTER call_data) +#endif /* !HAVE_GTK */ +{ + saver_preferences *p = (saver_preferences *) client_data; + char *new_text = get_text_string (text_widget); + Display *dpy = widget_display (text_widget); + Bool save = TRUE; + + int hack_number = -1; /* 0-based */ + +#ifdef HAVE_ATHENA + XawListReturnStruct *current = XawListShowCurrent(demo_list); + hack_number = current->list_index; +#elif defined(HAVE_MOTIF) + int *pos_list = 0; + int pos_count = 0; + if (XmListGetSelectedPos (demo_list, &pos_list, &pos_count)) + hack_number = pos_list[0] - 1; + if (pos_list) + XtFree ((char *) pos_list); +#elif defined(HAVE_GTK) + GList *slist = + GTK_LIST (GTK_BIN(GTK_BIN(demo_list)->child)->child)->selection; + GtkWidget *selected = (slist ? GTK_WIDGET (slist->data) : 0); + if (selected) + hack_number = + gtk_list_child_position ( + GTK_LIST (GTK_BIN(GTK_BIN(demo_list)->child)->child), + GTK_WIDGET (selected)); +#endif /* HAVE_GTK */ + + ensure_selected_item_visible (demo_list); + + if (hack_number < 0 || hack_number >= p->screenhacks_count) + { + set_text_string (text_widget, ""); +#ifdef HAVE_GTK + gdk_beep(); +#else /* !HAVE_GTK */ + XBell (XtDisplay (text_widget), 0); +#endif /* !HAVE_GTK */ + } + else + { + if (p->screenhacks [hack_number]) + free (p->screenhacks [hack_number]); + p->screenhacks [hack_number] = strdup (new_text); + +#ifdef HAVE_MOTIF + + XmListDeselectAllItems (demo_list); + { + XmString xmstr = XmStringCreate (new_text, XmSTRING_DEFAULT_CHARSET); + XmListReplaceItemsPos (demo_list, &xmstr, 1, hack_number+1); + XmStringFree (xmstr); + } + XmListSelectPos (demo_list, hack_number+1, True); + +#elif defined(HAVE_ATHENA) + + { + Widget vp = XtParent(demo_list); + Widget sb = (vp ? XtNameToWidget(vp, "*vertical") : 0); + Dimension list_h = 0; + Position vp_x = 0, vp_y = 0; + float sb_top = 0; + + XawListUnhighlight (demo_list); + + XtVaGetValues (vp, XtNx, &vp_x, 0); + XtVaGetValues (sb, XtNtopOfThumb, &sb_top, 0); + XtVaGetValues (demo_list, XtNheight, &list_h, 0); + vp_y = (sb_top * list_h); + XtVaSetValues (demo_list, + XtNlist, p->screenhacks, + XtNnumberStrings, p->screenhacks_count, + 0); + XawViewportSetCoordinates (vp, vp_x, vp_y); + XawListHighlight (demo_list, hack_number); + } + +#elif defined(HAVE_GTK) + { + GtkList *list_widget = + GTK_LIST (GTK_BIN(GTK_BIN(demo_list)->child)->child); + GList *slist = list_widget->selection; + GtkWidget *selected = (slist ? GTK_WIDGET (slist->data) : 0); + GtkLabel *label = (selected + ? GTK_LABEL (GTK_BIN (selected)->child) : 0); + char *old_text = 0; + gtk_label_get (label, &old_text); + save = !!strcmp (new_text, old_text); + if (label) + gtk_label_set_text (label, new_text); + } +#endif /* HAVE_GTK */ + + if (save) + write_init_file (p, short_version); + + XSync (dpy, False); + usleep (500000); /* give the disk time to settle down */ + + run_hack (dpy, hack_number+1); + } +} + + +#ifdef HAVE_ATHENA +/* Bend over backwards to make hitting Return in the text field do the + right thing. + */ +static void text_enter (Widget w, XEvent *event, String *av, Cardinal *ac) +{ + text_cb (w, global_prefs_kludge, 0); /* I hate C so much... */ +} + +static XtActionsRec actions[] = {{"done", text_enter} + }; +static char translations[] = ("Return: done()\n" + "Linefeed: done()\n" + "CtrlM: done()\n" + "CtrlJ: done()\n"); +#endif /* HAVE_ATHENA */ + + +#ifdef HAVE_GTK +/* Helper for the Gtk versions of the Run Next and Run Previous buttons. + */ +static void +next_internal (GtkEntry *entry, gboolean next_p) +{ + GtkScrolledWindow *scroller = GTK_SCROLLED_WINDOW (demo_list); + GtkList *list_widget = GTK_LIST(GTK_BIN(GTK_BIN(scroller)->child)->child); + GtkWidget *target = 0; + GList *kids; + int nkids = 0; + int n; + + GList *slist = list_widget->selection; + target = (slist ? GTK_WIDGET (slist->data) : 0); + + for (kids = gtk_container_children (GTK_CONTAINER (list_widget)); + kids; kids = kids->next) + nkids++; + + if (target) + { + n = gtk_list_child_position (GTK_LIST (list_widget), target); + n += (next_p ? 1 : -1); + if (n >= nkids) n = 0; + if (n < 0) n = nkids-1; + } + else if (next_p) + n = 0; + else + n = nkids-1; + + gtk_list_select_item (GTK_LIST (list_widget), n); + + ensure_selected_item_visible ((WIDGET) scroller); + + run_hack (widget_display (scroller), n + 1); +} + +#endif /* HAVE_GTK */ + + + +/* Callback for the Run Next button. + */ +static void +next_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ +#ifdef HAVE_ATHENA + XawListReturnStruct *current = XawListShowCurrent(demo_list); + int cnt; + XtVaGetValues (demo_list, XtNnumberStrings, &cnt, 0); + if (current->list_index == XAW_LIST_NONE || + current->list_index + 1 >= cnt) + current->list_index = 0; + else + current->list_index++; + XawListHighlight(demo_list, current->list_index); + + ensure_selected_item_visible (demo_list); + current = XawListShowCurrent(demo_list); + XtVaSetValues(text_line, XtNstring, current->string, 0); + + run_hack (XtDisplay (button), current->list_index + 1); + +#elif defined(HAVE_MOTIF) + + saver_preferences *p = (saver_preferences *) client_data; + int *pos_list = 0; + int pos_count = 0; + int pos; + if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count)) + { + pos = 1; + XmListDeselectAllItems (demo_list); /* LessTif lossage */ + XmListSelectPos (demo_list, pos, True); + } + else + { + pos = pos_list[0] + 1; + if (pos > p->screenhacks_count) + pos = 1; + XmListDeselectAllItems (demo_list); /* LessTif lossage */ + XmListSelectPos (demo_list, pos, True); + } + + ensure_selected_item_visible (demo_list); + run_hack (XtDisplay (button), pos); + if (pos_list) + XtFree ((char *) pos_list); + +#elif defined(HAVE_GTK) + next_internal (GTK_ENTRY (text_line), TRUE); +#endif /* HAVE_GTK */ +} + + +/* Callback for the Run Previous button. + */ +static void +prev_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ +#ifdef HAVE_ATHENA + XawListReturnStruct *current = XawListShowCurrent(demo_list); + int cnt; + XtVaGetValues (demo_list, XtNnumberStrings, &cnt, 0); + if (current->list_index == XAW_LIST_NONE || + current->list_index <= 0) + current->list_index = cnt-1; + else + current->list_index--; + XawListHighlight(demo_list, current->list_index); + + ensure_selected_item_visible (demo_list); + current = XawListShowCurrent(demo_list); + XtVaSetValues(text_line, XtNstring, current->string, 0); + + run_hack (XtDisplay (button), current->list_index + 1); + +#elif defined(HAVE_MOTIF) + + saver_preferences *p = (saver_preferences *) client_data; + int *pos_list = 0; + int pos_count = 0; + int pos; + if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count)) + { + pos = p->screenhacks_count; + XmListDeselectAllItems (demo_list); /* LessTif lossage */ + XmListSelectPos (demo_list, pos, True); + } + else + { + pos = pos_list[0] - 1; + if (pos == 0) + pos = p->screenhacks_count; + XmListDeselectAllItems (demo_list); /* LessTif lossage */ + XmListSelectPos (demo_list, pos, True); + } + + ensure_selected_item_visible (demo_list); + run_hack (XtDisplay (button), pos); + if (pos_list) + XtFree ((char *) pos_list); + +#elif defined(HAVE_GTK) + next_internal (GTK_ENTRY (text_line), FALSE); +#endif /* HAVE_GTK */ +} + + +/* Callback run when a list element is double-clicked. + (Note: in GTK, this one has a different arg list than the other callbacks.) + */ +#ifdef HAVE_GTK +static gint +select_cb (GtkWidget *button, GdkEventButton *event, gpointer client_data) +#else /* !HAVE_GTK */ +static void +select_cb (WIDGET button, POINTER client_data, POINTER call_data) +#endif /* !HAVE_GTK */ +{ +/* saver_preferences *p = (saver_preferences *) client_data; */ + +#ifdef HAVE_ATHENA + XawListReturnStruct *item = (XawListReturnStruct*)call_data; + XtVaSetValues(text_line, XtNstring, item->string, 0); + run_hack (XtDisplay (button), item->list_index + 1); + +#elif defined(HAVE_MOTIF) + XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data; + char *string = 0; + if (lcb->item) + XmStringGetLtoR (lcb->item, XmSTRING_DEFAULT_CHARSET, &string); + set_text_string (text_line, (string ? string : "")); + + if (lcb->reason == XmCR_DEFAULT_ACTION && string) + run_hack (XtDisplay (button), lcb->item_position); + + if (string) + XtFree (string); + +#elif defined(HAVE_GTK) + char *string = 0; + gtk_label_get (GTK_LABEL (GTK_BIN(button)->child), &string); + set_text_string (text_line, (string ? string : "")); + + if (event->type == GDK_2BUTTON_PRESS) + { + GtkViewport *vp = GTK_VIEWPORT (GTK_BIN(demo_list)->child); + GtkList *lw = GTK_LIST (GTK_BIN(vp)->child); + int which = gtk_list_child_position (lw, GTK_WIDGET (button)); + run_hack (gdk_display, which + 1); + } + + return FALSE; +#endif /* HAVE_GTK */ +} + + +static void pop_preferences_dialog (prefs_pair *pair); +static void make_preferences_dialog (prefs_pair *pair, Widget parent); + +/* Callback for the Preferences button. + */ +static void +preferences_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ + prefs_pair *pair = (prefs_pair *) client_data; +#ifdef HAVE_GTK + Widget parent = 0; +#else /* !HAVE_GTK */ + Widget parent = button; + + do { + parent = XtParent(parent); + } while (XtParent(parent)); +#endif /* !HAVE_GTK */ + + if (! preferences_dialog) + make_preferences_dialog (pair, parent); + *pair->b = *pair->a; + pop_preferences_dialog (pair); +} + + +/* Callback for the Quit button. + */ +static void +quit_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ + /* Save here? Right now we don't need to, because we save every time + the text field is edited, or the Preferences OK button is pressed. + */ + exit (0); +} + + +/* Callback for the (now unused) Restart button. + */ +static void +restart_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ + xscreensaver_command (widget_display (button), XA_RESTART, 0, False); +} + + +static void +pop_up_dialog_box (WIDGET dialog, WIDGET form) +{ +#ifdef HAVE_ATHENA + XtRealizeWidget (dialog); + XtPopup (dialog, XtGrabNone); +#elif defined(HAVE_MOTIF) + XtRealizeWidget (form); + XtManageChild (form); +#endif /* HAVE_MOTIF */ + +#ifdef HAVE_GTK + gtk_widget_show (dialog); + gdk_window_show (GTK_WIDGET (dialog)->window); + gdk_window_raise (GTK_WIDGET (dialog)->window); +#else /* !HAVE_GTK */ + XMapRaised (XtDisplay (dialog), XtWindow (dialog)); +#endif /* !HAVE_GTK */ +} + + +#ifdef HAVE_GTK +/* Callback for WM_DELETE_WINDOW on the main demo window. + */ +static void +destroy (GtkWidget *widget, gpointer data) +{ + gtk_main_quit (); +} + +/* Callback for the "Run" button to the right of the text entry line. + */ +static void +select_button_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ + gtk_signal_emit_by_name (GTK_OBJECT (text_line), "activate"); +} +#endif /* HAVE_GTK */ + + +static void +make_demo_dialog (Widget toplevel_shell, prefs_pair *pair) +{ + saver_preferences *p = pair->a; + /* saver_preferences *p2 = pair->b; */ + Widget parent = toplevel_shell; + char **hacks = p->screenhacks; + + create_demo_dialog (parent, + DefaultVisualOfScreen (widget_screen (parent)), + DefaultColormapOfScreen (widget_screen (parent))); + +#ifdef HAVE_GTK + gtk_window_set_title (GTK_WINDOW (demo_dialog), progclass); + gtk_signal_connect (GTK_OBJECT (demo_dialog), "delete_event", + GTK_SIGNAL_FUNC (destroy), NULL); + gtk_signal_connect (GTK_OBJECT (demo_dialog), "destroy", + GTK_SIGNAL_FUNC (destroy), NULL); +#endif /* HAVE_GTK */ + + format_into_label (label1, short_version); + add_button_callback (next, next_cb, (POINTER) p); + add_button_callback (prev, prev_cb, (POINTER) p); + add_button_callback (done, quit_cb, (POINTER) p); + if (restart) + add_button_callback(restart,restart_cb, (POINTER) p); + add_button_callback (edit, preferences_cb, (POINTER) pair); + +#ifdef HAVE_MOTIF + XtAddCallback (demo_list, XmNbrowseSelectionCallback, + select_cb, (POINTER) p); + XtAddCallback (demo_list, XmNdefaultActionCallback, + select_cb, (POINTER) p); + XtAddCallback (text_line, XmNactivateCallback, text_cb, (POINTER) p); + + if (hacks) + for (; *hacks; hacks++) + { + XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET); + XmListAddItem (demo_list, xmstr, 0); + XmStringFree (xmstr); + } + +#elif defined(HAVE_ATHENA) + + /* Hook up the text line. */ + + XtAppAddActions(XtWidgetToApplicationContext(text_line), + actions, XtNumber(actions)); + XtOverrideTranslations(text_line, XtParseTranslationTable(translations)); + + + /* Must realize the widget before populating the list, or the dialog + will be as wide as the longest string. + */ + XtRealizeWidget (demo_dialog); + + XtVaSetValues (demo_list, + XtNlist, hacks, + XtNnumberStrings, p->screenhacks_count, + 0); + XtAddCallback (demo_list, XtNcallback, select_cb, p); + + /* Now that we've populated the list, make sure that the list is as + wide as the dialog itself. + */ + { + Widget viewport = XtParent(demo_list); + Widget subform = XtParent(viewport); + Widget box = XtNameToWidget(demo_dialog, "*box"); + Widget label1 = XtNameToWidget(demo_dialog, "*label1"); + Widget label2 = XtNameToWidget(demo_dialog, "*label2"); + Dimension x=0, y=0, w=0, h=0, bw=0, w2=0; + XtVaGetValues(subform, + XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0); + XtVaGetValues(box, XtNwidth, &w2, 0); + if (w2 != w) + XtResizeWidget(subform, w2, h, bw); + + /* Why isn't the viewport getting centered? */ + XtVaGetValues(viewport, + XtNx, &x, XtNy, &y, XtNheight, &h, XtNborderWidth, &bw, 0); + XtConfigureWidget(viewport, x, y, w2-x-x, h, bw); + + /* And the text line, too. */ + XtVaGetValues(text_line, + XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0); + XtVaGetValues(viewport, XtNwidth, &w2, 0); + if (w2 != w) + XtResizeWidget(text_line, w2, h, bw); + + /* And the labels too. */ + XtVaGetValues(label1, + XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0); + if (w2 != w) + XtResizeWidget(label1, w2, h, bw); + + XtVaGetValues(label2, + XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0); + if (w2 != w) + XtResizeWidget(label2, w2, h, bw); + + } + +#elif defined(HAVE_GTK) + { + GtkList *list = GTK_LIST(GTK_BIN(GTK_BIN(demo_list)->child)->child); + char **s; + for (s = hacks; *s; s++) + { + GtkWidget *line = gtk_list_item_new_with_label (*s); + gtk_container_add (GTK_CONTAINER (list), line); + gtk_signal_connect (GTK_OBJECT (line), "button_press_event", + GTK_SIGNAL_FUNC (select_cb), + (POINTER) line); + GTK_WIDGET (GTK_BIN(line)->child)->style = + gtk_style_copy (GTK_WIDGET (text_line)->style); + gtk_widget_show (line); + } + gtk_signal_connect (GTK_OBJECT (text_line), "activate", + GTK_SIGNAL_FUNC (text_cb), + (POINTER) p); + gtk_signal_connect (GTK_OBJECT (text_activate), "clicked", + GTK_SIGNAL_FUNC (select_button_cb), + (POINTER) p); + } +#endif /* HAVE_GTK */ + + pop_up_dialog_box(demo_dialog, demo_form); + +#ifdef HAVE_ATHENA + /* For Athena, have to do this after the dialog is managed. */ + ensure_selected_item_visible (demo_list); +#endif /* HAVE_ATHENA */ +} + + +/* the Preferences dialog + */ + +/* Helper for the text fields that contain time specifications: + this parses the text, and does error checking. + */ +static void +hack_time_text (Display *dpy, char *line, Time *store, Bool sec_p) +{ + if (*line) + { + int value; + value = parse_time (line, sec_p, True); + value *= 1000; /* Time measures in microseconds */ + if (value < 0) + /*XBell (dpy, 0)*/; + else + *store = value; + } +} + + +/* Callback for text fields that hold a time that default to seconds, + when not fully spelled out. client_data is a Time* where the value goes. + */ +static void +prefs_sec_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ + hack_time_text (widget_display (button), get_text_string (button), + (Time *) client_data, True); +} + + +/* Callback for text fields that hold a time that default to minutes, + when not fully spelled out. client_data is an Time* where the value goes. + */ +static void +prefs_min_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ + hack_time_text (widget_display (button), get_text_string (button), + (Time *) client_data, False); +} + + +/* Callback for text fields that hold an integer value. + client_data is an int* where the value goes. + */ +static void +prefs_int_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ + char *line = get_text_string (button); + int *store = (int *) client_data; + unsigned int value; + char c; + if (! *line) + ; + else if (sscanf (line, "%u%c", &value, &c) != 1) +#ifdef HAVE_GTK + gdk_beep(); +#else /* !HAVE_GTK */ + XBell (XtDisplay (button), 0); +#endif /* !HAVE_GTK */ + else + *store = value; +} + + +/* Callback for toggle buttons. client_data is a Bool* where the value goes. + */ +static void +prefs_bool_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data) +{ + Bool *store = (Bool *) client_data; +#ifdef HAVE_MOTIF + *store = ((XmToggleButtonCallbackStruct *) call_data)->set; +#elif defined(HAVE_ATHENA) + Boolean state = FALSE; + XtVaGetValues (button, XtNstate, &state, 0); + *store = state; +#elif defined(HAVE_GTK) + *store = GTK_TOGGLE_BUTTON (button)->active; +#endif /* HAVE_GTK */ +} + + +/* Callback for the Cancel button on the Preferences dialog. + */ +static void +prefs_cancel_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) +{ +#ifdef HAVE_GTK + gdk_window_hide (GTK_WIDGET (preferences_dialog)->window); + gtk_widget_show (demo_dialog); + gdk_window_show (GTK_WIDGET (demo_dialog)->window); + gdk_window_raise (GTK_WIDGET (demo_dialog)->window); +#else /* !HAVE_GTK */ + XtDestroyWidget (preferences_dialog); + preferences_dialog = 0; + XMapRaised (XtDisplay (demo_dialog), XtWindow (demo_dialog)); +#endif /* !HAVE_GTK */ +} + + +/* Callback for the OK button on the Preferences dialog. + */ +static void +prefs_ok_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data) +{ + prefs_pair *pair = (prefs_pair *) client_data; + saver_preferences *p = pair->a; + saver_preferences *p2 = pair->b; + + prefs_cancel_cb CB_ARGS(button, client_data, call_data); + +#ifdef HAVE_ATHENA + /* Athena doesn't let us put callbacks on these widgets, so run + all the callbacks by hand when OK is pressed. */ + prefs_min_cb (timeout_text, (POINTER) &p2->timeout, 0); + prefs_min_cb (cycle_text, (POINTER) &p2->cycle, 0); + prefs_sec_cb (fade_text, (POINTER) &p2->fade_seconds, 0); + prefs_int_cb (fade_ticks_text, (POINTER) &p2->fade_ticks, 0); + prefs_min_cb (lock_timeout_text, (POINTER) &p2->lock_timeout, 0); + prefs_sec_cb (passwd_timeout_text, (POINTER) &p2->passwd_timeout, 0); +#elif defined(HAVE_GTK) + /* Do it again anyway for GTK. */ + prefs_min_cb ((POINTER) &p2->timeout, timeout_text); + prefs_min_cb ((POINTER) &p2->cycle, cycle_text); + prefs_sec_cb ((POINTER) &p2->fade_seconds, fade_text); + prefs_int_cb ((POINTER) &p2->fade_ticks, fade_ticks_text); + prefs_min_cb ((POINTER) &p2->lock_timeout, lock_timeout_text); + prefs_sec_cb ((POINTER) &p2->passwd_timeout, passwd_timeout_text); +#endif /* HAVE_GTK */ + + p->timeout = p2->timeout; + p->cycle = p2->cycle; + p->lock_timeout = p2->lock_timeout; + p->passwd_timeout = p2->passwd_timeout; + p->fade_seconds = p2->fade_seconds; + p->fade_ticks = p2->fade_ticks; + p->verbose_p = p2->verbose_p; + p->install_cmap_p = p2->install_cmap_p; + p->fade_p = p2->fade_p; + p->unfade_p = p2->unfade_p; + p->lock_p = p2->lock_p; + + write_init_file (p, short_version); +} + + +#ifdef HAVE_GTK +static void +close_prefs_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data) +{ + prefs_cancel_cb CB_ARGS(button, client_data, call_data); +} +#endif /* HAVE_GTK */ + + +static void +make_preferences_dialog (prefs_pair *pair, Widget parent) +{ + saver_preferences *p = pair->a; + saver_preferences *p2 = pair->b; + + Screen *screen = widget_screen (parent); + Display *dpy = widget_display (parent); + + *p2 = *p; /* copy all slots of p into p2. */ + + create_preferences_dialog (parent, + DefaultVisualOfScreen (screen), + DefaultColormapOfScreen (screen)); + +#ifdef HAVE_GTK + gtk_window_set_title (GTK_WINDOW (preferences_dialog), progclass); + gtk_signal_connect (GTK_OBJECT (preferences_dialog), "delete_event", + GTK_SIGNAL_FUNC (close_prefs_cb), NULL); + gtk_signal_connect (GTK_OBJECT (preferences_dialog), "destroy", + GTK_SIGNAL_FUNC (close_prefs_cb), NULL); +#endif /* HAVE_GTK */ + + add_button_callback (prefs_done, prefs_ok_cb, (POINTER) pair); + add_button_callback (prefs_cancel, prefs_cancel_cb, 0); + +#define CB(widget,type,slot) \ + add_text_callback ((widget), (type), (POINTER) (slot)) +#define CBT(widget,type,slot) \ + add_toggle_callback ((widget), (type), (POINTER) (slot)) + +#ifndef HAVE_ATHENA + /* When using Athena widgets, we can't set callbacks for these, + so in that case, we run them by hand when "OK" is pressed. */ + CB (timeout_text, prefs_min_cb, &p2->timeout); + CB (cycle_text, prefs_min_cb, &p2->cycle); + CB (fade_text, prefs_sec_cb, &p2->fade_seconds); + CB (fade_ticks_text, prefs_int_cb, &p2->fade_ticks); + CB (lock_timeout_text, prefs_min_cb, &p2->lock_timeout); + CB (passwd_timeout_text, prefs_sec_cb, &p2->passwd_timeout); + +#endif /* !HAVE_ATHENA */ + + CBT (verbose_toggle, prefs_bool_cb, &p2->verbose_p); + CBT (install_cmap_toggle, prefs_bool_cb, &p2->install_cmap_p); + CBT (fade_toggle, prefs_bool_cb, &p2->fade_p); + CBT (unfade_toggle, prefs_bool_cb, &p2->unfade_p); + CBT (lock_toggle, prefs_bool_cb, &p2->lock_p); +#undef CB +#undef CBT + + { + Bool found_any_writable_cells = False; + int nscreens = ScreenCount(dpy); + int i; + for (i = 0; i < nscreens; i++) + { + Screen *s = ScreenOfDisplay (dpy, i); + if (has_writable_cells (s, DefaultVisualOfScreen (s))) + { + found_any_writable_cells = True; + break; + } + } + + if (! found_any_writable_cells) /* fading isn't possible */ + { + disable_widget (fade_text); + disable_widget (fade_ticks_text); + disable_widget (install_cmap_toggle); + disable_widget (fade_toggle); + disable_widget (unfade_toggle); + } + } +} + + +/* Formats a `Time' into "H:MM:SS". (Time is microseconds.) + */ +static void +format_time (char *buf, Time time) +{ + int s = time / 1000; + unsigned int h = 0, m = 0; + if (s >= 60) + { + m += (s / 60); + s %= 60; + } + if (m >= 60) + { + h += (m / 60); + m %= 60; + } + sprintf (buf, "%u:%02u:%02u", h, m, s); +} + + +static void +pop_preferences_dialog (prefs_pair *pair) +{ + /* saver_preferences *p = pair->a; */ + saver_preferences *p2 = pair->b; + char s[100]; + + format_time (s, p2->timeout); set_text_string(timeout_text, s); + format_time (s, p2->cycle); set_text_string(cycle_text, s); + format_time (s, p2->lock_timeout); set_text_string(lock_timeout_text, s); + format_time (s, p2->passwd_timeout); set_text_string(passwd_timeout_text, s); + format_time (s, p2->fade_seconds); set_text_string(fade_text, s); + sprintf (s, "%u", p2->fade_ticks); set_text_string(fade_ticks_text, s); + + set_toggle_button_state (verbose_toggle, p2->verbose_p); + set_toggle_button_state (install_cmap_toggle, p2->install_cmap_p); + set_toggle_button_state (fade_toggle, p2->fade_p); + set_toggle_button_state (unfade_toggle, p2->unfade_p); + set_toggle_button_state (lock_toggle, p2->lock_p); + + pop_up_dialog_box (preferences_dialog, preferences_form); +} + + +static void +run_hack (Display *dpy, int n) +{ + if (n <= 0) abort(); + xscreensaver_command (dpy, XA_DEMO, n, False); +} + + +static void +warning_dialog_dismiss_cb CB_ARGS(WIDGET button, POINTER client_data, + POINTER ignored) +{ + WIDGET shell = (WIDGET) client_data; +#ifdef HAVE_GTK + gdk_window_hide (GTK_WIDGET (shell)->window); +#else /* !HAVE_GTK */ + XtDestroyWidget (shell); +#endif /* !HAVE_GTK */ +} + + +static void +warning_dialog (WIDGET parent, const char *message) +{ + char *msg = strdup (message); + char *head; + + WIDGET dialog = 0; + WIDGET label = 0; + WIDGET ok = 0; + int i = 0; + +#ifdef HAVE_MOTIF + + Widget w; + Widget container; + XmString xmstr; + Arg av[10]; + int ac = 0; + + ac = 0; + dialog = XmCreateWarningDialog (parent, "versionWarning", av, ac); + + w = XmMessageBoxGetChild (dialog, XmDIALOG_MESSAGE_LABEL); + if (w) XtUnmanageChild (w); + w = XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON); + if (w) XtUnmanageChild (w); + w = XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON); + if (w) XtUnmanageChild (w); + + ok = XmMessageBoxGetChild (dialog, XmDIALOG_OK_BUTTON); + + ac = 0; + XtSetArg (av[ac], XmNnumColumns, 1); ac++; + XtSetArg (av[ac], XmNorientation, XmVERTICAL); ac++; + XtSetArg (av[ac], XmNpacking, XmPACK_COLUMN); ac++; + XtSetArg (av[ac], XmNrowColumnType, XmWORK_AREA); ac++; + XtSetArg (av[ac], XmNspacing, 0); ac++; + container = XmCreateRowColumn (dialog, "container", av, ac); + +#elif defined(HAVE_ATHENA) + + Widget form; + dialog = XtVaCreatePopupShell("warning_dialog", transientShellWidgetClass, + parent, 0); + form = XtVaCreateManagedWidget("warning_form", formWidgetClass, dialog, 0); + +#elif defined(HAVE_GTK) + dialog = gtk_dialog_new (); +#endif /* HAVE_GTK */ + + head = msg; + while (head) + { + char name[20]; + char *s = strchr (head, '\n'); + if (s) *s = 0; + + sprintf (name, "label%d", i++); + +#ifdef HAVE_MOTIF + xmstr = XmStringCreate (head, XmSTRING_DEFAULT_CHARSET); + ac = 0; + XtSetArg (av[ac], XmNlabelString, xmstr); ac++; + label = XmCreateLabelGadget (container, name, av, ac); + XtManageChild (label); + XmStringFree (xmstr); +#elif defined(HAVE_ATHENA) + + label = XtVaCreateManagedWidget (name, labelWidgetClass, + form, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNlabel, head, + (label ? XtNfromVert : XtNtop), + (label ? label : XtChainTop), + 0); + +#elif defined(HAVE_GTK) + { + char buf[255]; + label = gtk_label_new (head); + sprintf (buf, "warning_dialog.%s.font", name); + GTK_WIDGET (label)->style = gtk_style_copy (GTK_WIDGET (label)->style); + GTK_WIDGET (label)->style->font = + gdk_font_load (get_string_resource (buf, "Dialog.Label.Font")); + /* gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); */ + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + label, TRUE, TRUE, 0); + gtk_widget_show (label); + } +#endif /* HAVE_GTK */ + + if (s) + head = s+1; + else + head = 0; + } + +#ifdef HAVE_MOTIF + + XtManageChild (container); + XtRealizeWidget (dialog); + XtManageChild (dialog); + +#elif defined(HAVE_ATHENA) + + ok = XtVaCreateManagedWidget ("ok", commandWidgetClass, form, + XtNleft, XtChainLeft, + XtNbottom, XtChainBottom, + XtNfromVert, label, + 0); + + XtRealizeWidget (dialog); + XtPopup (dialog, XtGrabNone); + +#elif defined(HAVE_GTK) + label = gtk_label_new (""); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + label, TRUE, TRUE, 0); + gtk_widget_show (label); + + label = gtk_hbutton_box_new (); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + label, TRUE, TRUE, 0); + + ok = gtk_button_new_with_label ( + get_string_resource ("warning_dialog.ok.label", + "warning_dialog.Button.Label")); + gtk_box_pack_start (GTK_BOX (label), ok, TRUE, FALSE, 0); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 10); + gtk_widget_show (ok); + gtk_widget_show (label); + gtk_widget_show (dialog); +/* gtk_window_set_default (GTK_WINDOW (dialog), ok);*/ + + gdk_window_set_transient_for (GTK_WIDGET (dialog)->window, + GTK_WIDGET (preferences_dialog + ? preferences_dialog + : demo_dialog)->window); + + gdk_window_show (GTK_WIDGET (dialog)->window); + gdk_window_raise (GTK_WIDGET (dialog)->window); +#endif /* HAVE_GTK */ + + add_button_callback (ok, warning_dialog_dismiss_cb, (POINTER) dialog); + + free (msg); +} + + + +/* The main demo-mode command loop. + */ + +#if 0 +static Bool +mapper (XrmDatabase *db, XrmBindingList bindings, XrmQuarkList quarks, + XrmRepresentation *type, XrmValue *value, XPointer closure) +{ + int i; + for (i = 0; quarks[i]; i++) + { + if (bindings[i] == XrmBindTightly) + fprintf (stderr, (i == 0 ? "" : ".")); + else if (bindings[i] == XrmBindLoosely) + fprintf (stderr, "*"); + else + fprintf (stderr, " ??? "); + fprintf(stderr, "%s", XrmQuarkToString (quarks[i])); + } + + fprintf (stderr, ": %s\n", (char *) value->addr); + + return False; +} +#endif + + +static void +the_network_is_not_the_computer (WIDGET parent) +{ + Display *dpy = widget_display (parent); + char *rversion, *ruser, *rhost; + char *luser, *lhost; + char *msg = 0; + struct passwd *p = getpwuid (getuid ()); + const char *d = DisplayString (dpy); + +# if defined(HAVE_UNAME) + struct utsname uts; + if (uname (&uts) < 0) + lhost = ""; + else + lhost = uts.nodename; +# elif defined(VMS) + strcpy (lhost, getenv("SYS$NODE")); +# else /* !HAVE_UNAME && !VMS */ + strcat (lhost, ""); +# endif /* !HAVE_UNAME && !VMS */ + + if (p && p->pw_name) + luser = p->pw_name; + else + luser = "???"; + + server_xscreensaver_version (dpy, &rversion, &ruser, &rhost); + + /* Make a buffer that's big enough for a number of copies of all the + strings, plus some. */ + msg = (char *) malloc (10 * ((rversion ? strlen(rversion) : 0) + + (ruser ? strlen(ruser) : 0) + + (rhost ? strlen(rhost) : 0) + + strlen(lhost) + + strlen(luser) + + strlen(d) + + 30)); + *msg = 0; + + if (!rversion || !*rversion) + { + sprintf (msg, + "Warning:\n\n" + "xscreensaver doesn't seem to be running on display \"%s\".", + d); + } + else if (p && ruser && *ruser && !!strcmp (ruser, p->pw_name)) + { + /* Warn that the two processes are running as different users. + */ + sprintf(msg, + "Warning:\n\n" + "%s is running as user \"%s\" on host \"%s\".\n" + "But the xscreensaver managing display \"%s\"\n" + "is running as user \"%s\" on host \"%s\".\n" + "\n" + "Since they are different users, they won't be reading/writing\n" + "the same ~/.xscreensaver file, so %s isn't\n" + "going to work right.\n" + "\n" + "Either re-run %s as \"%s\", or re-run\n" + "xscreensaver as \"%s\".\n", + progname, luser, lhost, + d, + (ruser ? ruser : "???"), (rhost ? rhost : "???"), + progname, + progname, (ruser ? ruser : "???"), + luser); + } + else if (rhost && *rhost && !!strcmp (rhost, lhost)) + { + /* Warn that the two processes are running on different hosts. + */ + sprintf (msg, + "Warning:\n\n" + "%s is running as user \"%s\" on host \"%s\".\n" + "But the xscreensaver managing display \"%s\"\n" + "is running as user \"%s\" on host \"%s\".\n" + "\n" + "If those two machines don't share a file system (that is,\n" + "if they don't see the same ~%s/.xscreensaver file) then\n" + "%s won't work right.", + progname, luser, lhost, + d, + (ruser ? ruser : "???"), (rhost ? rhost : "???"), + luser, + progname); + } + else if (!!strcmp (rversion, short_version)) + { + /* Warn that the version numbers don't match. + */ + sprintf (msg, + "Warning:\n\n" + "This is %s version %s.\n" + "But the xscreensaver managing display \"%s\"\n" + "is version %s. This could cause problems.", + progname, short_version, + d, + rversion); + } + + + if (*msg) + warning_dialog (parent, msg); + + free (msg); +} + + +/* We use this error handler so that X errors are preceeded by the name + of the program that generated them. + */ +static int +demo_ehandler (Display *dpy, XErrorEvent *error) +{ + fprintf (stderr, "\nX error in %s:\n", progname); + if (XmuPrintDefaultErrorMessage (dpy, error, stderr)) + exit (-1); + else + fprintf (stderr, " (nonfatal.)\n"); + return 0; +} + + +#ifdef HAVE_GTK + +/* We use this error handler so that Gtk/Gdk errors are preceeded by the name + of the program that generated them; and also that we can ignore one + particular bogus error message that Gdk madly spews. + */ +static void +g_log_handler (const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer user_data) +{ + /* Ignore the message "Got event for unknown window: 0x...". + Apparently some events are coming in for the xscreensaver window + (presumably reply events related to the ClientMessage) and Gdk + feels the need to complain about them. So, just suppress any + messages that look like that one. + */ + if (strstr (message, "unknown window")) + return; + + fprintf (stderr, "%s: %s-%s: %s%s", blurb(), log_domain, + (log_level == G_LOG_LEVEL_ERROR ? "error" : + log_level == G_LOG_LEVEL_CRITICAL ? "critical" : + log_level == G_LOG_LEVEL_WARNING ? "warning" : + log_level == G_LOG_LEVEL_MESSAGE ? "message" : + log_level == G_LOG_LEVEL_INFO ? "info" : + log_level == G_LOG_LEVEL_DEBUG ? "debug" : "???"), + message, + ((!*message || message[strlen(message)-1] != '\n') + ? "\n" : "")); +} +#endif /* HAVE_GTK */ + + + +static char *defaults[] = { +#include "XScreenSaver_ad.h" + 0 +}; + +int +main (int argc, char **argv) +{ + XtAppContext app; + prefs_pair Pair, *pair; + saver_preferences P, P2, *p, *p2; + Bool prefs = False; + int i; + Display *dpy; + Widget toplevel_shell; + char *real_progname = argv[0]; + char *s; + + s = strrchr (real_progname, '/'); + if (s) real_progname = s+1; + + p = &P; + p2 = &P2; + pair = &Pair; + pair->a = p; + pair->b = p2; + memset (p, 0, sizeof (*p)); + memset (p2, 0, sizeof (*p2)); + + progname = real_progname; + +#ifdef HAVE_GTK + /* Register our error message logger for every ``log domain'' known. + There's no way to do this globally, so I grepped the Gtk/Gdk sources + for all of the domains that seem to be in use. + */ + { + const char * const domains[] = { "Gtk", "Gdk", "GLib", "GModule", + "GThread", "Gnome", "GnomeUI", 0 }; + for (i = 0; domains[i]; i++) + g_log_set_handler (domains[i], G_LOG_LEVEL_MASK, g_log_handler, 0); + } + + /* This is gross, but Gtk understands --display and not -display... */ + for (i = 1; i < argc; i++) + if (argv[i][0] && argv[i][1] && + !strncmp(argv[i], "-display", strlen(argv[i]))) + argv[i] = "--display"; + + /* Let Gtk open the X connection, then initialize Xt to use that + same connection. Doctor Frankenstein would be proud. */ + gtk_init (&argc, &argv); +#endif /* HAVE_GTK */ + + + /* We must read exactly the same resources as xscreensaver. + That means we must have both the same progclass *and* progname, + at least as far as the resource database is concerned. So, + put "xscreensaver" in argv[0] while initializing Xt. + */ + argv[0] = "xscreensaver"; + progname = argv[0]; + + +#ifdef HAVE_GTK + /* If we're using Gtk, the X connection is already open. + Now teach Xt about it. + */ + XtToolkitInitialize (); + app = XtCreateApplicationContext (); + dpy = gdk_display; + XtAppSetFallbackResources (app, defaults); + XtDisplayInitialize (app, dpy, progname, progclass, 0, 0, &argc, argv); + toplevel_shell = XtAppCreateShell (progname, progclass, + applicationShellWidgetClass, + dpy, 0, 0); + +#else /* !HAVE_GTK */ + /* No Gtk -- open the X connection here. */ + toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, &argc, argv, + defaults, 0, 0); +#endif /* !HAVE_GTK */ + + dpy = XtDisplay (toplevel_shell); + db = XtDatabase (dpy); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + XSetErrorHandler (demo_ehandler); + + /* Complain about unrecognized command-line arguments. + */ + for (i = 1; i < argc; i++) + { + char *s = argv[i]; + if (s[0] == '-' && s[1] == '-') + s++; + if (!strcmp (s, "-prefs")) + prefs = True; + else + { + fprintf (stderr, "usage: %s [ -display dpy-string ] [ -prefs ]\n", + real_progname); + exit (1); + } + } + + short_version = (char *) malloc (5); + memcpy (short_version, screensaver_id + 17, 4); + short_version [4] = 0; + + /* Load the init file, which may end up consulting the X resource database + and the site-wide app-defaults file. Note that at this point, it's + important that `progname' be "xscreensaver", rather than whatever + was in argv[0]. + */ + p->db = db; + load_init_file (p); + *p2 = *p; + + /* Now that Xt has been initialized, and the resources have been read, + we can set our `progname' variable to something more in line with + reality. + */ + progname = real_progname; + + +#ifdef HAVE_ATHENA + global_prefs_kludge = p; /* I hate C so much... */ +#endif /* HAVE_ATHENA */ + +#if 0 + { + XrmName name = { 0 }; + XrmClass class = { 0 }; + int count = 0; + XrmEnumerateDatabase (db, &name, &class, XrmEnumAllLevels, mapper, + (POINTER) &count); + } +#endif + + + 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_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False); + XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False); + XA_SELECT = XInternAtom (dpy, "SELECT", False); + XA_DEMO = XInternAtom (dpy, "DEMO", False); + XA_RESTART = XInternAtom (dpy, "RESTART", False); + + make_demo_dialog (toplevel_shell, pair); + + if (prefs) + { + make_preferences_dialog (pair, toplevel_shell); + pop_preferences_dialog (pair); + } + + the_network_is_not_the_computer (preferences_dialog + ? preferences_dialog + : demo_dialog); + +#ifdef HAVE_GTK + + /* Run the Gtk event loop, and not the Xt event loop. This means that + if there were Xt timers or fds registered, they would never get serviced, + and if there were any Xt widgets, they would never have events delivered. + Fortunately, we're using Gtk for all of the UI, and only initialized + Xt so that we could process the command line and use the X resource + manager. + */ + gtk_main (); + +#else /* !HAVE_GTK */ + + XtAppMainLoop (app); + +#endif /* !HAVE_GTK */ + + exit (0); +} diff --git a/driver/dialogs-Gtk.c b/driver/dialogs-Gtk.c new file mode 100644 index 00000000..2d16dc9f --- /dev/null +++ b/driver/dialogs-Gtk.c @@ -0,0 +1,249 @@ +/* dialogs-Gtk.c --- Gtk widgets for demo, options, and password dialogs. + * xscreensaver, Copyright (c) 1999 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include "resources.h" + +#include + +GtkWidget *preferences_dialog; +GtkWidget *preferences_form; +GtkWidget *timeout_text; +GtkWidget *cycle_text; +GtkWidget *fade_text; +GtkWidget *fade_ticks_text; +GtkWidget *lock_timeout_text; +GtkWidget *passwd_timeout_text; +GtkWidget *verbose_toggle; +GtkWidget *install_cmap_toggle; +GtkWidget *fade_toggle; +GtkWidget *unfade_toggle; +GtkWidget *lock_toggle; +GtkWidget *prefs_done; +GtkWidget *prefs_cancel; + +GtkWidget *demo_dialog; +GtkWidget *demo_form; +GtkWidget *label1; +GtkWidget *label2; +GtkWidget *demo_list; +GtkWidget *text_line; +GtkWidget *text_activate; +GtkWidget *next; +GtkWidget *prev; +GtkWidget *edit; +GtkWidget *done; +GtkWidget *restart; /* #### */ + +/* This is a Gtk program that uses Xrm for localization and preferences -- + may god forgive me for what I have unleashed. */ +static char * +STR (char *resource) +{ + return (get_string_resource (resource, resource)); +} + + +void +create_preferences_dialog (void *ignore1, void *ignore2, void *ignore3) +{ + GtkWidget *window, *box1, *box2, *box3; + GtkWidget *label; + GtkWidget *timeout_label; + GtkWidget *cycle_label; + GtkWidget *faded_label; + GtkWidget *fade_ticks_label; + GtkWidget *lock_timeout_label; + GtkWidget *passwd_timeout_label; + int entry_width; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width (GTK_CONTAINER (window), 10); + + box1 = gtk_vbox_new (FALSE, 6); + box2 = gtk_table_new (6, 3, FALSE); + box3 = gtk_hbutton_box_new (); + + /* Create the labels. */ + label = gtk_label_new (STR("preferences_dialog.label1.label")); + timeout_label = gtk_label_new (STR("preferences_dialog.timeout.label")); + cycle_label = gtk_label_new (STR("preferences_dialog.cycle.label")); + faded_label = gtk_label_new (STR("preferences_dialog.fade.label")); + fade_ticks_label = gtk_label_new (STR("preferences_dialog.ticks.label")); + lock_timeout_label = gtk_label_new(STR("preferences_dialog.lockTime.label")); + passwd_timeout_label = + gtk_label_new (STR("preferences_dialog.passwdTime.label")); + + /* Make the labels right-justify. */ + gtk_misc_set_alignment (GTK_MISC (timeout_label), 1.0, 0.5); + gtk_misc_set_alignment (GTK_MISC (cycle_label), 1.0, 0.5); + gtk_misc_set_alignment (GTK_MISC (faded_label), 1.0, 0.5); + gtk_misc_set_alignment (GTK_MISC (fade_ticks_label), 1.0, 0.5); + gtk_misc_set_alignment (GTK_MISC (lock_timeout_label), 1.0, 0.5); + gtk_misc_set_alignment (GTK_MISC (passwd_timeout_label), 1.0, 0.5); + + prefs_done = + gtk_button_new_with_label (STR("preferences_dialog.done.label")); + prefs_cancel = + gtk_button_new_with_label (STR("preferences_dialog.cancel.label")); + + /* Create the text-entry widgets. */ + timeout_text = gtk_entry_new_with_max_length (8); + cycle_text = gtk_entry_new_with_max_length (8); + fade_text = gtk_entry_new_with_max_length (8); + fade_ticks_text = gtk_entry_new_with_max_length (8); + lock_timeout_text = gtk_entry_new_with_max_length (8); + passwd_timeout_text = gtk_entry_new_with_max_length (8); + + /* Set their sizes. */ + entry_width = gdk_text_width (GTK_WIDGET (timeout_text)->style->font, + "00:00:00 ", 9); + gtk_widget_set_usize (GTK_WIDGET (timeout_text), entry_width, -2); + gtk_widget_set_usize (GTK_WIDGET (cycle_text), entry_width, -2); + gtk_widget_set_usize (GTK_WIDGET (fade_text), entry_width, -2); + gtk_widget_set_usize (GTK_WIDGET (fade_ticks_text), entry_width, -2); + gtk_widget_set_usize (GTK_WIDGET (lock_timeout_text), entry_width, -2); + gtk_widget_set_usize (GTK_WIDGET (passwd_timeout_text), entry_width, -2); + + verbose_toggle = gtk_check_button_new_with_label + (STR("preferences_dialog.buttonbox.verbose.label")); + install_cmap_toggle = gtk_check_button_new_with_label + (STR("preferences_dialog.buttonbox.cmap.label")); + fade_toggle = gtk_check_button_new_with_label + (STR("preferences_dialog.buttonbox.fade.label")); + unfade_toggle = gtk_check_button_new_with_label + (STR("preferences_dialog.buttonbox.unfade.label")); + lock_toggle = gtk_check_button_new_with_label + (STR("preferences_dialog.buttonbox.lock.label")); + + gtk_box_pack_start (GTK_BOX(box1), label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box1), box2, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box1), box3, FALSE, FALSE, 0); + +# define FROB(widget, x, y) \ + gtk_table_attach_defaults (GTK_TABLE(box2), widget, x, x+1, y, y+1) + + FROB (timeout_label, 0, 0); + FROB (cycle_label, 0, 1); + FROB (faded_label, 0, 2); + FROB (fade_ticks_label, 0, 3); + FROB (lock_timeout_label, 0, 4); + FROB (passwd_timeout_label, 0, 5); + + FROB (timeout_text, 1, 0); + FROB (cycle_text, 1, 1); + FROB (fade_text, 1, 2); + FROB (fade_ticks_text, 1, 3); + FROB (lock_timeout_text, 1, 4); + FROB (passwd_timeout_text, 1, 5); + + FROB (verbose_toggle, 2, 0); + FROB (install_cmap_toggle, 2, 1); + FROB (fade_toggle, 2, 2); + FROB (unfade_toggle, 2, 3); + FROB (lock_toggle, 2, 4); +# undef FROB + gtk_table_set_col_spacings (GTK_TABLE(box2), 10); + + gtk_box_pack_start (GTK_BOX(box3), prefs_done, TRUE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box3), prefs_cancel, TRUE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (window), box1); + + gtk_widget_show_all (window); + + preferences_dialog = window; + preferences_form = window; +} + + +void +create_demo_dialog (void *ignore1, void *ignore2, void *ignore3) +{ + GtkWidget *window, *box1, *box2, *box3, *list; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + /* Set the minimum size. */ + gtk_widget_set_usize (GTK_WIDGET (window), 1, 1); + + /* Set the default size. */ + gtk_window_set_default_size (GTK_WINDOW (window), 600, 300); + + gtk_container_set_border_width (GTK_CONTAINER (window), 10); + + box1 = gtk_vbox_new (FALSE, 6); + box2 = gtk_hbutton_box_new (); + box3 = gtk_hbox_new (FALSE, 6); + list = gtk_list_new (); + + label1 = gtk_label_new (STR("label1.label")); + label2 = gtk_label_new (STR("label2.label")); + + demo_list = gtk_scrolled_window_new (0, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (demo_list), + GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (demo_list), + list); + gtk_widget_show (list); + + text_line = gtk_entry_new (); + gtk_entry_set_editable (GTK_ENTRY (text_line), TRUE); + text_activate = gtk_button_new_with_label (STR("demo_dialog.run.label")); + + GTK_WIDGET (text_line)->style = + gtk_style_copy (GTK_WIDGET (text_line)->style); + GTK_WIDGET (text_line)->style->font = + gdk_font_load (STR("demo_dialog.Text.font")); + + next = gtk_button_new_with_label (STR("demo_dialog.next.label")); + prev = gtk_button_new_with_label (STR("demo_dialog.prev.label")); + edit = gtk_button_new_with_label (STR("demo_dialog.edit.label")); + done = gtk_button_new_with_label (STR("demo_dialog.done.label")); + + gtk_widget_show (box1); + gtk_widget_show (box2); + gtk_widget_show (box3); + gtk_widget_show (label1); + gtk_widget_show (label2); + gtk_widget_show (demo_list); + gtk_widget_show (text_activate); + gtk_widget_show (text_line); + gtk_widget_show (next); + gtk_widget_show (prev); + gtk_widget_show (edit); + gtk_widget_show (done); + + gtk_box_pack_start (GTK_BOX(box3), text_line, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX(box3), text_activate, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX(box1), label1, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box1), label2, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box1), demo_list, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX(box1), box3, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box1), box2, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX(box2), next, TRUE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box2), prev, TRUE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box2), edit, TRUE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(box2), done, TRUE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (window), box1); + + demo_dialog = window; + demo_form = window; +} diff --git a/driver/dialogs-Xaw.c b/driver/dialogs-Xaw.c new file mode 100644 index 00000000..757a91eb --- /dev/null +++ b/driver/dialogs-Xaw.c @@ -0,0 +1,259 @@ +/* dialogs-Xaw.c --- Athena widgets for demo, options, and password dialogs. + * xscreensaver, Copyright (c) 1997, 1998 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. + * + * Most of this code contributed by Jon A. Christopher + * Copyright 1997, with the same permissions as above. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "visual.h" /* for visual_depth() */ + +Widget preferences_dialog; +Widget preferences_form; +Widget timeout_text; +Widget cycle_text; +Widget fade_text; +Widget fade_ticks_text; +Widget lock_timeout_text; +Widget passwd_timeout_text; +Widget verbose_toggle; +Widget install_cmap_toggle; +Widget fade_toggle; +Widget unfade_toggle; +Widget lock_toggle; +Widget prefs_done; +Widget prefs_cancel; + +Widget demo_dialog; +Widget demo_form; +Widget label1; +/*Widget label2;*/ +/*Widget text_area;*/ +Widget demo_list; +Widget text_line; +/*Widget vline;*/ +Widget next; +Widget prev; +Widget edit; +Widget done; +Widget restart; +/*Widget spacer;*/ + +static Widget buttonbox, textbox, okbox; + + +void +create_preferences_dialog(Widget parent, Visual *visual, Colormap colormap) +{ + Widget rlabel; + int depth = visual_depth(XtScreen(parent), visual); + + preferences_dialog = + XtVaCreatePopupShell("preferences_dialog", transientShellWidgetClass, parent, + XtNvisual, visual, + XtNcolormap, colormap, + XtNdepth, depth, + NULL); + + preferences_form = + XtVaCreateManagedWidget("preferences_form", formWidgetClass, + preferences_dialog, + XtNvisual, visual, + XtNcolormap, colormap, + XtNdepth, depth, + NULL); + + rlabel = XtVaCreateManagedWidget("label1", labelWidgetClass, preferences_form, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNtop, XtChainTop, + NULL); + + textbox= + XtVaCreateManagedWidget("textbox", formWidgetClass, preferences_form, + XtNleft, XtChainLeft, + XtNfromVert, rlabel, + NULL); + okbox= + XtVaCreateManagedWidget("textbox", boxWidgetClass, preferences_form, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNfromVert, textbox, + XtNorientation, XtorientHorizontal, + NULL); + timeout_text= + XtVaCreateManagedWidget("timeout", dialogWidgetClass, textbox, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNtop, XtChainTop, + NULL); + cycle_text= + XtVaCreateManagedWidget("cycle", dialogWidgetClass, textbox, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNfromVert, timeout_text, + NULL); + fade_text= + XtVaCreateManagedWidget("fade", dialogWidgetClass, textbox, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNfromVert, cycle_text, + NULL); + + fade_ticks_text = + XtVaCreateManagedWidget("ticks", dialogWidgetClass, textbox, + XtNtop, XtChainTop, + XtNright, XtChainRight, + XtNfromHoriz, timeout_text, + NULL); + + lock_timeout_text = + XtVaCreateManagedWidget("lockTime", dialogWidgetClass, textbox, + XtNfromVert, fade_ticks_text, + XtNright, XtChainRight, + XtNfromHoriz, cycle_text, + NULL); + + passwd_timeout_text = + XtVaCreateManagedWidget("passwdTime", dialogWidgetClass, textbox, + XtNfromVert, lock_timeout_text, + XtNright, XtChainRight, + XtNfromHoriz, fade_text, + NULL); + + buttonbox= + XtVaCreateManagedWidget("buttonbox", boxWidgetClass, preferences_form, + XtNfromVert, rlabel, + XtNfromHoriz, textbox, + XtNright, XtChainRight, + XtNorientation, XtorientVertical, + NULL); + verbose_toggle = + XtVaCreateManagedWidget("verbose", toggleWidgetClass, buttonbox, + NULL); + install_cmap_toggle = + XtVaCreateManagedWidget("cmap", toggleWidgetClass, buttonbox, + NULL); + fade_toggle = + XtVaCreateManagedWidget("fade", toggleWidgetClass, buttonbox, + NULL); + unfade_toggle = + XtVaCreateManagedWidget("unfade", toggleWidgetClass, buttonbox, + NULL); + lock_toggle = + XtVaCreateManagedWidget("lock", toggleWidgetClass, buttonbox, + NULL); + + + prefs_done = XtVaCreateManagedWidget("done", commandWidgetClass, okbox, + NULL); + prefs_cancel = XtVaCreateManagedWidget("cancel", commandWidgetClass, okbox, + NULL); +} + +void +create_demo_dialog(Widget parent, Visual *visual, Colormap colormap) +{ + Widget subform, box, viewport, label2; + int depth = visual_depth(XtScreen(parent), visual); + + demo_dialog = + XtVaCreatePopupShell("demo_dialog", transientShellWidgetClass, parent, + XtNvisual, visual, + XtNcolormap, colormap, + XtNdepth, depth, + NULL); + + demo_form = + XtVaCreateManagedWidget("demo_form", formWidgetClass, demo_dialog, + XtNvisual, visual, + XtNcolormap, colormap, + XtNdepth, depth, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNtop, XtChainTop, + NULL); + + label1 = XtVaCreateManagedWidget("label1", labelWidgetClass, demo_form, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNtop, XtChainTop, + NULL); + + label2 = XtVaCreateManagedWidget("label2", labelWidgetClass, demo_form, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNfromVert, label1, + NULL); + + subform = + XtVaCreateManagedWidget("subform", formWidgetClass, demo_form, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNfromVert, label2, + XtNresizable, True, + NULL); + viewport = + XtVaCreateManagedWidget("viewport", viewportWidgetClass, subform, + XtNtop, XtChainTop, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNallowVert, TRUE, + XtNallowHoriz, TRUE, + XtNforceBars, TRUE, + NULL); + + demo_list = XtVaCreateManagedWidget("demo_list", listWidgetClass, viewport, + XtNverticalList, TRUE, + XtNdefaultColumns, 1, + NULL); + + text_line = XtVaCreateManagedWidget("text", asciiTextWidgetClass, subform, + XtNleft, XtChainLeft, + XtNright, XtChainRight, + XtNfromVert, viewport, + XtNbottom, XtChainBottom, + XtNeditType, XawtextEdit, + NULL); + + box = + XtVaCreateManagedWidget("box", boxWidgetClass, demo_form, + XtNleft, XtChainLeft, + XtNfromVert, subform, + XtNbottom, XtChainBottom, + XtNright, XtChainRight, + XtNorientation, XtEhorizontal, + NULL); + next = XtVaCreateManagedWidget("next", commandWidgetClass, box, NULL); + prev = XtVaCreateManagedWidget("prev", commandWidgetClass, box, NULL); + edit = XtVaCreateManagedWidget("edit", commandWidgetClass, box, NULL); +#if 0 + restart = XtVaCreateManagedWidget("restart", commandWidgetClass, box, NULL); +#endif + done = XtVaCreateManagedWidget("done", commandWidgetClass, box, NULL); +} diff --git a/driver/dialogs-Xm.c b/driver/dialogs-Xm.c new file mode 100644 index 00000000..930b7b72 --- /dev/null +++ b/driver/dialogs-Xm.c @@ -0,0 +1,573 @@ +/* dialogs-Xm.c --- Motif widgets for demo, options, and password dialogs. + * xscreensaver, Copyright (c) 1993-1998 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. + */ + +/* The code in this file started off its life as the output of XDesigner, + but I've since hacked it by hand... It's a mess, avert your eyes. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "visual.h" /* for visual_depth() */ + +Widget preferences_dialog; +Widget preferences_form; +Widget timeout_text; +Widget cycle_text; +Widget fade_text; +Widget fade_ticks_text; +Widget lock_timeout_text; +Widget passwd_timeout_text; +Widget verbose_toggle; +Widget install_cmap_toggle; +Widget fade_toggle; +Widget unfade_toggle; +Widget lock_toggle; +Widget prefs_done; +Widget prefs_cancel; + +Widget demo_dialog; +Widget demo_form; +Widget label1; +Widget label2; +Widget text_area; +Widget demo_list; +Widget text_line; +Widget vline; +Widget next; +Widget prev; +Widget edit; +Widget done; +Widget restart; +Widget spacer; + +void +create_preferences_dialog(Widget parent, Visual *visual, Colormap colormap) +{ + Widget children[22]; /* Children to manage */ + Arg al[64]; /* Arg List */ + register int ac = 0; /* Arg Count */ + Widget widget12; + Widget widget13; + Widget widget14; + Widget widget15; + Widget widget16; + Widget widget17; + Widget widget18; + Widget widget48; + Widget widget29; + + Widget real_dialog; + Widget w; + + ac = 0; + XtSetArg (al[ac], XmNvisual, visual); ac++; + XtSetArg (al[ac], XmNcolormap, colormap); ac++; + XtSetArg (al[ac], XmNdepth, visual_depth(XtScreen(parent), visual)); ac++; + + real_dialog = XmCreatePromptDialog (parent, "preferencesForm", al, ac); + preferences_dialog = XtParent(real_dialog); + + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_SEPARATOR); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_TEXT); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_SELECTION_LABEL); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_HELP_BUTTON); + if (w) XtUnmanageChild (w); + + ac = 0; + XtSetArg (al [ac], XmNtopAttachment, XmATTACH_FORM); ac++; + XtSetArg (al [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; + XtSetArg (al [ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg (al [ac], XmNrightAttachment, XmATTACH_FORM); ac++; + preferences_form = XmCreateForm (real_dialog, "form", al, ac); + XtManageChild (preferences_form); + + ac = 0; + + widget12 = XmCreateLabel ( preferences_form, "preferencesLabel", al, ac ); + widget13 = XmCreateSeparator ( preferences_form, "separator", al, ac ); + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_END); ac++; + widget14 = XmCreateLabel ( preferences_form, "timeoutLabel", al, ac ); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_END); ac++; + widget15 = XmCreateLabel ( preferences_form, "cycleLabel", al, ac ); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_END); ac++; + widget16 = XmCreateLabel ( preferences_form, "fadeSecondsLabel", al, ac ); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_END); ac++; + widget17 = XmCreateLabel ( preferences_form, "fadeTicksLabel", al, ac ); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_END); ac++; + widget18 = XmCreateLabel ( preferences_form, "lockLabel", al, ac ); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_END); ac++; + widget48 = XmCreateLabel ( preferences_form, "passwdLabel", al, ac ); + ac = 0; + timeout_text = XmCreateTextField ( preferences_form, "timeoutText", al, ac ); + cycle_text = XmCreateTextField ( preferences_form, "cycleText", al, ac ); + fade_text = XmCreateTextField ( preferences_form, "fadeSecondsText", al, ac); + fade_ticks_text = XmCreateTextField ( preferences_form, "fadeTicksText", al, ac); + lock_timeout_text = XmCreateTextField ( preferences_form, "passwdText", al, ac); + passwd_timeout_text = XmCreateTextField ( preferences_form, "lockText", al, ac); + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + verbose_toggle = XmCreateToggleButton (preferences_form,"verboseToggle",al,ac); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + install_cmap_toggle = XmCreateToggleButton ( preferences_form, "cmapToggle", al, ac); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + fade_toggle = XmCreateToggleButton ( preferences_form, "fadeToggle", al, ac); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + unfade_toggle = XmCreateToggleButton (preferences_form,"unfadeToggle",al,ac); + ac = 0; + XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + lock_toggle = XmCreateToggleButton ( preferences_form, "lockToggle", al, ac); + ac = 0; + widget29 = XmCreateSeparator ( preferences_form, "separator", al, ac ); + + prefs_done = XmSelectionBoxGetChild (real_dialog, XmDIALOG_OK_BUTTON); + prefs_cancel = XmSelectionBoxGetChild (real_dialog, XmDIALOG_CANCEL_BUTTON); + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 4); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetValues ( widget12,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNtopWidget, widget12); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 0); ac++; + XtSetValues ( widget13,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNtopWidget, widget13); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomWidget, timeout_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 20); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetArg(al[ac], XmNrightWidget, timeout_text); ac++; + XtSetValues ( widget14,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, cycle_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, cycle_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 20); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetArg(al[ac], XmNrightWidget, cycle_text); ac++; + XtSetValues ( widget15,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, fade_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, fade_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 20); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetArg(al[ac], XmNrightWidget, fade_text); ac++; + XtSetValues ( widget16,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, fade_ticks_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, fade_ticks_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 20); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetArg(al[ac], XmNrightWidget, fade_ticks_text); ac++; + XtSetValues ( widget17,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, lock_timeout_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, lock_timeout_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 19); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetArg(al[ac], XmNrightWidget, lock_timeout_text); ac++; + XtSetValues ( widget18,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, passwd_timeout_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, passwd_timeout_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 14); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetArg(al[ac], XmNrightWidget, passwd_timeout_text); ac++; + XtSetValues ( widget48,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNtopWidget, widget13); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 141); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++; + XtSetValues ( timeout_text,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 2); ac++; + XtSetArg(al[ac], XmNtopWidget, timeout_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, timeout_text); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++; + XtSetValues ( cycle_text,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 2); ac++; + XtSetArg(al[ac], XmNtopWidget, cycle_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, cycle_text); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++; + XtSetValues ( fade_text,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 2); ac++; + XtSetArg(al[ac], XmNtopWidget, fade_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, fade_text); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++; + XtSetValues ( fade_ticks_text,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 2); ac++; + XtSetArg(al[ac], XmNtopWidget, fade_ticks_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, fade_ticks_text); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++; + XtSetValues ( lock_timeout_text,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNtopWidget, lock_timeout_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, lock_timeout_text); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++; + XtSetValues ( passwd_timeout_text,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNtopWidget, widget13); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, timeout_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 20); ac++; + XtSetArg(al[ac], XmNleftWidget, timeout_text); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 20); ac++; + XtSetValues ( verbose_toggle,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, cycle_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, cycle_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, verbose_toggle); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 20); ac++; + XtSetValues ( install_cmap_toggle,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, fade_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, fade_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, install_cmap_toggle); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 20); ac++; + XtSetValues ( fade_toggle,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, fade_ticks_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, fade_ticks_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, fade_toggle); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 20); ac++; + XtSetValues ( unfade_toggle,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, lock_timeout_text); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNbottomOffset, 0); ac++; + XtSetArg(al[ac], XmNbottomWidget, lock_timeout_text); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; + XtSetArg(al[ac], XmNleftOffset, 0); ac++; + XtSetArg(al[ac], XmNleftWidget, unfade_toggle); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 20); ac++; + XtSetValues ( lock_toggle,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 0); ac++; + XtSetArg(al[ac], XmNtopWidget, passwd_timeout_text); ac++; + + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNbottomOffset, 4); ac++; + + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetValues ( widget29,al, ac ); + ac = 0; + + + + ac = 0; + children[ac++] = widget12; + children[ac++] = widget13; + children[ac++] = widget14; + children[ac++] = widget15; + children[ac++] = widget16; + children[ac++] = widget17; + children[ac++] = widget18; + children[ac++] = widget48; + children[ac++] = timeout_text; + children[ac++] = cycle_text; + children[ac++] = fade_text; + children[ac++] = fade_ticks_text; + children[ac++] = lock_timeout_text; + children[ac++] = passwd_timeout_text; + children[ac++] = verbose_toggle; + children[ac++] = install_cmap_toggle; + children[ac++] = fade_toggle; + children[ac++] = unfade_toggle; + children[ac++] = lock_toggle; + children[ac++] = widget29; + + XtManageChildren(children, ac); + ac = 0; + + preferences_form = real_dialog; +} + + +void +create_demo_dialog(Widget parent, Visual *visual, Colormap colormap) +{ + Arg al[64]; /* Arg List */ + register int ac = 0; /* Arg Count */ + + Widget real_dialog; + Widget w; + + + ac = 0; + XtSetArg (al[ac], XmNvisual, visual); ac++; + XtSetArg (al[ac], XmNcolormap, colormap); ac++; + XtSetArg (al[ac], XmNdepth, visual_depth(XtScreen(parent), visual)); ac++; + + + real_dialog = XmCreatePromptDialog (parent, "demoForm", al, ac); + demo_dialog = XtParent(real_dialog); + + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_SEPARATOR); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_TEXT); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_SELECTION_LABEL); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_OK_BUTTON); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_CANCEL_BUTTON); + if (w) XtUnmanageChild (w); + w = XmSelectionBoxGetChild (real_dialog, XmDIALOG_HELP_BUTTON); + if (w) XtUnmanageChild (w); + + ac = 0; + XtSetArg (al [ac], XmNtopAttachment, XmATTACH_FORM); ac++; + XtSetArg (al [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; + XtSetArg (al [ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg (al [ac], XmNrightAttachment, XmATTACH_FORM); ac++; + demo_form = XmCreateForm (real_dialog, "form", al, ac); + XtManageChild (demo_form); + + label1 = XmCreateLabel ( demo_form, "label1", al, ac ); + label2 = XmCreateLabel ( demo_form, "label2", al, ac ); + demo_list = XmCreateScrolledList ( demo_form, "demoList", al, ac ); + text_area = XtParent ( demo_list ); + + ac = 0; + text_line = XmSelectionBoxGetChild (real_dialog, XmDIALOG_TEXT); + XtManageChild(text_line); + + /* #### ARRGH! This is apparently the only way to make hitting return in + the text field not *ALSO* activate the most-recently-selected button! + + This has the unfortunate side effect of making the buttons not be + keyboard-traversable, but that's less bad than not being able to try + out new switches by typing them into the text field. + + XmSelectionBox(3M) says in the "Additional Behavior" section: + KActivate: + Calls the activate callbacks for the button with + the keyboard focus. [... ] In a List widget or + single-line Text widget, the List or Text action + associated with KActivate is called before the + SelectionBox actions associated with KActivate." + + So they take it as a given that when running activateCallback on a single- + line Text widget, you'll also want to run activateCallback on whatever the + currently-focussed button is as well! Morons! Villains! Shitheads! + + (Perhaps there's some way to override XmSelectionBox's KActivate behavior. + I doubt it, but if there is, I don't know it.) + */ + ac = 0; + XtSetArg(al[ac], XmNtraversalOn, False); ac++; + + next = XmCreatePushButton ( real_dialog, "next", al, ac ); + prev = XmCreatePushButton ( real_dialog, "prev", al, ac ); + edit = XmCreatePushButton ( real_dialog, "edit", al, ac ); + done = XmCreatePushButton ( real_dialog, "done", al, ac ); +#if 0 + restart = XmCreatePushButton ( real_dialog, "restart", al, ac ); +#endif + XtManageChild(next); + XtManageChild(prev); + XtManageChild(edit); + XtManageChild(done); +#if 0 + XtManageChild(restart); +#endif + + ac = 0; + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNtopOffset, 5); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 4); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetValues ( label1,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNtopWidget, label1); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 4); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetValues ( label2,al, ac ); + ac = 0; + + XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; + XtSetArg(al[ac], XmNtopOffset, 4); ac++; + XtSetArg(al[ac], XmNtopWidget, label2); ac++; + XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNleftOffset, 4); ac++; + XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; + XtSetArg(al[ac], XmNrightOffset, 4); ac++; + XtSetValues ( text_area,al, ac ); + + XtManageChild(demo_list); + XtManageChild(label1); + XtManageChild(label2); + + demo_form = real_dialog; +} diff --git a/driver/link_axp.com b/driver/link_axp.com new file mode 100644 index 00000000..a1418927 --- /dev/null +++ b/driver/link_axp.com @@ -0,0 +1,15 @@ +$! We fisrt test the version of DECW/Motif ; if 1.2 we need to link with new +$! X11R5 libraries +$@sys$update:decw$get_image_version sys$share:decw$xlibshr.exe decw$version +$ if f$extract(4,3,decw$version).eqs."1.2" +$ then +$! DECW/Motif 1.2 : link with X11R5 libraries +$ link xscreensaver-command,vms_axp_12.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_axp_12.opt/opt +$ else +$! Else, link with X11R4 libraries +$ link xscreensaver-command,vms_axp.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_axp.opt/opt +$ endif diff --git a/driver/link_decc.com b/driver/link_decc.com new file mode 100644 index 00000000..d1de0d0a --- /dev/null +++ b/driver/link_decc.com @@ -0,0 +1,15 @@ +$! We fisrt test the version of DECW/Motif ; if 1.2 we need to link with new +$! X11R5 libraries +$@sys$update:decw$get_image_version sys$share:decw$xlibshr.exe decw$version +$ if f$extract(4,3,decw$version).eqs."1.2" +$ then +$! DECW/Motif 1.2 : link with X11R5 libraries +$ link xscreensaver-command,vms_decc_12.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_decc_12.opt/opt +$ else +$! Else, link with X11R4 libraries +$ link xscreensaver-command,vms_decc.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_decc.opt/opt +$ endif diff --git a/driver/lock.c b/driver/lock.c new file mode 100644 index 00000000..ce12efb4 --- /dev/null +++ b/driver/lock.c @@ -0,0 +1,1191 @@ +/* lock.c --- handling the password dialog for locking-mode. + * xscreensaver, Copyright (c) 1993-1998 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. + */ + +/* Athena locking code contributed by Jon A. Christopher */ +/* Copyright 1997, with the same permissions as above. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#include "xscreensaver.h" +#include "resources.h" + +#ifdef HAVE_SYSLOG +# include +#endif /* HAVE_SYSLOG */ + +#ifdef HAVE_XHPDISABLERESET +# include + static void hp_lock_reset (saver_info *si, Bool lock_p); +#endif /* HAVE_XHPDISABLERESET */ + +#ifdef HAVE_VT_LOCKSWITCH +# include +# include +# include + static void linux_lock_vt_switch (saver_info *si, Bool lock_p); +#endif /* HAVE_VT_LOCKSWITCH */ + +#ifdef HAVE_XF86VMODE +# include + static void xfree_lock_mode_switch (saver_info *si, Bool lock_p); +#endif /* HAVE_XF86VMODE */ + + +#ifdef _VROOT_H_ +ERROR! You must not include vroot.h in this file. +#endif + +#ifndef VMS +# include +#else /* VMS */ + +extern char *getenv(const char *name); +extern int validate_user(char *name, char *password); + +static Bool +vms_passwd_valid_p(char *pw, Bool verbose_p) +{ + return (validate_user (getenv("USER"), typed_passwd) == 1); +} +# undef passwd_valid_p +# define passwd_valid_p vms_passwd_valid_p + +#endif /* VMS */ + + +#undef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) + +enum passwd_state { pw_read, pw_ok, pw_null, pw_fail, pw_cancel, pw_time }; + +struct passwd_dialog_data { + + enum passwd_state state; + char typed_passwd [80]; + XtIntervalId timer; + int i_beam; + + float ratio; + Position x, y; + Dimension width; + Dimension height; + Dimension border_width; + + char *heading_label; + char *body_label; + char *user_label; + char *passwd_label; + char *user_string; + char *passwd_string; + + XFontStruct *heading_font; + XFontStruct *body_font; + XFontStruct *label_font; + XFontStruct *passwd_font; + + Pixel foreground; + Pixel background; + Pixel passwd_foreground; + Pixel passwd_background; + Pixel logo_foreground; + Pixel logo_background; + Pixel shadow_top; + Pixel shadow_bottom; + + Dimension logo_width; + Dimension logo_height; + Dimension thermo_width; + Dimension internal_border; + Dimension shadow_width; + + Dimension passwd_field_x, passwd_field_y; + Dimension passwd_field_width, passwd_field_height; + + Dimension thermo_field_x, thermo_field_y; + Dimension thermo_field_height; + + Pixmap save_under; +}; + +static void draw_passwd_window (saver_info *si); +static void update_passwd_window (saver_info *si, const char *printed_passwd, + float ratio); +static void destroy_passwd_window (saver_info *si); +static void undo_vp_motion (saver_info *si); + + +static void +make_passwd_window (saver_info *si) +{ + struct passwd *p = getpwuid (getuid ()); + XSetWindowAttributes attrs; + unsigned long attrmask = 0; + Screen *screen = si->default_screen->screen; + passwd_dialog_data *pw = (passwd_dialog_data *) calloc (1, sizeof(*pw)); + Colormap cmap = DefaultColormapOfScreen (screen); + char *f; + + pw->ratio = 1.0; + + pw->heading_label = get_string_resource ("passwd.heading.label", + "Dialog.Label.Label"); + pw->body_label = get_string_resource ("passwd.body.label", + "Dialog.Label.Label"); + pw->user_label = get_string_resource ("passwd.user.label", + "Dialog.Label.Label"); + pw->passwd_label = get_string_resource ("passwd.passwd.label", + "Dialog.Label.Label"); + + if (!pw->heading_label) + pw->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!pw->body_label) + pw->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!pw->user_label) pw->user_label = strdup("ERROR"); + if (!pw->passwd_label) pw->passwd_label = strdup("ERROR"); + + /* Put the version number in the label. */ + { + char *s = (char *) malloc (strlen(pw->heading_label) + 20); + sprintf(s, pw->heading_label, si->version); + free (pw->heading_label); + pw->heading_label = s; + } + + pw->user_string = (p->pw_name ? p->pw_name : "???"); + pw->passwd_string = strdup(""); + + f = get_string_resource ("passwd.headingFont", "Dialog.Font"); + pw->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!pw->heading_font) pw->heading_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + f = get_string_resource("passwd.bodyFont", "Dialog.Font"); + pw->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!pw->body_font) pw->body_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + f = get_string_resource("passwd.labelFont", "Dialog.Font"); + pw->label_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!pw->label_font) pw->label_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + f = get_string_resource("passwd.passwdFont", "Dialog.Font"); + pw->passwd_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + pw->foreground = get_pixel_resource ("passwd.foreground", + "Dialog.Foreground", + si->dpy, cmap); + pw->background = get_pixel_resource ("passwd.background", + "Dialog.Background", + si->dpy, cmap); + + if (pw->foreground == pw->background) + { + /* Make sure the error messages show up. */ + pw->foreground = BlackPixelOfScreen (screen); + pw->background = WhitePixelOfScreen (screen); + } + + pw->passwd_foreground = get_pixel_resource ("passwd.text.foreground", + "Dialog.Text.Foreground", + si->dpy, cmap); + pw->passwd_background = get_pixel_resource ("passwd.text.background", + "Dialog.Text.Background", + si->dpy, cmap); + pw->logo_foreground = get_pixel_resource ("passwd.logo.foreground", + "Dialog.Logo.Foreground", + si->dpy, cmap); + pw->logo_background = get_pixel_resource ("passwd.logo.background", + "Dialog.Logo.Background", + si->dpy, cmap); + pw->shadow_top = get_pixel_resource ("passwd.topShadowColor", + "Dialog.Foreground", + si->dpy, cmap); + pw->shadow_bottom = get_pixel_resource ("passwd.bottomShadowColor", + "Dialog.Background", + si->dpy, cmap); + + pw->logo_width = get_integer_resource ("passwd.logo.width", + "Dialog.Logo.Width"); + pw->logo_height = get_integer_resource ("passwd.logo.height", + "Dialog.Logo.Height"); + pw->thermo_width = get_integer_resource ("passwd.thermometer.width", + "Dialog.Thermometer.Width"); + pw->internal_border = get_integer_resource ("passwd.internalBorderWidth", + "Dialog.InternalBorderWidth"); + pw->shadow_width = get_integer_resource ("passwd.shadowThickness", + "Dialog.ShadowThickness"); + + if (pw->logo_width == 0) pw->logo_width = 150; + if (pw->logo_height == 0) pw->logo_height = 150; + if (pw->internal_border == 0) pw->internal_border = 15; + if (pw->shadow_width == 0) pw->shadow_width = 4; + if (pw->thermo_width == 0) pw->thermo_width = pw->shadow_width; + + { + int direction, ascent, descent; + XCharStruct overall; + + pw->width = 0; + pw->height = 0; + + /* Measure the heading_label. */ + XTextExtents (pw->heading_font, + pw->heading_label, strlen(pw->heading_label), + &direction, &ascent, &descent, &overall); + if (overall.width > pw->width) pw->width = overall.width; + pw->height += ascent + descent; + + /* Measure the body_label. */ + XTextExtents (pw->body_font, + pw->body_label, strlen(pw->body_label), + &direction, &ascent, &descent, &overall); + if (overall.width > pw->width) pw->width = overall.width; + pw->height += ascent + descent; + + { + Dimension w2 = 0, w3 = 0; + Dimension h2 = 0, h3 = 0; + const char *passwd_string = "MMMMMMMMMMMM"; + + /* Measure the user_label. */ + XTextExtents (pw->label_font, + pw->user_label, strlen(pw->user_label), + &direction, &ascent, &descent, &overall); + if (overall.width > w2) w2 = overall.width; + h2 += ascent + descent; + + /* Measure the passwd_label. */ + XTextExtents (pw->label_font, + pw->passwd_label, strlen(pw->passwd_label), + &direction, &ascent, &descent, &overall); + if (overall.width > w2) w2 = overall.width; + h2 += ascent + descent; + + /* Measure the user_string. */ + XTextExtents (pw->passwd_font, + pw->user_string, strlen(pw->user_string), + &direction, &ascent, &descent, &overall); + overall.width += (pw->shadow_width * 4); + ascent += (pw->shadow_width * 4); + if (overall.width > w3) w3 = overall.width; + h3 += ascent + descent; + + /* Measure the (maximally-sized, dummy) passwd_string. */ + XTextExtents (pw->passwd_font, + passwd_string, strlen(passwd_string), + &direction, &ascent, &descent, &overall); + overall.width += (pw->shadow_width * 4); + ascent += (pw->shadow_width * 4); + if (overall.width > w3) w3 = overall.width; + h3 += ascent + descent; + + w2 = w2 + w3 + (pw->shadow_width * 2); + h2 = MAX (h2, h3); + + if (w2 > pw->width) pw->width = w2; + pw->height += h2; + } + + pw->width += (pw->internal_border * 2); + pw->height += (pw->internal_border * 4); + + pw->width += pw->thermo_width + (pw->shadow_width * 3); + + if (pw->logo_height > pw->height) + pw->height = pw->logo_height; + else if (pw->height > pw->logo_height) + pw->logo_height = pw->height; + + pw->logo_width = pw->logo_height; + + pw->width += pw->logo_width; + } + + attrmask |= CWOverrideRedirect; attrs.override_redirect = True; + attrmask |= CWEventMask; attrs.event_mask = ExposureMask|KeyPressMask; + + { + int x, y, w, h; + get_screen_viewport (si->default_screen, &x, &y, &w, &h, False); + if (si->prefs.debug_p) w /= 2; + pw->x = x + ((w + pw->width) / 2) - pw->width; + pw->y = y + ((h + pw->height) / 2) - pw->height; + if (pw->x < x) pw->x = x; + if (pw->y < y) pw->y = y; + } + + pw->border_width = get_integer_resource ("passwd.borderWidth", + "Dialog.BorderWidth"); + + si->passwd_dialog = + XCreateWindow (si->dpy, + RootWindowOfScreen(screen), + pw->x, pw->y, pw->width, pw->height, pw->border_width, + DefaultDepthOfScreen (screen), InputOutput, + DefaultVisualOfScreen(screen), + attrmask, &attrs); + XSetWindowBackground (si->dpy, si->passwd_dialog, pw->background); + + + /* Before mapping the window, save the bits that are underneath the + rectangle the window will occlude. When we lower the window, we + restore these bits. This works, because the running screenhack + has already been sent SIGSTOP, so we know nothing else is drawing + right now! */ + { + XGCValues gcv; + GC gc; + pw->save_under = XCreatePixmap (si->dpy, + si->default_screen->screensaver_window, + pw->width + (pw->border_width*2) + 1, + pw->height + (pw->border_width*2) + 1, + si->default_screen->current_depth); + gcv.function = GXcopy; + gc = XCreateGC (si->dpy, pw->save_under, GCFunction, &gcv); + XCopyArea (si->dpy, si->default_screen->screensaver_window, + pw->save_under, gc, + pw->x - pw->border_width, pw->y - pw->border_width, + pw->width + (pw->border_width*2) + 1, + pw->height + (pw->border_width*2) + 1, + 0, 0); + XFreeGC (si->dpy, gc); + } + + XMapRaised (si->dpy, si->passwd_dialog); + XSync (si->dpy, False); + + move_mouse_grab (si, si->passwd_dialog, si->screens[0].cursor); + undo_vp_motion (si); + + si->pw_data = pw; + + draw_passwd_window (si); + XSync (si->dpy, False); +} + + +static void +draw_passwd_window (saver_info *si) +{ + passwd_dialog_data *pw = si->pw_data; + XGCValues gcv; + GC gc1, gc2; + int spacing, height; + int x1, x2, x3, y1, y2; + int sw; + int tb_height; + + height = (pw->heading_font->ascent + pw->heading_font->descent + + pw->body_font->ascent + pw->body_font->descent + + (2 * MAX ((pw->label_font->ascent + pw->label_font->descent), + (pw->passwd_font->ascent + pw->passwd_font->descent + + (pw->shadow_width * 4))))); + spacing = ((pw->height - (2 * pw->shadow_width) - + pw->internal_border - height)) / 8; + if (spacing < 0) spacing = 0; + + gcv.foreground = pw->foreground; + gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv); + gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv); + x1 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 3); + x3 = pw->width - (pw->shadow_width * 2); + y1 = (pw->shadow_width * 2) + spacing + spacing; + + /* top heading + */ + XSetFont (si->dpy, gc1, pw->heading_font->fid); + sw = string_width (pw->heading_font, pw->heading_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + y1 += spacing + pw->heading_font->ascent + pw->heading_font->descent; + XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, + pw->heading_label, strlen(pw->heading_label)); + + /* text below top heading + */ + XSetFont (si->dpy, gc1, pw->body_font->fid); + y1 += spacing + pw->body_font->ascent + pw->body_font->descent; + sw = string_width (pw->body_font, pw->body_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, + pw->body_label, strlen(pw->body_label)); + + + tb_height = (pw->passwd_font->ascent + pw->passwd_font->descent + + (pw->shadow_width * 4)); + + /* the "User:" prompt + */ + y1 += spacing; + y2 = y1; + XSetForeground (si->dpy, gc1, pw->foreground); + XSetFont (si->dpy, gc1, pw->label_font->fid); + y1 += (spacing + tb_height); + x2 = (x1 + pw->internal_border + + MAX(string_width (pw->label_font, pw->user_label), + string_width (pw->label_font, pw->passwd_label))); + XDrawString (si->dpy, si->passwd_dialog, gc1, + x2 - string_width (pw->label_font, pw->user_label), + y1, + pw->user_label, strlen(pw->user_label)); + + /* the "Password:" prompt + */ + y1 += (spacing + tb_height); + XDrawString (si->dpy, si->passwd_dialog, gc1, + x2 - string_width (pw->label_font, pw->passwd_label), + y1, + pw->passwd_label, strlen(pw->passwd_label)); + + + XSetForeground (si->dpy, gc2, pw->passwd_background); + + /* the "user name" text field + */ + y1 = y2; + XSetForeground (si->dpy, gc1, pw->passwd_foreground); + XSetFont (si->dpy, gc1, pw->passwd_font->fid); + y1 += (spacing + tb_height); + x2 += (pw->shadow_width * 4); + + pw->passwd_field_width = x3 - x2 - pw->internal_border; + pw->passwd_field_height = (pw->passwd_font->ascent + + pw->passwd_font->descent + + pw->shadow_width); + + XFillRectangle (si->dpy, si->passwd_dialog, gc2, + x2 - pw->shadow_width, + y1 - (pw->passwd_font->ascent + pw->passwd_font->descent), + pw->passwd_field_width, pw->passwd_field_height); + XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, + pw->user_string, strlen(pw->user_string)); + + /* the "password" text field + */ + y1 += (spacing + tb_height); + + pw->passwd_field_x = x2 - pw->shadow_width; + pw->passwd_field_y = y1 - (pw->passwd_font->ascent + + pw->passwd_font->descent); + + /* The shadow around the text fields + */ + y1 = y2; + y1 += (spacing + (pw->shadow_width * 3)); + x1 = x2 - (pw->shadow_width * 2); + x2 = pw->passwd_field_width + (pw->shadow_width * 2); + y2 = pw->passwd_field_height + (pw->shadow_width * 2); + + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + x1, y1, x2, y2, + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + + y1 += (spacing + pw->passwd_font->ascent + pw->passwd_font->descent + + (pw->shadow_width * 4)); + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + x1, y1, x2, y2, + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + + /* the logo + */ + XSetForeground (si->dpy, gc1, pw->logo_foreground); + XSetForeground (si->dpy, gc2, pw->logo_background); + + x1 = pw->shadow_width * 3; + y1 = pw->shadow_width * 3; + x2 = pw->logo_width - (pw->shadow_width * 6); + y2 = pw->logo_height - (pw->shadow_width * 6); + + XFillRectangle (si->dpy, si->passwd_dialog, gc2, x1, y1, x2, y2); + skull (si->dpy, si->passwd_dialog, gc1, gc2, + x1 + pw->shadow_width, y1 + pw->shadow_width, + x2 - (pw->shadow_width * 2), y2 - (pw->shadow_width * 2)); + + /* The thermometer + */ + pw->thermo_field_x = pw->logo_width + pw->shadow_width; + pw->thermo_field_y = pw->shadow_width * 3; + pw->thermo_field_height = pw->height - (pw->shadow_width * 6); + + /* Solid border inside the logo box. */ + XSetForeground (si->dpy, gc1, pw->foreground); + XDrawRectangle (si->dpy, si->passwd_dialog, gc1, x1, y1, x2-1, y2-1); + + /* The shadow around the logo + */ + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + pw->shadow_width * 2, + pw->shadow_width * 2, + pw->logo_width - (pw->shadow_width * 4), + pw->logo_height - (pw->shadow_width * 4), + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + + /* The shadow around the thermometer + */ + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + pw->logo_width, + pw->shadow_width * 2, + pw->thermo_width + (pw->shadow_width * 2), + pw->height - (pw->shadow_width * 4), + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + + /* Solid border inside the thermometer. */ + XSetForeground (si->dpy, gc1, pw->foreground); + XDrawRectangle (si->dpy, si->passwd_dialog, gc1, + pw->logo_width + pw->shadow_width, + pw->shadow_width * 3, + pw->thermo_width - 1, + pw->height - (pw->shadow_width * 6) - 1); + + /* The shadow around the whole window + */ + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + 0, 0, pw->width, pw->height, pw->shadow_width, + pw->shadow_top, pw->shadow_bottom); + + XFreeGC (si->dpy, gc1); + XFreeGC (si->dpy, gc2); + + update_passwd_window (si, pw->passwd_string, pw->ratio); +} + + +static void +update_passwd_window (saver_info *si, const char *printed_passwd, float ratio) +{ + passwd_dialog_data *pw = si->pw_data; + XGCValues gcv; + GC gc1, gc2; + int x, y; + XRectangle rects[1]; + + pw->ratio = ratio; + gcv.foreground = pw->passwd_foreground; + gcv.font = pw->passwd_font->fid; + gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground|GCFont, &gcv); + gcv.foreground = pw->passwd_background; + gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv); + + if (printed_passwd) + { + char *s = strdup (printed_passwd); + if (pw->passwd_string) free (pw->passwd_string); + pw->passwd_string = s; + } + + /* the "password" text field + */ + rects[0].x = pw->passwd_field_x; + rects[0].y = pw->passwd_field_y; + rects[0].width = pw->passwd_field_width; + rects[0].height = pw->passwd_field_height; + + XFillRectangle (si->dpy, si->passwd_dialog, gc2, + rects[0].x, rects[0].y, rects[0].width, rects[0].height); + + XSetClipRectangles (si->dpy, gc1, 0, 0, rects, 1, Unsorted); + + XDrawString (si->dpy, si->passwd_dialog, gc1, + rects[0].x + pw->shadow_width, + rects[0].y + (pw->passwd_font->ascent + + pw->passwd_font->descent), + pw->passwd_string, strlen(pw->passwd_string)); + + XSetClipMask (si->dpy, gc1, None); + + /* The I-beam + */ + if (pw->i_beam != 0) + { + x = (rects[0].x + pw->shadow_width + + string_width (pw->passwd_font, pw->passwd_string)); + y = rects[0].y + pw->shadow_width; + + if (x > rects[0].x + rects[0].width - 1) + x = rects[0].x + rects[0].width - 1; + XDrawLine (si->dpy, si->passwd_dialog, gc1, + x, y, x, y + pw->passwd_font->ascent); + } + + pw->i_beam = (pw->i_beam + 1) % 4; + + + /* the thermometer + */ + y = pw->thermo_field_height * (1.0 - pw->ratio); + if (y > 0) + { + XFillRectangle (si->dpy, si->passwd_dialog, gc2, + pw->thermo_field_x + 1, + pw->thermo_field_y + 1, + pw->thermo_width-2, + y); + XSetForeground (si->dpy, gc1, pw->logo_foreground); + XFillRectangle (si->dpy, si->passwd_dialog, gc1, + pw->thermo_field_x + 1, + pw->thermo_field_y + 1 + y, + pw->thermo_width-2, + MAX (0, pw->thermo_field_height - y - 2)); + } + + XFreeGC (si->dpy, gc1); + XFreeGC (si->dpy, gc2); + XSync (si->dpy, False); +} + + +static void +destroy_passwd_window (saver_info *si) +{ + passwd_dialog_data *pw = si->pw_data; + Screen *screen = si->default_screen->screen; + Colormap cmap = DefaultColormapOfScreen (screen); + Pixel black = BlackPixelOfScreen (screen); + Pixel white = WhitePixelOfScreen (screen); + + if (pw->timer) + XtRemoveTimeOut (pw->timer); + + move_mouse_grab (si, RootWindowOfScreen(si->screens[0].screen), + si->screens[0].cursor); + + if (si->passwd_dialog) + { + XDestroyWindow (si->dpy, si->passwd_dialog); + si->passwd_dialog = 0; + } + + if (pw->save_under) + { + XGCValues gcv; + GC gc; + gcv.function = GXcopy; + gc = XCreateGC (si->dpy, si->default_screen->screensaver_window, + GCFunction, &gcv); + XCopyArea (si->dpy, pw->save_under, + si->default_screen->screensaver_window, gc, + 0, 0, + pw->width + (pw->border_width*2) + 1, + pw->height + (pw->border_width*2) + 1, + pw->x - pw->border_width, pw->y - pw->border_width); + XFreePixmap (si->dpy, pw->save_under); + pw->save_under = 0; + XFreeGC (si->dpy, gc); + } + + if (pw->heading_label) free (pw->heading_label); + if (pw->body_label) free (pw->body_label); + if (pw->user_label) free (pw->user_label); + if (pw->passwd_label) free (pw->passwd_label); + + if (pw->heading_font) XFreeFont (si->dpy, pw->heading_font); + if (pw->body_font) XFreeFont (si->dpy, pw->body_font); + if (pw->label_font) XFreeFont (si->dpy, pw->label_font); + if (pw->passwd_font) XFreeFont (si->dpy, pw->passwd_font); + + if (pw->foreground != black && pw->foreground != white) + XFreeColors (si->dpy, cmap, &pw->foreground, 1, 0L); + if (pw->background != black && pw->background != white) + XFreeColors (si->dpy, cmap, &pw->background, 1, 0L); + if (pw->passwd_foreground != black && pw->passwd_foreground != white) + XFreeColors (si->dpy, cmap, &pw->passwd_foreground, 1, 0L); + if (pw->passwd_background != black && pw->passwd_background != white) + XFreeColors (si->dpy, cmap, &pw->passwd_background, 1, 0L); + if (pw->logo_foreground != black && pw->logo_foreground != white) + XFreeColors (si->dpy, cmap, &pw->logo_foreground, 1, 0L); + if (pw->logo_background != black && pw->logo_background != white) + XFreeColors (si->dpy, cmap, &pw->logo_background, 1, 0L); + if (pw->shadow_top != black && pw->shadow_top != white) + XFreeColors (si->dpy, cmap, &pw->shadow_top, 1, 0L); + if (pw->shadow_bottom != black && pw->shadow_bottom != white) + XFreeColors (si->dpy, cmap, &pw->shadow_bottom, 1, 0L); + + memset (pw, 0, sizeof(*pw)); + free (pw); + + si->pw_data = 0; +} + + +#ifdef HAVE_XHPDISABLERESET +/* This function enables and disables the C-Sh-Reset hot-key, which + normally resets the X server (logging out the logged-in user.) + We don't want random people to be able to do that while the + screen is locked. + */ +static void +hp_lock_reset (saver_info *si, Bool lock_p) +{ + static Bool hp_locked_p = False; + + /* Calls to XHPDisableReset and XHPEnableReset must be balanced, + or BadAccess errors occur. (It's ok for this to be global, + since it affects the whole machine, not just the current screen.) + */ + if (hp_locked_p == lock_p) + return; + + if (lock_p) + XHPDisableReset (si->dpy); + else + XHPEnableReset (si->dpy); + hp_locked_p = lock_p; +} +#endif /* HAVE_XHPDISABLERESET */ + + + +/* This function enables and disables the C-Sh-F1 ... F12 hot-keys, + which, on Linux systems, switches to another virtual console. + We'd like the whole screen/keyboard to be locked, not just one + virtual console, so this function disables that while the X + screen is locked. + + Unfortunately, this doesn't work -- this ioctl only works when + called by root, and we have disavowed our privileges long ago. + */ +#ifdef HAVE_VT_LOCKSWITCH +static void +linux_lock_vt_switch (saver_info *si, Bool lock_p) +{ + saver_preferences *p = &si->prefs; + static Bool vt_locked_p = False; + const char *dev_console = "/dev/console"; + int fd; + + if (lock_p == vt_locked_p) + return; + + if (lock_p && !p->lock_vt_p) + return; + + fd = open (dev_console, O_RDWR); + if (fd < 0) + { + char buf [255]; + sprintf (buf, "%s: couldn't %s VTs: %s", blurb(), + (lock_p ? "lock" : "unlock"), + dev_console); +#if 1 /* #### doesn't work yet, so don't bother complaining */ + perror (buf); +#endif + return; + } + + if (ioctl (fd, (lock_p ? VT_LOCKSWITCH : VT_UNLOCKSWITCH)) == 0) + { + vt_locked_p = lock_p; + + if (p->verbose_p) + fprintf (stderr, "%s: %s VTs\n", blurb(), + (lock_p ? "locked" : "unlocked")); + } + else + { + char buf [255]; + sprintf (buf, "%s: couldn't %s VTs: ioctl", blurb(), + (lock_p ? "lock" : "unlock")); +#if 0 /* #### doesn't work yet, so don't bother complaining */ + perror (buf); +#endif + } + + close (fd); +} +#endif /* HAVE_VT_LOCKSWITCH */ + + +/* This function enables and disables the C-Alt-Plus and C-Alt-Minus + hot-keys, which normally change the resolution of the X server. + We don't want people to be able to switch the server resolution + while the screen is locked, because if they switch to a higher + resolution, it could cause part of the underlying desktop to become + exposed. + */ +#ifdef HAVE_XF86VMODE + +static int ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error); +static Bool vp_got_error = False; + +static void +xfree_lock_mode_switch (saver_info *si, Bool lock_p) +{ + static Bool mode_locked_p = False; + saver_preferences *p = &si->prefs; + int screen = 0; /* always screen 0 */ + int event, error; + Bool status; + XErrorHandler old_handler; + + if (mode_locked_p == lock_p) + return; + if (!XF86VidModeQueryExtension (si->dpy, &event, &error)) + return; + + XSync (si->dpy, False); + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + status = XF86VidModeLockModeSwitch (si->dpy, screen, lock_p); + XSync (si->dpy, False); + XSetErrorHandler (old_handler); + if (vp_got_error) status = False; + + if (status) + mode_locked_p = lock_p; + + if (!status && (p->verbose_p || !lock_p)) + /* Only print this when verbose, or when we locked but can't unlock. + I tried printing this message whenever it comes up, but + mode-locking always fails if DontZoom is set in XF86Config. */ + fprintf (stderr, "%s: unable to %s mode switching!\n", + blurb(), (lock_p ? "lock" : "unlock")); + else if (p->verbose_p) + fprintf (stderr, "%s: %s mode switching.\n", + blurb(), (lock_p ? "locked" : "unlocked")); +} + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + vp_got_error = True; + return 0; +} + +#endif /* HAVE_XF86VMODE */ + + +/* If the viewport has been scrolled since the screen was blanked, + then scroll it back to where it belongs. This function only exists + to patch over a very brief race condition. + */ +static void +undo_vp_motion (saver_info *si) +{ +#ifdef HAVE_XF86VMODE + saver_preferences *p = &si->prefs; + int screen = 0; /* always screen 0 */ + saver_screen_info *ssi = &si->screens[screen]; + int event, error, x, y; + Bool status; + + if (ssi->blank_vp_x == -1 && ssi->blank_vp_y == -1) + return; + if (!XF86VidModeQueryExtension (si->dpy, &event, &error)) + return; + if (!XF86VidModeGetViewPort (si->dpy, 0, &x, &y)) + return; + if (ssi->blank_vp_x == x && ssi->blank_vp_y == y) + return; + + /* We're going to move the viewport. The mouse has just been grabbed on + (and constrained to, thus warped to) the password window, so it is no + longer near the edge of the screen. However, wait a bit anyway, just + to make sure the server drains its last motion event, so that the + screen doesn't continue to scroll after we've reset the viewport. + */ + XSync (si->dpy, False); + usleep (250); /* 1/4 second */ + XSync (si->dpy, False); + + status = XF86VidModeSetViewPort (si->dpy, screen, + ssi->blank_vp_x, ssi->blank_vp_y); + + if (!status) + fprintf (stderr, "%s: unable to move vp from (%d,%d) back to (%d,%d)!\n", + blurb(), x, y, ssi->blank_vp_x, ssi->blank_vp_y); + else if (p->verbose_p) + fprintf (stderr, "%s: vp moved to (%d,%d); moved it back to (%d,%d).\n", + blurb(), x, y, ssi->blank_vp_x, ssi->blank_vp_y); + +#endif /* HAVE_XF86VMODE */ +} + + + +/* Interactions + */ + +static void +passwd_animate_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + int tick = 166; + passwd_dialog_data *pw = si->pw_data; + + if (!pw) return; + + pw->ratio -= (1.0 / ((double) si->prefs.passwd_timeout / (double) tick)); + if (pw->ratio < 0) + { + pw->ratio = 0; + if (pw->state == pw_read) + pw->state = pw_time; + } + + update_passwd_window (si, 0, pw->ratio); + + if (pw->state == pw_read) + pw->timer = XtAppAddTimeOut (si->app, tick, passwd_animate_timer, + (XtPointer) si); + else + pw->timer = 0; + + idle_timer ((XtPointer) si, id); +} + + +static void +handle_passwd_key (saver_info *si, XKeyEvent *event) +{ + saver_preferences *p = &si->prefs; + passwd_dialog_data *pw = si->pw_data; + int pw_size = sizeof (pw->typed_passwd) - 1; + char *typed_passwd = pw->typed_passwd; + char s[2]; + char *stars = 0; + int i; + int size = XLookupString (event, s, 1, 0, 0); + + if (size != 1) return; + + s[1] = 0; + + switch (*s) + { + case '\010': case '\177': /* Backspace */ + if (!*typed_passwd) + XBell (si->dpy, 0); + else + typed_passwd [strlen(typed_passwd)-1] = 0; + break; + + case '\025': case '\030': /* Erase line */ + memset (typed_passwd, 0, pw_size); + break; + + case '\012': case '\015': /* Enter */ + if (pw->state != pw_read) + ; /* already done? */ + else if (typed_passwd[0] == 0) + pw->state = pw_null; + else + { + update_passwd_window (si, "Checking...", pw->ratio); + XSync (si->dpy, False); + if (passwd_valid_p (typed_passwd, p->verbose_p)) + pw->state = pw_ok; + else + pw->state = pw_fail; + update_passwd_window (si, "", pw->ratio); + } + break; + + default: + i = strlen (typed_passwd); + if (i >= pw_size-1) + XBell (si->dpy, 0); + else + { + typed_passwd [i] = *s; + typed_passwd [i+1] = 0; + } + break; + } + + i = strlen(typed_passwd); + stars = (char *) malloc(i+1); + memset (stars, '*', i); + stars[i] = 0; + update_passwd_window (si, stars, pw->ratio); + free (stars); +} + + +static void +passwd_event_loop (saver_info *si) +{ + saver_preferences *p = &si->prefs; + char *msg = 0; + XEvent event; + passwd_animate_timer ((XtPointer) si, 0); + + while (si->pw_data && si->pw_data->state == pw_read) + { + XtAppNextEvent (si->app, &event); + if (event.xany.window == si->passwd_dialog && event.xany.type == Expose) + draw_passwd_window (si); + else if (event.xany.type == KeyPress) + handle_passwd_key (si, &event.xkey); + else + XtDispatchEvent (&event); + } + + switch (si->pw_data->state) + { + case pw_ok: msg = 0; break; + case pw_null: msg = ""; break; + case pw_time: msg = "Timed out!"; break; + default: msg = "Sorry!"; break; + } + + if (si->pw_data->state == pw_fail) + si->unlock_failures++; + + if (p->verbose_p) + switch (si->pw_data->state) + { + case pw_ok: + fprintf (stderr, "%s: password correct.\n", blurb()); break; + case pw_fail: + fprintf (stderr, "%s: password incorrect!\n", blurb()); break; + case pw_null: + case pw_cancel: + fprintf (stderr, "%s: password entry cancelled.\n", blurb()); break; + case pw_time: + fprintf (stderr, "%s: password entry timed out.\n", blurb()); break; + default: break; + } + +#ifdef HAVE_SYSLOG + if (si->pw_data->state == pw_fail) + { + /* If they typed a password (as opposed to just hitting return) and + the password was invalid, log it. + */ + struct passwd *pw = getpwuid (getuid ()); + char *d = DisplayString (si->dpy); + char *u = (pw->pw_name ? pw->pw_name : "???"); + int opt = 0; + int fac = 0; + +# ifdef LOG_PID + opt = LOG_PID; +# endif + +# if defined(LOG_AUTHPRIV) + fac = LOG_AUTHPRIV; +# elif defined(LOG_AUTH) + fac = LOG_AUTH; +# else + fac = LOG_DAEMON; +# endif + + if (!d) d = ""; + openlog (progname, opt, fac); + syslog (LOG_NOTICE, "FAILED LOGIN %d ON DISPLAY \"%s\", FOR \"%s\"", + si->unlock_failures, d, u); + closelog (); + } +#endif /* HAVE_SYSLOG */ + + if (si->pw_data->state == pw_fail) + XBell (si->dpy, False); + + if (si->pw_data->state == pw_ok && si->unlock_failures != 0) + { + if (si->unlock_failures == 1) + fprintf (real_stderr, + "%s: WARNING: 1 failed attempt to unlock the screen.\n", + blurb()); + else + fprintf (real_stderr, + "%s: WARNING: %d failed attempts to unlock the screen.\n", + blurb(), si->unlock_failures); + fflush (real_stderr); + + si->unlock_failures = 0; + } + + if (msg) + { + si->pw_data->i_beam = 0; + update_passwd_window (si, msg, 0.0); + XSync (si->dpy, False); + sleep (1); + + /* Swallow all pending KeyPress/KeyRelease events. */ + { + XEvent e; + while (XCheckMaskEvent (si->dpy, KeyPressMask|KeyReleaseMask, &e)) + ; + } + } +} + + +Bool +unlock_p (saver_info *si) +{ + saver_preferences *p = &si->prefs; + Screen *screen = si->default_screen->screen; + Colormap cmap = DefaultColormapOfScreen (screen); + Bool status; + + raise_window (si, True, True, True); + + if (p->verbose_p) + fprintf (stderr, "%s: prompting for password.\n", blurb()); + + if (si->pw_data || si->passwd_dialog) + destroy_passwd_window (si); + + make_passwd_window (si); + if (cmap) XInstallColormap (si->dpy, cmap); + + passwd_event_loop (si); + + status = (si->pw_data->state == pw_ok); + destroy_passwd_window (si); + + cmap = si->default_screen->cmap; + if (cmap) XInstallColormap (si->dpy, cmap); + + return status; +} + + +void +set_locked_p (saver_info *si, Bool locked_p) +{ + si->locked_p = locked_p; + +#ifdef HAVE_XHPDISABLERESET + hp_lock_reset (si, locked_p); /* turn off/on C-Sh-Reset */ +#endif +#ifdef HAVE_VT_LOCKSWITCH + linux_lock_vt_switch (si, locked_p); /* turn off/on C-Alt-F1 */ +#endif +#ifdef HAVE_XF86VMODE + xfree_lock_mode_switch (si, locked_p); /* turn off/on C-Alt-Plus */ +#endif +} + + +#else /* NO_LOCKING -- whole file */ + +void +set_locked_p (saver_info *si, Bool locked_p) +{ + if (locked_p) abort(); +} + +#endif /* !NO_LOCKING */ diff --git a/driver/passwd-kerberos.c b/driver/passwd-kerberos.c new file mode 100644 index 00000000..1e28d60a --- /dev/null +++ b/driver/passwd-kerberos.c @@ -0,0 +1,180 @@ +/* kpasswd.c --- verify kerberos passwords. + * written by Nat Lanza (magus@cs.cmu.edu) for + * xscreensaver, Copyright (c) 1993-1997, 1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include + +#if !defined(VMS) && !defined(HAVE_ADJUNCT_PASSWD) +# include +#endif + + +#ifdef __bsdi__ +# include +# if _BSDI_VERSION >= 199608 +# define BSD_AUTH +# endif +#endif /* __bsdi__ */ + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + +/* The user information we need to store */ +static char realm[REALM_SZ]; +static char name[ANAME_SZ]; +static char inst[INST_SZ]; +static char *tk_file; + + +/* Called at startup to grab user, instance, and realm information + from the user's ticketfile (remember, name.inst@realm). Since we're + using tf_get_pname(), this should work even if your kerberos username + isn't the same as your local username. We grab the ticket at startup + time so that even if your ticketfile dies while the screen's locked + we'll still have the information to unlock it. + + Problems: the password dialog currently displays local username, so if + you have some non-standard name/instance when you run xscreensaver, + you'll need to remember what it was when unlocking, or else you lose. + + Also, we use des_string_to_key(), so if you have an AFS password + (encrypted with ka_StringToKey()), you'll lose. Get a kerberos password; + it isn't that hard. + + Like the original lock_init, we return false if something went wrong. + We don't use the arguments we're given, though. + */ +Bool +kerberos_lock_init (int argc, char **argv, Bool verbose_p) +{ + int k_errno; + + memset(name, 0, sizeof(name)); + memset(inst, 0, sizeof(inst)); + + /* find out where the user's keeping his tickets. + squirrel it away for later use. */ + tk_file = tkt_string(); + + /* open ticket file or die trying. */ + if ((k_errno = tf_init(tk_file, R_TKT_FIL))) { + return False; + } + + /* same with principal and instance names */ + if ((k_errno = tf_get_pname(name)) || + (k_errno = tf_get_pinst(inst))) { + return False; + } + + /* close the ticketfile to release the lock on it. */ + tf_close(); + + /* figure out what realm we're authenticated to. this ought + to be the local realm, but it pays to be sure. */ + if ((k_errno = krb_get_tf_realm(tk_file, realm))) { + return False; + } + + /* last-minute sanity check on what we got. */ + if ((strlen(name)+strlen(inst)+strlen(realm)+3) > + (REALM_SZ + ANAME_SZ + INST_SZ + 3)) { + return False; + } + + /* success */ + return True; +} + + +/* des_string_to_key() wants this. If C didn't suck, we could have an + anonymous function do this. Even a local one. But it does, so here + we are. Calling it ive_got_your_local_function_right_here_buddy() + would have been rude. + */ +static int +key_to_key(char *user, char *instance, char *realm, char *passwd, C_Block key) +{ + memcpy(key, passwd, sizeof(des_cblock)); + return (0); +} + +/* Called to see if the user's typed password is valid. We do this by asking + the kerberos server for a ticket and checking to see if it gave us one. + We need to move the ticketfile first, or otherwise we end up updating the + user's tkfile with new tickets. This would break services like zephyr that + like to stay authenticated, and it would screw with AFS authentication at + some sites. So, we do a quick, painful hack with a tmpfile. + */ +Bool +kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p) +{ + C_Block mitkey; + Bool success; + char *newtkfile; + + /* temporarily switch to a new ticketfile. + I'm not using tmpnam() because it isn't entirely portable. + this could probably be fixed with autoconf. */ + newtkfile = malloc(80 * sizeof(char)); + memset(newtkfile, 0, sizeof(newtkfile)); + + sprintf(newtkfile, "/tmp/xscrn-%i", getpid()); + + krb_set_tkt_string(newtkfile); + + /* encrypt the typed password. if you have an AFS password instead + of a kerberos one, you lose *right here*. If you want to use AFS + passwords, you can use ka_StringToKey() instead. As always, ymmv. */ + des_string_to_key(typed_passwd, mitkey); + + if (krb_get_in_tkt(name, inst, realm, "krbtgt", realm, DEFAULT_TKT_LIFE, + key_to_key, NULL, mitkey) != 0) { + success = False; + } else { + success = True; + } + + /* quickly block out the tempfile and password to prevent snooping, + then restore the old ticketfile and cleean up a bit. */ + + dest_tkt(); + krb_set_tkt_string(tk_file); + free(newtkfile); + memset(mitkey, 0, sizeof(mitkey)); + + + /* Did we verify successfully? */ + return success; +} + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/passwd-pam.c b/driver/passwd-pam.c new file mode 100644 index 00000000..a02cf811 --- /dev/null +++ b/driver/passwd-pam.c @@ -0,0 +1,392 @@ +/* passwd-pam.c --- verifying typed passwords with PAM + * (Pluggable Authentication Modules.) + * written by Bill Nottingham (and jwz) for + * xscreensaver, Copyright (c) 1993-1998 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. + * + * Some PAM resources: + * + * PAM home page: + * http://www.us.kernel.org/pub/linux/libs/pam/ + * + * PAM FAQ: + * http://www.us.kernel.org/pub/linux/libs/pam/FAQ + * + * PAM Application Developers' Guide: + * http://www.us.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam_appl.html + * + * PAM Mailing list archives: + * http://www.linuxhq.com/lnxlists/linux-pam/ + * + * Compatibility notes, especially between Linux and Solaris: + * http://www.contrib.andrew.cmu.edu/u/shadow/pam.html + * + * The Open Group's PAM API documentation: + * http://www.opengroup.org/onlinepubs/8329799/pam_start.htm + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +extern char *blurb(void); + + +#include +#include +#include +#include +#include +#include + +#include + + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + +#undef countof +#define countof(x) (sizeof((x))/sizeof(*(x))) + +static int pam_conversation (int nmsgs, + const struct pam_message **msg, + struct pam_response **resp, + void *closure); + +struct pam_closure { + const char *user; + const char *typed_passwd; + Bool verbose_p; +}; + + +#ifdef HAVE_PAM_FAIL_DELAY + /* We handle delays ourself.*/ + /* Don't set this to 0 (Linux bug workaround.) */ +# define PAM_NO_DELAY(pamh) pam_fail_delay ((pamh), 1) +#else /* !HAVE_PAM_FAIL_DELAY */ +# define PAM_NO_DELAY(pamh) /* */ +#endif /* !HAVE_PAM_FAIL_DELAY */ + + +/* On SunOS 5.6, and on Linux with PAM 0.64, pam_strerror() takes two args. + On some other Linux systems with some other version of PAM (e.g., + whichever Debian release comes with a 2.2.5 kernel) it takes one arg. + I can't tell which is more "recent" or "correct" behavior, so configure + figures out which is in use for us. Shoot me! + */ +#ifdef PAM_STRERROR_TWO_ARGS +# define PAM_STRERROR(pamh, status) pam_strerror((pamh), (status)) +#else /* !PAM_STRERROR_TWO_ARGS */ +# define PAM_STRERROR(pamh, status) pam_strerror((status)) +#endif /* !PAM_STRERROR_TWO_ARGS */ + + +/* PAM sucks in that there is no way to tell whether a particular service + is configured at all. That is, there is no way to tell the difference + between "authentication of the FOO service is not allowed" and "the + user typed the wrong password." + + On RedHat 5.1 systems, if a service name is not known, it defaults to + being not allowed (because the fallback service, /etc/pam.d/other, is + set to `pam_deny'.) + + On Solaris 2.6 systems, unknown services default to authenticating normally. + + So, we could simply require that the person who installs xscreensaver + set up an "xscreensaver" PAM service. However, if we went that route, + it would have a really awful failure mode: the failure mode would be that + xscreensaver was willing to *lock* the screen, but would be unwilling to + *unlock* the screen. (With the non-PAM password code, the analagous + situation -- security not being configured properly, for example do to the + executable not being installed as setuid root -- the failure mode is much + more palettable, in that xscreensaver will refuse to *lock* the screen, + because it can know up front that there is no password that will work.) + + Another route would be to have the service name to consult be computed at + compile-time (perhaps with a configure option.) However, that doesn't + really solve the problem, because it means that the same executable might + work fine on one machine, but refuse to unlock when run on another + machine. + + Another alternative would be to look in /etc/pam.conf or /etc/pam.d/ at + runtime to see what services actually exist. But I think that's no good, + because who is to say that the PAM info is actually specified in those + files? Opening and reading those files is not a part of the PAM client + API, so it's not guarenteed to work on any given system. + + An alternative I tried was to specify a list of services to try, and to + try them all in turn ("xscreensaver", "xlock", "xdm", and "login"). + This worked, but it was slow (and I also had to do some contortions to + work around bugs in Linux PAM 0.64-3.) + + So what we do today is, try PAM once, and if that fails, try the usual + getpwent() method. So if PAM doesn't work, it will at least make an + attempt at looking up passwords in /etc/passwd or /etc/shadow instead. + + This all kind of blows. I'm not sure what else to do. + */ + + +/* On SunOS 5.6, the `pam_conv.appdata_ptr' slot seems to be ignored, and + the `closure' argument to pc.conv always comes in as random garbage. + So we get around this by using a global variable instead. Shoot me! + + (I've been told this is bug 4092227, and is fixed in Solaris 7.) + */ +static void *suns_pam_implementation_blows = 0; + + +/* This can be called at any time, and says whether the typed password + belongs to either the logged in user (real uid, not effective); or + to root. + */ +Bool +pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p) +{ + const char *service = PAM_SERVICE_NAME; + pam_handle_t *pamh = 0; + int status = -1; + struct pam_conv pc; + struct pam_closure c; + char *user = 0; + + struct passwd *p = getpwuid (getuid ()); + if (!p) return False; + + user = strdup (p->pw_name); + + c.user = user; + c.typed_passwd = typed_passwd; + c.verbose_p = verbose_p; + + pc.conv = &pam_conversation; + pc.appdata_ptr = (void *) &c; + + /* On SunOS 5.6, the `appdata_ptr' slot seems to be ignored, and the + `closure' argument to pc.conv always comes in as random garbage. */ + suns_pam_implementation_blows = (void *) &c; + + + /* Initialize PAM. + */ + status = pam_start (service, c.user, &pc, &pamh); + if (verbose_p) + fprintf (stderr, "%s: pam_start (\"%s\", \"%s\", ...) ==> %d (%s)\n", + blurb(), service, c.user, + status, PAM_STRERROR (pamh, status)); + if (status != PAM_SUCCESS) goto DONE; + + /* #### We should set PAM_TTY to the display we're using, but we + don't have that handy from here. So set it to :0.0, which is a + good guess (and has the bonus of counting as a "secure tty" as + far as PAM is concerned...) + */ + { + const char *tty = ":0.0"; + status = pam_set_item (pamh, PAM_TTY, strdup(tty)); + if (verbose_p) + fprintf (stderr, "%s: pam_set_item (p, PAM_TTY, \"%s\") ==> %d (%s)\n", + blurb(), tty, status, PAM_STRERROR(pamh, status)); + } + + /* Try to authenticate as the current user. + */ + PAM_NO_DELAY(pamh); + status = pam_authenticate (pamh, 0); + if (verbose_p) + fprintf (stderr, "%s: pam_authenticate (...) ==> %d (%s)\n", + blurb(), status, PAM_STRERROR(pamh, status)); + if (status == PAM_SUCCESS) /* Win! */ + goto DONE; + + /* If that didn't work, set the user to root, and try to authenticate again. + */ + c.user = "root"; + status = pam_set_item (pamh, PAM_USER, strdup(c.user)); + if (verbose_p) + fprintf (stderr, "%s: pam_set_item(p, PAM_USER, \"%s\") ==> %d (%s)\n", + blurb(), c.user, status, PAM_STRERROR(pamh, status)); + if (status != PAM_SUCCESS) goto DONE; + + PAM_NO_DELAY(pamh); + status = pam_authenticate (pamh, 0); + if (verbose_p) + fprintf (stderr, "%s: pam_authenticate (...) ==> %d (%s)\n", + blurb(), status, PAM_STRERROR(pamh, status)); + + DONE: + if (user) free (user); + if (pamh) + { + int status2 = pam_end (pamh, status); + pamh = 0; + if (verbose_p) + fprintf (stderr, "%s: pam_end (...) ==> %d (%s)\n", + blurb(), status2, + (status2 == PAM_SUCCESS ? "Success" : "Failure")); + } + return (status == PAM_SUCCESS ? True : False); +} + + +Bool +pam_priv_init (int argc, char **argv, Bool verbose_p) +{ + /* We have nothing to do at init-time. + However, we might as well do some error checking. + If "/etc/pam.d" exists and is a directory, but "/etc/pam.d/xlock" + does not exist, warn that PAM probably isn't going to work. + + This is a priv-init instead of a non-priv init in case the directory + is unreadable or something (don't know if that actually happens.) + */ + const char dir[] = "/etc/pam.d"; + const char file[] = "/etc/pam.d/" PAM_SERVICE_NAME; + const char file2[] = "/etc/pam.conf"; + struct stat st; + + if (stat (dir, &st) == 0 && st.st_mode & S_IFDIR) + { + if (stat (file, &st) != 0) + fprintf (stderr, + "%s: warning: %s does not exist.\n" + "%s: password authentication via PAM is unlikely to work.\n", + blurb(), file, blurb()); + } + else if (stat (file2, &st) == 0) + { + FILE *f = fopen (file2, "r"); + if (f) + { + Bool ok = False; + char buf[255]; + while (fgets (buf, sizeof(buf), f)) + if (strstr (buf, PAM_SERVICE_NAME)) + { + ok = True; + break; + } + fclose (f); + if (!ok) + { + fprintf (stderr, + "%s: warning: %s does not list the `%s' service.\n" + "%s: password authentication via PAM is unlikely to work.\n", + blurb(), file2, PAM_SERVICE_NAME, blurb()); + } + } + /* else warn about file2 existing but being unreadable? */ + } + else + { + fprintf (stderr, + "%s: warning: neither %s nor %s exist.\n" + "%s: password authentication via PAM is unlikely to work.\n", + blurb(), file2, file, blurb()); + } + + /* Return true anyway, just in case. */ + return True; +} + + +/* This is the function PAM calls to have a conversation with the user. + Really, this function should be the thing that pops up dialog boxes + as needed, and prompts for various strings. + + But, for now, xscreensaver uses its normal password-prompting dialog + first, and then this function simply returns the result that has been + typed. + + This means that if PAM was using a retina scanner for auth, xscreensaver + would prompt for a password; then pam_conversation() would be called + with a string like "Please look into the retina scanner". The user + would never see this string, and the prompted-for password would be + ignored. + */ +static int +pam_conversation (int nmsgs, + const struct pam_message **msg, + struct pam_response **resp, + void *closure) +{ + int replies = 0; + struct pam_response *reply = 0; + struct pam_closure *c = (struct pam_closure *) closure; + + /* On SunOS 5.6, the `closure' argument always comes in as random garbage. */ + c = (struct pam_closure *) suns_pam_implementation_blows; + + + reply = (struct pam_response *) calloc (nmsgs, sizeof (*reply)); + if (!reply) return PAM_CONV_ERR; + + for (replies = 0; replies < nmsgs; replies++) + { + switch (msg[replies]->msg_style) + { + case PAM_PROMPT_ECHO_ON: + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = strdup (c->user); /* freed by PAM */ + if (c->verbose_p) + fprintf (stderr, "%s: PAM ECHO_ON(\"%s\") ==> \"%s\"\n", + blurb(), msg[replies]->msg, + reply[replies].resp); + break; + case PAM_PROMPT_ECHO_OFF: + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = strdup (c->typed_passwd); /* freed by PAM */ + if (c->verbose_p) + fprintf (stderr, "%s: PAM ECHO_OFF(\"%s\") ==> password\n", + blurb(), msg[replies]->msg); + break; + case PAM_TEXT_INFO: + /* ignore it... */ + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = 0; + if (c->verbose_p) + fprintf (stderr, "%s: PAM TEXT_INFO(\"%s\") ==> ignored\n", + blurb(), msg[replies]->msg); + break; + case PAM_ERROR_MSG: + /* ignore it... */ + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = 0; + if (c->verbose_p) + fprintf (stderr, "%s: PAM ERROR_MSG(\"%s\") ==> ignored\n", + blurb(), msg[replies]->msg); + break; + default: + /* Must be an error of some sort... */ + free (reply); + if (c->verbose_p) + fprintf (stderr, "%s: PAM unknown %d(\"%s\") ==> ignored\n", + blurb(), msg[replies]->msg_style, msg[replies]->msg); + return PAM_CONV_ERR; + } + } + *resp = reply; + return PAM_SUCCESS; +} + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/passwd-pwent.c b/driver/passwd-pwent.c new file mode 100644 index 00000000..a2d5e0c8 --- /dev/null +++ b/driver/passwd-pwent.c @@ -0,0 +1,305 @@ +/* passwd-pwent.c --- verifying typed passwords with the OS. + * xscreensaver, Copyright (c) 1993-1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_CRYPT_H +# include +#endif + +#include +#include +#include +#ifndef VMS +# include +# include +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + + +#ifdef __bsdi__ +# include +# if _BSDI_VERSION >= 199608 +# define BSD_AUTH +# endif +#endif /* __bsdi__ */ + + +#if defined(HAVE_SHADOW_PASSWD) /* passwds live in /etc/shadow */ + +# include +# define PWTYPE struct spwd * +# define PWPSLOT sp_pwdp +# define GETPW getspnam + +#elif defined(HAVE_ENHANCED_PASSWD) /* passwds live in /tcb/files/auth/ */ + /* M.Matsumoto */ +# include +# include + +# define PWTYPE struct pr_passwd * +# define PWPSLOT ufld.fd_encrypt +# define GETPW getprpwnam + +#elif defined(HAVE_ADJUNCT_PASSWD) + +# include +# include +# include + +# define PWTYPE struct passwd_adjunct * +# define PWPSLOT pwa_passwd +# define GETPW getpwanam + +#elif defined(HAVE_HPUX_PASSWD) + +# include +# include + +# define PWTYPE struct s_passwd * +# define PWPSLOT pw_passwd +# define GETPW getspwnam + +# define HAVE_BIGCRYPT + +#endif + + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + + +extern const char *blurb(void); + +static char *encrypted_root_passwd = 0; +static char *encrypted_user_passwd = 0; + +#ifdef VMS +# define ROOT "SYSTEM" +#else +# define ROOT "root" +#endif + + + +#ifndef VMS + +static char * +user_name (void) +{ + /* I think that just checking $USER here is not the best idea. */ + + const char *u = 0; + + /* It has been reported that getlogin() returns the wrong user id on some + very old SGI systems... And I've seen it return the string "rlogin" + sometimes! Screw it, using getpwuid() should be enough... + */ +/* u = (char *) getlogin (); + */ + + /* getlogin() fails if not attached to a terminal; in that case, use + getpwuid(). (Note that in this case, we're not doing shadow stuff, since + all we're interested in is the name, not the password. So that should + still work. Right?) */ + if (!u || !*u) + { + struct passwd *p = getpwuid (getuid ()); + u = (p ? p->pw_name : 0); + } + + return (u ? strdup(u) : 0); +} + +#else /* VMS */ + +static char * +user_name (void) +{ + char *u = getenv("USER"); + return (u ? strdup(u) : 0); +} + +#endif /* VMS */ + + +static Bool +passwd_known_p (const char *pw) +{ + return (pw && + pw[0] != '*' && /* This would be sensible... */ + strlen(pw) > 4); /* ...but this is what Solaris does. */ +} + + +static char * +get_encrypted_passwd(const char *user) +{ + char *result = 0; + +#ifdef PWTYPE + if (user && *user && !result) + { /* First check the shadow passwords. */ + PWTYPE p = GETPW((char *) user); + if (p && passwd_known_p (p->PWPSLOT)) + result = strdup(p->PWPSLOT); + } +#endif /* PWTYPE */ + + if (user && *user && !result) + { /* Check non-shadow passwords too. */ + struct passwd *p = getpwnam(user); + if (p && passwd_known_p (p->pw_passwd)) + result = strdup(p->pw_passwd); + } + + /* The manual for passwd(4) on HPUX 10.10 says: + + Password aging is put in effect for a particular user if his + encrypted password in the password file is followed by a comma and + a nonnull string of characters from the above alphabet. This + string defines the "age" needed to implement password aging. + + So this means that passwd->pw_passwd isn't simply a string of cyphertext, + it might have trailing junk. So, if there is a comma in the string, and + that comma is beyond position 13, terminate the string before the comma. + */ + if (result && strlen(result) > 13) + { + char *s = strchr (result+13, ','); + if (s) + *s = 0; + } + +#ifndef HAVE_PAM + /* We only issue this warning if not compiled with support for PAM. + If we're using PAM, it's not unheard of that normal pwent passwords + would be unavailable. */ + + if (!result) + fprintf (stderr, "%s: couldn't get password of \"%s\"\n", + blurb(), (user ? user : "(null)")); +#endif /* !HAVE_PAM */ + + return result; +} + + + +/* This has to be called before we've changed our effective user ID, + because it might need privileges to get at the encrypted passwords. + Returns false if we weren't able to get any passwords, and therefore, + locking isn't possible. (It will also have written to stderr.) + */ + +#ifndef VMS + +Bool +pwent_priv_init (int argc, char **argv, Bool verbose_p) +{ + char *u; + +#ifdef HAVE_ENHANCED_PASSWD + set_auth_parameters(argc, argv); + check_auth_parameters(); +#endif /* HAVE_DEC_ENHANCED */ + + u = user_name(); + encrypted_user_passwd = get_encrypted_passwd(u); + encrypted_root_passwd = get_encrypted_passwd(ROOT); + if (u) free (u); + + if (encrypted_user_passwd) + return True; + else + return False; +} + + +Bool +pwent_lock_init (int argc, char **argv, Bool verbose_p) +{ + if (encrypted_user_passwd) + return True; + else + return False; +} + + + +static Bool +passwds_match_p (const char *cleartext, const char *ciphertext) +{ + char *s = 0; /* note that on some systems, crypt() may return null */ + + s = (char *) crypt (cleartext, ciphertext); + if (s && !strcmp (s, ciphertext)) + return True; + +#ifdef HAVE_BIGCRYPT + /* There seems to be no way to tell at runtime if an HP machine is in + "trusted" mode, and thereby, which of crypt() or bigcrypt() we should + be calling to compare passwords. So call them both, and see which + one works. */ + + s = (char *) bigcrypt (cleartext, ciphertext); + if (s && !strcmp (s, ciphertext)) + return True; + +#endif /* HAVE_BIGCRYPT */ + + return False; +} + + + +/* This can be called at any time, and says whether the typed password + belongs to either the logged in user (real uid, not effective); or + to root. + */ +Bool +pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p) +{ + if (encrypted_user_passwd && + passwds_match_p (typed_passwd, encrypted_user_passwd)) + return True; + + /* do not allow root to have a null password. */ + else if (typed_passwd[0] && + encrypted_root_passwd && + passwds_match_p (typed_passwd, encrypted_root_passwd)) + return True; + + else + return False; +} + +#else /* VMS */ +Bool pwent_lock_init (int argc, char **argv, Bool verbose_p) { return True; } +#endif /* VMS */ + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/passwd.c b/driver/passwd.c new file mode 100644 index 00000000..b55334c9 --- /dev/null +++ b/driver/passwd.c @@ -0,0 +1,162 @@ +/* passwd.c --- verifying typed passwords with the OS. + * xscreensaver, Copyright (c) 1993-1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +extern char *blurb(void); + + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + +#undef countof +#define countof(x) (sizeof((x))/sizeof(*(x))) + +struct auth_methods { + const char *name; + Bool (*init) (int argc, char **argv, Bool verbose_p); + Bool (*priv_init) (int argc, char **argv, Bool verbose_p); + Bool (*valid_p) (const char *typed_passwd, Bool verbose_p); + Bool initted_p; + Bool priv_initted_p; +}; + + +#ifdef HAVE_KERBEROS +extern Bool kerberos_lock_init (int argc, char **argv, Bool verbose_p); +extern Bool kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p); +#endif +#ifdef HAVE_PAM +extern Bool pam_priv_init (int argc, char **argv, Bool verbose_p); +extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p); +#endif +extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p); +extern Bool pwent_priv_init (int argc, char **argv, Bool verbose_p); +extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p); + + +/* The authorization methods to try, in order. + Note that the last one (the pwent version) is actually two auth methods, + since that code tries shadow passwords, and then non-shadow passwords. + (It's all in the same file since the APIs are randomly nearly-identical.) + */ +struct auth_methods methods[] = { +# ifdef HAVE_KERBEROS + { "Kerberos", kerberos_lock_init, 0, kerberos_passwd_valid_p, + False, False }, +# endif +# ifdef HAVE_PAM + { "PAM", 0, pam_priv_init, pam_passwd_valid_p, + False, False }, +# endif + { "normal", pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p, + False, False } +}; + + +Bool +lock_priv_init (int argc, char **argv, Bool verbose_p) +{ + int i; + Bool any_ok = False; + for (i = 0; i < countof(methods); i++) + { + if (!methods[i].priv_init) + methods[i].priv_initted_p = True; + else + methods[i].priv_initted_p = methods[i].priv_init (argc, argv, + verbose_p); + + if (methods[i].priv_initted_p) + any_ok = True; + else if (verbose_p) + fprintf (stderr, "%s: initialization of %s passwords failed.\n", + blurb(), methods[i].name); + } + return any_ok; +} + + +Bool +lock_init (int argc, char **argv, Bool verbose_p) +{ + int i; + Bool any_ok = False; + for (i = 0; i < countof(methods); i++) + { + if (!methods[i].priv_initted_p) /* Bail if lock_priv_init failed. */ + continue; + + if (!methods[i].init) + methods[i].initted_p = True; + else + methods[i].initted_p = methods[i].init (argc, argv, verbose_p); + + if (methods[i].initted_p) + any_ok = True; + else if (verbose_p) + fprintf (stderr, "%s: initialization of %s passwords failed.\n", + blurb(), methods[i].name); + } + return any_ok; +} + + +Bool +passwd_valid_p (const char *typed_passwd, Bool verbose_p) +{ + int i, j; + for (i = 0; i < countof(methods); i++) + { + if (methods[i].initted_p && + methods[i].valid_p (typed_passwd, verbose_p)) + { + /* If we successfully authenticated by method N, but attempting + to authenticate by method N-1 failed, mention that (since if + an earlier authentication method fails and a later one succeeds, + something screwy is probably going on.) + */ + if (verbose_p && i > 0) + { + for (j = 0; j < i; j++) + if (methods[j].initted_p) + fprintf (stderr, + "%s: authentication via %s passwords failed.\n", + blurb(), methods[j].name); + fprintf (stderr, + "%s: but authentication via %s passwords succeeded.\n", + blurb(), methods[i].name); + } + + return True; /* Successfully authenticated! */ + } + } + + return False; /* Authentication failure. */ +} + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/prefs.c b/driver/prefs.c new file mode 100644 index 00000000..fa8950f9 --- /dev/null +++ b/driver/prefs.c @@ -0,0 +1,1029 @@ +/* dotfile.c --- management of the ~/.xscreensaver file. + * xscreensaver, Copyright (c) 1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#ifndef VMS +# include +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + + +/* Just in case there's something pathological about stat.h... */ +#ifndef S_IRUSR +# define S_IRUSR 00400 +#endif +#ifndef S_IWUSR +# define S_IWUSR 00200 +#endif +#ifndef S_IXUSR +# define S_IXUSR 00100 +#endif +#ifndef S_IXGRP +# define S_IXGRP 00010 +#endif +#ifndef S_IXOTH +# define S_IXOTH 00001 +#endif + + +#include "prefs.h" +#include "resources.h" + + +extern char *progname; +extern char *progclass; +extern const char *blurb (void); + + + +static void get_screenhacks (saver_preferences *p); + + +static char * +chase_symlinks (const char *file) +{ +# ifdef HAVE_REALPATH + if (file) + { + char buf [2048]; + if (realpath (file, buf)) + return strdup (buf); + + sprintf (buf, "%s: realpath", blurb()); + perror(buf); + } +# endif /* HAVE_REALPATH */ + return 0; +} + + +const char * +init_file_name (void) +{ + static char *file = 0; + + if (!file) + { + struct passwd *p = getpwuid (getuid ()); + + if (!p || !p->pw_name || !*p->pw_name) + { + fprintf (stderr, "%s: couldn't get user info of uid %d\n", + blurb(), getuid ()); + file = ""; + } + else if (!p->pw_dir || !*p->pw_dir) + { + fprintf (stderr, "%s: couldn't get home directory of \"%s\"\n", + blurb(), (p->pw_name ? p->pw_name : "???")); + file = ""; + } + else + { + const char *home = p->pw_dir; + const char *name = ".xscreensaver"; + file = (char *) malloc(strlen(home) + strlen(name) + 2); + strcpy(file, home); + if (!*home || home[strlen(home)-1] != '/') + strcat(file, "/"); + strcat(file, name); + } + } + + if (file && *file) + return file; + else + return 0; +} + + +static const char * +init_file_tmp_name (void) +{ + static char *file = 0; + if (!file) + { + const char *name = init_file_name(); + const char *suffix = ".tmp"; + + char *n2 = chase_symlinks (name); + if (n2) name = n2; + + if (!name || !*name) + file = ""; + else + { + file = (char *) malloc(strlen(name) + strlen(suffix) + 2); + strcpy(file, name); + strcat(file, suffix); + } + + if (n2) free (n2); + } + + if (file && *file) + return file; + else + return 0; +} + + +static const char * const prefs[] = { + "timeout", + "cycle", + "lock", + "lockVTs", + "lockTimeout", + "passwdTimeout", + "visualID", + "installColormap", + "verbose", + "timestamp", + "splash", /* not saved -- same as "splashDuration: 0" */ + "splashDuration", + "demoCommand", + "prefsCommand", + "helpURL", + "loadURL", + "nice", + "fade", + "unfade", + "fadeSeconds", + "fadeTicks", + "captureStderr", + "captureStdout", /* not saved -- obsolete */ + "font", + "", + "programs", + "", + "pointerPollTime", + "windowCreationTimeout", + "initialDelay", + "sgiSaverExtension", + "mitSaverExtension", + "xidleExtension", + "procInterrupts", + "overlayStderr", + "overlayTextBackground", /* not saved -- X resources only */ + "overlayTextForeground", /* not saved -- X resources only */ + "bourneShell", /* not saved -- X resources only */ + 0 +}; + +static char * +strip (char *s) +{ + char *s2; + while (*s == '\t' || *s == ' ' || *s == '\r' || *s == '\n') + s++; + for (s2 = s; *s2; s2++) + ; + for (s2--; s2 >= s; s2--) + if (*s2 == '\t' || *s2 == ' ' || *s2 == '\r' || *s2 =='\n') + *s2 = 0; + else + break; + return s; +} + + +/* Reading + */ + +static int +handle_entry (XrmDatabase *db, const char *key, const char *value, + const char *filename, int line) +{ + int i; + for (i = 0; prefs[i]; i++) + if (*prefs[i] && !strcasecmp(key, prefs[i])) + { + char *val = strdup(value); + char *spec = (char *) malloc(strlen(progclass) + strlen(prefs[i]) +10); + strcpy(spec, progclass); + strcat(spec, "."); + strcat(spec, prefs[i]); + + XrmPutStringResource (db, spec, val); + + free(spec); + free(val); + return 0; + } + + fprintf(stderr, "%s: %s:%d: unknown option \"%s\"\n", + blurb(), filename, line, key); + return 1; +} + + +static int +parse_init_file (saver_preferences *p) +{ + time_t write_date = 0; + const char *name = init_file_name(); + int line = 0; + struct stat st; + FILE *in; + int buf_size = 1024; + char *buf; + + if (!name) return 0; + + if (stat(name, &st) != 0) + { + p->init_file_date = 0; + return 0; + } + + in = fopen(name, "r"); + if (!in) + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: error reading \"%s\"", blurb(), name); + perror(buf); + free(buf); + return -1; + } + + if (fstat (fileno(in), &st) == 0) + { + write_date = st.st_mtime; + } + else + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: couldn't re-stat \"%s\"", blurb(), name); + perror(buf); + free(buf); + return -1; + } + + buf = (char *) malloc(buf_size); + + while (fgets (buf, buf_size-1, in)) + { + char *key, *value; + int L = strlen(buf); + + line++; + while (L > 2 && + (buf[L-1] != '\n' || /* whole line didn't fit in buffer */ + buf[L-2] == '\\')) /* or line ended with backslash */ + { + if (buf[L-2] == '\\') /* backslash-newline gets swallowed */ + { + buf[L-2] = 0; + L -= 2; + } + buf_size += 1024; + buf = (char *) realloc(buf, buf_size); + if (!buf) exit(1); + + line++; + if (!fgets (buf + L, buf_size-L-1, in)) + break; + L = strlen(buf); + } + + /* Now handle other backslash escapes. */ + { + int i, j; + for (i = 0; buf[i]; i++) + if (buf[i] == '\\') + { + switch (buf[i+1]) + { + case 'n': buf[i] = '\n'; break; + case 'r': buf[i] = '\r'; break; + case 't': buf[i] = '\t'; break; + default: buf[i] = buf[i+1]; break; + } + for (j = i+2; buf[j]; j++) + buf[j-1] = buf[j]; + buf[j-1] = 0; + } + } + + key = strip(buf); + + if (*key == '#' || *key == '!' || *key == ';' || + *key == '\n' || *key == 0) + continue; + + value = strchr (key, ':'); + if (!value) + { + fprintf(stderr, "%s: %s:%d: unparsable line: %s\n", blurb(), + name, line, key); + continue; + } + else + { + *value++ = 0; + value = strip(value); + } + + if (!p->db) abort(); + handle_entry (&p->db, key, value, name, line); + } + free(buf); + + p->init_file_date = write_date; + return 0; +} + + +Bool +init_file_changed_p (saver_preferences *p) +{ + const char *name = init_file_name(); + struct stat st; + + if (!name) return False; + + if (stat(name, &st) != 0) + return False; + + if (p->init_file_date == st.st_mtime) + return False; + + return True; +} + + +/* Writing + */ + +static int +tab_to (FILE *out, int from, int to) +{ + int tab_width = 8; + int to_mod = (to / tab_width) * tab_width; + while (from < to_mod) + { + fprintf(out, "\t"); + from = (((from / tab_width) + 1) * tab_width); + } + while (from < to) + { + fprintf(out, " "); + from++; + } + return from; +} + +static void +write_entry (FILE *out, const char *key, const char *value) +{ + char *v = strdup(value ? value : ""); + char *v2 = v; + char *nl = 0; + int col; + Bool do_visual_kludge = (!strcmp(key, "programs")); + Bool do_wrap = do_visual_kludge; + int tab = (do_visual_kludge ? 16 : 23); + int tab2 = 3; + Bool first = True; + + fprintf(out, "%s:", key); + col = strlen(key) + 1; + + while (1) + { + char *s; + Bool disabled_p = False; + + v2 = strip(v2); + nl = strchr(v2, '\n'); + if (nl) + *nl = 0; + + if (do_visual_kludge && *v2 == '-') + { + disabled_p = True; + v2++; + v2 = strip(v2); + } + + if (first && disabled_p) + first = False; + + if (first) + first = False; + else + { + col = tab_to(out, col, 75); + fprintf(out, " \\n\\\n"); + col = 0; + } + + if (disabled_p) + { + fprintf(out, "-"); + col++; + } + + s = (do_visual_kludge ? strpbrk(v2, " \t\n:") : 0); + if (s && *s == ':') + col = tab_to (out, col, tab2); + else + col = tab_to (out, col, tab); + + if (do_wrap && + strlen(v2) + col > 75) + { + int L = strlen(v2); + int start = 0; + int end = start; + while (start < L) + { + while (v2[end] == ' ' || v2[end] == '\t') + end++; + while (v2[end] != ' ' && v2[end] != '\t' && + v2[end] != '\n' && v2[end] != 0) + end++; + if (col + (end - start) >= 74) + { + col = tab_to (out, col, 75); + fprintf(out, " \\\n"); + col = tab_to (out, 0, tab + 2); + while (v2[start] == ' ' || v2[start] == '\t') + start++; + } + + while (start < end) + { + fputc(v2[start++], out); + col++; + } + } + } + else + { + fprintf (out, "%s", v2); + col += strlen(v2); + } + + if (nl) + v2 = nl + 1; + else + break; + } + + fprintf(out, "\n"); + free(v); +} + +void +write_init_file (saver_preferences *p, const char *version_string) +{ + const char *name = init_file_name(); + const char *tmp_name = init_file_tmp_name(); + char *n2 = chase_symlinks (name); + struct stat st; + int i, j; + + /* Kludge, since these aren't in the saver_preferences struct as strings... + */ + char *visual_name; + char *programs; + Bool capture_stderr_p; + Bool overlay_stderr_p; + char *stderr_font; + FILE *out; + + if (!name) goto END; + + if (n2) name = n2; + + if (p->verbose_p) + fprintf (stderr, "%s: writing \"%s\".\n", blurb(), name); + + unlink (tmp_name); + out = fopen(tmp_name, "w"); + if (!out) + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: error writing \"%s\"", blurb(), name); + perror(buf); + free(buf); + goto END; + } + + /* Give the new .xscreensaver file the same permissions as the old one; + except ensure that it is readable and writable by owner, and not + executable. + */ + if (stat(name, &st) == 0) + { + mode_t mode = st.st_mode; + mode |= S_IRUSR | S_IWUSR; + mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); + if (fchmod (fileno(out), mode) != 0) + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf (buf, "%s: error fchmodding \"%s\" to 0%o", blurb(), + tmp_name, (unsigned int) mode); + perror(buf); + free(buf); + goto END; + } + } + + /* Kludge, since these aren't in the saver_preferences struct... */ + visual_name = get_string_resource ("visualID", "VisualID"); + programs = 0; + capture_stderr_p = get_boolean_resource ("captureStderr", "Boolean"); + overlay_stderr_p = get_boolean_resource ("overlayStderr", "Boolean"); + stderr_font = get_string_resource ("font", "Font"); + + i = 0; + for (j = 0; j < p->screenhacks_count; j++) + i += strlen(p->screenhacks[j]) + 2; + { + char *ss = programs = (char *) malloc(i + 10); + *ss = 0; + for (j = 0; j < p->screenhacks_count; j++) + { + strcat(ss, p->screenhacks[j]); + ss += strlen(ss); + *ss++ = '\n'; + *ss = 0; + } + } + + { + struct passwd *pw = getpwuid (getuid ()); + char *whoami = (pw && pw->pw_name && *pw->pw_name + ? pw->pw_name + : ""); + time_t now = time ((time_t *) 0); + char *timestr = (char *) ctime (&now); + char *nl = (char *) strchr (timestr, '\n'); + if (nl) *nl = 0; + fprintf (out, + "# %s Preferences File\n" + "# Written by %s %s for %s on %s.\n" + "# http://www.jwz.org/xscreensaver/\n" + "\n", + progclass, progname, version_string, whoami, timestr); + } + + for (j = 0; prefs[j]; j++) + { + char buf[255]; + const char *pr = prefs[j]; + enum pref_type { pref_str, pref_int, pref_bool, pref_time + } type = pref_str; + const char *s = 0; + int i = 0; + Bool b = False; + Time t = 0; + + if (pr && !*pr) + { + fprintf(out, "\n"); + continue; + } + +# undef CHECK +# define CHECK(X) else if (!strcmp(pr, X)) + if (!pr || !*pr) ; + CHECK("timeout") type = pref_time, t = p->timeout; + CHECK("cycle") type = pref_time, t = p->cycle; + CHECK("lock") type = pref_bool, b = p->lock_p; +# if 0 /* #### not ready yet */ + CHECK("lockVTs") type = pref_bool, b = p->lock_vt_p; +# else + CHECK("lockVTs") continue; /* don't save */ +# endif + CHECK("lockTimeout") type = pref_time, t = p->lock_timeout; + CHECK("passwdTimeout") type = pref_time, t = p->passwd_timeout; + CHECK("visualID") type = pref_str, s = visual_name; + CHECK("installColormap") type = pref_bool, b = p->install_cmap_p; + CHECK("verbose") type = pref_bool, b = p->verbose_p; + CHECK("timestamp") type = pref_bool, b = p->timestamp_p; + CHECK("splash") continue; /* don't save */ + CHECK("splashDuration") type = pref_time, t = p->splash_duration; + CHECK("demoCommand") type = pref_str, s = p->demo_command; + CHECK("prefsCommand") type = pref_str, s = p->prefs_command; + CHECK("helpURL") type = pref_str, s = p->help_url; + CHECK("loadURL") type = pref_str, s = p->load_url_command; + CHECK("nice") type = pref_int, i = p->nice_inferior; + CHECK("fade") type = pref_bool, b = p->fade_p; + CHECK("unfade") type = pref_bool, b = p->unfade_p; + CHECK("fadeSeconds") type = pref_time, t = p->fade_seconds; + CHECK("fadeTicks") type = pref_int, i = p->fade_ticks; + CHECK("captureStderr") type = pref_bool, b = capture_stderr_p; + CHECK("captureStdout") continue; /* don't save */ + CHECK("font") type = pref_str, s = stderr_font; + CHECK("programs") type = pref_str, s = programs; + CHECK("pointerPollTime") type = pref_time, t = p->pointer_timeout; + CHECK("windowCreationTimeout")type=pref_time,t= p->notice_events_timeout; + CHECK("initialDelay") type = pref_time, t = p->initial_delay; + CHECK("sgiSaverExtension")type = pref_bool, b=p->use_sgi_saver_extension; + CHECK("mitSaverExtension")type = pref_bool, b=p->use_mit_saver_extension; + CHECK("xidleExtension") type = pref_bool, b = p->use_xidle_extension; + CHECK("procInterrupts") type = pref_bool, b = p->use_proc_interrupts; + CHECK("overlayStderr") type = pref_bool, b = overlay_stderr_p; + CHECK("overlayTextBackground") continue; /* don't save */ + CHECK("overlayTextForeground") continue; /* don't save */ + CHECK("bourneShell") continue; + else abort(); +# undef CHECK + + switch (type) + { + case pref_str: + break; + case pref_int: + sprintf(buf, "%d", i); + s = buf; + break; + case pref_bool: + s = b ? "True" : "False"; + break; + case pref_time: + { + unsigned int hour = 0, min = 0, sec = (unsigned int) (t/1000); + if (sec >= 60) + { + min += (sec / 60); + sec %= 60; + } + if (min >= 60) + { + hour += (min / 60); + min %= 60; + } + sprintf (buf, "%u:%02u:%02u", hour, min, sec); + s = buf; + } + break; + default: + abort(); + break; + } + write_entry (out, pr, s); + } + + fprintf(out, "\n"); + + if (visual_name) free(visual_name); + if (stderr_font) free(stderr_font); + if (programs) free(programs); + + if (fclose(out) == 0) + { + time_t write_date = 0; + + if (stat(tmp_name, &st) == 0) + { + write_date = st.st_mtime; + } + else + { + char *buf = (char *) malloc(1024 + strlen(tmp_name) + strlen(name)); + sprintf(buf, "%s: couldn't stat \"%s\"", blurb(), tmp_name); + perror(buf); + unlink (tmp_name); + free(buf); + goto END; + } + + if (rename (tmp_name, name) != 0) + { + char *buf = (char *) malloc(1024 + strlen(tmp_name) + strlen(name)); + sprintf(buf, "%s: error renaming \"%s\" to \"%s\"", + blurb(), tmp_name, name); + perror(buf); + unlink (tmp_name); + free(buf); + goto END; + } + else + { + p->init_file_date = write_date; + + /* Since the .xscreensaver file is used for IPC, let's try and make + sure that the bits actually land on the disk right away. */ + sync (); + } + } + else + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: error closing \"%s\"", blurb(), name); + perror(buf); + free(buf); + unlink (tmp_name); + goto END; + } + + END: + if (n2) free (n2); +} + + +/* Parsing the resource database + */ + + +/* Populate `saver_preferences' with the contents of the resource database. + Note that this may be called multiple times -- it is re-run each time + the ~/.xscreensaver file is reloaded. + + This function can be very noisy, since it issues resource syntax errors + and so on. + */ +void +load_init_file (saver_preferences *p) +{ + static Bool first_time = True; + + if (parse_init_file (p) != 0) /* file might have gone away */ + if (!first_time) return; + + first_time = False; + + p->xsync_p = get_boolean_resource ("synchronous", "Synchronous"); + p->verbose_p = get_boolean_resource ("verbose", "Boolean"); + p->timestamp_p = get_boolean_resource ("timestamp", "Boolean"); + p->lock_p = get_boolean_resource ("lock", "Boolean"); + p->lock_vt_p = get_boolean_resource ("lockVTs", "Boolean"); + p->fade_p = get_boolean_resource ("fade", "Boolean"); + p->unfade_p = get_boolean_resource ("unfade", "Boolean"); + p->fade_seconds = 1000 * get_seconds_resource ("fadeSeconds", "Time"); + p->fade_ticks = get_integer_resource ("fadeTicks", "Integer"); + p->install_cmap_p = get_boolean_resource ("installColormap", "Boolean"); + p->nice_inferior = get_integer_resource ("nice", "Nice"); + + p->initial_delay = 1000 * get_seconds_resource ("initialDelay", "Time"); + p->splash_duration = 1000 * get_seconds_resource ("splashDuration", "Time"); + p->timeout = 1000 * get_minutes_resource ("timeout", "Time"); + p->lock_timeout = 1000 * get_minutes_resource ("lockTimeout", "Time"); + p->cycle = 1000 * get_minutes_resource ("cycle", "Time"); + p->passwd_timeout = 1000 * get_seconds_resource ("passwdTimeout", "Time"); + p->pointer_timeout = 1000 * get_seconds_resource ("pointerPollTime", "Time"); + p->notice_events_timeout = 1000*get_seconds_resource("windowCreationTimeout", + "Time"); + p->shell = get_string_resource ("bourneShell", "BourneShell"); + + p->demo_command = get_string_resource("demoCommand", "URL"); + p->prefs_command = get_string_resource("prefsCommand", "URL"); + p->help_url = get_string_resource("helpURL", "URL"); + p->load_url_command = get_string_resource("loadURL", "LoadURL"); + + { + char *s; + if ((s = get_string_resource ("splash", "Boolean"))) + if (!get_boolean_resource("splash", "Boolean")) + p->splash_duration = 0; + if (s) free (s); + } + + p->use_xidle_extension = get_boolean_resource ("xidleExtension","Boolean"); + p->use_mit_saver_extension = get_boolean_resource ("mitSaverExtension", + "Boolean"); + p->use_sgi_saver_extension = get_boolean_resource ("sgiSaverExtension", + "Boolean"); + p->use_proc_interrupts = get_boolean_resource ("procInterrupts", "Boolean"); + + /* Throttle the various timeouts to reasonable values. + */ + if (p->passwd_timeout <= 0) p->passwd_timeout = 30000; /* 30 secs */ + if (p->timeout < 10000) p->timeout = 10000; /* 10 secs */ + if (p->cycle != 0 && p->cycle < 2000) p->cycle = 2000; /* 2 secs */ + if (p->pointer_timeout <= 0) p->pointer_timeout = 5000; /* 5 secs */ + if (p->notice_events_timeout <= 0) + p->notice_events_timeout = 10000; /* 10 secs */ + if (p->fade_seconds <= 0 || p->fade_ticks <= 0) + p->fade_p = False; + if (! p->fade_p) p->unfade_p = False; + + p->watchdog_timeout = p->cycle * 0.6; + if (p->watchdog_timeout < 30000) p->watchdog_timeout = 30000; /* 30 secs */ + if (p->watchdog_timeout > 3600000) p->watchdog_timeout = 3600000; /* 1 hr */ + + get_screenhacks (p); + + if (p->debug_p) + { + p->xsync_p = True; + p->verbose_p = True; + p->timestamp_p = True; + p->initial_delay = 0; + } +} + + +/* Parsing the programs resource. + */ + +static char * +reformat_hack (const char *hack) +{ + int i; + const char *in = hack; + int indent = 15; + char *h2 = (char *) malloc(strlen(in) + indent + 2); + char *out = h2; + Bool disabled_p = False; + + while (isspace(*in)) in++; /* skip whitespace */ + + if (*in == '-') /* Handle a leading "-". */ + { + in++; + hack = in; + *out++ = '-'; + *out++ = ' '; + disabled_p = True; + while (isspace(*in)) in++; + } + else + { + *out++ = ' '; + *out++ = ' '; + } + + while (*in && !isspace(*in) && *in != ':') + *out++ = *in++; /* snarf first token */ + while (isspace(*in)) in++; /* skip whitespace */ + + if (*in == ':') + *out++ = *in++; /* copy colon */ + else + { + in = hack; + out = h2 + 2; /* reset to beginning */ + } + + *out = 0; + + while (isspace(*in)) in++; /* skip whitespace */ + for (i = strlen(h2); i < indent; i++) /* indent */ + *out++ = ' '; + + /* copy the rest of the line. */ + while (*in) + { + /* shrink all whitespace to one space, for the benefit of the "demo" + mode display. We only do this when we can easily tell that the + whitespace is not significant (no shell metachars). + */ + switch (*in) + { + case '\'': case '"': case '`': case '\\': + { + /* Metachars are scary. Copy the rest of the line unchanged. */ + while (*in) + *out++ = *in++; + } + break; + case ' ': case '\t': + { + while (*in == ' ' || *in == '\t') + in++; + *out++ = ' '; + } + break; + default: + *out++ = *in++; + break; + } + } + *out = 0; + + /* strip trailing whitespace. */ + out = out-1; + while (out > h2 && (*out == ' ' || *out == '\t' || *out == '\n')) + *out-- = 0; + + return h2; +} + + +static void +get_screenhacks (saver_preferences *p) +{ + int i = 0; + int start = 0; + int end = 0; + int size; + char *d; + + d = get_string_resource ("monoPrograms", "MonoPrograms"); + if (d && !*d) { free(d); d = 0; } + if (!d) + d = get_string_resource ("colorPrograms", "ColorPrograms"); + if (d && !*d) { free(d); d = 0; } + + if (d) + { + fprintf (stderr, + "%s: the `monoPrograms' and `colorPrograms' resources are obsolete;\n\ + see the manual for details.\n", blurb()); + free(d); + } + + d = get_string_resource ("programs", "Programs"); + + if (p->screenhacks) + { + for (i = 0; i < p->screenhacks_count; i++) + if (p->screenhacks[i]) + free (p->screenhacks[i]); + free(p->screenhacks); + p->screenhacks = 0; + } + + if (!d || !*d) + { + p->screenhacks_count = 0; + p->screenhacks = 0; + return; + } + + size = strlen (d); + + + /* Count up the number of newlines (which will be equal to or larger than + the number of hacks.) + */ + i = 0; + for (i = 0; d[i]; i++) + if (d[i] == '\n') + i++; + i++; + + p->screenhacks = (char **) calloc (sizeof (char *), i+1); + + /* Iterate over the lines in `d' (the string with newlines) + and make new strings to stuff into the `screenhacks' array. + */ + p->screenhacks_count = 0; + while (start < size) + { + /* skip forward over whitespace. */ + while (d[start] == ' ' || d[start] == '\t' || d[start] == '\n') + start++; + + /* skip forward to newline or end of string. */ + end = start; + while (d[end] != 0 && d[end] != '\n') + end++; + + /* null terminate. */ + d[end] = 0; + + p->screenhacks[p->screenhacks_count++] = reformat_hack (d + start); + if (p->screenhacks_count >= i) + abort(); + + start = end+1; + } + + if (p->screenhacks_count == 0) + { + free (p->screenhacks); + p->screenhacks = 0; + } +} diff --git a/driver/prefs.h b/driver/prefs.h new file mode 100644 index 00000000..62c768d9 --- /dev/null +++ b/driver/prefs.h @@ -0,0 +1,81 @@ +/* xscreensaver, Copyright (c) 1993-1998 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. + */ + +#ifndef __XSCREENSAVER_PREFS_H__ +#define __XSCREENSAVER_PREFS_H__ + +typedef struct saver_preferences saver_preferences; + + +/* This structure holds all the user-specified parameters, read from the + command line, the resource database, or entered through a dialog box. + */ +struct saver_preferences { + + XrmDatabase db; /* The resource database into which the + init file is merged, and out of which the + preferences are parsed. */ + + time_t init_file_date; /* The date (from stat()) of the .xscreensaver + file the last time this process read or + wrote it. */ + + Bool verbose_p; /* whether to print out lots of status info */ + Bool timestamp_p; /* whether to mark messages with a timestamp */ + Bool debug_p; /* pay no mind to the man behind the curtain */ + Bool xsync_p; /* whether XSynchronize has been called */ + + Bool lock_p; /* whether to lock as well as save */ + Bool lock_vt_p; /* whether to lock VTs too, if possible */ + + Bool fade_p; /* whether to fade to black, if possible */ + Bool unfade_p; /* whether to fade from black, if possible */ + int fade_seconds; /* how long that should take */ + int fade_ticks; /* how many ticks should be used */ + + Bool install_cmap_p; /* whether we should use our own colormap + when using the screen's default visual. */ + + char **screenhacks; /* the programs to run */ + int screenhacks_count; + + int nice_inferior; /* nice value for subprocs */ + + Time initial_delay; /* how long to sleep after launch */ + Time splash_duration; /* how long the splash screen stays up */ + Time timeout; /* how much idle time before activation */ + Time lock_timeout; /* how long after activation locking starts */ + Time cycle; /* how long each hack should run */ + Time passwd_timeout; /* how much time before pw dialog goes down */ + Time pointer_timeout; /* how often to check mouse position */ + Time notice_events_timeout; /* how long after window creation to select */ + Time watchdog_timeout; /* how often to re-raise and re-blank screen */ + + Bool use_xidle_extension; /* which extension to use, if possible */ + Bool use_mit_saver_extension; + Bool use_sgi_saver_extension; + Bool use_proc_interrupts; + + char *shell; /* where to find /bin/sh */ + + char *demo_command; /* How to enter demo mode. */ + char *prefs_command; /* How to edit preferences. */ + char *help_url; /* Where the help document resides. */ + char *load_url_command; /* How one loads URLs. */ +}; + + +extern void load_init_file (saver_preferences *p); +extern Bool init_file_changed_p (saver_preferences *p); +extern void write_init_file (saver_preferences *p, const char *version_string); +const char *init_file_name (void); + +#endif /* __XSCREENSAVER_PREFS_H__ */ diff --git a/driver/remote.c b/driver/remote.c new file mode 100644 index 00000000..26c85558 --- /dev/null +++ b/driver/remote.c @@ -0,0 +1,461 @@ +/* xscreensaver-command, Copyright (c) 1991-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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#ifdef HAVE_SYS_SELECT_H +# include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include /* for CARD32 */ +#include +#include +#include /* for XGetClassHint() */ +#include + +#include "remote.h" + +#ifdef _VROOT_H_ +ERROR! you must not include vroot.h in this file +#endif + +extern char *progname; +extern Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; +extern Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_TIME; +extern Atom XA_VROOT, XA_SELECT, XA_DEMO; + + +static XErrorHandler old_handler = 0; +static Bool got_badwindow = False; +static int +BadWindow_ehandler (Display *dpy, XErrorEvent *error) +{ + if (error->error_code == BadWindow) + { + got_badwindow = True; + return 0; + } + else + { + fprintf (stderr, "%s: ", progname); + if (!old_handler) abort(); + return (*old_handler) (dpy, error); + } +} + + + +static Window +find_screensaver_window (Display *dpy, char **version) +{ + int i; + Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy)); + Window root2, parent, *kids; + unsigned int nkids; + + if (version) *version = 0; + + if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids)) + abort (); + if (root != root2) + abort (); + if (parent) + abort (); + if (! (kids && nkids)) + abort (); + for (i = 0; i < nkids; i++) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + char *v; + int status; + + /* We're walking the list of root-level windows and trying to find + the one that has a particular property on it. We need to trap + BadWindows errors while doing this, because it's possible that + some random window might get deleted in the meantime. (That + window won't have been the one we're looking for.) + */ + XSync (dpy, False); + if (old_handler) abort(); + old_handler = XSetErrorHandler (BadWindow_ehandler); + status = XGetWindowProperty (dpy, kids[i], + XA_SCREENSAVER_VERSION, + 0, 200, False, XA_STRING, + &type, &format, &nitems, &bytesafter, + (unsigned char **) &v); + XSync (dpy, False); + XSetErrorHandler (old_handler); + old_handler = 0; + + if (got_badwindow) + status = BadWindow; + + if (status == Success && type != None) + { + if (version) + *version = v; + return kids[i]; + } + } + fprintf (stderr, "%s: no screensaver is running on display %s\n", progname, + DisplayString (dpy)); + return 0; +} + + +static int +send_xscreensaver_command (Display *dpy, Atom command, long arg, + Window *window_ret) +{ + char *v = 0; + Window window = find_screensaver_window (dpy, &v); + XWindowAttributes xgwa; + + if (window_ret) + *window_ret = window; + + if (!window) + return -1; + + /* Select for property change events, so that we can read the response. */ + XGetWindowAttributes (dpy, window, &xgwa); + XSelectInput (dpy, window, xgwa.your_event_mask | PropertyChangeMask); + + 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", + progname, (unsigned int) window); + return -1; + } + + XGetClassHint(dpy, window, &hint); + if (!hint.res_class) + { + fprintf (stderr, "%s: class hints not set on window 0x%x?\n", + progname, (unsigned int) window); + return -1; + } + + fprintf (stdout, "%s %s", hint.res_class, v); + + if (command != XA_SCREENSAVER_TIME) + { + fprintf (stdout, "\n"); + } + else + { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *data = 0; + Bool active_p = False; + + if (XGetWindowProperty (dpy, window, XA_VROOT, + 0, 0, False, XA_WINDOW, + &type, &format, &nitems, &bytesafter, + &data) + == Success + && type != None) + active_p = True; + + if (data) free (data); + data = 0; + + if (XGetWindowProperty (dpy, window, + XA_SCREENSAVER_TIME, + 0, 1, False, XA_INTEGER, + &type, &format, &nitems, &bytesafter, + &data) + == Success + && type == XA_INTEGER + && data) + { + CARD32 time32 = *((CARD32 *)data); + time_t tt = (time_t) time32; + + if (active_p) + fprintf (stdout, ": screen blanked since "); + else + /* 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); + } + else + { + if (data) free (data); + fprintf (stdout, "\n"); + fflush (stdout); + fprintf (stderr, "%s: no time on window 0x%x (%s %s).\n", + progname, (unsigned int) window, + hint.res_class, (v ? v : "???")); + return -1; + } + } + + /* No need to read a response for these commands. */ + return 1; + } + else + { + XEvent event; + long arg1 = arg; + long arg2 = 0; + + if (arg < 0) + abort(); + else if (arg == 0 && command == XA_SELECT) + abort(); + else if (arg != 0 && command == XA_DEMO) + { + arg1 = 300; /* version number of the XA_DEMO protocol, */ + arg2 = arg; /* since it didn't use to take an argument. */ + } + + event.xany.type = ClientMessage; + event.xclient.display = dpy; + event.xclient.window = window; + event.xclient.message_type = XA_SCREENSAVER; + event.xclient.format = 32; + memset (&event.xclient.data, 0, sizeof(event.xclient.data)); + event.xclient.data.l[0] = (long) command; + event.xclient.data.l[1] = arg1; + event.xclient.data.l[2] = arg2; + if (! XSendEvent (dpy, window, False, 0L, &event)) + { + fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n", + progname, (unsigned int) window); + return -1; + } + } + XSync (dpy, 0); + return 0; +} + + +static int +xscreensaver_command_response (Display *dpy, Window window, Bool verbose_p) +{ + int fd = ConnectionNumber (dpy); + int timeout = 10; + int status; + fd_set fds; + struct timeval tv; + + while (1) + { + FD_ZERO(&fds); + FD_SET(fd, &fds); + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = timeout; + status = select (fd+1, &fds, 0, &fds, &tv); + + if (status < 0) + { + char buf[1024]; + sprintf (buf, "%s: waiting for reply", progname); + perror (buf); + return status; + } + else if (status == 0) + { + fprintf (stderr, "%s: no response to command.\n", progname); + return -1; + } + else + { + XEvent event; + XNextEvent (dpy, &event); + if (event.xany.type == PropertyNotify && + event.xproperty.state == PropertyNewValue && + event.xproperty.atom == XA_SCREENSAVER_RESPONSE) + { + Status st2; + Atom type; + int format; + unsigned long nitems, bytesafter; + char *msg = 0; + + XSync (dpy, False); + if (old_handler) abort(); + old_handler = XSetErrorHandler (BadWindow_ehandler); + st2 = XGetWindowProperty (dpy, window, + XA_SCREENSAVER_RESPONSE, + 0, 1024, True, + AnyPropertyType, + &type, &format, &nitems, &bytesafter, + (unsigned char **) &msg); + XSync (dpy, False); + XSetErrorHandler (old_handler); + old_handler = 0; + + if (got_badwindow) + { + fprintf (stdout, + "%s: xscreensaver window has been deleted.\n", + progname); + return 0; + } + + if (st2 == Success && type != None) + { + if (type != XA_STRING || format != 8) + { + fprintf (stderr, + "%s: unrecognized response property.\n", + progname); + if (msg) XFree (msg); + return -1; + } + else if (!msg || (msg[0] != '+' && msg[0] != '-')) + { + fprintf (stderr, + "%s: unrecognized response message.\n", + progname); + if (msg) XFree (msg); + return -1; + } + else + { + int ret = (msg[0] == '+' ? 0 : -1); + if (verbose_p || ret != 0) + fprintf ((ret < 0 ? stderr : stdout), + "%s: %s\n", + progname, + msg+1); + XFree (msg); + return ret; + } + } + } + } + } +} + + +int +xscreensaver_command (Display *dpy, Atom command, long arg, Bool verbose_p) +{ + Window w = 0; + int status = send_xscreensaver_command (dpy, command, arg, &w); + if (status == 0) + status = xscreensaver_command_response (dpy, w, verbose_p); + fflush (stdout); + fflush (stderr); + return status; +} + + +void +server_xscreensaver_version (Display *dpy, + char **version_ret, + char **user_ret, + char **host_ret) +{ + Window window = find_screensaver_window (dpy, 0); + + Atom type; + int format; + unsigned long nitems, bytesafter; + + if (version_ret) + *version_ret = 0; + if (user_ret) + *user_ret = 0; + if (host_ret) + *host_ret = 0; + + if (!window) + return; + + if (version_ret) + { + char *v = 0; + XGetWindowProperty (dpy, window, XA_SCREENSAVER_VERSION, 0, 1, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, (unsigned char **) &v); + if (v) + { + *version_ret = strdup (v); + XFree (v); + } + } + + if (user_ret || host_ret) + { + char *id = 0; + const char *user = 0; + const char *host = 0; + + XGetWindowProperty (dpy, window, XA_SCREENSAVER_ID, 0, 512, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, (unsigned char **) &id); + if (id && *id) + { + const char *old_tag = " on host "; + const char *s = strstr (id, old_tag); + if (s) + { + /* found ID of the form "1234 on host xyz". */ + user = 0; + host = s + strlen (old_tag); + } + else + { + char *o = 0, *p = 0, *c = 0; + o = strchr (id, '('); + if (o) p = strchr (o, '@'); + if (p) c = strchr (p, ')'); + if (c) + { + /* found ID of the form "1234 (user@host)". */ + user = o+1; + host = p+1; + *p = 0; + *c = 0; + } + } + + } + + if (user && *user && *user != '?') + *user_ret = strdup (user); + else + *user_ret = 0; + + if (host && *host && *host != '?') + *host_ret = strdup (host); + else + *host_ret = 0; + + if (id) + XFree (id); + } +} diff --git a/driver/remote.h b/driver/remote.h new file mode 100644 index 00000000..d368e43c --- /dev/null +++ b/driver/remote.h @@ -0,0 +1,24 @@ +/* xscreensaver-command, Copyright (c) 1991-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. + */ + +#ifndef _XSCREENSAVER_REMOTE_H_ +#define _XSCREENSAVER_REMOTE_H_ + +extern int xscreensaver_command (Display *dpy, Atom command, long arg, + Bool verbose_p); + +extern void server_xscreensaver_version (Display *dpy, + char **version_ret, + char **user_ret, + char **host_ret); + +#endif /* _XSCREENSAVER_REMOTE_H_ */ diff --git a/driver/setuid.c b/driver/setuid.c new file mode 100644 index 00000000..83ad494e --- /dev/null +++ b/driver/setuid.c @@ -0,0 +1,309 @@ +/* setuid.c --- management of runtime privileges. + * xscreensaver, Copyright (c) 1993-1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include /* not used for much... */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" + +#ifndef EPERM +#include +#endif + +#include /* for getpwnam() and struct passwd */ +#include /* for getgrgid() and struct group */ + +static const char * +uid_gid_string (uid_t uid, gid_t gid) +{ + static char buf[255]; + struct passwd *p = 0; + struct group *g = 0; + p = getpwuid (uid); + g = getgrgid (gid); + sprintf (buf, "%s/%s (%ld/%ld)", + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???"), + (long) uid, (long) gid); + return buf; +} + + +void +describe_uids (saver_info *si, FILE *out) +{ + uid_t uid = getuid(); + gid_t gid = getgid(); + uid_t euid = geteuid(); + gid_t egid = getegid(); + char *s1 = strdup (uid_gid_string (uid, gid)); + char *s2 = strdup (uid_gid_string (euid, egid)); + + if (si->orig_uid && *si->orig_uid && + (!!strcmp (si->orig_uid, s1) || + !!strcmp (si->orig_uid, s2))) + fprintf (out, "%s: initial effective uid/gid was %s\n", blurb(), + si->orig_uid); + + fprintf (out, "%s: running as %s", blurb(), s1); + if (uid != euid || gid != egid) + fprintf (out, "; effectively %s", s2); + fprintf(out, "\n"); + free(s1); + free(s2); +} + + +static int +set_ids_by_name (struct passwd *p, struct group *g, char **message_ret) +{ + int uid_errno = 0; + int gid_errno = 0; + uid_t uid = p->pw_uid; + gid_t gid = g->gr_gid; + + if (message_ret) + *message_ret = 0; + + /* Rumor has it that some implementations of of setuid() do nothing + when called with -1; therefore, if the "nobody" user has a uid of + -1, then that would be Really Bad. Rumor further has it that such + systems really ought to be using -2 for "nobody", since that works. + So, if we get a uid (or gid, for good measure) of -1, switch to -2 + instead. + */ + if (gid == (gid_t) -1) gid = (gid_t) -2; + if (uid == (uid_t) -1) uid = (uid_t) -2; + + errno = 0; + if (setgid (gid) != 0) + gid_errno = errno ? errno : -1; + + errno = 0; + if (setuid (uid) != 0) + uid_errno = errno ? errno : -1; + + if (uid_errno == 0 && gid_errno == 0) + { + static char buf [1024]; + sprintf (buf, "changed uid/gid to %s/%s (%ld/%ld).", + p->pw_name, (g ? g->gr_name : "???"), + (long) uid, (long) gid); + if (message_ret) + *message_ret = buf; + return 0; + } + else + { + char buf [1024]; + if (gid_errno) + { + sprintf (buf, "%s: couldn't set gid to %s (%ld)", + blurb(), + (g ? g->gr_name : "???"), + (long) gid); + if (gid_errno == -1) + fprintf(stderr, "%s: unknown error\n", buf); + else + perror(buf); + } + + if (uid_errno) + { + sprintf (buf, "%s: couldn't set uid to %s (%ld)", + blurb(), + (p ? p->pw_name : "???"), + (long) uid); + if (uid_errno == -1) + fprintf(stderr, "%s: unknown error\n", buf); + else + perror(buf); + } + + return -1; + } +} + +static int +set_ids_by_number (uid_t uid, gid_t gid, char **message_ret) +{ + struct passwd *p; + struct group *g; + + errno = 0; + p = getpwuid (uid); + if (!p) + { + char buf [1024]; + sprintf (buf, "%s: error looking up name of user %d", blurb(), + (long) uid); + if (errno) + perror (buf); + else + fprintf (stderr, "%s: unknown error.\n", buf); + return -1; + } + + errno = 0; + g = getgrgid (gid); + if (!g) + { + char buf [1024]; + sprintf (buf, "%s: error looking up name of group %d", blurb(), + (long) gid); + if (errno) + perror (buf); + else + fprintf (stderr, "%s: unknown error.\n", buf); + return -1; + } + + return set_ids_by_name (p, g, message_ret); +} + + +/* If we've been run as setuid or setgid to someone else (most likely root) + turn off the extra permissions so that random user-specified programs + don't get special privileges. (On some systems it is necessary to install + this program as setuid root in order to read the passwd file to implement + lock-mode.) + + *** WARNING: DO NOT DISABLE ANY OF THE FOLLOWING CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ +void +hack_uid (saver_info *si) +{ + + /* Discard privileges, and set the effective user/group ids to the + real user/group ids. That is, give up our "chmod +s" rights. + */ + { + uid_t euid = geteuid(); + gid_t egid = getegid(); + uid_t uid = getuid(); + gid_t gid = getgid(); + + si->orig_uid = strdup (uid_gid_string (euid, egid)); + + if (uid != euid || gid != egid) + if (set_ids_by_number (uid, gid, &si->uid_message) != 0) + saver_exit (si, 1, 0); + } + + + /* Locking can't work when running as root, because we have no way of + knowing what the user id of the logged in user is (so we don't know + whose password to prompt for.) + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + if (getuid() == (uid_t) 0) + { + si->locking_disabled_p = True; + si->nolock_reason = "running as root"; + } + + + /* If we're running as root, switch to a safer user. This is above and + beyond the fact that we've disabling locking, above -- the theory is + that running graphics demos as root is just always a stupid thing + to do, since they have probably never been security reviewed and are + more likely to be buggy than just about any other kind of program. + (And that assumes non-malicious code. There are also attacks here.) + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + if (getuid() == (uid_t) 0) + { + struct passwd *p; + + p = getpwnam ("nobody"); + if (! p) p = getpwnam ("noaccess"); + if (! p) p = getpwnam ("daemon"); + if (! p) + { + fprintf (stderr, + "%s: running as root, and couldn't find a safer uid.\n", + blurb()); + saver_exit(si, 1, 0); + } + + if (set_ids_by_number (p->pw_uid, p->pw_gid, &si->uid_message) != 0) + saver_exit (si, -1, 0); + } + + + /* If there's anything even remotely funny looking about the passwd struct, + or if we're running as some other user from the list below (a + non-comprehensive selection of users known to be privileged in some way, + and not normal end-users) then disable locking. If it was possible, + switching to "nobody" would be the thing to do, but only root itself has + the privs to do that. + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + { + uid_t uid = getuid (); /* get it again */ + struct passwd *p = getpwuid (uid); /* get it again */ + + if (!p || + uid == (uid_t) 0 || + uid == (uid_t) -1 || + uid == (uid_t) -2 || + p->pw_uid == (uid_t) 0 || + p->pw_uid == (uid_t) -1 || + p->pw_uid == (uid_t) -2 || + !p->pw_name || + !*p->pw_name || + !strcmp (p->pw_name, "root") || + !strcmp (p->pw_name, "nobody") || + !strcmp (p->pw_name, "noaccess") || + !strcmp (p->pw_name, "operator") || + !strcmp (p->pw_name, "daemon") || + !strcmp (p->pw_name, "bin") || + !strcmp (p->pw_name, "adm") || + !strcmp (p->pw_name, "sys") || + !strcmp (p->pw_name, "games")) + { + static char buf [1024]; + sprintf (buf, "running as %s", + (p && p->pw_name && *p->pw_name + ? p->pw_name : "")); + si->nolock_reason = buf; + si->locking_disabled_p = True; + si->dangerous_uid_p = True; + } + } +} diff --git a/driver/splash.c b/driver/splash.c new file mode 100644 index 00000000..fabd8824 --- /dev/null +++ b/driver/splash.c @@ -0,0 +1,756 @@ +/* xscreensaver, Copyright (c) 1991-1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "xscreensaver.h" +#include "resources.h" + +#undef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) + +void +draw_shaded_rectangle (Display *dpy, Window window, + int x, int y, + int width, int height, + int thickness, + unsigned long top_color, + unsigned long bottom_color) +{ + XPoint points[4]; + XGCValues gcv; + GC gc1, gc2; + if (thickness == 0) return; + + gcv.foreground = top_color; + gc1 = XCreateGC (dpy, window, GCForeground, &gcv); + gcv.foreground = bottom_color; + gc2 = XCreateGC (dpy, window, GCForeground, &gcv); + + points [0].x = x; + points [0].y = y; + points [1].x = x + width; + points [1].y = y; + points [2].x = x + width - thickness; + points [2].y = y + thickness; + points [3].x = x; + points [3].y = y + thickness; + XFillPolygon (dpy, window, gc1, points, 4, Convex, CoordModeOrigin); + + points [0].x = x; + points [0].y = y + thickness; + points [1].x = x; + points [1].y = y + height; + points [2].x = x + thickness; + points [2].y = y + height - thickness; + points [3].x = x + thickness; + points [3].y = y + thickness; + XFillPolygon (dpy, window, gc1, points, 4, Convex, CoordModeOrigin); + + points [0].x = x + width; + points [0].y = y; + points [1].x = x + width - thickness; + points [1].y = y + thickness; + points [2].x = x + width - thickness; + points [2].y = y + height - thickness; + points [3].x = x + width; + points [3].y = y + height - thickness; + XFillPolygon (dpy, window, gc2, points, 4, Convex, CoordModeOrigin); + + points [0].x = x; + points [0].y = y + height; + points [1].x = x + width; + points [1].y = y + height; + points [2].x = x + width; + points [2].y = y + height - thickness; + points [3].x = x + thickness; + points [3].y = y + height - thickness; + XFillPolygon (dpy, window, gc2, points, 4, Convex, CoordModeOrigin); + + XFreeGC (dpy, gc1); + XFreeGC (dpy, gc2); +} + + +int +string_width (XFontStruct *font, char *s) +{ + int direction, ascent, descent; + XCharStruct overall; + XTextExtents (font, s, strlen(s), &direction, &ascent, &descent, &overall); + return overall.width; +} + + +static void update_splash_window (saver_info *si); +static void draw_splash_window (saver_info *si); +static void destroy_splash_window (saver_info *si); +static void unsplash_timer (XtPointer closure, XtIntervalId *id); + +static void do_demo (saver_info *si); +static void do_prefs (saver_info *si); +static void do_help (saver_info *si); + + +struct splash_dialog_data { + XtIntervalId timer; + + Dimension width; + Dimension height; + + char *heading_label; + char *body_label; + char *body2_label; + char *demo_label; + char *prefs_label; + char *help_label; + + XFontStruct *heading_font; + XFontStruct *body_font; + XFontStruct *button_font; + + Pixel foreground; + Pixel background; + Pixel button_foreground; + Pixel button_background; + Pixel logo_foreground; + Pixel logo_background; + Pixel shadow_top; + Pixel shadow_bottom; + + Dimension logo_width; + Dimension logo_height; + Dimension internal_border; + Dimension shadow_width; + + Dimension button_width, button_height; + Dimension demo_button_x, demo_button_y; + Dimension prefs_button_x, prefs_button_y; + Dimension help_button_x, help_button_y; + + int pressed; +}; + + +void +make_splash_dialog (saver_info *si) +{ + int x, y, bw; + XSetWindowAttributes attrs; + unsigned long attrmask = 0; + splash_dialog_data *sp; + Screen *screen = si->default_screen->screen; + Colormap cmap = DefaultColormapOfScreen (screen); + char *f; + + if (si->sp_data) + return; + if (si->prefs.splash_duration <= 0) + return; + + sp = (splash_dialog_data *) calloc (1, sizeof(*sp)); + + sp->heading_label = get_string_resource ("splash.heading.label", + "Dialog.Label.Label"); + sp->body_label = get_string_resource ("splash.body.label", + "Dialog.Label.Label"); + sp->body2_label = get_string_resource ("splash.body2.label", + "Dialog.Label.Label"); + sp->demo_label = get_string_resource ("splash.demo.label", + "Dialog.Button.Label"); + sp->prefs_label = get_string_resource ("splash.prefs.label", + "Dialog.Button.Label"); + sp->help_label = get_string_resource ("splash.help.label", + "Dialog.Button.Label"); + + if (!sp->heading_label) + sp->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!sp->body_label) + sp->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!sp->body2_label) + sp->body2_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!sp->demo_label) sp->demo_label = strdup("ERROR"); + if (!sp->prefs_label) sp->prefs_label = strdup("ERROR"); + if (!sp->help_label) sp->help_label = strdup("ERROR"); + + /* Put the version number in the label. */ + { + char *s = (char *) malloc (strlen(sp->heading_label) + 20); + sprintf(s, sp->heading_label, si->version); + free (sp->heading_label); + sp->heading_label = s; + } + + f = get_string_resource ("splash.headingFont", "Dialog.Font"); + sp->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!sp->heading_font) sp->heading_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + f = get_string_resource("splash.bodyFont", "Dialog.Font"); + sp->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!sp->body_font) sp->body_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + f = get_string_resource("splash.buttonFont", "Dialog.Font"); + sp->button_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!sp->button_font) sp->button_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + sp->foreground = get_pixel_resource ("splash.foreground", + "Dialog.Foreground", + si->dpy, cmap); + sp->background = get_pixel_resource ("splash.background", + "Dialog.Background", + si->dpy, cmap); + + if (sp->foreground == sp->background) + { + /* Make sure the error messages show up. */ + sp->foreground = BlackPixelOfScreen (screen); + sp->background = WhitePixelOfScreen (screen); + } + + sp->button_foreground = get_pixel_resource ("splash.Button.foreground", + "Dialog.Button.Foreground", + si->dpy, cmap); + sp->button_background = get_pixel_resource ("splash.Button.background", + "Dialog.Button.Background", + si->dpy, cmap); + sp->logo_foreground = get_pixel_resource ("splash.logo.foreground", + "Dialog.Logo.Foreground", + si->dpy, cmap); + sp->logo_background = get_pixel_resource ("splash.logo.background", + "Dialog.Logo.Background", + si->dpy, cmap); + sp->shadow_top = get_pixel_resource ("splash.topShadowColor", + "Dialog.Foreground", + si->dpy, cmap); + sp->shadow_bottom = get_pixel_resource ("splash.bottomShadowColor", + "Dialog.Background", + si->dpy, cmap); + + sp->logo_width = get_integer_resource ("splash.logo.width", + "Dialog.Logo.Width"); + sp->logo_height = get_integer_resource ("splash.logo.height", + "Dialog.Logo.Height"); + sp->internal_border = get_integer_resource ("splash.internalBorderWidth", + "Dialog.InternalBorderWidth"); + sp->shadow_width = get_integer_resource ("splash.shadowThickness", + "Dialog.ShadowThickness"); + + if (sp->logo_width == 0) sp->logo_width = 150; + if (sp->logo_height == 0) sp->logo_height = 150; + if (sp->internal_border == 0) sp->internal_border = 15; + if (sp->shadow_width == 0) sp->shadow_width = 4; + + { + int direction, ascent, descent; + XCharStruct overall; + + sp->width = 0; + sp->height = 0; + + /* Measure the heading_label. */ + XTextExtents (sp->heading_font, + sp->heading_label, strlen(sp->heading_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + sp->height += ascent + descent; + + /* Measure the body_label. */ + XTextExtents (sp->body_font, + sp->body_label, strlen(sp->body_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + sp->height += ascent + descent; + + /* Measure the body2_label. */ + XTextExtents (sp->body_font, + sp->body2_label, strlen(sp->body2_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + sp->height += ascent + descent; + + { + Dimension w2 = 0, w3 = 0, w4 = 0; + Dimension h2 = 0, h3 = 0, h4 = 0; + + /* Measure the Demo button. */ + XTextExtents (sp->button_font, + sp->demo_label, strlen(sp->demo_label), + &direction, &ascent, &descent, &overall); + w2 = overall.width; + h2 = ascent + descent; + + /* Measure the Prefs button. */ + XTextExtents (sp->button_font, + sp->prefs_label, strlen(sp->prefs_label), + &direction, &ascent, &descent, &overall); + w3 = overall.width; + h3 = ascent + descent; + + /* Measure the Help button. */ + XTextExtents (sp->button_font, + sp->help_label, strlen(sp->help_label), + &direction, &ascent, &descent, &overall); + w4 = overall.width; + h4 = ascent + descent; + + w2 = MAX(w2, w3); w2 = MAX(w2, w4); + h2 = MAX(h2, h3); h2 = MAX(h2, h4); + + w2 += ((ascent + descent) / 2) + (sp->shadow_width * 2); + h2 += ((ascent + descent) / 2) + (sp->shadow_width * 2); + + sp->button_width = w2; + sp->button_height = h2; + + w2 *= 3; + + w2 += ((ascent + descent) * 2); /* for space between buttons */ + + if (w2 > sp->width) sp->width = w2; + sp->height += h2; + } + + sp->width += (sp->internal_border * 2); + sp->height += (sp->internal_border * 3); + + if (sp->logo_height > sp->height) + sp->height = sp->logo_height; + else if (sp->height > sp->logo_height) + sp->logo_height = sp->height; + + sp->logo_width = sp->logo_height; + + sp->width += sp->logo_width; + } + + attrmask |= CWOverrideRedirect; attrs.override_redirect = True; + attrmask |= CWEventMask; + attrs.event_mask = (ExposureMask | ButtonPressMask | ButtonReleaseMask); + + { + int sx, sy, w, h; + get_screen_viewport (si->default_screen, &sx, &sy, &w, &h, False); + if (si->prefs.debug_p) w /= 2; + x = sx + (((w + sp->width) / 2) - sp->width); + y = sy + (((h + sp->height) / 2) - sp->height); + if (x < sx) x = sx; + if (y < sy) y = sy; + } + + bw = get_integer_resource ("splash.borderWidth", "Dialog.BorderWidth"); + + si->splash_dialog = + XCreateWindow (si->dpy, + RootWindowOfScreen(screen), + x, y, sp->width, sp->height, bw, + DefaultDepthOfScreen (screen), InputOutput, + DefaultVisualOfScreen(screen), + attrmask, &attrs); + XSetWindowBackground (si->dpy, si->splash_dialog, sp->background); + + XMapRaised (si->dpy, si->splash_dialog); + XSync (si->dpy, False); + + si->sp_data = sp; + + sp->timer = XtAppAddTimeOut (si->app, si->prefs.splash_duration, + unsplash_timer, (XtPointer) si); + + draw_splash_window (si); + XSync (si->dpy, False); +} + +static void +draw_splash_window (saver_info *si) +{ + splash_dialog_data *sp = si->sp_data; + XGCValues gcv; + GC gc1, gc2; + int hspacing, vspacing, height; + int x1, x2, x3, y1, y2; + int sw; + + height = (sp->heading_font->ascent + sp->heading_font->descent + + sp->body_font->ascent + sp->body_font->descent + + sp->body_font->ascent + sp->body_font->descent + + sp->button_font->ascent + sp->button_font->descent); + vspacing = ((sp->height + - (4 * sp->shadow_width) + - (2 * sp->internal_border) + - height) / 5); + if (vspacing < 0) vspacing = 0; + if (vspacing > (sp->heading_font->ascent * 2)) + vspacing = (sp->heading_font->ascent * 2); + + gcv.foreground = sp->foreground; + gc1 = XCreateGC (si->dpy, si->splash_dialog, GCForeground, &gcv); + gc2 = XCreateGC (si->dpy, si->splash_dialog, GCForeground, &gcv); + x1 = sp->logo_width; + x3 = sp->width - (sp->shadow_width * 2); + y1 = sp->internal_border; + + /* top heading + */ + XSetFont (si->dpy, gc1, sp->heading_font->fid); + sw = string_width (sp->heading_font, sp->heading_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + y1 += sp->heading_font->ascent; + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->heading_label, strlen(sp->heading_label)); + y1 += sp->heading_font->descent; + + /* text below top heading + */ + XSetFont (si->dpy, gc1, sp->body_font->fid); + y1 += vspacing + sp->body_font->ascent; + sw = string_width (sp->body_font, sp->body_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->body_label, strlen(sp->body_label)); + y1 += sp->body_font->descent; + + y1 += sp->body_font->ascent; + sw = string_width (sp->body_font, sp->body2_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->body2_label, strlen(sp->body2_label)); + y1 += sp->body_font->descent; + + /* The buttons + */ + XSetForeground (si->dpy, gc1, sp->button_foreground); + XSetForeground (si->dpy, gc2, sp->button_background); + +/* y1 += (vspacing * 2);*/ + y1 = sp->height - sp->internal_border - sp->button_height; + + x1 += sp->internal_border; + y2 = (y1 + ((sp->button_height - + (sp->button_font->ascent + sp->button_font->descent)) + / 2) + + sp->button_font->ascent); + hspacing = ((sp->width - x1 - (sp->shadow_width * 2) - + sp->internal_border - (sp->button_width * 3)) + / 2); + + x2 = x1 + ((sp->button_width - string_width(sp->button_font, sp->demo_label)) + / 2); + XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, + sp->button_width, sp->button_height); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y2, + sp->demo_label, strlen(sp->demo_label)); + sp->demo_button_x = x1; + sp->demo_button_y = y1; + + x1 += hspacing + sp->button_width; + x2 = x1 + ((sp->button_width - string_width(sp->button_font,sp->prefs_label)) + / 2); + XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, + sp->button_width, sp->button_height); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y2, + sp->prefs_label, strlen(sp->prefs_label)); + sp->prefs_button_x = x1; + sp->prefs_button_y = y1; + + x1 += hspacing + sp->button_width; + x2 = x1 + ((sp->button_width - string_width(sp->button_font,sp->help_label)) + / 2); + XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, + sp->button_width, sp->button_height); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y2, + sp->help_label, strlen(sp->help_label)); + sp->help_button_x = x1; + sp->help_button_y = y1; + + + /* the logo + */ + XSetForeground (si->dpy, gc1, sp->logo_foreground); + XSetForeground (si->dpy, gc2, sp->logo_background); + + x1 = sp->shadow_width * 3; + y1 = sp->shadow_width * 3; + x2 = sp->logo_width - (sp->shadow_width * 6); + y2 = sp->logo_height - (sp->shadow_width * 6); + + XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, x2, y2); + skull (si->dpy, si->splash_dialog, gc1, gc2, + x1 + sp->shadow_width, y1 + sp->shadow_width, + x2 - (sp->shadow_width * 2), y2 - (sp->shadow_width * 2)); + + + /* The shadow around the logo + */ + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->shadow_width * 2, + sp->shadow_width * 2, + sp->logo_width - (sp->shadow_width * 4), + sp->logo_height - (sp->shadow_width * 4), + sp->shadow_width, + sp->shadow_bottom, sp->shadow_top); + + /* The shadow around the whole window + */ + draw_shaded_rectangle (si->dpy, si->splash_dialog, + 0, 0, sp->width, sp->height, sp->shadow_width, + sp->shadow_top, sp->shadow_bottom); + + XFreeGC (si->dpy, gc1); + XFreeGC (si->dpy, gc2); + + update_splash_window (si); +} + + +static void +update_splash_window (saver_info *si) +{ + splash_dialog_data *sp = si->sp_data; + int pressed; + if (!sp) return; + pressed = sp->pressed; + + /* The shadows around the buttons + */ + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->demo_button_x, sp->demo_button_y, + sp->button_width, sp->button_height, sp->shadow_width, + (pressed == 1 ? sp->shadow_bottom : sp->shadow_top), + (pressed == 1 ? sp->shadow_top : sp->shadow_bottom)); + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->prefs_button_x, sp->prefs_button_y, + sp->button_width, sp->button_height, sp->shadow_width, + (pressed == 2 ? sp->shadow_bottom : sp->shadow_top), + (pressed == 2 ? sp->shadow_top : sp->shadow_bottom)); + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->help_button_x, sp->help_button_y, + sp->button_width, sp->button_height, sp->shadow_width, + (pressed == 3 ? sp->shadow_bottom : sp->shadow_top), + (pressed == 3 ? sp->shadow_top : sp->shadow_bottom)); +} + +static void +destroy_splash_window (saver_info *si) +{ + splash_dialog_data *sp = si->sp_data; + Screen *screen = si->default_screen->screen; + Colormap cmap = DefaultColormapOfScreen (screen); + Pixel black = BlackPixelOfScreen (screen); + Pixel white = WhitePixelOfScreen (screen); + + if (sp->timer) + XtRemoveTimeOut (sp->timer); + + if (si->splash_dialog) + { + XDestroyWindow (si->dpy, si->splash_dialog); + si->splash_dialog = 0; + } + + if (sp->heading_label) free (sp->heading_label); + if (sp->body_label) free (sp->body_label); + if (sp->demo_label) free (sp->demo_label); + if (sp->prefs_label) free (sp->prefs_label); + if (sp->help_label) free (sp->help_label); + + if (sp->heading_font) XFreeFont (si->dpy, sp->heading_font); + if (sp->body_font) XFreeFont (si->dpy, sp->body_font); + if (sp->button_font) XFreeFont (si->dpy, sp->button_font); + + if (sp->foreground != black && sp->foreground != white) + XFreeColors (si->dpy, cmap, &sp->foreground, 1, 0L); + if (sp->background != black && sp->background != white) + XFreeColors (si->dpy, cmap, &sp->background, 1, 0L); + if (sp->button_foreground != black && sp->button_foreground != white) + XFreeColors (si->dpy, cmap, &sp->button_foreground, 1, 0L); + if (sp->button_background != black && sp->button_background != white) + XFreeColors (si->dpy, cmap, &sp->button_background, 1, 0L); + if (sp->logo_foreground != black && sp->logo_foreground != white) + XFreeColors (si->dpy, cmap, &sp->logo_foreground, 1, 0L); + if (sp->logo_background != black && sp->logo_background != white) + XFreeColors (si->dpy, cmap, &sp->logo_background, 1, 0L); + if (sp->shadow_top != black && sp->shadow_top != white) + XFreeColors (si->dpy, cmap, &sp->shadow_top, 1, 0L); + if (sp->shadow_bottom != black && sp->shadow_bottom != white) + XFreeColors (si->dpy, cmap, &sp->shadow_bottom, 1, 0L); + + memset (sp, 0, sizeof(*sp)); + free (sp); + + si->sp_data = 0; +} + +void +handle_splash_event (saver_info *si, XEvent *event) +{ + splash_dialog_data *sp = si->sp_data; + int which = 0; + if (!sp) return; + + switch (event->xany.type) + { + case Expose: + draw_splash_window (si); + break; + + case ButtonPress: case ButtonRelease: + + if (event->xbutton.x >= sp->demo_button_x && + event->xbutton.x < sp->demo_button_x + sp->button_width && + event->xbutton.y >= sp->demo_button_y && + event->xbutton.y < sp->demo_button_y + sp->button_height) + which = 1; + + else if (event->xbutton.x >= sp->prefs_button_x && + event->xbutton.x < sp->prefs_button_x + sp->button_width && + event->xbutton.y >= sp->prefs_button_y && + event->xbutton.y < sp->prefs_button_y + sp->button_height) + which = 2; + + else if (event->xbutton.x >= sp->help_button_x && + event->xbutton.x < sp->help_button_x + sp->button_width && + event->xbutton.y >= sp->help_button_y && + event->xbutton.y < sp->help_button_y + sp->button_height) + which = 3; + + if (event->xany.type == ButtonPress) + { + sp->pressed = which; + update_splash_window (si); + if (which == 0) + XBell (si->dpy, False); + } + else if (event->xany.type == ButtonRelease) + { + if (which && sp->pressed == which) + { + destroy_splash_window (si); + switch (which) + { + case 1: do_demo (si); break; + case 2: do_prefs (si); break; + case 3: do_help (si); break; + default: abort(); + } + } + sp->pressed = 0; + update_splash_window (si); + } + break; + + default: + break; + } +} + +static void +unsplash_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + if (si && si->sp_data) + destroy_splash_window (si); +} + + +/* Button callbacks */ + +#ifdef VMS +# define pid_t int +# define fork vfork +#endif /* VMS */ + +static void +fork_and_exec (saver_info *si, const char *command, const char *desc) +{ + saver_preferences *p = &si->prefs; + pid_t forked; + char buf [512]; + char *av[5]; + int ac; + + if (!command || !*command) + { + fprintf (stderr, "%s: no %s command has been specified.\n", + blurb(), desc); + return; + } + + switch ((int) (forked = fork ())) + { + case -1: + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + break; + + case 0: + close (ConnectionNumber (si->dpy)); /* close display fd */ + hack_subproc_environment (si->default_screen); /* set $DISPLAY */ + ac = 0; + av [ac++] = (char *) p->shell; + av [ac++] = (char *) "-c"; + av [ac++] = (char *) command; + av [ac] = 0; + execvp (av[0], av); /* shouldn't return. */ + + sprintf (buf, "%s: execvp(\"%s\", \"%s\", \"%s\") failed", + blurb(), av[0], av[1], av[2]); + perror (buf); + fflush (stderr); + fflush (stdout); + exit (1); /* Note that this only exits a child fork. */ + break; + + default: + /* parent fork. */ + break; + } +} + + +static void +do_demo (saver_info *si) +{ + saver_preferences *p = &si->prefs; + fork_and_exec (si, p->demo_command, "demo-mode"); +} + +static void +do_prefs (saver_info *si) +{ + saver_preferences *p = &si->prefs; + fork_and_exec (si, p->prefs_command, "preferences"); +} + +static void +do_help (saver_info *si) +{ + saver_preferences *p = &si->prefs; + char *help_command; + + if (!p->help_url || !*p->help_url) + { + fprintf (stderr, "%s: no Help URL has been specified.\n", blurb()); + return; + } + + help_command = (char *) malloc (strlen (p->load_url_command) + + (strlen (p->help_url) * 2) + 10); + sprintf (help_command, p->load_url_command, p->help_url, p->help_url); + fork_and_exec (si, help_command, "URL-loading"); + free (help_command); +} diff --git a/driver/stderr.c b/driver/stderr.c new file mode 100644 index 00000000..fafb1e58 --- /dev/null +++ b/driver/stderr.c @@ -0,0 +1,444 @@ +/* stderr.c --- capturing stdout/stderr output onto the screensaver window. + * xscreensaver, Copyright (c) 1991-1998 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. + */ + +/* stderr hackery - Why Unix Sucks, reason number 32767. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_FCNTL +# include +#endif + +#include + +#include "xscreensaver.h" +#include "resources.h" +#include "visual.h" + +FILE *real_stderr = 0; +FILE *real_stdout = 0; + + +/* It's ok for these to be global, since they refer to the one and only + stderr stream, not to a particular screen or window or visual. + */ +static char stderr_buffer [4096]; +static char *stderr_tail = 0; +static time_t stderr_last_read = 0; + +static void make_stderr_overlay_window (saver_screen_info *); + + +void +reset_stderr (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + + if (si->prefs.debug_p) + fprintf ((real_stderr ? real_stderr : stderr), + "%s: resetting stderr\n", blurb()); + + ssi->stderr_text_x = 0; + ssi->stderr_text_y = 0; + + if (ssi->stderr_gc) + XFreeGC (si->dpy, ssi->stderr_gc); + ssi->stderr_gc = 0; + + if (ssi->stderr_overlay_window) + XDestroyWindow(si->dpy, ssi->stderr_overlay_window); + ssi->stderr_overlay_window = 0; + + if (ssi->stderr_cmap) + XFreeColormap(si->dpy, ssi->stderr_cmap); + ssi->stderr_cmap = 0; +} + +void +clear_stderr (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + ssi->stderr_text_x = 0; + ssi->stderr_text_y = 0; + if (ssi->stderr_overlay_window) + XClearWindow (si->dpy, ssi->stderr_overlay_window); +} + + +static void +print_stderr_1 (saver_screen_info *ssi, char *string) +{ + saver_info *si = ssi->global; + Display *dpy = si->dpy; + Screen *screen = ssi->screen; + Window window = (ssi->stderr_overlay_window ? + ssi->stderr_overlay_window : + ssi->screensaver_window); + int h_border = 20; + int v_border = 20; + char *head = string; + char *tail; + + if (! ssi->stderr_font) + { + char *font_name = get_string_resource ("font", "Font"); + if (!font_name) font_name = "fixed"; + ssi->stderr_font = XLoadQueryFont (dpy, font_name); + if (! ssi->stderr_font) ssi->stderr_font = XLoadQueryFont (dpy, "fixed"); + ssi->stderr_line_height = (ssi->stderr_font->ascent + + ssi->stderr_font->descent); + } + + if (! ssi->stderr_gc) + { + XGCValues gcv; + Pixel fg, bg; + Colormap cmap = ssi->cmap; + + if (!ssi->stderr_overlay_window && + get_boolean_resource("overlayStderr", "Boolean")) + { + make_stderr_overlay_window (ssi); + if (ssi->stderr_overlay_window) + window = ssi->stderr_overlay_window; + if (ssi->stderr_cmap) + cmap = ssi->stderr_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; + ssi->stderr_gc = XCreateGC (dpy, window, + (GCFont | GCForeground | GCBackground), + &gcv); + } + + + if (ssi->stderr_cmap) + XInstallColormap(si->dpy, ssi->stderr_cmap); + + for (tail = string; *tail; tail++) + { + if (*tail == '\n' || *tail == '\r') + { + int maxy = HeightOfScreen (screen) - v_border - v_border; + if (tail != head) + XDrawImageString (dpy, window, ssi->stderr_gc, + ssi->stderr_text_x + h_border, + ssi->stderr_text_y + v_border + + ssi->stderr_font->ascent, + head, tail - head); + ssi->stderr_text_x = 0; + ssi->stderr_text_y += ssi->stderr_line_height; + head = tail + 1; + if (*tail == '\r' && *head == '\n') + head++, tail++; + + if (ssi->stderr_text_y > maxy - ssi->stderr_line_height) + { +#if 0 + ssi->stderr_text_y = 0; +#else + int offset = ssi->stderr_line_height * 5; + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + + XCopyArea (dpy, window, window, ssi->stderr_gc, + 0, v_border + offset, + xgwa.width, + (xgwa.height - v_border - v_border - offset), + 0, v_border); + XClearArea (dpy, window, + 0, xgwa.height - v_border - offset, + xgwa.width, offset, False); + ssi->stderr_text_y -= offset; +#endif + } + } + } + if (tail != head) + { + int direction, ascent, descent; + XCharStruct overall; + XDrawImageString (dpy, window, ssi->stderr_gc, + ssi->stderr_text_x + h_border, + ssi->stderr_text_y + v_border + + ssi->stderr_font->ascent, + head, tail - head); + XTextExtents (ssi->stderr_font, tail, tail - head, + &direction, &ascent, &descent, &overall); + ssi->stderr_text_x += overall.width; + } +} + +static void +make_stderr_overlay_window (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + unsigned long transparent_pixel = 0; + Visual *visual = get_overlay_visual (ssi->screen, &transparent_pixel); + if (visual) + { + int depth = visual_depth (ssi->screen, visual); + XSetWindowAttributes attrs; + XWindowAttributes xgwa; + unsigned long attrmask; + XGetWindowAttributes (si->dpy, ssi->screensaver_window, &xgwa); + + if (si->prefs.debug_p) + fprintf(real_stderr, + "%s: using overlay visual 0x%0x for stderr text layer.\n", + blurb(), (int) XVisualIDFromVisual (visual)); + + ssi->stderr_cmap = XCreateColormap(si->dpy, + RootWindowOfScreen(ssi->screen), + visual, AllocNone); + + attrmask = (CWColormap | CWBackPixel | CWBackingPixel | CWBorderPixel | + CWBackingStore | CWSaveUnder); + attrs.colormap = ssi->stderr_cmap; + attrs.background_pixel = transparent_pixel; + attrs.backing_pixel = transparent_pixel; + attrs.border_pixel = transparent_pixel; + attrs.backing_store = NotUseful; + attrs.save_under = False; + + ssi->stderr_overlay_window = + XCreateWindow(si->dpy, ssi->screensaver_window, 0, 0, + xgwa.width, xgwa.height, + 0, depth, InputOutput, visual, attrmask, &attrs); + XMapRaised(si->dpy, ssi->stderr_overlay_window); + } +} + + +static void +print_stderr (saver_info *si, char *string) +{ + saver_preferences *p = &si->prefs; + int i; + + /* In verbose mode, copy it to stderr as well. */ + if (p->verbose_p) + fprintf (real_stderr, "%s", string); + + for (i = 0; i < si->nscreens; i++) + print_stderr_1 (&si->screens[i], string); +} + + +static void +stderr_popup_timer_fn (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + char *s = stderr_buffer; + if (*s) + { + /* If too much data was printed, then something has gone haywire, + so truncate it. */ + char *trailer = "\n\n<< stderr diagnostics have been truncated >>\n\n"; + int max = sizeof (stderr_buffer) - strlen (trailer) - 5; + if (strlen (s) > max) + strcpy (s + max, trailer); + /* Now show the user. */ + print_stderr (si, s); + } + + stderr_tail = stderr_buffer; + si->stderr_popup_timer = 0; +} + + +static void +stderr_callback (XtPointer closure, int *fd, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + char *s; + int left; + int size; + int read_this_time = 0; + + if (stderr_tail == 0) + stderr_tail = stderr_buffer; + + left = ((sizeof (stderr_buffer) - 2) - (stderr_tail - stderr_buffer)); + + s = stderr_tail; + *s = 0; + + /* Read as much data from the fd as we can, up to our buffer size. */ + if (left > 0) + { + while ((size = read (*fd, (void *) s, left)) > 0) + { + left -= size; + s += size; + read_this_time += size; + } + *s = 0; + } + else + { + char buf2 [1024]; + /* The buffer is full; flush the rest of it. */ + while (read (*fd, (void *) buf2, sizeof (buf2)) > 0) + ; + } + + stderr_tail = s; + stderr_last_read = time ((time_t *) 0); + + /* Now we have read some data that we would like to put up in a dialog + box. But more data may still be coming in - so don't pop up the + dialog right now, but instead, start a timer that will pop it up + a second from now. Should more data come in in the meantime, we + will be called again, and will reset that timer again. So the + dialog will only pop up when a second has elapsed with no new data + being written to stderr. + + However, if the buffer is full (meaning lots of data has been written) + then we don't reset the timer. + */ + if (read_this_time > 0) + { + if (si->stderr_popup_timer) + XtRemoveTimeOut (si->stderr_popup_timer); + + si->stderr_popup_timer = + XtAppAddTimeOut (si->app, 1 * 1000, stderr_popup_timer_fn, + (XtPointer) si); + } +} + +void +initialize_stderr (saver_info *si) +{ + static Boolean done = False; + int fds [2]; + int in, out; + int new_stdout, new_stderr; + int stdout_fd = 1; + int stderr_fd = 2; + int flags = 0; + Boolean stderr_dialog_p; + + if (done) return; + done = True; + + real_stderr = stderr; + real_stdout = stdout; + + stderr_dialog_p = get_boolean_resource ("captureStderr", "Boolean"); + + if (!stderr_dialog_p) + return; + + if (pipe (fds)) + { + perror ("error creating pipe:"); + return; + } + + in = fds [0]; + out = fds [1]; + +# ifdef HAVE_FCNTL + +# if defined(O_NONBLOCK) + flags = O_NONBLOCK; +# elif defined(O_NDELAY) + flags = O_NDELAY; +# else + ERROR!! neither O_NONBLOCK nor O_NDELAY are defined. +# endif + + /* Set both sides of the pipe to nonblocking - this is so that + our reads (in stderr_callback) will terminate, and so that + out writes (in the client programs) will silently fail when + the pipe is full, instead of hosing the program. */ + if (fcntl (in, F_SETFL, flags) != 0) + { + perror ("fcntl:"); + return; + } + if (fcntl (out, F_SETFL, flags) != 0) + { + perror ("fcntl:"); + return; + } + +# endif /* !HAVE_FCNTL */ + + if (stderr_dialog_p) + { + FILE *new_stderr_file; + FILE *new_stdout_file; + + new_stderr = dup (stderr_fd); + if (new_stderr < 0) + { + perror ("could not dup() a stderr:"); + return; + } + if (! (new_stderr_file = fdopen (new_stderr, "w"))) + { + perror ("could not fdopen() the new stderr:"); + return; + } + real_stderr = new_stderr_file; + + close (stderr_fd); + if (dup2 (out, stderr_fd) < 0) + { + perror ("could not dup() a new stderr:"); + return; + } + + + new_stdout = dup (stdout_fd); + if (new_stdout < 0) + { + perror ("could not dup() a stdout:"); + return; + } + if (! (new_stdout_file = fdopen (new_stdout, "w"))) + { + perror ("could not fdopen() the new stdout:"); + return; + } + real_stdout = new_stdout_file; + + close (stdout_fd); + if (dup2 (out, stdout_fd) < 0) + { + perror ("could not dup() a new stdout:"); + return; + } + } + + XtAppAddInput (si->app, in, (XtPointer) XtInputReadMask, stderr_callback, + (XtPointer) si); +} diff --git a/driver/subprocs.c b/driver/subprocs.c new file mode 100644 index 00000000..fcfdf897 --- /dev/null +++ b/driver/subprocs.c @@ -0,0 +1,1141 @@ +/* subprocs.c --- choosing, spawning, and killing screenhacks. + * xscreensaver, Copyright (c) 1991, 1992, 1993, 1995, 1997, 1998 + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include /* not used for much... */ + +#ifndef ESRCH +# include +#endif + +#include /* sys/resource.h needs this for timeval */ + +#ifdef HAVE_SYS_WAIT_H +# include /* for waitpid() and associated macros */ +#endif + +#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) +# include /* for setpriority() and PRIO_PROCESS */ +#endif + +#ifdef VMS +# include +# include /* for close */ +# include /* for getpid */ +# define pid_t int +# define fork vfork +#endif /* VMS */ + +#include /* for the signal names */ + +#if !defined(SIGCHLD) && defined(SIGCLD) +# define SIGCHLD SIGCLD +#endif + +#if 0 /* putenv() is declared in stdlib.h on modern linux systems. */ +#ifdef HAVE_PUTENV +extern int putenv (/* const char * */); /* getenv() is in stdlib.h... */ +#endif +#endif + +extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" +#include "yarandom.h" + + +extern saver_info *global_si_kludge; /* I hate C so much... */ + +static void +nice_subproc (int nice_level) +{ + if (nice_level == 0) + return; + +#if defined(HAVE_NICE) + { + int old_nice = nice (0); + int n = nice_level - old_nice; + errno = 0; + if (nice (n) == -1 && errno != 0) + { + char buf [512]; + sprintf (buf, "%s: nice(%d) failed", blurb(), n); + perror (buf); + } + } +#elif defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) + if (setpriority (PRIO_PROCESS, getpid(), nice_level) != 0) + { + char buf [512]; + sprintf (buf, "%s: setpriority(PRIO_PROCESS, %lu, %d) failed", + blurb(), (unsigned long) getpid(), nice_level); + perror (buf); + } +#else + fprintf (stderr, + "%s: don't know how to change process priority on this system.\n", + blurb()); + +#endif +} + + +#ifndef VMS + +static void +exec_simple_command (const char *command) +{ + char *av[1024]; + int ac = 0; + char *token = strtok (strdup(command), " \t"); + while (token) + { + av[ac++] = token; + token = strtok(0, " \t"); + } + av[ac] = 0; + + execvp (av[0], av); /* shouldn't return. */ + + { + char buf [512]; + sprintf (buf, "%s: could not execute \"%s\"", blurb(), av[0]); + perror (buf); + + if (errno == ENOENT && + (token = getenv("PATH"))) + { +# ifndef PATH_MAX +# ifdef MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# else +# define PATH_MAX 2048 +# endif +# endif + char path[PATH_MAX]; + fprintf (stderr, "\n"); + *path = 0; +# if defined(HAVE_GETCWD) + getcwd (path, sizeof(path)); +# elif defined(HAVE_GETWD) + getwd (path); +# endif + if (*path) + fprintf (stderr, " Current directory is: %s\n", path); + fprintf (stderr, " PATH is:\n"); + token = strtok (strdup(token), ":"); + while (token) + { + fprintf (stderr, " %s\n", token); + token = strtok(0, ":"); + } + fprintf (stderr, "\n"); + } + } + fflush(stderr); + fflush(stdout); + exit (1); /* Note that this only exits a child fork. */ +} + + +static void +exec_complex_command (const char *shell, const char *command) +{ + char *av[5]; + int ac = 0; + char *command2 = (char *) malloc (strlen (command) + 10); + const char *s; + int got_eq = 0; + const char *after_vars; + + /* Skip leading whitespace. + */ + while (*command == ' ' || *command == '\t') + command++; + + /* If the string has a series of tokens with "=" in them at them, set + `after_vars' to point into the string after those tokens and any + trailing whitespace. Otherwise, after_vars == command. + */ + after_vars = command; + for (s = command; *s; s++) + { + if (*s == '=') got_eq = 1; + else if (*s == ' ') + { + if (got_eq) + { + while (*s == ' ' || *s == '\t') + s++; + after_vars = s; + got_eq = 0; + } + else + break; + } + } + + *command2 = 0; + strncat (command2, command, after_vars - command); + strcat (command2, "exec "); + strcat (command2, after_vars); + + /* We have now done these transformations: + "foo -x -y" ==> "exec foo -x -y" + "BLAT=foop foo -x" ==> "BLAT=foop exec foo -x" + "BLAT=foop A=b foo -x" ==> "BLAT=foop A=b exec foo -x" + */ + + + /* Invoke the shell as "/bin/sh -c 'exec prog -arg -arg ...'" */ + av [ac++] = (char *) shell; + av [ac++] = "-c"; + av [ac++] = command2; + av [ac] = 0; + + execvp (av[0], av); /* shouldn't return. */ + + { + char buf [512]; + sprintf (buf, "%s: execvp(\"%s\") failed", blurb(), av[0]); + perror (buf); + fflush(stderr); + fflush(stdout); + exit (1); /* Note that this only exits a child fork. */ + } +} + +#else /* VMS */ + +static void +exec_vms_command (const char *command) +{ + system (command); + fflush (stderr); + fflush (stdout); + exit (1); /* Note that this only exits a child fork. */ +} + +#endif /* !VMS */ + + +static void +exec_screenhack (saver_info *si, const char *command) +{ + /* I don't believe what a sorry excuse for an operating system UNIX is! + + - I want to spawn a process. + - I want to know it's pid so that I can kill it. + - I would like to receive a message when it dies of natural causes. + - I want the spawned process to have user-specified arguments. + + If shell metacharacters are present (wildcards, backquotes, etc), the + only way to parse those arguments is to run a shell to do the parsing + for you. + + And the only way to know the pid of the process is to fork() and exec() + it in the spawned side of the fork. + + But if you're running a shell to parse your arguments, this gives you + the pid of the *shell*, not the pid of the *process* that you're + actually interested in, which is an *inferior* of the shell. This also + means that the SIGCHLD you get applies to the shell, not its inferior. + (Why isn't that sufficient? I don't remember any more, but it turns + out that it isn't.) + + So, the only solution, when metacharacters are present, is to force the + shell to exec() its inferior. What a fucking hack! We prepend "exec " + to the command string, and hope it doesn't contain unquoted semicolons + or ampersands (we don't search for them, because we don't want to + prohibit their use in quoted strings (messages, for example) and parsing + out the various quote characters is too much of a pain.) + + (Actually, Clint Wong points out that process groups + might be used to take care of this problem; this may be worth considering + some day, except that, 1: this code works now, so why fix it, and 2: from + what I've seen in Emacs, dealing with process groups isn't especially + portable.) + */ + saver_preferences *p = &si->prefs; + +#ifndef VMS + Bool hairy_p = !!strpbrk (command, "*?$&!<>[];`'\\\"="); + /* note: = is in the above because of the sh syntax "FOO=bar cmd". */ + + if (getuid() == (uid_t) 0 || geteuid() == (uid_t) 0) + { + /* If you're thinking of commenting this out, think again. + If you do so, you will open a security hole. Mail jwz + so that he may enlighten you as to the error of your ways. + */ + fprintf (stderr, "%s: we're still running as root! Disaster!\n", + blurb()); + saver_exit (si, 1, 0); + } + + if (p->verbose_p) + fprintf (stderr, "%s: spawning \"%s\" in pid %lu%s.\n", + blurb(), command, (unsigned long) getpid (), + (hairy_p ? " (via shell)" : "")); + + if (hairy_p) + /* If it contains any shell metacharacters, do it the hard way, + and fork a shell to parse the arguments for us. */ + exec_complex_command (p->shell, command); + else + /* Otherwise, we can just exec the program directly. */ + exec_simple_command (command); + +#else /* VMS */ + if (p->verbose_p) + fprintf (stderr, "%s: spawning \"%s\" in pid %lu.\n", + blurb(), command, getpid()); + exec_vms_command (command); +#endif /* VMS */ + + abort(); /* that shouldn't have returned. */ +} + + + +/* Management of child processes, and de-zombification. + */ + +enum job_status { + job_running, /* the process is still alive */ + job_stopped, /* we have sent it a STOP signal */ + job_killed, /* we have sent it a TERM signal */ + job_dead /* we have wait()ed for it, and it's dead -- this state only + occurs so that we can avoid calling free() from a signal + handler. Shortly after going into this state, the list + element will be removed. */ +}; + +struct screenhack_job { + char *name; + pid_t pid; + enum job_status status; + struct screenhack_job *next; +}; + +static struct screenhack_job *jobs = 0; + +/* for debugging -- nothing calls this, but it's useful to invoke from gdb. */ +void +show_job_list (void) +{ + struct screenhack_job *job; + fprintf(stderr, "%s: job list:\n", blurb()); + for (job = jobs; job; job = job->next) + fprintf (stderr, " %5ld: (%s) %s\n", + (long) job->pid, + (job->status == job_running ? "running" : + job->status == job_stopped ? "stopped" : + job->status == job_killed ? " killed" : + job->status == job_dead ? " dead" : " ???"), + job->name); + fprintf (stderr, "\n"); +} + + +static void clean_job_list (void); + +static struct screenhack_job * +make_job (pid_t pid, const char *cmd) +{ + struct screenhack_job *job = (struct screenhack_job *) malloc (sizeof(*job)); + + static char name [1024]; + const char *in = cmd; + char *out = name; + int got_eq = 0; + int first = 1; + + clean_job_list(); + + AGAIN: + while (isspace(*in)) in++; /* skip whitespace */ + while (!isspace(*in) && *in != ':') { + if (*in == '=') got_eq = 1; + *out++ = *in++; /* snarf first token */ + } + + if (got_eq) /* if the first token was FOO=bar */ + { /* then get the next token instead. */ + got_eq = 0; + out = name; + first = 0; + goto AGAIN; + } + + while (isspace(*in)) in++; /* skip whitespace */ + if (first && *in == ':') /* token was a visual name; skip it. */ + { + out = name; + first = 0; + goto AGAIN; + } + *out = 0; + + job->name = strdup(name); + job->pid = pid; + job->status = job_running; + job->next = jobs; + jobs = job; + + return jobs; +} + + +static void +free_job (struct screenhack_job *job) +{ + if (!job) + return; + else if (job == jobs) + jobs = jobs->next; + else + { + struct screenhack_job *job2, *prev; + for (prev = 0, job2 = jobs; + job2; + prev = job2, job2 = job2->next) + if (job2 == job) + { + prev->next = job->next; + break; + } + } + free(job->name); + free(job); +} + + +/* Cleans out dead jobs from the jobs list -- this must only be called + from the main thread, not from a signal handler. + */ +static void +clean_job_list (void) +{ + struct screenhack_job *job, *prev, *next; + for (prev = 0, job = jobs, next = (job ? job->next : 0); + job; + prev = job, job = next, next = (job ? job->next : 0)) + { + if (job->status == job_dead) + { + if (prev) + prev->next = next; + free_job (job); + job = prev; + } + } +} + + +static struct screenhack_job * +find_job (pid_t pid) +{ + struct screenhack_job *job; + for (job = jobs; job; job = job->next) + if (job->pid == pid) + return job; + return 0; +} + +static void await_dying_children (saver_info *si); +#ifndef VMS +static void describe_dead_child (saver_info *, pid_t, int wait_status); +#endif + + +/* Semaphore to temporarily turn the SIGCHLD handler into a no-op. + Don't alter this directly -- use block_sigchld() / unblock_sigchld(). + */ +static int block_sigchld_handler = 0; + + +static void +block_sigchld (void) +{ +#ifdef HAVE_SIGACTION + sigset_t child_set; + sigemptyset (&child_set); + sigaddset (&child_set, SIGCHLD); + sigprocmask (SIG_BLOCK, &child_set, 0); +#endif /* HAVE_SIGACTION */ + + block_sigchld_handler++; +} + +static void +unblock_sigchld (void) +{ +#ifdef HAVE_SIGACTION + sigset_t child_set; + sigemptyset(&child_set); + sigaddset(&child_set, SIGCHLD); + sigprocmask(SIG_UNBLOCK, &child_set, 0); +#endif /* HAVE_SIGACTION */ + + block_sigchld_handler--; +} + +static int +kill_job (saver_info *si, pid_t pid, int signal) +{ + saver_preferences *p = &si->prefs; + struct screenhack_job *job; + int status = -1; + + clean_job_list(); + + if (block_sigchld_handler) + /* This function should not be called from the signal handler. */ + abort(); + + block_sigchld(); /* we control the horizontal... */ + + job = find_job (pid); + if (!job || + !job->pid || + job->status == job_killed) + { + if (p->verbose_p) + fprintf (stderr, "%s: no child %ld to signal!\n", + blurb(), (long) pid); + goto DONE; + } + + switch (signal) { + case SIGTERM: job->status = job_killed; break; +#ifdef SIGSTOP + /* #### there must be a way to do this on VMS... */ + case SIGSTOP: job->status = job_stopped; break; + case SIGCONT: job->status = job_running; break; +#endif /* SIGSTOP */ + default: abort(); + } + +#ifdef SIGSTOP + if (p->verbose_p) + fprintf (stderr, "%s: %s pid %lu.\n", blurb(), + (signal == SIGTERM ? "killing" : + signal == SIGSTOP ? "suspending" : + signal == SIGCONT ? "resuming" : "signalling"), + (unsigned long) job->pid); +#else /* !SIGSTOP */ + if (p->verbose_p) + fprintf (stderr, "%s: %s pid %lu.\n", blurb(), "killing", + (unsigned long) job->pid); +#endif /* !SIGSTOP */ + + status = kill (job->pid, signal); + + if (p->verbose_p && status < 0) + { + if (errno == ESRCH) + fprintf (stderr, "%s: child process %lu (%s) was already dead.\n", + blurb(), job->pid, job->name); + else + { + char buf [1024]; + sprintf (buf, "%s: couldn't kill child process %lu (%s)", + blurb(), job->pid, job->name); + perror (buf); + } + } + + await_dying_children (si); + + DONE: + unblock_sigchld(); + if (block_sigchld_handler < 0) + abort(); + + clean_job_list(); + return status; +} + + +#ifdef SIGCHLD +static RETSIGTYPE +sigchld_handler (int sig) +{ + saver_info *si = global_si_kludge; /* I hate C so much... */ + + if (si->prefs.debug_p) + fprintf(stderr, "%s: got SIGCHLD%s\n", blurb(), + (block_sigchld_handler ? " (blocked)" : "")); + + if (block_sigchld_handler < 0) + abort(); + else if (block_sigchld_handler == 0) + { + block_sigchld(); + await_dying_children (si); + unblock_sigchld(); + } + + init_sigchld(); +} +#endif /* SIGCHLD */ + + +#ifndef VMS +static void +await_dying_children (saver_info *si) +{ + while (1) + { + int wait_status = 0; + pid_t kid; + + errno = 0; + kid = waitpid (-1, &wait_status, WNOHANG|WUNTRACED); + + if (si->prefs.debug_p) + { + if (kid < 0 && errno) + fprintf (stderr, "%s: waitpid(-1) ==> %ld (%d)\n", blurb(), + (long) kid, errno); + else + fprintf (stderr, "%s: waitpid(-1) ==> %ld\n", blurb(), + (long) kid); + } + + /* 0 means no more children to reap. + -1 means error -- except "interrupted system call" isn't a "real" + error, so if we get that, we should just try again. */ + if (kid == 0 || + (kid < 0 && errno != EINTR)) + break; + + describe_dead_child (si, kid, wait_status); + } +} + + +static void +describe_dead_child (saver_info *si, pid_t kid, int wait_status) +{ + int i; + saver_preferences *p = &si->prefs; + struct screenhack_job *job = find_job (kid); + const char *name = job ? job->name : ""; + + if (WIFEXITED (wait_status)) + { + int exit_status = WEXITSTATUS (wait_status); + + /* Treat exit code as a signed 8-bit quantity. */ + if (exit_status & 0x80) exit_status |= ~0xFF; + + /* One might assume that exiting with non-0 means something went wrong. + But that loser xswarm exits with the code that it was killed with, so + it *always* exits abnormally. Treat abnormal exits as "normal" (don't + mention them) if we've just killed the subprocess. But mention them + if they happen on their own. + */ + if (!job || + (exit_status != 0 && + (p->verbose_p || job->status != job_killed))) + fprintf (stderr, + "%s: child pid %lu (%s) exited abnormally (code %d).\n", + blurb(), (unsigned long) kid, name, exit_status); + else if (p->verbose_p) + fprintf (stderr, "%s: child pid %lu (%s) exited normally.\n", + blurb(), (unsigned long) kid, name); + + if (job) + job->status = job_dead; + } + else if (WIFSIGNALED (wait_status)) + { + if (p->verbose_p || + !job || + job->status != job_killed || + WTERMSIG (wait_status) != SIGTERM) + fprintf (stderr, "%s: child pid %lu (%s) terminated with %s.\n", + blurb(), (unsigned long) kid, name, + signal_name (WTERMSIG(wait_status))); + + if (job) + job->status = job_dead; + } + else if (WIFSTOPPED (wait_status)) + { + if (p->verbose_p) + fprintf (stderr, "%s: child pid %lu (%s) stopped with %s.\n", + blurb(), (unsigned long) kid, name, + signal_name (WSTOPSIG (wait_status))); + + if (job) + job->status = job_stopped; + } + else + { + fprintf (stderr, "%s: child pid %lu (%s) died in a mysterious way!", + blurb(), (unsigned long) kid, name); + if (job) + job->status = job_dead; + } + + /* Clear out the pid so that screenhack_running_p() knows it's dead. + */ + if (!job || job->status == job_dead) + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (kid == ssi->pid) + ssi->pid = 0; + } +} + +#else /* VMS */ +static void await_dying_children (saver_info *si) { return; } +#endif /* VMS */ + + +void +init_sigchld (void) +{ +#ifdef SIGCHLD + +# ifdef HAVE_SIGACTION /* Thanks to Tom Kelly */ + + static Bool sigchld_initialized_p = 0; + if (!sigchld_initialized_p) + { + struct sigaction action, old; + + action.sa_handler = sigchld_handler; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + + if (sigaction(SIGCHLD, &action, &old) < 0) + { + char buf [255]; + sprintf (buf, "%s: couldn't catch SIGCHLD", blurb()); + perror (buf); + } + sigchld_initialized_p = True; + } + +# else /* !HAVE_SIGACTION */ + + if (((long) signal (SIGCHLD, sigchld_handler)) == -1L) + { + char buf [255]; + sprintf (buf, "%s: couldn't catch SIGCHLD", blurb()); + perror (buf); + } +# endif /* !HAVE_SIGACTION */ +#endif /* SIGCHLD */ +} + + + + + +static Bool +hack_enabled_p (const char *hack) +{ + const char *s = hack; + while (isspace(*s)) s++; + return (*s != '-'); +} + +static Bool +select_visual_of_hack (saver_screen_info *ssi, const char *hack) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + Bool selected; + static char vis [1024]; + const char *in = hack; + char *out = vis; + while (isspace(*in)) in++; /* skip whitespace */ + if (*in == '-') in++; /* skip optional "-" */ + while (isspace(*in)) in++; /* skip whitespace */ + + while (!isspace(*in) && *in != ':') + *out++ = *in++; /* snarf first token */ + while (isspace(*in)) in++; /* skip whitespace */ + *out = 0; + + if (*in == ':') + selected = select_visual(ssi, vis); + else + selected = select_visual(ssi, 0); + + if (!selected && (p->verbose_p || si->demoing_p)) + { + if (*in == ':') in++; + while (isspace(*in)) in++; + fprintf (stderr, + (si->demoing_p + ? "%s: warning, no \"%s\" visual for \"%s\".\n" + : "%s: no \"%s\" visual; skipping \"%s\".\n"), + blurb(), (*vis ? vis : "???"), in); + } + + return selected; +} + + +static void +spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + raise_window (si, first_time_p, True, False); + XFlush (si->dpy); + + if (p->screenhacks_count) + { + char *hack; + pid_t forked; + char buf [255]; + int new_hack; + int retry_count = 0; + Bool force = False; + + AGAIN: + + if (p->screenhacks_count == 1) + /* If there is only one hack in the list, there is no choice. */ + new_hack = 0; + + else if (si->selection_mode == -1) + /* Select the next hack, wrapping. */ + new_hack = (ssi->current_hack + 1) % p->screenhacks_count; + + else if (si->selection_mode == -2) + /* Select the previous hack, wrapping. */ + new_hack = ((ssi->current_hack + p->screenhacks_count - 1) + % p->screenhacks_count); + + else if (si->selection_mode > 0) + /* Select a specific hack, by number. No negotiation. */ + { + new_hack = ((si->selection_mode - 1) % p->screenhacks_count); + force = True; + } + else + { + /* Select a random hack (but not the one we just ran.) */ + while ((new_hack = random () % p->screenhacks_count) + == ssi->current_hack) + ; + } + + ssi->current_hack = new_hack; + hack = p->screenhacks[ssi->current_hack]; + + /* If the hack is disabled, or there is no visual for this hack, + then try again (move forward, or backward, or re-randomize.) + Unless this hack was specified explicitly, in which case, + use it regardless. + */ + if (force) + select_visual_of_hack (ssi, hack); + + if (!force && + (!hack_enabled_p (hack) || + !select_visual_of_hack (ssi, hack))) + { + if (++retry_count > (p->screenhacks_count*4)) + { + /* Uh, oops. Odds are, there are no suitable visuals, + and we're looping. Give up. (This is totally lame, + what we should do is make a list of suitable hacks at + the beginning, then only loop over them.) + */ + if (p->verbose_p) + fprintf(stderr, + "%s: no suitable visuals for these programs.\n", + blurb()); + return; + } + else + goto AGAIN; + } + + /* Turn off "next" and "prev" modes now, but "demo" mode is only + turned off by explicit action. + */ + if (si->selection_mode < 0) + si->selection_mode = 0; + + + /* If there's a visual description on the front of the command, nuke it. + */ + { + char *in = hack; + while (isspace(*in)) in++; /* skip whitespace */ + if (*in == '-') in++; /* skip optional "-" */ + while (isspace(*in)) in++; /* skip whitespace */ + hack = in; + while (!isspace(*in) && *in != ':') in++; /* snarf first token */ + while (isspace(*in)) in++; /* skip whitespace */ + if (*in == ':') + { + in++; + while (isspace(*in)) in++; + hack = in; + } + } + + switch ((int) (forked = fork ())) + { + case -1: + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + restore_real_vroot (si); + saver_exit (si, 1, 0); + + case 0: + close (ConnectionNumber (si->dpy)); /* close display fd */ + nice_subproc (p->nice_inferior); /* change process priority */ + hack_subproc_environment (ssi); /* set $DISPLAY */ + exec_screenhack (si, hack); /* this does not return */ + abort(); + break; + + default: + ssi->pid = forked; + (void) make_job (forked, hack); + break; + } + } +} + + +void +spawn_screenhack (saver_info *si, Bool first_time_p) +{ + int i; + + if (!monitor_powered_on_p (si)) + { + if (si->prefs.verbose_p) + fprintf (stderr, + "%s: server reports that monitor has powered down; " + "not launching a new hack.\n", blurb()); + return; + } + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + spawn_screenhack_1 (ssi, first_time_p); + } +} + + +void +kill_screenhack (saver_info *si) +{ + int i; + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->pid) + kill_job (si, ssi->pid, SIGTERM); + ssi->pid = 0; + } +} + + +void +suspend_screenhack (saver_info *si, Bool suspend_p) +{ +#ifdef SIGSTOP /* older VMS doesn't have it... */ + int i; + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->pid) + kill_job (si, ssi->pid, (suspend_p ? SIGSTOP : SIGCONT)); + } +#endif /* SIGSTOP */ +} + + +/* Called when we're exiting abnormally, to kill off the subproc. */ +void +emergency_kill_subproc (saver_info *si) +{ + int i; +#ifdef SIGCHLD + signal (SIGCHLD, SIG_IGN); +#endif /* SIGCHLD */ + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->pid) + { + kill_job (si, ssi->pid, SIGTERM); + ssi->pid = 0; + } + } +} + +Bool +screenhack_running_p (saver_info *si) +{ + Bool result = True; + int i; + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (!ssi->pid) + result = False; + } + return result; +} + + +/* Environment variables. */ + + +/* Modifies $PATH in the current environment, so that if DEFAULT_PATH_PREFIX + is defined, the xscreensaver daemon will search that directory for hacks. + */ +void +hack_environment (saver_info *si) +{ +#if defined(HAVE_PUTENV) && defined(DEFAULT_PATH_PREFIX) + static const char *def_path = DEFAULT_PATH_PREFIX; + if (def_path && *def_path) + { + const char *opath = getenv("PATH"); + char *npath = (char *) malloc(strlen(def_path) + strlen(opath) + 20); + strcpy (npath, "PATH="); + strcat (npath, def_path); + strcat (npath, ":"); + strcat (npath, opath); + + if (putenv (npath)) + abort (); + } +#endif /* HAVE_PUTENV && DEFAULT_PATH_PREFIX */ +} + + +void +hack_subproc_environment (saver_screen_info *ssi) +{ + /* Store $DISPLAY into the environment, so that the $DISPLAY variable that + the spawned processes inherit is correct. First, it must be on the same + host and display as the value of -display passed in on our command line + (which is not necessarily the same as what our $DISPLAY variable is.) + Second, the screen number in the $DISPLAY passed to the subprocess should + be the screen on which this particular hack is running -- not the display + specification which the driver itself is using, since the driver ignores + its screen number and manages all existing screens. + */ + saver_info *si = ssi->global; + const char *odpy = DisplayString (si->dpy); + char *ndpy = (char *) malloc(strlen(odpy) + 20); + int screen_number; + char *s; + + for (screen_number = 0; screen_number < si->nscreens; screen_number++) + if (ssi == &si->screens[screen_number]) + break; + + strcpy (ndpy, "DISPLAY="); + s = ndpy + strlen(ndpy); + strcpy (s, odpy); + + while (*s && *s != ':') s++; /* skip to colon */ + while (*s == ':') s++; /* skip over colons */ + while (isdigit(*s)) s++; /* skip over dpy number */ + while (*s == '.') s++; /* skip over dot */ + if (s[-1] != '.') *s++ = '.'; /* put on a dot */ + sprintf(s, "%d", screen_number); /* put on screen number */ + + /* Allegedly, BSD 4.3 didn't have putenv(), but nobody runs such systems + any more, right? It's not Posix, but everyone seems to have it. */ +#ifdef HAVE_PUTENV + if (putenv (ndpy)) + abort (); +#endif /* HAVE_PUTENV */ +} + + +/* Restarting the xscreensaver process from scratch. */ + +static char **saved_argv; + +void +save_argv (int argc, char **argv) +{ + saved_argv = (char **) calloc (argc+2, sizeof (char *)); + saved_argv [argc] = 0; + while (argc--) + { + int i = strlen (argv [argc]) + 1; + saved_argv [argc] = (char *) malloc (i); + memcpy (saved_argv [argc], argv [argc], i); + } +} + + +/* Re-execs the process with the arguments in saved_argv. + Does not return unless there was an error. + */ +void +restart_process (saver_info *si) +{ + if (si->prefs.verbose_p) + { + int i; + fprintf (real_stderr, "%s: re-executing", blurb()); + for (i = 0; saved_argv[i]; i++) + fprintf (real_stderr, " %s", saved_argv[i]); + fprintf (real_stderr, "\n"); + } + describe_uids (si, real_stderr); + fprintf (real_stderr, "\n"); + + fflush (real_stdout); + fflush (real_stderr); + execvp (saved_argv [0], saved_argv); /* shouldn't return */ + { + char buf [512]; + sprintf (buf, "%s: could not restart process", blurb()); + perror(buf); + fflush(stderr); + } + XBell(si->dpy, 0); +} diff --git a/driver/test-apm.c b/driver/test-apm.c new file mode 100644 index 00000000..108905f0 --- /dev/null +++ b/driver/test-apm.c @@ -0,0 +1,100 @@ +/* test-apm.c --- playing with the APM library. + * xscreensaver, Copyright (c) 1999 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include + +#include +#include + +#include + +#define countof(x) (sizeof((x))/sizeof(*(x))) + + +char *progname = 0; +char *progclass = "XScreenSaver"; + +static const char * +blurb (void) +{ + static char buf[255]; + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + +static void +apm_cb (XtPointer closure, int *fd, XtInputId *id) +{ + apm_event_t events[100]; + int n, i; + while ((n = apm_get_events (*fd, 0, events, countof(events))) + > 0) + for (i = 0; i < n; i++) + { + fprintf (stderr, "%s: APM event 0x%x: %s.\n", blurb(), + events[i], apm_event_name (events[i])); +#if 0 + switch (events[i]) + { + case APM_SYS_STANDBY: + case APM_USER_STANDBY: + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + case APM_CRITICAL_SUSPEND: + break; + } +#endif + } +} + +int +main (int argc, char **argv) +{ + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + int fd; + XtInputId id; + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + fd = apm_open (); + if (fd <= 0) + { + fprintf (stderr, "%s: couldn't initialize APM.\n", blurb()); + exit (1); + } + + id = XtAppAddInput(app, fd, + (XtPointer) (XtInputReadMask | XtInputWriteMask), + apm_cb, 0); + XtAppMainLoop (app); + exit (0); +} diff --git a/driver/test-grab.c b/driver/test-grab.c new file mode 100644 index 00000000..9b4a9145 --- /dev/null +++ b/driver/test-grab.c @@ -0,0 +1,89 @@ +/* test-uid.c --- playing with grabs. + * xscreensaver, Copyright (c) 1999 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include + +#include +#include + +char *progname = 0; +char *progclass = "XScreenSaver"; + +#define ALL_POINTER_EVENTS \ + (ButtonPressMask | ButtonReleaseMask | EnterWindowMask | \ + LeaveWindowMask | PointerMotionMask | PointerMotionHintMask | \ + Button1MotionMask | Button2MotionMask | Button3MotionMask | \ + Button4MotionMask | Button5MotionMask | ButtonMotionMask) + +int +main (int argc, char **argv) +{ + XtAppContext app; + int kstatus, mstatus; + Cursor cursor = 0; + int delay = 60 * 15; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + Window w = RootWindow (dpy, DefaultScreen(dpy)); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + kstatus = XGrabKeyboard (dpy, w, True, + GrabModeSync, GrabModeAsync, + CurrentTime); + fprintf (stderr, "%s: grabbing keyboard on 0x%x... %s.\n", + progname, (unsigned long) w, + (kstatus == GrabSuccess ? "GrabSuccess" : + kstatus == AlreadyGrabbed ? "AlreadyGrabbed" : + kstatus == GrabInvalidTime ? "GrabInvalidTime" : + kstatus == GrabNotViewable ? "GrabNotViewable" : + kstatus == GrabFrozen ? "GrabFrozen" : + "???")); + + mstatus = XGrabPointer (dpy, w, True, ALL_POINTER_EVENTS, + GrabModeAsync, GrabModeAsync, None, + cursor, CurrentTime); + fprintf (stderr, "%s: grabbing mouse on 0x%x... %s.\n", + progname, (unsigned long) w, + (mstatus == GrabSuccess ? "GrabSuccess" : + mstatus == AlreadyGrabbed ? "AlreadyGrabbed" : + mstatus == GrabInvalidTime ? "GrabInvalidTime" : + mstatus == GrabNotViewable ? "GrabNotViewable" : + mstatus == GrabFrozen ? "GrabFrozen" : + "???")); + + XSync(dpy, False); + + if (kstatus == GrabSuccess || mstatus == GrabSuccess) + { + fprintf (stderr, "%s: sleeping for %d:%02d:%02d...\n", + progname, + delay / (60 * 60), + (delay % (60 * 60)) / 60, + delay % 60); + fflush(stderr); + sleep (delay); + XSync(dpy, False); + } + + exit (0); +} diff --git a/driver/test-passwd.c b/driver/test-passwd.c new file mode 100644 index 00000000..f4fef0d5 --- /dev/null +++ b/driver/test-passwd.c @@ -0,0 +1,208 @@ +/* xscreensaver, Copyright (c) 1998 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. + */ + +/* This is a kludgy test harness for debugging the password dialog box. + It's somewhat easier to debug it here than in the xscreensaver executable + itself. + */ + +#define WHICH 0 + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xscreensaver.h" +#include "resources.h" +#include "version.h" +#include "visual.h" + +char *progname = 0; +char *progclass = 0; +XrmDatabase db = 0; +saver_info *global_si_kludge; + +FILE *real_stderr, *real_stdout; + +void monitor_power_on (saver_info *si) {} +Bool monitor_powered_on_p (saver_info *si) { return True; } +void initialize_screensaver_window (saver_info *si) {} +void raise_window (saver_info *si, Bool i, Bool b, Bool d) {} +Bool blank_screen (saver_info *si) {return False;} +void unblank_screen (saver_info *si) {} +Bool select_visual (saver_screen_info *ssi, const char *v) { return False; } +Bool window_exists_p (Display *dpy, Window window) {return True;} +void start_notice_events_timer (saver_info *si, Window w, Bool b) {} +Bool handle_clientmessage (saver_info *si, XEvent *e, Bool u) { return False; } +int BadWindow_ehandler (Display *dpy, XErrorEvent *error) { exit(1); } +const char *signal_name(int signal) { return "???"; } +void restore_real_vroot (saver_info *si) {} +void saver_exit (saver_info *si, int status, const char *core) { exit(status);} +int move_mouse_grab (saver_info *si, Window to, Cursor cursor) { return 0; } + +const char *blurb(void) { return progname; } +Atom XA_SCREENSAVER, XA_DEMO, XA_PREFS; + +void +get_screen_viewport (saver_screen_info *ssi, + int *x_ret, int *y_ret, + int *w_ret, int *h_ret, + Bool verbose_p) +{ + *x_ret = 0; + *y_ret = 0; + *w_ret = WidthOfScreen (ssi->screen); + *h_ret = HeightOfScreen (ssi->screen); +} + + +void +idle_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + XEvent fake_event; + fake_event.type = 0; /* XAnyEvent type, ignored. */ + fake_event.xany.display = si->dpy; + fake_event.xany.window = 0; + XPutBackEvent (si->dpy, &fake_event); +} + + +static char *fallback[] = { +#include "XScreenSaver_ad.h" + 0 +}; + +int +main (int argc, char **argv) +{ + Widget toplevel_shell = 0; + saver_screen_info ssip; + saver_info sip; + saver_info *si = &sip; + saver_preferences *p = &si->prefs; + + memset(&sip, 0, sizeof(sip)); + memset(&ssip, 0, sizeof(ssip)); + + si->nscreens = 1; + si->screens = si->default_screen = &ssip; + ssip.global = si; + + global_si_kludge = si; + real_stderr = stderr; + real_stdout = stdout; + + si->version = (char *) malloc (5); + memcpy (si->version, screensaver_id + 17, 4); + progname = argv[0]; + { + char *s = strrchr(progname, '/'); + if (*s) strcpy (progname, s+1); + } + + /* before hack_uid() for proper permissions */ + lock_priv_init (argc, argv, True); + + hack_uid (si); + + if (! lock_init (argc, argv, si->prefs.verbose_p)) + { + si->locking_disabled_p = True; + si->nolock_reason = "error getting password"; + } + + progclass = "XScreenSaver"; + +#if (WHICH != 2) + toplevel_shell = XtAppInitialize (&si->app, progclass, 0, 0, + &argc, argv, fallback, + 0, 0); + + si->dpy = XtDisplay (toplevel_shell); + p->db = XtDatabase (si->dpy); + si->default_screen->toplevel_shell = toplevel_shell; + si->default_screen->screen = XtScreen(toplevel_shell); + si->default_screen->default_visual = + si->default_screen->current_visual = + DefaultVisualOfScreen(si->default_screen->screen); + si->default_screen->screensaver_window = + RootWindowOfScreen(si->default_screen->screen); + si->default_screen->current_depth = + visual_depth(si->default_screen->screen, + si->default_screen->current_visual); + + db = p->db; + XtGetApplicationNameAndClass (si->dpy, &progname, &progclass); + + load_init_file (&si->prefs); + +#endif /* (WHICH != 2) */ + + p->verbose_p = True; + + while (1) + { +#if WHICH == 0 + if (unlock_p (si)) + fprintf (stderr, "%s: password correct\n", progname); + else + fprintf (stderr, "%s: password INCORRECT!\n", progname); + + XSync(si->dpy, False); + sleep (3); +#elif WHICH == 1 + { + XEvent event; + make_splash_dialog (si); + XtAppAddTimeOut (si->app, p->splash_duration + 1000, + idle_timer, (XtPointer) si); + while (si->splash_dialog) + { + XtAppNextEvent (si->app, &event); + if (event.xany.window == si->splash_dialog) + handle_splash_event (si, &event); + XtDispatchEvent (&event); + } + XSync (si->dpy, False); + sleep (1); + } +#elif WHICH == 2 + { + char *pass; + char buf[255]; + struct passwd *p = getpwuid (getuid ()); + printf ("\n%s: %s's password: ", progname, p->pw_name); + + pass = fgets (buf, sizeof(buf)-1, stdin); + if (!pass || !*pass) + exit (0); + if (pass[strlen(pass)-1] == '\n') + pass[strlen(pass)-1] = 0; + + if (passwd_valid_p (pass, True)) + printf ("%s: Ok!\n", progname); + else + printf ("%s: Wrong!\n", progname); + } +#endif + } +} diff --git a/driver/test-uid.c b/driver/test-uid.c new file mode 100644 index 00000000..0a75fcf4 --- /dev/null +++ b/driver/test-uid.c @@ -0,0 +1,180 @@ +/* test-uid.c --- playing with setuid. + * xscreensaver, Copyright (c) 1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +static void +print(void) +{ + int uid = getuid(); + int gid = getgid(); + int euid = geteuid(); + int egid = getegid(); + struct passwd *p = 0; + struct group *g = 0; + + p = getpwuid (uid); + g = getgrgid (gid); + fprintf(stderr, "real user/group: %ld/%ld (%s/%s)\n", (long) uid, (long) gid, + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???")); + + p = getpwuid (euid); + g = getgrgid (egid); + fprintf(stderr, "eff. user/group: %ld/%ld (%s/%s)\n", (long)euid, (long)egid, + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???")); +} + +int +main (int argc, char **argv) +{ + int i; + struct passwd *p = 0; + struct group *g = 0; + + if (argc <= 1) + { + fprintf(stderr, + "usage: %s [ user/group ... ]\n" + "\tEach argument may be a user name, or user/group.\n" + "\tThis program will attempt to setuid/setgid to each\n" + "\tin turn, and report the results. The user and group\n" + "\tnames may be strings, or numeric.\n", + argv[0]); + exit(1); + } + + print(); + for (i = 1; i < argc; i++) + { + char *user = argv[i]; + char *group = strchr(user, '/'); + if (!group) + group = strchr(user, '.'); + if (group) + *group++ = 0; + + if (group && *group) + { + long gid = 0; + int was_numeric = 0; + + g = 0; + if (*group == '-' || (*group >= '0' && *group <= '9')) + if (1 == sscanf(group, "%ld", &gid)) + { + g = getgrgid (gid); + was_numeric = 1; + } + + if (!g) + g = getgrnam(group); + + if (g) + { + gid = g->gr_gid; + group = g->gr_name; + } + else + { + if (was_numeric) + { + fprintf(stderr, "no group numbered %s.\n", group); + group = ""; + } + else + { + fprintf(stderr, "no group named %s.\n", group); + goto NOGROUP; + } + } + + fprintf(stderr, "setgid(%ld) \"%s\"", gid, group); + if (setgid(gid) == 0) + fprintf(stderr, " succeeded.\n"); + else + perror(" failed"); + + NOGROUP: ; + } + + if (user && *user) + { + long uid = 0; + int was_numeric = 0; + + p = 0; + if (*user == '-' || (*user >= '0' && *user <= '9')) + if (1 == sscanf(user, "%ld", &uid)) + { + p = getpwuid (uid); + was_numeric = 1; + } + + if (!p) + p = getpwnam(user); + + if (p) + { + uid = p->pw_uid; + user = p->pw_name; + } + else + { + if (was_numeric) + { + fprintf(stderr, "no user numbered \"%s\".\n", user); + user = ""; + } + else + { + fprintf(stderr, "no user named %s.\n", user); + goto NOUSER; + } + } + + fprintf(stderr, "setuid(%ld) \"%s\"", uid, user); + if (setuid(uid) == 0) + fprintf(stderr, " succeeded.\n"); + else + perror(" failed"); + NOUSER: ; + } + print(); + } + + fprintf(stderr, + "running \"whoami\" and \"groups\" in a sub-process reports:\n"); + fflush(stdout); + fflush(stderr); + system ("/bin/sh -c 'echo \"`whoami` / `groups`\"'"); + + fflush(stdout); + fflush(stderr); + exit(0); +} diff --git a/driver/test-xdpms.c b/driver/test-xdpms.c new file mode 100644 index 00000000..79a0dfdf --- /dev/null +++ b/driver/test-xdpms.c @@ -0,0 +1,159 @@ +/* test-xdpms.c --- playing with the XDPMS extension. + * xscreensaver, Copyright (c) 1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include + +extern Bool DPMSQueryExtension (Display *dpy, int *event_ret, int *error_ret); +extern Bool DPMSCapable (Display *dpy); +extern Status DPMSForceLevel (Display *dpy, CARD16 level); +extern Status DPMSInfo (Display *dpy, CARD16 *power_level, BOOL *state); + +extern Status DPMSGetVersion (Display *dpy, int *major_ret, int *minor_ret); +extern Status DPMSSetTimeouts (Display *dpy, + CARD16 standby, CARD16 suspend, CARD16 off); +extern Bool DPMSGetTimeouts (Display *dpy, + CARD16 *standby, CARD16 *suspend, CARD16 *off); +extern Status DPMSEnable (Display *dpy); +extern Status DPMSDisable (Display *dpy); + + +char *progname = 0; +char *progclass = "XScreenSaver"; + +static const char * +blurb (void) +{ + static char buf[255]; + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + + +int +main (int argc, char **argv) +{ + int delay = 10; + + int event_number, error_number; + int major, minor; + CARD16 standby, suspend, off; + CARD16 state; + BOOL onoff; + + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + if (!DPMSQueryExtension(dpy, &event_number, &error_number)) + { + fprintf(stderr, "%s: DPMSQueryExtension(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, "%s: server does not support the XDPMS extension.\n", + blurb()); + exit(1); + } + else + fprintf(stderr, "%s: DPMSQueryExtension(dpy, ...) ==> %d, %d\n", blurb(), + event_number, error_number); + + if (!DPMSCapable(dpy)) + { + fprintf(stderr, "%s: DPMSCapable(dpy) ==> False\n", blurb()); + fprintf(stderr, "%s: server says hardware doesn't support DPMS.\n", + blurb()); + exit(1); + } + else + fprintf(stderr, "%s: DPMSCapable(dpy) ==> True\n", blurb()); + + if (!DPMSGetVersion(dpy, &major, &minor)) + { + fprintf(stderr, "%s: DPMSGetVersion(dpy, ...) ==> False\n", blurb()); + fprintf(stderr, "%s: server didn't report XDPMS version numbers?\n", + blurb()); + } + else + fprintf(stderr, "%s: DPMSGetVersion(dpy, ...) ==> %d, %d\n", blurb(), + major, minor); + + if (!DPMSGetTimeouts(dpy, &standby, &suspend, &off)) + { + fprintf(stderr, "%s: DPMSGetTimeouts(dpy, ...) ==> False\n", blurb()); + fprintf(stderr, "%s: server didn't report DPMS timeouts?\n", blurb()); + } + else + fprintf(stderr, + "%s: DPMSGetTimeouts(dpy, ...)\n" + "\t ==> standby = %d, suspend = %d, off = %d\n", + blurb(), standby, suspend, off); + + while (1) + { + if (!DPMSInfo(dpy, &state, &onoff)) + { + fprintf(stderr, "%s: DPMSInfo(dpy, ...) ==> False\n", blurb()); + fprintf(stderr, "%s: couldn't read DPMS state?\n", blurb()); + onoff = 0; + state = -1; + } + else + { + fprintf(stderr, "%s: DPMSInfo(dpy, ...) ==> %s, %s\n", blurb(), + (state == DPMSModeOn ? "DPMSModeOn" : + state == DPMSModeStandby ? "DPMSModeStandby" : + state == DPMSModeSuspend ? "DPMSModeSuspend" : + state == DPMSModeOff ? "DPMSModeOff" : "???"), + (onoff == 1 ? "On" : onoff == 0 ? "Off" : "???")); + } + + if (state == DPMSModeStandby || + state == DPMSModeSuspend || + state == DPMSModeOff) + { + Status st; + fprintf(stderr, "%s: monitor is off; turning it on.\n", blurb()); + st = DPMSForceLevel (dpy, DPMSModeOn); + fprintf (stderr, "%s: DPMSForceLevel (dpy, DPMSModeOn) ==> %s\n", + blurb(), (st ? "Ok" : "Error")); + } + + sleep (delay); + } +} diff --git a/driver/timers.c b/driver/timers.c new file mode 100644 index 00000000..a6a9486f --- /dev/null +++ b/driver/timers.c @@ -0,0 +1,1071 @@ +/* timers.c --- detecting when the user is idle, and other timer-related tasks. + * xscreensaver, Copyright (c) 1991-1997, 1998 + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* #define DEBUG_TIMERS */ + +#include +#include +#include +#include +#ifdef HAVE_XMU +# ifndef VMS +# include +# else /* VMS */ +# include +# endif /* VMS */ +# else /* !HAVE_XMU */ +# include "xmu.h" +#endif /* !HAVE_XMU */ + +#ifdef HAVE_XIDLE_EXTENSION +#include +#endif /* HAVE_XIDLE_EXTENSION */ + +#ifdef HAVE_MIT_SAVER_EXTENSION +#include +#endif /* HAVE_MIT_SAVER_EXTENSION */ + +#ifdef HAVE_SGI_SAVER_EXTENSION +#include +#endif /* HAVE_SGI_SAVER_EXTENSION */ + +#include "xscreensaver.h" + +#ifdef HAVE_PROC_INTERRUPTS +static Bool proc_interrupts_activity_p (saver_info *si); +#endif /* HAVE_PROC_INTERRUPTS */ + +static void check_for_clock_skew (saver_info *si); + + +void +idle_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + + /* What an amazingly shitty design. Not only does Xt execute timeout + events from XtAppNextEvent() instead of from XtDispatchEvent(), but + there is no way to tell Xt to block until there is an X event OR a + timeout happens. Once your timeout proc is called, XtAppNextEvent() + still won't return until a "real" X event comes in. + + So this function pushes a stupid, gratuitous, unnecessary event back + on the event queue to force XtAppNextEvent to return Right Fucking Now. + When the code in sleep_until_idle() sees an event of type XAnyEvent, + which the server never generates, it knows that a timeout has occurred. + */ + XEvent fake_event; + fake_event.type = 0; /* XAnyEvent type, ignored. */ + fake_event.xany.display = si->dpy; + fake_event.xany.window = 0; + XPutBackEvent (si->dpy, &fake_event); +} + + +static void +schedule_wakeup_event (saver_info *si, Time when, Bool verbose_p) +{ + /* Wake up periodically to ask the server if we are idle. */ + si->timer_id = XtAppAddTimeOut (si->app, when, idle_timer, + (XtPointer) si); + +#ifdef DEBUG_TIMERS + if (verbose_p) + fprintf (stderr, "%s: starting idle_timer (%ld, %ld)\n", + blurb(), when, si->timer_id); +#endif /* DEBUG_TIMERS */ +} + + +static void +notice_events (saver_info *si, Window window, Bool top_p) +{ + saver_preferences *p = &si->prefs; + XWindowAttributes attrs; + unsigned long events; + Window root, parent, *kids; + unsigned int nkids; + + if (XtWindowToWidget (si->dpy, window)) + /* If it's one of ours, don't mess up its event mask. */ + return; + + if (!XQueryTree (si->dpy, window, &root, &parent, &kids, &nkids)) + return; + if (window == root) + top_p = False; + + XGetWindowAttributes (si->dpy, window, &attrs); + events = ((attrs.all_event_masks | attrs.do_not_propagate_mask) + & KeyPressMask); + + /* Select for SubstructureNotify on all windows. + Select for KeyPress on all windows that already have it selected. + + Note that we can't select for ButtonPress, because of X braindamage: + only one client at a time may select for ButtonPress on a given + window, though any number can select for KeyPress. Someone explain + *that* to me. + + So, if the user spends a while clicking the mouse without ever moving + the mouse or touching the keyboard, we won't know that they've been + active, and the screensaver will come on. That sucks, but I don't + know how to get around it. + */ + XSelectInput (si->dpy, window, SubstructureNotifyMask | events); + + if (top_p && p->verbose_p && (events & KeyPressMask)) + { + /* Only mention one window per tree (hack hack). */ + fprintf (stderr, "%s: selected KeyPress on 0x%lX\n", blurb(), + (unsigned long) window); + top_p = False; + } + + if (kids) + { + while (nkids) + notice_events (si, kids [--nkids], top_p); + XFree ((char *) kids); + } +} + + +int +BadWindow_ehandler (Display *dpy, XErrorEvent *error) +{ + /* When we notice a window being created, we spawn a timer that waits + 30 seconds or so, and then selects events on that window. This error + handler is used so that we can cope with the fact that the window + may have been destroyed <30 seconds after it was created. + */ + if (error->error_code == BadWindow || + error->error_code == BadMatch || + error->error_code == BadDrawable) + return 0; + else + return saver_ehandler (dpy, error); +} + + +struct notice_events_timer_arg { + saver_info *si; + Window w; +}; + +static void +notice_events_timer (XtPointer closure, XtIntervalId *id) +{ + struct notice_events_timer_arg *arg = + (struct notice_events_timer_arg *) closure; + + XErrorHandler old_handler = XSetErrorHandler (BadWindow_ehandler); + + saver_info *si = arg->si; + Window window = arg->w; + + free(arg); + notice_events (si, window, True); + XSync (si->dpy, False); + XSetErrorHandler (old_handler); +} + +void +start_notice_events_timer (saver_info *si, Window w, Bool verbose_p) +{ + saver_preferences *p = &si->prefs; + struct notice_events_timer_arg *arg = + (struct notice_events_timer_arg *) malloc(sizeof(*arg)); + arg->si = si; + arg->w = w; + XtAppAddTimeOut (si->app, p->notice_events_timeout, notice_events_timer, + (XtPointer) arg); + + if (verbose_p) + fprintf (stderr, "%s: starting notice_events_timer for 0x%X (%lu)\n", + blurb(), (unsigned int) w, p->notice_events_timeout); +} + + +/* When the screensaver is active, this timer will periodically change + the running program. + */ +void +cycle_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + Time how_long = p->cycle; + + if (si->selection_mode > 0 && + screenhack_running_p (si)) + /* If we're in "SELECT n" mode, the cycle timer going off will just + restart this same hack again. There's not much point in doing this + every 5 or 10 minutes, but on the other hand, leaving one hack running + for days is probably not a great idea, since they tend to leak and/or + crash. So, restart the thing once an hour. */ + how_long = 1000 * 60 * 60; + + if (si->dbox_up_p) + { + if (p->verbose_p) + fprintf (stderr, "%s: dialog box up; delaying hack change.\n", + blurb()); + how_long = 30000; /* 30 secs */ + } + else + { + maybe_reload_init_file (si); + if (p->verbose_p) + fprintf (stderr, "%s: changing graphics hacks.\n", blurb()); + kill_screenhack (si); + + if (!si->throttled_p) + spawn_screenhack (si, False); + else + { + raise_window (si, True, True, False); + if (p->verbose_p) + fprintf (stderr, "%s: not launching new hack (throttled.)\n", + blurb()); + } + } + + si->cycle_id = XtAppAddTimeOut (si->app, how_long, cycle_timer, + (XtPointer) si); + +#ifdef DEBUG_TIMERS + if (p->verbose_p) + fprintf (stderr, "%s: starting cycle_timer (%ld, %ld)\n", + blurb(), how_long, si->cycle_id); +#endif /* DEBUG_TIMERS */ +} + + +void +activate_lock_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + + if (p->verbose_p) + fprintf (stderr, "%s: timed out; activating lock.\n", blurb()); + set_locked_p (si, True); +} + + +/* Call this when user activity (or "simulated" activity) has been noticed. + */ +static void +reset_timers (saver_info *si) +{ + saver_preferences *p = &si->prefs; + if (si->using_mit_saver_extension || si->using_sgi_saver_extension) + return; + + if (si->timer_id) + { +#ifdef DEBUG_TIMERS + if (p->verbose_p) + fprintf (stderr, "%s: killing idle_timer (%ld, %ld)\n", + blurb(), p->timeout, si->timer_id); +#endif /* DEBUG_TIMERS */ + XtRemoveTimeOut (si->timer_id); + } + + schedule_wakeup_event (si, p->timeout, p->verbose_p); /* sets si->timer_id */ + + if (si->cycle_id) abort (); /* no cycle timer when inactive */ + + si->last_activity_time = time ((time_t *) 0); +} + + +/* When we aren't using a server extension, this timer is used to periodically + wake up and poll the mouse position, which is possibly more reliable than + selecting motion events on every window. + */ +static void +check_pointer_timer (XtPointer closure, XtIntervalId *id) +{ + int i; + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + Bool active_p = False; + + if (!si->using_proc_interrupts && + (si->using_xidle_extension || + si->using_mit_saver_extension || + si->using_sgi_saver_extension)) + /* If an extension is in use, we should not be polling the mouse. + Unless we're also checking /proc/interrupts, in which case, we should. + */ + abort (); + + si->check_pointer_timer_id = + XtAppAddTimeOut (si->app, p->pointer_timeout, check_pointer_timer, + (XtPointer) si); + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + Window root, child; + int root_x, root_y, x, y; + unsigned int mask; + + XQueryPointer (si->dpy, ssi->screensaver_window, &root, &child, + &root_x, &root_y, &x, &y, &mask); + + if (root_x == ssi->poll_mouse_last_root_x && + root_y == ssi->poll_mouse_last_root_y && + child == ssi->poll_mouse_last_child && + mask == ssi->poll_mouse_last_mask) + continue; + + active_p = True; + +#ifdef DEBUG_TIMERS + if (p->verbose_p) + if (root_x == ssi->poll_mouse_last_root_x && + root_y == ssi->poll_mouse_last_root_y && + child == ssi->poll_mouse_last_child) + fprintf (stderr, "%s: modifiers changed at %s on screen %d.\n", + blurb(), timestring(), i); + else + fprintf (stderr, "%s: pointer moved at %s on screen %d.\n", + blurb(), timestring(), i); +#endif /* DEBUG_TIMERS */ + + si->last_activity_screen = ssi; + ssi->poll_mouse_last_root_x = root_x; + ssi->poll_mouse_last_root_y = root_y; + ssi->poll_mouse_last_child = child; + ssi->poll_mouse_last_mask = mask; + } + +#ifdef HAVE_PROC_INTERRUPTS + if (!active_p && + si->using_proc_interrupts && + proc_interrupts_activity_p (si)) + { +# ifdef DEBUG_TIMERS + if (p->verbose_p) + fprintf (stderr, "%s: /proc/interrupts activity at %s.\n", + blurb(), timestring()); +# endif /* DEBUG_TIMERS */ + active_p = True; + } +#endif /* HAVE_PROC_INTERRUPTS */ + + + if (active_p) + reset_timers (si); + + check_for_clock_skew (si); +} + + +/* An unfortunate situation is this: the saver is not active, because the + user has been typing. The machine is a laptop. The user closes the lid + and suspends it. The CPU halts. Some hours later, the user opens the + lid. At this point, Xt's timers will fire, and xscreensaver will blank + the screen. + + So far so good -- well, not really, but it's the best that we can do, + since the OS doesn't send us a signal *before* shutdown -- but if the + user had delayed locking (lockTimeout > 0) then we should start off + in the locked state, rather than only locking N minutes from when the + lid was opened. Also, eschewing fading is probably a good idea, to + clamp down as soon as possible. + + We only do this when we'd be polling the mouse position anyway. + This amounts to an assumption that machines with APM support also + have /proc/interrupts. + */ +static void +check_for_clock_skew (saver_info *si) +{ + saver_preferences *p = &si->prefs; + time_t now = time ((time_t *) 0); + long shift = now - si->last_wall_clock_time; + +#ifdef DEBUG_TIMERS + if (p->verbose_p) + fprintf (stderr, "%s: checking wall clock (%d).\n", blurb(), + (si->last_wall_clock_time == 0 ? 0 : shift)); +#endif /* DEBUG_TIMERS */ + + if (si->last_wall_clock_time != 0 && + shift > (p->timeout / 1000)) + { + if (p->verbose_p) + fprintf (stderr, "%s: wall clock has jumped by %d:%02d:%02d!\n", + blurb(), + (shift / (60 * 60)), ((shift / 60) % 60), (shift % 60)); + + si->emergency_lock_p = True; + idle_timer ((XtPointer) si, 0); + } + + si->last_wall_clock_time = now; +} + + + +static void +dispatch_event (saver_info *si, XEvent *event) +{ + /* If this is for the splash dialog, pass it along. + Note that the password dialog is handled with its own event loop, + so events for that window will never come through here. + */ + if (si->splash_dialog && event->xany.window == si->splash_dialog) + handle_splash_event (si, event); + + XtDispatchEvent (event); +} + + +/* methods of detecting idleness: + + explicitly informed by SGI SCREEN_SAVER server event; + explicitly informed by MIT-SCREEN-SAVER server event; + poll server idle time with XIDLE extension; + select events on all windows, and note absence of recent events; + note that /proc/interrupts has not changed in a while; + activated by clientmessage. + + methods of detecting non-idleness: + + read events on the xscreensaver window; + explicitly informed by SGI SCREEN_SAVER server event; + explicitly informed by MIT-SCREEN-SAVER server event; + select events on all windows, and note events on any of them; + note that /proc/interrupts has changed; + deactivated by clientmessage. + + I trust that explains why this function is a big hairy mess. + */ +void +sleep_until_idle (saver_info *si, Bool until_idle_p) +{ + saver_preferences *p = &si->prefs; + XEvent event; + + /* We need to select events on all windows if we're not using any extensions. + Otherwise, we don't need to. */ + Bool scanning_all_windows = !(si->using_xidle_extension || + si->using_mit_saver_extension || + si->using_sgi_saver_extension); + + /* We need to periodically wake up and check for idleness if we're not using + any extensions, or if we're using the XIDLE extension. The other two + extensions explicitly deliver events when we go idle/non-idle, so we + don't need to poll. */ + Bool polling_for_idleness = !(si->using_mit_saver_extension || + si->using_sgi_saver_extension); + + /* Whether we need to periodically wake up and check to see if the mouse has + moved. We only need to do this when not using any extensions. The reason + this isn't the same as `polling_for_idleness' is that the "idleness" poll + can happen (for example) 5 minutes from now, whereas the mouse-position + poll should happen with low periodicity. We don't need to poll the mouse + position with the XIDLE extension, but we do need to periodically wake up + and query the server with that extension. For our purposes, polling + /proc/interrupts is just like polling the mouse position. It has to + happen on the same kind of schedule. */ + Bool polling_mouse_position = (si->using_proc_interrupts || + !(si->using_xidle_extension || + si->using_mit_saver_extension || + si->using_sgi_saver_extension)); + + if (until_idle_p) + { + if (polling_for_idleness) + /* This causes a no-op event to be delivered to us in a while, so that + we come back around through the event loop again. Use of this timer + is economical: for example, if the screensaver should come on in 5 + minutes, and the user has been idle for 2 minutes, then this + timeout will go off no sooner than 3 minutes from now. */ + schedule_wakeup_event (si, p->timeout, p->verbose_p); + + if (polling_mouse_position) + /* Check to see if the mouse has moved, and set up a repeating timer + to do so periodically (typically, every 5 seconds.) */ + check_pointer_timer ((XtPointer) si, 0); + } + + while (1) + { + XtAppNextEvent (si->app, &event); + + switch (event.xany.type) { + case 0: /* our synthetic "timeout" event has been signalled */ + if (until_idle_p) + { + Time idle; +#ifdef HAVE_XIDLE_EXTENSION + if (si->using_xidle_extension) + { + /* The XIDLE extension uses the synthetic event to prod us into + re-asking the server how long the user has been idle. */ + if (! XGetIdleTime (si->dpy, &idle)) + { + fprintf (stderr, "%s: XGetIdleTime() failed.\n", blurb()); + saver_exit (si, 1, 0); + } + } + else +#endif /* HAVE_XIDLE_EXTENSION */ +#ifdef HAVE_MIT_SAVER_EXTENSION + if (si->using_mit_saver_extension) + { + /* We don't need to do anything in this case - the synthetic + event isn't necessary, as we get sent specific events + to wake us up. In fact, this event generally shouldn't + be being delivered when the MIT extension is in use. */ + idle = 0; + } + else +#endif /* HAVE_MIT_SAVER_EXTENSION */ +#ifdef HAVE_SGI_SAVER_EXTENSION + if (si->using_sgi_saver_extension) + { + /* We don't need to do anything in this case - the synthetic + event isn't necessary, as we get sent specific events + to wake us up. In fact, this event generally shouldn't + be being delivered when the SGI extension is in use. */ + idle = 0; + } + else +#endif /* HAVE_SGI_SAVER_EXTENSION */ + { + /* Otherwise, no server extension is in use. The synthetic + event was to tell us to wake up and see if the user is now + idle. Compute the amount of idle time by comparing the + `last_activity_time' to the wall clock. The l_a_t was set + by calling `reset_timers()', which is called only in only + two situations: when polling the mouse position has revealed + the the mouse has moved (user activity) or when we have read + an event (again, user activity.) + */ + idle = 1000 * (si->last_activity_time - time ((time_t *) 0)); + } + + if (idle >= p->timeout) + { + /* Look, we've been idle long enough. We're done. */ + goto DONE; + } + else if (si->emergency_lock_p) + { + /* Oops, the wall clock has jumped far into the future, so + we need to lock down in a hurry! */ + goto DONE; + } + else + { + /* The event went off, but it turns out that the user has not + yet been idle for long enough. So re-signal the event. + */ + if (polling_for_idleness) + schedule_wakeup_event (si, p->timeout - idle, p->verbose_p); + } + } + break; + + case ClientMessage: + if (handle_clientmessage (si, &event, until_idle_p)) + goto DONE; + break; + + case CreateNotify: + /* A window has been created on the screen somewhere. If we're + supposed to scan all windows for events, prepare this window. */ + if (scanning_all_windows) + { + Window w = event.xcreatewindow.window; +#ifdef DEBUG_TIMERS + start_notice_events_timer (si, w, p->verbose_p); +#else /* !DEBUG_TIMERS */ + start_notice_events_timer (si, w, False); +#endif /* !DEBUG_TIMERS */ + } + break; + + case KeyPress: + case KeyRelease: + case ButtonPress: + case ButtonRelease: + case MotionNotify: + +#ifdef DEBUG_TIMERS + if (p->verbose_p) + { + if (event.xany.type == MotionNotify) + fprintf (stderr,"%s: MotionNotify at %s\n",blurb(),timestring()); + else if (event.xany.type == KeyPress) + fprintf (stderr, "%s: KeyPress seen on 0x%X at %s\n", blurb(), + (unsigned int) event.xkey.window, timestring ()); + else if (event.xany.type == ButtonPress) + fprintf (stderr, "%s: ButtonPress seen on 0x%X at %s\n", blurb(), + (unsigned int) event.xbutton.window, timestring ()); + } +#endif /* DEBUG_TIMERS */ + + /* If any widgets want to handle this event, let them. */ + dispatch_event (si, &event); + + /* We got a user event. + If we're waiting for the user to become active, this is it. + If we're waiting until the user becomes idle, reset the timers + (since now we have longer to wait.) + */ + if (!until_idle_p) + { + if (si->demoing_p && + (event.xany.type == MotionNotify || + event.xany.type == KeyRelease)) + /* When we're demoing a single hack, mouse motion doesn't + cause deactivation. Only clicks and keypresses do. */ + ; + else + /* If we're not demoing, then any activity causes deactivation. + */ + goto DONE; + } + else + reset_timers (si); + + break; + + default: + +#ifdef HAVE_MIT_SAVER_EXTENSION + if (event.type == si->mit_saver_ext_event_number) + { + /* This event's number is that of the MIT-SCREEN-SAVER server + extension. This extension has one event number, and the event + itself contains sub-codes that say what kind of event it was + (an "idle" or "not-idle" event.) + */ + XScreenSaverNotifyEvent *sevent = + (XScreenSaverNotifyEvent *) &event; + if (sevent->state == ScreenSaverOn) + { + int i = 0; + if (p->verbose_p) + fprintf (stderr, "%s: MIT ScreenSaverOn event received.\n", + blurb()); + + /* Get the "real" server window(s) out of the way as soon + as possible. */ + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->server_mit_saver_window && + window_exists_p (si->dpy, + ssi->server_mit_saver_window)) + XUnmapWindow (si->dpy, ssi->server_mit_saver_window); + } + + if (sevent->kind != ScreenSaverExternal) + { + fprintf (stderr, + "%s: ScreenSaverOn event wasn't of type External!\n", + blurb()); + } + + if (until_idle_p) + goto DONE; + } + else if (sevent->state == ScreenSaverOff) + { + if (p->verbose_p) + fprintf (stderr, "%s: MIT ScreenSaverOff event received.\n", + blurb()); + if (!until_idle_p) + goto DONE; + } + else + fprintf (stderr, + "%s: unknown MIT-SCREEN-SAVER event %d received!\n", + blurb(), sevent->state); + } + else + +#endif /* HAVE_MIT_SAVER_EXTENSION */ + + +#ifdef HAVE_SGI_SAVER_EXTENSION + if (event.type == (si->sgi_saver_ext_event_number + ScreenSaverStart)) + { + /* The SGI SCREEN_SAVER server extension has two event numbers, + and this event matches the "idle" event. */ + if (p->verbose_p) + fprintf (stderr, "%s: SGI ScreenSaverStart event received.\n", + blurb()); + + if (until_idle_p) + goto DONE; + } + else if (event.type == (si->sgi_saver_ext_event_number + + ScreenSaverEnd)) + { + /* The SGI SCREEN_SAVER server extension has two event numbers, + and this event matches the "idle" event. */ + if (p->verbose_p) + fprintf (stderr, "%s: SGI ScreenSaverEnd event received.\n", + blurb()); + if (!until_idle_p) + goto DONE; + } + else +#endif /* HAVE_SGI_SAVER_EXTENSION */ + + /* Just some random event. Let the Widgets handle it, if desired. */ + dispatch_event (si, &event); + } + } + DONE: + + + /* If there's a user event on the queue, swallow it. + If we're using a server extension, and the user becomes active, we + get the extension event before the user event -- so the keypress or + motion or whatever is still on the queue. This makes "unfade" not + work, because it sees that event, and bugs out. (This problem + doesn't exhibit itself without an extension, because in that case, + there's only one event generated by user activity, not two.) + */ + XCheckMaskEvent (si->dpy, (KeyPressMask|ButtonPressMask|PointerMotionMask), + &event); + + + if (si->check_pointer_timer_id) + { + XtRemoveTimeOut (si->check_pointer_timer_id); + si->check_pointer_timer_id = 0; + } + if (si->timer_id) + { + XtRemoveTimeOut (si->timer_id); + si->timer_id = 0; + } + + if (until_idle_p && si->cycle_id) /* no cycle timer when inactive */ + abort (); + + return; +} + + + +/* Some crap for dealing with /proc/interrupts. + + On Linux systems, it's possible to see the hardware interrupt count + associated with the keyboard. We can therefore use that as another method + of detecting idleness. + + Why is it a good idea to do this? Because it lets us detect keyboard + activity that is not associated with X events. For example, if the user + has switched to another virtual console, it's good for xscreensaver to not + be running graphics hacks on the (non-visible) X display. The common + complaint that checking /proc/interrupts addresses is that the user is + playing Quake on a non-X console, and the GL hacks are perceptibly slowing + the game... + + This is tricky for a number of reasons. + + * First, we must be sure to only do this when running on an X server that + is on the local machine (because otherwise, we'd be reacting to the + wrong keyboard.) The way we do this is by noting that the $DISPLAY is + pointing to display 0 on the local machine. It *could* be that display + 1 is also on the local machine (e.g., two X servers, each on a different + virtual-terminal) but it's also possible that screen 1 is an X terminal, + using this machine as the host. So we can't take that chance. + + * Second, one can only access these interrupt numbers in a completely + and utterly brain-damaged way. You would think that one would use an + ioctl for this. But no. The ONLY way to get this information is to + open the pseudo-file /proc/interrupts AS A FILE, and read the numbers + out of it TEXTUALLY. Because this is Unix, and all the world's a file, + and the only real data type is the short-line sequence of ASCII bytes. + + Now it's all well and good that the /proc/interrupts pseudo-file + exists; that's a clever idea, and a useful API for things that are + already textually oriented, like shell scripts, and users doing + interactive debugging sessions. But to make a *C PROGRAM* open a file + and parse the textual representation of integers out of it is just + insane. + + * Third, you can't just hold the file open, and fseek() back to the + beginning to get updated data! If you do that, the data never changes. + And I don't want to call open() every five seconds, because I don't want + to risk going to disk for any inodes. It turns out that if you dup() + it early, then each copy gets fresh data, so we can get around that in + this way (but for how many releases, one might wonder?) + + * Fourth, the format of the output of the /proc/interrupts file is + undocumented, and has changed several times already! In Linux 2.0.33, + even on a multiprocessor machine, it looks like this: + + 0: 309453991 timer + 1: 4771729 keyboard + + but on later kernels with MP machines, it looks like this: + + CPU0 CPU1 + 0: 1671450 1672618 IO-APIC-edge timer + 1: 13037 13495 IO-APIC-edge keyboard + + Joy! So how are we expected to parse that? Well, this code doesn't + parse it: it saves the last line with the string "keyboard" in it, and + does a string-comparison to note when it has changed. + + Thanks to Nat Friedman for figuring out all of this crap. + + Note that this only checks for lines with "keyboard" or "PS/2 Mouse" in + them. If you have a serial mouse, it won't detect that, it will only detect + keyboard activity. That's because there's no way to tell the difference + between a serial mouse and a general serial port, and it would be somewhat + unfortunate to have the screensaver turn off when the modem on COM1 burped. + */ + + +#ifdef HAVE_PROC_INTERRUPTS + +#define PROC_INTERRUPTS "/proc/interrupts" + +Bool +query_proc_interrupts_available (saver_info *si, const char **why) +{ + /* We can use /proc/interrupts if $DISPLAY points to :0, and if the + "/proc/interrupts" file exists and is readable. + */ + FILE *f; + if (why) *why = 0; + + if (!display_is_on_console_p (si)) + { + if (why) *why = "not on primary console"; + return False; + } + + f = fopen (PROC_INTERRUPTS, "r"); + if (!f) + return False; + + fclose (f); + return True; +} + + +static Bool +proc_interrupts_activity_p (saver_info *si) +{ + static FILE *f0 = 0; + FILE *f1 = 0; + int fd; + static char last_kbd_line[255] = { 0, }; + static char last_ptr_line[255] = { 0, }; + char new_line[sizeof(last_kbd_line)]; + Bool got_kbd = False, kbd_diff = False; + Bool got_ptr = False, ptr_diff = False; + + if (!f0) + { + /* First time -- open the file. */ + f0 = fopen (PROC_INTERRUPTS, "r"); + if (!f0) + { + char buf[255]; + sprintf(buf, "%s: error opening %s", blurb(), PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + } + + if (f0 == (FILE *) -1) /* means we got an error initializing. */ + return False; + + fd = dup (fileno (f0)); + if (fd < 0) + { + char buf[255]; + sprintf(buf, "%s: could not dup() the %s fd", blurb(), PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + + f1 = fdopen (fd, "r"); + if (!f1) + { + char buf[255]; + sprintf(buf, "%s: could not fdopen() the %s fd", blurb(), + PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + + /* Actually, I'm unclear on why this fseek() is necessary, given the timing + of the dup() above, but it is. */ + if (fseek (f1, 0, SEEK_SET) != 0) + { + char buf[255]; + sprintf(buf, "%s: error rewinding %s", blurb(), PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + + /* Now read through the pseudo-file until we find the "keyboard" line. */ + + while (fgets (new_line, sizeof(new_line)-1, f1)) + { + if (!got_kbd && strstr (new_line, "keyboard")) + { + kbd_diff = (*last_kbd_line && !!strcmp (new_line, last_kbd_line)); + strcpy (last_kbd_line, new_line); + got_kbd = True; + } + else if (!got_ptr && strstr (new_line, "PS/2 Mouse")) + { + ptr_diff = (*last_ptr_line && !!strcmp (new_line, last_ptr_line)); + strcpy (last_ptr_line, new_line); + got_ptr = True; + } + + if (got_kbd && got_ptr) + break; + } + + if (got_kbd || got_ptr) + { + fclose (f1); + return (kbd_diff || ptr_diff); + } + + + /* If we got here, we didn't find either a "keyboard" or a "PS/2 Mouse" + line in the file at all. */ + fprintf (stderr, "%s: no keyboard or mouse data in %s?\n", + blurb(), PROC_INTERRUPTS); + + FAIL: + if (f1) + fclose (f1); + + if (f0 && f0 != (FILE *) -1) + fclose (f0); + + f0 = (FILE *) -1; + return False; +} + +#endif /* HAVE_PROC_INTERRUPTS */ + + +/* This timer goes off every few minutes, whether the user is idle or not, + to try and clean up anything that has gone wrong. + + It calls disable_builtin_screensaver() so that if xset has been used, + or some other program (like xlock) has messed with the XSetScreenSaver() + settings, they will be set back to sensible values (if a server extension + is in use, messing with xlock can cause xscreensaver to never get a wakeup + event, and could cause monitor power-saving to occur, and all manner of + heinousness.) + + If the screen is currently blanked, it raises the window, in case some + other window has been mapped on top of it. + + If the screen is currently blanked, and there is no hack running, it + clears the window, in case there is an error message printed on it (we + don't want the error message to burn in.) + */ + +static void +watchdog_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + + disable_builtin_screensaver (si, False); + + if (si->screen_blanked_p) + { + Bool running_p = screenhack_running_p (si); + + if (si->dbox_up_p) + { +#ifdef DEBUG_TIMERS + if (si->prefs.verbose_p) + fprintf (stderr, "%s: dialog box is up: not raising screen.\n", + blurb()); +#endif /* DEBUG_TIMERS */ + } + else + { +#ifdef DEBUG_TIMERS + if (si->prefs.verbose_p) + fprintf (stderr, "%s: watchdog timer raising %sscreen.\n", + blurb(), (running_p ? "" : "and clearing ")); +#endif /* DEBUG_TIMERS */ + + raise_window (si, True, True, running_p); + } + + if (!monitor_powered_on_p (si)) + { + if (si->prefs.verbose_p) + fprintf (stderr, + "%s: server reports that monitor has powered down; " + "killing running hacks.\n", blurb()); + kill_screenhack (si); + } + + /* Re-schedule this timer. The watchdog timer defaults to a bit less + than the hack cycle period, but is never longer than one hour. + */ + si->watchdog_id = 0; + reset_watchdog_timer (si, True); + } +} + + +void +reset_watchdog_timer (saver_info *si, Bool on_p) +{ + saver_preferences *p = &si->prefs; + + if (si->watchdog_id) + { + XtRemoveTimeOut (si->watchdog_id); + si->watchdog_id = 0; + } + + if (on_p && p->watchdog_timeout) + { + si->watchdog_id = XtAppAddTimeOut (si->app, p->watchdog_timeout, + watchdog_timer, (XtPointer) si); + +#ifdef DEBUG_TIMERS + if (p->verbose_p) + fprintf (stderr, "%s: restarting watchdog_timer (%ld, %ld)\n", + blurb(), p->watchdog_timeout, si->watchdog_id); +#endif /* DEBUG_TIMERS */ + + } +} diff --git a/driver/vms-getpwnam.c b/driver/vms-getpwnam.c new file mode 100644 index 00000000..ec0650c9 --- /dev/null +++ b/driver/vms-getpwnam.c @@ -0,0 +1,129 @@ +/* + * getpwnam(name) - retrieves a UAF entry + * + * Author: Patrick L. Mahan + * Location: TGV, Inc + * Date: 15-Nov-1991 + * + * Purpose: Provides emulation for the UNIX getpwname routine. + * + * Modification History + * + * Date | Who | Version | Reason + * ------------+-----------+---------------+--------------------------- + * 15-Nov-1991 | PLM | 1.0 | First Write + */ + +#define PASSWDROUTINES + +#include +#include +#include +#include +#include +#include +#include "vms-pwd.h" + +struct uic { + unsigned short uid; + unsigned short gid; +}; + +#define TEST(ptr, str) { if (ptr == NULL) { \ + fprintf(stderr, "getpwnam: memory allocation failure for \"%s\"\n", \ + str); \ + return ((struct passwd *)(NULL)); \ + } } + +struct passwd *getpwnam(name) +char *name; +{ + int istatus; + int UserNameLen; + int UserOwnerLen; + int UserDeviceLen; + int UserDirLen; + static char UserName[13]; + static char UserOwner[32]; + static char UserDevice[32]; + static char UserDir[64]; + char *cptr, *sptr; + unsigned long int UserPwd[2]; + unsigned short int UserSalt; + unsigned long int UserEncrypt; + struct uic UicValue; + struct passwd *entry; + + struct dsc$descriptor_s VMSNAME = + {strlen(name), DSC$K_DTYPE_T, DSC$K_CLASS_S, name}; + + struct itmlist3 { + unsigned short int length; + unsigned short int item; + unsigned long int addr; + unsigned long int retaddr; + } ItemList[] = { + {12, UAI$_USERNAME, (unsigned long)&UserName, (unsigned long)&UserNameLen}, + {8, UAI$_PWD, (unsigned long)&UserPwd, 0}, + {4, UAI$_UIC, (unsigned long)&UicValue, 0}, + {32, UAI$_OWNER, (unsigned long)&UserOwner, (unsigned long)&UserOwnerLen}, + {32, UAI$_DEFDEV, (unsigned long)&UserDevice, (unsigned long)&UserDeviceLen}, + {64, UAI$_DEFDIR, (unsigned long)&UserDir, (unsigned long)&UserDirLen}, + {2, UAI$_SALT, (unsigned long)&UserSalt, 0}, + {4, UAI$_ENCRYPT, (unsigned long)&UserEncrypt, 0}, + {0, 0, 0, 0} + }; + + UserNameLen = 0; + istatus = sys$getuai (0, 0, &VMSNAME, &ItemList, 0, 0, 0); + + if (!(istatus & 1)) { + fprintf (stderr, "getpwnam: unable to retrieve passwd entry for %s\n", + name); + fprintf (stderr, "getpwnam: vms error number is 0x%x\n", istatus); + return ((struct passwd *)NULL); + } + + entry = (struct passwd *) calloc (1, sizeof(struct passwd)); + TEST(entry, "PASSWD_ENTRY"); + + entry->pw_uid = UicValue.uid; + entry->pw_gid = UicValue.gid; + entry->pw_salt = UserSalt; + entry->pw_encrypt = UserEncrypt; + + sptr = UserName; + cptr = calloc (UserNameLen+1, sizeof(char)); + TEST(cptr, "USERNAME"); + strncpy (cptr, sptr, UserNameLen); + cptr[UserNameLen] = '\0'; + entry->pw_name = cptr; + + cptr = calloc(8, sizeof(char)); + TEST(cptr, "PASSWORD"); + memcpy(cptr, UserPwd, 8); + entry->pw_passwd = cptr; + + sptr = UserOwner; sptr++; + cptr = calloc ((int)UserOwner[0]+1, sizeof(char)); + TEST(cptr, "FULLNAME"); + strncpy (cptr, sptr, (int)UserOwner[0]); + cptr[(int)UserOwner[0]] = '\0'; + entry->pw_gecos = cptr; + + cptr = calloc ((int)UserDevice[0]+(int)UserDir[0]+1, sizeof(char)); + TEST(cptr, "HOME"); + sptr = UserDevice; sptr++; + strncpy (cptr, sptr, (int)UserDevice[0]); + sptr = UserDir; sptr++; + strncat (cptr, sptr, (int)UserDir[0]); + cptr[(int)UserDevice[0]+(int)UserDir[0]] = '\0'; + entry->pw_dir = cptr; + + cptr = calloc (strlen("SYS$SYSTEM:LOGINOUT.EXE")+1, sizeof(char)); + TEST(cptr,"SHELL"); + strcpy (cptr, "SYS$SYSTEM:LOGINOUT.EXE"); + entry->pw_shell = cptr; + + return (entry); +} diff --git a/driver/vms-hpwd.c b/driver/vms-hpwd.c new file mode 100644 index 00000000..707e3ea5 --- /dev/null +++ b/driver/vms-hpwd.c @@ -0,0 +1,75 @@ +/* + * VAX/VMS Password hashing routines: + * + * uses the System Service SYS$HASH_PASSWORD + * + * 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. + * + */ + +#include +#include +#include +#include +/* + * Hashing routine + */ +hash_vms_password(output_buf,input_buf,input_length,username,encryption_type,salt) +char *output_buf; +char *input_buf; +int input_length; +char *username; +int encryption_type; +unsigned short salt; +{ + struct dsc$descriptor_s password; + struct dsc$descriptor_s user; + + /* + * Check the VMS Version. If this is V5.4 or later, then + * we can use the new system service SYS$HASH_PASSWORD. Else + * fail and return garbage. + */ + + static char VMS_Version[32]; + struct { + unsigned short int Size; + unsigned short int Code; + char *Buffer; + unsigned short int *Resultant_Size; + } Item_List[2]={32, SYI$_VERSION, VMS_Version, 0, 0, 0}; + struct {int Size; char *Ptr;} Descr1; + + /* + * Get the information + */ + sys$getsyiw(0,0,0,Item_List,0,0,0); + /* + * Call the old routine if this isn't V5.4 or later... + */ +#ifndef __DECC + if ((VMS_Version[1] < '5') || + ((VMS_Version[1] == '5') && (VMS_Version[3] < '4'))) { + printf("Unsupported OS version\n"); + return(1); + } +#endif /* !__DECC */ + /* + * Call the SYS$HASH_PASSWORD system service... + */ + password.dsc$b_dtype = DSC$K_DTYPE_T; + password.dsc$b_class = DSC$K_CLASS_S; + password.dsc$w_length = input_length; + password.dsc$a_pointer = input_buf; + user.dsc$b_dtype = DSC$K_DTYPE_T; + user.dsc$b_class = DSC$K_CLASS_S; + user.dsc$w_length = strlen(username); + user.dsc$a_pointer = username; + sys$hash_password (&password, encryption_type, salt, &user, output_buf); +} diff --git a/driver/vms-pwd.h b/driver/vms-pwd.h new file mode 100644 index 00000000..6cb73d3e --- /dev/null +++ b/driver/vms-pwd.h @@ -0,0 +1,48 @@ +/* @(#)pwd.h 1.7 89/08/24 SMI; from S5R2 1.1 */ + +#ifndef __pwd_h +#define __pwd_h + +#ifdef vax11c +#include +#else +#include +#endif /* vax11c */ + +#ifdef PASSWDROUTINES +#define EXTERN +#else +#define EXTERN extern +#endif /* PASSWDROUTINES */ + +struct passwd { + char *pw_name; + char *pw_passwd; + int pw_uid; + int pw_gid; + short pw_salt; + int pw_encrypt; + char *pw_age; + char *pw_comment; + char *pw_gecos; + char *pw_dir; + char *pw_shell; +}; + + +#ifndef _POSIX_SOURCE +extern struct passwd *getpwent(); + +struct comment { + char *c_dept; + char *c_name; + char *c_acct; + char *c_bin; +}; + +#endif + +EXTERN struct passwd *getpwuid(/* uid_t uid */); +EXTERN struct passwd *getpwnam(/* char *name */); + +#endif /* !__pwd_h */ diff --git a/driver/vms-validate.c b/driver/vms-validate.c new file mode 100644 index 00000000..8f7141d6 --- /dev/null +++ b/driver/vms-validate.c @@ -0,0 +1,75 @@ +/* + * validate a password for a user + * + * 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. + */ + +/* + * Includes + */ +#include +#include +#include + +#include "vms-pwd.h" +int hash_vms_password(char *output_buf,char *input_buf,int input_length, + char *username,int encryption_type,unsigned short salt); + +/* + * + * Validate a VMS UserName/Password pair. + * + */ + +int validate_user(name,password) +char *name; +char *password; +{ + char password_buf[64]; + char username_buf[31]; + char encrypt_buf[8]; + register int i; + register char *cp,*cp1; + struct passwd *user_entry; + + /* + * Get the users UAF entry + */ + user_entry = getpwnam(name); + + /* + * If user_entry == NULL then we got a bad error + * return -1 to indicate a bad error + */ + if (user_entry == NULL) return (-1); + + /* + * Uppercase the password + */ + cp = password; + cp1 = password_buf; + while (*cp) + if (islower(*cp)) + *cp1++ = toupper(*cp++); + else + *cp1++ = *cp++; + /* + * Get the length of the password + */ + i = strlen(password); + /* + * Encrypt the password + */ + hash_vms_password(encrypt_buf,password_buf,i,user_entry->pw_name, + user_entry->pw_encrypt, user_entry->pw_salt); + if (memcmp(encrypt_buf,user_entry->pw_passwd,8) == 0) + return(1); + else return(0); +} + diff --git a/driver/vms_axp.opt b/driver/vms_axp.opt new file mode 100644 index 00000000..04d465df --- /dev/null +++ b/driver/vms_axp.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_AXP/LIB +SYS$SHARE:DECW$XMLIBSHR.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHR.EXE/SHARE +SYS$SHARE:DECW$XTSHR.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/vms_axp_12.opt b/driver/vms_axp_12.opt new file mode 100644 index 00000000..25dd1f18 --- /dev/null +++ b/driver/vms_axp_12.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_AXP/LIB +SYS$SHARE:DECW$XMLIBSHR12.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XTLIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/vms_decc.opt b/driver/vms_decc.opt new file mode 100644 index 00000000..65bec033 --- /dev/null +++ b/driver/vms_decc.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_DECC/LIB +SYS$SHARE:DECW$XMLIBSHR.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHR.EXE/SHARE +SYS$SHARE:DECW$XTSHR.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/vms_decc_12.opt b/driver/vms_decc_12.opt new file mode 100644 index 00000000..fdd9a802 --- /dev/null +++ b/driver/vms_decc_12.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_DECC/LIB +SYS$SHARE:DECW$XMLIBSHR12.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XTLIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/windows.c b/driver/windows.c new file mode 100644 index 00000000..ded26972 --- /dev/null +++ b/driver/windows.c @@ -0,0 +1,1538 @@ +/* windows.c --- turning the screen black; dealing with visuals, virtual roots. + * xscreensaver, Copyright (c) 1991-1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef VMS +# include /* for getpid() */ +# include "vms-gtod.h" /* for gettimeofday() */ +#endif /* VMS */ + +#ifndef VMS +# include /* for getpwuid() */ +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + +#ifdef HAVE_UNAME +# include /* for uname() */ +#endif /* HAVE_UNAME */ + +#include +#include /* for CARD32 */ +#include +#include /* for XSetClassHint() */ +#include +#include /* for time() */ +#include /* for the signal names */ + +#ifdef HAVE_MIT_SAVER_EXTENSION +# include +#endif /* HAVE_MIT_SAVER_EXTENSION */ + +#ifdef HAVE_XF86VMODE +# include +#endif /* HAVE_XF86VMODE */ + + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" +#include "visual.h" +#include "fade.h" + + +extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ + +Atom XA_VROOT, XA_XSETROOT_ID; +Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID; +Atom XA_SCREENSAVER_TIME; + + +extern saver_info *global_si_kludge; /* I hate C so much... */ + + +static void store_activate_time (saver_info *si, Bool use_last_p); + +#define ALL_POINTER_EVENTS \ + (ButtonPressMask | ButtonReleaseMask | EnterWindowMask | \ + LeaveWindowMask | PointerMotionMask | PointerMotionHintMask | \ + Button1MotionMask | Button2MotionMask | Button3MotionMask | \ + Button4MotionMask | Button5MotionMask | ButtonMotionMask) + + +static const char * +grab_string(int status) +{ + switch (status) + { + case GrabSuccess: return "GrabSuccess"; + case AlreadyGrabbed: return "AlreadyGrabbed"; + case GrabInvalidTime: return "GrabInvalidTime"; + case GrabNotViewable: return "GrabNotViewable"; + case GrabFrozen: return "GrabFrozen"; + default: + { + static char foo[255]; + sprintf(foo, "unknown status: %d", status); + return foo; + } + } +} + +static int +grab_kbd(saver_info *si, Window w) +{ + saver_preferences *p = &si->prefs; + int status = XGrabKeyboard (si->dpy, w, True, + /* I don't really understand Sync vs Async, + but these seem to work... */ + GrabModeSync, GrabModeAsync, + CurrentTime); + if (status == GrabSuccess) + si->keyboard_grab_window = w; + + if (p->verbose_p) + fprintf(stderr, "%s: grabbing keyboard on 0x%x... %s.\n", + blurb(), (unsigned long) w, grab_string(status)); + return status; +} + + +static int +grab_mouse (saver_info *si, Window w, Cursor cursor) +{ + saver_preferences *p = &si->prefs; + int status = XGrabPointer (si->dpy, w, True, ALL_POINTER_EVENTS, + GrabModeAsync, GrabModeAsync, w, + cursor, CurrentTime); + if (status == GrabSuccess) + si->mouse_grab_window = w; + + if (p->verbose_p) + fprintf(stderr, "%s: grabbing mouse on 0x%x... %s.\n", + blurb(), (unsigned long) w, grab_string(status)); + return status; +} + + +static void +ungrab_kbd(saver_info *si) +{ + saver_preferences *p = &si->prefs; + XUngrabKeyboard(si->dpy, CurrentTime); + if (p->verbose_p) + fprintf(stderr, "%s: ungrabbing keyboard (was 0x%x).\n", blurb(), + (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->verbose_p) + fprintf(stderr, "%s: ungrabbing mouse (was 0x%x).\n", blurb(), + (unsigned long) si->mouse_grab_window); + si->mouse_grab_window = 0; +} + + +static Bool +grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor) +{ + Status mstatus, kstatus; + XSync (si->dpy, False); + + kstatus = grab_kbd (si, window); + if (kstatus != GrabSuccess) + { /* try again in a second */ + sleep (1); + kstatus = grab_kbd (si, window); + if (kstatus != GrabSuccess) + fprintf (stderr, "%s: couldn't grab keyboard! (%s)\n", + blurb(), grab_string(kstatus)); + } + + mstatus = grab_mouse (si, window, cursor); + if (mstatus != GrabSuccess) + { /* try again in a second */ + sleep (1); + mstatus = grab_mouse (si, window, cursor); + if (mstatus != GrabSuccess) + fprintf (stderr, "%s: couldn't grab pointer! (%s)\n", + blurb(), grab_string(mstatus)); + } + + return (kstatus == GrabSuccess || + mstatus == GrabSuccess); +} + +static void +ungrab_keyboard_and_mouse (saver_info *si) +{ + ungrab_mouse (si); + ungrab_kbd (si); +} + + +int +move_mouse_grab (saver_info *si, Window to, Cursor cursor) +{ + Window old = si->mouse_grab_window; + + if (old == 0) + return grab_mouse (si, to, cursor); + else + { + saver_preferences *p = &si->prefs; + int status; + + XSync (si->dpy, False); + XGrabServer (si->dpy); /* ############ DANGER! */ + XSync (si->dpy, False); + + if (p->verbose_p) + fprintf(stderr, "%s: grabbing server...\n", blurb()); + + ungrab_mouse (si); + status = grab_mouse (si, to, cursor); + + if (status != GrabSuccess) /* Augh! */ + { + sleep (1); /* Note dramatic evil of sleeping + with server grabbed. */ + XSync (si->dpy, False); + status = grab_mouse (si, to, cursor); + } + + if (status != GrabSuccess) /* Augh! Try to get the old one back... */ + grab_mouse (si, to, cursor); + + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + + if (p->verbose_p) + fprintf(stderr, "%s: ungrabbing server.\n", blurb()); + + return status; + } +} + + +/* 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; + unsigned int nkids; + XErrorHandler old_handler = XSetErrorHandler (BadWindow_ehandler); + + if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids)) + abort (); + if (root != root2) + abort (); + if (parent) + abort (); + for (i = 0; i < nkids; i++) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + char *version; + + if (XGetWindowProperty (dpy, kids[i], XA_SCREENSAVER_VERSION, 0, 1, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, (unsigned char **) &version) + == Success + && type != None) + { + char *id; + if (!XGetWindowProperty (dpy, kids[i], XA_SCREENSAVER_ID, 0, 512, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, (unsigned char **) &id) + == Success + || type == None) + id = "???"; + + fprintf (stderr, + "%s: already running on display %s (window 0x%x)\n from process %s.\n", + blurb(), DisplayString (dpy), (int) kids [i], id); + status = True; + } + } + + if (kids) XFree ((char *) kids); + XSync (dpy, False); + XSetErrorHandler (old_handler); + return status; +} + + + +/* Virtual-root hackery */ + +#ifdef _VROOT_H_ +ERROR! You must not include vroot.h in this file. +#endif + +static void +store_vroot_property (Display *dpy, Window win, Window value) +{ +#if 0 + if (p->verbose_p) + fprintf (stderr, + "%s: storing XA_VROOT = 0x%x (%s) = 0x%x (%s)\n", blurb(), + win, + (win == screensaver_window ? "ScreenSaver" : + (win == real_vroot ? "VRoot" : + (win == real_vroot_value ? "Vroot_value" : "???"))), + value, + (value == screensaver_window ? "ScreenSaver" : + (value == real_vroot ? "VRoot" : + (value == real_vroot_value ? "Vroot_value" : "???")))); +#endif + XChangeProperty (dpy, win, XA_VROOT, XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &value, 1); +} + +static void +remove_vroot_property (Display *dpy, Window win) +{ +#if 0 + if (p->verbose_p) + fprintf (stderr, "%s: removing XA_VROOT from 0x%x (%s)\n", blurb(), win, + (win == screensaver_window ? "ScreenSaver" : + (win == real_vroot ? "VRoot" : + (win == real_vroot_value ? "Vroot_value" : "???")))); +#endif + XDeleteProperty (dpy, win, XA_VROOT); +} + + +static void +kill_xsetroot_data (Display *dpy, Window window, Bool verbose_p) +{ + Atom type; + int format; + unsigned long nitems, bytesafter; + Pixmap *dataP = 0; + + /* If the user has been using xv or xsetroot as a screensaver (to display + an image on the screensaver window, as a kind of slideshow) then the + pixmap and its associated color cells have been put in RetainPermanent + CloseDown mode. Since we're not destroying the xscreensaver window, + but merely unmapping it, we need to free these resources or those + colormap cells will stay allocated while the screensaver is off. (We + could just delete the screensaver window and recreate it later, but + that could cause other problems.) This code does an atomic read-and- + delete of the _XSETROOT_ID property, and if it held a pixmap, then we + cause the RetainPermanent resources of the client which created it + (and which no longer exists) to be freed. + */ + if (XGetWindowProperty (dpy, window, XA_XSETROOT_ID, 0, 1, + True, AnyPropertyType, &type, &format, &nitems, + &bytesafter, (unsigned char **) &dataP) + == Success + && type != None) + { + if (dataP && *dataP && type == XA_PIXMAP && format == 32 && + nitems == 1 && bytesafter == 0) + { + if (verbose_p) + fprintf (stderr, "%s: destroying xsetroot data (0x%lX).\n", + blurb(), *dataP); + XKillClient (dpy, *dataP); + } + else + fprintf (stderr, "%s: deleted unrecognised _XSETROOT_ID property: \n\ + %lu, %lu; type: %lu, format: %d, nitems: %lu, bytesafter %ld\n", + blurb(), (unsigned long) dataP, (dataP ? *dataP : 0), type, + format, nitems, bytesafter); + } +} + + +static void handle_signals (saver_info *si, Bool on_p); + +static void +save_real_vroot (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + Display *dpy = si->dpy; + Screen *screen = ssi->screen; + int i; + Window root = RootWindowOfScreen (screen); + Window root2, parent, *kids; + unsigned int nkids; + XErrorHandler old_handler; + + /* It's possible that a window might be deleted between our call to + XQueryTree() and our call to XGetWindowProperty(). Don't die if + that happens (but just ignore that window, it's not the one we're + interested in anyway.) + */ + XSync (dpy, False); + old_handler = XSetErrorHandler (BadWindow_ehandler); + XSync (dpy, False); + + ssi->real_vroot = 0; + ssi->real_vroot_value = 0; + if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids)) + abort (); + if (root != root2) + abort (); + if (parent) + abort (); + for (i = 0; i < nkids; i++) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + Window *vrootP = 0; + + if (XGetWindowProperty (dpy, kids[i], XA_VROOT, 0, 1, False, XA_WINDOW, + &type, &format, &nitems, &bytesafter, + (unsigned char **) &vrootP) + != Success) + continue; + if (! vrootP) + continue; + if (ssi->real_vroot) + { + if (*vrootP == ssi->screensaver_window) abort (); + fprintf (stderr, + "%s: more than one virtual root window found (0x%x and 0x%x).\n", + blurb(), (int) ssi->real_vroot, (int) kids [i]); + exit (1); + } + ssi->real_vroot = kids [i]; + ssi->real_vroot_value = *vrootP; + } + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + if (ssi->real_vroot) + { + handle_signals (si, True); + remove_vroot_property (si->dpy, ssi->real_vroot); + XSync (dpy, False); + } + + XFree ((char *) kids); +} + + +static Bool +restore_real_vroot_2 (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + if (p->verbose_p && ssi->real_vroot) + fprintf (stderr, + "%s: restoring __SWM_VROOT property on the real vroot (0x%lx).\n", + blurb(), (unsigned long) ssi->real_vroot); + remove_vroot_property (si->dpy, ssi->screensaver_window); + if (ssi->real_vroot) + { + store_vroot_property (si->dpy, ssi->real_vroot, ssi->real_vroot_value); + ssi->real_vroot = 0; + ssi->real_vroot_value = 0; + /* make sure the property change gets there before this process + terminates! We might be doing this because we have intercepted + SIGTERM or something. */ + XSync (si->dpy, False); + return True; + } + return False; +} + +static Bool +restore_real_vroot_1 (saver_info *si) +{ + int i; + Bool did_any = False; + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (restore_real_vroot_2 (ssi)) + did_any = True; + } + return did_any; +} + +void +restore_real_vroot (saver_info *si) +{ + if (restore_real_vroot_1 (si)) + handle_signals (si, False); +} + + +/* Signal hackery to ensure that the vroot doesn't get left in an + inconsistent state + */ + +const char * +signal_name(int signal) +{ + switch (signal) { + case SIGHUP: return "SIGHUP"; + case SIGINT: return "SIGINT"; + case SIGQUIT: return "SIGQUIT"; + case SIGILL: return "SIGILL"; + case SIGTRAP: return "SIGTRAP"; +#ifdef SIGABRT + case SIGABRT: return "SIGABRT"; +#endif + case SIGFPE: return "SIGFPE"; + case SIGKILL: return "SIGKILL"; + case SIGBUS: return "SIGBUS"; + case SIGSEGV: return "SIGSEGV"; + case SIGPIPE: return "SIGPIPE"; + case SIGALRM: return "SIGALRM"; + case SIGTERM: return "SIGTERM"; +#ifdef SIGSTOP + case SIGSTOP: return "SIGSTOP"; +#endif +#ifdef SIGCONT + case SIGCONT: return "SIGCONT"; +#endif +#ifdef SIGUSR1 + case SIGUSR1: return "SIGUSR1"; +#endif +#ifdef SIGUSR2 + case SIGUSR2: return "SIGUSR2"; +#endif +#ifdef SIGEMT + case SIGEMT: return "SIGEMT"; +#endif +#ifdef SIGSYS + case SIGSYS: return "SIGSYS"; +#endif +#ifdef SIGCHLD + case SIGCHLD: return "SIGCHLD"; +#endif +#ifdef SIGPWR + case SIGPWR: return "SIGPWR"; +#endif +#ifdef SIGWINCH + case SIGWINCH: return "SIGWINCH"; +#endif +#ifdef SIGURG + case SIGURG: return "SIGURG"; +#endif +#ifdef SIGIO + case SIGIO: return "SIGIO"; +#endif +#ifdef SIGVTALRM + case SIGVTALRM: return "SIGVTALRM"; +#endif +#ifdef SIGXCPU + case SIGXCPU: return "SIGXCPU"; +#endif +#ifdef SIGXFSZ + case SIGXFSZ: return "SIGXFSZ"; +#endif +#ifdef SIGDANGER + case SIGDANGER: return "SIGDANGER"; +#endif + default: + { + static char buf[50]; + sprintf(buf, "signal %d\n", signal); + return buf; + } + } +} + + + +static RETSIGTYPE +restore_real_vroot_handler (int sig) +{ + saver_info *si = global_si_kludge; /* I hate C so much... */ + + signal (sig, SIG_DFL); + if (restore_real_vroot_1 (si)) + fprintf (real_stderr, "\n%s: %s intercepted, vroot restored.\n", + blurb(), signal_name(sig)); + kill (getpid (), sig); +} + +static void +catch_signal (saver_info *si, int sig, Bool on_p) +{ + if (! on_p) + signal (sig, SIG_DFL); + else + { + if (((long) signal (sig, restore_real_vroot_handler)) == -1L) + { + char buf [255]; + sprintf (buf, "%s: couldn't catch %s", blurb(), signal_name(sig)); + perror (buf); + saver_exit (si, 1, 0); + } + } +} + +static void +handle_signals (saver_info *si, Bool on_p) +{ +#if 0 + if (on_p) fprintf (stderr, "handling signals\n"); + else fprintf (stderr, "unhandling signals\n"); +#endif + + catch_signal (si, SIGHUP, on_p); + catch_signal (si, SIGINT, on_p); + catch_signal (si, SIGQUIT, on_p); + catch_signal (si, SIGILL, on_p); + catch_signal (si, SIGTRAP, on_p); + catch_signal (si, SIGIOT, on_p); + catch_signal (si, SIGABRT, on_p); +#ifdef SIGEMT + catch_signal (si, SIGEMT, on_p); +#endif + catch_signal (si, SIGFPE, on_p); + catch_signal (si, SIGBUS, on_p); + catch_signal (si, SIGSEGV, on_p); +#ifdef SIGSYS + catch_signal (si, SIGSYS, on_p); +#endif + catch_signal (si, SIGTERM, on_p); +#ifdef SIGXCPU + catch_signal (si, SIGXCPU, on_p); +#endif +#ifdef SIGXFSZ + catch_signal (si, SIGXFSZ, on_p); +#endif +#ifdef SIGDANGER + catch_signal (si, SIGDANGER, on_p); +#endif +} + +void +saver_exit (saver_info *si, int status, const char *dump_core_reason) +{ + saver_preferences *p = &si->prefs; + static Bool exiting = False; + Bool bugp; + Bool vrs; + + if (exiting) + exit(status); + + exiting = True; + + vrs = restore_real_vroot_1 (si); + emergency_kill_subproc (si); + + if (vrs && (p->verbose_p || status != 0)) + fprintf (real_stderr, "%s: vroot restored, exiting.\n", blurb()); + else if (p->verbose_p) + fprintf (real_stderr, "%s: no vroot to restore; exiting.\n", blurb()); + + fflush(real_stdout); + +#ifdef VMS /* on VMS, 1 is the "normal" exit code instead of 0. */ + if (status == 0) status = 1; + else if (status == 1) status = -1; +#endif + + bugp = !!dump_core_reason; + + if (si->prefs.debug_p && !dump_core_reason) + dump_core_reason = "because of -debug"; + + if (dump_core_reason) + { + /* Note that the Linux man page for setuid() says If uid is + different from the old effective uid, the process will be + forbidden from leaving core dumps. + */ + char cwd[4096]; /* should really be PATH_MAX, but who cares. */ + cwd[0] = 0; + fprintf(real_stderr, "%s: dumping core (%s)\n", blurb(), + dump_core_reason); + + if (bugp) + fprintf(real_stderr, + "%s: see http://www.jwz.org/xscreensaver/bugs.html\n" + "\t\tfor bug reporting information.\n\n", + blurb()); + +# if defined(HAVE_GETCWD) + if (!getcwd (cwd, sizeof(cwd))) +# elif defined(HAVE_GETWD) + if (!getwd (cwd)) +# endif + strcpy(cwd, "unknown."); + + fprintf (real_stderr, "%s: current directory is %s\n", blurb(), cwd); + describe_uids (si, real_stderr); + + /* Do this to drop a core file, so that we can get a stack trace. */ + abort(); + } + + exit (status); +} + + +/* Managing the actual screensaver window */ + +Bool +window_exists_p (Display *dpy, Window window) +{ + XErrorHandler old_handler; + XWindowAttributes xgwa; + xgwa.screen = 0; + old_handler = XSetErrorHandler (BadWindow_ehandler); + XGetWindowAttributes (dpy, window, &xgwa); + XSync (dpy, False); + XSetErrorHandler (old_handler); + return (xgwa.screen != 0); +} + +static void +store_saver_id (saver_screen_info *ssi) +{ + XClassHint class_hints; + saver_info *si = ssi->global; + unsigned long pid = (unsigned long) getpid (); + char buf[20]; + struct passwd *p = getpwuid (getuid ()); + const char *name, *host; + char *id; + + /* First store the name and class on the window. + */ + class_hints.res_name = progname; + class_hints.res_class = progclass; + XSetClassHint (si->dpy, ssi->screensaver_window, &class_hints); + XStoreName (si->dpy, ssi->screensaver_window, "screensaver"); + + /* Then store the xscreensaver version number. + */ + XChangeProperty (si->dpy, ssi->screensaver_window, + XA_SCREENSAVER_VERSION, + XA_STRING, 8, PropModeReplace, + (unsigned char *) si->version, + strlen (si->version)); + + /* Now store the XSCREENSAVER_ID property, that says what user and host + xscreensaver is running as. + */ + + if (p && p->pw_name && *p->pw_name) + name = p->pw_name; + else if (p) + { + sprintf (buf, "%lu", (unsigned long) p->pw_uid); + name = buf; + } + else + name = "???"; + +# if defined(HAVE_UNAME) + { + struct utsname uts; + if (uname (&uts) < 0) + host = "???"; + else + host = uts.nodename; + } +# elif defined(VMS) + host = getenv("SYS$NODE"); +# else /* !HAVE_UNAME && !VMS */ + host = "???"; +# endif /* !HAVE_UNAME && !VMS */ + + id = (char *) malloc (strlen(name) + strlen(host) + 50); + sprintf (id, "%lu (%s@%s)", pid, name, host); + + XChangeProperty (si->dpy, ssi->screensaver_window, + XA_SCREENSAVER_ID, XA_STRING, + 8, PropModeReplace, + (unsigned char *) id, strlen (id)); + free (id); +} + + +/* Returns the area of the screen which the xscreensaver window should cover. + Normally this is the whole screen, but if the X server's root window is + actually larger than the monitor's displayable area, then we want to + operate in the currently-visible portion of the desktop instead. + */ +void +get_screen_viewport (saver_screen_info *ssi, + int *x_ret, int *y_ret, + int *w_ret, int *h_ret, + Bool verbose_p) +{ + int w = WidthOfScreen (ssi->screen); + int h = HeightOfScreen (ssi->screen); + +#ifdef HAVE_XF86VMODE + saver_info *si = ssi->global; + int screen_no = screen_number (ssi->screen); + int event, error; + int dot; + XF86VidModeModeLine ml; + int x, y; + + if (XF86VidModeQueryExtension (si->dpy, &event, &error) && + XF86VidModeGetModeLine (si->dpy, screen_no, &dot, &ml) && + XF86VidModeGetViewPort (si->dpy, screen_no, &x, &y)) + { + char msg[512]; + *x_ret = x; + *y_ret = y; + *w_ret = ml.hdisplay; + *h_ret = ml.vdisplay; + + if (*x_ret == 0 && *y_ret == 0 && *w_ret == w && *h_ret == h) + /* There is no viewport -- the screen does not scroll. */ + return; + + sprintf (msg, "%s: vp is %dx%d+%d+%d", + blurb(), *w_ret, *h_ret, *x_ret, *y_ret); + + + /* Apparently, though the server stores the X position in increments of + 1 pixel, it will only make changes to the *display* in some other + increment. With XF86_SVGA on a Thinkpad, the display only updates + in multiples of 8 pixels when in 8-bit mode, and in multiples of 4 + pixels in 16-bit mode. I don't know what it does in 24- and 32-bit + mode, because I don't have enough video memory to find out. + + I consider it a bug that XF86VidModeGetViewPort() is telling me the + server's *target* scroll position rather than the server's *actual* + scroll position. David Dawes agrees, and says they may fix this in + XFree86 4.0, but it's notrivial. + + He also confirms that this behavior is server-dependent, so the + actual scroll position cannot be reliably determined by the client. + So... that means the only solution is to provide a ``sandbox'' + around the blackout window -- we make the window be up to N pixels + larger than the viewport on both the left and right sides. That + means some part of the outer edges of each hack might not be + visible, but screw it. + + I'm going to guess that 16 pixels is enough, and that the Y dimension + doesn't have this problem. + + The drawback of doing this, of course, is that some of the screenhacks + will still look pretty stupid -- for example, "slidescreen" will cut + off the left and right edges of the grid, etc. + */ +# define FUDGE 16 + if (x > 0 && x < w - ml.hdisplay) /* not at left edge or right edge */ + { + /* Round X position down to next lower multiple of FUDGE. + Increase width by 2*FUDGE in case some server rounds up. + */ + *x_ret = ((x - 1) / FUDGE) * FUDGE; + *w_ret += (FUDGE * 2); + } +# undef FUDGE + + if (*x_ret != x || + *y_ret != y || + *w_ret != ml.hdisplay || + *h_ret != ml.vdisplay) + sprintf (msg + strlen(msg), "; fudged to %dx%d+%d+%d", + *w_ret, *h_ret, *x_ret, *y_ret); + + if (verbose_p) + fprintf (stderr, "%s.\n", msg); + + return; + } + +#endif /* HAVE_XF86VMODE */ + + *x_ret = 0; + *y_ret = 0; + *w_ret = w; + *h_ret = h; +} + + +static void +initialize_screensaver_window_1 (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + Bool install_cmap_p = ssi->install_cmap_p; /* not p->install_cmap_p */ + + /* This resets the screensaver window as fully as possible, since there's + no way of knowing what some random client may have done to us in the + meantime. We could just destroy and recreate the window, but that has + its own set of problems... + */ + XColor black; + XSetWindowAttributes attrs; + unsigned long attrmask; + int x, y, width, height; + static Bool printed_visual_info = False; /* only print the message once. */ + + get_screen_viewport (ssi, &x, &y, &width, &height, + (p->verbose_p && !si->screen_blanked_p)); + + black.red = black.green = black.blue = 0; + + if (ssi->cmap == DefaultColormapOfScreen (ssi->screen)) + ssi->cmap = 0; + + if (ssi->current_visual != DefaultVisualOfScreen (ssi->screen)) + /* It's not the default visual, so we have no choice but to install. */ + install_cmap_p = True; + + if (install_cmap_p) + { + if (! ssi->cmap) + { + ssi->cmap = XCreateColormap (si->dpy, + RootWindowOfScreen (ssi->screen), + ssi->current_visual, AllocNone); + if (! XAllocColor (si->dpy, ssi->cmap, &black)) abort (); + ssi->black_pixel = black.pixel; + } + } + else + { + Colormap def_cmap = DefaultColormapOfScreen (ssi->screen); + if (ssi->cmap) + { + XFreeColors (si->dpy, ssi->cmap, &ssi->black_pixel, 1, 0); + if (ssi->cmap != ssi->demo_cmap && + ssi->cmap != def_cmap) + XFreeColormap (si->dpy, ssi->cmap); + } + ssi->cmap = def_cmap; + ssi->black_pixel = BlackPixelOfScreen (ssi->screen); + } + + attrmask = (CWOverrideRedirect | CWEventMask | CWBackingStore | CWColormap | + CWBackPixel | CWBackingPixel | CWBorderPixel); + attrs.override_redirect = True; + + /* When use_mit_saver_extension or use_sgi_saver_extension is true, we won't + actually be reading these events during normal operation; but we still + need to see Button events for demo-mode to work properly. + */ + attrs.event_mask = (KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask); + + attrs.backing_store = NotUseful; + attrs.colormap = ssi->cmap; + attrs.background_pixel = ssi->black_pixel; + attrs.backing_pixel = ssi->black_pixel; + attrs.border_pixel = ssi->black_pixel; + + if (p->debug_p) width = width / 2; + + if (!p->verbose_p || printed_visual_info) + ; + else if (ssi->current_visual == DefaultVisualOfScreen (ssi->screen)) + { + fprintf (stderr, "%s: using default visual ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + install_cmap_p); + } + else + { + fprintf (stderr, "%s: using visual: ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + install_cmap_p); + fprintf (stderr, "%s: default visual: ", blurb()); + describe_visual (stderr, ssi->screen, + DefaultVisualOfScreen (ssi->screen), + ssi->install_cmap_p); + } + printed_visual_info = True; + +#ifdef HAVE_MIT_SAVER_EXTENSION + if (si->using_mit_saver_extension) + { + XScreenSaverInfo *info; + Window root = RootWindowOfScreen (ssi->screen); + +#if 0 + /* This call sets the server screensaver timeouts to what we think + they should be (based on the resources and args xscreensaver was + started with.) It's important that we do this to sync back up + with the server - if we have turned on prematurely, as by an + ACTIVATE ClientMessage, then the server may decide to activate + the screensaver while it's already active. That's ok for us, + since we would know to ignore that ScreenSaverActivate event, + but a side effect of this would be that the server would map its + saver window (which we then hide again right away) meaning that + the bits currently on the screen get blown away. Ugly. */ + + /* #### Ok, that doesn't work - when we tell the server that the + screensaver is "off" it sends us a Deactivate event, which is + sensible... but causes the saver to never come on. Hmm. */ + disable_builtin_screensaver (si, True); +#endif /* 0 */ + +#if 0 + /* #### The MIT-SCREEN-SAVER extension gives us access to the + window that the server itself uses for saving the screen. + However, using this window in any way, in particular, calling + XScreenSaverSetAttributes() as below, tends to make the X server + crash. So fuck it, let's try and get along without using it... + + It's also inconvenient to use this window because it doesn't + always exist (though the ID is constant.) So to use this + window, we'd have to reimplement the ACTIVATE ClientMessage to + tell the *server* to tell *us* to turn on, to cause the window + to get created at the right time. Gag. */ + XScreenSaverSetAttributes (si->dpy, root, + 0, 0, width, height, 0, + current_depth, InputOutput, visual, + attrmask, &attrs); + XSync (si->dpy, False); +#endif /* 0 */ + + info = XScreenSaverAllocInfo (); + XScreenSaverQueryInfo (si->dpy, root, info); + ssi->server_mit_saver_window = info->window; + if (! ssi->server_mit_saver_window) abort (); + XFree (info); + } +#endif /* HAVE_MIT_SAVER_EXTENSION */ + + if (ssi->screensaver_window) + { + XWindowChanges changes; + unsigned int changesmask = CWX|CWY|CWWidth|CWHeight|CWBorderWidth; + changes.x = x; + changes.y = y; + changes.width = width; + changes.height = height; + changes.border_width = 0; + + XConfigureWindow (si->dpy, ssi->screensaver_window, + changesmask, &changes); + XChangeWindowAttributes (si->dpy, ssi->screensaver_window, + attrmask, &attrs); + } + else + { + ssi->screensaver_window = + XCreateWindow (si->dpy, RootWindowOfScreen (ssi->screen), + x, y, width, height, + 0, ssi->current_depth, InputOutput, + ssi->current_visual, attrmask, &attrs); + + reset_stderr (ssi); + store_activate_time(si, True); + if (p->verbose_p) + fprintf (stderr, "%s: saver window is 0x%lx.\n", + blurb(), (unsigned long) ssi->screensaver_window); + } + + + store_saver_id (ssi); + + if (!ssi->cursor) + { + Pixmap bit; + bit = XCreatePixmapFromBitmapData (si->dpy, ssi->screensaver_window, + "\000", 1, 1, + BlackPixelOfScreen (ssi->screen), + BlackPixelOfScreen (ssi->screen), + 1); + ssi->cursor = XCreatePixmapCursor (si->dpy, bit, bit, &black, &black, + 0, 0); + XFreePixmap (si->dpy, bit); + } + + XSetWindowBackground (si->dpy, ssi->screensaver_window, ssi->black_pixel); + + if (si->demoing_p) + XUndefineCursor (si->dpy, ssi->screensaver_window); + else + XDefineCursor (si->dpy, ssi->screensaver_window, ssi->cursor); +} + +void +initialize_screensaver_window (saver_info *si) +{ + int i; + for (i = 0; i < si->nscreens; i++) + initialize_screensaver_window_1 (&si->screens[i]); +} + + +void +raise_window (saver_info *si, + Bool inhibit_fade, Bool between_hacks_p, Bool dont_clear) +{ + saver_preferences *p = &si->prefs; + int i; + + if (si->demoing_p) + inhibit_fade = True; + + if (si->emergency_lock_p) + inhibit_fade = True; + + if (!dont_clear) + initialize_screensaver_window (si); + + reset_watchdog_timer (si, True); + + if (p->fade_p && si->fading_possible_p && !inhibit_fade) + { + Window *current_windows = (Window *) + calloc(sizeof(Window), si->nscreens); + Colormap *current_maps = (Colormap *) + calloc(sizeof(Colormap), si->nscreens); + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + current_windows[i] = ssi->screensaver_window; + current_maps[i] = (between_hacks_p + ? ssi->cmap + : DefaultColormapOfScreen (ssi->screen)); + /* Ensure that the default background of the window is really black, + not a pixmap or something. (This does not clear the window.) */ + XSetWindowBackground (si->dpy, ssi->screensaver_window, + ssi->black_pixel); + } + + if (p->verbose_p) fprintf (stderr, "%s: fading...\n", blurb()); + + XGrabServer (si->dpy); /* ############ DANGER! */ + + /* Clear the stderr layer on each screen. + */ + if (!dont_clear) + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->stderr_overlay_window) + /* Do this before the fade, since the stderr cmap won't fade + even if we uninstall it (beats me...) */ + 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/1000, p->fade_ticks, True, !dont_clear); + + free(current_maps); + free(current_windows); + current_maps = 0; + current_windows = 0; + + if (p->verbose_p) fprintf (stderr, "%s: fading done.\n", blurb()); + +#ifdef HAVE_MIT_SAVER_EXTENSION + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->server_mit_saver_window && + window_exists_p (si->dpy, ssi->server_mit_saver_window)) + XUnmapWindow (si->dpy, ssi->server_mit_saver_window); + } +#endif /* HAVE_MIT_SAVER_EXTENSION */ + + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + } + else + { + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (!dont_clear) + XClearWindow (si->dpy, ssi->screensaver_window); + if (!dont_clear || ssi->stderr_overlay_window) + clear_stderr (ssi); + XMapRaised (si->dpy, ssi->screensaver_window); +#ifdef HAVE_MIT_SAVER_EXTENSION + if (ssi->server_mit_saver_window && + window_exists_p (si->dpy, ssi->server_mit_saver_window)) + XUnmapWindow (si->dpy, ssi->server_mit_saver_window); +#endif /* HAVE_MIT_SAVER_EXTENSION */ + } + } + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->cmap) + XInstallColormap (si->dpy, ssi->cmap); + } +} + +Bool +blank_screen (saver_info *si) +{ + int i; + Bool ok; + + /* 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. + */ + ok = grab_keyboard_and_mouse (si, + /*si->screens[0].screensaver_window,*/ + RootWindowOfScreen(si->screens[0].screen), + (si->demoing_p + ? 0 + : si->screens[0].cursor)); + + + if (si->using_mit_saver_extension || si->using_sgi_saver_extension) + /* If we're using a server extension, then failure to get a grab is + not a big deal -- even without the grab, we will still be able + to un-blank when there is user activity, since the server will + tell us. */ + ok = True; + + if (!ok) + return False; + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + + save_real_vroot (ssi); + store_vroot_property (si->dpy, + ssi->screensaver_window, + ssi->screensaver_window); + +#ifdef HAVE_XF86VMODE + { + int ev, er; + if (!XF86VidModeQueryExtension (si->dpy, &ev, &er) || + !XF86VidModeGetViewPort (si->dpy, i, + &ssi->blank_vp_x, + &ssi->blank_vp_y)) + ssi->blank_vp_x = ssi->blank_vp_y = -1; + } +#endif /* HAVE_XF86VMODE */ + } + store_activate_time (si, si->screen_blanked_p); + raise_window (si, False, False, False); + + si->screen_blanked_p = True; + si->last_wall_clock_time = 0; + + return True; +} + +void +unblank_screen (saver_info *si) +{ + saver_preferences *p = &si->prefs; + Bool unfade_p = (si->fading_possible_p && p->unfade_p); + int i; + + monitor_power_on (si); + + store_activate_time (si, True); + reset_watchdog_timer (si, False); + + if (si->demoing_p) + unfade_p = False; + + if (unfade_p) + { + Window *current_windows = (Window *) + calloc(sizeof(Window), si->nscreens); + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + current_windows[i] = ssi->screensaver_window; + /* Ensure that the default background of the window is really black, + not a pixmap or something. (This does not clear the window.) */ + XSetWindowBackground (si->dpy, ssi->screensaver_window, + ssi->black_pixel); + } + + if (p->verbose_p) fprintf (stderr, "%s: unfading...\n", blurb()); + + + XSync (si->dpy, False); + XGrabServer (si->dpy); /* ############ DANGER! */ + XSync (si->dpy, False); + + /* Clear the stderr layer on each screen. + */ + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + clear_stderr (ssi); + } + + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + + + fade_screens (si->dpy, 0, current_windows, + p->fade_seconds/1000, p->fade_ticks, + False, False); + + free(current_windows); + current_windows = 0; + + if (p->verbose_p) fprintf (stderr, "%s: unfading done.\n", blurb()); + } + else + { + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->cmap) + { + Colormap c = DefaultColormapOfScreen (ssi->screen); + /* avoid technicolor */ + XClearWindow (si->dpy, ssi->screensaver_window); + if (c) XInstallColormap (si->dpy, c); + } + XUnmapWindow (si->dpy, ssi->screensaver_window); + } + } + + + /* If the focus window does has a non-default colormap, then install + that colormap as well. (On SGIs, this will cause both the root map + and the focus map to be installed simultaniously. It'd be nice to + pick up the other colormaps that had been installed, too; perhaps + XListInstalledColormaps could be used for that?) + */ + { + Window focus = 0; + int revert_to; + XGetInputFocus (si->dpy, &focus, &revert_to); + if (focus && focus != PointerRoot && focus != None) + { + XWindowAttributes xgwa; + xgwa.colormap = 0; + XGetWindowAttributes (si->dpy, focus, &xgwa); + if (xgwa.colormap && + xgwa.colormap != DefaultColormapOfScreen (xgwa.screen)) + XInstallColormap (si->dpy, xgwa.colormap); + } + } + + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + kill_xsetroot_data (si->dpy, ssi->screensaver_window, p->verbose_p); + } + + store_activate_time(si, False); /* store unblank time */ + + ungrab_keyboard_and_mouse (si); + restore_real_vroot (si); + + /* Unmap the windows a second time, dammit -- just to avoid a race + with the screen-grabbing hacks. (I'm not sure if this is really + necessary; I'm stabbing in the dark now.) + */ + for (i = 0; i < si->nscreens; i++) + XUnmapWindow (si->dpy, si->screens[i].screensaver_window); + + si->screen_blanked_p = False; + si->last_wall_clock_time = 0; +} + + +static void +store_activate_time (saver_info *si, Bool use_last_p) +{ + static time_t last_time = 0; + time_t now = ((use_last_p && last_time) ? last_time : time ((time_t) 0)); + CARD32 now32 = (CARD32) now; + int i; + last_time = now; + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (!ssi->screensaver_window) continue; + XChangeProperty (si->dpy, ssi->screensaver_window, XA_SCREENSAVER_TIME, + XA_INTEGER, 32, PropModeReplace, + (unsigned char *) &now32, 1); + } +} + + +Bool +select_visual (saver_screen_info *ssi, const char *visual_name) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + Bool install_cmap_p = p->install_cmap_p; + Bool was_installed_p = (ssi->cmap != DefaultColormapOfScreen(ssi->screen)); + Visual *new_v = 0; + Bool got_it; + + if (visual_name && *visual_name) + { + if (!strcmp(visual_name, "default-i")) + { + visual_name = "default"; + install_cmap_p = True; + } + else if (!strcmp(visual_name, "default-n")) + { + visual_name = "default"; + install_cmap_p = False; + } +#ifdef DAEMON_USE_GL + else if (!strcmp(visual_name, "gl") || + !strcmp(visual_name, "GL")) + { + new_v = get_gl_visual (ssi->screen); + if (!new_v && p->verbose_p) + fprintf (stderr, "%s: no GL visuals.\n", progname); + } +#endif /* DAEMON_USE_GL */ + + if (!new_v) + new_v = get_visual (ssi->screen, visual_name, True, False); + } + else + { + new_v = ssi->default_visual; + } + + got_it = !!new_v; + + if (new_v && new_v != DefaultVisualOfScreen(ssi->screen)) + /* It's not the default visual, so we have no choice but to install. */ + install_cmap_p = True; + + ssi->install_cmap_p = install_cmap_p; + + if (new_v && + ((ssi->current_visual != new_v) || + (install_cmap_p != was_installed_p))) + { + Colormap old_c = ssi->cmap; + Window old_w = ssi->screensaver_window; + + if (p->verbose_p) + { + fprintf (stderr, "%s: switching to visual ", blurb()); + describe_visual (stderr, ssi->screen, new_v, install_cmap_p); +#if 0 + fprintf (stderr, "%s: from ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + was_installed_p); +#endif + } + + reset_stderr (ssi); + ssi->current_visual = new_v; + ssi->current_depth = visual_depth(ssi->screen, new_v); + ssi->cmap = 0; + ssi->screensaver_window = 0; + + initialize_screensaver_window_1 (ssi); + + /* stderr_overlay_window is a child of screensaver_window, so we need + to destroy that as well (actually, we just need to invalidate and + drop our pointers to it, but this will destroy it, which is ok so + long as it happens before old_w itself is destroyed.) */ + reset_stderr (ssi); + + raise_window (si, True, True, False); + store_vroot_property (si->dpy, + 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->demoing_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", + blurb(), (unsigned long) old_w); + + if (old_c && + old_c != DefaultColormapOfScreen (ssi->screen) && + old_c != ssi->demo_cmap) + XFreeColormap (si->dpy, old_c); + } + + return got_it; +} diff --git a/driver/xscreensaver-command.c b/driver/xscreensaver-command.c new file mode 100644 index 00000000..cc169d27 --- /dev/null +++ b/driver/xscreensaver-command.c @@ -0,0 +1,284 @@ +/* xscreensaver-command, Copyright (c) 1991-1999 + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include /* for CARD32 */ +#include +#include +#include /* for XGetClassHint() */ +#include + +#include /* only needed to get through xscreensaver.h */ + +#include "remote.h" +#include "version.h" + +#ifdef _VROOT_H_ +ERROR! you must not include vroot.h in this file +#endif + +char *progname; + +Atom XA_VROOT; +Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; +Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_TIME, XA_SELECT, XA_DEMO; +static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV, XA_EXIT; +static Atom XA_RESTART, XA_PREFS, XA_LOCK, XA_THROTTLE, XA_UNTHROTTLE; + +static char *screensaver_version; +static char *usage = "\n\ +usage: %s -