http://ftp.x.org/contrib/applications/xscreensaver-3.20.tar.gz
authorZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:39 +0000 (00:42 -0500)
committerZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:39 +0000 (00:42 -0500)
-rw-r--r-- 1 zblaxell zblaxell 1257055 Nov 11  1999 xscreensaver-3.20.tar.gz
19fe5ed1cd6eb8ffb83460aa8c7049c8629e7b24  xscreensaver-3.20.tar.gz

51 files changed:
README
configure
configure.in
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/demo-Gtk-stubs.h [new file with mode: 0644]
driver/demo-Gtk-widgets.c [new file with mode: 0644]
driver/demo-Gtk-widgets.h [new file with mode: 0644]
driver/demo-Gtk.c [new file with mode: 0644]
driver/demo.c
driver/dialogs-Gtk.c [deleted file]
driver/lock.c
driver/prefs.c
driver/prefs.h
driver/remote.c
driver/subprocs.c
driver/timers.c
driver/windows.c
driver/xdpyinfo.c [new file with mode: 0644]
driver/xscreensaver-command.c
driver/xscreensaver-command.man
driver/xscreensaver-demo-old.man [new file with mode: 0644]
driver/xscreensaver-demo.glade [new file with mode: 0644]
driver/xscreensaver-demo.man
driver/xscreensaver.c
driver/xscreensaver.h
driver/xscreensaver.man
driver/xset.c
hacks/Makefile.in
hacks/compile_axp.com
hacks/compile_decc.com
hacks/distort.c
hacks/glx/Makefile.in
hacks/glx/extrusion.c
hacks/glx/sierpinski3d.c [new file with mode: 0644]
hacks/petri.c
hacks/ripples.c [new file with mode: 0644]
hacks/screenhack.c
hacks/sonar.c
hacks/vidwhacker
hacks/webcollage
hacks/webcollage.man
hacks/xsublim.c
setup.com
utils/resources.c
utils/resources.h
utils/version.h
utils/visual.c
xscreensaver.lsm
xscreensaver.spec

diff --git a/README b/README
index 6555321f6388aa8624dde8f603fd6210f77f58b4..374d7694a2864c3ebe80ae6c4ad47fd374278ffe 100644 (file)
--- a/README
+++ b/README
@@ -77,6 +77,25 @@ http://www.jwz.org/xscreensaver/.
 
                               ============
 
+Changes since 3.19:   * Added new hack `ripples' and `sierpinski3d'.
+                      * Made `xscreensaver-command -exit' be silent when no
+                        screen saver was running (instead of complaining.)
+                      * Made `webcollage' and `vidwhacker' use `xloadimage'
+                        when available (in addition to `xli' and `xv'.)
+                      * Improved memory usage in `petri' and gave it a hard
+                        cap on how much memory it can allocate.
+                      * Added `-watch' option to `xscreensaver-command'.
+                      * Made `xscreensaver-demo' come up with the
+                        most-recently-run hack selected by default.
+                      * Rewrote the Gtk version of `xscreensaver-demo'.
+                        It's a lot easier to use now.
+                      * Extended the format of the programs list in the
+                        .xscreensaver file, for the benefit of the new
+                        capabilities of `xscreensaver-demo'.
+                        NOTE: you might want to delete your ~/.xscreensaver
+                        file and allow it to be re-created!  The old one
+                        should still work, but xscreensaver-demo won't be as
+                        pretty.
 Changes since 3.18:   * Fixed gcc dependencies in `bumps' and `ccurve'.
                       * New hack, `extrusion'.
                       * Some of the web sites that `webcollage' was using as
index 135f8a3d0ca03eab4a27918a0a7cb6ffbbcfeabd..b698405dbe0de732c20aae0586f0f97bab5f6a75 100755 (executable)
--- a/configure
+++ b/configure
@@ -1083,6 +1083,8 @@ 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"
+    echo "$ac_t""Disabling C++ comments in ANSI C code." 1>&6
+    CC="$CC -Wp,-lang-c89"
   else
     case "$host" in
       *-irix5* |*-irix6.0-3* )
@@ -1099,7 +1101,7 @@ fi
   fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1114: checking how to run the C preprocessor" >&5
+echo "configure:1116: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1114,13 +1116,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1129 "configure"
+#line 1131 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1135: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1137: \"$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
   :
@@ -1131,13 +1133,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1146 "configure"
+#line 1148 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1154: \"$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
   :
@@ -1148,13 +1150,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1163 "configure"
+#line 1165 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1169: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1171: \"$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
   :
@@ -1179,12 +1181,12 @@ fi
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1194: checking for working const" >&5
+echo "configure:1196: 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 <<EOF
-#line 1199 "configure"
+#line 1201 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1233,7 +1235,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:1248: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1254,21 +1256,21 @@ EOF
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1269: checking for inline" >&5
+echo "configure:1271: 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 <<EOF
-#line 1276 "configure"
+#line 1278 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:1283: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1285: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -1307,7 +1309,7 @@ esac
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1322: checking for a BSD compatible install" >&5
+echo "configure:1324: 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
@@ -1360,7 +1362,7 @@ 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:1375: checking whether \"\${INSTALL} -d\" creates intermediate directories" >&5
+echo "configure:1377: 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
@@ -1382,7 +1384,7 @@ 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:1397: checking whether \"mkdir -p\" creates intermediate directories" >&5
+echo "configure:1399: 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
@@ -1413,7 +1415,7 @@ echo "$ac_t""$ac_cv_mkdir_p_creates_dirs" 1>&6
   fi
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1428: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1430: 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
@@ -1442,12 +1444,12 @@ fi
 
 # random libc stuff
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1457: checking for ANSI C header files" >&5
+echo "configure:1459: 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 <<EOF
-#line 1462 "configure"
+#line 1464 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1455,7 +1457,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1470: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1472: \"$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*
@@ -1472,7 +1474,7 @@ 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
-#line 1487 "configure"
+#line 1489 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1490,7 +1492,7 @@ 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
-#line 1505 "configure"
+#line 1507 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1511,7 +1513,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1526 "configure"
+#line 1528 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1522,7 +1524,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1539: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1549,17 +1551,17 @@ 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:1564: checking for $ac_hdr" >&5
+echo "configure:1566: 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
-#line 1569 "configure"
+#line 1571 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1574: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1576: \"$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*
@@ -1586,12 +1588,12 @@ fi
 done
 
 echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:1601: checking for mode_t" >&5
+echo "configure:1603: 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 <<EOF
-#line 1606 "configure"
+#line 1608 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1619,12 +1621,12 @@ EOF
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1634: checking for pid_t" >&5
+echo "configure:1636: 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 <<EOF
-#line 1639 "configure"
+#line 1641 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1652,12 +1654,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1667: checking for size_t" >&5
+echo "configure:1669: 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 <<EOF
-#line 1672 "configure"
+#line 1674 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1685,12 +1687,12 @@ EOF
 fi
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1700: checking return type of signal handlers" >&5
+echo "configure:1702: 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 <<EOF
-#line 1705 "configure"
+#line 1707 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -1707,7 +1709,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:1722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1724: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -1726,12 +1728,12 @@ EOF
 
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1741: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1743: 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 <<EOF
-#line 1746 "configure"
+#line 1748 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1740,7 +1742,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:1755: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1757: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -1761,12 +1763,12 @@ EOF
 fi
 
 echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1776: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1778: 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 <<EOF
-#line 1781 "configure"
+#line 1783 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -1782,7 +1784,7 @@ wait (&s);
 s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
 ; return 0; }
 EOF
-if { (eval echo configure:1797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1799: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_sys_wait_h=yes
 else
@@ -1807,12 +1809,12 @@ 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:1822: checking for $ac_hdr that defines DIR" >&5
+echo "configure:1824: 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 <<EOF
-#line 1827 "configure"
+#line 1829 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -1820,7 +1822,7 @@ int main() {
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:1835: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1837: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -1845,7 +1847,7 @@ 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:1860: checking for opendir in -ldir" >&5
+echo "configure:1862: 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
@@ -1853,7 +1855,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1868 "configure"
+#line 1870 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1864,7 +1866,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1886,7 +1888,7 @@ fi
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1901: checking for opendir in -lx" >&5
+echo "configure:1903: 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
@@ -1894,7 +1896,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1909 "configure"
+#line 1911 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1905,7 +1907,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1928,12 +1930,12 @@ fi
 fi
 
 echo $ac_n "checking how to call gettimeofday""... $ac_c" 1>&6
-echo "configure:1943: checking how to call gettimeofday" >&5
+echo "configure:1945: 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 <<EOF
-#line 1948 "configure"
+#line 1950 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                     #include <sys/time.h>
@@ -1942,7 +1944,7 @@ struct timeval tv; struct timezone tzp;
                     gettimeofday(&tv, &tzp);
 ; return 0; }
 EOF
-if { (eval echo configure:1957: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_gettimeofday_args=2
 else
@@ -1950,7 +1952,7 @@ else
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   cat > conftest.$ac_ext <<EOF
-#line 1965 "configure"
+#line 1967 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                                     #include <sys/time.h>
@@ -1958,7 +1960,7 @@ int main() {
 struct timeval tv; gettimeofday(&tv);
 ; return 0; }
 EOF
-if { (eval echo configure:1973: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1975: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_gettimeofday_args=1
 else
@@ -1997,12 +1999,12 @@ EOF
 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:2012: checking for $ac_func" >&5
+echo "configure:2014: 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 <<EOF
-#line 2017 "configure"
+#line 2019 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2025,7 +2027,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2042: \"$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
@@ -2053,12 +2055,12 @@ done
 for ac_func in sigaction syslog realpath
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2068: checking for $ac_func" >&5
+echo "configure:2070: 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 <<EOF
-#line 2073 "configure"
+#line 2075 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2081,7 +2083,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2098: \"$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
@@ -2106,12 +2108,12 @@ fi
 done
 
 echo $ac_n "checking for struct icmp""... $ac_c" 1>&6
-echo "configure:2121: checking for struct icmp" >&5
+echo "configure:2123: 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 <<EOF
-#line 2126 "configure"
+#line 2128 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                    #include <stdio.h>
@@ -2146,7 +2148,7 @@ struct icmp i;
                    ip.ip_hl = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:2161: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_icmp=yes
 else
@@ -2166,12 +2168,12 @@ EOF
 
  fi
 echo $ac_n "checking for struct icmphdr""... $ac_c" 1>&6
-echo "configure:2181: checking for struct icmphdr" >&5
+echo "configure:2183: 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 <<EOF
-#line 2186 "configure"
+#line 2188 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                    #include <stdio.h>
@@ -2206,7 +2208,7 @@ struct icmphdr i;
                    ip.ip_hl = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:2221: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2223: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_icmphdr=yes
 else
@@ -2229,17 +2231,17 @@ 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:2244: checking for $ac_hdr" >&5
+echo "configure:2246: 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
-#line 2249 "configure"
+#line 2251 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2254: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2256: \"$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*
@@ -2270,7 +2272,7 @@ 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:2285: checking for $ac_word" >&5
+echo "configure:2287: 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
@@ -2309,7 +2311,7 @@ done
     PERL_VERSION=0
   else
     echo $ac_n "checking perl version""... $ac_c" 1>&6
-echo "configure:2324: checking perl version" >&5
+echo "configure:2326: checking perl version" >&5
 if eval "test \"`echo '$''{'ac_cv_perl_version'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2331,7 +2333,7 @@ fi
 # 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:2346: checking for X" >&5
+echo "configure:2348: checking for X" >&5
 
 # Check whether --with-x or --without-x was given.
 if test "${with_x+set}" = set; then
@@ -2393,12 +2395,12 @@ if test "$ac_x_includes" = NO; then
 
   # First, try using that file with no special directory specified.
 cat > conftest.$ac_ext <<EOF
-#line 2408 "configure"
+#line 2410 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2413: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2415: \"$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*
@@ -2467,14 +2469,14 @@ if test "$ac_x_libraries" = NO; then
   ac_save_LIBS="$LIBS"
   LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2482 "configure"
+#line 2484 "configure"
 #include "confdefs.h"
 
 int main() {
 ${x_direct_test_function}()
 ; return 0; }
 EOF
-if { (eval echo configure:2489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2491: \"$ac_link\") 1>&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.
@@ -2580,17 +2582,17 @@ else
     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:2595: checking whether -R must be followed by a space" >&5
+echo "configure:2597: checking whether -R must be followed by a space" >&5
       ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
       cat > conftest.$ac_ext <<EOF
-#line 2598 "configure"
+#line 2600 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2607: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_R_nospace=yes
 else
@@ -2606,14 +2608,14 @@ rm -f conftest*
       else
        LIBS="$ac_xsave_LIBS -R $x_libraries"
        cat > conftest.$ac_ext <<EOF
-#line 2621 "configure"
+#line 2623 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2630: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_R_space=yes
 else
@@ -2645,7 +2647,7 @@ rm -f conftest*
     # 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:2660: checking for dnet_ntoa in -ldnet" >&5
+echo "configure:2662: 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
@@ -2653,7 +2655,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2668 "configure"
+#line 2670 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2664,7 +2666,7 @@ int main() {
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:2679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2681: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2686,7 +2688,7 @@ 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:2701: checking for dnet_ntoa in -ldnet_stub" >&5
+echo "configure:2703: 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
@@ -2694,7 +2696,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet_stub  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2709 "configure"
+#line 2711 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2705,7 +2707,7 @@ int main() {
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:2720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2734,12 +2736,12 @@ fi
     # 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:2749: checking for gethostbyname" >&5
+echo "configure:2751: 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 <<EOF
-#line 2754 "configure"
+#line 2756 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostbyname(); below.  */
@@ -2762,7 +2764,7 @@ gethostbyname();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2779: \"$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
@@ -2783,7 +2785,7 @@ fi
 
     if test $ac_cv_func_gethostbyname = no; then
       echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:2798: checking for gethostbyname in -lnsl" >&5
+echo "configure:2800: 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
@@ -2791,7 +2793,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2806 "configure"
+#line 2808 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2802,7 +2804,7 @@ int main() {
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:2817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2832,12 +2834,12 @@ fi
     # -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:2847: checking for connect" >&5
+echo "configure:2849: 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 <<EOF
-#line 2852 "configure"
+#line 2854 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char connect(); below.  */
@@ -2860,7 +2862,7 @@ connect();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2875: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2877: \"$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
@@ -2881,7 +2883,7 @@ fi
 
     if test $ac_cv_func_connect = no; then
       echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:2896: checking for connect in -lsocket" >&5
+echo "configure:2898: 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
@@ -2889,7 +2891,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2904 "configure"
+#line 2906 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2900,7 +2902,7 @@ int main() {
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:2915: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2924,12 +2926,12 @@ 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:2939: checking for remove" >&5
+echo "configure:2941: 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 <<EOF
-#line 2944 "configure"
+#line 2946 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char remove(); below.  */
@@ -2952,7 +2954,7 @@ remove();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2969: \"$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
@@ -2973,7 +2975,7 @@ fi
 
     if test $ac_cv_func_remove = no; then
       echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
-echo "configure:2988: checking for remove in -lposix" >&5
+echo "configure:2990: 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
@@ -2981,7 +2983,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lposix  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2996 "configure"
+#line 2998 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2992,7 +2994,7 @@ int main() {
 remove()
 ; return 0; }
 EOF
-if { (eval echo configure:3007: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3009: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3016,12 +3018,12 @@ fi
 
     # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
     echo $ac_n "checking for shmat""... $ac_c" 1>&6
-echo "configure:3031: checking for shmat" >&5
+echo "configure:3033: 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 <<EOF
-#line 3036 "configure"
+#line 3038 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char shmat(); below.  */
@@ -3044,7 +3046,7 @@ shmat();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3061: \"$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
@@ -3065,7 +3067,7 @@ fi
 
     if test $ac_cv_func_shmat = no; then
       echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
-echo "configure:3080: checking for shmat in -lipc" >&5
+echo "configure:3082: 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
@@ -3073,7 +3075,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lipc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3088 "configure"
+#line 3090 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3084,7 +3086,7 @@ int main() {
 shmat()
 ; return 0; }
 EOF
-if { (eval echo configure:3099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3117,7 +3119,7 @@ fi
   # 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:3132: checking for IceConnectionNumber in -lICE" >&5
+echo "configure:3134: 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
@@ -3125,7 +3127,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lICE $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3140 "configure"
+#line 3142 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3136,7 +3138,7 @@ int main() {
 IceConnectionNumber()
 ; return 0; }
 EOF
-if { (eval echo configure:3151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3153: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3167,7 +3169,7 @@ fi
 
 
     echo $ac_n "checking for X app-defaults directory""... $ac_c" 1>&6
-echo "configure:3182: checking for X app-defaults directory" >&5
+echo "configure:3184: 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
@@ -3366,7 +3368,7 @@ case "$host" in
 
         # 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:3381: checking for regcmp in -lgen" >&5
+echo "configure:3383: 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
@@ -3374,7 +3376,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgen  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3389 "configure"
+#line 3391 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3385,7 +3387,7 @@ int main() {
 regcmp()
 ; return 0; }
 EOF
-if { (eval echo configure:3400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3402: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3409,7 +3411,7 @@ fi
     ;;
   esac
 echo $ac_n "checking for XPointer""... $ac_c" 1>&6
-echo "configure:3424: checking for XPointer" >&5
+echo "configure:3426: checking for XPointer" >&5
 if eval "test \"`echo '$''{'ac_cv_xpointer'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3420,14 +3422,14 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 3435 "configure"
+#line 3437 "configure"
 #include "confdefs.h"
 #include <X11/Xlib.h>
 int main() {
 XPointer foo = (XPointer) 0;
 ; return 0; }
 EOF
-if { (eval echo configure:3442: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3444: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_xpointer=yes
 else
@@ -3465,17 +3467,17 @@ have_xmu=no
   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:3480: checking for X11/Xmu/Error.h" >&5
+echo "configure:3482: 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
-#line 3485 "configure"
+#line 3487 "configure"
 #include "confdefs.h"
 #include <X11/Xmu/Error.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3490: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3492: \"$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*
@@ -3528,7 +3530,7 @@ 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:3543: checking for the SunOS 4.1.x _get_wmShellWidgetClass bug" >&5
+echo "configure:3545: 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
@@ -3541,14 +3543,14 @@ else
                     # with X libraries because we know it's SunOS.
                     LDFLAGS="$LDFLAGS -lXmu -lXt -lX11 -lXext -lm"
                     cat > conftest.$ac_ext <<EOF
-#line 3556 "configure"
+#line 3558 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:3563: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_sunos_xmu_bug=no
 else
@@ -3564,21 +3566,21 @@ 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:3579: checking whether the compiler understands -static" >&5
+echo "configure:3581: 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 <<EOF
-#line 3586 "configure"
+#line 3588 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:3593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_ld_static=yes
 else
@@ -3661,7 +3663,7 @@ fi
 
     /*)
      echo $ac_n "checking for SGI SCREEN_SAVER headers""... $ac_c" 1>&6
-echo "configure:3676: checking for SGI SCREEN_SAVER headers" >&5
+echo "configure:3678: checking for SGI SCREEN_SAVER headers" >&5
      d=$with_sgi/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -3671,7 +3673,7 @@ echo "configure:3676: checking for SGI SCREEN_SAVER headers" >&5
      fi
 
      echo $ac_n "checking for SGI SCREEN_SAVER libs""... $ac_c" 1>&6
-echo "configure:3686: checking for SGI SCREEN_SAVER libs" >&5
+echo "configure:3688: checking for SGI SCREEN_SAVER libs" >&5
      d=$with_sgi/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -3704,17 +3706,17 @@ if test "$with_sgi" = yes; then
   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:3719: checking for X11/extensions/XScreenSaver.h" >&5
+echo "configure:3721: 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
-#line 3724 "configure"
+#line 3726 "configure"
 #include "confdefs.h"
 #include <X11/extensions/XScreenSaver.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3729: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3731: \"$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*
@@ -3771,7 +3773,7 @@ fi
 
     /*)
      echo $ac_n "checking for MIT-SCREEN-SAVER headers""... $ac_c" 1>&6
-echo "configure:3786: checking for MIT-SCREEN-SAVER headers" >&5
+echo "configure:3788: checking for MIT-SCREEN-SAVER headers" >&5
      d=$with_mit/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -3781,7 +3783,7 @@ echo "configure:3786: checking for MIT-SCREEN-SAVER headers" >&5
      fi
 
      echo $ac_n "checking for MIT-SCREEN-SAVER libs""... $ac_c" 1>&6
-echo "configure:3796: checking for MIT-SCREEN-SAVER libs" >&5
+echo "configure:3798: checking for MIT-SCREEN-SAVER libs" >&5
      d=$with_mit/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -3814,17 +3816,17 @@ if test "$with_mit" = yes; then
   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:3829: checking for X11/extensions/scrnsaver.h" >&5
+echo "configure:3831: 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
-#line 3834 "configure"
+#line 3836 "configure"
 #include "confdefs.h"
 #include <X11/extensions/scrnsaver.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3839: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3841: \"$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*
@@ -3866,10 +3868,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XScreenSaverRegister in -lXext""... $ac_c" 1>&6
-echo "configure:3884: checking for XScreenSaverRegister in -lXext" >&5
+echo "configure:3886: 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
@@ -3877,7 +3879,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3892 "configure"
+#line 3894 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3888,7 +3890,7 @@ int main() {
 XScreenSaverRegister()
 ; return 0; }
 EOF
-if { (eval echo configure:3903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3932,10 +3934,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XScreenSaverRegister in -lXExExt""... $ac_c" 1>&6
-echo "configure:3950: checking for XScreenSaverRegister in -lXExExt" >&5
+echo "configure:3952: 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
@@ -3943,7 +3945,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXExExt -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3958 "configure"
+#line 3960 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3954,7 +3956,7 @@ int main() {
 XScreenSaverRegister()
 ; return 0; }
 EOF
-if { (eval echo configure:3969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4001,10 +4003,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XScreenSaverRegister in -lXss""... $ac_c" 1>&6
-echo "configure:4019: checking for XScreenSaverRegister in -lXss" >&5
+echo "configure:4021: 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
@@ -4012,7 +4014,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXss -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4027 "configure"
+#line 4029 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4023,7 +4025,7 @@ int main() {
 XScreenSaverRegister()
 ; return 0; }
 EOF
-if { (eval echo configure:4038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4089,7 +4091,7 @@ fi
 
     /*)
      echo $ac_n "checking for XIDLE headers""... $ac_c" 1>&6
-echo "configure:4104: checking for XIDLE headers" >&5
+echo "configure:4106: checking for XIDLE headers" >&5
      d=$with_xidle/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -4099,7 +4101,7 @@ echo "configure:4104: checking for XIDLE headers" >&5
      fi
 
      echo $ac_n "checking for XIDLE libs""... $ac_c" 1>&6
-echo "configure:4114: checking for XIDLE libs" >&5
+echo "configure:4116: checking for XIDLE libs" >&5
      d=$with_xidle/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -4132,17 +4134,17 @@ if test "$with_xidle" = yes; then
   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:4147: checking for X11/extensions/xidle.h" >&5
+echo "configure:4149: 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
-#line 4152 "configure"
+#line 4154 "configure"
 #include "confdefs.h"
 #include <X11/extensions/xidle.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4159: \"$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*
@@ -4198,7 +4200,7 @@ fi
 
     /*)
      echo $ac_n "checking for SGI-VIDEO-CONTROL headers""... $ac_c" 1>&6
-echo "configure:4213: checking for SGI-VIDEO-CONTROL headers" >&5
+echo "configure:4215: checking for SGI-VIDEO-CONTROL headers" >&5
      d=$with_sgivc/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -4208,7 +4210,7 @@ echo "configure:4213: checking for SGI-VIDEO-CONTROL headers" >&5
      fi
 
      echo $ac_n "checking for SGI-VIDEO-CONTROL libs""... $ac_c" 1>&6
-echo "configure:4223: checking for SGI-VIDEO-CONTROL libs" >&5
+echo "configure:4225: checking for SGI-VIDEO-CONTROL libs" >&5
      d=$with_sgivc/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -4243,17 +4245,17 @@ if test "$with_sgivc" = yes; then
   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:4258: checking for X11/extensions/XSGIvc.h" >&5
+echo "configure:4260: 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
-#line 4263 "configure"
+#line 4265 "configure"
 #include "confdefs.h"
 #include <X11/extensions/XSGIvc.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4268: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4270: \"$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*
@@ -4294,10 +4296,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XSGIvcQueryGammaMap in -lXsgivc""... $ac_c" 1>&6
-echo "configure:4312: checking for XSGIvcQueryGammaMap in -lXsgivc" >&5
+echo "configure:4314: 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
@@ -4305,7 +4307,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXsgivc -lXext -lX11 $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4320 "configure"
+#line 4322 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4316,7 +4318,7 @@ int main() {
 XSGIvcQueryGammaMap()
 ; return 0; }
 EOF
-if { (eval echo configure:4331: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4381,7 +4383,7 @@ fi
 
     /*)
      echo $ac_n "checking for DPMS headers""... $ac_c" 1>&6
-echo "configure:4396: checking for DPMS headers" >&5
+echo "configure:4398: checking for DPMS headers" >&5
      d=$with_dpms/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -4391,7 +4393,7 @@ echo "configure:4396: checking for DPMS headers" >&5
      fi
 
      echo $ac_n "checking for DPMS libs""... $ac_c" 1>&6
-echo "configure:4406: checking for DPMS libs" >&5
+echo "configure:4408: checking for DPMS libs" >&5
      d=$with_dpms/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -4426,17 +4428,17 @@ if test "$with_dpms" = yes; then
   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:4441: checking for X11/extensions/dpms.h" >&5
+echo "configure:4443: 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
-#line 4446 "configure"
+#line 4448 "configure"
 #include "confdefs.h"
 #include <X11/extensions/dpms.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4451: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4453: \"$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*
@@ -4477,10 +4479,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for DPMSInfo in -lXdpms""... $ac_c" 1>&6
-echo "configure:4495: checking for DPMSInfo in -lXdpms" >&5
+echo "configure:4497: 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
@@ -4488,7 +4490,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXdpms -lXext -lX11 $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4503 "configure"
+#line 4505 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4499,7 +4501,7 @@ int main() {
 DPMSInfo()
 ; return 0; }
 EOF
-if { (eval echo configure:4514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4564,7 +4566,7 @@ fi
 
     /*)
      echo $ac_n "checking for xf86vmode headers""... $ac_c" 1>&6
-echo "configure:4579: checking for xf86vmode headers" >&5
+echo "configure:4581: checking for xf86vmode headers" >&5
      d=$with_xf86vmode/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -4574,7 +4576,7 @@ echo "configure:4579: checking for xf86vmode headers" >&5
      fi
 
      echo $ac_n "checking for xf86vmode libs""... $ac_c" 1>&6
-echo "configure:4589: checking for xf86vmode libs" >&5
+echo "configure:4591: checking for xf86vmode libs" >&5
      d=$with_xf86vmode/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -4609,17 +4611,17 @@ if test "$with_xf86vmode" = yes; then
   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:4624: checking for X11/extensions/xf86vmode.h" >&5
+echo "configure:4626: 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
-#line 4629 "configure"
+#line 4631 "configure"
 #include "confdefs.h"
 #include <X11/extensions/xf86vmode.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4634: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4636: \"$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*
@@ -4660,10 +4662,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XF86VidModeGetViewPort in -lXxf86vm""... $ac_c" 1>&6
-echo "configure:4678: checking for XF86VidModeGetViewPort in -lXxf86vm" >&5
+echo "configure:4680: 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
@@ -4671,7 +4673,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXxf86vm -lXext -lX11 $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4686 "configure"
+#line 4688 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4682,7 +4684,7 @@ int main() {
 XF86VidModeGetViewPort()
 ; return 0; }
 EOF
-if { (eval echo configure:4697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4736,7 +4738,7 @@ fi
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 4751 "configure"
+#line 4753 "configure"
 #include "confdefs.h"
 #include <X11/XHPlib.h>
 EOF
@@ -4774,7 +4776,7 @@ fi
 if test "$with_proc_interrupts" = yes; then
 
    echo $ac_n "checking whether /proc/interrupts contains keyboard data""... $ac_c" 1>&6
-echo "configure:4789: checking whether /proc/interrupts contains keyboard data" >&5
+echo "configure:4791: 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
@@ -4907,7 +4909,7 @@ fi
 
     /*)
      echo $ac_n "checking for PAM headers""... $ac_c" 1>&6
-echo "configure:4922: checking for PAM headers" >&5
+echo "configure:4924: checking for PAM headers" >&5
      d=$with_pam/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -4917,7 +4919,7 @@ echo "configure:4922: checking for PAM headers" >&5
      fi
 
      echo $ac_n "checking for PAM libs""... $ac_c" 1>&6
-echo "configure:4932: checking for PAM libs" >&5
+echo "configure:4934: checking for PAM libs" >&5
      d=$with_pam/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -4943,7 +4945,7 @@ echo "configure:4932: checking for PAM libs" >&5
 
 if test "$enable_locking" = yes -a "$with_pam" = yes; then
   echo $ac_n "checking for PAM""... $ac_c" 1>&6
-echo "configure:4958: checking for PAM" >&5
+echo "configure:4960: checking for PAM" >&5
 if eval "test \"`echo '$''{'ac_cv_pam'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4954,14 +4956,14 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 4969 "configure"
+#line 4971 "configure"
 #include "confdefs.h"
 #include <security/pam_appl.h>
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:4976: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4978: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_pam=yes
 else
@@ -4986,7 +4988,7 @@ EOF
     # 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:5001: checking for dlopen in -ldl" >&5
+echo "configure:5003: 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
@@ -4994,7 +4996,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5009 "configure"
+#line 5011 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5005,7 +5007,7 @@ int main() {
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:5020: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5027,12 +5029,12 @@ fi
 
 
     echo $ac_n "checking how to call pam_strerror""... $ac_c" 1>&6
-echo "configure:5042: checking how to call pam_strerror" >&5
+echo "configure:5044: 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 <<EOF
-#line 5047 "configure"
+#line 5049 "configure"
 #include "confdefs.h"
 #include <stdio.h>
                       #include <stdlib.h>
@@ -5042,7 +5044,7 @@ pam_handle_t *pamh = 0;
                       char *s = pam_strerror(pamh, PAM_SUCCESS);
 ; return 0; }
 EOF
-if { (eval echo configure:5057: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5059: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_pam_strerror_args=2
 else
@@ -5050,7 +5052,7 @@ else
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   cat > conftest.$ac_ext <<EOF
-#line 5065 "configure"
+#line 5067 "configure"
 #include "confdefs.h"
 #include <stdio.h>
                                       #include <stdlib.h>
@@ -5060,7 +5062,7 @@ char *s =
                                        pam_strerror(PAM_SUCCESS);
 ; return 0; }
 EOF
-if { (eval echo configure:5075: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5077: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_pam_strerror_args=1
 else
@@ -5116,7 +5118,7 @@ fi
 
     /*)
      echo $ac_n "checking for Kerberos headers""... $ac_c" 1>&6
-echo "configure:5131: checking for Kerberos headers" >&5
+echo "configure:5133: checking for Kerberos headers" >&5
      d=$with_kerberos/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -5126,7 +5128,7 @@ echo "configure:5131: checking for Kerberos headers" >&5
      fi
 
      echo $ac_n "checking for Kerberos libs""... $ac_c" 1>&6
-echo "configure:5141: checking for Kerberos libs" >&5
+echo "configure:5143: checking for Kerberos libs" >&5
      d=$with_kerberos/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -5152,7 +5154,7 @@ echo "configure:5141: checking for Kerberos libs" >&5
 
 if test "$enable_locking" = yes -a "$with_kerberos" = yes; then
   echo $ac_n "checking for Kerberos""... $ac_c" 1>&6
-echo "configure:5167: checking for Kerberos" >&5
+echo "configure:5169: checking for Kerberos" >&5
 if eval "test \"`echo '$''{'ac_cv_kerberos'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5163,14 +5165,14 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 5178 "configure"
+#line 5180 "configure"
 #include "confdefs.h"
 #include <krb.h>
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:5185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5187: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_kerberos=yes
 else
@@ -5194,12 +5196,12 @@ EOF
     # from Tim Showalter <tjs+@andrew.cmu.edu>
     PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes"
     echo $ac_n "checking for res_search""... $ac_c" 1>&6
-echo "configure:5209: checking for res_search" >&5
+echo "configure:5211: 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 <<EOF
-#line 5214 "configure"
+#line 5216 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char res_search(); below.  */
@@ -5222,7 +5224,7 @@ res_search();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5239: \"$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
@@ -5240,7 +5242,7 @@ if eval "test \"`echo '$ac_cv_func_'res_search`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for res_search in -lresolv""... $ac_c" 1>&6
-echo "configure:5255: checking for res_search in -lresolv" >&5
+echo "configure:5257: 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
@@ -5248,7 +5250,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5263 "configure"
+#line 5265 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5259,7 +5261,7 @@ int main() {
 res_search()
 ; return 0; }
 EOF
-if { (eval echo configure:5274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5315,7 +5317,7 @@ fi
 
     /*)
      echo $ac_n "checking for shadow password headers""... $ac_c" 1>&6
-echo "configure:5330: checking for shadow password headers" >&5
+echo "configure:5332: checking for shadow password headers" >&5
      d=$with_shadow/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -5325,7 +5327,7 @@ echo "configure:5330: checking for shadow password headers" >&5
      fi
 
      echo $ac_n "checking for shadow password libs""... $ac_c" 1>&6
-echo "configure:5340: checking for shadow password libs" >&5
+echo "configure:5342: checking for shadow password libs" >&5
      d=$with_shadow/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -5363,7 +5365,7 @@ fi
 
 if test "$with_shadow" = yes ; then
   echo $ac_n "checking for Sun-style shadow passwords""... $ac_c" 1>&6
-echo "configure:5378: checking for Sun-style shadow passwords" >&5
+echo "configure:5380: 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
@@ -5374,7 +5376,7 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 5389 "configure"
+#line 5391 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                                     #include <unistd.h>
@@ -5387,7 +5389,7 @@ struct passwd_adjunct *p = getpwanam("nobody");
                        const char *pw = p->pwa_passwd;
 ; return 0; }
 EOF
-if { (eval echo configure:5402: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5404: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sun_adjunct=yes
 else
@@ -5417,7 +5419,7 @@ fi
 
 if test "$with_shadow" = yes ; then
   echo $ac_n "checking for DEC-style shadow passwords""... $ac_c" 1>&6
-echo "configure:5432: checking for DEC-style shadow passwords" >&5
+echo "configure:5434: 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
@@ -5428,7 +5430,7 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 5443 "configure"
+#line 5445 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                                     #include <unistd.h>
@@ -5445,7 +5447,7 @@ struct pr_passwd *p;
                        pw = p->ufld.fd_encrypt;
 ; return 0; }
 EOF
-if { (eval echo configure:5460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5462: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_enhanced_passwd=yes
 else
@@ -5469,7 +5471,7 @@ echo "$ac_t""$ac_cv_enhanced_passwd" 1>&6
     # But on DEC, it's in -lsecurity.
     #
     echo $ac_n "checking for getprpwnam in -lprot""... $ac_c" 1>&6
-echo "configure:5484: checking for getprpwnam in -lprot" >&5
+echo "configure:5486: 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
@@ -5477,7 +5479,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lprot -lx $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5492 "configure"
+#line 5494 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5488,7 +5490,7 @@ int main() {
 getprpwnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5503: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5507,7 +5509,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:5522: checking for getprpwnam in -lsecurity" >&5
+echo "configure:5524: 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
@@ -5515,7 +5517,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsecurity  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5530 "configure"
+#line 5532 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5526,7 +5528,7 @@ int main() {
 getprpwnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5543: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5559,7 +5561,7 @@ fi
 
 if test "$with_shadow" = yes ; then
   echo $ac_n "checking for HP-style shadow passwords""... $ac_c" 1>&6
-echo "configure:5574: checking for HP-style shadow passwords" >&5
+echo "configure:5576: 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
@@ -5570,7 +5572,7 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 5585 "configure"
+#line 5587 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                                     #include <unistd.h>
@@ -5583,7 +5585,7 @@ struct s_passwd *p = getspwnam("nobody");
                        const char *pw = p->pw_passwd;
 ; return 0; }
 EOF
-if { (eval echo configure:5598: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5600: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_hpux_passwd=yes
 else
@@ -5604,7 +5606,7 @@ echo "$ac_t""$ac_cv_hpux_passwd" 1>&6
 
     # on HPUX, bigcrypt is in -lsec
     echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6
-echo "configure:5619: checking for bigcrypt in -lsec" >&5
+echo "configure:5621: 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
@@ -5612,7 +5614,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsec  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5627 "configure"
+#line 5629 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5623,7 +5625,7 @@ int main() {
 bigcrypt()
 ; return 0; }
 EOF
-if { (eval echo configure:5638: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5661,7 +5663,7 @@ fi
 
 if test "$with_shadow" = yes ; then
   echo $ac_n "checking for FreeBSD-style shadow passwords""... $ac_c" 1>&6
-echo "configure:5676: checking for FreeBSD-style shadow passwords" >&5
+echo "configure:5678: 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
@@ -5687,7 +5689,7 @@ fi
 
 if test "$with_shadow" = yes ; then
   echo $ac_n "checking for generic shadow passwords""... $ac_c" 1>&6
-echo "configure:5702: checking for generic shadow passwords" >&5
+echo "configure:5704: 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
@@ -5698,7 +5700,7 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 5713 "configure"
+#line 5715 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
                                     #include <unistd.h>
@@ -5710,7 +5712,7 @@ struct spwd *p = getspnam("nobody");
                        const char *pw = p->sp_pwdp;
 ; return 0; }
 EOF
-if { (eval echo configure:5725: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_shadow=yes
 else
@@ -5731,7 +5733,7 @@ echo "$ac_t""$ac_cv_shadow" 1>&6
     # 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:5746: checking for getspnam in -lc" >&5
+echo "configure:5748: 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
@@ -5739,7 +5741,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5754 "configure"
+#line 5756 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5750,7 +5752,7 @@ int main() {
 getspnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5772,7 +5774,7 @@ fi
 
     if test "$have_getspnam" = no ; then
       echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6
-echo "configure:5787: checking for getspnam in -lgen" >&5
+echo "configure:5789: 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
@@ -5780,7 +5782,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgen  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5795 "configure"
+#line 5797 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5791,7 +5793,7 @@ int main() {
 getspnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5806: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5827,7 +5829,7 @@ 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:5842: checking for crypt in -lc" >&5
+echo "configure:5844: 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
@@ -5835,7 +5837,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5850 "configure"
+#line 5852 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5846,7 +5848,7 @@ int main() {
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:5861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5868,7 +5870,7 @@ fi
 
   if test "$have_crypt" = no ; then
     echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:5883: checking for crypt in -lcrypt" >&5
+echo "configure:5885: 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
@@ -5876,7 +5878,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lcrypt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5891 "configure"
+#line 5893 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5887,7 +5889,7 @@ int main() {
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:5902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5904: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5971,7 +5973,7 @@ fi
 
     /*)
      echo $ac_n "checking for Motif headers""... $ac_c" 1>&6
-echo "configure:5986: checking for Motif headers" >&5
+echo "configure:5988: checking for Motif headers" >&5
      d=$with_motif/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -5981,7 +5983,7 @@ echo "configure:5986: checking for Motif headers" >&5
      fi
 
      echo $ac_n "checking for Motif libs""... $ac_c" 1>&6
-echo "configure:5996: checking for Motif libs" >&5
+echo "configure:5998: checking for Motif libs" >&5
      d=$with_motif/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -6020,17 +6022,17 @@ if test "$with_motif" = yes; then
   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:6035: checking for Xm/Xm.h" >&5
+echo "configure:6037: 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
-#line 6040 "configure"
+#line 6042 "configure"
 #include "confdefs.h"
 #include <Xm/Xm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6045: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6047: \"$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*
@@ -6095,7 +6097,7 @@ esac
 
     /*)
      echo $ac_n "checking for Gtk headers""... $ac_c" 1>&6
-echo "configure:6110: checking for Gtk headers" >&5
+echo "configure:6112: checking for Gtk headers" >&5
      d=$with_gtk/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -6105,7 +6107,7 @@ echo "configure:6110: checking for Gtk headers" >&5
      fi
 
      echo $ac_n "checking for Gtk libs""... $ac_c" 1>&6
-echo "configure:6120: checking for Gtk libs" >&5
+echo "configure:6122: checking for Gtk libs" >&5
      d=$with_gtk/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -6154,7 +6156,7 @@ 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:6169: checking for $ac_word" >&5
+echo "configure:6171: 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
@@ -6194,7 +6196,7 @@ 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:6209: checking for $ac_word" >&5
+echo "configure:6211: 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
@@ -6235,7 +6237,7 @@ done
   fi
   if test "$have_gtk" = yes; then
     echo $ac_n "checking Gtk version number""... $ac_c" 1>&6
-echo "configure:6250: checking Gtk version number" >&5
+echo "configure:6252: 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
@@ -6262,7 +6264,7 @@ echo "$ac_t""$ac_cv_gtk_version_string" 1>&6
   fi
   if test "$have_gtk" = yes; then
     echo $ac_n "checking for Gtk includes""... $ac_c" 1>&6
-echo "configure:6277: checking for Gtk includes" >&5
+echo "configure:6279: 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
@@ -6271,7 +6273,7 @@ fi
 
 echo "$ac_t""$ac_cv_gtk_config_cflags" 1>&6
     echo $ac_n "checking for Gtk libs""... $ac_c" 1>&6
-echo "configure:6286: checking for Gtk libs" >&5
+echo "configure:6288: 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
@@ -6314,7 +6316,7 @@ fi
 
     /*)
      echo $ac_n "checking for Athena headers""... $ac_c" 1>&6
-echo "configure:6329: checking for Athena headers" >&5
+echo "configure:6331: checking for Athena headers" >&5
      d=$with_athena/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -6324,7 +6326,7 @@ echo "configure:6329: checking for Athena headers" >&5
      fi
 
      echo $ac_n "checking for Athena libs""... $ac_c" 1>&6
-echo "configure:6339: checking for Athena libs" >&5
+echo "configure:6341: checking for Athena libs" >&5
      d=$with_athena/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -6365,17 +6367,17 @@ if test "$with_athena" = yes; then
   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:6380: checking for X11/Xaw/Dialog.h" >&5
+echo "configure:6382: 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
-#line 6385 "configure"
+#line 6387 "configure"
 #include "confdefs.h"
 #include <X11/Xaw/Dialog.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6390: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6392: \"$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*
@@ -6413,10 +6415,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for Xaw3dComputeTopShadowRGB in -lXaw3d""... $ac_c" 1>&6
-echo "configure:6431: checking for Xaw3dComputeTopShadowRGB in -lXaw3d" >&5
+echo "configure:6433: 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
@@ -6424,7 +6426,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXaw3d -lXt -lXmu -lXext -lX11 $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6439 "configure"
+#line 6441 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6435,7 +6437,7 @@ int main() {
 Xaw3dComputeTopShadowRGB()
 ; return 0; }
 EOF
-if { (eval echo configure:6450: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6480,7 +6482,7 @@ fi
 # 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:6495: checking for XawViewportSetCoordinates in Viewport.h" >&5
+echo "configure:6497: 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
@@ -6492,7 +6494,7 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 6507 "configure"
+#line 6509 "configure"
 #include "confdefs.h"
 #include <X11/Xaw/Viewport.h>
 EOF
@@ -6525,7 +6527,7 @@ fi
 have_lesstif=no
 if test "$have_motif" = yes ; then
   echo $ac_n "checking whether Motif is really LessTif""... $ac_c" 1>&6
-echo "configure:6540: checking whether Motif is really LessTif" >&5
+echo "configure:6542: 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
@@ -6536,14 +6538,14 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 6551 "configure"
+#line 6553 "configure"
 #include "confdefs.h"
 #include <Xm/Xm.h>
 int main() {
 long vers = LesstifVersion;
 ; return 0; }
 EOF
-if { (eval echo configure:6558: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6560: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_lesstif=yes
 else
@@ -6568,7 +6570,7 @@ 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:6583: checking LessTif version number" >&5
+echo "configure:6585: 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
@@ -6583,7 +6585,7 @@ else
                      ac_cv_lesstif_version_string=unknown
 else
   cat > conftest.$ac_ext <<EOF
-#line 6598 "configure"
+#line 6600 "configure"
 #include "confdefs.h"
 #include <stdio.h>
                      #include <Xm/Xm.h>
@@ -6596,7 +6598,7 @@ else
                        exit(0);
                      }
 EOF
-if { (eval echo configure:6611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6613: \"$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/ .*//'`
@@ -6626,7 +6628,7 @@ 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:6641: checking Motif version number" >&5
+echo "configure:6643: 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
@@ -6641,7 +6643,7 @@ else
                      ac_cv_motif_version_string=unknown
 else
   cat > conftest.$ac_ext <<EOF
-#line 6656 "configure"
+#line 6658 "configure"
 #include "confdefs.h"
 #include <stdio.h>
                      #include <Xm/Xm.h>
@@ -6654,7 +6656,7 @@ else
                        exit(0);
                      }
 EOF
-if { (eval echo configure:6669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6671: \"$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/ .*//'`
@@ -6698,7 +6700,7 @@ fi
 motif_requires_xpm=no
 if test "$have_motif" = yes ; then
    echo $ac_n "checking whether Motif requires XPM""... $ac_c" 1>&6
-echo "configure:6713: checking whether Motif requires XPM" >&5
+echo "configure:6715: checking whether Motif requires XPM" >&5
    if test "$motif_version" = "unknown" || test "$motif_version" -ge 2000
    then
      motif_requires_xpm=yes
@@ -6737,10 +6739,10 @@ if test "$have_motif" = yes ; then
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XpQueryExtension in -lXp""... $ac_c" 1>&6
-echo "configure:6755: checking for XpQueryExtension in -lXp" >&5
+echo "configure:6757: 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
@@ -6748,7 +6750,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXp -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6763 "configure"
+#line 6765 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6759,7 +6761,7 @@ int main() {
 XpQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:6774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6776: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6810,10 +6812,10 @@ if test "$have_motif" = yes ; then
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for _Xsetlocale in -lXintl""... $ac_c" 1>&6
-echo "configure:6828: checking for _Xsetlocale in -lXintl" >&5
+echo "configure:6830: 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
@@ -6821,7 +6823,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXintl -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6836 "configure"
+#line 6838 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6832,7 +6834,7 @@ int main() {
 _Xsetlocale()
 ; return 0; }
 EOF
-if { (eval echo configure:6847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6849: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6888,7 +6890,7 @@ fi
 
     /*)
      echo $ac_n "checking for GL headers""... $ac_c" 1>&6
-echo "configure:6903: checking for GL headers" >&5
+echo "configure:6905: checking for GL headers" >&5
      d=$with_gl/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -6898,7 +6900,7 @@ echo "configure:6903: checking for GL headers" >&5
      fi
 
      echo $ac_n "checking for GL libs""... $ac_c" 1>&6
-echo "configure:6913: checking for GL libs" >&5
+echo "configure:6915: checking for GL libs" >&5
      d=$with_gl/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -6934,17 +6936,17 @@ if test "$with_gl" = yes; then
   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:6949: checking for GL/gl.h" >&5
+echo "configure:6951: 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
-#line 6954 "configure"
+#line 6956 "configure"
 #include "confdefs.h"
 #include <GL/gl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6959: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6961: \"$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*
@@ -6975,17 +6977,17 @@ 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:6990: checking for GL/glx.h" >&5
+echo "configure:6992: 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
-#line 6995 "configure"
+#line 6997 "configure"
 #include "confdefs.h"
 #include <GL/glx.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7000: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7002: \"$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*
@@ -7017,7 +7019,7 @@ fi
     # to link against.
     #
     echo $ac_n "checking whether GL is really MesaGL""... $ac_c" 1>&6
-echo "configure:7032: checking whether GL is really MesaGL" >&5
+echo "configure:7034: 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
@@ -7029,7 +7031,7 @@ else
   fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   cat > conftest.$ac_ext <<EOF
-#line 7044 "configure"
+#line 7046 "configure"
 #include "confdefs.h"
 #include <GL/glx.h>
 EOF
@@ -7048,12 +7050,62 @@ echo "$ac_t""$ac_cv_have_mesa_gl" 1>&6
     ac_have_mesa_gl=$ac_cv_have_mesa_gl
  
 
+    gl_lib_1=""
+    GL_LIBS=""
+
+
+    # Some versions of MesaGL are compiled to require -lpthread.
+    # So if the Mesa headers exist, and -lpthread exists, then always
+    # link -lpthread after the Mesa libs (be they named -lGL or -lMesaGL.)
+    #
+    if test "$ac_have_mesa_gl" = yes; then
+      echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
+echo "configure:7075: 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 <<EOF
+#line 7083 "configure"
+#include "confdefs.h"
+/* 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 pthread_create();
+
+int main() {
+pthread_create()
+; return 0; }
+EOF
+if { (eval echo configure:7094: \"$ac_link\") 1>&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
+  GL_LIBS="-lpthread"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+
     # If we have Mesa headers, check to see if we can link against -lMesaGL.
     # If we don't have Mesa headers, or we don't have -lMesaGL, try -lGL.
     # Else, warn that GL is busted.  (We have the headers, but no libs.)
     #
-    gl_lib_1=""
-    GL_LIBS=""
 
     if test "$ac_have_mesa_gl" = yes ; then
       
@@ -7071,18 +7123,18 @@ echo "$ac_t""$ac_cv_have_mesa_gl" 1>&6
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for glXCreateContext in -lMesaGL""... $ac_c" 1>&6
-echo "configure:7089: checking for glXCreateContext in -lMesaGL" >&5
+echo "configure:7141: checking for glXCreateContext in -lMesaGL" >&5
 ac_lib_var=`echo MesaGL'_'glXCreateContext | 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="-lMesaGL -lMesaGLU -lX11 -lXext -lm $LIBS"
+LIBS="-lMesaGL -lMesaGLU $GL_LIBS -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7097 "configure"
+#line 7149 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7093,7 +7145,7 @@ int main() {
 glXCreateContext()
 ; return 0; }
 EOF
-if { (eval echo configure:7108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7109,7 +7161,7 @@ fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   gl_lib_1="MesaGL"
-                      GL_LIBS="-lMesaGL -lMesaGLU"
+                      GL_LIBS="-lMesaGL -lMesaGLU $GL_LIBS"
 else
   echo "$ac_t""no" 1>&6
 fi
@@ -7136,18 +7188,18 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for glXCreateContext in -lGL""... $ac_c" 1>&6
-echo "configure:7154: checking for glXCreateContext in -lGL" >&5
+echo "configure:7206: checking for glXCreateContext in -lGL" >&5
 ac_lib_var=`echo GL'_'glXCreateContext | 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="-lGL -lGLU -lX11 -lXext -lm $LIBS"
+LIBS="-lGL -lGLU $GL_LIBS -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7162 "configure"
+#line 7214 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7158,7 +7210,7 @@ int main() {
 glXCreateContext()
 ; return 0; }
 EOF
-if { (eval echo configure:7173: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7225: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7174,7 +7226,7 @@ fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   gl_lib_1="GL"
-                      GL_LIBS="-lGL -lGLU"
+                      GL_LIBS="-lGL -lGLU $GL_LIBS"
 else
   echo "$ac_t""no" 1>&6
 fi
@@ -7215,12 +7267,12 @@ EOF
     if test "$ac_have_mesa_gl" = yes; then
 
       echo $ac_n "checking MesaGL version number""... $ac_c" 1>&6
-echo "configure:7230: checking MesaGL version number" >&5
+echo "configure:7282: 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 <<EOF
-#line 7235 "configure"
+#line 7287 "configure"
 #include "confdefs.h"
 #include <GL/gl.h>
 configure: MESA_MAJOR_VERSION MESA_MINOR_VERSION
@@ -7266,122 +7318,6 @@ echo "$ac_t""$ac_cv_mesagl_version_string" 1>&6
     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:7288: 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 <<EOF
-#line 7296 "configure"
-#include "confdefs.h"
-/* 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 pthread_create();
-
-int main() {
-pthread_create()
-; return 0; }
-EOF
-if { (eval echo configure:7307: \"$ac_link\") 1>&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:7346: 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 <<EOF
-#line 7354 "configure"
-#include "confdefs.h"
-/* 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 gl_get_thread_context();
-
-int main() {
-gl_get_thread_context()
-; return 0; }
-EOF
-if { (eval echo configure:7365: \"$ac_link\") 1>&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.
     #
     
@@ -7399,10 +7335,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for glBindTexture in -l$gl_lib_1""... $ac_c" 1>&6
-echo "configure:7417: checking for glBindTexture in -l$gl_lib_1" >&5
+echo "configure:7353: 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
@@ -7410,7 +7346,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-l$gl_lib_1 $GL_LIBS -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7425 "configure"
+#line 7361 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7421,7 +7357,7 @@ int main() {
 glBindTexture()
 ; return 0; }
 EOF
-if { (eval echo configure:7436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7455,7 +7391,7 @@ fi
     # 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:7470: checking whether drastic GL measures must be taken" >&5
+echo "configure:7406: checking whether drastic GL measures must be taken" >&5
     case "$host" in
       *-sgi*)
         echo "$ac_t""yes -- hello, SGI." 1>&6
@@ -7507,7 +7443,7 @@ fi
 
     /*)
      echo $ac_n "checking for GLE headers""... $ac_c" 1>&6
-echo "configure:7522: checking for GLE headers" >&5
+echo "configure:7458: checking for GLE headers" >&5
      d=$with_gle/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -7517,7 +7453,7 @@ echo "configure:7522: checking for GLE headers" >&5
      fi
 
      echo $ac_n "checking for GLE libs""... $ac_c" 1>&6
-echo "configure:7532: checking for GLE libs" >&5
+echo "configure:7468: checking for GLE libs" >&5
      d=$with_gle/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -7553,17 +7489,17 @@ if test "$with_gle" = yes; then
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   ac_safe=`echo "GL/gutil.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for GL/gutil.h""... $ac_c" 1>&6
-echo "configure:7568: checking for GL/gutil.h" >&5
+echo "configure:7504: checking for GL/gutil.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
-#line 7573 "configure"
+#line 7509 "configure"
 #include "confdefs.h"
 #include <GL/gutil.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7578: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7514: \"$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*
@@ -7594,17 +7530,17 @@ fi
   CPPFLAGS="$CPPFLAGS $X_CFLAGS"
   ac_safe=`echo "GL/tube.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for GL/tube.h""... $ac_c" 1>&6
-echo "configure:7609: checking for GL/tube.h" >&5
+echo "configure:7545: checking for GL/tube.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
-#line 7614 "configure"
+#line 7550 "configure"
 #include "confdefs.h"
 #include <GL/tube.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7619: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7555: \"$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*
@@ -7648,10 +7584,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for gleCreateGC in -lgle""... $ac_c" 1>&6
-echo "configure:7666: checking for gleCreateGC in -lgle" >&5
+echo "configure:7602: checking for gleCreateGC in -lgle" >&5
 ac_lib_var=`echo gle'_'gleCreateGC | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7659,7 +7595,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgle $GL_LIBS -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7674 "configure"
+#line 7610 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7670,7 +7606,7 @@ int main() {
 gleCreateGC()
 ; return 0; }
 EOF
-if { (eval echo configure:7685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7712,10 +7648,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for uview_direction_d in -lmatrix""... $ac_c" 1>&6
-echo "configure:7730: checking for uview_direction_d in -lmatrix" >&5
+echo "configure:7666: checking for uview_direction_d in -lmatrix" >&5
 ac_lib_var=`echo matrix'_'uview_direction_d | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7723,7 +7659,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lmatrix $GL_LIBS -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7738 "configure"
+#line 7674 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7734,7 +7670,7 @@ int main() {
 uview_direction_d()
 ; return 0; }
 EOF
-if { (eval echo configure:7749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7799,7 +7735,7 @@ fi
 
     /*)
      echo $ac_n "checking for XPM headers""... $ac_c" 1>&6
-echo "configure:7814: checking for XPM headers" >&5
+echo "configure:7750: checking for XPM headers" >&5
      d=$with_xpm/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -7809,7 +7745,7 @@ echo "configure:7814: checking for XPM headers" >&5
      fi
 
      echo $ac_n "checking for XPM libs""... $ac_c" 1>&6
-echo "configure:7824: checking for XPM libs" >&5
+echo "configure:7760: checking for XPM libs" >&5
      d=$with_xpm/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -7842,17 +7778,17 @@ if test "$with_xpm" = yes; then
   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:7857: checking for X11/xpm.h" >&5
+echo "configure:7793: 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
-#line 7862 "configure"
+#line 7798 "configure"
 #include "confdefs.h"
 #include <X11/xpm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7867: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7803: \"$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*
@@ -7918,7 +7854,7 @@ fi
 
     /*)
      echo $ac_n "checking for XSHM headers""... $ac_c" 1>&6
-echo "configure:7933: checking for XSHM headers" >&5
+echo "configure:7869: checking for XSHM headers" >&5
      d=$with_xshm/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -7928,7 +7864,7 @@ echo "configure:7933: checking for XSHM headers" >&5
      fi
 
      echo $ac_n "checking for XSHM libs""... $ac_c" 1>&6
-echo "configure:7943: checking for XSHM libs" >&5
+echo "configure:7879: checking for XSHM libs" >&5
      d=$with_xshm/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -7963,17 +7899,17 @@ if test "$with_xshm" = yes; then
   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:7978: checking for X11/extensions/XShm.h" >&5
+echo "configure:7914: 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
-#line 7983 "configure"
+#line 7919 "configure"
 #include "confdefs.h"
 #include <X11/extensions/XShm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7988: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7924: \"$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*
@@ -8007,17 +7943,17 @@ 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:8022: checking for sys/ipc.h" >&5
+echo "configure:7958: 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
-#line 8027 "configure"
+#line 7963 "configure"
 #include "confdefs.h"
 #include <sys/ipc.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8032: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7968: \"$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*
@@ -8052,17 +7988,17 @@ 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:8067: checking for sys/shm.h" >&5
+echo "configure:8003: 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
-#line 8072 "configure"
+#line 8008 "configure"
 #include "confdefs.h"
 #include <sys/shm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8077: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8013: \"$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*
@@ -8110,10 +8046,10 @@ fi
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XShmQueryExtension in -lXextSam""... $ac_c" 1>&6
-echo "configure:8128: checking for XShmQueryExtension in -lXextSam" >&5
+echo "configure:8064: 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
@@ -8121,7 +8057,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXextSam -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8136 "configure"
+#line 8072 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8132,7 +8068,7 @@ int main() {
 XShmQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:8147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8083: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8198,7 +8134,7 @@ fi
 
     /*)
      echo $ac_n "checking for DOUBLE-BUFFER headers""... $ac_c" 1>&6
-echo "configure:8213: checking for DOUBLE-BUFFER headers" >&5
+echo "configure:8149: checking for DOUBLE-BUFFER headers" >&5
      d=$with_xdbe/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -8208,7 +8144,7 @@ echo "configure:8213: checking for DOUBLE-BUFFER headers" >&5
      fi
 
      echo $ac_n "checking for DOUBLE-BUFFER libs""... $ac_c" 1>&6
-echo "configure:8223: checking for DOUBLE-BUFFER libs" >&5
+echo "configure:8159: checking for DOUBLE-BUFFER libs" >&5
      d=$with_xdbe/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -8242,17 +8178,17 @@ if test "$with_xdbe" = yes; then
   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:8257: checking for X11/extensions/Xdbe.h" >&5
+echo "configure:8193: 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
-#line 8262 "configure"
+#line 8198 "configure"
 #include "confdefs.h"
 #include <X11/extensions/Xdbe.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8267: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8203: \"$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*
@@ -8315,7 +8251,7 @@ fi
 
     /*)
      echo $ac_n "checking for XReadDisplay headers""... $ac_c" 1>&6
-echo "configure:8330: checking for XReadDisplay headers" >&5
+echo "configure:8266: checking for XReadDisplay headers" >&5
      d=$with_readdisplay/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -8325,7 +8261,7 @@ echo "configure:8330: checking for XReadDisplay headers" >&5
      fi
 
      echo $ac_n "checking for XReadDisplay libs""... $ac_c" 1>&6
-echo "configure:8340: checking for XReadDisplay libs" >&5
+echo "configure:8276: checking for XReadDisplay libs" >&5
      d=$with_readdisplay/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -8358,17 +8294,17 @@ if test "$with_readdisplay" = yes; then
   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:8373: checking for X11/extensions/readdisplay.h" >&5
+echo "configure:8309: 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
-#line 8378 "configure"
+#line 8314 "configure"
 #include "confdefs.h"
 #include <X11/extensions/readdisplay.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8319: \"$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*
@@ -8423,7 +8359,7 @@ fi
 
     /*)
      echo $ac_n "checking for Iris Video headers""... $ac_c" 1>&6
-echo "configure:8438: checking for Iris Video headers" >&5
+echo "configure:8374: checking for Iris Video headers" >&5
      d=$with_sgivideo/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -8433,7 +8369,7 @@ echo "configure:8438: checking for Iris Video headers" >&5
      fi
 
      echo $ac_n "checking for Iris Video libs""... $ac_c" 1>&6
-echo "configure:8448: checking for Iris Video libs" >&5
+echo "configure:8384: checking for Iris Video libs" >&5
      d=$with_sgivideo/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -8466,17 +8402,17 @@ if test "$with_sgivideo" = yes; then
   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:8481: checking for dmedia/vl.h" >&5
+echo "configure:8417: 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
-#line 8486 "configure"
+#line 8422 "configure"
 #include "confdefs.h"
 #include <dmedia/vl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8491: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8427: \"$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*
@@ -8501,7 +8437,7 @@ fi
   if test "$have_sgivideo" = yes; then
     have_sgivideo=no
     echo $ac_n "checking for vlOpenVideo in -lvl""... $ac_c" 1>&6
-echo "configure:8516: checking for vlOpenVideo in -lvl" >&5
+echo "configure:8452: 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
@@ -8509,7 +8445,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lvl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8524 "configure"
+#line 8460 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8520,7 +8456,7 @@ int main() {
 vlOpenVideo()
 ; return 0; }
 EOF
-if { (eval echo configure:8535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8591,7 +8527,7 @@ if test -n "$with_zippy_req" ; then
   case "$with_zippy_req" in
     /*)
       echo $ac_n "checking for $with_zippy_req""... $ac_c" 1>&6
-echo "configure:8606: checking for $with_zippy_req" >&5
+echo "configure:8542: checking for $with_zippy_req" >&5
       if test -x "$with_zippy_req" ; then
         echo "$ac_t""yes" 1>&6
       else
@@ -8605,7 +8541,7 @@ echo "configure:8606: checking for $with_zippy_req" >&5
       # 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:8620: checking for $ac_word" >&5
+echo "configure:8556: 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
@@ -8655,7 +8591,7 @@ 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:8670: checking for $ac_word" >&5
+echo "configure:8606: 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
@@ -8689,7 +8625,7 @@ 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:8704: checking for $ac_word" >&5
+echo "configure:8640: 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
@@ -8724,7 +8660,7 @@ done
 
   if test -n "$emacs_exe" ; then
     echo $ac_n "checking for emacs yow""... $ac_c" 1>&6
-echo "configure:8739: checking for emacs yow" >&5
+echo "configure:8675: checking for emacs yow" >&5
     #
     # get emacs to tell us where the libexec directory is.
     #
@@ -8746,7 +8682,7 @@ echo "configure:8739: checking for emacs yow" >&5
 
   if test -z "$ac_cv_zippy_program" ; then
     echo $ac_n "checking for xemacs yow""... $ac_c" 1>&6
-echo "configure:8761: checking for xemacs yow" >&5
+echo "configure:8697: checking for xemacs yow" >&5
     if test -n "$xemacs_exe" ; then
       #
       # get xemacs to tell us where the libexec directory is.
@@ -8805,7 +8741,7 @@ 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:8820: checking for $ac_word" >&5
+echo "configure:8756: 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
@@ -8841,7 +8777,7 @@ 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:8856: checking for $ac_word" >&5
+echo "configure:8792: 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
@@ -8912,23 +8848,25 @@ if test \! -z "$libdir" ; then
 fi
 
 
+DEMO_MAN="xscreensaver-demo-old.man"
 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
+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_motif" = yes; then
   PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Xm
   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"
+  DEMO_MAN="xscreensaver-demo.man"
+fi
 
 
 if test "$have_kerberos" = yes; then
@@ -8949,7 +8887,7 @@ if test "$enable_locking" = yes; then
   LOCK_OBJS='$(LOCK_OBJS_1) $(PASSWD_OBJS)'
 else
   LOCK_SRCS='$(NOLOCK_SRCS_1)'
-  LOCK_OBJS='$(NOLOCK_SRCS_1)'
+  LOCK_OBJS='$(NOLOCK_OBJS_1)'
 fi
 
 if test "$need_setuid" = yes; then
@@ -8966,15 +8904,15 @@ if test "$have_gl" = yes; then
   GL_MEN='$(GL_MEN)'
   GL_KLUDGE="${tab}  "
 else
-  GL_KLUDGE="  -${tab}  "
+  GL_KLUDGE="-${tab}  "
 fi
 
 if test "$have_gle" = yes; then
   GLE_EXES='$(GLE_EXES)'
   GLE_MEN='$(GLE_MEN)'
-  GLE_KLUDGE="${tab}  "
+  GLE_KLUDGE="${tab}   "
 else
-  GLE_KLUDGE="  -${tab}  "
+  GLE_KLUDGE="-${tab}   "
 fi
 
 
@@ -9020,6 +8958,7 @@ fi
 
 
 
+
 
 
 APPDEFAULTS=$ac_x_app_defaults
@@ -9193,6 +9132,7 @@ 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%@DEMO_MAN@%$DEMO_MAN%g
 s%@SAVER_LIBS@%$SAVER_LIBS%g
 s%@MOTIF_LIBS@%$MOTIF_LIBS%g
 s%@GTK_LIBS@%$GTK_LIBS%g
index ed3a8193ef71517050cad4eaa218a3f7ed1c5705..322862f6dd55af18720a4a99551ce9e7830be6d3 100644 (file)
@@ -66,6 +66,8 @@ AC_DEFUN(AC_PROG_CC_ANSI,
   if test -n "$GCC"; then
     AC_MSG_RESULT(Turning on gcc compiler warnings.)
     CC="$CC -Wall -Wstrict-prototypes -Wnested-externs -Wno-format"
+    AC_MSG_RESULT(Disabling C++ comments in ANSI C code.)
+    CC="$CC -Wp,-lang-c89"
   else
     case "$host" in
       *-irix5* |*-irix6.[0-3]* )
@@ -563,7 +565,7 @@ AC_DEFUN(AC_CHECK_X_LIB, [
     LDFLAGS="$LDFLAGS -L$libdir"
   fi
   # note: $X_LIBS includes $x_libraries
-  LDFLAGS="$LDFLAGS $X_LIBS"
+  LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   AC_CHECK_LIB([$1], [$2], [$3], [$4], [$5])
   CPPFLAGS="$ac_save_CPPFLAGS"
@@ -1818,25 +1820,36 @@ if test "$with_gl" = yes; then
     ac_have_mesa_gl=$ac_cv_have_mesa_gl
  
 
+    gl_lib_1=""
+    GL_LIBS=""
+
+
+    # Some versions of MesaGL are compiled to require -lpthread.
+    # So if the Mesa headers exist, and -lpthread exists, then always
+    # link -lpthread after the Mesa libs (be they named -lGL or -lMesaGL.)
+    #
+    if test "$ac_have_mesa_gl" = yes; then
+      AC_CHECK_LIB(pthread, pthread_create, [GL_LIBS="-lpthread"], [],)
+    fi
+
+
     # If we have Mesa headers, check to see if we can link against -lMesaGL.
     # If we don't have Mesa headers, or we don't have -lMesaGL, try -lGL.
     # Else, warn that GL is busted.  (We have the headers, but no libs.)
     #
-    gl_lib_1=""
-    GL_LIBS=""
 
     if test "$ac_have_mesa_gl" = yes ; then
       AC_CHECK_X_LIB(MesaGL, glXCreateContext, 
                      [gl_lib_1="MesaGL"
-                      GL_LIBS="-lMesaGL -lMesaGLU"],
-                     [], -lMesaGLU -lX11 -lXext -lm)
+                      GL_LIBS="-lMesaGL -lMesaGLU $GL_LIBS"],
+                     [], -lMesaGLU $GL_LIBS -lX11 -lXext -lm)
     fi
 
     if test "$gl_lib_1" = "" ; then
       AC_CHECK_X_LIB(GL, glXCreateContext, 
                      [gl_lib_1="GL"
-                      GL_LIBS="-lGL -lGLU"],
-                     [], -lGLU -lX11 -lXext -lm)
+                      GL_LIBS="-lGL -lGLU $GL_LIBS"],
+                     [], -lGLU $GL_LIBS -lX11 -lXext -lm)
     fi
 
     if test "$gl_lib_1" = "" ; then
@@ -1907,24 +1920,6 @@ EOF
     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)],
@@ -2369,23 +2364,25 @@ if test \! -z "$libdir" ; then
 fi
 
 
+DEMO_MAN="xscreensaver-demo-old.man"
 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
+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_motif" = yes; then
   PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Xm
   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"
+  DEMO_MAN="xscreensaver-demo.man"
+fi
 
 
 if test "$have_kerberos" = yes; then
@@ -2406,7 +2403,7 @@ if test "$enable_locking" = yes; then
   LOCK_OBJS='$(LOCK_OBJS_1) $(PASSWD_OBJS)'
 else
   LOCK_SRCS='$(NOLOCK_SRCS_1)'
-  LOCK_OBJS='$(NOLOCK_SRCS_1)'
+  LOCK_OBJS='$(NOLOCK_OBJS_1)'
 fi
 
 if test "$need_setuid" = yes; then
@@ -2423,15 +2420,15 @@ if test "$have_gl" = yes; then
   GL_MEN='$(GL_MEN)'
   GL_KLUDGE="${tab}  "
 else
-  GL_KLUDGE="  -${tab}  "
+  GL_KLUDGE="-${tab}  "
 fi
 
 if test "$have_gle" = yes; then
   GLE_EXES='$(GLE_EXES)'
   GLE_MEN='$(GLE_MEN)'
-  GLE_KLUDGE="${tab}  "
+  GLE_KLUDGE="${tab}   "
 else
-  GLE_KLUDGE="  -${tab}  "
+  GLE_KLUDGE="-${tab}   "
 fi
 
 
@@ -2445,6 +2442,7 @@ AC_SUBST(INCLUDES)
 
 AC_SUBST(PREFERRED_DEMO_PROGRAM)
 AC_SUBST(ALL_DEMO_PROGRAMS)
+AC_SUBST(DEMO_MAN)
 AC_SUBST(SAVER_LIBS)
 AC_SUBST(MOTIF_LIBS)
 AC_SUBST(GTK_LIBS)
index 7e101dbd70e2ca1e2bcaeb76d6f5617d8f790507..3e830096a376a438322dfcee6564dc98ea4b4121 100644 (file)
@@ -66,8 +66,8 @@ 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
+GTK_SRCS       = demo-Gtk.c demo-Gtk-widgets.c
+GTK_OBJS       = demo-Gtk.o demo-Gtk-widgets.o
 
 ATHENA_SRCS    = dialogs-Xaw.c
 ATHENA_OBJS    = dialogs-Xaw.o
@@ -86,7 +86,8 @@ LOCK_OBJS_1   = lock.o passwd.o
 NOLOCK_SRCS_1  = lock.c
 NOLOCK_OBJS_1  = lock.o
 
-TEST_SRCS      = test-passwd.c test-uid.c test-xdpms.c test-grab.c test-apm.c
+TEST_SRCS      = test-passwd.c test-uid.c test-xdpms.c test-grab.c \
+                 test-apm.c xdpyinfo.c
 
 MOTIF_LIBS     = @MOTIF_LIBS@
 GTK_LIBS       = @GTK_LIBS@
@@ -135,7 +136,7 @@ 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_OBJS_1    = prefs.o demo-Xm.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)
@@ -150,11 +151,15 @@ CMD_LIBS  = $(LIBS) $(X_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 \
+HDRS           = XScreenSaver_ad.h xscreensaver.h prefs.h remote.h \
+                 demo-Gtk-widgets.h demo-Gtk-stubs.h
+MEN            = xscreensaver.man @DEMO_MAN@ \
+                 xscreensaver-command.man
+ALL_MEN                = xscreensaver.man \
+                 xscreensaver-demo.man xscreensaver-demo-old.man \
                  xscreensaver-command.man
 EXTRAS         = README Makefile.in XScreenSaver.ad.in xscreensaver.pam \
-                 xscreensaver.kss .gdbinit
+                 xscreensaver.kss xscreensaver-demo.glade .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
@@ -162,7 +167,7 @@ VMSFILES    = compile_axp.com compile_decc.com link_axp.com link_decc.com \
 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)
+                 $(CMD_SRCS) $(HDRS) $(TEST_SRCS) $(ALL_MEN)
 
 
 default: $(EXES)
@@ -238,6 +243,7 @@ install-man: $(MEN)
        if [ ! -d $(man1dir) ]; then $(INSTALL_DIRS) $(man1dir) ; fi ;  \
        for man in $$men; do                                            \
          instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ;     \
+         instname=`echo $$instname | sed 's/-old//'` ;                 \
          echo $(INSTALL_DATA) $(srcdir)/$$man $(man1dir)/$$instname ;  \
          $(INSTALL_DATA) $(srcdir)/$$man $(man1dir)/$$instname ;       \
        done
@@ -474,9 +480,8 @@ xscreensaver-demo-Xm: $(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) \
+xscreensaver-demo-Gtk: $(DEMO_OBJS) $(GTK_OBJS)
+       $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(GTK_OBJS) $(LIBS) $(X_LIBS) \
        $(GTK_LIBS) $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS)
 
 xscreensaver-demo-Xaw: $(DEMO_OBJS) $(ATHENA_OBJS) demo-Xaw.o
@@ -492,9 +497,6 @@ xscreensaver-demo-Xaw3d: $(DEMO_OBJS) $(ATHENA_OBJS) demo-Xaw.o
 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
@@ -528,6 +530,15 @@ test-apm: test-apm.o
        $(CC) $(LDFLAGS) -o $@ test-apm.o $(SAVER_LIBS) -lapm
 
 
+xdpyinfo.o: xdpyinfo.c
+       $(CC) -c $(INCLUDES) -DHAVE_GLX $(CFLAGS) $(X_CFLAGS) \
+         $(srcdir)/xdpyinfo.c
+
+xdpyinfo: xdpyinfo.o
+       $(CC) $(LDFLAGS) -o $@ xdpyinfo.o \
+               $(LIBS) $(X_LIBS) @GL_LIBS@ \
+               $(X_PRE_LIBS) -lX11 -lXext $(X_EXTRA_LIBS) -lm
+
 
 ##############################################################################
 #
@@ -572,8 +583,18 @@ 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
+demo-Gtk.o: ../config.h
+demo-Gtk.o: $(UTILS_SRC)/version.h
+demo-Gtk.o: $(srcdir)/prefs.h
+demo-Gtk.o: $(UTILS_SRC)/resources.h
+demo-Gtk.o: $(UTILS_SRC)/visual.h
+demo-Gtk.o: $(srcdir)/remote.h
+demo-Gtk.o: $(UTILS_SRC)/usleep.h
+demo-Gtk.o: $(srcdir)/demo-Gtk-widgets.h
+demo-Gtk.o: XScreenSaver_ad.h
+demo-Gtk-widgets.o: ../config.h
+demo-Gtk-widgets.o: $(srcdir)/demo-Gtk-stubs.h
+demo-Gtk-widgets.o: $(srcdir)/demo-Gtk-widgets.h
 dialogs-Xaw.o: ../config.h
 dialogs-Xaw.o: $(UTILS_SRC)/visual.h
 passwd-pwent.o: ../config.h
index cccc369372e0c9ffd900c306c717a8799d683a00..bc0f4031777c0e795e920c6a782602b302aa6861 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 3.19
-!                                30-Oct-99
+!                              version 3.20
+!                                12-Nov-99
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
 ! 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\
-               ccurve -root                                            \n\
-               blaster -root                                           \n\
-               bumps -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\
-@GLE_KLUDGE@ GL:  extrusion -root                                      \n
+*programs:                                                                   \
+                "Qix (solid)"  qix -root -solid -delay 0 -segments 100     \n\
+          "Qix (transparent)"  qix -root -count 4 -solid -transparent      \n\
+               "Qix (linear)"  qix -root -count 5 -solid -transparent        \
+                                 -linear -segments 250 -size 100           \n\
+         "Attraction (balls)"  attraction -root -mode balls                \n\
+         "Attraction (lines)"  attraction -root -mode lines -points 3        \
+                                 -segments 200                             \n\
+       "Attraction (splines)"  attraction -root -mode splines -segments      \
+                                 300                                       \n\
+       "Attraction (orbital)"  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\
+             "Ripples (oily)"  ripples -root -oily -light 2                \n\
+             "Ripples (stir)"  ripples -root -oily -light 2 -stir          \n\
+          "Ripples (desktop)"  ripples -root -water -light 6               \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 (trails)"  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 -max-velocity 0.5 -elasticity      \
+                                 0.9                                       \n\
+                               starfish -root                              \n\
+            "Starfish (blob)"  starfish -root -blob                        \n\
+                               munch -root                                 \n\
+                               fadeplot -root                              \n\
+                               coral -root -delay 0                        \n\
+                               mountain -root                              \n\
+                               triangle -root -delay 1                     \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 (mobile)"  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 (spots)"  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 2 -count 20               \n\
+                    "Petri 2"  petri -root -minlifespeed 0.02                \
+                                 -maxlifespeed 0.03 -minlifespan 1           \
+                                 -maxlifespan 1 -instantdeathchan 0          \
+                                 -minorchan 0 -anychan 0.3                 \n\
+                               shadebobs -root                             \n\
+                               ccurve -root                                \n\
+                               blaster -root                               \n\
+                               bumps -root                                 \n\
+  default-n:                   webcollage -root                            \n\
+  default-n:  "WebCollage (whacked)"                                         \
+                               webcollage -root -filter                      \
+                                 'vidwhacker -stdin -stdout'               \n\
+- default-n:                   vidwhacker -root                            \n\
+                                                                             \
+- mono:        "Rocks (mono)"  rocks -root                                 \n\
+  color:       "Rocks (color)"         rocks -root -fg darksalmon                  \n\
+- mono:           "Qix (xor)"  qix -root -linear -count 5 -size 200          \
+                                 -spread 30 -segments 75 -solid -xor       \n\
+  color:   "Attraction (poly)"         attraction -root -mode polygons             \n\
+- color:  "Attraction (filled)"        attraction -root -mode filled-splines         \
+                                 -segments 0                               \n\
+- Color:  "Attraction (glow)"  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 (textures)"                                        \
+                                 pulsar -root -texture -mipmap               \
+                                 -texture_quality -light -fog              \n\
+@GLE_KLUDGE@GL:                        extrusion -root                             \n\
+@GL_KLUDGE@ GL:                        sierpinski3d -root                          \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\
+!                              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\
+!    default:  "Xtacy (funky)" xtacy -root -delay 100 -funky -number 3     \n\
+!    default:  "Xtacy (grav)"  xtacy -root -delay 100 -gravity             \n\
+!    default:  "Xtacy (mixer)" xtacy -root -delay 100 -mixer               \n\
+!    default:  "Xtacy (taffy)" 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\
+!    default-n:  "Slideshow"   xv -root -rmode 5 -random -viewonly           \
+!                                -wloop -wait 30 $HOME/bitmaps/*.jpg       \n\
 !
 ! or, if you prefer "xli" to "xv", like this: (but note that xli's "-delay"
 ! option doesn't work in conjunction with "-onroot", so you need to add a
 ! line for each image individually... "xv" is better in this respect.)
 !
-!     default-n: xli -quiet -onroot -center -border black                 \
-!                    $HOME/bitmaps/pic1.jpg                             \n\
-!     default-n: xli -quiet -onroot -center -border black                 \
-!                    $HOME/bitmaps/pic2.jpg                             \n\
-!     default-n: xli -quiet -onroot -center -border black                 \
-!                    $HOME/bitmaps/pic3.jpg                             \n\
+!    default-n: xli -quiet -onroot -center -border black                     \
+!                $HOME/bitmaps/pic1.jpg                                    \n\
+!    default-n: xli -quiet -onroot -center -border black                     \
+!                $HOME/bitmaps/pic2.jpg                                    \n\
+!    default-n: xli -quiet -onroot -center -border black                     \
+!                $HOME/bitmaps/pic3.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
@@ -543,3 +554,700 @@ XScreenSaver.preferences_dialog*Command.internalHeight: 4
 *warning_dialog*Command.vertDistance:          20
 *warning_dialog*Command.internalWidth:         20
 *warning_dialog*Command.internalHeight:                5
+
+
+!=============================================================================
+!
+! Online documentation for xscreensaver-demo.
+!
+!=============================================================================
+
+! sanity check -- hands off.
+*hacks.documentation.isInstalled: True
+
+*hacks.grav.documentation:                                             \
+This program draws a simple orbital simulation.         If you turn on         \
+trails, it looks kind of like a cloud-chamber photograph.  Written by  \
+Greg Bowering.
+
+*hacks.qix.documentation:                                              \
+This is the swiss army chainsaw of qix programs.  It bounces a series  \
+of line segments around the screen, and uses variations on this basic  \
+motion pattern to produce all sorts of different presentations: line   \
+segments, filled polygons, overlapping translucent areas...  Written   \
+by Jamie Zawinski.
+
+*hacks.attraction.documentation:                                       \
+Like qix, this uses a simple simple motion model to generate many      \
+different display modes.  The control points attract each other up to  \
+a certain distance, and then begin to repel each other.         The            \
+attraction/repulsion is proportional to the distance between any two   \
+particles, similar to the strong and weak nuclear forces.              \
+                                                                   \n\n\
+One of the most interesting ways to watch this hack is simply as       \
+bouncing balls, because their motions and interactions with each       \
+other are so odd.  Sometimes two balls will get into a tight orbit     \
+around each other, to be interrupted later by a third, or by the edge  \
+of the screen. It looks quite chaotic.                                 \
+                                                                   \n\n\
+Written by Jamie Zawinski, based on Lisp code by John Pezaris.
+
+*hacks.pyro.documentation:                                             \
+Pyro draws exploding fireworks.         Blah blah blah.  Written by Jamie      \
+Zawinski.
+
+*hacks.helix.documentation:                                            \
+This repeatedly generates spirally string-art-ish patterns.  Written   \
+by Jamie Zawinski.
+
+*hacks.pedal.documentation:                                            \
+This is sort of a combination spirograph/string-art.  It generates a   \
+large, complex polygon, and lets the X server do the bulk of the work  \
+by giving it an even/odd winding rule. Written by Dale Moore, based    \
+on some ancient PDP-11 code.
+
+*hacks.rorschach.documentation:                                                \
+This generates random inkblot patterns.         The algorithm is deceptively   \
+simple for how well it works; it merely walks a dot around the screen  \
+randomly, and then reflects the image horizontally, vertically, or     \
+both.  Any deep-seated neurotic tendencies which this program reveals  \
+are your own problem.  Written by Jamie Zawinski.
+
+*hacks.hopalong.documentation:                                         \
+This draws lacy fractal patterns, based on iteration in the imaginary  \
+plane, from a 1986 Scientific American article.         Mostly written by      \
+Patrick Naughton.
+
+*hacks.greynetic.documentation:                                                \
+This draws random colored and stippled rectangles.  Written by Jamie   \
+Zawinski.
+
+*hacks.xroger.documentation:                                           \
+The XScreenSaver logo. Don't you hate it?  So do I.  Would you like    \
+to design a new logo for XScreenSaver? If so, send jwz your            \
+submissions.
+
+*hacks.imsmap.name: IMSmap
+*hacks.imsmap.documentation:                                           \
+This generates random cloud-like patterns.  It looks quite different   \
+in monochrome and color.  The basic idea is to take four points on     \
+the edge of the image, and assign each a random ``elevation''. Then    \
+find the point between them, and give it a value which is the average  \
+of the other four, plus some small random offset. Then coloration is   \
+done based on elevation.                                               \
+                                                                   \n\n\
+The color selection is done by binding the elevation to either hue,    \
+saturation, or brightness, and assigning random values to the others.  \
+The ``brightness'' mode tends to yield cloudlike patterns, and the     \
+others tend to generate images that look like heat-maps or CAT-scans.  \
+Written by Juergen Nickelsen and Jamie Zawinski.
+
+*hacks.slidescreen.name: SlideScreen
+*hacks.slidescreen.documentation:                                      \
+This grabs an image of whatever is on your screen, divides it into a   \
+grid, and then randomly shuffles the squares around as if it was one   \
+of those annoying ``16-puzzle'' games, where there is a grid of                \
+squares, one of which is missing.  I hate trying to solve those                \
+puzzles, but watching one permute itself is more amusing.  Written by  \
+Jamie Zawinski.
+
+*hacks.decayscreen.name: DecayScreen
+*hacks.decayscreen.documentation:                                      \
+This grabs an image of whatever is on your screen, and makes it melt.  \
+You've no doubt seen this effect before, but no screensaver would      \
+really be complete without it. It works best if there's something      \
+colorful visible.  Warning, if the effect continues after the screen   \
+saver is off, seek medical attention.  Written by David Wald and       \
+Vivek Khera.                                                           \
+                                                                   \n\n\
+A number of these screenhacks have the ability to take an image of     \
+your desktop and manipulate it in some way.  On SGI systems, these     \
+programs are able to (at random) pull their source image from the      \
+system's video input instead!  This works nicely if you leave some     \
+some random television station plugged in.
+
+*hacks.jigsaw.documentation:                                           \
+This grabs a screen image, carves it up into a jigsaw puzzle,          \
+shuffles it, and then solves the puzzle.  This works especially well   \
+when you feed it an external video signal instead of letting it grab   \
+the screen image (actually, I guess this is generally true...) When    \
+it is grabbing a video image, it is sometimes pretty hard to guess     \
+what the image is going to look like once the puzzle is solved.                \
+Written by Jamie Zawinski.
+
+*hacks.blitspin.name: BlitSpin
+*hacks.blitspin.documentation:                                         \
+The ``blitspin'' hack repeatedly rotates a bitmap by 90 degrees by     \
+using logical operations: the bitmap is divided into quadrants, and    \
+the quadrants are shifted clockwise.  Then the same thing is done      \
+again with progressively smaller quadrants, except that all            \
+sub-quadrants of a given size are rotated in parallel. Written by      \
+Jamie Zawinski based on some cool SmallTalk code seen in in Byte       \
+Magazine in 1981.                                                      \
+                                                                   \n\n\
+As you watch it, the image appears to dissolve into static and then    \
+reconstitute itself, but rotated. You can provide the image to use,    \
+as an XBM or XPM file, or tell it to grab a screen image and rotate    \
+that.
+
+*hacks.slip.documentation:                                             \
+This program throws some random bits on the screen, then sucks them    \
+through a jet engine and spews them out the other side.         To avoid       \
+turning the image completely to mush, every now and then it will and   \
+then it interjects some splashes of color into the scene, or go into   \
+a spin cycle, or stretch the image like taffy, or (this is my          \
+addition) grab an image of your current desktop to chew on.            \
+Originally written by Scott Draves; whacked on by Jamie Zawinski.
+
+*hacks.distort.documentation:                                          \
+This hack grabs an image of the screen, and then lets a transparent    \
+lens wander around the screen, magnifying whatever is underneath.      \
+Written by Jonas Munsin.
+
+*hacks.spotlight.documentation:                                                \
+Draws a spotlight scanning across a black screen, illumnating the      \
+underlying desktop when it passes.  Written by Rick Schultz.
+
+*hacks.hypercube.documentation:                                                \
+This displays 2D projections of the sequence of 3D objects which are   \
+the projections of the 4D analog to the cube: as a square is composed  \
+of four lines, each touching two others; and a cube is composed of     \
+six squares, each touching four others; a hypercube is composed of     \
+eight cubes, each touching six others. To make it easier to            \
+visualize the rotation, it uses a different color for the edges of     \
+each face.  Don't think about it too long, or your brain will melt.    \
+Written by Joe Keane, Fritz Mueller, and Jamie Zawinski.
+
+*hacks.halo.documentation:                                             \
+This draws trippy psychedelic circular patterns that hurt to look at.  \
+It can also animate the control-points, but that takes a lot of CPU    \
+and bandwidth. Written by Jamie Zawinski.
+
+*hacks.maze.documentation:                                             \
+This is the ancient X maze demo, modified to work with xscreensaver.   \
+It generates a random maze, then solves it with visual feedback.       \
+Originally by Jim Randell; modified by a cast of thousands.
+
+*hacks.noseguy.documentation:                                          \
+A little man with a big nose wanders around your screen saying         \
+things.         The things which he says can come from a file, or from an      \
+external program like `zippy' or `fortune'.  This was extracted from   \
+`xnlock' by Dan Heller.         Colorized by Jamie Zawinski.
+
+*hacks.flame.documentation:                                            \
+Another iterative fractal generator.  Written by Scott Draves.
+
+*hacks.lmorph.name: LMorph
+*hacks.lmorph.documentation:                                           \
+This generates random spline-ish line drawings and morphs between      \
+them.  Written by Sverre H.  Huseby and Glenn T.  Lines.
+
+*hacks.deco.documentation:                                             \
+This one subdivides and colors rectangles randomly.  It looks kind of  \
+like Brady-Bunch-era rec-room wall paneling.  (Raven says: ``this      \
+screensaver is ugly enough to peel paint.'')  Written by Jamie         \
+Zawinski, inspired by Java code by Michael Bayne.
+
+*hacks.moire.documentation:                                            \
+This one draws cool circular interference patterns.  Most of the       \
+circles you see aren't explicitly rendered, but show up as a result    \
+of interactions between the other pixels that were drawn.  Written by  \
+Jamie Zawinski, inspired by Java code by Michael Bayne.         As he          \
+pointed out, the beauty of this one is that the heart of the display   \
+algorithm can be expressed with just a pair of loops and a handful of  \
+arithmetic, giving it a high ``display hack metric''.
+
+*hacks.moire2.documentation:                                           \
+Another example of the fun you can have with moire                     \
+interference patterns; this hack generates fields of concentric                \
+circles or ovals, and combines the planes with various operations.     \
+The planes are moving independently of one another, causing the                \
+interference lines to ``spray.''  Written by Jamie Zawinski.
+
+*hacks.lightning.documentation:                                                \
+This one draws crackling fractal lightning bolts.  It's simple,                \
+direct, and to the point.  If only it had sound... Written by Keith    \
+Romberg.
+
+*hacks.strange.documentation:                                          \
+This draws strange attractors: it's a colorful,                                \
+unpredictably-animating field of dots that swoops and twists around.   \
+The motion is very nice.  Written by Massimino Pascal.
+
+*hacks.spiral.documentation:                                           \
+Moving circular patterns, by Peter Schmitzberger.  Moving circular     \
+patterns means moire; interference patterns, of course.
+
+*hacks.laser.documentation:                                            \
+Moving radiating lines, that look vaguely like scanning laser beams.   \
+Written by Pascal Pensa.  (Frankie say: relax.)
+
+*hacks.grav.documentation:                                             \
+This program draws a simple orbital simulation.         If you turn on         \
+trails, it looks kind of like a cloud-chamber photograph.  Written     \
+by Greg Bowering.
+
+*hacks.drift.documentation:                                            \
+How could one possibly describe this except as ``drifting recursive    \
+fractal cosmic flames?''  Another fine hack from the Scott Draves      \
+collection of fine hacks.
+
+*hacks.ifs.name: IFS
+*hacks.ifs.documentation:                                              \
+This one draws spinning, colliding iterated-function-system images.    \
+Written by Massimino Pascal.
+
+*hacks.julia.documentation:                                            \
+This one draws spinning, animating (are you detecting a pattern here   \
+yet?)  explorations of the Julia set. You've probably seen static      \
+images of this fractal form before, but it's a lot of fun to watch in  \
+motion as well.         One interesting thing is that there is a small         \
+swinging dot passing in front of the image, which indicates the                \
+control point from which the rest of the image was generated.          \
+Written by Sean McCullough.
+
+*hacks.penrose.documentation:                                          \
+Draws quasiperiodic tilings; think of the implications on modern       \
+formica technology.  Written by Timo Korvola.                          \
+                                                                   \n\n\
+In April 1997, Sir Roger Penrose, a British math professor who has     \
+worked with Stephen Hawking on such topics as relativity, black                \
+holes, and whether time has a beginning, filed a                       \
+copyright-infringement lawsuit against the Kimberly-Clark              \
+Corporation, which Penrose said copied a pattern he created (a         \
+pattern demonstrating that ``a nonrepeating pattern could exist in     \
+nature'') for its Kleenex quilted toilet paper.        Penrose said he         \
+doesn't like litigation but, ``When it comes to the population of      \
+Great Britain being invited by a multinational to wipe their bottoms   \
+on what appears to be the work of a Knight of the Realm, then a last   \
+stand must be taken.''                                                 \
+                                                                   \n\n\
+As reported by News of the Weird #491, 4-jul-1997.
+
+*hacks.sierpinski.documentation:                                       \
+This draws the two-dimensional variant of the recursive Sierpinski     \
+triangle fractal.  Written by Desmond Daignault.
+
+*hacks.braid.documentation:                                            \
+Draws random color-cycling inter-braided concentric circles.  Written  \
+by John Neil.
+
+*hacks.galaxy.documentation:                                           \
+This draws spinning galaxies, which then collide and scatter their     \
+stars to the, uh, four winds or something.  Originally an Amiga                \
+program by Uli Siegmund.
+
+*hacks.bouboule.documentation:                                         \
+This draws what looks like a spinning, deforming baloon with           \
+varying-sized spots painted on its invisible surface.  Written by      \
+Jeremie Petit.
+
+*hacks.swirl.documentation:                                            \
+More flowing, swirly patterns. This version is by M.  Dobie and R.     \
+Taylor, but you might have seen a Mac program similar to this called   \
+FlowFazer.  There is also a cool Java applet of a similar concept
+
+*hacks.flag.documentation:                                             \
+This draws a waving colored flag, that undulates its way around the    \
+screen.         The trick is the flag can contain arbitrary text and images.   \
+By default, it displays either the current system name and OS          \
+type, or a picture of ``Bob,'' but you can replace the text or the     \
+image with a command-line option.  Written by Charles Vidal and Jamie  \
+Zawinski.
+
+*hacks.sphere.documentation:                                           \
+Another of the classic screenhacks of the distant past, this one       \
+draws shaded spheres in multiple colors.  This hack traces its         \
+lineage back to Tom Duff in 1982.
+
+*hacks.forest.documentation:                                           \
+This draws fractal trees.  Written by Peter Baumung.  Everybody loves  \
+fractals, right?
+
+*hacks.lisa.documentation:                                             \
+This draws Lisajous loops, by Caleb Cullen.  Remember that device      \
+they had the Phantom Zone prisoners in during their trial in           \
+Superman?  I think that was one of these.
+
+*hacks.lissie.documentation:                                           \
+Another Lissajous figure.  This one draws the progress of circular     \
+shapes along a path.  Written by Alexander Jolk.
+
+*hacks.goop.documentation:                                             \
+This draws set of animating, transparent, amoeba-like blobs.  The      \
+blobs change shape as they wander around the screen, and they are      \
+translucent, so you can see the lower blobs through the higher ones,   \
+and when one passes over another, their colors merge.  Written by      \
+Jamie Zawinski.         I got the idea for this from a cool mouse pad I        \
+have, which achieves the same kind of effect in real life by having    \
+several layers plastic with colored oil between them.  Written by      \
+Jamie Zawinski.
+
+*hacks.starfish.documentation:                                         \
+This generates a sequence of undulating, throbbing, star-like          \
+patterns which pulsate, rotate, and turn inside out.  Another display  \
+mode uses these shapes to lay down a field of colors, which are then   \
+cycled.         The motion is very organic.  Written by Jamie Zawinski.
+
+*hacks.munch.documentation:                                          \n\
+        DATAI 2                                                              \n\
+        ADDB 1,2                                                     \n\
+        ROTC 2,-22                                                   \n\
+        XOR 1,2                                                              \n\
+        JRST .-4                                                     \n\
+                                                                     \n\
+As reported by HAKMEM, in 1962, Jackson Wright wrote the above PDP-1   \
+code. That code still lives on in this screenhack, some 35 years       \
+later.  The number of lines of enclosing code has increased            \
+substantially, however.  This version is by Tim Showalter.
+
+*hacks.fadeplot.name: FadePlot
+*hacks.fadeplot.documentation:                                         \
+Draws what looks like a waving ribbon following a sinusoidal path.     \
+Written by Bas van Gaalen and Charles Vidal.
+
+*hacks.coral.documentation:                                            \
+Simulates coral growth, albeit somewhat slowly.         This image doesn't     \
+really do it justice.  Written by Frederick Roeber.
+
+*hacks.mountain.documentation:                                         \
+Generates random 3d plots that look vaguely mountainous.  Written by   \
+Pascal Pensa.
+
+*hacks.triangle.documentation:                                         \
+Generates random mountain ranges using iterative subdivision of                \
+triangles.  Written by Tobias Gloth.
+
+*hacks.worm.documentation:                                             \
+An ancient xlock hack that draws multicolored worms that crawl around  \
+the screen.  Written by Brad Taylor, Dave Lemke, Boris Putanec, and    \
+Henrik Theiling.
+
+*hacks.rotor.documentation:                                            \
+Another ancient xlock demo, this one by Tom Lawrence.  It draws a      \
+line segment moving along a complex spiraling curve.  I tweaked this   \
+to generate curvier lines, but still frames of it don't look like      \
+much.
+
+*hacks.ant.documentation:                                              \
+A cellular automaton that is really a two-dimensional Turing machine:  \
+as the heads (``ants'') walk along the screen, they change pixel       \
+values in their path.  Then, as they pass over changed pixels, their   \
+behavior is influenced.         Written by David Bagley.
+
+*hacks.demon.documentation:                                            \
+A cellular automaton that starts with a random field, and organizes    \
+it into stripes and spirals.  Written by David Bagley.
+
+*hacks.loop.documentation:                                             \
+This one produces loop-shaped colonies that spawn, age, and            \
+eventually die.         Written by David Bagley.
+
+*hacks.vines.documentation:                                            \
+This one generates a continuous sequence of small, curvy geometric     \
+patterns.  It scatters them around your screen until it fills up,      \
+then it clears the screen and starts over.  Written by Tracy Camp and  \
+David Hansen.
+
+*hacks.kaleidescope.documentation:                                     \
+Another clone of an ancient meme, consisting largely of frenetic       \
+rotational motion of colored lines.  This one is by Ron Tapia. The     \
+motion is nice, but I think it needs more solids, or perhaps just      \
+brighter colors.  More variations in the rotational speed might help,  \
+too.
+
+*hacks.xjack.documentation:                                            \
+This program behaves schizophrenically and makes a lot of typos.       \
+Written by Jamie Zawinski.  If you haven't seen Stanley Kubrick's      \
+masterpiece, ``The Shining,'' you won't get it.         Those who have         \
+describe this hack as ``inspired.''
+
+*hacks.xlyap.documentation:                                            \
+This generates pretty fractal pictures by doing funky math involving   \
+the ``Lyapunov exponent.''  It has a cool interactive mode, too.       \
+Written by Ron Record.
+
+*hacks.cynosure.documentation:                                         \
+A hack similar to `greynetic', but less frenetic.  The first           \
+implementation was by Stephen Linhart; then Ozymandias G. Desiderata   \
+wrote a Java applet clone.  That clone was discovered by Jamie         \
+Zawinski, and ported to C for inclusion here.
+
+*hacks.flow.documentation:                                             \
+Another series of strange attractors: a flowing series of points,      \
+making strange rotational shapes.  Written by Jeff Butterworth.
+
+*hacks.epicycle.documentation:                                         \
+This program draws the path traced out by a point on the edge of a     \
+circle.         That circle rotates around a point on the rim of another       \
+circle, and so on, several times. These were the basis for the         \
+pre-heliocentric model of planetary motion.  Written by James          \
+Youngman.
+
+*hacks.interference.documentation:                                     \
+Another color-field hack, this one works by computing decaying         \
+sinusoidal waves, and allowing them to interfere with each other as    \
+their origins move.  Written by Hannu Mallat.
+
+*hacks.truchet.documentation:                                          \
+This draws line- and arc-based Truchet patterns that tile the screen.  \
+Written by Adrian Likins.
+
+*hacks.bsod.name: BSOD
+*hacks.bsod.documentation:                                             \
+BSOD stands for ``Blue Screen of Death.''  The finest in personal      \
+computer emulation, this hack simulates popular screen savers from a   \
+number of less robust operating systems.  Written by Jamie Zawinski.
+
+*hacks.crystal.documentation:                                          \
+Moving polygons, similar to a kaleidescope (more like a kaleidescope   \
+than the hack called `kaleid,' actually.) This one by Jouk Jansen.
+
+*hacks.discrete.documentation:                                         \
+More ``discrete map'' systems, including new variants of Hopalong and  \
+Julia, and a few others.  Written by Tim Auckland.
+
+*hacks.kumppa.documentation:                                           \
+Spiraling, spinning, and very, very fast splashes of color rush                \
+toward the screen.  Written by Teemu Suutari.
+
+*hacks.rd-bomb.name: RD-Bomb
+*hacks.rd-bomb.documentation:                                          \
+Another variation of the `Bomb' program by Scott Draves.  This draws   \
+a grid of growing square-like shapes that, once they overtake each     \
+other, react in unpredictable ways.  ``RD'' stands for                 \
+reaction-diffusion.
+
+*hacks.sonar.documentation:                                            \
+This program draws a simulation of a sonar screen.  Written by         \
+default, it displays a random assortment of ``bogies'' on the screen,  \
+but if compiled properly, it can ping (pun intended) your local                \
+network, and actually plot the proximity of the other hosts on your    \
+network to you.         It would be easy to make it monitor other sources of   \
+data, too.  (Processes?         Active network connections?  CPU usage per     \
+user?) Written by Stephen Martin.
+
+*hacks.t3d.name: T3D
+*hacks.t3d.documentation:                                              \
+This draws a working analog clock composed of floating, throbbing      \
+bubbles.  Written by Bernd Paysan.
+
+*hacks.penetrate.documentation:                                                \
+This hack simulates the classic arcade game Missile Command.  Written  \
+by Adam Miller.
+
+*hacks.deluxe.documentation:                                           \
+This draws a pulsing sequence of stars, circles, and lines.  It would  \
+look better if it was faster, but as far as I can tell, there is no    \
+way to make this be both: fast, and flicker-free.  Yet another reason  \
+X sucks.  Written by Jamie Zawinski.
+
+*hacks.compass.documentation:                                          \
+This draws a compass, with all elements spinning about randomly, for   \
+that ``lost and nauseous'' feeling. Written by Jamie Zawinski.
+
+*hacks.squiral.documentation:                                          \
+Draws a set of interacting, square-spiral-producing automata.  The     \
+spirals grow outward until they hit something, then they go around     \
+it.  Written by Jeff Epler.
+
+*hacks.xflame.documentation:                                           \
+Draws a simulation of pulsing fire.  It can also take an arbitrary     \
+image and set it on fire too.  Written by Carsten Haitzler, hacked on  \
+by many others.
+
+*hacks.wander.documentation:                                           \
+Draws a colorful random-walk, in various forms.         Written by Rick        \
+Campbell.
+
+*hacks.critical.documentation:                                         \
+Draws a system of self-organizing lines.  It starts out as random      \
+squiggles, but after a few iterations, order begins to appear.         \
+Written by Martin Pool.
+
+*hacks.phosphor.documentation:                                         \
+Draws a simulation of an old terminal, with large pixels and           \
+long-sustain phosphor. It can run any program as a source of the text  \
+it displays.  Written by Jamie Zawinski.
+
+*hacks.xmatrix.documentation:                                          \
+A rendition of the text scrolls seen in the movie ``The Matrix.''      \
+Written by Jamie Zawinski.
+
+*hacks.petri.documentation:                                            \
+This simulates colonies of mold growing in a petri dish.  Growing      \
+colored circles overlap and leave spiral interference in their wake.   \
+Written by Dan Bornstein.
+
+*hacks.shadebobs.name: ShadeBobs
+*hacks.shadebobs.documentation:                                                \
+This draws smoothly-shaded oscilating oval patterns, that look         \
+something like vapor trails or neon tubes.  Written by Shane Smit.
+
+*hacks.ccurve.name: C Curve
+*hacks.ccurve.documentation:                                           \
+Generates self-similar linear fractals, including the classic ``C      \
+Curve.''  Written by Rick Campbell.
+
+*hacks.blaster.documentation:                                          \
+Draws a simulation of flying space-combat robots (cleverly disguised   \
+as colored circles) doing battle in front of a moving star field.      \
+Written by Jonathan Lin.
+
+*hacks.bumps.documentation:                                            \
+A bit like `Spotlight', except that instead of merely exposing part    \
+of your desktop, it creates a bump map from it.         Basically, it          \
+3D-izes a roaming section of your desktop, based on color intensity.   \
+Written by Shane Smit.
+
+*hacks.webcollage.name: WebCollage
+*hacks.webcollage.documentation:                                       \
+This program makes collages out of random images pulled off of the     \
+World Wide Web.         It finds these images by doing random web searches,    \
+and then extracting images from the returned pages.  It can also be    \
+set up to filter the images through the `VidWhacker' program, above,   \
+which looks really great.                                              \
+                                                                   \n\n\
+(Note that most of the images it finds are text, and not pictures.     \
+This is because most of the web is pictures of text.  Which is pretty  \
+sad.)  Written by Jamie Zawinski.
+
+*hacks.vidwhacker.name: VidWhacker
+*hacks.vidwhacker.documentation:                                       \
+This is actually just a shell script that grabs a frame of video from  \
+the system's video input, and then uses some PBM filters (chosen at    \
+random) to manipulate and recombine the video frame in various ways    \
+(edge detection, subtracting the image from a rotated version of       \
+itself, etc.)  Then it displays that image for a few seconds, and      \
+does it again. This works really well if you just feed broadcast       \
+television into it.                                                    \
+                                                                   \n\n\
+Currently, the three lines of the script that actually grab the                \
+source picture are SGI specific, but it should be trivial to adapt it  \
+to work on other systems that can grab video (please send me the       \
+changes if you do this...)
+
+*hacks.rocks.documentation:                                            \
+This draws an animation of flight through an asteroid field, with      \
+changes in rotation and direction.  It can also display 3D             \
+separations for red/blue glasses!  Mostly written by Jamie Zawinski.
+
+*hacks.bubbles.documentation:                                          \
+This simulates the kind of bubble formation that happens when water    \
+boils:small bubbles appear, and as they get closer to each other,      \
+they combine to form larger bubbles, which eventually pop.  Written    \
+by James Macnicol.
+
+*hacks.gears.documentation:                                            \
+This draws a set of turning, interlocking gears, rotating in three     \
+dimensions.  Another GL hack, by Danny Sung, Brian Paul, and Ed                \
+Mackey.
+
+*hacks.superquadrics.documentation:                                    \
+Ed Mackey reports that he wrote the first version of this program in   \
+BASIC on a Commodore 64 in 1987, as a 320x200 black and white          \
+wireframe.  Now it is GL and has specular reflections.
+
+*hacks.morph3d.name: Morph3D
+*hacks.morph3d.documentation:                                          \
+Another 3d shape-changing GL hack, by Marcelo Vianna.  It has the      \
+same shiny-plastic feel as Superquadrics, as many computer-generated   \
+objects do...
+
+*hacks.cage.documentation:                                             \
+This draws Escher's ``Impossible Cage,'' a 3d analog of a moebius      \
+strip, and rotates it in three dimensions.  Written by Marcelo         \
+Vianna.
+
+*hacks.moebius.documentation:                                          \
+Another M.  C. Escher hack by Marcelo Vianna, this one draws           \
+``Moebius Strip II,'' a GL image of ants walking along the surface of  \
+a moebius strip.
+
+*hacks.stairs.documentation:                                           \
+by Marcelo Vianna's third Escher GL hack, this one draws an            \
+``infinite'' staircase.
+
+*hacks.pipes.documentation:                                            \
+If you've ever been in the same room with a Windows NT machine,                \
+you've probably seen this GL hack.  This version is by Marcelo         \
+Vianna.
+
+*hacks.sproingies.documentation:                                       \
+Q-Bert meets Marble Madness!  Written by Ed Mackey.
+
+*hacks.rubik.documentation:                                            \
+Draws a Rubik's Cube that rotates in three dimensions and repeatedly   \
+shuffles and solves itself.  Another fine GL hack by Marcelo Vianna.
+
+*hacks.atlantis.documentation:                                         \
+This is xfishtank writ large: a GL animation of a number of sharks,    \
+dolphins, and whales.  The swimming motions are great. Originally      \
+written by Mark Kilgard.
+
+*hacks.lament.documentation:                                           \
+Animates a simulation of Lemarchand's Box, repeatedly solving itself.  \
+Requires OpenGL, and a machine with fast hardware support for texture  \
+maps.  Warning: occasionally opens doors.  Written by Jamie Zawinski.
+
+*hacks.bubble3d.name: Bubble3D
+*hacks.bubble3d.documentation:                                         \
+Draws a stream of rising, undulating 3D bubbles, rising toward the     \
+top of the screen, with nice specular reflections. Written by Richard  \
+Jones.
+
+*hacks.glplanet.name: GLPlanet
+*hacks.glplanet.documentation:                                         \
+Draws a planet bouncing around in space.  Written by David Konerding.  \
+The built-in image is a map of the earth (extracted from `xearth'),    \
+but you can wrap any texture around the sphere, e.g., the planetary    \
+textures that come with `ssystem'.
+
+*hacks.pulsar.documentation:                                           \
+Draws some intersecting planes, making use of alpha blending, fog,     \
+textures, and mipmaps, plus a ``frames per second'' meter so that you  \
+can tell how fast your graphics card is...  Requires OpenGL.  Written  \
+by David Konerding.
+
+*hacks.extrusion.documentation:                                                \
+Draws various rotating extruded shapes that twist around, lengthen,    \
+and turn inside out.  Created by David Konerding from the samples      \
+that come with the GL Extrusion library by Linas Vepstas.
+
+*hacks.sierpinski3d.name: Sierpinski3D
+*hacks.sierpinski3d.documentation:                                     \
+This draws the three-dimensional variant of the recursive Sierpinski   \
+triangle fractal, using GL.  Written by Tim Robinson.
+
+*hacks.ripples.documentation:                                          \
+This draws rippling interference patterns like splashing water.                \
+With the -water option, it manipulates your desktop image to look      \
+like something is dripping into it.  Written by Tom Hammersley.
+
+
+!=============================================================================
+!
+! Documentation for some programs that are not bundled with XScreenSaver
+!
+!=============================================================================
+
+*hacks.xdaliclock.name: XDaliClock
+*hacks.xdaliclock.documentation:                                       \
+XDaliClock draws a large digital clock, the numbers of which change by \
+``melting'' into their new shapes.  Written by Jamie Zawinski.
+
+*hacks.xearth.documentation:                                           \
+XEarth draws an image of the Earth, as seen from your favorite vantage \
+point in space, correctly shaded for the current position of the Sun.  \
+Written by Kirk Johnson.
+
+*hacks.ssystem.name: SSystem
+*hacks.ssystem.documentation:                                          \
+SSystem is a GL Solar System simulator.  It simulates flybys of Sun,   \
+the nine planets and a few major satellites, with four camera modes.   \
+Written by Raul Alonso.
+
+*hacks.xmountains.documentation:                                       \
+XMountains generates realistic-looking fractal terrains of snow-capped \
+mountains near water, with either a top view or a side view.           \
+Written by Stephen Booth.
index 4d87b251cd7ea040cd807d77851c5ad25acc67f4..10bef5795ce3fc6ce26a760dd502e3c71a0fedca 100644 (file)
 "*loadURL: netscape -remote 'openURL(%s)' || netscape '%s'",
 "*dateFormat:          %d-%b-%y (%a); %I:%M %p",
 "*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\
-               ccurve -root                                            \\n\
-               blaster -root                                           \\n\
-               bumps -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\
-          GL:  extrusion -root                                         \\n",
-" ",
+"*programs:                                                                  \
+                \"Qix (solid)\"        qix -root -solid -delay 0 -segments 100     \\n\
+          \"Qix (transparent)\"        qix -root -count 4 -solid -transparent      \\n\
+               \"Qix (linear)\"        qix -root -count 5 -solid -transparent        \
+                                 -linear -segments 250 -size 100           \\n\
+         \"Attraction (balls)\"        attraction -root -mode balls                \\n\
+         \"Attraction (lines)\"        attraction -root -mode lines -points 3        \
+                                 -segments 200                             \\n\
+       \"Attraction (splines)\"        attraction -root -mode splines -segments      \
+                                 300                                       \\n\
+       \"Attraction (orbital)\"        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\
+             \"Ripples (oily)\"        ripples -root -oily -light 2                \\n\
+             \"Ripples (stir)\"        ripples -root -oily -light 2 -stir          \\n\
+          \"Ripples (desktop)\"        ripples -root -water -light 6               \\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 (trails)\"        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 -max-velocity 0.5 -elasticity      \
+                                 0.9                                       \\n\
+                               starfish -root                              \\n\
+            \"Starfish (blob)\"        starfish -root -blob                        \\n\
+                               munch -root                                 \\n\
+                               fadeplot -root                              \\n\
+                               coral -root -delay 0                        \\n\
+                               mountain -root                              \\n\
+                               triangle -root -delay 1                     \\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 (mobile)\"        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 (spots)\"        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 2 -count 20               \\n\
+                    \"Petri 2\"        petri -root -minlifespeed 0.02                \
+                                 -maxlifespeed 0.03 -minlifespan 1           \
+                                 -maxlifespan 1 -instantdeathchan 0          \
+                                 -minorchan 0 -anychan 0.3                 \\n\
+                               shadebobs -root                             \\n\
+                               ccurve -root                                \\n\
+                               blaster -root                               \\n\
+                               bumps -root                                 \\n\
+  default-n:                   webcollage -root                            \\n\
+  default-n:  \"WebCollage (whacked)\"                                       \
+                               webcollage -root -filter                      \
+                                 'vidwhacker -stdin -stdout'               \\n\
+- default-n:                   vidwhacker -root                            \\n\
+                                                                             \
+- mono:        \"Rocks (mono)\"        rocks -root                                 \\n\
+  color:       \"Rocks (color)\"       rocks -root -fg darksalmon                  \\n\
+- mono:           \"Qix (xor)\"        qix -root -linear -count 5 -size 200          \
+                                 -spread 30 -segments 75 -solid -xor       \\n\
+  color:   \"Attraction (poly)\"       attraction -root -mode polygons             \\n\
+- color:  \"Attraction (filled)\"      attraction -root -mode filled-splines         \
+                                 -segments 0                               \\n\
+- Color:  \"Attraction (glow)\"        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 (textures)\"                                              \
+                                 pulsar -root -texture -mipmap               \
+                                 -texture_quality -light -fog              \\n\
+          GL:                  extrusion -root                             \\n\
+          GL:                  sierpinski3d -root                          \\n\
+ ",
 "XScreenSaver.pointerPollTime:         5",
 "XScreenSaver.initialDelay:            0",
 "XScreenSaver.windowCreationTimeout:   30",
 "*warning_dialog*Command.vertDistance:         20",
 "*warning_dialog*Command.internalWidth:                20",
 "*warning_dialog*Command.internalHeight:               5",
+"*hacks.documentation.isInstalled: True",
+"*hacks.grav.documentation:                                            \
+This program draws a simple orbital simulation.         If you turn on         \
+trails, it looks kind of like a cloud-chamber photograph.  Written by  \
+Greg Bowering.",
+"*hacks.qix.documentation:                                             \
+This is the swiss army chainsaw of qix programs.  It bounces a series  \
+of line segments around the screen, and uses variations on this basic  \
+motion pattern to produce all sorts of different presentations: line   \
+segments, filled polygons, overlapping translucent areas...  Written   \
+by Jamie Zawinski.",
+"*hacks.attraction.documentation:                                      \
+Like qix, this uses a simple simple motion model to generate many      \
+different display modes.  The control points attract each other up to  \
+a certain distance, and then begin to repel each other.         The            \
+attraction/repulsion is proportional to the distance between any two   \
+particles, similar to the strong and weak nuclear forces.              \
+                                                                   \\n\\n\
+One of the most interesting ways to watch this hack is simply as       \
+bouncing balls, because their motions and interactions with each       \
+other are so odd.  Sometimes two balls will get into a tight orbit     \
+around each other, to be interrupted later by a third, or by the edge  \
+of the screen. It looks quite chaotic.                                 \
+                                                                   \\n\\n\
+Written by Jamie Zawinski, based on Lisp code by John Pezaris.",
+"*hacks.pyro.documentation:                                            \
+Pyro draws exploding fireworks.         Blah blah blah.  Written by Jamie      \
+Zawinski.",
+"*hacks.helix.documentation:                                           \
+This repeatedly generates spirally string-art-ish patterns.  Written   \
+by Jamie Zawinski.",
+"*hacks.pedal.documentation:                                           \
+This is sort of a combination spirograph/string-art.  It generates a   \
+large, complex polygon, and lets the X server do the bulk of the work  \
+by giving it an even/odd winding rule. Written by Dale Moore, based    \
+on some ancient PDP-11 code.",
+"*hacks.rorschach.documentation:                                               \
+This generates random inkblot patterns.         The algorithm is deceptively   \
+simple for how well it works; it merely walks a dot around the screen  \
+randomly, and then reflects the image horizontally, vertically, or     \
+both.  Any deep-seated neurotic tendencies which this program reveals  \
+are your own problem.  Written by Jamie Zawinski.",
+"*hacks.hopalong.documentation:                                                \
+This draws lacy fractal patterns, based on iteration in the imaginary  \
+plane, from a 1986 Scientific American article.         Mostly written by      \
+Patrick Naughton.",
+"*hacks.greynetic.documentation:                                               \
+This draws random colored and stippled rectangles.  Written by Jamie   \
+Zawinski.",
+"*hacks.xroger.documentation:                                          \
+The XScreenSaver logo. Don't you hate it?  So do I.  Would you like    \
+to design a new logo for XScreenSaver? If so, send jwz your            \
+submissions.",
+"*hacks.imsmap.name: IMSmap",
+"*hacks.imsmap.documentation:                                          \
+This generates random cloud-like patterns.  It looks quite different   \
+in monochrome and color.  The basic idea is to take four points on     \
+the edge of the image, and assign each a random ``elevation''. Then    \
+find the point between them, and give it a value which is the average  \
+of the other four, plus some small random offset. Then coloration is   \
+done based on elevation.                                               \
+                                                                   \\n\\n\
+The color selection is done by binding the elevation to either hue,    \
+saturation, or brightness, and assigning random values to the others.  \
+The ``brightness'' mode tends to yield cloudlike patterns, and the     \
+others tend to generate images that look like heat-maps or CAT-scans.  \
+Written by Juergen Nickelsen and Jamie Zawinski.",
+"*hacks.slidescreen.name: SlideScreen",
+"*hacks.slidescreen.documentation:                                     \
+This grabs an image of whatever is on your screen, divides it into a   \
+grid, and then randomly shuffles the squares around as if it was one   \
+of those annoying ``16-puzzle'' games, where there is a grid of                \
+squares, one of which is missing.  I hate trying to solve those                \
+puzzles, but watching one permute itself is more amusing.  Written by  \
+Jamie Zawinski.",
+"*hacks.decayscreen.name: DecayScreen",
+"*hacks.decayscreen.documentation:                                     \
+This grabs an image of whatever is on your screen, and makes it melt.  \
+You've no doubt seen this effect before, but no screensaver would      \
+really be complete without it. It works best if there's something      \
+colorful visible.  Warning, if the effect continues after the screen   \
+saver is off, seek medical attention.  Written by David Wald and       \
+Vivek Khera.                                                           \
+                                                                   \\n\\n\
+A number of these screenhacks have the ability to take an image of     \
+your desktop and manipulate it in some way.  On SGI systems, these     \
+programs are able to (at random) pull their source image from the      \
+system's video input instead!  This works nicely if you leave some     \
+some random television station plugged in.",
+"*hacks.jigsaw.documentation:                                          \
+This grabs a screen image, carves it up into a jigsaw puzzle,          \
+shuffles it, and then solves the puzzle.  This works especially well   \
+when you feed it an external video signal instead of letting it grab   \
+the screen image (actually, I guess this is generally true...) When    \
+it is grabbing a video image, it is sometimes pretty hard to guess     \
+what the image is going to look like once the puzzle is solved.                \
+Written by Jamie Zawinski.",
+"*hacks.blitspin.name: BlitSpin",
+"*hacks.blitspin.documentation:                                                \
+The ``blitspin'' hack repeatedly rotates a bitmap by 90 degrees by     \
+using logical operations: the bitmap is divided into quadrants, and    \
+the quadrants are shifted clockwise.  Then the same thing is done      \
+again with progressively smaller quadrants, except that all            \
+sub-quadrants of a given size are rotated in parallel. Written by      \
+Jamie Zawinski based on some cool SmallTalk code seen in in Byte       \
+Magazine in 1981.                                                      \
+                                                                   \\n\\n\
+As you watch it, the image appears to dissolve into static and then    \
+reconstitute itself, but rotated. You can provide the image to use,    \
+as an XBM or XPM file, or tell it to grab a screen image and rotate    \
+that.",
+"*hacks.slip.documentation:                                            \
+This program throws some random bits on the screen, then sucks them    \
+through a jet engine and spews them out the other side.         To avoid       \
+turning the image completely to mush, every now and then it will and   \
+then it interjects some splashes of color into the scene, or go into   \
+a spin cycle, or stretch the image like taffy, or (this is my          \
+addition) grab an image of your current desktop to chew on.            \
+Originally written by Scott Draves; whacked on by Jamie Zawinski.",
+"*hacks.distort.documentation:                                         \
+This hack grabs an image of the screen, and then lets a transparent    \
+lens wander around the screen, magnifying whatever is underneath.      \
+Written by Jonas Munsin.",
+"*hacks.spotlight.documentation:                                               \
+Draws a spotlight scanning across a black screen, illumnating the      \
+underlying desktop when it passes.  Written by Rick Schultz.",
+"*hacks.hypercube.documentation:                                               \
+This displays 2D projections of the sequence of 3D objects which are   \
+the projections of the 4D analog to the cube: as a square is composed  \
+of four lines, each touching two others; and a cube is composed of     \
+six squares, each touching four others; a hypercube is composed of     \
+eight cubes, each touching six others. To make it easier to            \
+visualize the rotation, it uses a different color for the edges of     \
+each face.  Don't think about it too long, or your brain will melt.    \
+Written by Joe Keane, Fritz Mueller, and Jamie Zawinski.",
+"*hacks.halo.documentation:                                            \
+This draws trippy psychedelic circular patterns that hurt to look at.  \
+It can also animate the control-points, but that takes a lot of CPU    \
+and bandwidth. Written by Jamie Zawinski.",
+"*hacks.maze.documentation:                                            \
+This is the ancient X maze demo, modified to work with xscreensaver.   \
+It generates a random maze, then solves it with visual feedback.       \
+Originally by Jim Randell; modified by a cast of thousands.",
+"*hacks.noseguy.documentation:                                         \
+A little man with a big nose wanders around your screen saying         \
+things.         The things which he says can come from a file, or from an      \
+external program like `zippy' or `fortune'.  This was extracted from   \
+`xnlock' by Dan Heller.         Colorized by Jamie Zawinski.",
+"*hacks.flame.documentation:                                           \
+Another iterative fractal generator.  Written by Scott Draves.",
+"*hacks.lmorph.name: LMorph",
+"*hacks.lmorph.documentation:                                          \
+This generates random spline-ish line drawings and morphs between      \
+them.  Written by Sverre H.  Huseby and Glenn T.  Lines.",
+"*hacks.deco.documentation:                                            \
+This one subdivides and colors rectangles randomly.  It looks kind of  \
+like Brady-Bunch-era rec-room wall paneling.  (Raven says: ``this      \
+screensaver is ugly enough to peel paint.'')  Written by Jamie         \
+Zawinski, inspired by Java code by Michael Bayne.",
+"*hacks.moire.documentation:                                           \
+This one draws cool circular interference patterns.  Most of the       \
+circles you see aren't explicitly rendered, but show up as a result    \
+of interactions between the other pixels that were drawn.  Written by  \
+Jamie Zawinski, inspired by Java code by Michael Bayne.         As he          \
+pointed out, the beauty of this one is that the heart of the display   \
+algorithm can be expressed with just a pair of loops and a handful of  \
+arithmetic, giving it a high ``display hack metric''.",
+"*hacks.moire2.documentation:                                          \
+Another example of the fun you can have with moire                     \
+interference patterns; this hack generates fields of concentric                \
+circles or ovals, and combines the planes with various operations.     \
+The planes are moving independently of one another, causing the                \
+interference lines to ``spray.''  Written by Jamie Zawinski.",
+"*hacks.lightning.documentation:                                               \
+This one draws crackling fractal lightning bolts.  It's simple,                \
+direct, and to the point.  If only it had sound... Written by Keith    \
+Romberg.",
+"*hacks.strange.documentation:                                         \
+This draws strange attractors: it's a colorful,                                \
+unpredictably-animating field of dots that swoops and twists around.   \
+The motion is very nice.  Written by Massimino Pascal.",
+"*hacks.spiral.documentation:                                          \
+Moving circular patterns, by Peter Schmitzberger.  Moving circular     \
+patterns means moire; interference patterns, of course.",
+"*hacks.laser.documentation:                                           \
+Moving radiating lines, that look vaguely like scanning laser beams.   \
+Written by Pascal Pensa.  (Frankie say: relax.)",
+"*hacks.grav.documentation:                                            \
+This program draws a simple orbital simulation.         If you turn on         \
+trails, it looks kind of like a cloud-chamber photograph.  Written     \
+by Greg Bowering.",
+"*hacks.drift.documentation:                                           \
+How could one possibly describe this except as ``drifting recursive    \
+fractal cosmic flames?''  Another fine hack from the Scott Draves      \
+collection of fine hacks.",
+"*hacks.ifs.name: IFS",
+"*hacks.ifs.documentation:                                             \
+This one draws spinning, colliding iterated-function-system images.    \
+Written by Massimino Pascal.",
+"*hacks.julia.documentation:                                           \
+This one draws spinning, animating (are you detecting a pattern here   \
+yet?)  explorations of the Julia set. You've probably seen static      \
+images of this fractal form before, but it's a lot of fun to watch in  \
+motion as well.         One interesting thing is that there is a small         \
+swinging dot passing in front of the image, which indicates the                \
+control point from which the rest of the image was generated.          \
+Written by Sean McCullough.",
+"*hacks.penrose.documentation:                                         \
+Draws quasiperiodic tilings; think of the implications on modern       \
+formica technology.  Written by Timo Korvola.                          \
+                                                                   \\n\\n\
+In April 1997, Sir Roger Penrose, a British math professor who has     \
+worked with Stephen Hawking on such topics as relativity, black                \
+holes, and whether time has a beginning, filed a                       \
+copyright-infringement lawsuit against the Kimberly-Clark              \
+Corporation, which Penrose said copied a pattern he created (a         \
+pattern demonstrating that ``a nonrepeating pattern could exist in     \
+nature'') for its Kleenex quilted toilet paper.        Penrose said he         \
+doesn't like litigation but, ``When it comes to the population of      \
+Great Britain being invited by a multinational to wipe their bottoms   \
+on what appears to be the work of a Knight of the Realm, then a last   \
+stand must be taken.''                                                 \
+                                                                   \\n\\n\
+As reported by News of the Weird #491, 4-jul-1997.",
+"*hacks.sierpinski.documentation:                                      \
+This draws the two-dimensional variant of the recursive Sierpinski     \
+triangle fractal.  Written by Desmond Daignault.",
+"*hacks.braid.documentation:                                           \
+Draws random color-cycling inter-braided concentric circles.  Written  \
+by John Neil.",
+"*hacks.galaxy.documentation:                                          \
+This draws spinning galaxies, which then collide and scatter their     \
+stars to the, uh, four winds or something.  Originally an Amiga                \
+program by Uli Siegmund.",
+"*hacks.bouboule.documentation:                                                \
+This draws what looks like a spinning, deforming baloon with           \
+varying-sized spots painted on its invisible surface.  Written by      \
+Jeremie Petit.",
+"*hacks.swirl.documentation:                                           \
+More flowing, swirly patterns. This version is by M.  Dobie and R.     \
+Taylor, but you might have seen a Mac program similar to this called   \
+FlowFazer.  There is also a cool Java applet of a similar concept",
+"*hacks.flag.documentation:                                            \
+This draws a waving colored flag, that undulates its way around the    \
+screen.         The trick is the flag can contain arbitrary text and images.   \
+By default, it displays either the current system name and OS          \
+type, or a picture of ``Bob,'' but you can replace the text or the     \
+image with a command-line option.  Written by Charles Vidal and Jamie  \
+Zawinski.",
+"*hacks.sphere.documentation:                                          \
+Another of the classic screenhacks of the distant past, this one       \
+draws shaded spheres in multiple colors.  This hack traces its         \
+lineage back to Tom Duff in 1982.",
+"*hacks.forest.documentation:                                          \
+This draws fractal trees.  Written by Peter Baumung.  Everybody loves  \
+fractals, right?",
+"*hacks.lisa.documentation:                                            \
+This draws Lisajous loops, by Caleb Cullen.  Remember that device      \
+they had the Phantom Zone prisoners in during their trial in           \
+Superman?  I think that was one of these.",
+"*hacks.lissie.documentation:                                          \
+Another Lissajous figure.  This one draws the progress of circular     \
+shapes along a path.  Written by Alexander Jolk.",
+"*hacks.goop.documentation:                                            \
+This draws set of animating, transparent, amoeba-like blobs.  The      \
+blobs change shape as they wander around the screen, and they are      \
+translucent, so you can see the lower blobs through the higher ones,   \
+and when one passes over another, their colors merge.  Written by      \
+Jamie Zawinski.         I got the idea for this from a cool mouse pad I        \
+have, which achieves the same kind of effect in real life by having    \
+several layers plastic with colored oil between them.  Written by      \
+Jamie Zawinski.",
+"*hacks.starfish.documentation:                                                \
+This generates a sequence of undulating, throbbing, star-like          \
+patterns which pulsate, rotate, and turn inside out.  Another display  \
+mode uses these shapes to lay down a field of colors, which are then   \
+cycled.         The motion is very organic.  Written by Jamie Zawinski.",
+"*hacks.munch.documentation:                                         \\n\
+        DATAI 2                                                              \\n\
+        ADDB 1,2                                                     \\n\
+        ROTC 2,-22                                                   \\n\
+        XOR 1,2                                                              \\n\
+        JRST .-4                                                     \\n\
+                                                                     \\n\
+As reported by HAKMEM, in 1962, Jackson Wright wrote the above PDP-1   \
+code. That code still lives on in this screenhack, some 35 years       \
+later.  The number of lines of enclosing code has increased            \
+substantially, however.  This version is by Tim Showalter.",
+"*hacks.fadeplot.name: FadePlot",
+"*hacks.fadeplot.documentation:                                                \
+Draws what looks like a waving ribbon following a sinusoidal path.     \
+Written by Bas van Gaalen and Charles Vidal.",
+"*hacks.coral.documentation:                                           \
+Simulates coral growth, albeit somewhat slowly.         This image doesn't     \
+really do it justice.  Written by Frederick Roeber.",
+"*hacks.mountain.documentation:                                                \
+Generates random 3d plots that look vaguely mountainous.  Written by   \
+Pascal Pensa.",
+"*hacks.triangle.documentation:                                                \
+Generates random mountain ranges using iterative subdivision of                \
+triangles.  Written by Tobias Gloth.",
+"*hacks.worm.documentation:                                            \
+An ancient xlock hack that draws multicolored worms that crawl around  \
+the screen.  Written by Brad Taylor, Dave Lemke, Boris Putanec, and    \
+Henrik Theiling.",
+"*hacks.rotor.documentation:                                           \
+Another ancient xlock demo, this one by Tom Lawrence.  It draws a      \
+line segment moving along a complex spiraling curve.  I tweaked this   \
+to generate curvier lines, but still frames of it don't look like      \
+much.",
+"*hacks.ant.documentation:                                             \
+A cellular automaton that is really a two-dimensional Turing machine:  \
+as the heads (``ants'') walk along the screen, they change pixel       \
+values in their path.  Then, as they pass over changed pixels, their   \
+behavior is influenced.         Written by David Bagley.",
+"*hacks.demon.documentation:                                           \
+A cellular automaton that starts with a random field, and organizes    \
+it into stripes and spirals.  Written by David Bagley.",
+"*hacks.loop.documentation:                                            \
+This one produces loop-shaped colonies that spawn, age, and            \
+eventually die.         Written by David Bagley.",
+"*hacks.vines.documentation:                                           \
+This one generates a continuous sequence of small, curvy geometric     \
+patterns.  It scatters them around your screen until it fills up,      \
+then it clears the screen and starts over.  Written by Tracy Camp and  \
+David Hansen.",
+"*hacks.kaleidescope.documentation:                                    \
+Another clone of an ancient meme, consisting largely of frenetic       \
+rotational motion of colored lines.  This one is by Ron Tapia. The     \
+motion is nice, but I think it needs more solids, or perhaps just      \
+brighter colors.  More variations in the rotational speed might help,  \
+too.",
+"*hacks.xjack.documentation:                                           \
+This program behaves schizophrenically and makes a lot of typos.       \
+Written by Jamie Zawinski.  If you haven't seen Stanley Kubrick's      \
+masterpiece, ``The Shining,'' you won't get it.         Those who have         \
+describe this hack as ``inspired.''",
+"*hacks.xlyap.documentation:                                           \
+This generates pretty fractal pictures by doing funky math involving   \
+the ``Lyapunov exponent.''  It has a cool interactive mode, too.       \
+Written by Ron Record.",
+"*hacks.cynosure.documentation:                                                \
+A hack similar to `greynetic', but less frenetic.  The first           \
+implementation was by Stephen Linhart; then Ozymandias G. Desiderata   \
+wrote a Java applet clone.  That clone was discovered by Jamie         \
+Zawinski, and ported to C for inclusion here.",
+"*hacks.flow.documentation:                                            \
+Another series of strange attractors: a flowing series of points,      \
+making strange rotational shapes.  Written by Jeff Butterworth.",
+"*hacks.epicycle.documentation:                                                \
+This program draws the path traced out by a point on the edge of a     \
+circle.         That circle rotates around a point on the rim of another       \
+circle, and so on, several times. These were the basis for the         \
+pre-heliocentric model of planetary motion.  Written by James          \
+Youngman.",
+"*hacks.interference.documentation:                                    \
+Another color-field hack, this one works by computing decaying         \
+sinusoidal waves, and allowing them to interfere with each other as    \
+their origins move.  Written by Hannu Mallat.",
+"*hacks.truchet.documentation:                                         \
+This draws line- and arc-based Truchet patterns that tile the screen.  \
+Written by Adrian Likins.",
+"*hacks.bsod.name: BSOD",
+"*hacks.bsod.documentation:                                            \
+BSOD stands for ``Blue Screen of Death.''  The finest in personal      \
+computer emulation, this hack simulates popular screen savers from a   \
+number of less robust operating systems.  Written by Jamie Zawinski.",
+"*hacks.crystal.documentation:                                         \
+Moving polygons, similar to a kaleidescope (more like a kaleidescope   \
+than the hack called `kaleid,' actually.) This one by Jouk Jansen.",
+"*hacks.discrete.documentation:                                                \
+More ``discrete map'' systems, including new variants of Hopalong and  \
+Julia, and a few others.  Written by Tim Auckland.",
+"*hacks.kumppa.documentation:                                          \
+Spiraling, spinning, and very, very fast splashes of color rush                \
+toward the screen.  Written by Teemu Suutari.",
+"*hacks.rd-bomb.name: RD-Bomb",
+"*hacks.rd-bomb.documentation:                                         \
+Another variation of the `Bomb' program by Scott Draves.  This draws   \
+a grid of growing square-like shapes that, once they overtake each     \
+other, react in unpredictable ways.  ``RD'' stands for                 \
+reaction-diffusion.",
+"*hacks.sonar.documentation:                                           \
+This program draws a simulation of a sonar screen.  Written by         \
+default, it displays a random assortment of ``bogies'' on the screen,  \
+but if compiled properly, it can ping (pun intended) your local                \
+network, and actually plot the proximity of the other hosts on your    \
+network to you.         It would be easy to make it monitor other sources of   \
+data, too.  (Processes?         Active network connections?  CPU usage per     \
+user?) Written by Stephen Martin.",
+"*hacks.t3d.name: T3D",
+"*hacks.t3d.documentation:                                             \
+This draws a working analog clock composed of floating, throbbing      \
+bubbles.  Written by Bernd Paysan.",
+"*hacks.penetrate.documentation:                                               \
+This hack simulates the classic arcade game Missile Command.  Written  \
+by Adam Miller.",
+"*hacks.deluxe.documentation:                                          \
+This draws a pulsing sequence of stars, circles, and lines.  It would  \
+look better if it was faster, but as far as I can tell, there is no    \
+way to make this be both: fast, and flicker-free.  Yet another reason  \
+X sucks.  Written by Jamie Zawinski.",
+"*hacks.compass.documentation:                                         \
+This draws a compass, with all elements spinning about randomly, for   \
+that ``lost and nauseous'' feeling. Written by Jamie Zawinski.",
+"*hacks.squiral.documentation:                                         \
+Draws a set of interacting, square-spiral-producing automata.  The     \
+spirals grow outward until they hit something, then they go around     \
+it.  Written by Jeff Epler.",
+"*hacks.xflame.documentation:                                          \
+Draws a simulation of pulsing fire.  It can also take an arbitrary     \
+image and set it on fire too.  Written by Carsten Haitzler, hacked on  \
+by many others.",
+"*hacks.wander.documentation:                                          \
+Draws a colorful random-walk, in various forms.         Written by Rick        \
+Campbell.",
+"*hacks.critical.documentation:                                                \
+Draws a system of self-organizing lines.  It starts out as random      \
+squiggles, but after a few iterations, order begins to appear.         \
+Written by Martin Pool.",
+"*hacks.phosphor.documentation:                                                \
+Draws a simulation of an old terminal, with large pixels and           \
+long-sustain phosphor. It can run any program as a source of the text  \
+it displays.  Written by Jamie Zawinski.",
+"*hacks.xmatrix.documentation:                                         \
+A rendition of the text scrolls seen in the movie ``The Matrix.''      \
+Written by Jamie Zawinski.",
+"*hacks.petri.documentation:                                           \
+This simulates colonies of mold growing in a petri dish.  Growing      \
+colored circles overlap and leave spiral interference in their wake.   \
+Written by Dan Bornstein.",
+"*hacks.shadebobs.name: ShadeBobs",
+"*hacks.shadebobs.documentation:                                               \
+This draws smoothly-shaded oscilating oval patterns, that look         \
+something like vapor trails or neon tubes.  Written by Shane Smit.",
+"*hacks.ccurve.name: C Curve",
+"*hacks.ccurve.documentation:                                          \
+Generates self-similar linear fractals, including the classic ``C      \
+Curve.''  Written by Rick Campbell.",
+"*hacks.blaster.documentation:                                         \
+Draws a simulation of flying space-combat robots (cleverly disguised   \
+as colored circles) doing battle in front of a moving star field.      \
+Written by Jonathan Lin.",
+"*hacks.bumps.documentation:                                           \
+A bit like `Spotlight', except that instead of merely exposing part    \
+of your desktop, it creates a bump map from it.         Basically, it          \
+3D-izes a roaming section of your desktop, based on color intensity.   \
+Written by Shane Smit.",
+"*hacks.webcollage.name: WebCollage",
+"*hacks.webcollage.documentation:                                      \
+This program makes collages out of random images pulled off of the     \
+World Wide Web.         It finds these images by doing random web searches,    \
+and then extracting images from the returned pages.  It can also be    \
+set up to filter the images through the `VidWhacker' program, above,   \
+which looks really great.                                              \
+                                                                   \\n\\n\
+(Note that most of the images it finds are text, and not pictures.     \
+This is because most of the web is pictures of text.  Which is pretty  \
+sad.)  Written by Jamie Zawinski.",
+"*hacks.vidwhacker.name: VidWhacker",
+"*hacks.vidwhacker.documentation:                                      \
+This is actually just a shell script that grabs a frame of video from  \
+the system's video input, and then uses some PBM filters (chosen at    \
+random) to manipulate and recombine the video frame in various ways    \
+(edge detection, subtracting the image from a rotated version of       \
+itself, etc.)  Then it displays that image for a few seconds, and      \
+does it again. This works really well if you just feed broadcast       \
+television into it.                                                    \
+                                                                   \\n\\n\
+Currently, the three lines of the script that actually grab the                \
+source picture are SGI specific, but it should be trivial to adapt it  \
+to work on other systems that can grab video (please send me the       \
+changes if you do this...)",
+"*hacks.rocks.documentation:                                           \
+This draws an animation of flight through an asteroid field, with      \
+changes in rotation and direction.  It can also display 3D             \
+separations for red/blue glasses!  Mostly written by Jamie Zawinski.",
+"*hacks.bubbles.documentation:                                         \
+This simulates the kind of bubble formation that happens when water    \
+boils:small bubbles appear, and as they get closer to each other,      \
+they combine to form larger bubbles, which eventually pop.  Written    \
+by James Macnicol.",
+"*hacks.gears.documentation:                                           \
+This draws a set of turning, interlocking gears, rotating in three     \
+dimensions.  Another GL hack, by Danny Sung, Brian Paul, and Ed                \
+Mackey.",
+"*hacks.superquadrics.documentation:                                   \
+Ed Mackey reports that he wrote the first version of this program in   \
+BASIC on a Commodore 64 in 1987, as a 320x200 black and white          \
+wireframe.  Now it is GL and has specular reflections.",
+"*hacks.morph3d.name: Morph3D",
+"*hacks.morph3d.documentation:                                         \
+Another 3d shape-changing GL hack, by Marcelo Vianna.  It has the      \
+same shiny-plastic feel as Superquadrics, as many computer-generated   \
+objects do...",
+"*hacks.cage.documentation:                                            \
+This draws Escher's ``Impossible Cage,'' a 3d analog of a moebius      \
+strip, and rotates it in three dimensions.  Written by Marcelo         \
+Vianna.",
+"*hacks.moebius.documentation:                                         \
+Another M.  C. Escher hack by Marcelo Vianna, this one draws           \
+``Moebius Strip II,'' a GL image of ants walking along the surface of  \
+a moebius strip.",
+"*hacks.stairs.documentation:                                          \
+by Marcelo Vianna's third Escher GL hack, this one draws an            \
+``infinite'' staircase.",
+"*hacks.pipes.documentation:                                           \
+If you've ever been in the same room with a Windows NT machine,                \
+you've probably seen this GL hack.  This version is by Marcelo         \
+Vianna.",
+"*hacks.sproingies.documentation:                                      \
+Q-Bert meets Marble Madness!  Written by Ed Mackey.",
+"*hacks.rubik.documentation:                                           \
+Draws a Rubik's Cube that rotates in three dimensions and repeatedly   \
+shuffles and solves itself.  Another fine GL hack by Marcelo Vianna.",
+"*hacks.atlantis.documentation:                                                \
+This is xfishtank writ large: a GL animation of a number of sharks,    \
+dolphins, and whales.  The swimming motions are great. Originally      \
+written by Mark Kilgard.",
+"*hacks.lament.documentation:                                          \
+Animates a simulation of Lemarchand's Box, repeatedly solving itself.  \
+Requires OpenGL, and a machine with fast hardware support for texture  \
+maps.  Warning: occasionally opens doors.  Written by Jamie Zawinski.",
+"*hacks.bubble3d.name: Bubble3D",
+"*hacks.bubble3d.documentation:                                                \
+Draws a stream of rising, undulating 3D bubbles, rising toward the     \
+top of the screen, with nice specular reflections. Written by Richard  \
+Jones.",
+"*hacks.glplanet.name: GLPlanet",
+"*hacks.glplanet.documentation:                                                \
+Draws a planet bouncing around in space.  Written by David Konerding.  \
+The built-in image is a map of the earth (extracted from `xearth'),    \
+but you can wrap any texture around the sphere, e.g., the planetary    \
+textures that come with `ssystem'.",
+"*hacks.pulsar.documentation:                                          \
+Draws some intersecting planes, making use of alpha blending, fog,     \
+textures, and mipmaps, plus a ``frames per second'' meter so that you  \
+can tell how fast your graphics card is...  Requires OpenGL.  Written  \
+by David Konerding.",
+"*hacks.extrusion.documentation:                                               \
+Draws various rotating extruded shapes that twist around, lengthen,    \
+and turn inside out.  Created by David Konerding from the samples      \
+that come with the GL Extrusion library by Linas Vepstas.",
+"*hacks.sierpinski3d.name: Sierpinski3D",
+"*hacks.sierpinski3d.documentation:                                    \
+This draws the three-dimensional variant of the recursive Sierpinski   \
+triangle fractal, using GL.  Written by Tim Robinson.",
+"*hacks.ripples.documentation:                                         \
+This draws rippling interference patterns like splashing water.                \
+With the -water option, it manipulates your desktop image to look      \
+like something is dripping into it.  Written by Tom Hammersley.",
+"*hacks.xdaliclock.name: XDaliClock",
+"*hacks.xdaliclock.documentation:                                      \
+XDaliClock draws a large digital clock, the numbers of which change by \
+``melting'' into their new shapes.  Written by Jamie Zawinski.",
+"*hacks.xearth.documentation:                                          \
+XEarth draws an image of the Earth, as seen from your favorite vantage \
+point in space, correctly shaded for the current position of the Sun.  \
+Written by Kirk Johnson.",
+"*hacks.ssystem.name: SSystem",
+"*hacks.ssystem.documentation:                                         \
+SSystem is a GL Solar System simulator.  It simulates flybys of Sun,   \
+the nine planets and a few major satellites, with four camera modes.   \
+Written by Raul Alonso.",
+"*hacks.xmountains.documentation:                                      \
+XMountains generates realistic-looking fractal terrains of snow-capped \
+mountains near water, with either a top view or a side view.           \
+Written by Stephen Booth.",
diff --git a/driver/demo-Gtk-stubs.h b/driver/demo-Gtk-stubs.h
new file mode 100644 (file)
index 0000000..cd86ee6
--- /dev/null
@@ -0,0 +1,70 @@
+#include <gtk/gtk.h>
+
+
+void
+activate_menu_cb                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+lock_menu_cb                           (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+kill_menu_cb                           (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+restart_menu_cb                        (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+exit_menu_cb                           (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+cut_menu_cb                            (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+copy_menu_cb                           (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+paste_menu_cb                          (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+about_menu_cb                          (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+doc_menu_cb                            (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+run_next_cb                            (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+run_prev_cb                            (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+run_this_cb                            (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+apply_this_cb                          (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+cancel_this_cb                         (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+prefs_ok_cb                            (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+prefs_cancel_cb                        (GtkButton       *button,
+                                        gpointer         user_data);
diff --git a/driver/demo-Gtk-widgets.c b/driver/demo-Gtk-widgets.c
new file mode 100644 (file)
index 0000000..0b133bc
--- /dev/null
@@ -0,0 +1,894 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "demo-Gtk-stubs.h"
+#include "demo-Gtk-widgets.h"
+
+
+GtkWidget*
+create_xscreensaver_demo ()
+{
+  GtkWidget *xscreensaver_demo;
+  GtkWidget *outer_vbox;
+  GtkWidget *menubar;
+  guint tmp_key;
+  GtkWidget *file;
+  GtkWidget *file_menu;
+  GtkAccelGroup *file_menu_accels;
+  GtkWidget *activate_menu;
+  GtkWidget *lock_menu;
+  GtkWidget *kill_menu;
+  GtkWidget *restart;
+  GtkWidget *separator1;
+  GtkWidget *exit_menu;
+  GtkWidget *edit;
+  GtkWidget *edit_menu;
+  GtkAccelGroup *edit_menu_accels;
+  GtkWidget *cut_menu;
+  GtkWidget *copy_menu;
+  GtkWidget *paste_menu;
+  GtkWidget *help;
+  GtkWidget *help_menu;
+  GtkAccelGroup *help_menu_accels;
+  GtkWidget *about_menu;
+  GtkWidget *doc_menu;
+  GtkWidget *notebook;
+  GtkWidget *demos_hbox;
+  GtkWidget *list_vbox;
+  GtkWidget *scroller;
+  GtkWidget *viewport;
+  GtkWidget *list;
+  GtkWidget *centering_hbox;
+  GtkWidget *next_prev_hbox;
+  GtkWidget *next;
+  GtkWidget *prev;
+  GtkWidget *opts_vbox;
+  GtkWidget *frame;
+  GtkWidget *doc;
+  GtkWidget *opts_vbox2;
+  GtkWidget *cmd_label;
+  GtkWidget *cmd_text;
+  GtkWidget *opts_hbox3;
+  GtkWidget *enabled;
+  GtkWidget *visual;
+  GtkWidget *visual_combo;
+  GList *visual_combo_items = NULL;
+  GtkWidget *combo_entry1;
+  GtkWidget *demo_hline;
+  GtkWidget *demo_cancel_hbox;
+  GtkWidget *demo;
+  GtkWidget *apply;
+  GtkWidget *cancel;
+  GtkWidget *demo_tab;
+  GtkWidget *prefs_hbox;
+  GtkWidget *prefs_frame;
+  GtkWidget *prefs_table;
+  GtkWidget *timeout_text;
+  GtkWidget *cycle_text;
+  GtkWidget *fade_text;
+  GtkWidget *ticks_text;
+  GtkWidget *lock_text;
+  GtkWidget *pass_text;
+  GtkWidget *timeout_label;
+  GtkWidget *cycle_label;
+  GtkWidget *fade_label;
+  GtkWidget *ticks_label;
+  GtkWidget *lock_label;
+  GtkWidget *pass_label;
+  GtkWidget *verbose_button;
+  GtkWidget *install_button;
+  GtkWidget *fade_button;
+  GtkWidget *unfade_button;
+  GtkWidget *lock_button;
+  GtkWidget *hbuttonbox3;
+  GtkWidget *prefs_ok;
+  GtkWidget *prefs_cancel;
+  GtkWidget *prefs_tab;
+  GtkAccelGroup *accel_group;
+  GtkTooltips *tooltips;
+
+  tooltips = gtk_tooltips_new ();
+
+  accel_group = gtk_accel_group_new ();
+
+  xscreensaver_demo = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (xscreensaver_demo, "xscreensaver_demo");
+  gtk_object_set_data (GTK_OBJECT (xscreensaver_demo), "xscreensaver_demo", xscreensaver_demo);
+  gtk_window_set_title (GTK_WINDOW (xscreensaver_demo), "XScreenSaver");
+  gtk_window_set_default_size (GTK_WINDOW (xscreensaver_demo), 600, 400);
+  gtk_window_set_policy (GTK_WINDOW (xscreensaver_demo), TRUE, TRUE, FALSE);
+  gtk_window_set_wmclass (GTK_WINDOW (xscreensaver_demo), "xscreensaver", "XScreenSaver");
+
+  outer_vbox = gtk_vbox_new (FALSE, 5);
+  gtk_widget_set_name (outer_vbox, "outer_vbox");
+  gtk_widget_ref (outer_vbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "outer_vbox", outer_vbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (outer_vbox);
+  gtk_container_add (GTK_CONTAINER (xscreensaver_demo), outer_vbox);
+
+  menubar = gtk_menu_bar_new ();
+  gtk_widget_set_name (menubar, "menubar");
+  gtk_widget_ref (menubar);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "menubar", menubar,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (menubar);
+  gtk_box_pack_start (GTK_BOX (outer_vbox), menubar, FALSE, FALSE, 0);
+
+  file = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file)->child),
+                                   "_File");
+  gtk_widget_add_accelerator (file, "activate_item", accel_group,
+                              tmp_key, GDK_MOD1_MASK, 0);
+  gtk_widget_set_name (file, "file");
+  gtk_widget_ref (file);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "file", file,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (file);
+  gtk_container_add (GTK_CONTAINER (menubar), file);
+
+  file_menu = gtk_menu_new ();
+  gtk_widget_set_name (file_menu, "file_menu");
+  gtk_widget_ref (file_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "file_menu", file_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (file), file_menu);
+  file_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file_menu));
+
+  activate_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (activate_menu)->child),
+                                   "_Blank Screen Now");
+  gtk_widget_add_accelerator (activate_menu, "activate_item", file_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (activate_menu, "activate_menu");
+  gtk_widget_ref (activate_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "activate_menu", activate_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (activate_menu);
+  gtk_container_add (GTK_CONTAINER (file_menu), activate_menu);
+  gtk_tooltips_set_tip (tooltips, activate_menu, "Activate the XScreenSaver daemon now (locking the screen if so configured.)", NULL);
+
+  lock_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (lock_menu)->child),
+                                   "_Lock Screen Now");
+  gtk_widget_add_accelerator (lock_menu, "activate_item", file_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (lock_menu, "lock_menu");
+  gtk_widget_ref (lock_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_menu", lock_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (lock_menu);
+  gtk_container_add (GTK_CONTAINER (file_menu), lock_menu);
+  gtk_tooltips_set_tip (tooltips, lock_menu, "Lock the screen now (even if \"Require Password\" is unchecked.)", NULL);
+
+  kill_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (kill_menu)->child),
+                                   "_Kill Daemon");
+  gtk_widget_add_accelerator (kill_menu, "activate_item", file_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (kill_menu, "kill_menu");
+  gtk_widget_ref (kill_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "kill_menu", kill_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (kill_menu);
+  gtk_container_add (GTK_CONTAINER (file_menu), kill_menu);
+  gtk_tooltips_set_tip (tooltips, kill_menu, "Tell the running XScreenSaver daemon to exit.", NULL);
+
+  restart = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (restart)->child),
+                                   "_Restart Daemon");
+  gtk_widget_add_accelerator (restart, "activate_item", file_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (restart, "restart");
+  gtk_widget_ref (restart);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "restart", restart,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (restart);
+  gtk_container_add (GTK_CONTAINER (file_menu), restart);
+  gtk_tooltips_set_tip (tooltips, restart, "Kill and re-launch the XScreenSaver daemon.", NULL);
+
+  separator1 = gtk_menu_item_new ();
+  gtk_widget_set_name (separator1, "separator1");
+  gtk_widget_ref (separator1);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "separator1", separator1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (separator1);
+  gtk_container_add (GTK_CONTAINER (file_menu), separator1);
+  gtk_widget_set_sensitive (separator1, FALSE);
+
+  exit_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (exit_menu)->child),
+                                   "_Exit");
+  gtk_widget_add_accelerator (exit_menu, "activate_item", file_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (exit_menu, "exit_menu");
+  gtk_widget_ref (exit_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "exit_menu", exit_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (exit_menu);
+  gtk_container_add (GTK_CONTAINER (file_menu), exit_menu);
+  gtk_tooltips_set_tip (tooltips, exit_menu, "Exit the xscreensaver-demo program (but leave the XScreenSaver daemon running in the background.)", NULL);
+
+  edit = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (edit)->child),
+                                   "_Edit");
+  gtk_widget_add_accelerator (edit, "activate_item", accel_group,
+                              tmp_key, GDK_MOD1_MASK, 0);
+  gtk_widget_set_name (edit, "edit");
+  gtk_widget_ref (edit);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "edit", edit,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (edit);
+  gtk_container_add (GTK_CONTAINER (menubar), edit);
+
+  edit_menu = gtk_menu_new ();
+  gtk_widget_set_name (edit_menu, "edit_menu");
+  gtk_widget_ref (edit_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "edit_menu", edit_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (edit), edit_menu);
+  edit_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (edit_menu));
+
+  cut_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (cut_menu)->child),
+                                   "C_ut");
+  gtk_widget_add_accelerator (cut_menu, "activate_item", edit_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (cut_menu, "cut_menu");
+  gtk_widget_ref (cut_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cut_menu", cut_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (cut_menu);
+  gtk_container_add (GTK_CONTAINER (edit_menu), cut_menu);
+
+  copy_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (copy_menu)->child),
+                                   "_Copy");
+  gtk_widget_add_accelerator (copy_menu, "activate_item", edit_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (copy_menu, "copy_menu");
+  gtk_widget_ref (copy_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "copy_menu", copy_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (copy_menu);
+  gtk_container_add (GTK_CONTAINER (edit_menu), copy_menu);
+
+  paste_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (paste_menu)->child),
+                                   "_Paste");
+  gtk_widget_add_accelerator (paste_menu, "activate_item", edit_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (paste_menu, "paste_menu");
+  gtk_widget_ref (paste_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "paste_menu", paste_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (paste_menu);
+  gtk_container_add (GTK_CONTAINER (edit_menu), paste_menu);
+
+  help = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (help)->child),
+                                   "_Help");
+  gtk_widget_add_accelerator (help, "activate_item", accel_group,
+                              tmp_key, GDK_MOD1_MASK, 0);
+  gtk_widget_set_name (help, "help");
+  gtk_widget_ref (help);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "help", help,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (help);
+  gtk_container_add (GTK_CONTAINER (menubar), help);
+
+  help_menu = gtk_menu_new ();
+  gtk_widget_set_name (help_menu, "help_menu");
+  gtk_widget_ref (help_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "help_menu", help_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu);
+  help_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (help_menu));
+
+  about_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (about_menu)->child),
+                                   "_About...");
+  gtk_widget_add_accelerator (about_menu, "activate_item", help_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (about_menu, "about_menu");
+  gtk_widget_ref (about_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "about_menu", about_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (about_menu);
+  gtk_container_add (GTK_CONTAINER (help_menu), about_menu);
+  gtk_tooltips_set_tip (tooltips, about_menu, "Display version information.", NULL);
+
+  doc_menu = gtk_menu_item_new_with_label ("");
+  tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (doc_menu)->child),
+                                   "_Documentation...");
+  gtk_widget_add_accelerator (doc_menu, "activate_item", help_menu_accels,
+                              tmp_key, 0, 0);
+  gtk_widget_set_name (doc_menu, "doc_menu");
+  gtk_widget_ref (doc_menu);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "doc_menu", doc_menu,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (doc_menu);
+  gtk_container_add (GTK_CONTAINER (help_menu), doc_menu);
+  gtk_tooltips_set_tip (tooltips, doc_menu, "Go to the documentation on the XScreenSaver web page.", NULL);
+
+  notebook = gtk_notebook_new ();
+  gtk_widget_set_name (notebook, "notebook");
+  gtk_widget_ref (notebook);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "notebook", notebook,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (notebook);
+  gtk_box_pack_start (GTK_BOX (outer_vbox), notebook, TRUE, TRUE, 0);
+
+  demos_hbox = gtk_hbox_new (FALSE, 5);
+  gtk_widget_set_name (demos_hbox, "demos_hbox");
+  gtk_widget_ref (demos_hbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demos_hbox", demos_hbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (demos_hbox);
+  gtk_container_add (GTK_CONTAINER (notebook), demos_hbox);
+
+  list_vbox = gtk_vbox_new (FALSE, 5);
+  gtk_widget_set_name (list_vbox, "list_vbox");
+  gtk_widget_ref (list_vbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "list_vbox", list_vbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (list_vbox);
+  gtk_box_pack_start (GTK_BOX (demos_hbox), list_vbox, FALSE, FALSE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (list_vbox), 10);
+
+  scroller = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_set_name (scroller, "scroller");
+  gtk_widget_ref (scroller);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "scroller", scroller,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (scroller);
+  gtk_box_pack_start (GTK_BOX (list_vbox), scroller, TRUE, TRUE, 0);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+  viewport = gtk_viewport_new (NULL, NULL);
+  gtk_widget_set_name (viewport, "viewport");
+  gtk_widget_ref (viewport);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "viewport", viewport,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (viewport);
+  gtk_container_add (GTK_CONTAINER (scroller), viewport);
+  gtk_container_set_border_width (GTK_CONTAINER (viewport), 1);
+
+  list = gtk_list_new ();
+  gtk_widget_set_name (list, "list");
+  gtk_widget_ref (list);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "list", list,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (list);
+  gtk_container_add (GTK_CONTAINER (viewport), list);
+
+  centering_hbox = gtk_hbox_new (TRUE, 0);
+  gtk_widget_set_name (centering_hbox, "centering_hbox");
+  gtk_widget_ref (centering_hbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "centering_hbox", centering_hbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (centering_hbox);
+  gtk_box_pack_start (GTK_BOX (list_vbox), centering_hbox, FALSE, TRUE, 0);
+
+  next_prev_hbox = gtk_hbox_new (FALSE, 0);
+  gtk_widget_set_name (next_prev_hbox, "next_prev_hbox");
+  gtk_widget_ref (next_prev_hbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "next_prev_hbox", next_prev_hbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (next_prev_hbox);
+  gtk_box_pack_start (GTK_BOX (centering_hbox), next_prev_hbox, FALSE, FALSE, 0);
+
+  next = gtk_button_new_with_label ("\\/");
+  gtk_widget_set_name (next, "next");
+  gtk_widget_ref (next);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "next", next,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (next);
+  gtk_box_pack_start (GTK_BOX (next_prev_hbox), next, FALSE, FALSE, 0);
+  GTK_WIDGET_SET_FLAGS (next, GTK_CAN_DEFAULT);
+  gtk_tooltips_set_tip (tooltips, next, "Run the next demo in this list in full-screen mode (click the mouse to return.)", NULL);
+
+  prev = gtk_button_new_with_label ("/\\");
+  gtk_widget_set_name (prev, "prev");
+  gtk_widget_ref (prev);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prev", prev,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prev);
+  gtk_box_pack_start (GTK_BOX (next_prev_hbox), prev, FALSE, FALSE, 0);
+  GTK_WIDGET_SET_FLAGS (prev, GTK_CAN_DEFAULT);
+  gtk_tooltips_set_tip (tooltips, prev, "Run the previous demo in this list in full-screen mode (click the mouse to return.)", NULL);
+
+  opts_vbox = gtk_vbox_new (FALSE, 0);
+  gtk_widget_set_name (opts_vbox, "opts_vbox");
+  gtk_widget_ref (opts_vbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "opts_vbox", opts_vbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (opts_vbox);
+  gtk_box_pack_start (GTK_BOX (demos_hbox), opts_vbox, TRUE, TRUE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (opts_vbox), 10);
+
+  frame = gtk_frame_new (NULL);
+  gtk_widget_set_name (frame, "frame");
+  gtk_widget_ref (frame);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "frame", frame,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame);
+  gtk_box_pack_start (GTK_BOX (opts_vbox), frame, TRUE, TRUE, 0);
+
+  doc = gtk_label_new ("");
+  gtk_widget_set_name (doc, "doc");
+  gtk_widget_ref (doc);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "doc", doc,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (doc);
+  gtk_container_add (GTK_CONTAINER (frame), doc);
+  gtk_label_set_justify (GTK_LABEL (doc), GTK_JUSTIFY_LEFT);
+  gtk_label_set_line_wrap (GTK_LABEL (doc), TRUE);
+  gtk_misc_set_alignment (GTK_MISC (doc), 0, 0);
+  gtk_misc_set_padding (GTK_MISC (doc), 10, 10);
+
+  opts_vbox2 = gtk_vbox_new (FALSE, 2);
+  gtk_widget_set_name (opts_vbox2, "opts_vbox2");
+  gtk_widget_ref (opts_vbox2);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "opts_vbox2", opts_vbox2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (opts_vbox2);
+  gtk_box_pack_start (GTK_BOX (opts_vbox), opts_vbox2, FALSE, TRUE, 0);
+
+  cmd_label = gtk_label_new ("Command Line:");
+  gtk_widget_set_name (cmd_label, "cmd_label");
+  gtk_widget_ref (cmd_label);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cmd_label", cmd_label,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (cmd_label);
+  gtk_box_pack_start (GTK_BOX (opts_vbox2), cmd_label, FALSE, FALSE, 0);
+  gtk_label_set_justify (GTK_LABEL (cmd_label), GTK_JUSTIFY_LEFT);
+  gtk_misc_set_alignment (GTK_MISC (cmd_label), 0, 1);
+  gtk_misc_set_padding (GTK_MISC (cmd_label), 0, 2);
+
+  cmd_text = gtk_entry_new ();
+  gtk_widget_set_name (cmd_text, "cmd_text");
+  gtk_widget_ref (cmd_text);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cmd_text", cmd_text,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (cmd_text);
+  gtk_box_pack_start (GTK_BOX (opts_vbox2), cmd_text, FALSE, TRUE, 0);
+
+  opts_hbox3 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_set_name (opts_hbox3, "opts_hbox3");
+  gtk_widget_ref (opts_hbox3);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "opts_hbox3", opts_hbox3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (opts_hbox3);
+  gtk_box_pack_start (GTK_BOX (opts_vbox2), opts_hbox3, FALSE, TRUE, 4);
+  gtk_container_set_border_width (GTK_CONTAINER (opts_hbox3), 4);
+
+  enabled = gtk_check_button_new_with_label ("Enabled");
+  gtk_widget_set_name (enabled, "enabled");
+  gtk_widget_ref (enabled);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "enabled", enabled,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (enabled);
+  gtk_box_pack_start (GTK_BOX (opts_hbox3), enabled, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enabled), TRUE);
+
+  visual = gtk_label_new ("Visual:");
+  gtk_widget_set_name (visual, "visual");
+  gtk_widget_ref (visual);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "visual", visual,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (visual);
+  gtk_box_pack_start (GTK_BOX (opts_hbox3), visual, FALSE, FALSE, 0);
+  gtk_label_set_justify (GTK_LABEL (visual), GTK_JUSTIFY_RIGHT);
+  gtk_misc_set_alignment (GTK_MISC (visual), 1, 0.5);
+  gtk_misc_set_padding (GTK_MISC (visual), 10, 0);
+
+  visual_combo = gtk_combo_new ();
+  gtk_widget_set_name (visual_combo, "visual_combo");
+  gtk_widget_ref (visual_combo);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "visual_combo", visual_combo,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (visual_combo);
+  gtk_box_pack_start (GTK_BOX (opts_hbox3), visual_combo, FALSE, FALSE, 0);
+  visual_combo_items = g_list_append (visual_combo_items, "Any");
+  visual_combo_items = g_list_append (visual_combo_items, "Best");
+  visual_combo_items = g_list_append (visual_combo_items, "Default");
+  visual_combo_items = g_list_append (visual_combo_items, "Default-N");
+  visual_combo_items = g_list_append (visual_combo_items, "GL");
+  visual_combo_items = g_list_append (visual_combo_items, "TrueColor");
+  visual_combo_items = g_list_append (visual_combo_items, "PseudoColor");
+  visual_combo_items = g_list_append (visual_combo_items, "StaticGray");
+  visual_combo_items = g_list_append (visual_combo_items, "GrayScale");
+  visual_combo_items = g_list_append (visual_combo_items, "DirectColor");
+  visual_combo_items = g_list_append (visual_combo_items, "Color");
+  visual_combo_items = g_list_append (visual_combo_items, "Gray");
+  visual_combo_items = g_list_append (visual_combo_items, "Mono");
+  gtk_combo_set_popdown_strings (GTK_COMBO (visual_combo), visual_combo_items);
+  g_list_free (visual_combo_items);
+
+  combo_entry1 = GTK_COMBO (visual_combo)->entry;
+  gtk_widget_set_name (combo_entry1, "combo_entry1");
+  gtk_widget_ref (combo_entry1);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "combo_entry1", combo_entry1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (combo_entry1);
+  gtk_tooltips_set_tip (tooltips, combo_entry1, "The X visual type that this demo will require.  If that visual is available it will be used, otherwise, this demo will not be run.", NULL);
+  gtk_entry_set_text (GTK_ENTRY (combo_entry1), "Any");
+
+  demo_hline = gtk_hseparator_new ();
+  gtk_widget_set_name (demo_hline, "demo_hline");
+  gtk_widget_ref (demo_hline);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demo_hline", demo_hline,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (demo_hline);
+  gtk_box_pack_start (GTK_BOX (opts_vbox), demo_hline, FALSE, FALSE, 5);
+
+  demo_cancel_hbox = gtk_hbutton_box_new ();
+  gtk_widget_set_name (demo_cancel_hbox, "demo_cancel_hbox");
+  gtk_widget_ref (demo_cancel_hbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demo_cancel_hbox", demo_cancel_hbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (demo_cancel_hbox);
+  gtk_box_pack_start (GTK_BOX (opts_vbox), demo_cancel_hbox, FALSE, TRUE, 0);
+
+  demo = gtk_button_new_with_label ("Demo");
+  gtk_widget_set_name (demo, "demo");
+  gtk_widget_ref (demo);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demo", demo,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (demo);
+  gtk_container_add (GTK_CONTAINER (demo_cancel_hbox), demo);
+  GTK_WIDGET_SET_FLAGS (demo, GTK_CAN_DEFAULT);
+  gtk_tooltips_set_tip (tooltips, demo, "Make any changes to this demo's parameters permanent, and run it in full-screen mode (click the mouse to return.)", NULL);
+
+  apply = gtk_button_new_with_label ("Apply");
+  gtk_widget_set_name (apply, "apply");
+  gtk_widget_ref (apply);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "apply", apply,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (apply);
+  gtk_container_add (GTK_CONTAINER (demo_cancel_hbox), apply);
+  GTK_WIDGET_SET_FLAGS (apply, GTK_CAN_DEFAULT);
+  gtk_tooltips_set_tip (tooltips, apply, "Make any changes to this demo's parameters permanent.", NULL);
+
+  cancel = gtk_button_new_with_label ("Cancel");
+  gtk_widget_set_name (cancel, "cancel");
+  gtk_widget_ref (cancel);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cancel", cancel,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (cancel);
+  gtk_container_add (GTK_CONTAINER (demo_cancel_hbox), cancel);
+  GTK_WIDGET_SET_FLAGS (cancel, GTK_CAN_DEFAULT);
+  gtk_tooltips_set_tip (tooltips, cancel, "Discard any changes you have made to this demo's parameters.", NULL);
+
+  demo_tab = gtk_label_new ("Graphics Demos");
+  gtk_widget_set_name (demo_tab, "demo_tab");
+  gtk_widget_ref (demo_tab);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demo_tab", demo_tab,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (demo_tab);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0), demo_tab);
+
+  prefs_hbox = gtk_vbox_new (FALSE, 0);
+  gtk_widget_set_name (prefs_hbox, "prefs_hbox");
+  gtk_widget_ref (prefs_hbox);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prefs_hbox", prefs_hbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prefs_hbox);
+  gtk_container_add (GTK_CONTAINER (notebook), prefs_hbox);
+
+  prefs_frame = gtk_frame_new (NULL);
+  gtk_widget_set_name (prefs_frame, "prefs_frame");
+  gtk_widget_ref (prefs_frame);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prefs_frame", prefs_frame,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prefs_frame);
+  gtk_box_pack_start (GTK_BOX (prefs_hbox), prefs_frame, TRUE, TRUE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (prefs_frame), 10);
+
+  prefs_table = gtk_table_new (6, 3, FALSE);
+  gtk_widget_set_name (prefs_table, "prefs_table");
+  gtk_widget_ref (prefs_table);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prefs_table", prefs_table,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prefs_table);
+  gtk_container_add (GTK_CONTAINER (prefs_frame), prefs_table);
+  gtk_container_set_border_width (GTK_CONTAINER (prefs_table), 10);
+  gtk_table_set_row_spacings (GTK_TABLE (prefs_table), 2);
+  gtk_table_set_col_spacings (GTK_TABLE (prefs_table), 10);
+
+  timeout_text = gtk_entry_new_with_max_length (8);
+  gtk_widget_set_name (timeout_text, "timeout_text");
+  gtk_widget_ref (timeout_text);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "timeout_text", timeout_text,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (timeout_text);
+  gtk_table_attach (GTK_TABLE (prefs_table), timeout_text, 1, 2, 0, 1,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, timeout_text, "How long until the screensaver activates.", NULL);
+
+  cycle_text = gtk_entry_new_with_max_length (8);
+  gtk_widget_set_name (cycle_text, "cycle_text");
+  gtk_widget_ref (cycle_text);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cycle_text", cycle_text,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (cycle_text);
+  gtk_table_attach (GTK_TABLE (prefs_table), cycle_text, 1, 2, 1, 2,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, cycle_text, "How long each demo will be run before moving on to another.", NULL);
+
+  fade_text = gtk_entry_new_with_max_length (8);
+  gtk_widget_set_name (fade_text, "fade_text");
+  gtk_widget_ref (fade_text);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_text", fade_text,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fade_text);
+  gtk_table_attach (GTK_TABLE (prefs_table), fade_text, 1, 2, 2, 3,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, fade_text, "How long (in seconds) it should take for the screen to fade to black (8-bit displays only.)", NULL);
+
+  ticks_text = gtk_entry_new_with_max_length (8);
+  gtk_widget_set_name (ticks_text, "ticks_text");
+  gtk_widget_ref (ticks_text);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "ticks_text", ticks_text,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (ticks_text);
+  gtk_table_attach (GTK_TABLE (prefs_table), ticks_text, 1, 2, 3, 4,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, ticks_text, "How many steps are in the fade animation (8-bit displays only.)", NULL);
+
+  lock_text = gtk_entry_new_with_max_length (8);
+  gtk_widget_set_name (lock_text, "lock_text");
+  gtk_widget_ref (lock_text);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_text", lock_text,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (lock_text);
+  gtk_table_attach (GTK_TABLE (prefs_table), lock_text, 1, 2, 4, 5,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, lock_text, "How long after the screensaver has activated until a password will be required (if  `Require Password' is also set.)", NULL);
+
+  pass_text = gtk_entry_new_with_max_length (8);
+  gtk_widget_set_name (pass_text, "pass_text");
+  gtk_widget_ref (pass_text);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "pass_text", pass_text,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (pass_text);
+  gtk_table_attach (GTK_TABLE (prefs_table), pass_text, 1, 2, 5, 6,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, pass_text, "How long the password dialog will wait.", NULL);
+
+  timeout_label = gtk_label_new ("Saver Timeout:");
+  gtk_widget_set_name (timeout_label, "timeout_label");
+  gtk_widget_ref (timeout_label);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "timeout_label", timeout_label,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (timeout_label);
+  gtk_table_attach (GTK_TABLE (prefs_table), timeout_label, 0, 1, 0, 1,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_label_set_justify (GTK_LABEL (timeout_label), GTK_JUSTIFY_RIGHT);
+  gtk_misc_set_alignment (GTK_MISC (timeout_label), 1, 0.5);
+
+  cycle_label = gtk_label_new ("Cycle Timeout:");
+  gtk_widget_set_name (cycle_label, "cycle_label");
+  gtk_widget_ref (cycle_label);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cycle_label", cycle_label,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (cycle_label);
+  gtk_table_attach (GTK_TABLE (prefs_table), cycle_label, 0, 1, 1, 2,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_label_set_justify (GTK_LABEL (cycle_label), GTK_JUSTIFY_RIGHT);
+  gtk_misc_set_alignment (GTK_MISC (cycle_label), 1, 0.5);
+
+  fade_label = gtk_label_new ("Fade Duration:");
+  gtk_widget_set_name (fade_label, "fade_label");
+  gtk_widget_ref (fade_label);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_label", fade_label,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fade_label);
+  gtk_table_attach (GTK_TABLE (prefs_table), fade_label, 0, 1, 2, 3,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_label_set_justify (GTK_LABEL (fade_label), GTK_JUSTIFY_RIGHT);
+  gtk_misc_set_alignment (GTK_MISC (fade_label), 1, 0.5);
+
+  ticks_label = gtk_label_new ("Fade Ticks:");
+  gtk_widget_set_name (ticks_label, "ticks_label");
+  gtk_widget_ref (ticks_label);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "ticks_label", ticks_label,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (ticks_label);
+  gtk_table_attach (GTK_TABLE (prefs_table), ticks_label, 0, 1, 3, 4,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_label_set_justify (GTK_LABEL (ticks_label), GTK_JUSTIFY_RIGHT);
+  gtk_misc_set_alignment (GTK_MISC (ticks_label), 1, 0.5);
+
+  lock_label = gtk_label_new ("Lock Timeout:");
+  gtk_widget_set_name (lock_label, "lock_label");
+  gtk_widget_ref (lock_label);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_label", lock_label,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (lock_label);
+  gtk_table_attach (GTK_TABLE (prefs_table), lock_label, 0, 1, 4, 5,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_label_set_justify (GTK_LABEL (lock_label), GTK_JUSTIFY_RIGHT);
+  gtk_misc_set_alignment (GTK_MISC (lock_label), 1, 0.5);
+
+  pass_label = gtk_label_new ("Password Timeout:");
+  gtk_widget_set_name (pass_label, "pass_label");
+  gtk_widget_ref (pass_label);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "pass_label", pass_label,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (pass_label);
+  gtk_table_attach (GTK_TABLE (prefs_table), pass_label, 0, 1, 5, 6,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_label_set_justify (GTK_LABEL (pass_label), GTK_JUSTIFY_RIGHT);
+  gtk_misc_set_alignment (GTK_MISC (pass_label), 1, 0.5);
+
+  verbose_button = gtk_check_button_new_with_label ("Verbose");
+  gtk_widget_set_name (verbose_button, "verbose_button");
+  gtk_widget_ref (verbose_button);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "verbose_button", verbose_button,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (verbose_button);
+  gtk_table_attach (GTK_TABLE (prefs_table), verbose_button, 2, 3, 0, 1,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 10, 0);
+
+  install_button = gtk_check_button_new_with_label ("Install Colormap");
+  gtk_widget_set_name (install_button, "install_button");
+  gtk_widget_ref (install_button);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "install_button", install_button,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (install_button);
+  gtk_table_attach (GTK_TABLE (prefs_table), install_button, 2, 3, 1, 2,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 10, 0);
+
+  fade_button = gtk_check_button_new_with_label ("Fade Colormap");
+  gtk_widget_set_name (fade_button, "fade_button");
+  gtk_widget_ref (fade_button);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_button", fade_button,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fade_button);
+  gtk_table_attach (GTK_TABLE (prefs_table), fade_button, 2, 3, 2, 3,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 10, 0);
+
+  unfade_button = gtk_check_button_new_with_label ("Unfade Colormap");
+  gtk_widget_set_name (unfade_button, "unfade_button");
+  gtk_widget_ref (unfade_button);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "unfade_button", unfade_button,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (unfade_button);
+  gtk_table_attach (GTK_TABLE (prefs_table), unfade_button, 2, 3, 3, 4,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 10, 0);
+
+  lock_button = gtk_check_button_new_with_label ("Require Password");
+  gtk_widget_set_name (lock_button, "lock_button");
+  gtk_widget_ref (lock_button);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_button", lock_button,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (lock_button);
+  gtk_table_attach (GTK_TABLE (prefs_table), lock_button, 2, 3, 4, 5,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 10, 0);
+
+  hbuttonbox3 = gtk_hbutton_box_new ();
+  gtk_widget_set_name (hbuttonbox3, "hbuttonbox3");
+  gtk_widget_ref (hbuttonbox3);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "hbuttonbox3", hbuttonbox3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbuttonbox3);
+  gtk_box_pack_start (GTK_BOX (prefs_hbox), hbuttonbox3, FALSE, FALSE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox3), 10);
+
+  prefs_ok = gtk_button_new_with_label ("OK");
+  gtk_widget_set_name (prefs_ok, "prefs_ok");
+  gtk_widget_ref (prefs_ok);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prefs_ok", prefs_ok,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prefs_ok);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox3), prefs_ok);
+  GTK_WIDGET_SET_FLAGS (prefs_ok, GTK_CAN_DEFAULT);
+
+  prefs_cancel = gtk_button_new_with_label ("Cancel");
+  gtk_widget_set_name (prefs_cancel, "prefs_cancel");
+  gtk_widget_ref (prefs_cancel);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prefs_cancel", prefs_cancel,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prefs_cancel);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox3), prefs_cancel);
+  GTK_WIDGET_SET_FLAGS (prefs_cancel, GTK_CAN_DEFAULT);
+
+  prefs_tab = gtk_label_new ("Screensaver Options");
+  gtk_widget_set_name (prefs_tab, "prefs_tab");
+  gtk_widget_ref (prefs_tab);
+  gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prefs_tab", prefs_tab,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prefs_tab);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), prefs_tab);
+
+  gtk_signal_connect (GTK_OBJECT (activate_menu), "activate",
+                      GTK_SIGNAL_FUNC (activate_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (lock_menu), "activate",
+                      GTK_SIGNAL_FUNC (lock_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (kill_menu), "activate",
+                      GTK_SIGNAL_FUNC (kill_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (restart), "activate",
+                      GTK_SIGNAL_FUNC (restart_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (exit_menu), "activate",
+                      GTK_SIGNAL_FUNC (exit_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (cut_menu), "activate",
+                      GTK_SIGNAL_FUNC (cut_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (copy_menu), "activate",
+                      GTK_SIGNAL_FUNC (copy_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (paste_menu), "activate",
+                      GTK_SIGNAL_FUNC (paste_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (about_menu), "activate",
+                      GTK_SIGNAL_FUNC (about_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (doc_menu), "activate",
+                      GTK_SIGNAL_FUNC (doc_menu_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (next), "clicked",
+                      GTK_SIGNAL_FUNC (run_next_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (prev), "clicked",
+                      GTK_SIGNAL_FUNC (run_prev_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (demo), "clicked",
+                      GTK_SIGNAL_FUNC (run_this_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (apply), "clicked",
+                      GTK_SIGNAL_FUNC (apply_this_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (cancel), "clicked",
+                      GTK_SIGNAL_FUNC (cancel_this_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (prefs_ok), "clicked",
+                      GTK_SIGNAL_FUNC (prefs_ok_cb),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (prefs_cancel), "clicked",
+                      GTK_SIGNAL_FUNC (prefs_cancel_cb),
+                      NULL);
+
+  gtk_widget_grab_default (next);
+  gtk_object_set_data (GTK_OBJECT (xscreensaver_demo), "tooltips", tooltips);
+
+  gtk_window_add_accel_group (GTK_WINDOW (xscreensaver_demo), accel_group);
+
+  return xscreensaver_demo;
+}
+
diff --git a/driver/demo-Gtk-widgets.h b/driver/demo-Gtk-widgets.h
new file mode 100644 (file)
index 0000000..54ca500
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+GtkWidget* create_xscreensaver_demo (void);
diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c
new file mode 100644 (file)
index 0000000..f0e8824
--- /dev/null
@@ -0,0 +1,1744 @@
+/* demo-Gtk.c --- implements the interactive demo-mode and options dialogs.
+ * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_GTK /* whole file */
+
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifndef VMS
+# include <pwd.h>              /* for getpwuid() */
+#else /* VMS */
+# include "vms-pwd.h"
+#endif /* VMS */
+
+#ifdef HAVE_UNAME
+# include <sys/utsname.h>      /* for uname() */
+#endif /* HAVE_UNAME */
+
+#include <stdio.h>
+
+#include <X11/Xproto.h>                /* for CARD32 */
+#include <X11/Xatom.h>         /* for XA_INTEGER */
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+/* We don't actually use any widget internals, but these are included
+   so that gdb will have debug info for the widgets... */
+#include <X11/IntrinsicP.h>
+#include <X11/ShellP.h>
+
+#ifdef HAVE_XMU
+# ifndef VMS
+#  include <X11/Xmu/Error.h>
+# else /* VMS */
+#  include <Xmu/Error.h>
+# endif
+#else
+# include "xmu.h"
+#endif
+
+
+
+#include <gtk/gtk.h>
+
+extern Display *gdk_display;
+
+#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 "demo-Gtk-widgets.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+
+char *progname = 0;
+char *progclass = "XScreenSaver";
+XrmDatabase db;
+
+typedef struct {
+  saver_preferences *a, *b;
+} prefs_pair;
+
+static void *global_prefs_pair;  /* I hate C so much... */
+
+
+
+char *blurb (void) { return progname; }
+
+static void run_hack (int which);
+
+static char *short_version = 0;
+
+Atom XA_VROOT;
+Atom XA_SCREENSAVER, XA_SCREENSAVER_RESPONSE, XA_SCREENSAVER_VERSION;
+Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO;
+Atom XA_ACTIVATE, XA_BLANK, XA_LOCK, XA_RESTART, XA_EXIT;
+
+
+
+static void populate_demo_window (GtkWidget *toplevel,
+                                  int which, prefs_pair *pair);
+static void populate_prefs_page (GtkWidget *top, prefs_pair *pair);
+
+
+\f
+/* Some random utility functions
+ */
+
+static GtkWidget *
+name_to_widget (GtkWidget *widget, const char *name)
+{
+  while (1)
+    {
+      GtkWidget *parent = (GTK_IS_MENU (widget)
+                           ? gtk_menu_get_attach_widget (GTK_MENU (widget))
+                           : widget->parent);
+      if (parent)
+        widget = parent;
+      else
+        break;
+    }
+  return (GtkWidget *) gtk_object_get_data (GTK_OBJECT (widget), name);
+}
+
+
+
+/* Why this behavior isn't automatic in *either* toolkit, I'll never know.
+   Takes a scroller, viewport, or list as an argument.
+ */
+static void
+ensure_selected_item_visible (GtkWidget *widget)
+{
+  GtkScrolledWindow *scroller = 0;
+  GtkViewport *vp = 0;
+  GtkList *list_widget = 0;
+  GList *slist;
+  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;
+
+  if (GTK_IS_SCROLLED_WINDOW (widget))
+    {
+      scroller = GTK_SCROLLED_WINDOW (widget);
+      vp = GTK_VIEWPORT (GTK_BIN (scroller)->child);
+      list_widget = GTK_LIST (GTK_BIN(vp)->child);
+    }
+  else if (GTK_IS_VIEWPORT (widget))
+    {
+      vp = GTK_VIEWPORT (widget);
+      scroller = GTK_SCROLLED_WINDOW (GTK_WIDGET (vp)->parent);
+      list_widget = GTK_LIST (GTK_BIN(vp)->child);
+    }
+  else if (GTK_IS_LIST (widget))
+    {
+      list_widget = GTK_LIST (widget);
+      vp = GTK_VIEWPORT (GTK_WIDGET (list_widget)->parent);
+      scroller = GTK_SCROLLED_WINDOW (GTK_WIDGET (vp)->parent);
+    }
+  else
+    abort();
+
+  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;
+      int slop = parent_h * 0.75; /* how much to overshoot by */
+
+      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);
+          target += slop;
+        }
+      else /* if (ratio_b > ((adj->value + adj->page_size) / adj->upper))*/
+        {
+          target = ratio_t * adj->upper;
+          target -= slop;
+        }
+
+      if (target > adj->upper - adj->page_size)
+        target = adj->upper - adj->page_size;
+      if (target < 0)
+        target = 0;
+
+      gtk_adjustment_set_value (adj, target);
+    }
+}
+
+
+static void
+warning_dialog_dismiss_cb (GtkButton *button, gpointer user_data)
+{
+  GtkWidget *shell = GTK_WIDGET (user_data);
+  while (shell->parent)
+    shell = shell->parent;
+  gtk_widget_destroy (GTK_WIDGET (shell));
+}
+
+
+static void
+warning_dialog (GtkWidget *parent, const char *message, int center)
+{
+  char *msg = strdup (message);
+  char *head;
+
+  GtkWidget *dialog = gtk_dialog_new ();
+  GtkWidget *label = 0;
+  GtkWidget *ok = 0;
+  int i = 0;
+
+  while (parent->parent)
+    parent = parent->parent;
+
+  head = msg;
+  while (head)
+    {
+      char name[20];
+      char *s = strchr (head, '\n');
+      if (s) *s = 0;
+
+      sprintf (name, "label%d", i++);
+
+      {
+        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"));
+        if (center <= 0)
+          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);
+      }
+
+      if (s)
+       head = s+1;
+      else
+       head = 0;
+
+      center--;
+    }
+
+  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)->action_area),
+                      label, TRUE, TRUE, 0);
+
+  ok = gtk_button_new_with_label (
+                          get_string_resource ("warning_dialog.ok.label",
+                                               "warning_dialog.Button.Label"));
+  gtk_container_add (GTK_CONTAINER (label), ok);
+
+  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+  gtk_container_set_border_width (GTK_CONTAINER (dialog), 10);
+  gtk_window_set_title (GTK_WINDOW (dialog), progclass);
+  gtk_widget_show (ok);
+  gtk_widget_show (label);
+  gtk_widget_show (dialog);
+/*  gtk_window_set_default (GTK_WINDOW (dialog), ok);*/
+
+  gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+                             GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb),
+                             (gpointer) dialog);
+  gdk_window_set_transient_for (GTK_WIDGET (dialog)->window,
+                                GTK_WIDGET (parent)->window);
+
+  gdk_window_show (GTK_WIDGET (dialog)->window);
+  gdk_window_raise (GTK_WIDGET (dialog)->window);
+
+  free (msg);
+}
+
+
+static void
+run_hack (int which)
+{
+  int status;
+  if (which < 0) return;
+  status = xscreensaver_command (gdk_display, XA_DEMO, which + 1, False);
+  if (status < 0)
+    {
+      char buf [255];
+      sprintf (buf,
+               "Error:\n\n"
+               "The DEMO %d command failed (%d).\n", which + 1, status);
+#if 0
+      warning_dialog (GTK_WIDGET (menuitem), buf, 1);
+#endif
+    }
+}
+
+
+\f
+/* Button callbacks
+ */
+
+void
+exit_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  gtk_main_quit ();
+}
+
+static void
+wm_close_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+  exit_menu_cb (NULL, NULL);
+}
+
+
+void
+cut_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  /* #### */
+  warning_dialog (GTK_WIDGET (menuitem),
+                  "Error:\n\n"
+                  "cut unimplemented\n", 1);
+}
+
+
+void
+copy_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  /* #### */
+  warning_dialog (GTK_WIDGET (menuitem),
+                  "Error:\n\n"
+                  "copy unimplemented\n", 1);
+}
+
+
+void
+paste_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  /* #### */
+  warning_dialog (GTK_WIDGET (menuitem),
+                  "Error:\n\n"
+                  "paste unimplemented\n", 1);
+}
+
+
+void
+about_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  char buf [2048];
+  char *s = strdup (screensaver_id + 4);
+  char *s2;
+
+  s2 = strchr (s, ',');
+  *s2 = 0;
+  s2 += 2;
+
+  sprintf (buf, "%s\n%s\n\n"
+           "For updates, check http://www.jwz.org/xscreensaver/",
+           s, s2);
+  free (s);
+
+  warning_dialog (GTK_WIDGET (menuitem), buf, 100);
+}
+
+
+void
+doc_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+
+  saver_preferences *p =  pair->a;
+  char *help_command;
+
+  if (!p->help_url || !*p->help_url)
+    {
+      warning_dialog (GTK_WIDGET (menuitem),
+                      "Error:\n\n"
+                      "No Help URL has been specified.\n", 100);
+      return;
+    }
+
+  help_command = (char *) malloc (strlen (p->load_url_command) +
+                                 (strlen (p->help_url) * 2) + 20);
+  strcpy (help_command, "( ");
+  sprintf (help_command + strlen(help_command),
+           p->load_url_command, p->help_url, p->help_url);
+  strcat (help_command, " ) &");
+  system (help_command);
+  free (help_command);
+}
+
+
+void
+activate_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  int status = xscreensaver_command (gdk_display, XA_ACTIVATE, 0, False);
+  if (status < 0)
+    {
+      char buf [255];
+      sprintf (buf,
+               "Error:\n\n"
+               "The ACTIVATE command failed (%d).\n", status);
+      warning_dialog (GTK_WIDGET (menuitem), buf, 100);
+    }
+}
+
+
+void
+lock_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  int status = xscreensaver_command (gdk_display, XA_LOCK, 0, False);
+  if (status < 0)
+    {
+      char buf [255];
+      sprintf (buf,
+               "Error:\n\n"
+               "The LOCK command failed (%d).\n", status);
+      warning_dialog (GTK_WIDGET (menuitem), buf, 100);
+    }
+}
+
+
+void
+kill_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+  int status = xscreensaver_command (gdk_display, XA_EXIT, 0, False);
+  if (status < 0)
+    {
+      char buf [255];
+      sprintf (buf,
+               "Error:\n\n"
+               "The EXIT command failed (%d).\n", status);
+      warning_dialog (GTK_WIDGET (menuitem), buf, 100);
+    }
+}
+
+
+void
+restart_menu_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+#if 0
+  int status = xscreensaver_command (gdk_display, XA_RESTART, 0, False);
+  if (status < 0)
+    {
+      char buf [255];
+      sprintf (buf,
+               "Error:\n\n"
+               "The RESTART command failed (%d).\n", status);
+      warning_dialog (GTK_WIDGET (menuitem), buf, 100);
+    }
+#else
+  xscreensaver_command (gdk_display, XA_EXIT, 0, False);
+  sleep (1);
+  system ("xscreensaver -nosplash &");
+#endif
+}
+
+
+static int
+selected_hack_number (GtkWidget *toplevel)
+{
+  GtkViewport *vp = GTK_VIEWPORT (name_to_widget (toplevel, "viewport"));
+  GtkList *list_widget = GTK_LIST (GTK_BIN(vp)->child);
+  GList *slist = list_widget->selection;
+  GtkWidget *selected = (slist ? GTK_WIDGET (slist->data) : 0);
+  int which = (selected
+               ? gtk_list_child_position (list_widget, GTK_WIDGET (selected))
+               : -1);
+  return which;
+}
+
+
+void
+apply_this_cb (GtkButton *button, gpointer user_data)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+
+  saver_preferences *p =  pair->a;
+  GtkList *list_widget =
+    GTK_LIST (name_to_widget (GTK_WIDGET (button), "list"));
+  int which = selected_hack_number (GTK_WIDGET (button));
+
+  GtkEntry *cmd = GTK_ENTRY (name_to_widget (GTK_WIDGET (button), "cmd_text"));
+  GtkToggleButton *enabled =
+    GTK_TOGGLE_BUTTON (name_to_widget (GTK_WIDGET (button), "enabled"));
+  GtkCombo *vis = GTK_COMBO (name_to_widget (GTK_WIDGET (button),
+                                             "visual_combo"));
+
+  Bool enabled_p = gtk_toggle_button_get_active (enabled);
+  const char *visual = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (vis)->entry));
+  const char *command = gtk_entry_get_text (cmd);
+  
+  char c;
+  unsigned long id;
+
+  if (which < 0) return;
+
+  /* Sanity-check and canonicalize whatever the user typed into the combo box.
+   */
+  if      (!strcasecmp (visual, "any"))                visual = "";
+  if      (!strcasecmp (visual, "default"))            visual = "Default";
+  else if (!strcasecmp (visual, "default-n"))          visual = "Default-N";
+  else if (!strcasecmp (visual, "default-i"))          visual = "Default-I";
+  else if (!strcasecmp (visual, "best"))               visual = "Best";
+  else if (!strcasecmp (visual, "mono"))               visual = "Mono";
+  else if (!strcasecmp (visual, "monochrome"))         visual = "Mono";
+  else if (!strcasecmp (visual, "gray"))               visual = "Gray";
+  else if (!strcasecmp (visual, "grey"))               visual = "Gray";
+  else if (!strcasecmp (visual, "color"))              visual = "Color";
+  else if (!strcasecmp (visual, "gl"))                 visual = "GL";
+  else if (!strcasecmp (visual, "staticgray"))         visual = "StaticGray";
+  else if (!strcasecmp (visual, "staticcolor"))        visual = "StaticColor";
+  else if (!strcasecmp (visual, "truecolor"))          visual = "TrueColor";
+  else if (!strcasecmp (visual, "grayscale"))          visual = "GrayScale";
+  else if (!strcasecmp (visual, "greyscale"))          visual = "GrayScale";
+  else if (!strcasecmp (visual, "pseudocolor"))        visual = "PseudoColor";
+  else if (!strcasecmp (visual, "directcolor"))        visual = "DirectColor";
+  else if (1 == sscanf (visual, " %ld %c", &id, &c))   ;
+  else if (1 == sscanf (visual, " 0x%lx %c", &id, &c)) ;
+  else
+    {
+      gdk_beep ();                               /* unparsable */
+      visual = "";
+      gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry), "Any");
+    }
+
+  p->screenhacks[which]->enabled_p = enabled_p;
+  if (p->screenhacks[which]->visual)
+    free (p->screenhacks[which]->visual);
+  if (p->screenhacks[which]->command)
+    free (p->screenhacks[which]->command);
+  p->screenhacks[which]->visual = strdup (visual);
+  p->screenhacks[which]->command = strdup (command);
+
+  ensure_selected_item_visible (GTK_WIDGET (list_widget));
+
+  write_init_file (p, short_version);
+}
+
+
+void
+run_this_cb (GtkButton *button, gpointer user_data)
+{
+  int which = selected_hack_number (GTK_WIDGET (button));
+  if (which < 0) return;
+  apply_this_cb (button, user_data);
+  run_hack (which);
+}
+
+
+void
+cancel_this_cb (GtkButton *button, gpointer user_data)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+  GtkList *list_widget =
+    GTK_LIST (name_to_widget (GTK_WIDGET (button), "list"));
+  int which = selected_hack_number (GTK_WIDGET (button));
+  if (which < 0) return;
+  ensure_selected_item_visible (GTK_WIDGET (list_widget));
+  populate_demo_window (GTK_WIDGET (button), which, pair);
+}
+
+
+void
+run_next_cb (GtkButton *button, gpointer user_data)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+  saver_preferences *p =  pair->a;
+
+  GtkList *list_widget =
+    GTK_LIST (name_to_widget (GTK_WIDGET (button), "list"));
+  int which = selected_hack_number (GTK_WIDGET (button));
+
+  if (which < 0)
+    which = 0;
+  else
+    which++;
+
+  if (which >= p->screenhacks_count)
+    which = 0;
+
+  gtk_list_select_item (GTK_LIST (list_widget), which);
+  ensure_selected_item_visible (GTK_WIDGET (list_widget));
+  populate_demo_window (GTK_WIDGET (button), which, pair);
+  run_hack (which);
+}
+
+
+void
+run_prev_cb (GtkButton *button, gpointer user_data)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+  saver_preferences *p =  pair->a;
+
+  GtkList *list_widget =
+    GTK_LIST (name_to_widget (GTK_WIDGET (button), "list"));
+  int which = selected_hack_number (GTK_WIDGET (button));
+
+  if (which < 0)
+    which = p->screenhacks_count - 1;
+  else
+    which--;
+
+  if (which < 0)
+    which = p->screenhacks_count - 1;
+
+  gtk_list_select_item (GTK_LIST (list_widget), which);
+  ensure_selected_item_visible (GTK_WIDGET (list_widget));
+  populate_demo_window (GTK_WIDGET (button), which, pair);
+  run_hack (which);
+}
+
+
+/* Helper for the text fields that contain time specifications:
+   this parses the text, and does error checking.
+ */
+static void 
+hack_time_text (const char *line, Time *store, Bool sec_p)
+{
+  if (*line)
+    {
+      int value;
+      value = parse_time ((char *) line, sec_p, True);
+      value *= 1000;   /* Time measures in microseconds */
+      if (value < 0)
+        /* gdk_beep () */;
+      else
+       *store = value;
+    }
+}
+
+
+void
+prefs_ok_cb (GtkButton *button, gpointer user_data)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+
+  saver_preferences *p =  pair->a;
+  saver_preferences *p2 = pair->b;
+
+# define SECONDS(field, name) \
+  hack_time_text (gtk_entry_get_text (\
+                    GTK_ENTRY (name_to_widget (GTK_WIDGET(button), (name)))), \
+                  (field), \
+                  True)
+
+# define MINUTES(field, name) \
+  hack_time_text (gtk_entry_get_text (\
+                    GTK_ENTRY (name_to_widget (GTK_WIDGET(button), (name)))), \
+                  (field), \
+                  False)
+
+# define INTEGER(field, name) do { \
+    char *line = gtk_entry_get_text (\
+                    GTK_ENTRY (name_to_widget (GTK_WIDGET(button), (name)))); \
+    unsigned int value; \
+    char c; \
+    if (! *line) \
+      ; \
+    else if (sscanf (line, "%u%c", &value, &c) != 1) \
+     gdk_beep(); \
+   else \
+     *(field) = value; \
+  } while(0)
+
+  MINUTES (&p2->timeout,        "timeout_text");
+  MINUTES (&p2->cycle,          "cycle_text");
+  SECONDS (&p2->fade_seconds,   "fade_text");
+  INTEGER (&p2->fade_ticks,     "ticks_text");
+  MINUTES (&p2->lock_timeout,   "lock_text");
+  SECONDS (&p2->passwd_timeout, "pass_text");
+
+#undef SECONDS
+#undef MINUTES
+#undef INTEGER
+
+  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;
+
+  populate_prefs_page (GTK_WIDGET (button), pair);
+
+  write_init_file (p, short_version);
+}
+
+
+void
+prefs_cancel_cb (GtkButton *button, gpointer user_data)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+
+  *pair->b = *pair->a;
+  populate_prefs_page (GTK_WIDGET (button), pair);
+}
+
+
+static gint
+list_doubleclick_cb (GtkWidget *button, GdkEventButton *event,
+                     gpointer client_data)
+{
+  if (event->type == GDK_2BUTTON_PRESS)
+    {
+      GtkList *list = GTK_LIST (name_to_widget (button, "list"));
+      int which = gtk_list_child_position (list, GTK_WIDGET (button));
+
+      if (which >= 0)
+        run_hack (which);
+    }
+
+  return FALSE;
+}
+
+
+static void
+list_select_cb (GtkList *list, GtkWidget *child)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+
+  int which = gtk_list_child_position (list, GTK_WIDGET (child));
+  populate_demo_window (GTK_WIDGET (list), which, pair);
+}
+
+static void
+list_unselect_cb (GtkList *list, GtkWidget *child)
+{
+  /* prefs_pair *pair = (prefs_pair *) client_data; */
+  prefs_pair *pair = global_prefs_pair;  /* I hate C so much... */
+
+  populate_demo_window (GTK_WIDGET (list), -1, pair);
+}
+
+\f
+/* Populating the various widgets
+ */
+
+
+/* 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 char *
+make_pretty_name (const char *shell_command)
+{
+  char *s = strdup (shell_command);
+  char *s2;
+  char res_name[255];
+
+  for (s2 = s; *s2; s2++)      /* truncate at first whitespace */
+    if (isspace (*s2))
+      {
+        *s2 = 0;
+        break;
+      }
+
+  s2 = strrchr (s, '/');       /* if pathname, take last component */
+  if (s2)
+    {
+      s2 = strdup (s2+1);
+      free (s);
+      s = s2;
+    }
+
+  if (strlen (s) > 50)         /* 51 is hereby defined as "unreasonable" */
+    s[50] = 0;
+
+  sprintf (res_name, "hacks.%s.name", s);              /* resource? */
+  s2 = get_string_resource (res_name, res_name);
+  if (s2)
+    return s2;
+
+  for (s2 = s; *s2; s2++)      /* if it has any capitals, return it */
+    if (*s2 >= 'A' && *s2 <= 'Z')
+      return s;
+
+  if (s[0] >= 'a' && s[0] <= 'z')                      /* else cap it */
+    s[0] -= 'a'-'A';
+  if (s[0] == 'X' && s[1] >= 'a' && s[1] <= 'z')       /* (magic leading X) */
+    s[1] -= 'a'-'A';
+  return s;
+}
+
+
+/* Finds the number of the last hack to run, and makes that item be
+   selected by default.
+ */
+static void
+scroll_to_current_hack (GtkWidget *toplevel, prefs_pair *pair)
+{
+  Atom type;
+  int format;
+  unsigned long nitems, bytesafter;
+  CARD32 *data = 0;
+  Display *dpy = gdk_display;
+  int which = 0;
+  GtkList *list;
+
+  if (XGetWindowProperty (dpy, RootWindow (dpy, 0), /* always screen #0 */
+                          XA_SCREENSAVER_STATUS,
+                          0, 3, False, XA_INTEGER,
+                          &type, &format, &nitems, &bytesafter,
+                          (unsigned char **) &data)
+      == Success
+      && type == XA_INTEGER
+      && nitems >= 3
+      && data)
+    which = (int) data[2] - 1;
+
+  if (data) free (data);
+
+  if (which < 0)
+    return;
+
+  list = GTK_LIST (name_to_widget (toplevel, "list"));
+  gtk_list_select_item (list, which);
+  ensure_selected_item_visible (GTK_WIDGET (list));
+  populate_demo_window (toplevel, which, pair);
+}
+
+
+
+static void
+populate_hack_list (GtkWidget *toplevel, prefs_pair *pair)
+{
+  saver_preferences *p =  pair->a;
+  GtkList *list = GTK_LIST (name_to_widget (toplevel, "list"));
+  screenhack **hacks = p->screenhacks;
+  screenhack **h;
+
+  for (h = hacks; *h; h++)
+    {
+      GtkWidget *line;
+      char *pretty_name = (h[0]->name
+                           ? strdup (h[0]->name)
+                           : make_pretty_name (h[0]->command));
+
+      line = gtk_list_item_new_with_label (pretty_name);
+      free (pretty_name);
+
+      gtk_container_add (GTK_CONTAINER (list), line);
+      gtk_signal_connect (GTK_OBJECT (line), "button_press_event",
+                          GTK_SIGNAL_FUNC (list_doubleclick_cb),
+                          (gpointer) pair);
+#if 0 /* #### */
+      GTK_WIDGET (GTK_BIN(line)->child)->style =
+        gtk_style_copy (GTK_WIDGET (text_line)->style);
+#endif
+      gtk_widget_show (line);
+    }
+
+  gtk_signal_connect (GTK_OBJECT (list), "select_child",
+                      GTK_SIGNAL_FUNC (list_select_cb),
+                      (gpointer) pair);
+  gtk_signal_connect (GTK_OBJECT (list), "unselect_child",
+                      GTK_SIGNAL_FUNC (list_unselect_cb),
+                      (gpointer) pair);
+}
+
+
+static void
+populate_prefs_page (GtkWidget *top, prefs_pair *pair)
+{
+  saver_preferences *p =  pair->a;
+  char s[100];
+
+  format_time (s, p->timeout);
+  gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "timeout_text")), s);
+  format_time (s, p->cycle);
+  gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "cycle_text")), s);
+  format_time (s, p->lock_timeout);
+  gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "lock_text")), s);
+  format_time (s, p->passwd_timeout);
+  gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "pass_text")), s);
+  format_time (s, p->fade_seconds);
+  gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "fade_text")), s);
+  sprintf (s, "%u", p->fade_ticks);
+  gtk_entry_set_text (GTK_ENTRY (name_to_widget (top, "ticks_text")), s);
+
+  gtk_toggle_button_set_active (
+                   GTK_TOGGLE_BUTTON (name_to_widget (top, "verbose_button")),
+                   p->verbose_p);
+  gtk_toggle_button_set_active (
+                   GTK_TOGGLE_BUTTON (name_to_widget (top, "install_button")),
+                   p->install_cmap_p);
+  gtk_toggle_button_set_active (
+                   GTK_TOGGLE_BUTTON (name_to_widget (top, "fade_button")),
+                   p->fade_p);
+  gtk_toggle_button_set_active (
+                   GTK_TOGGLE_BUTTON (name_to_widget (top, "unfade_button")),
+                   p->unfade_p);
+  gtk_toggle_button_set_active (
+                   GTK_TOGGLE_BUTTON (name_to_widget (top, "lock_button")),
+                   p->lock_p);
+
+
+  {
+    Bool found_any_writable_cells = False;
+    Display *dpy = gdk_display;
+    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;
+         }
+      }
+
+    gtk_widget_set_sensitive (
+                           GTK_WIDGET (name_to_widget (top, "fade_label")),
+                           found_any_writable_cells);
+    gtk_widget_set_sensitive (
+                           GTK_WIDGET (name_to_widget (top, "ticks_label")),
+                           found_any_writable_cells);
+    gtk_widget_set_sensitive (
+                           GTK_WIDGET (name_to_widget (top, "fade_text")),
+                           found_any_writable_cells);
+    gtk_widget_set_sensitive (
+                           GTK_WIDGET (name_to_widget (top, "ticks_text")),
+                           found_any_writable_cells);
+    gtk_widget_set_sensitive (
+                           GTK_WIDGET (name_to_widget (top, "install_button")),
+                           found_any_writable_cells);
+    gtk_widget_set_sensitive (
+                           GTK_WIDGET (name_to_widget (top, "fade_button")),
+                           found_any_writable_cells);
+    gtk_widget_set_sensitive (
+                           GTK_WIDGET (name_to_widget (top, "unfade_button")),
+                           found_any_writable_cells);
+  }
+
+}
+
+
+static void
+sensitize_demo_widgets (GtkWidget *toplevel, Bool sensitive_p)
+{
+  const char *names[] = { "cmd_label", "cmd_text", "enabled",
+                          "visual", "visual_combo",
+                          "demo", "apply", "cancel" };
+  int i;
+  for (i = 0; i < countof(names); i++)
+    {
+      GtkWidget *w = name_to_widget (toplevel, names[i]);
+      gtk_widget_set_sensitive (GTK_WIDGET(w), sensitive_p);
+    }
+
+  /* I don't know how to handle these yet... */
+  {
+    const char *names2[] = { "cut_menu", "copy_menu", "paste_menu" };
+    for (i = 0; i < countof(names2); i++)
+      {
+        GtkWidget *w = name_to_widget (toplevel, names2[i]);
+        gtk_widget_set_sensitive (GTK_WIDGET(w), False);
+      }
+  }
+}
+
+
+/* Even though we've given these text fields a maximum number of characters,
+   their default size is still about 30 characters wide -- so measure out
+   a string in their font, and resize them to just fit that.
+ */
+static void
+fix_text_entry_sizes (GtkWidget *toplevel)
+{
+  const char *names[] = { "timeout_text", "cycle_text", "fade_text",
+                          "ticks_text", "lock_text", "pass_text" };
+  int i;
+  int width = 0;
+  GtkWidget *w;
+
+  for (i = 0; i < countof(names); i++)
+    {
+      w = GTK_WIDGET (name_to_widget (toplevel, names[i]));
+      if (width == 0)
+        width = gdk_text_width (w->style->font, "00:00:00_", 9);
+      gtk_widget_set_usize (w, width, -2);
+    }
+
+  /* Now fix the size of the combo box.
+   */
+  w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "visual_combo"));
+  w = GTK_COMBO (w)->entry;
+  width = gdk_text_width (w->style->font, "PseudoColor___", 14);
+  gtk_widget_set_usize (w, width, -2);
+
+#if 0
+  /* Now fix the size of the list.
+   */
+  w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "list"));
+  width = gdk_text_width (w->style->font, "nnnnnnnnnnnnnnnnnnnnnn", 22);
+  gtk_widget_set_usize (w, width, -2);
+#endif
+}
+
+
+
+\f
+/* Pixmaps for the up and down arrow buttons (yeah, this is sleazy...)
+ */
+
+static char *up_arrow_xpm[] = {
+  "15 15 4 1",
+  "    c None",
+  "-   c #FFFFFF",
+  "+   c #D6D6D6",
+  "@   c #000000",
+
+  "       @       ",
+  "       @       ",
+  "      -+@      ",
+  "      -+@      ",
+  "     -+++@     ",
+  "     -+++@     ",
+  "    -+++++@    ",
+  "    -+++++@    ",
+  "   -+++++++@   ",
+  "   -+++++++@   ",
+  "  -+++++++++@  ",
+  "  -+++++++++@  ",
+  " -+++++++++++@ ",
+  " @@@@@@@@@@@@@ ",
+  "               ",
+
+  /* Need these here because gdk_pixmap_create_from_xpm_d() walks off
+     the end of the array (Gtk 1.2.5.) */
+  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
+  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+};
+
+static char *down_arrow_xpm[] = {
+  "15 15 4 1",
+  "    c None",
+  "-   c #FFFFFF",
+  "+   c #D6D6D6",
+  "@   c #000000",
+
+  " ------------- ",
+  " -+++++++++++@ ",
+  "  -+++++++++@  ",
+  "  -+++++++++@  ",
+  "   -+++++++@   ",
+  "   -+++++++@   ",
+  "    -+++++@    ",
+  "    -+++++@    ",
+  "     -+++@     ",
+  "     -+++@     ",
+  "      -+@      ",
+  "      -+@      ",
+  "       @       ",
+  "       @       ",
+
+  /* Need these here because gdk_pixmap_create_from_xpm_d() walks off
+     the end of the array (Gtk 1.2.5.) */
+  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
+  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+};
+
+static void
+pixmapify_buttons (GtkWidget *toplevel)
+{
+  GdkPixmap *pixmap;
+  GdkBitmap *mask;
+  GtkWidget *pixmapwid;
+  GtkStyle *style;
+  GtkWidget *w;
+
+  w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "next"));
+  style = gtk_widget_get_style (w);
+  mask = 0;
+  pixmap = gdk_pixmap_create_from_xpm_d (w->window, &mask,
+                                         &style->bg[GTK_STATE_NORMAL],
+                                         (gchar **) down_arrow_xpm);
+  pixmapwid = gtk_pixmap_new (pixmap, mask);
+  gtk_widget_show (pixmapwid);
+  gtk_container_remove (GTK_CONTAINER (w), GTK_BIN (w)->child);
+  gtk_container_add (GTK_CONTAINER (w), pixmapwid);
+
+  w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "prev"));
+  style = gtk_widget_get_style (w);
+  mask = 0;
+  pixmap = gdk_pixmap_create_from_xpm_d (w->window, &mask,
+                                         &style->bg[GTK_STATE_NORMAL],
+                                         (gchar **) up_arrow_xpm);
+  pixmapwid = gtk_pixmap_new (pixmap, mask);
+  gtk_widget_show (pixmapwid);
+  gtk_container_remove (GTK_CONTAINER (w), GTK_BIN (w)->child);
+  gtk_container_add (GTK_CONTAINER (w), pixmapwid);
+}
+
+
+\f
+/* Work around a Gtk bug that causes label widgets to wrap text too early.
+ */
+
+static void
+you_are_not_a_unique_or_beautiful_snowflake (GtkWidget *label,
+                                             GtkAllocation *allocation,
+                                            void *foo)
+{
+  GtkRequisition req;
+  GtkWidgetAuxInfo *aux_info;
+
+  aux_info = gtk_object_get_data (GTK_OBJECT (label), "gtk-aux-info");
+
+  aux_info->width = allocation->width;
+  aux_info->height = -2;
+  aux_info->x = -1;
+  aux_info->y = -1;
+
+  gtk_widget_size_request (label, &req);
+}
+
+
+/* Feel the love.  Thanks to Nat Friedman for finding this workaround.
+ */
+static void
+eschew_gtk_lossage (GtkWidget *toplevel)
+{
+  GtkWidgetAuxInfo *aux_info;
+  GtkWidget *label = GTK_WIDGET (name_to_widget (toplevel, "doc"));
+
+  aux_info = g_new0 (GtkWidgetAuxInfo, 1);
+  aux_info->width = label->allocation.width;
+  aux_info->height = -2;
+  aux_info->x = -1;
+  aux_info->y = -1;
+
+  gtk_object_set_data (GTK_OBJECT (label), "gtk-aux-info", aux_info);
+
+  gtk_signal_connect (GTK_OBJECT (label), "size_allocate",
+                     you_are_not_a_unique_or_beautiful_snowflake, NULL);
+
+  gtk_widget_queue_resize (label); 
+}
+
+
+char *
+get_hack_blurb (screenhack *hack)
+{
+  char *doc_string;
+  char *prog_name = strdup (hack->command);
+  char *pretty_name = (hack->name
+                       ? strdup (hack->name)
+                       : make_pretty_name (hack->command));
+  char doc_name[255], doc_class[255];
+  char *s, *s2;
+
+  for (s = prog_name; *s && !isspace(*s); s++)
+    ;
+  *s = 0;
+  s = strrchr (prog_name, '/');
+  if (s) strcpy (prog_name, s+1);
+
+  sprintf (doc_name,  "hacks.%s.documentation", pretty_name);
+  sprintf (doc_class, "hacks.%s.documentation", prog_name);
+  free (prog_name);
+  free (pretty_name);
+
+  doc_string = get_string_resource (doc_name, doc_class);
+  if (doc_string)
+    {
+      for (s = doc_string; *s; s++)
+        {
+          if (*s == '\n')
+            {
+              /* skip over whitespace at beginning of line */
+              s++;
+              while (*s && (*s == ' ' || *s == '\t'))
+                s++;
+            }
+          else if (*s == ' ' || *s == '\t')
+            {
+              /* compress all other horizontal whitespace. */
+              *s = ' ';
+              s++;
+              for (s2 = s; *s2 && (*s2 == ' ' || *s2 == '\t'); s2++)
+                ;
+              if (s2 > s) strcpy (s, s2);
+              s--;
+            }
+        }
+
+      while (*s && isspace (*s))      /* Strip trailing whitespace */
+        *(--s) = 0;
+
+      /* Delete whitespace at end of each line. */
+      for (; s > doc_string; s--)
+        if (*s == '\n' && (s[-1] == ' ' || s[-1] == '\t'))
+          {
+            for (s2 = s-1;
+                 s2 > doc_string && (*s2 == ' ' || *s2 == '\t');
+                 s2--)
+              ;
+            s2++;
+            if (s2 < s) strcpy (s2, s);
+            s = s2;
+          }
+      
+      /* Delete leading blank lines. */
+      for (s = doc_string; *s == '\n'; s++)
+        ;
+      if (s > doc_string) strcpy (doc_string, s);
+    }
+  else
+    {
+      static int doc_installed = 0;
+      if (doc_installed == 0)
+        {
+          if (get_boolean_resource ("hacks.documentation.isInstalled",
+                                    "hacks.documentation.isInstalled"))
+            doc_installed = 1;
+          else
+            doc_installed = -1;
+        }
+
+      if (doc_installed < 0)
+        doc_string =
+          strdup ("Error:\n\n"
+                  "The documentation strings do not appear to be "
+                  "installed.  This is probably because there is "
+                  "an \"XScreenSaver\" app-defaults file installed "
+                  "that is from an older version of the program. "
+                  "To fix this problem, delete that file, or "
+                  "install a current version (either will work.)");
+      else
+        doc_string = strdup ("");
+    }
+
+  return doc_string;
+}
+
+
+static void
+populate_demo_window (GtkWidget *toplevel, int which, prefs_pair *pair)
+{
+  saver_preferences *p = pair->a;
+  screenhack *hack = (which >= 0 ? p->screenhacks[which] : 0);
+  GtkFrame *frame = GTK_FRAME (name_to_widget (toplevel, "frame"));
+  GtkLabel *doc = GTK_LABEL (name_to_widget (toplevel, "doc"));
+  GtkEntry *cmd = GTK_ENTRY (name_to_widget (toplevel, "cmd_text"));
+  GtkToggleButton *enabled =
+    GTK_TOGGLE_BUTTON (name_to_widget (toplevel, "enabled"));
+  GtkCombo *vis = GTK_COMBO (name_to_widget (toplevel, "visual_combo"));
+
+  char *pretty_name = (hack
+                       ? (hack->name
+                          ? strdup (hack->name)
+                          : make_pretty_name (hack->command))
+                       : 0);
+  char *doc_string = hack ? get_hack_blurb (hack) : 0;
+
+  gtk_frame_set_label (frame, (pretty_name ? pretty_name : ""));
+  gtk_label_set_text (doc, (doc_string ? doc_string : ""));
+  gtk_entry_set_text (cmd, (hack ? hack->command : ""));
+  gtk_entry_set_position (cmd, 0);
+  gtk_toggle_button_set_active (enabled, (hack ? hack->enabled_p : False));
+  gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry),
+                      (hack
+                       ? (hack->visual && hack->visual
+                          ? hack->visual
+                          : "Any")
+                       : ""));
+
+  gtk_container_resize_children (GTK_CONTAINER (GTK_WIDGET (doc)->parent));
+
+  sensitize_demo_widgets (toplevel, (hack ? True : False));
+
+  if (pretty_name) free (pretty_name);
+  if (doc_string) free (doc_string);
+}
+
+
+
+\f
+/* 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 (GtkWidget *parent)
+{
+  Display *dpy = gdk_display;
+  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 = "<UNKNOWN>";
+  else
+    lhost = uts.nodename;
+# elif defined(VMS)
+  strcpy (lhost, getenv("SYS$NODE"));
+# else  /* !HAVE_UNAME && !VMS */
+  strcat (lhost, "<UNKNOWN>");
+# 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) +
+                              1024));
+  *msg = 0;
+
+  if (!rversion || !*rversion)
+    {
+      sprintf (msg,
+              "Warning:\n\n"
+               "The XScreenSaver daemon doesn't seem to be running\n"
+               "on display \"%s\".  You can launch it by selecting\n"
+               "`Restart Daemon' from the File menu, or by typing\n"
+               "\"xscreensaver &\" in a shell.",
+              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\" (which you can do by\n"
+              "selecting `Restart Daemon' from the File menu.)\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.\n"
+               "\n"
+               "You can restart the daemon on \"%s\" as \"%s\" by\n"
+               "selecting `Restart Daemon' from the File menu.)",
+              progname, luser, lhost,
+              d,
+              (ruser ? ruser : "???"), (rhost ? rhost : "???"),
+              luser,
+              progname,
+               lhost, luser);
+    }
+  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, 1);
+
+  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;
+}
+
+
+/* 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" : ""));
+}
+
+
+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;
+  GtkWidget *gtk_window;
+  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));
+
+  global_prefs_pair = pair;  /* I hate C so much... */
+
+  progname = real_progname;
+
+  short_version = (char *) malloc (5);
+  memcpy (short_version, screensaver_id + 17, 4);
+  short_version [4] = 0;
+
+
+  /* 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);
+
+
+  /* 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];
+
+
+  /* Teach Xt to use the Display that Gtk/Gdk have already opened.
+   */
+  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);
+
+  dpy = XtDisplay (toplevel_shell);
+  db = XtDatabase (dpy);
+  XtGetApplicationNameAndClass (dpy, &progname, &progclass);
+  XSetErrorHandler (demo_ehandler);
+
+
+  /* After doing Xt-style command-line processing, complain about any
+     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);
+       }
+    }
+
+  /* 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;
+
+
+#if 0
+  /* Print out all the resources we read. */
+  {
+    XrmName name = { 0 };
+    XrmClass class = { 0 };
+    int count = 0;
+    XrmEnumerateDatabase (db, &name, &class, XrmEnumAllLevels, mapper,
+                         (POINTER) &count);
+  }
+#endif
+
+
+  /* Intern the atoms that xscreensaver_command() needs.
+   */
+  XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False);
+  XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False);
+  XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False);
+  XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", 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_ACTIVATE = XInternAtom (dpy, "ACTIVATE", False);
+  XA_BLANK = XInternAtom (dpy, "BLANK", False);
+  XA_LOCK = XInternAtom (dpy, "LOCK", False);
+  XA_EXIT = XInternAtom (dpy, "EXIT", False);
+  XA_RESTART = XInternAtom (dpy, "RESTART", False);
+
+
+  /* Create the window and all its widgets.
+   */
+  gtk_window = create_xscreensaver_demo ();
+
+  /* Set the window's title. */
+  {
+    char title[255];
+    char *v = (char *) strdup(strchr(screensaver_id, ' '));
+    char *s1, *s2, *s3, *s4;
+    s1 = (char *) strchr(v,  ' '); s1++;
+    s2 = (char *) strchr(s1, ' ');
+    s3 = (char *) strchr(v,  '('); s3++;
+    s4 = (char *) strchr(s3, ')');
+    *s2 = 0;
+    *s4 = 0;
+    sprintf (title, "%.50s %.50s, %.50s", progclass, s1, s3);
+    gtk_window_set_title (GTK_WINDOW (gtk_window), title);
+    free (v);
+  }
+
+  /* Various other widget initializations...
+   */
+  gtk_signal_connect (GTK_OBJECT (gtk_window), "delete_event",
+                      GTK_SIGNAL_FUNC (wm_close_cb), NULL);
+
+  populate_hack_list (gtk_window, pair);
+  populate_prefs_page (gtk_window, pair);
+  sensitize_demo_widgets (gtk_window, False);
+  fix_text_entry_sizes (gtk_window);
+  scroll_to_current_hack (gtk_window, pair);
+  gtk_widget_show (gtk_window);
+
+  /* The next three calls must come after gtk_widget_show(). */
+  pixmapify_buttons (gtk_window);
+  eschew_gtk_lossage (gtk_window);
+  ensure_selected_item_visible (GTK_WIDGET(name_to_widget(gtk_window,"list")));
+
+  /* Handle the -prefs command-line argument. */
+  if (prefs)
+    {
+      GtkNotebook *notebook =
+        GTK_NOTEBOOK (name_to_widget (gtk_window, "notebook"));
+      gtk_notebook_set_page (notebook, 1);
+    }
+
+  /* Issue any warnings about the running xscreensaver daemon. */
+  the_network_is_not_the_computer (gtk_window);
+
+  /* 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 ();
+  exit (0);
+}
+
+#endif /* HAVE_GTK -- whole file */
index 2e38746073c27cdc53891a54be3039c8d193f5a8..bec72e0e8a4bf52185bc086063712cff504ae1e8 100644 (file)
 
 #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
 
 
@@ -64,6 +51,8 @@
 
 #include <stdio.h>
 
+#include <X11/Xproto.h>                /* for CARD32 */
+#include <X11/Xatom.h>         /* for XA_INTEGER */
 #include <X11/Intrinsic.h>
 #include <X11/StringDefs.h>
 
 # include <X11/Xaw/Scrollbar.h>
 # include <X11/Xaw/Text.h>
 
-#elif defined(HAVE_GTK)
-# include <gtk/gtk.h>
-extern Display *gdk_display;
 #endif /* HAVE_ATHENA */
 
 #include "version.h"
@@ -122,14 +108,8 @@ extern Display *gdk_display;
 #include <string.h>
 #include <ctype.h>
 
-#ifdef HAVE_GTK
-# define WIDGET GtkWidget *
-# define POINTER gpointer
-#else
-# define WIDGET Widget
-# define POINTER XtPointer
-#endif
-
+#define WIDGET Widget
+#define POINTER XtPointer
 
 
 char *progname = 0;
@@ -153,7 +133,8 @@ 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;
+Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO;
+Atom XA_BLANK, XA_LOCK, XA_RESTART, XA_EXIT;
 
 extern void create_demo_dialog (Widget, Visual *, Colormap);
 extern void create_preferences_dialog (Widget, Visual *, Colormap);
@@ -222,29 +203,7 @@ extern WIDGET lock_toggle;
 # 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 */
+#endif /* HAVE_ATHENA */
 
 
 
@@ -264,9 +223,7 @@ get_text_string (WIDGET text_widget)
     string = 0;
 
   return string;
-#elif defined(HAVE_GTK)
-  return gtk_entry_get_text (GTK_ENTRY (text_widget));
-#endif /* HAVE_GTK */
+#endif /* HAVE_ATHENA */
 }
 
 
@@ -285,11 +242,7 @@ get_label_string (WIDGET label_widget)
   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 */
+#endif /* HAVE_ATHENA */
 }
 
 
@@ -302,9 +255,7 @@ set_label_string (WIDGET label_widget, char *string)
   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 */
+#endif /* HAVE_ATHENA */
 }
 
 
@@ -324,10 +275,7 @@ format_into_label (WIDGET label, const char *arg)
 
     set_label_string (label, buf);
     free (buf);
-
-# ifndef HAVE_GTK
     XtFree (text);
-# endif /* HAVE_GTK */
 }
 
 
@@ -410,68 +358,33 @@ ensure_selected_item_visible (WIDGET list)
       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;
+#endif /* HAVE_ATHENA */
+}
 
-  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))
+#ifdef HAVE_ATHENA
+static void
+set_hack_list (Widget demo_list, saver_preferences *p)
+{
+  char **strings = (char **) calloc (sizeof (char *), p->screenhacks_count);
+  int i;
+  for (i = 0; i < p->screenhacks_count; i++)
+    strings[i] = format_hack (p->screenhacks[i], False);
+  XtVaSetValues (demo_list,
+                 XtNlist, strings,
+                 XtNnumberStrings, p->screenhacks_count,
+                 0);
+# if 0
+  for (i = 0; i < p->screenhacks_count; i++)
     {
-      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);
+      free (strings[i]);
+      strings[i] = (char *) 0xDEADBEEF;
     }
-
-
-#endif /* HAVE_GTK */
+  free (strings);
+# endif
 }
+#endif /* HAVE_ATHENA */
+
 
 
 /* Callback for the text area:
@@ -479,15 +392,9 @@ ensure_selected_item_visible (WIDGET list)
    - 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);
@@ -506,33 +413,21 @@ text_cb (WIDGET text_widget, POINTER client_data, POINTER call_data)
     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 */
+#endif /* HAVE_ATHENA */
 
   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
     {
+      screenhack *new_hack = parse_screenhack (new_text);
       if (p->screenhacks [hack_number])
-       free (p->screenhacks [hack_number]);
-      p->screenhacks [hack_number] = strdup (new_text);
+       free_screenhack (p->screenhacks [hack_number]);
+      p->screenhacks [hack_number] = new_hack;
 
 #ifdef HAVE_MOTIF
 
@@ -554,34 +449,16 @@ text_cb (WIDGET text_widget, POINTER client_data, POINTER call_data)
        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);
+        set_hack_list (demo_list, p);
        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 */
+#endif /* HAVE_ATHENA */
 
       if (save)
         write_init_file (p, short_version);
@@ -612,49 +489,6 @@ static char translations[] = ("<Key>Return:        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
@@ -703,9 +537,7 @@ next_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored)
   if (pos_list)
     XtFree ((char *) pos_list);
 
-#elif defined(HAVE_GTK)
-  next_internal (GTK_ENTRY (text_line), TRUE);
-#endif /* HAVE_GTK */
+#endif /* HAVE_MOTIF */
 }
 
 
@@ -757,22 +589,14 @@ prev_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored)
   if (pos_list)
     XtFree ((char *) pos_list);
 
-#elif defined(HAVE_GTK)
-  next_internal (GTK_ENTRY (text_line), FALSE);
-#endif /* HAVE_GTK */
+#endif /* HAVE_MOTIF */
 }
 
 
 /* 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; */
 
@@ -794,21 +618,7 @@ select_cb (WIDGET button, POINTER client_data, POINTER call_data)
   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 */
+#endif /* HAVE_MOTIF */
 }
 
 
@@ -821,15 +631,11 @@ 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);
@@ -859,6 +665,48 @@ restart_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored)
 }
 
 
+/* Finds the number of the last hack to run, and makes that item be
+   selected by default.
+ */
+static void
+scroll_to_current_hack (WIDGET dialog)
+{
+  Atom type;
+  int format;
+  unsigned long nitems, bytesafter;
+  CARD32 *data = 0;
+  Display *dpy = widget_display (dialog);
+  int hack = 0;
+
+  if (XGetWindowProperty (dpy, RootWindow (dpy, 0), /* always screen #0 */
+                          XA_SCREENSAVER_STATUS,
+                          0, 3, False, XA_INTEGER,
+                          &type, &format, &nitems, &bytesafter,
+                          (unsigned char **) &data)
+      == Success
+      && type == XA_INTEGER
+      && nitems >= 3
+      && data)
+    hack = (int) data[2];
+
+  if (data) free (data);
+
+  if (hack <= 0)
+    return;
+
+#ifdef HAVE_MOTIF
+  XmListDeselectAllItems (demo_list);  /* LessTif lossage */
+  XmListSelectPos (demo_list, hack, False);
+  ensure_selected_item_visible (demo_list);
+
+#elif defined(HAVE_ATHENA)
+  XawListUnhighlight (demo_list);
+  XawListHighlight (demo_list, hack - 1);
+
+#endif /* HAVE_ATHENA */
+}
+
+
 static void
 pop_up_dialog_box (WIDGET dialog, WIDGET form)
 {
@@ -868,36 +716,23 @@ pop_up_dialog_box (WIDGET dialog, WIDGET form)
 #elif defined(HAVE_MOTIF)
   XtRealizeWidget (form);
   XtManageChild (form);
+
+  /* Motif likes to make the dialog wider than the screen; throttle it. */
+  {
+    Dimension w=0, h=0, bw=0;
+    Dimension max_w;
+    Screen *screen = 0;
+    XtVaGetValues (dialog, XtNscreen, &screen, 0);
+    max_w = WidthOfScreen (screen) * 0.8;
+    XtVaGetValues(dialog, XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0);
+    if (w > max_w)
+      XtResizeWidget(dialog, max_w, h, bw);
+  }
 #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)
@@ -905,20 +740,14 @@ 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;
+#ifdef HAVE_MOTIF
+  screenhack **hacks = p->screenhacks;
+#endif /* HAVE_MOTIF */
 
   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);
@@ -937,9 +766,11 @@ make_demo_dialog (Widget toplevel_shell, prefs_pair *pair)
   if (hacks)
     for (; *hacks; hacks++)
       {
-       XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
+        char *hs = format_hack (*hacks, False);
+       XmString xmstr = XmStringCreate (hs, XmSTRING_DEFAULT_CHARSET);
        XmListAddItem (demo_list, xmstr, 0);
        XmStringFree (xmstr);
+        free (hs);
       }
 
 #elif defined(HAVE_ATHENA)
@@ -956,10 +787,7 @@ make_demo_dialog (Widget toplevel_shell, prefs_pair *pair)
   */
   XtRealizeWidget (demo_dialog);
 
-  XtVaSetValues (demo_list,
-                XtNlist, hacks,
-                XtNnumberStrings, p->screenhacks_count,
-                0);
+  set_hack_list (demo_list, p);
   XtAddCallback (demo_list, XtNcallback, select_cb, p);
 
   /* Now that we've populated the list, make sure that the list is as
@@ -1003,34 +831,14 @@ make_demo_dialog (Widget toplevel_shell, prefs_pair *pair)
 
   }
 
-#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 */
+#endif /* HAVE_ATHENA */
+
+  scroll_to_current_hack (demo_dialog);
 
   pop_up_dialog_box(demo_dialog, demo_form);
 
-#ifdef HAVE_ATHENA
-  /* For Athena, have to do this after the dialog is managed. */
+#if defined(HAVE_ATHENA)
+  /* For Athena and Gtk, have to do this after the dialog is managed. */
   ensure_selected_item_visible (demo_list);
 #endif /* HAVE_ATHENA */
 }
@@ -1093,11 +901,7 @@ prefs_int_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored)
   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;
 }
@@ -1115,9 +919,7 @@ prefs_bool_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data)
   Boolean state = FALSE;
   XtVaGetValues (button, XtNstate, &state, 0);
   *store = state;
-#elif defined(HAVE_GTK)
-  *store = GTK_TOGGLE_BUTTON (button)->active;
-#endif /* HAVE_GTK */
+#endif /* HAVE_ATHENA */
 }
 
 
@@ -1126,16 +928,9 @@ prefs_bool_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data)
 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 */
 }
 
 
@@ -1159,15 +954,7 @@ prefs_ok_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data)
   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 */
+#endif /* HAVE_ATHENA */
 
   p->timeout       = p2->timeout;
   p->cycle         = p2->cycle;
@@ -1185,15 +972,6 @@ prefs_ok_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data)
 }
 
 
-#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)
 {
@@ -1209,14 +987,6 @@ make_preferences_dialog (prefs_pair *pair, Widget 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);
 
@@ -1329,11 +1099,7 @@ 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 */
 }
 
 
@@ -1382,10 +1148,7 @@ warning_dialog (WIDGET parent, const char *message)
   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 */
+#endif /* HAVE_ATHENA */
 
   head = msg;
   while (head)
@@ -1414,20 +1177,7 @@ warning_dialog (WIDGET parent, const char *message)
                                       (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 */
+#endif /* HAVE_ATHENA */
 
       if (s)
        head = s+1;
@@ -1451,36 +1201,7 @@ warning_dialog (WIDGET parent, const char *message)
 
   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 */
+#endif /* HAVE_ATHENA */
 
   add_button_callback (ok, warning_dialog_dismiss_cb, (POINTER) dialog);
 
@@ -1642,40 +1363,6 @@ demo_ehandler (Display *dpy, XErrorEvent *error)
 }
 
 
-#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
@@ -1707,30 +1394,6 @@ main (int argc, char **argv)
 
   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,
@@ -1740,24 +1403,8 @@ main (int argc, char **argv)
   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);
@@ -1819,11 +1466,14 @@ main (int argc, char **argv)
   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_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", 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_BLANK = XInternAtom (dpy, "BLANK", False);
+  XA_LOCK = XInternAtom (dpy, "LOCK", False);
+  XA_EXIT = XInternAtom (dpy, "EXIT", False);
   XA_RESTART = XInternAtom (dpy, "RESTART", False);
 
   make_demo_dialog (toplevel_shell, pair);
@@ -1838,22 +1488,7 @@ main (int argc, char **argv)
                                   ? 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
deleted file mode 100644 (file)
index 2d16dc9..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/* dialogs-Gtk.c --- Gtk widgets for demo, options, and password dialogs.
- * xscreensaver, Copyright (c) 1999 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation.  No representations are made about the suitability of this
- * software for any purpose.  It is provided "as is" without express or 
- * implied warranty.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <X11/Xlib.h>
-#include <gtk/gtk.h>
-#include "resources.h"
-
-#include <stdio.h>
-
-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;
-}
index 26441f071261c8fb522fb45ee0a698e2bb3d6fb3..194752d1cf5e4404882a4b95ef725dc0b6a8f4f1 100644 (file)
 # include "config.h"
 #endif
 
-#ifndef NO_LOCKING   /* whole file */
-
 #include <X11/Intrinsic.h>
 #include <X11/Xos.h>           /* for time() */
 #include "xscreensaver.h"
 #include "resources.h"
 
+#ifndef NO_LOCKING              /* (mostly) whole file */
+
 #ifdef HAVE_SYSLOG
 # include <syslog.h>
 #endif /* HAVE_SYSLOG */
@@ -1234,6 +1234,8 @@ set_locked_p (saver_info *si, Bool locked_p)
 #ifdef HAVE_XF86VMODE
   xfree_lock_mode_switch (si, locked_p);        /* turn off/on C-Alt-Plus */
 #endif
+
+  store_saver_status (si);                     /* store locked-p */
 }
 
 
index 747db1e58e85c4107755ebdede87c3e3c37e985f..2b8be46d05b5a3a6b8dff8c7315beda2d2b08157 100644 (file)
@@ -73,6 +73,7 @@ extern const char *blurb (void);
 
 
 static void get_screenhacks (saver_preferences *p);
+static char *format_command (const char *cmd, Bool wrap_p);
 
 
 static char *
@@ -410,6 +411,44 @@ tab_to (FILE *out, int from, int to)
   return from;
 }
 
+static char *
+stab_to (char *out, int from, int to)
+{
+  int tab_width = 8;
+  int to_mod = (to / tab_width) * tab_width;
+  while (from < to_mod)
+    {
+      *out++ = '\t';
+      from = (((from / tab_width) + 1) * tab_width);
+    }
+  while (from < to)
+    {
+      *out++ = ' ';
+      from++;
+    }
+  return out;
+}
+
+static int
+string_columns (const char *string, int length, int start)
+{
+  int tab_width = 8;
+  int col = start;
+  const char *end = string + length;
+  while (string < end)
+    {
+      if (*string == '\n')
+        col = 0;
+      else if (*string == '\t')
+        col = (((col / tab_width) + 1) * tab_width);
+      else
+        col++;
+      string++;
+    }
+  return col;
+}
+
+
 static void
 write_entry (FILE *out, const char *key, const char *value)
 {
@@ -417,10 +456,8 @@ write_entry (FILE *out, const char *key, const char *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 programs_p = (!strcmp(key, "programs"));
+  int tab = (programs_p ? 32 : 16);
   Bool first = True;
 
   fprintf(out, "%s:", key);
@@ -428,49 +465,35 @@ write_entry (FILE *out, const char *key, const char *value)
 
   while (1)
     {
-      char *s;
-      Bool disabled_p = False;
-
-      v2 = strip(v2);
+      if (!programs_p)
+        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 && programs_p)
+        {
+         col = tab_to (out, col, 77);
+         fprintf (out, " \\\n");
+         col = 0;
+        }
 
       if (first)
        first = False;
       else
        {
-         col = tab_to(out, col, 75);
-         fprintf(out, " \\n\\\n");
+         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 (!programs_p)
+        col = tab_to (out, col, tab);
 
-      if (do_wrap &&
-         strlen(v2) + col > 75)
+      if (programs_p &&
+         string_columns(v2, strlen (v2), col) + col > 75)
        {
-         int L = strlen(v2);
+         int L = strlen (v2);
          int start = 0;
          int end = start;
          while (start < L)
@@ -480,7 +503,7 @@ write_entry (FILE *out, const char *key, const char *value)
              while (v2[end] != ' ' && v2[end] != '\t' &&
                     v2[end] != '\n' && v2[end] != 0)
                end++;
-             if (col + (end - start) >= 74)
+             if (string_columns (v2 + start, (end - start), col) >= 74)
                {
                  col = tab_to (out, col, 75);
                  fprintf(out, "   \\\n");
@@ -489,17 +512,15 @@ write_entry (FILE *out, const char *key, const char *value)
                    start++;
                }
 
+              col = string_columns (v2 + start, (end - start), col);
              while (start < end)
-               {
-                 fputc(v2[start++], out);
-                 col++;
-               }
+                fputc(v2[start++], out);
            }
        }
       else
        {
          fprintf (out, "%s", v2);
-         col += strlen(v2);
+         col += string_columns(v2, strlen (v2), col);
        }
 
       if (nl)
@@ -576,14 +597,24 @@ write_init_file (saver_preferences *p, const char *version_string)
   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);
+    char *ss;
+    char **hack_strings = (char **)
+      calloc (p->screenhacks_count, sizeof(char *));
+
+    for (j = 0; j < p->screenhacks_count; j++)
+      {
+        hack_strings[j] = format_hack (p->screenhacks[j], True);
+        i += strlen (hack_strings[j]);
+        i += 2;
+      }
+
+    ss = programs = (char *) malloc(i + 10);
     *ss = 0;
     for (j = 0; j < p->screenhacks_count; j++)
       {
-       strcat(ss, p->screenhacks[j]);
+        strcat (ss, hack_strings[j]);
+        free (hack_strings[j]);
        ss += strlen(ss);
        *ss++ = '\n';
        *ss = 0;
@@ -858,52 +889,73 @@ load_init_file (saver_preferences *p)
 /* Parsing the programs resource.
  */
 
-static char *
-reformat_hack (const char *hack)
+screenhack *
+parse_screenhack (const char *line)
 {
-  int i;
-  const char *in = hack;
-  int indent = 15;
-  char *h2 = (char *) malloc(strlen(in) + indent + 2);
-  char *out = h2;
-  Bool disabled_p = False;
+  screenhack *h = (screenhack *) calloc (1, sizeof(*h));
+  const char *s;
 
-  while (isspace(*in)) in++;           /* skip whitespace */
+  h->enabled_p = True;
 
-  if (*in == '-')                      /* Handle a leading "-". */
+  while (isspace(*line)) line++;               /* skip whitespace */
+  if (*line == '-')                            /* handle "-" */
     {
-      in++;
-      hack = in;
-      *out++ = '-';
-      *out++ = ' ';
-      disabled_p = True;
-      while (isspace(*in)) in++;
+      h->enabled_p = False;
+      line++;
+      while (isspace(*line)) line++;           /* skip whitespace */
     }
+
+  s = line;                                    /* handle "visual:" */
+  while (*line && *line != ':' && *line != '"' && !isspace(*line))
+    line++;
+  if (*line != ':')
+    line = s;
   else
     {
-      *out++ = ' ';
-      *out++ = ' ';
+      h->visual = (char *) malloc (line-s+1);
+      strncpy (h->visual, s, line-s);
+      h->visual[line-s] = 0;
+      if (*line == ':') line++;                        /* skip ":" */
+      while (isspace(*line)) line++;           /* skip whitespace */
     }
 
-  while (*in && !isspace(*in) && *in != ':')
-    *out++ = *in++;                    /* snarf first token */
-  while (isspace(*in)) in++;           /* skip whitespace */
-
-  if (*in == ':')
-    *out++ = *in++;                    /* copy colon */
-  else
+  if (*line == '"')                            /* handle "name" */
     {
-      in = hack;
-      out = h2 + 2;                    /* reset to beginning */
+      line++;
+      s = line;
+      while (*line && *line != '"')
+        line++;
+      h->name = (char *) malloc (line-s+1);
+      strncpy (h->name, s, line-s);
+      h->name[line-s] = 0;
+      if (*line == '"') line++;                        /* skip "\"" */
+      while (isspace(*line)) line++;           /* skip whitespace */
     }
 
-  *out = 0;
+  h->command = format_command (line, False);   /* handle command */
+  return h;
+}
+
 
-  while (isspace(*in)) in++;           /* skip whitespace */
-  for (i = strlen(h2); i < indent; i++)        /* indent */
-    *out++ = ' ';
+void
+free_screenhack (screenhack *hack)
+{
+  if (hack->visual) free (hack->visual);
+  if (hack->name) free (hack->name);
+  free (hack->command);
+  memset (hack, 0, sizeof(*hack));
+  free (hack);
+}
 
-  /* copy the rest of the line. */
+
+static char *
+format_command (const char *cmd, Bool wrap_p)
+{
+  int tab = 30;
+  int col = tab;
+  char *cmd2 = (char *) calloc (1, 2 * (strlen (cmd) + 1));
+  const char *in = cmd;
+  char *out = cmd2;
   while (*in)
     {
       /* shrink all whitespace to one space, for the benefit of the "demo"
@@ -913,30 +965,98 @@ reformat_hack (const char *hack)
       switch (*in)
        {
        case '\'': case '"': case '`': case '\\':
-         {
-           /* Metachars are scary.  Copy the rest of the line unchanged. */
-           while (*in)
-             *out++ = *in++;
-         }
+          /* Metachars are scary.  Copy the rest of the line unchanged. */
+          while (*in)
+            *out++ = *in++, col++;
          break;
+
        case ' ': case '\t':
-         {
-           while (*in == ' ' || *in == '\t')
-             in++;
-           *out++ = ' ';
-         }
+          /* Squeeze all other whitespace down to one space. */
+          while (*in == ' ' || *in == '\t')
+            in++;
+          *out++ = ' ', col++;
          break;
+
        default:
-         *out++ = *in++;
+          /* Copy other chars unchanged. */
+         *out++ = *in++, col++;
          break;
        }
     }
+
   *out = 0;
 
-  /* strip trailing whitespace. */
-  out = out-1;
-  while (out > h2 && (*out == ' ' || *out == '\t' || *out == '\n'))
-    *out-- = 0;
+  /* Strip trailing whitespace */
+  while (out > cmd2 && isspace (out[-1]))
+    *(--out) = 0;
+
+  return cmd2;
+}
+
+
+char *
+format_hack (screenhack *hack, Bool wrap_p)
+{
+  int tab = 32;
+  int size = (2 * (strlen(hack->command) +
+                   (hack->visual ? strlen(hack->visual) : 0) +
+                   (hack->name ? strlen(hack->name) : 0) +
+                   tab));
+  char *h2 = (char *) malloc (size);
+  char *out = h2;
+  char *s;
+  int col = 0;
+
+  if (!hack->enabled_p) *out++ = '-';          /* write disabled flag */
+
+  if (hack->visual && *hack->visual)           /* write visual name */
+    {
+      if (hack->enabled_p) *out++ = ' ';
+      *out++ = ' ';
+      strcpy (out, hack->visual);
+      out += strlen (hack->visual);
+      *out++ = ':';
+      *out++ = ' ';
+    }
+
+  *out = 0;
+  col = string_columns (h2, strlen (h2), 0);
+
+  if (hack->name && *hack->name)               /* write pretty name */
+    {
+      int L = (strlen (hack->name) + 2);
+      if (L + col < tab)
+        out = stab_to (out, col, tab - L - 2);
+      else
+        *out++ = ' ';
+      *out++ = '"';
+      strcpy (out, hack->name);
+      out += strlen (hack->name);
+      *out++ = '"';
+      *out = 0;
+
+      col = string_columns (h2, strlen (h2), 0);
+      if (wrap_p && col >= tab)
+        {
+          out = stab_to (out, col, 77);
+          *out += strlen(out);
+        }
+      else
+        *out++ = ' ';
+
+      if (out >= h2+size) abort();
+    }
+
+  *out = 0;
+  col = string_columns (h2, strlen (h2), 0);
+  out = stab_to (out, col, tab);               /* indent */
+
+  if (out >= h2+size) abort();
+  s = format_command (hack->command, wrap_p);
+  strcpy (out, s);
+  out += strlen (s);
+  free (s);
+  *out = 0;
 
   return h2;
 }
@@ -971,7 +1091,7 @@ get_screenhacks (saver_preferences *p)
     {
       for (i = 0; i < p->screenhacks_count; i++)
        if (p->screenhacks[i])
-         free (p->screenhacks[i]);
+         free_screenhack (p->screenhacks[i]);
       free(p->screenhacks);
       p->screenhacks = 0;
     }
@@ -995,7 +1115,7 @@ get_screenhacks (saver_preferences *p)
       i++;
   i++;
 
-  p->screenhacks = (char **) calloc (sizeof (char *), i+1);
+  p->screenhacks = (screenhack **) calloc (sizeof (screenhack *), i+1);
 
   /* Iterate over the lines in `d' (the string with newlines)
      and make new strings to stuff into the `screenhacks' array.
@@ -1015,7 +1135,7 @@ get_screenhacks (saver_preferences *p)
       /* null terminate. */
       d[end] = 0;
 
-      p->screenhacks[p->screenhacks_count++] = reformat_hack (d + start);
+      p->screenhacks[p->screenhacks_count++] = parse_screenhack (d + start);
       if (p->screenhacks_count >= i)
        abort();
 
index 62c768d9bd4ad14ed3f66d2ce76407c2424837b8..b5a528c9aa7108d7c478858c35c5f6e1c75057a1 100644 (file)
 #ifndef __XSCREENSAVER_PREFS_H__
 #define __XSCREENSAVER_PREFS_H__
 
+typedef struct screenhack screenhack;
+struct screenhack {
+  Bool enabled_p;
+  char *visual;
+  char *name;
+  char *command;
+};
+
 typedef struct saver_preferences saver_preferences;
 
 
@@ -38,13 +46,13 @@ struct saver_preferences {
 
   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 */
+  Time 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 */
+  screenhack **screenhacks;    /* the programs to run */
   int screenhacks_count;
 
   int nice_inferior;           /* nice value for subprocs */
@@ -78,4 +86,8 @@ 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);
 
+extern screenhack *parse_screenhack (const char *line);
+extern void free_screenhack (screenhack *hack);
+extern char *format_hack (screenhack *hack, Bool wrap_p);
+
 #endif /* __XSCREENSAVER_PREFS_H__ */
index 26c855584f81d7f70e7893f53b84025f8adc8d22..e05c93e4d0ad478455d866d189dc79765e1449b8 100644 (file)
@@ -41,8 +41,8 @@ ERROR! you must not include vroot.h in this file
 
 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;
+extern Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_EXIT;
+extern Atom XA_VROOT, XA_SELECT, XA_DEMO, XA_BLANK, XA_LOCK;
 
 
 static XErrorHandler old_handler = 0;
@@ -99,6 +99,7 @@ find_screensaver_window (Display *dpy, char **version)
        */
       XSync (dpy, False);
       if (old_handler) abort();
+      got_badwindow = False;
       old_handler = XSetErrorHandler (BadWindow_ehandler);
       status = XGetWindowProperty (dpy, kids[i],
                                    XA_SCREENSAVER_VERSION,
@@ -110,7 +111,10 @@ find_screensaver_window (Display *dpy, char **version)
       old_handler = 0;
 
       if (got_badwindow)
-        status = BadWindow;
+        {
+          status = BadWindow;
+          got_badwindow = False;
+        }
 
       if (status == Success && type != None)
        {
@@ -119,8 +123,6 @@ find_screensaver_window (Display *dpy, char **version)
          return kids[i];
        }
     }
-  fprintf (stderr, "%s: no screensaver is running on display %s\n", progname,
-          DisplayString (dpy));
   return 0;
 }
 
@@ -137,13 +139,21 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg,
     *window_ret = window;
 
   if (!window)
-    return -1;
+    {
+      if (command == XA_EXIT)
+        return 1;
+
+      /* Don't print this if xscreensaver is already dead. */
+      fprintf (stderr, "%s: no screensaver is running on display %s\n",
+               progname, DisplayString (dpy));
+      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 ||
+  if (command == XA_SCREENSAVER_STATUS ||
       command == XA_SCREENSAVER_VERSION)
     {
       XClassHint hint;
@@ -165,7 +175,7 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg,
 
       fprintf (stdout, "%s %s", hint.res_class, v);
 
-      if (command != XA_SCREENSAVER_TIME)
+      if (command != XA_SCREENSAVER_STATUS)
        {
          fprintf (stdout, "\n");
        }
@@ -174,38 +184,83 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg,
          Atom type;
          int format;
          unsigned long nitems, bytesafter;
-         unsigned char *data = 0;
-         Bool active_p = False;
+         CARD32 *data = 0;
 
-         if (XGetWindowProperty (dpy, window, XA_VROOT,
-                                 0, 0, False, XA_WINDOW,
+         if (XGetWindowProperty (dpy,
+                                  RootWindow (dpy, 0),
+                                 XA_SCREENSAVER_STATUS,
+                                 0, 999, False, XA_INTEGER,
                                  &type, &format, &nitems, &bytesafter,
-                                 &data)
+                                 (unsigned char **) &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
+             && type
              && data)
            {
-             CARD32 time32 = *((CARD32 *)data);
-             time_t tt = (time_t) time32;
-
-             if (active_p)
-               fprintf (stdout, ": screen blanked since ");
-             else
+              Atom blanked;
+              time_t tt;
+              char *s;
+
+              if (type != XA_INTEGER || nitems < 3)
+                {
+                STATUS_LOSE:
+                  if (data) free (data);
+                  fprintf (stdout, "\n");
+                  fflush (stdout);
+                  fprintf (stderr, "%s: bad status format on root window.\n",
+                           progname);
+                  return -1;
+                }
+                  
+              blanked = (Atom) data[0];
+              tt = (time_t) data[1];
+
+              if (tt <= (time_t) 666000000L) /* early 1991 */
+                goto STATUS_LOSE;
+
+             if (blanked == XA_BLANK)
+               fputs (": screen blanked since ", stdout);
+             else if (blanked == XA_LOCK)
+               fputs (": screen locked since ", stdout);
+             else if (blanked == 0)
                /* suggestions for a better way to phrase this are welcome. */
-               fprintf (stdout, ": screen non-blanked since ");
-             fprintf (stdout, "%s", ctime(&tt));
+               fputs (": screen non-blanked since ", stdout);
+              else
+                /* `blanked' has an unknown value - fail. */
+                goto STATUS_LOSE;
+
+              s = ctime(&tt);
+              if (s[strlen(s)-1] == '\n')
+                s[strlen(s)-1] = 0;
+              fputs (s, stdout);
+
+              {
+                int nhacks = nitems - 2;
+                Bool any = False;
+                int i;
+                for (i = 0; i < nhacks; i++)
+                  if (data[i + 2] > 0)
+                    {
+                      any = True;
+                      break;
+                    }
+
+                if (any && nhacks == 1)
+                  fprintf (stdout, " (hack #%d)\n", data[2]);
+                else if (any)
+                  {
+                    fprintf (stdout, " (hacks: ");
+                    for (i = 0; i < nhacks; i++)
+                      {
+                        fprintf (stdout, "#%d", data[2 + i]);
+                        if (i != nhacks-1)
+                          fputs (", ", stdout);
+                      }
+                    fputs (")\n", stdout);
+                  }
+                else
+                  fputs ("\n", stdout);
+              }
+
              if (data) free (data);
            }
          else
@@ -213,9 +268,8 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg,
              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 : "???"));
+             fprintf (stderr, "%s: no saver status on root window.\n",
+                      progname);
              return -1;
            }
        }
@@ -261,7 +315,8 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg,
 
 
 static int
-xscreensaver_command_response (Display *dpy, Window window, Bool verbose_p)
+xscreensaver_command_response (Display *dpy, Window window,
+                               Bool verbose_p, Bool exiting_p)
 {
   int fd = ConnectionNumber (dpy);
   int timeout = 10;
@@ -318,10 +373,13 @@ xscreensaver_command_response (Display *dpy, Window window, Bool verbose_p)
 
              if (got_badwindow)
                {
-                 fprintf (stdout,
-                          "%s: xscreensaver window has been deleted.\n",
+                  if (exiting_p)
+                    return 0;
+
+                  fprintf (stderr,
+                          "%s: xscreensaver window unexpectedly deleted.\n",
                           progname);
-                 return 0;
+                 return -1;
                }
 
              if (st2 == Success && type != None)
@@ -366,10 +424,12 @@ 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);
+    status = xscreensaver_command_response (dpy, w, verbose_p,
+                                            (command == XA_EXIT));
+
   fflush (stdout);
   fflush (stderr);
-  return status;
+  return (status < 0 ? status : 0);
 }
 
 
index fcfdf897f7803bbea2ab9c0732dbb5146ef26a8b..c693d5b68a6cb6b0180d15dbd848bd3c469569b3 100644 (file)
@@ -765,46 +765,25 @@ init_sigchld (void)
 \f
 
 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)
+select_visual_of_hack (saver_screen_info *ssi, screenhack *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);
+  if (hack->visual && *hack->visual == ':')
+    selected = select_visual(ssi, hack->visual);
   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);
-    }
+    fprintf (stderr,
+             (si->demoing_p
+              ? "%s: warning, no \"%s\" visual for \"%s\".\n"
+              : "%s: no \"%s\" visual; skipping \"%s\".\n"),
+             blurb(),
+             (hack->visual && *hack->visual ? hack->visual : "???"),
+             hack->command);
 
   return selected;
 }
@@ -820,7 +799,7 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p)
 
   if (p->screenhacks_count)
     {
-      char *hack;
+      screenhack *hack;
       pid_t forked;
       char buf [255];
       int new_hack;
@@ -868,7 +847,7 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p)
         select_visual_of_hack (ssi, hack);
         
       if (!force &&
-         (!hack_enabled_p (hack) ||
+         (!hack->enabled_p ||
           !select_visual_of_hack (ssi, hack)))
        {
          if (++retry_count > (p->screenhacks_count*4))
@@ -894,25 +873,6 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p)
       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:
@@ -925,13 +885,13 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p)
          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 */
+         exec_screenhack (si, hack->command);  /* this does not return */
          abort();
          break;
 
        default:
          ssi->pid = forked;
-         (void) make_job (forked, hack);
+         (void) make_job (forked, hack->command);
          break;
        }
     }
@@ -941,22 +901,21 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p)
 void
 spawn_screenhack (saver_info *si, Bool first_time_p)
 {
-  int i;
-
-  if (!monitor_powered_on_p (si))
+  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;
+      int i;
+      for (i = 0; i < si->nscreens; i++)
+        {
+          saver_screen_info *ssi = &si->screens[i];
+          spawn_screenhack_1 (ssi, first_time_p);
+        }
     }
+  else if (si->prefs.verbose_p)
+    fprintf (stderr,
+             "%s: server reports that monitor has powered down; "
+             "not launching a new hack.\n", blurb());
 
-  for (i = 0; i < si->nscreens; i++)
-    {
-      saver_screen_info *ssi = &si->screens[i];
-      spawn_screenhack_1 (ssi, first_time_p);
-    }
+  store_saver_status (si);  /* store current hack numbers */
 }
 
 
index 5ffc63ed0641efeab11818b6a5697bdb29899b4a..61a0155d097f26d2d73d1224d877ae2d1acc9e4b 100644 (file)
@@ -348,6 +348,16 @@ check_pointer_timer (XtPointer closure, XtIntervalId *id)
        else
          fprintf (stderr, "%s: pointer moved at %s on screen %d.\n",
                   blurb(), timestring(), i);
+
+# if 0
+      fprintf (stderr, "%s: old: %d %d 0x%x ; new: %d %d 0x%x\n",
+               blurb(), 
+               ssi->poll_mouse_last_root_x,
+               ssi->poll_mouse_last_root_y,
+               (unsigned int) ssi->poll_mouse_last_child,
+               root_x, root_y, (unsigned int) child);
+# endif /* 0 */
+
 #endif /* DEBUG_TIMERS */
 
       si->last_activity_screen    = ssi;
@@ -456,7 +466,7 @@ swallow_unlock_typeahead_events (saver_info *si, XEvent *e)
       if (event.xany.type == KeyPress)
         {
           char s[2];
-          int size = XLookupString (&event, s, 1, 0, 0);
+          int size = XLookupString ((XKeyEvent *) &event, s, 1, 0, 0);
           if (size != 1) continue;
           switch (*s)
             {
index 205e43bdfe3d6df570542e58c35aa38beee5303a..21eb6a39aac25a71b15d7aed591f5fdc2d2c78fd 100644 (file)
@@ -63,14 +63,12 @@ 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;
+Atom XA_SCREENSAVER_STATUS;
 
 
 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 | \
@@ -654,10 +652,13 @@ saver_exit (saver_info *si, int status, const char *dump_core_reason)
   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());
+  if (p->verbose_p)    /* nobody cares about this */
+    {
+      if (vrs)
+        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);
 
@@ -731,7 +732,7 @@ store_saver_id (saver_screen_info *ssi)
   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;
@@ -786,6 +787,35 @@ store_saver_id (saver_screen_info *ssi)
 }
 
 
+void
+store_saver_status (saver_info *si)
+{
+  CARD32 *status;
+  int size = si->nscreens + 2;
+  int i;
+
+  status = (CARD32 *) calloc (size, sizeof(CARD32));
+
+  status[0] = (CARD32) (si->screen_blanked_p
+                        ? (si->locked_p ? XA_LOCK : XA_BLANK)
+                        : 0);
+  status[1] = (CARD32) si->blank_time;
+
+  for (i = 0; i < si->nscreens; i++)
+    {
+      saver_screen_info *ssi = &si->screens[i];
+      status [2 + i] = ssi->current_hack + 1;
+    }
+
+  XChangeProperty (si->dpy,
+                   RootWindow (si->dpy, 0),  /* always screen #0 */
+                   XA_SCREENSAVER_STATUS,
+                   XA_INTEGER, 32, PropModeReplace,
+                   (unsigned char *) status, size);
+}
+
+
+
 /* 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
@@ -1090,14 +1120,12 @@ initialize_screensaver_window_1 (saver_screen_info *ssi)
                       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);
+  store_saver_id (ssi);       /* store window name and IDs */
 
   if (!ssi->cursor)
     {
@@ -1282,15 +1310,19 @@ blank_screen (saver_info *si)
       }
 #endif /* HAVE_XF86VMODE */
     }
-  store_activate_time (si, si->screen_blanked_p);
+
   raise_window (si, False, False, False);
 
   si->screen_blanked_p = True;
+  si->blank_time = time ((time_t) 0);
   si->last_wall_clock_time = 0;
 
+  store_saver_status (si);  /* store blank time */
+
   return True;
 }
 
+
 void
 unblank_screen (saver_info *si)
 {
@@ -1299,8 +1331,6 @@ unblank_screen (saver_info *si)
   int i;
 
   monitor_power_on (si);
-
-  store_activate_time (si, True);
   reset_watchdog_timer (si, False);
 
   if (si->demoing_p)
@@ -1394,8 +1424,7 @@ unblank_screen (saver_info *si)
       kill_xsetroot_data (si->dpy, ssi->screensaver_window, p->verbose_p);
     }
 
-  store_activate_time(si, False);  /* store unblank time */
-
+  store_saver_status (si);  /* store unblank time */
   ungrab_keyboard_and_mouse (si);
   restore_real_vroot (si);
 
@@ -1407,27 +1436,10 @@ unblank_screen (saver_info *si)
     XUnmapWindow (si->dpy, si->screens[i].screensaver_window);
 
   si->screen_blanked_p = False;
+  si->blank_time = time ((time_t) 0);
   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);
-    }
+  store_saver_status (si);  /* store unblank time */
 }
 
 
@@ -1443,18 +1455,24 @@ select_visual (saver_screen_info *ssi, const char *visual_name)
 
   if (visual_name && *visual_name)
     {
-      if (!strcmp(visual_name, "default-i"))
+      if (!strcmp(visual_name, "default-i") ||
+          !strcmp(visual_name, "Default-i") ||
+          !strcmp(visual_name, "Default-I")
+          )
        {
          visual_name = "default";
          install_cmap_p = True;
        }
-      else if (!strcmp(visual_name, "default-n"))
+      else if (!strcmp(visual_name, "default-n") ||
+               !strcmp(visual_name, "Default-n") ||
+               !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") ||
                !strcmp(visual_name, "GL"))
         {
           new_v = get_gl_visual (ssi->screen);
@@ -1514,8 +1532,6 @@ select_visual (saver_screen_info *ssi, const char *visual_name)
       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.
diff --git a/driver/xdpyinfo.c b/driver/xdpyinfo.c
new file mode 100644 (file)
index 0000000..acce044
--- /dev/null
@@ -0,0 +1,1077 @@
+/*
+ * $ TOG: xdpyinfo.c /main/35 1998/02/09 13:57:05 kaleb $
+ * 
+ * xdpyinfo - print information about X display connecton
+ *
+ * 
+Copyright 1988, 1998  The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author:  Jim Fulton, MIT X Consortium
+ * GLX and Overlay support added by Jamie Zawinski <jwz@jwz.org>, 11-Nov-99
+ *
+ *      To compile:
+ *         cc -DHAVE_GLX glxdpyinfo.c -o glxdpyinfo -lGL -lX11 -lXext -lm
+ *
+ *      Other defines to consider:
+ *         -DHAVE_XIE -DHAVE_XTEST -DHAVE_SYNC -DHAVE_XRECORD
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xproto.h> /* for CARD32 */
+#include <X11/extensions/multibuf.h>
+#ifdef HAVE_XIE
+#include <X11/extensions/XIElib.h>
+#endif /* HAVE_XIE */
+#ifdef HAVE_XTEST
+#include <X11/extensions/XTest.h>
+#endif /* HAVE_XTEST */
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif /* HAVE_XSYNC */
+#include <X11/extensions/Xdbe.h>
+#ifdef HAVE_XRECORD
+#include <X11/extensions/record.h>
+#endif /* HAVE_XRECORD */
+#ifdef MITSHM
+#include <X11/extensions/XShm.h>
+#endif
+#include <X11/Xos.h>
+#include <stdio.h>
+
+#ifdef HAVE_GLX
+# include <GL/gl.h>
+# include <GL/glx.h>
+#endif /* HAVE_GLX */
+
+#define HAVE_OVERLAY /* jwz: no compile-time deps, so do this all the time */
+
+char *ProgramName;
+Bool queryExtensions = False;
+
+static int StrCmp(a, b)
+    char **a, **b;
+{
+    return strcmp(*a, *b);
+}
+
+
+#ifdef HAVE_GLX  /* Added by jwz, 11-Nov-99 */
+
+static void
+print_glx_versions (dpy)
+    Display *dpy;
+{
+  /* Note: with Mesa 3.0, this lies: it prints the info from the
+     client's GL library, rather than the info from the GLX server.
+
+     Note also that we can't protect these calls by only doing
+     them when the GLX extension is present, because with Mesa,
+     the server doesn't have that extension (but the GL library
+     works anyway.)
+   */
+      int scr = DefaultScreen (dpy);
+      const char *vend, *vers;
+      vend = glXQueryServerString (dpy, scr, GLX_VENDOR);
+      if (!vend) return;
+      vers = glXQueryServerString (dpy, scr, GLX_VERSION);
+      printf ("GLX vendor:    %s (%s)\n",
+              vend, (vers ? vers : "unknown version"));
+}
+
+static void
+print_glx_visual_info (dpy, vip)
+    Display *dpy;
+    XVisualInfo *vip;
+{
+  int status, value = False;
+
+  status = glXGetConfig (dpy, vip, GLX_USE_GL, &value);
+  if (status == GLX_NO_EXTENSION)
+    /* dpy does not support the GLX extension. */
+    return;
+
+  if (status == GLX_BAD_VISUAL || value == False)
+    {
+      printf ("    GLX supported:     no\n");
+      return;
+    }
+  else
+    {
+      printf ("    GLX supported:     yes\n");
+    }
+    
+  if (!glXGetConfig (dpy, vip, GLX_LEVEL, &value) &&
+      value != 0)
+    printf ("    GLX level:         %d\n", value);
+
+  if (!glXGetConfig (dpy, vip, GLX_RGBA, &value) && value)
+    {
+      int r=0, g=0, b=0, a=0;
+      glXGetConfig (dpy, vip, GLX_RED_SIZE,   &r);
+      glXGetConfig (dpy, vip, GLX_GREEN_SIZE, &g);
+      glXGetConfig (dpy, vip, GLX_BLUE_SIZE,  &b);
+      glXGetConfig (dpy, vip, GLX_ALPHA_SIZE, &a);
+      printf ("    GLX type:          RGBA (%2d, %2d, %2d, %2d)\n",
+              r, g, b, a);
+
+      r=0, g=0, b=0, a=0;
+      glXGetConfig (dpy, vip, GLX_ACCUM_RED_SIZE,   &r);
+      glXGetConfig (dpy, vip, GLX_ACCUM_GREEN_SIZE, &g);
+      glXGetConfig (dpy, vip, GLX_ACCUM_BLUE_SIZE,  &b);
+      glXGetConfig (dpy, vip, GLX_ACCUM_ALPHA_SIZE, &a);
+      printf ("    GLX accum:         RGBA (%2d, %2d, %2d, %2d)\n",
+              r, g, b, a);
+    }
+  else
+    {
+      value = 0;
+      glXGetConfig (dpy, vip, GLX_BUFFER_SIZE, &value);
+      printf ("    GLX type:          indexed (%d)\n", value);
+    }
+
+# if 0  /* redundant */
+  if (!glXGetConfig (dpy, vip, GLX_X_VISUAL_TYPE_EXT, &value))
+      printf ("    GLX class:         %s\n",
+              (value == GLX_TRUE_COLOR_EXT ? "TrueColor" :
+               value == GLX_DIRECT_COLOR_EXT ? "DirectColor" :
+               value == GLX_PSEUDO_COLOR_EXT ? "PseudoColor" :
+               value == GLX_STATIC_COLOR_EXT ? "StaticColor" :
+               value == GLX_GRAY_SCALE_EXT ? "Grayscale" :
+               value == GLX_STATIC_GRAY_EXT ? "StaticGray" : "???"));
+# endif
+
+# ifdef GLX_VISUAL_CAVEAT_EXT
+  if (!glXGetConfig (dpy, vip, GLX_VISUAL_CAVEAT_EXT, &value) &&
+      value != GLX_NONE_EXT)
+    printf ("    GLX rating:        %s\n",
+            (value == GLX_NONE_EXT ? "none" :
+             value == GLX_SLOW_VISUAL_EXT ? "slow" :
+#   ifdef GLX_NON_CONFORMANT_EXT
+             value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
+#   endif
+             "???"));
+# endif
+
+  if (!glXGetConfig (dpy, vip, GLX_DOUBLEBUFFER, &value))
+    printf ("    GLX double-buffer: %s\n", (value ? "yes" : "no"));
+
+  if (!glXGetConfig (dpy, vip, GLX_STEREO, &value) &&
+      value)
+    printf ("    GLX stereo:        %s\n", (value ? "yes" : "no"));
+
+  if (!glXGetConfig (dpy, vip, GLX_AUX_BUFFERS, &value) &&
+      value != 0)
+    printf ("    GLX aux buffers:   %d\n", value);
+
+  if (!glXGetConfig (dpy, vip, GLX_DEPTH_SIZE, &value))
+    printf ("    GLX depth size:    %d\n", value);
+
+  if (!glXGetConfig (dpy, vip, GLX_STENCIL_SIZE, &value) &&
+      value != 0)
+    printf ("    GLX stencil size:  %d\n", value);
+
+# ifdef GLX_SAMPLE_BUFFERS_SGIS
+  if (!glXGetConfig (dpy, vip, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
+      value != 0)
+    {
+      int bufs = value;
+      if (!glXGetConfig (dpy, vip, GLX_SAMPLES_SGIS, &value))
+        printf ("    GLX multisamplers: %d (%d)\n", bufs, value);
+    }
+# endif
+
+  if (!glXGetConfig (dpy, vip, GLX_TRANSPARENT_TYPE_EXT, &value) &&
+      value != GLX_NONE_EXT)
+    {
+      if (value == GLX_NONE_EXT)
+        printf ("    GLX transparency:  none\n");
+      else if (value == GLX_TRANSPARENT_INDEX_EXT)
+        {
+          if (!glXGetConfig (dpy, vip, GLX_TRANSPARENT_INDEX_VALUE_EXT,&value))
+            printf ("    GLX transparency:  indexed (%d)\n", value);
+        }
+      else if (value == GLX_TRANSPARENT_RGB_EXT)
+        {
+          int r=0, g=0, b=0, a=0;
+          glXGetConfig (dpy, vip, GLX_TRANSPARENT_RED_VALUE_EXT,   &r);
+          glXGetConfig (dpy, vip, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
+          glXGetConfig (dpy, vip, GLX_TRANSPARENT_BLUE_VALUE_EXT,  &b);
+          glXGetConfig (dpy, vip, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
+          printf ("    GLX transparency:  RGBA (%2d, %2d, %2d, %2d)\n",
+                  r, g, b, a);
+        }
+    }
+}
+#endif /* HAVE_GLX */
+
+
+#ifdef HAVE_OVERLAY  /* Added by jwz, 11-Nov-99 */
+
+ /* If the server's root window contains a SERVER_OVERLAY_VISUALS property,
+    then that identifies the visuals which correspond to the video hardware's
+    overlay planes.  Windows created in these kinds of visuals may have
+    transparent pixels that let other layers shine through.
+
+    This might not be an X Consortium standard, but it turns out that
+    SGI, HP, DEC, and IBM all use this same mechanism.  So that's close
+    enough for me.
+
+    Documentation on the SERVER_OVERLAY_VISUALS property can be found at:
+    http://www.hp.com/xwindow/sharedInfo/Whitepapers/Visuals/server_overlay_visuals.html
+  */
+
+struct overlay
+{
+  CARD32 visual_id;
+  CARD32 transparency; /* 0: none; 1: pixel; 2: mask */
+  CARD32 value;                /* the transparent pixel */
+  CARD32 layer;                /* -1: underlay; 0: normal; 1: popup; 2: overlay */
+};
+
+struct overlay_list
+{
+  int count;
+  struct overlay *list;
+};
+
+static struct overlay_list *overlays = 0;
+
+static void
+find_overlay_info (dpy)
+  Display *dpy;
+{
+  int screen;
+  Atom OVERLAY = XInternAtom (dpy, "SERVER_OVERLAY_VISUALS", False);
+
+  overlays = (struct overlay_list *) calloc (sizeof (struct overlay_list),
+                                             ScreenCount (dpy));
+
+  for (screen = 0; screen < ScreenCount (dpy); screen++)
+    {
+      Window window = RootWindow (dpy, screen);
+      Atom actual_type;
+      int actual_format;
+      unsigned long nitems, bytes_after;
+      struct overlay *data = 0;
+      int result = XGetWindowProperty (dpy, window, OVERLAY,
+                                       0, (65536 / sizeof (long)), False, 
+                                       OVERLAY, &actual_type, &actual_format,
+                                       &nitems, &bytes_after,
+                                       (unsigned char **) &data);
+      if (result == Success &&
+          actual_type == OVERLAY &&
+          actual_format == 32 &&
+          nitems > 0)
+        {
+          overlays[screen].count = (nitems /
+                                    (sizeof(struct overlay) / sizeof(CARD32)));
+          overlays[screen].list = data;
+        }
+      else if (data)
+        XFree((char *) data);
+    }
+}
+
+static void
+print_overlay_visual_info (vip)
+    XVisualInfo *vip;
+{
+  int i;
+  int vis = vip->visualid;
+  int scr = vip->screen;
+  if (!overlays) return;
+  for (i = 0; i < overlays[scr].count; i++)
+    if (vis == overlays[scr].list[i].visual_id)
+      {
+        struct overlay *ov = &overlays[scr].list[i];
+        printf ("    Overlay info:      layer %ld (%s), ",
+                (long) ov->layer,
+                (ov->layer == -1 ? "underlay" :
+                 ov->layer ==  0 ? "normal" :
+                 ov->layer ==  1 ? "popup" :
+                 ov->layer ==  2 ? "overlay" : "???"));
+        if (ov->transparency == 1)
+          printf ("transparent pixel %lu\n", (unsigned long) ov->value);
+        else if (ov->transparency == 2)
+          printf ("transparent mask 0x%x\n", (unsigned long) ov->value);
+        else
+          printf ("opaque\n");
+      }
+}
+#endif /* HAVE_OVERLAY */
+
+
+void
+print_extension_info (dpy)
+    Display *dpy;
+{
+    int n = 0;
+    char **extlist = XListExtensions (dpy, &n);
+
+    printf ("number of extensions:    %d\n", n);
+
+    if (extlist) {
+       register int i;
+       int opcode, event, error;
+
+       qsort(extlist, n, sizeof(char *), StrCmp);
+       for (i = 0; i < n; i++) {
+           if (!queryExtensions) {
+               printf ("    %s\n", extlist[i]);
+               continue;
+           }
+           XQueryExtension(dpy, extlist[i], &opcode, &event, &error);
+           printf ("    %s  (opcode: %d", extlist[i], opcode);
+           if (event)
+               printf (", base event: %d", event);
+           if (error)
+               printf (", base error: %d", error);
+           printf(")\n");
+       }
+       /* do not free, Xlib can depend on contents being unaltered */
+       /* XFreeExtensionList (extlist); */
+    }
+}
+
+void
+print_display_info (dpy)
+    Display *dpy;
+{
+    char dummybuf[40];
+    char *cp;
+    int minkeycode, maxkeycode;
+    int i, n;
+    long req_size;
+    XPixmapFormatValues *pmf;
+    Window focuswin;
+    int focusrevert;
+
+    printf ("name of display:    %s\n", DisplayString (dpy));
+    printf ("version number:    %d.%d\n",
+           ProtocolVersion (dpy), ProtocolRevision (dpy));
+    printf ("vendor string:    %s\n", ServerVendor (dpy));
+    printf ("vendor release number:    %d\n", VendorRelease (dpy));
+
+#ifdef HAVE_GLX
+    print_glx_versions (dpy);
+#endif /* HAVE_GLX */
+
+    req_size = XExtendedMaxRequestSize (dpy);
+    if (!req_size) req_size = XMaxRequestSize (dpy);
+    printf ("maximum request size:  %ld bytes\n", req_size * 4);
+    printf ("motion buffer size:  %d\n", XDisplayMotionBufferSize (dpy));
+
+    switch (BitmapBitOrder (dpy)) {
+      case LSBFirst:    cp = "LSBFirst"; break;
+      case MSBFirst:    cp = "MSBFirst"; break;
+      default:    
+       sprintf (dummybuf, "unknown order %d", BitmapBitOrder (dpy));
+       cp = dummybuf;
+       break;
+    }
+    printf ("bitmap unit, bit order, padding:    %d, %s, %d\n",
+           BitmapUnit (dpy), cp, BitmapPad (dpy));
+
+    switch (ImageByteOrder (dpy)) {
+      case LSBFirst:    cp = "LSBFirst"; break;
+      case MSBFirst:    cp = "MSBFirst"; break;
+      default:    
+       sprintf (dummybuf, "unknown order %d", ImageByteOrder (dpy));
+       cp = dummybuf;
+       break;
+    }
+    printf ("image byte order:    %s\n", cp);
+
+    pmf = XListPixmapFormats (dpy, &n);
+    printf ("number of supported pixmap formats:    %d\n", n);
+    if (pmf) {
+       printf ("supported pixmap formats:\n");
+       for (i = 0; i < n; i++) {
+           printf ("    depth %d, bits_per_pixel %d, scanline_pad %d\n",
+                   pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad);
+       }
+       XFree ((char *) pmf);
+    }
+
+
+    /*
+     * when we get interfaces to the PixmapFormat stuff, insert code here
+     */
+
+    XDisplayKeycodes (dpy, &minkeycode, &maxkeycode);
+    printf ("keycode range:    minimum %d, maximum %d\n",
+           minkeycode, maxkeycode);
+
+    XGetInputFocus (dpy, &focuswin, &focusrevert);
+    printf ("focus:  ");
+    switch (focuswin) {
+      case PointerRoot:
+       printf ("PointerRoot\n");
+       break;
+      case None:
+       printf ("None\n");
+       break;
+      default:
+       printf("window 0x%lx, revert to ", focuswin);
+       switch (focusrevert) {
+         case RevertToParent:
+           printf ("Parent\n");
+           break;
+         case RevertToNone:
+           printf ("None\n");
+           break;
+         case RevertToPointerRoot:
+           printf ("PointerRoot\n");
+           break;
+         default:                      /* should not happen */
+           printf ("%d\n", focusrevert);
+           break;
+       }
+       break;
+    }
+
+    print_extension_info (dpy);
+
+    printf ("default screen number:    %d\n", DefaultScreen (dpy));
+    printf ("number of screens:    %d\n", ScreenCount (dpy));
+}
+
+void
+print_visual_info (vip)
+    XVisualInfo *vip;
+{
+    char errorbuf[40];                 /* for sprintfing into */
+    char *class = NULL;                        /* for printing */
+
+    switch (vip->class) {
+      case StaticGray:    class = "StaticGray"; break;
+      case GrayScale:    class = "GrayScale"; break;
+      case StaticColor:    class = "StaticColor"; break;
+      case PseudoColor:    class = "PseudoColor"; break;
+      case TrueColor:    class = "TrueColor"; break;
+      case DirectColor:    class = "DirectColor"; break;
+      default:    
+       sprintf (errorbuf, "unknown class %d", vip->class);
+       class = errorbuf;
+       break;
+    }
+
+    printf ("  visual:\n");
+    printf ("    visual id:    0x%lx\n", vip->visualid);
+    printf ("    class:    %s\n", class);
+    printf ("    depth:    %d plane%s\n", vip->depth, 
+           vip->depth == 1 ? "" : "s");
+    if (vip->class == TrueColor || vip->class == DirectColor)
+       printf ("    available colormap entries:    %d per subfield\n",
+               vip->colormap_size);
+    else
+       printf ("    available colormap entries:    %d\n",
+               vip->colormap_size);
+    printf ("    red, green, blue masks:    0x%lx, 0x%lx, 0x%lx\n",
+           vip->red_mask, vip->green_mask, vip->blue_mask);
+    printf ("    significant bits in color specification:    %d bits\n",
+           vip->bits_per_rgb);
+}
+
+void
+print_screen_info (dpy, scr)
+    Display *dpy;
+    int scr;
+{
+    Screen *s = ScreenOfDisplay (dpy, scr);  /* opaque structure */
+    XVisualInfo viproto;               /* fill in for getting info */
+    XVisualInfo *vip;                  /* retured info */
+    int nvi;                           /* number of elements returned */
+    int i;                             /* temp variable: iterator */
+    char eventbuf[80];                 /* want 79 chars per line + nul */
+    static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED";
+    double xres, yres;
+    int ndepths = 0, *depths = NULL;
+    unsigned int width, height;
+
+
+    /*
+     * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
+     *
+     *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
+     *         = N pixels / (M inch / 25.4)
+     *         = N * 25.4 pixels / M inch
+     */
+
+    xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) / 
+           ((double) DisplayWidthMM(dpy,scr)));
+    yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) / 
+           ((double) DisplayHeightMM(dpy,scr)));
+
+    printf ("\n");
+    printf ("screen #%d:\n", scr);
+    printf ("  dimensions:    %dx%d pixels (%dx%d millimeters)\n",
+           DisplayWidth (dpy, scr), DisplayHeight (dpy, scr),
+           DisplayWidthMM(dpy, scr), DisplayHeightMM (dpy, scr));
+    printf ("  resolution:    %dx%d dots per inch\n", 
+           (int) (xres + 0.5), (int) (yres + 0.5));
+    depths = XListDepths (dpy, scr, &ndepths);
+    if (!depths) ndepths = 0;
+    printf ("  depths (%d):    ", ndepths);
+    for (i = 0; i < ndepths; i++) {
+       printf ("%d", depths[i]);
+       if (i < ndepths - 1) { 
+           putchar (',');
+           putchar (' ');
+       }
+    }
+    putchar ('\n');
+    if (depths) XFree ((char *) depths);
+    printf ("  root window id:    0x%lx\n", RootWindow (dpy, scr));
+    printf ("  depth of root window:    %d plane%s\n",
+           DisplayPlanes (dpy, scr),
+           DisplayPlanes (dpy, scr) == 1 ? "" : "s");
+    printf ("  number of colormaps:    minimum %d, maximum %d\n",
+           MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
+    printf ("  default colormap:    0x%lx\n", DefaultColormap (dpy, scr));
+    printf ("  default number of colormap cells:    %d\n",
+           DisplayCells (dpy, scr));
+    printf ("  preallocated pixels:    black %d, white %d\n",
+           BlackPixel (dpy, scr), WhitePixel (dpy, scr));
+    printf ("  options:    backing-store %s, save-unders %s\n",
+           (DoesBackingStore (s) == NotUseful) ? no :
+           ((DoesBackingStore (s) == Always) ? yes : when),
+           DoesSaveUnders (s) ? yes : no);
+    XQueryBestSize (dpy, CursorShape, RootWindow (dpy, scr), 65535, 65535,
+                   &width, &height);
+    if (width == 65535 && height == 65535)
+       printf ("  largest cursor:    unlimited\n");
+    else
+       printf ("  largest cursor:    %dx%d\n", width, height);
+    printf ("  current input event mask:    0x%lx\n", EventMaskOfScreen (s));
+    (void) print_event_mask (eventbuf, 79, 4, EventMaskOfScreen (s));
+                     
+
+    nvi = 0;
+    viproto.screen = scr;
+    vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi);
+    printf ("  number of visuals:    %d\n", nvi);
+    printf ("  default visual id:  0x%lx\n", 
+           XVisualIDFromVisual (DefaultVisual (dpy, scr)));
+    for (i = 0; i < nvi; i++) {
+       print_visual_info (vip+i);
+#ifdef HAVE_OVERLAY
+       print_overlay_visual_info (vip+i);
+#endif /* HAVE_OVERLAY */
+#ifdef HAVE_GLX
+       print_glx_visual_info (dpy, vip+i);
+#endif /* HAVE_GLX */
+    }
+    if (vip) XFree ((char *) vip);
+}
+
+/*
+ * The following routine prints out an event mask, wrapping events at nice
+ * boundaries.
+ */
+
+#define MASK_NAME_WIDTH 25
+
+static struct _event_table {
+    char *name;
+    long value;
+} event_table[] = {
+    { "KeyPressMask             ", KeyPressMask },
+    { "KeyReleaseMask           ", KeyReleaseMask },
+    { "ButtonPressMask          ", ButtonPressMask },
+    { "ButtonReleaseMask        ", ButtonReleaseMask },
+    { "EnterWindowMask          ", EnterWindowMask },
+    { "LeaveWindowMask          ", LeaveWindowMask },
+    { "PointerMotionMask        ", PointerMotionMask },
+    { "PointerMotionHintMask    ", PointerMotionHintMask },
+    { "Button1MotionMask        ", Button1MotionMask },
+    { "Button2MotionMask        ", Button2MotionMask },
+    { "Button3MotionMask        ", Button3MotionMask },
+    { "Button4MotionMask        ", Button4MotionMask },
+    { "Button5MotionMask        ", Button5MotionMask },
+    { "ButtonMotionMask         ", ButtonMotionMask },
+    { "KeymapStateMask          ", KeymapStateMask },
+    { "ExposureMask             ", ExposureMask },
+    { "VisibilityChangeMask     ", VisibilityChangeMask },
+    { "StructureNotifyMask      ", StructureNotifyMask },
+    { "ResizeRedirectMask       ", ResizeRedirectMask },
+    { "SubstructureNotifyMask   ", SubstructureNotifyMask },
+    { "SubstructureRedirectMask ", SubstructureRedirectMask },
+    { "FocusChangeMask          ", FocusChangeMask },
+    { "PropertyChangeMask       ", PropertyChangeMask },
+    { "ColormapChangeMask       ", ColormapChangeMask },
+    { "OwnerGrabButtonMask      ", OwnerGrabButtonMask },
+    { NULL, 0 }};
+
+int print_event_mask (buf, lastcol, indent, mask)
+    char *buf;                         /* string to write into */
+    int lastcol;                       /* strlen(buf)+1 */
+    int indent;                                /* amount by which to indent */
+    long mask;                         /* event mask */
+{
+    struct _event_table *etp;
+    int len;
+    int bitsfound = 0;
+
+    buf[0] = buf[lastcol] = '\0';      /* just in case */
+
+#define INDENT() { register int i; len = indent; \
+                  for (i = 0; i < indent; i++) buf[i] = ' '; }
+
+    INDENT ();
+
+    for (etp = event_table; etp->name; etp++) {
+       if (mask & etp->value) {
+           if (len + MASK_NAME_WIDTH > lastcol) {
+               puts (buf);
+               INDENT ();
+           }
+           strcpy (buf+len, etp->name);
+           len += MASK_NAME_WIDTH;
+           bitsfound++;
+       }
+    }
+
+    if (bitsfound) puts (buf);
+
+#undef INDENT
+
+    return (bitsfound);
+}
+
+void
+print_standard_extension_info(dpy, extname, majorrev, minorrev)
+    Display *dpy;
+    char *extname;
+    int majorrev, minorrev;
+{
+    int opcode, event, error;
+
+    printf("%s version %d.%d ", extname, majorrev, minorrev);
+
+    XQueryExtension(dpy, extname, &opcode, &event, &error);
+    printf ("opcode: %d", opcode);
+    if (event)
+       printf (", base event: %d", event);
+    if (error)
+       printf (", base error: %d", error);
+    printf("\n");
+}
+
+int
+print_multibuf_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    int i, j;                  /* temp variable: iterator */
+    int nmono, nstereo;                /* count */
+    XmbufBufferInfo *mono_info = NULL, *stereo_info = NULL; /* arrays */
+    static char *fmt = 
+       "    visual id, max buffers, depth:    0x%lx, %d, %d\n";
+    int scr = 0;
+    int majorrev, minorrev;
+
+    if (!XmbufGetVersion(dpy, &majorrev, &minorrev))
+       return 0;
+
+    print_standard_extension_info(dpy, extname, majorrev, minorrev);
+
+    for (i = 0; i < ScreenCount (dpy); i++)
+    {
+       if (!XmbufGetScreenInfo (dpy, RootWindow(dpy, scr), &nmono, &mono_info,
+                                &nstereo, &stereo_info)) {
+           fprintf (stderr,
+                    "%s:  unable to get multibuffer info for screen %d\n",
+                    ProgramName, scr);
+       } else {
+           printf ("  screen %d number of mono multibuffer types:    %d\n", i, nmono);
+           for (j = 0; j < nmono; j++) {
+               printf (fmt, mono_info[j].visualid, mono_info[j].max_buffers,
+                       mono_info[j].depth);
+           }
+           printf ("  number of stereo multibuffer types:    %d\n", nstereo);
+           for (j = 0; j < nstereo; j++) {
+               printf (fmt, stereo_info[j].visualid,
+                       stereo_info[j].max_buffers, stereo_info[j].depth);
+           }
+           if (mono_info) XFree ((char *) mono_info);
+           if (stereo_info) XFree ((char *) stereo_info);
+       }
+    }
+    return 1;
+} /* end print_multibuf_info */
+
+
+/* XIE stuff */
+
+#ifdef HAVE_XIE
+
+char *subset_names[] = { NULL, "FULL", "DIS" };
+char *align_names[] = { NULL, "Alignable", "Arbitrary" };
+char *group_names[] = { /* 0  */ "Default",
+                           /* 2  */ "ColorAlloc",
+                           /* 4  */ "Constrain",
+                           /* 6  */ "ConvertFromRGB",
+                           /* 8  */ "ConvertToRGB",
+                           /* 10 */ "Convolve",
+                           /* 12 */ "Decode",
+                           /* 14 */ "Dither",
+                           /* 16 */ "Encode",
+                           /* 18 */ "Gamut",
+                           /* 20 */ "Geometry",
+                           /* 22 */ "Histogram",
+                           /* 24 */ "WhiteAdjust"
+                           };
+
+int
+print_xie_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    XieExtensionInfo *xieInfo;
+    int i;
+    int ntechs;
+    XieTechnique *techs;
+    XieTechniqueGroup prevGroup;
+
+    if (!XieInitialize(dpy, &xieInfo ))
+       return 0;
+
+    print_standard_extension_info(dpy, extname,
+       xieInfo->server_major_rev, xieInfo->server_minor_rev);
+
+    printf("  service class: %s\n", subset_names[xieInfo->service_class]);
+    printf("  alignment: %s\n", align_names[xieInfo->alignment]);
+    printf("  uncnst_mantissa: %d\n", xieInfo->uncnst_mantissa);
+    printf("  uncnst_min_exp: %d\n", xieInfo->uncnst_min_exp);
+    printf("  uncnst_max_exp: %d\n", xieInfo->uncnst_max_exp);
+    printf("  cnst_levels:"); 
+    for (i = 0; i < xieInfo->n_cnst_levels; i++)
+       printf(" %d", xieInfo->cnst_levels[i]);
+    printf("\n");
+
+    if (!XieQueryTechniques(dpy, xieValAll, &ntechs, &techs))
+       return 1;
+
+    prevGroup = -1;
+
+    for (i = 0; i < ntechs; i++)
+    {
+       if (techs[i].group != prevGroup)
+       {
+           printf("  technique group: %s\n", group_names[techs[i].group >> 1]);
+           prevGroup = techs[i].group;
+       }
+       printf("    %s\tspeed: %d  needs_param: %s  number: %d\n",
+              techs[i].name,
+              techs[i].speed, (techs[i].needs_param ? "True " : "False"),
+              techs[i].number);
+    }
+    return 1;
+} /* end print_xie_info */
+
+#endif /* HAVE_XIE */
+
+
+#ifdef HAVE_XTEST
+int
+print_xtest_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    int majorrev, minorrev, foo;
+
+    if (!XTestQueryExtension(dpy, &foo, &foo, &majorrev, &minorrev))
+       return 0;
+    print_standard_extension_info(dpy, extname, majorrev, minorrev);
+    return 1;
+}
+#endif /* HAVE_XTEST */
+
+#ifdef HAVE_XSYNC
+int
+print_sync_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    int majorrev, minorrev;
+    XSyncSystemCounter *syscounters;
+    int ncounters, i;
+
+    if (!XSyncInitialize(dpy, &majorrev, &minorrev))
+       return 0;
+    print_standard_extension_info(dpy, extname, majorrev, minorrev);
+
+    syscounters = XSyncListSystemCounters(dpy, &ncounters);
+    printf("  system counters: %d\n", ncounters);
+    for (i = 0; i < ncounters; i++)
+    {
+       printf("    %s  id: 0x%08x  resolution_lo: %d  resolution_hi: %d\n",
+              syscounters[i].name, syscounters[i].counter,
+              XSyncValueLow32(syscounters[i].resolution),
+              XSyncValueHigh32(syscounters[i].resolution));
+    }
+    XSyncFreeSystemCounterList(syscounters);
+    return 1;
+}
+#endif /* HAVE_XSYNC */
+
+int
+print_shape_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    int majorrev, minorrev;
+
+    if (!XShapeQueryVersion(dpy, &majorrev, &minorrev))
+       return 0;
+    print_standard_extension_info(dpy, extname, majorrev, minorrev);
+    return 1;
+}
+
+#ifdef MITSHM
+int
+print_mitshm_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    int majorrev, minorrev;
+    Bool sharedPixmaps;
+
+    if (!XShmQueryVersion(dpy, &majorrev, &minorrev, &sharedPixmaps))
+       return 0;
+    print_standard_extension_info(dpy, extname, majorrev, minorrev);
+    printf("  shared pixmaps: ");
+    if (sharedPixmaps)
+    {
+       int format = XShmPixmapFormat(dpy);
+       printf("yes, format: %d\n", format);
+    }
+    else
+    {
+       printf("no\n");
+    }
+    return 1;
+}
+#endif /* MITSHM */
+
+int
+print_dbe_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    int majorrev, minorrev;
+    XdbeScreenVisualInfo *svi;
+    int numscreens = 0;
+    int iscrn, ivis;
+
+    if (!XdbeQueryExtension(dpy, &majorrev, &minorrev))
+       return 0;
+
+    print_standard_extension_info(dpy, extname, majorrev, minorrev);
+    svi = XdbeGetVisualInfo(dpy, (Drawable *)NULL, &numscreens);
+    for (iscrn = 0; iscrn < numscreens; iscrn++)
+    {
+       printf("  Double-buffered visuals on screen %d\n", iscrn);
+       for (ivis = 0; ivis < svi[iscrn].count; ivis++)
+       {
+           printf("    visual id 0x%lx  depth %d  perflevel %d\n",
+                  svi[iscrn].visinfo[ivis].visual,
+                  svi[iscrn].visinfo[ivis].depth,
+                  svi[iscrn].visinfo[ivis].perflevel);
+       }
+    }
+    XdbeFreeVisualInfo(svi);
+    return 1;
+}
+
+#ifdef HAVE_XRECORD
+int
+print_record_info(dpy, extname)
+    Display *dpy;
+    char *extname;
+{
+    int majorrev, minorrev;
+
+    if (!XRecordQueryVersion(dpy, &majorrev, &minorrev))
+       return 0;
+    print_standard_extension_info(dpy, extname, majorrev, minorrev);
+    return 1;
+}
+#endif /* HAVE_XRECORD */
+
+/* utilities to manage the list of recognized extensions */
+
+
+typedef int (*ExtensionPrintFunc)(
+#if NeedFunctionPrototypes
+    Display *, char *
+#endif
+);
+
+typedef struct {
+    char *extname;
+    ExtensionPrintFunc printfunc;
+    Bool printit;
+} ExtensionPrintInfo;
+
+ExtensionPrintInfo known_extensions[] =
+{
+#ifdef MITSHM
+    {"MIT-SHM",        print_mitshm_info, False},
+#endif /* MITSHM */
+    {MULTIBUFFER_PROTOCOL_NAME,        print_multibuf_info, False},
+    {"SHAPE", print_shape_info, False},
+#ifdef HAVE_XSYNC
+    {SYNC_NAME, print_sync_info, False},
+#endif /* HAVE_XSYNC */
+#ifdef HAVE_XIE
+    {xieExtName, print_xie_info, False},
+#endif /* HAVE_XIE */
+#ifdef HAVE_XTEST
+    {XTestExtensionName, print_xtest_info, False},
+#endif /* HAVE_XTEST */
+    {"DOUBLE-BUFFER", print_dbe_info, False},
+#ifdef HAVE_XRECORD
+    {"RECORD", print_record_info, False}    
+#endif /* HAVE_XRECORD */
+    /* add new extensions here */
+    /* wish list: PEX XKB LBX */
+};
+
+int num_known_extensions = sizeof known_extensions / sizeof known_extensions[0];
+
+void
+print_known_extensions(f)
+    FILE *f;
+{
+    int i;
+    for (i = 0; i < num_known_extensions; i++)
+    {
+       fprintf(f, "%s ", known_extensions[i].extname);
+    }
+}
+
+void
+mark_extension_for_printing(extname)
+    char *extname;
+{
+    int i;
+
+    if (strcmp(extname, "all") == 0)
+    {
+       for (i = 0; i < num_known_extensions; i++)
+           known_extensions[i].printit = True;
+    }
+    else
+    {
+       for (i = 0; i < num_known_extensions; i++)
+       {
+           if (strcmp(extname, known_extensions[i].extname) == 0)
+           {
+               known_extensions[i].printit = True;
+               return;
+           }
+       }
+       printf("%s extension not supported by %s\n", extname, ProgramName);
+    }
+}
+
+void
+print_marked_extensions(dpy)
+    Display *dpy;
+{
+    int i;
+    for (i = 0; i < num_known_extensions; i++)
+    {
+       if (known_extensions[i].printit)
+       {
+           printf("\n");
+           if (! (*known_extensions[i].printfunc)(dpy,
+                                       known_extensions[i].extname))
+           {
+               printf("%s extension not supported by server\n",
+                      known_extensions[i].extname);
+           }
+       }
+    }
+}
+
+static void usage ()
+{
+    fprintf (stderr, "usage:  %s [options]\n", ProgramName);
+    fprintf (stderr, "-display displayname\tserver to query\n");
+    fprintf (stderr, "-queryExtensions\tprint info returned by XQueryExtension\n");
+    fprintf (stderr, "-ext all\t\tprint detailed info for all supported extensions\n");
+    fprintf (stderr, "-ext extension-name\tprint detailed info for extension-name if one of:\n     ");
+    print_known_extensions(stderr);
+    fprintf (stderr, "\n");
+    exit (1);
+}
+
+int main (argc, argv)
+    int argc;
+    char *argv[];
+{
+    Display *dpy;                      /* X connection */
+    char *displayname = NULL;          /* server to contact */
+    int i;                             /* temp variable:  iterator */
+    Bool multibuf = False;
+    int mbuf_event_base, mbuf_error_base;
+
+    ProgramName = argv[0];
+
+    for (i = 1; i < argc; i++) {
+       char *arg = argv[i];
+       int len = strlen(arg);
+       
+       if (!strncmp("-display", arg, len)) {
+           if (++i >= argc) usage ();
+           displayname = argv[i];
+       } else if (!strncmp("-queryExtensions", arg, len)) {
+           queryExtensions = True;
+       } else if (!strncmp("-ext", arg, len)) {
+           if (++i >= argc) usage ();
+           mark_extension_for_printing(argv[i]);
+       } else
+           usage ();
+    }
+
+    dpy = XOpenDisplay (displayname);
+    if (!dpy) {
+       fprintf (stderr, "%s:  unable to open display \"%s\".\n",
+                ProgramName, XDisplayName (displayname));
+       exit (1);
+    }
+
+#ifdef HAVE_OVERLAY
+       find_overlay_info (dpy);
+#endif /* HAVE_OVERLAY */
+
+    print_display_info (dpy);
+    for (i = 0; i < ScreenCount (dpy); i++) {
+       print_screen_info (dpy, i);
+    }
+
+    print_marked_extensions(dpy);
+
+    XCloseDisplay (dpy);
+    exit (0);
+}
index cc169d2792d3ea6384b2b8e1cf5a4cd6d77dad14..cd2ea714b22639f63e45ad137098782b93eeb1e4 100644 (file)
@@ -42,9 +42,10 @@ 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;
+Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO, XA_EXIT;
+Atom XA_BLANK, XA_LOCK;
+static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV;
+static Atom XA_RESTART, XA_PREFS, XA_THROTTLE, XA_UNTHROTTLE;
 
 static char *screensaver_version;
 static char *usage = "\n\
@@ -121,6 +122,12 @@ usage: %s -<option>\n\
                 deactivated (roughly, how long the user has been idle or\n\
                 non-idle -- but not quite, since it only tells you when the\n\
                 screen became blanked or un-blanked.)\n\
+\n\
+  -watch        Prints a line each time the screensaver changes state: when\n\
+                the screen blanks, locks, unblanks, or when the running hack\n\
+                is changed.  This option never returns; it is intended for\n\
+                by shell scripts that want to react to the screensaver in\n\
+                some way.\n\
 \n\
   See the man page for more details.\n\
   For updates, check http://www.jwz.org/xscreensaver/\n\
@@ -130,6 +137,8 @@ usage: %s -<option>\n\
  fprintf (stderr, usage, progname, screensaver_version); exit (1); \
  } while(0)
 
+static int watch (Display *);
+
 int
 main (int argc, char **argv)
 {
@@ -168,7 +177,8 @@ main (int argc, char **argv)
       else if (!strncmp (s, "-throttle", L))   cmd = &XA_THROTTLE;
       else if (!strncmp (s, "-unthrottle", L)) cmd = &XA_UNTHROTTLE;
       else if (!strncmp (s, "-version", L))    cmd = &XA_SCREENSAVER_VERSION;
-      else if (!strncmp (s, "-time", L))       cmd = &XA_SCREENSAVER_TIME;
+      else if (!strncmp (s, "-time", L))       cmd = &XA_SCREENSAVER_STATUS;
+      else if (!strncmp (s, "-watch", L))      cmd = (Atom *) &watch;
       else USAGE ();
 
       if (cmd == &XA_SELECT || cmd == &XA_DEMO)
@@ -254,7 +264,7 @@ main (int argc, char **argv)
   XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False);
   XA_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False);
   XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False);
-  XA_SCREENSAVER_TIME = XInternAtom (dpy, "_SCREENSAVER_TIME", False);
+  XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False);
   XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False);
   XA_ACTIVATE = XInternAtom (dpy, "ACTIVATE", False);
   XA_DEACTIVATE = XInternAtom (dpy, "DEACTIVATE", False);
@@ -267,11 +277,18 @@ main (int argc, char **argv)
   XA_DEMO = XInternAtom (dpy, "DEMO", False);
   XA_PREFS = XInternAtom (dpy, "PREFS", False);
   XA_LOCK = XInternAtom (dpy, "LOCK", False);
+  XA_BLANK = XInternAtom (dpy, "BLANK", False);
   XA_THROTTLE = XInternAtom (dpy, "THROTTLE", False);
   XA_UNTHROTTLE = XInternAtom (dpy, "UNTHROTTLE", False);
 
   XSync (dpy, 0);
 
+  if (cmd == (Atom *) &watch)
+    {
+      i = watch (dpy);
+      exit (i);
+    }
+
   if (*cmd == XA_ACTIVATE || *cmd == XA_LOCK ||
       *cmd == XA_NEXT || *cmd == XA_PREV || *cmd == XA_SELECT)
     /* People never guess that KeyRelease deactivates the screen saver too,
@@ -282,3 +299,115 @@ main (int argc, char **argv)
   if (i < 0) exit (i);
   else exit (0);
 }
+
+
+static int
+watch (Display *dpy)
+{
+  char *v = 0;
+  Window window = RootWindow (dpy, 0);
+  XWindowAttributes xgwa;
+  XEvent event;
+  CARD32 *last = 0;
+
+  if (v) free (v);
+  XGetWindowAttributes (dpy, window, &xgwa);
+  XSelectInput (dpy, window, xgwa.your_event_mask | PropertyChangeMask);
+
+  while (1)
+    {
+      XNextEvent (dpy, &event);
+      if (event.xany.type == PropertyNotify &&
+          event.xproperty.state == PropertyNewValue &&
+          event.xproperty.atom == XA_SCREENSAVER_STATUS)
+        {
+         Atom type;
+         int format;
+         unsigned long nitems, bytesafter;
+         CARD32 *data = 0;
+
+         if (XGetWindowProperty (dpy,
+                                  RootWindow (dpy, 0),  /* always screen #0 */
+                                 XA_SCREENSAVER_STATUS,
+                                 0, 999, False, XA_INTEGER,
+                                 &type, &format, &nitems, &bytesafter,
+                                 (unsigned char **) &data)
+             == Success
+             && type
+             && data)
+           {
+              time_t tt;
+              char *s;
+              Bool changed = False;
+              Bool running = False;
+
+              if (type != XA_INTEGER || nitems < 3)
+                {
+                STATUS_LOSE:
+                  if (last) free (last);
+                  if (data) free (data);
+                  fprintf (stderr, "%s: bad status format on root window.\n",
+                           progname);
+                  return -1;
+                }
+                  
+              tt = (time_t) data[1];
+              if (tt <= (time_t) 666000000L) /* early 1991 */
+                goto STATUS_LOSE;
+
+              s = ctime(&tt);
+              if (s[strlen(s)-1] == '\n')
+                s[strlen(s)-1] = 0;
+
+              if (!last || data[0] != last[0])
+                {
+                  /* State changed. */
+                  if (data[0] == XA_BLANK)
+                    printf ("BLANK %s\n", s);
+                  else if (data[0] == XA_LOCK)
+                    printf ("LOCK %s\n", s);
+                  else if (data[0] == 0)
+                    printf ("UNBLANK %s\n", s);
+                  else
+                    goto STATUS_LOSE;
+                }
+
+              if (!last)
+                changed = True;
+              else
+                {
+                  int i;
+                  for (i = 2; i < nitems; i++)
+                    {
+                      if (data[i] != last[i])
+                        changed = True;
+                      if (data[i])
+                        running = True;
+                    }
+                }
+
+              if (running && changed)
+                {
+                  int i;
+                  fprintf (stdout, "RUN", s);
+                  for (i = 2; i < nitems; i++)
+                    fprintf (stdout, " %d", (int) data[i]);
+                  fprintf (stdout, "\n");
+                }
+
+              fflush (stdout);
+
+              if (last) free (last);
+              last = data;
+           }
+         else
+           {
+             if (last) free (last);
+             if (data) free (data);
+             fprintf (stderr, "%s: no saver status on root window.\n",
+                      progname);
+             return -1;
+           }
+        }
+    }
+}
index b02acfff9e815fb6447f252c37a89e0b345d68c7..3374a78c8e844fb269b46875dbec3e505a820f8c 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "30-Oct-99 (3.19)" "X Version 11"
+.TH XScreenSaver 1 "12-Nov-99 (3.20)" "X Version 11"
 .SH NAME
 xscreensaver-command - control a running xscreensaver process
 .SH SYNOPSIS
@@ -31,7 +31,8 @@ xscreensaver-command - control a running xscreensaver process
 [\-throttle] \
 [\-unthrottle] \
 [\-version] \
-[\-time]
+[\-time] \
+[\-watch]
 .SH DESCRIPTION
 The \fIxscreensaver\-command\fP program controls a running \fIxscreensaver\fP
 process by sending it client-messages.
@@ -177,6 +178,53 @@ launching it again.
 The important point is, you need to make sure that the xscreensaver 
 process is running as you.  If it's not, it won't be reading the 
 right \fI.xscreensaver\fP file.
+.TP 8
+.B \-watch
+Prints a line each time the screensaver changes state: when the screen
+blanks, locks, unblanks, or when the running hack is changed.  This option
+never returns; it is intended for by shell scripts that want to react to
+the screensaver in some way.  An example of its output would be:
+.EX
+BLANK Fri Nov  5 01:57:22 1999
+RUN 34
+RUN 79
+RUN 16
+LOCK Fri Nov  5 01:57:22 1999
+RUN 76
+RUN 12
+UNBLANK Fri Nov  5 02:05:59 1999
+.EE
+The above shows the screensaver activating, running three different
+hacks, then locking (perhaps because the lock-timeout went off) then
+unblanking (because the user became active, and typed the correct
+password.)  The hack numbers are their index in the `programs'
+list (starting with 1, not 0, as for the \fI\-select\fP command.)
+
+For example, suppose you want to run a program that turns down the volume
+on your machine when the screen blanks, and turns it back up when the screen
+un-blanks.  You could do that by running a Perl program like the following
+in the background.  The following program tracks the output of 
+the \fI\-watch\fP command and reacts accordingly:
+.EX
+#!/usr/bin/perl
+
+my $blanked = 0;
+open (IN, "xscreensaver-command -watch |");
+while (<IN>) {
+    if (m/^(BLANK|LOCK)/) {
+        if (!$blanked) {
+            system "sound-off";
+            $blanked = 1;
+        }
+    } elsif (m/^UNBLANK/) {
+        system "sound-on";
+        $blanked = 0;
+    }
+}
+.EE
+Note that LOCK might come either with or without a preceeding BLANK
+(depending on whether the lock-timeout is non-zero), so the above program
+is keeps track of both of them.
 .SH DIAGNOSTICS
 If an error occurs while communicating with the \fIxscreensaver\fP daemon, or
 if the daemon reports an error, a diagnostic message will be printed to
diff --git a/driver/xscreensaver-demo-old.man b/driver/xscreensaver-demo-old.man
new file mode 100644 (file)
index 0000000..e6c4b0a
--- /dev/null
@@ -0,0 +1,213 @@
+.de EX         \"Begin example
+.ne 5
+.if n .sp 1
+.if t .sp .5
+.nf
+.in +.5i
+..
+.de EE
+.fi
+.in -.5i
+.if n .sp 1
+.if t .sp .5
+..
+.TH XScreenSaver 1 "09-Nov-99 (3.19)" "X Version 11"
+.SH NAME
+xscreensaver-demo - interactively control the background xscreensaver daemon
+.SH SYNOPSIS
+.B xscreensaver\-demo
+[\-display \fIhost:display.screen\fP] [\-prefs] [\-xrm \fIresources\fP]
+.SH DESCRIPTION
+The \fIxscreensaver\-demo\fP program is a graphical front-end for 
+setting the parameters used by the background
+.BR xscreensaver (1)
+daemon.
+It is essentially two things: a tool for editing the \fI~/.xscreensaver\fP
+file; and a tool for demoing the various graphics hacks that 
+the \fIxscreensaver\fP daemon will launch.
+
+.B Note:
+this manual describes the Motif and Athena versions of
+the \fIxscreensaver\-demo\fP command.  At this point, the Gtk 
+version of \fIxscreensaver\-demo\fP is somewhat more advanced.
+
+The main dialog box contains a scrolling list, a text field, and a number 
+of buttons.  
+
+Double-clicking on one of the programs in the list will run it.  The screen
+will go black, and the program will run in full-screen mode, just as it would
+if the \fIxscreensaver\fP daemon had launched it.  Clicking the mouse again
+will stop the demo and un-blank the screen, making the dialog box visible 
+again.
+
+Single-clicking in the list will place the indicated program and its args
+in the text field to be edited.  Edit the arguments and hit return to run
+the program with the parameters you have specified.  This will also save
+your changes to your \fI~/.xscreensaver\fP file: so any changes you make
+in this way are persistent.
+
+If one of the lines in the scrolling list begins with the character "-",
+then that means that the program is disabled: \fIxscreensaver\fP will not
+select it to be run (though you can still try it out by clicking on it.)
+Rather than just deleting the programs you don't want to run, you might
+want to disable them in this way instead, so that you can more easily change
+your mind later.
+
+If the line begins with the name of a visual, followed by a colon, then
+that program will only be run on that kind of visual.  For example, you can
+specify that a particular program should only be run if color is available,
+and another should only be run in monochrome.  See the discussion of 
+the \fIprograms\fP parameter in the \fIConfiguration\fP section of the
+.BR xscreensaver (1)
+manual.
+
+The buttons are:
+.TP 8
+.B Run Next
+Clicking this button will run the next program in the list after the 
+currently-selected one, and will wrap around to the top when it reaches
+the bottom.
+.TP 8
+.B Run Previous
+Opposite of Run Next; at the top, it wraps around to the bottom.
+.TP 8
+.B Preferences
+This pops up a second dialog box, in which you have the option to 
+interactively change most of the screensaver's operational parameters,
+such as its timeouts, and whether it should lock the screen.  When you
+click OK, your chosen settings will take effect immediately, and will
+also be saved to the \fI~/.xscreensaver\fP file in your home directory,
+so that the settings will persist next time.
+.TP 8
+.B Quit
+Exits the \fIxscreensaver-demo\fP program.  The background \fIxscreensaver\fP
+daemon will continue running as before.
+.P
+The Preferences dialog box lets you change the following settings.
+
+(There are more settings available, but these are the most commonly used
+ones; see the manual for
+.BR xscreensaver (1)
+for other parameters that can be set by editing the \fI~/.xscreensaver\fP
+file, or the X resource database.)
+.TP 8
+.B Saver Timeout
+After the user has been idle this long, the \fIxscreensaver\fP daemon
+will blank the screen.
+.TP 8
+.B Cycle Timeout
+After the screensaver has been running for this long, the currently
+running graphics demo will be killed, and a new one started.  
+If this is 0, then the graphics demo will never be changed:
+only one demo will run until the screensaver is deactivated by user 
+activity.
+.TP 8
+.B Verbose\ 
+Whether to print lots of debugging information.
+.TP 8
+.B Install Colormap
+Whether to install a private colormap while the screensaver is active, so
+that the graphics hacks can get as many colors as possible.  (This only
+applies when the screen's default visual is being used, since non-default
+visuals get their own colormaps automatically.)  This can also be overridden
+on a per-demo basis.
+.TP 8
+.B Fade Colormap
+If selected, then when the screensaver activates, the current contents
+of the screen will fade to black instead of simply winking out.  This only
+works on displays with writable colormaps, that is, if the screen's default
+visual is a PseudoColor visual.  A fade will also be done when
+switching graphics hacks (when the \fICycle Timeout\fP expires.)
+.TP 8
+.B Unfade Colormap
+The complement to \fIFade Colormap\fP: if selected, then when the screensaver
+deactivates, the original contents of the screen will fade in from black
+instead of appearing immediately.  This only works on displays with writable
+colormaps, and when \fIFade Colormap\fP is also selected.
+.TP 8
+.B Fade Duration
+When fading or unfading are selected, this controls how long the fade will
+take.
+.TP 8
+.B Fade Ticks
+This controls how many times a second the colormap will be changed to 
+effect a fade.  Higher numbers yield smoother fades, but may make the
+fades take longer than the specified number of seconds, if your server
+isn't fast enough to keep up.
+.TP 8
+.B Require Password
+Whether the screen saver should lock the screen when it activates.
+.TP 8
+.B Lock Timeout
+If \fIRequire Password\fP is selected, this controls the length of 
+the ``grace period'' between when the screensaver activates, and when the
+screen becomes locked.  For example, if this is 0:05:00, 
+and \fISaver Timeout\fP is 0:10:00, then after 10 minutes, the screen 
+would blank.  If there was user  activity at 12 minutes, no password
+would be required to un-blank the screen.  But, if there was user activity
+at 15 minutes or later (that is, \fILock Timeout\fP minutes after 
+activation) then a password would be required.  The default is 0, meaning
+that if locking is enabled, then a password will be required as soon as the 
+screen blanks.
+.TP 8
+.B Password Timeout
+When the screensaver is prompting for a password, the prompt dialog box will
+stay on the screen for this long before giving up, and reverting to 
+screen-saving mode.
+.SH COMMAND-LINE OPTIONS
+.I xscreensaver\-demo
+accepts the following command line options.
+.TP 8
+.B \-display \fIhost:display.screen\fP
+The X display to use.  The \fIxscreensaver\-demo\fP program will open its
+window on that display, and also control the \fIxscreensaver\fP daemon that
+is managing that same display.
+.TP 8
+.B \-prefs
+Start up in Preferences mode: this is just like launching the program with
+no arguments, and then pressing the \fIPreferences\fP button.
+.P
+It is important that the \fIxscreensaver\fP and \fIxscreensaver\-demo\fP
+processes be running on the same machine, or at least, on two machines
+that share a file system.  When \fIxscreensaver\-demo\fP writes a new version
+of the \fI~/.xscreensaver\fP file, it's important that the \fIxscreensaver\fP
+see that same file.  If the two processes are seeing 
+different \fI~/.xscreensaver\fP files, things will malfunction.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B PATH
+to find the sub-programs to run.  However, note that the sub-programs 
+are actually launched by the \fIxscreensaver\fP daemon, not 
+by \fIxscreensaver-demo\fP itself.  So, what matters is what \fB$PATH\fP
+the \fIxscreensaver\fP program sees.
+.TP 8
+.B HOME
+for the directory in which to read and write the \fI.xscreensaver\fP file.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH UPGRADES
+The latest version can always be found at 
+http://www.jwz.org/xscreensaver/
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1),
+.BR xscreensaver\-command (1)
+.SH COPYRIGHT
+Copyright \(co 1992, 1993, 1997, 1998, 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.
+.SH AUTHOR
+Jamie Zawinski <jwz@jwz.org>, 13-aug-92.
+
+Please let me know if you find any bugs or make any improvements.
diff --git a/driver/xscreensaver-demo.glade b/driver/xscreensaver-demo.glade
new file mode 100644 (file)
index 0000000..c1a6751
--- /dev/null
@@ -0,0 +1,1110 @@
+<?xml version="1.0"?>
+<GTK-Interface>
+
+<project>
+  <name>XScreenSaver</name>
+  <program_name>xscreensaver-demo</program_name>
+  <directory></directory>
+  <source_directory></source_directory>
+  <pixmaps_directory></pixmaps_directory>
+  <language>C</language>
+  <gnome_support>False</gnome_support>
+  <gettext_support>False</gettext_support>
+  <use_widget_names>True</use_widget_names>
+  <output_main_file>False</output_main_file>
+  <output_support_files>False</output_support_files>
+  <output_build_files>False</output_build_files>
+  <backup_source_files>False</backup_source_files>
+  <main_source_file>demo-Gtk-widgets.c</main_source_file>
+  <main_header_file>demo-Gtk-widgets.h</main_header_file>
+  <handler_source_file>demo-Gtk-stubs.c</handler_source_file>
+  <handler_header_file>demo-Gtk-stubs.h</handler_header_file>
+  <support_source_file>support.c</support_source_file>
+  <support_header_file>support.h</support_header_file>
+  <translatable_strings_file></translatable_strings_file>
+</project>
+
+<widget>
+  <class>GtkWindow</class>
+  <name>xscreensaver_demo</name>
+  <title>XScreenSaver</title>
+  <type>GTK_WINDOW_TOPLEVEL</type>
+  <position>GTK_WIN_POS_NONE</position>
+  <modal>False</modal>
+  <default_width>600</default_width>
+  <default_height>400</default_height>
+  <allow_shrink>True</allow_shrink>
+  <allow_grow>True</allow_grow>
+  <auto_shrink>False</auto_shrink>
+  <wmclass_name>xscreensaver</wmclass_name>
+  <wmclass_class>XScreenSaver</wmclass_class>
+
+  <widget>
+    <class>GtkVBox</class>
+    <name>outer_vbox</name>
+    <homogeneous>False</homogeneous>
+    <spacing>5</spacing>
+
+    <widget>
+      <class>GtkMenuBar</class>
+      <name>menubar</name>
+      <shadow_type>GTK_SHADOW_OUT</shadow_type>
+      <child>
+       <padding>0</padding>
+       <expand>False</expand>
+       <fill>False</fill>
+      </child>
+
+      <widget>
+       <class>GtkMenuItem</class>
+       <name>file</name>
+       <stock_item>GNOMEUIINFO_MENU_FILE_TREE</stock_item>
+
+       <widget>
+         <class>GtkMenu</class>
+         <name>file_menu</name>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>activate_menu</name>
+           <tooltip>Activate the XScreenSaver daemon now (locking the screen if so configured.)</tooltip>
+           <signal>
+             <name>activate</name>
+             <handler>activate_menu_cb</handler>
+             <last_modification_time>Tue, 09 Nov 1999 00:01:23 GMT</last_modification_time>
+           </signal>
+           <label>_Blank Screen Now</label>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>lock_menu</name>
+           <tooltip>Lock the screen now (even if &quot;Require Password&quot; is unchecked.)</tooltip>
+           <signal>
+             <name>activate</name>
+             <handler>lock_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 23:57:18 GMT</last_modification_time>
+           </signal>
+           <label>_Lock Screen Now</label>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>kill_menu</name>
+           <tooltip>Tell the running XScreenSaver daemon to exit.</tooltip>
+           <signal>
+             <name>activate</name>
+             <handler>kill_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 23:55:30 GMT</last_modification_time>
+           </signal>
+           <label>_Kill Daemon</label>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>restart</name>
+           <tooltip>Kill and re-launch the XScreenSaver daemon.</tooltip>
+           <signal>
+             <name>activate</name>
+             <handler>restart_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 23:54:28 GMT</last_modification_time>
+           </signal>
+           <label>_Restart Daemon</label>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>separator1</name>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>exit_menu</name>
+           <tooltip>Exit the xscreensaver-demo program (but leave the XScreenSaver daemon running in the background.)</tooltip>
+           <signal>
+             <name>activate</name>
+             <handler>exit_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 05:34:35 GMT</last_modification_time>
+           </signal>
+           <label>_Exit</label>
+           <right_justify>False</right_justify>
+         </widget>
+       </widget>
+      </widget>
+
+      <widget>
+       <class>GtkMenuItem</class>
+       <name>edit</name>
+       <stock_item>GNOMEUIINFO_MENU_EDIT_TREE</stock_item>
+
+       <widget>
+         <class>GtkMenu</class>
+         <name>edit_menu</name>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>cut_menu</name>
+           <signal>
+             <name>activate</name>
+             <handler>cut_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 05:34:40 GMT</last_modification_time>
+           </signal>
+           <label>C_ut</label>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>copy_menu</name>
+           <signal>
+             <name>activate</name>
+             <handler>copy_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 05:35:00 GMT</last_modification_time>
+           </signal>
+           <label>_Copy</label>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>paste_menu</name>
+           <signal>
+             <name>activate</name>
+             <handler>paste_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 05:35:16 GMT</last_modification_time>
+           </signal>
+           <label>_Paste</label>
+           <right_justify>False</right_justify>
+         </widget>
+       </widget>
+      </widget>
+
+      <widget>
+       <class>GtkMenuItem</class>
+       <name>help</name>
+       <stock_item>GNOMEUIINFO_MENU_HELP_TREE</stock_item>
+
+       <widget>
+         <class>GtkMenu</class>
+         <name>help_menu</name>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>about_menu</name>
+           <tooltip>Display version information.</tooltip>
+           <signal>
+             <name>activate</name>
+             <handler>about_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 05:35:41 GMT</last_modification_time>
+           </signal>
+           <label>_About...</label>
+           <right_justify>False</right_justify>
+         </widget>
+
+         <widget>
+           <class>GtkMenuItem</class>
+           <name>doc_menu</name>
+           <tooltip>Go to the documentation on the XScreenSaver web page.</tooltip>
+           <signal>
+             <name>activate</name>
+             <handler>doc_menu_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 04:58:51 GMT</last_modification_time>
+           </signal>
+           <label>_Documentation...</label>
+           <right_justify>False</right_justify>
+         </widget>
+       </widget>
+      </widget>
+    </widget>
+
+    <widget>
+      <class>GtkNotebook</class>
+      <name>notebook</name>
+      <can_focus>True</can_focus>
+      <show_tabs>True</show_tabs>
+      <show_border>True</show_border>
+      <tab_pos>GTK_POS_TOP</tab_pos>
+      <scrollable>False</scrollable>
+      <tab_hborder>2</tab_hborder>
+      <tab_vborder>2</tab_vborder>
+      <popup_enable>False</popup_enable>
+      <child>
+       <padding>0</padding>
+       <expand>True</expand>
+       <fill>True</fill>
+      </child>
+
+      <widget>
+       <class>GtkHBox</class>
+       <name>demos_hbox</name>
+       <homogeneous>False</homogeneous>
+       <spacing>5</spacing>
+
+       <widget>
+         <class>GtkVBox</class>
+         <name>list_vbox</name>
+         <border_width>10</border_width>
+         <homogeneous>False</homogeneous>
+         <spacing>5</spacing>
+         <child>
+           <padding>0</padding>
+           <expand>False</expand>
+           <fill>False</fill>
+         </child>
+
+         <widget>
+           <class>GtkScrolledWindow</class>
+           <name>scroller</name>
+           <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
+           <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
+           <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
+           <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
+           <child>
+             <padding>0</padding>
+             <expand>True</expand>
+             <fill>True</fill>
+           </child>
+
+           <widget>
+             <class>GtkViewport</class>
+             <name>viewport</name>
+             <border_width>1</border_width>
+             <shadow_type>GTK_SHADOW_IN</shadow_type>
+
+             <widget>
+               <class>GtkList</class>
+               <name>list</name>
+               <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
+             </widget>
+           </widget>
+         </widget>
+
+         <widget>
+           <class>GtkHBox</class>
+           <name>centering_hbox</name>
+           <homogeneous>True</homogeneous>
+           <spacing>0</spacing>
+           <child>
+             <padding>0</padding>
+             <expand>False</expand>
+             <fill>True</fill>
+           </child>
+
+           <widget>
+             <class>GtkHBox</class>
+             <name>next_prev_hbox</name>
+             <homogeneous>False</homogeneous>
+             <spacing>0</spacing>
+             <child>
+               <padding>0</padding>
+               <expand>False</expand>
+               <fill>False</fill>
+             </child>
+
+             <widget>
+               <class>GtkButton</class>
+               <name>next</name>
+               <tooltip>Run the next demo in this list in full-screen mode (click the mouse to return.)</tooltip>
+               <can_default>True</can_default>
+               <has_default>True</has_default>
+               <can_focus>True</can_focus>
+               <signal>
+                 <name>clicked</name>
+                 <handler>run_next_cb</handler>
+                 <last_modification_time>Mon, 08 Nov 1999 04:46:12 GMT</last_modification_time>
+               </signal>
+               <label>\/</label>
+               <child>
+                 <padding>0</padding>
+                 <expand>False</expand>
+                 <fill>False</fill>
+               </child>
+             </widget>
+
+             <widget>
+               <class>GtkButton</class>
+               <name>prev</name>
+               <tooltip>Run the previous demo in this list in full-screen mode (click the mouse to return.)</tooltip>
+               <can_default>True</can_default>
+               <can_focus>True</can_focus>
+               <signal>
+                 <name>clicked</name>
+                 <handler>run_prev_cb</handler>
+                 <last_modification_time>Wed, 10 Nov 1999 01:31:30 GMT</last_modification_time>
+               </signal>
+               <label>/\</label>
+               <child>
+                 <padding>0</padding>
+                 <expand>False</expand>
+                 <fill>False</fill>
+               </child>
+             </widget>
+           </widget>
+         </widget>
+       </widget>
+
+       <widget>
+         <class>GtkVBox</class>
+         <name>opts_vbox</name>
+         <border_width>10</border_width>
+         <homogeneous>False</homogeneous>
+         <spacing>0</spacing>
+         <child>
+           <padding>0</padding>
+           <expand>True</expand>
+           <fill>True</fill>
+         </child>
+
+         <widget>
+           <class>GtkFrame</class>
+           <name>frame</name>
+           <label_xalign>0</label_xalign>
+           <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
+           <child>
+             <padding>0</padding>
+             <expand>True</expand>
+             <fill>True</fill>
+           </child>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>doc</name>
+             <label></label>
+             <justify>GTK_JUSTIFY_LEFT</justify>
+             <wrap>True</wrap>
+             <xalign>0</xalign>
+             <yalign>0</yalign>
+             <xpad>10</xpad>
+             <ypad>10</ypad>
+           </widget>
+         </widget>
+
+         <widget>
+           <class>GtkVBox</class>
+           <name>opts_vbox2</name>
+           <homogeneous>False</homogeneous>
+           <spacing>2</spacing>
+           <child>
+             <padding>0</padding>
+             <expand>False</expand>
+             <fill>True</fill>
+           </child>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>cmd_label</name>
+             <label>Command Line:</label>
+             <justify>GTK_JUSTIFY_LEFT</justify>
+             <wrap>False</wrap>
+             <xalign>0</xalign>
+             <yalign>1</yalign>
+             <xpad>0</xpad>
+             <ypad>2</ypad>
+             <child>
+               <padding>0</padding>
+               <expand>False</expand>
+               <fill>False</fill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkEntry</class>
+             <name>cmd_text</name>
+             <can_focus>True</can_focus>
+             <editable>True</editable>
+             <text_visible>True</text_visible>
+             <text_max_length>0</text_max_length>
+             <text></text>
+             <child>
+               <padding>0</padding>
+               <expand>False</expand>
+               <fill>True</fill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkHBox</class>
+             <name>opts_hbox3</name>
+             <border_width>4</border_width>
+             <homogeneous>False</homogeneous>
+             <spacing>0</spacing>
+             <child>
+               <padding>4</padding>
+               <expand>False</expand>
+               <fill>True</fill>
+             </child>
+
+             <widget>
+               <class>GtkCheckButton</class>
+               <name>enabled</name>
+               <can_focus>True</can_focus>
+               <label>Enabled</label>
+               <active>True</active>
+               <draw_indicator>True</draw_indicator>
+               <child>
+                 <padding>0</padding>
+                 <expand>False</expand>
+                 <fill>False</fill>
+               </child>
+             </widget>
+
+             <widget>
+               <class>GtkLabel</class>
+               <name>visual</name>
+               <label>Visual:</label>
+               <justify>GTK_JUSTIFY_RIGHT</justify>
+               <wrap>False</wrap>
+               <xalign>1</xalign>
+               <yalign>0.5</yalign>
+               <xpad>10</xpad>
+               <ypad>0</ypad>
+               <child>
+                 <padding>0</padding>
+                 <expand>False</expand>
+                 <fill>False</fill>
+               </child>
+             </widget>
+
+             <widget>
+               <class>GtkCombo</class>
+               <name>visual_combo</name>
+               <value_in_list>False</value_in_list>
+               <ok_if_empty>True</ok_if_empty>
+               <case_sensitive>False</case_sensitive>
+               <use_arrows>True</use_arrows>
+               <use_arrows_always>False</use_arrows_always>
+               <items>Any
+Best
+Default
+Default-N
+GL
+TrueColor
+PseudoColor
+StaticGray
+GrayScale
+DirectColor
+Color
+Gray
+Mono
+</items>
+               <child>
+                 <padding>0</padding>
+                 <expand>False</expand>
+                 <fill>False</fill>
+               </child>
+
+               <widget>
+                 <class>GtkEntry</class>
+                 <child_name>GtkCombo:entry</child_name>
+                 <name>combo-entry1</name>
+                 <tooltip>The X visual type that this demo will require.  If that visual is available it will be used, otherwise, this demo will not be run.</tooltip>
+                 <can_focus>True</can_focus>
+                 <editable>True</editable>
+                 <text_visible>True</text_visible>
+                 <text_max_length>0</text_max_length>
+                 <text>Any</text>
+               </widget>
+             </widget>
+           </widget>
+         </widget>
+
+         <widget>
+           <class>GtkHSeparator</class>
+           <name>demo_hline</name>
+           <child>
+             <padding>5</padding>
+             <expand>False</expand>
+             <fill>False</fill>
+           </child>
+         </widget>
+
+         <widget>
+           <class>GtkHButtonBox</class>
+           <name>demo_cancel_hbox</name>
+           <layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
+           <spacing>30</spacing>
+           <child_min_width>85</child_min_width>
+           <child_min_height>27</child_min_height>
+           <child_ipad_x>7</child_ipad_x>
+           <child_ipad_y>0</child_ipad_y>
+           <child>
+             <padding>0</padding>
+             <expand>False</expand>
+             <fill>True</fill>
+           </child>
+
+           <widget>
+             <class>GtkButton</class>
+             <name>demo</name>
+             <tooltip>Make any changes to this demo's parameters permanent, and run it in full-screen mode (click the mouse to return.)</tooltip>
+             <can_default>True</can_default>
+             <can_focus>True</can_focus>
+             <signal>
+               <name>clicked</name>
+               <handler>run_this_cb</handler>
+               <last_modification_time>Mon, 08 Nov 1999 04:46:40 GMT</last_modification_time>
+             </signal>
+             <label>Demo</label>
+           </widget>
+
+           <widget>
+             <class>GtkButton</class>
+             <name>apply</name>
+             <tooltip>Make any changes to this demo's parameters permanent.</tooltip>
+             <can_default>True</can_default>
+             <can_focus>True</can_focus>
+             <signal>
+               <name>clicked</name>
+               <handler>apply_this_cb</handler>
+               <last_modification_time>Mon, 08 Nov 1999 04:46:59 GMT</last_modification_time>
+             </signal>
+             <label>Apply</label>
+           </widget>
+
+           <widget>
+             <class>GtkButton</class>
+             <name>cancel</name>
+             <tooltip>Discard any changes you have made to this demo's parameters.</tooltip>
+             <can_default>True</can_default>
+             <can_focus>True</can_focus>
+             <signal>
+               <name>clicked</name>
+               <handler>cancel_this_cb</handler>
+               <last_modification_time>Mon, 08 Nov 1999 04:47:15 GMT</last_modification_time>
+             </signal>
+             <label>Cancel</label>
+           </widget>
+         </widget>
+       </widget>
+      </widget>
+
+      <widget>
+       <class>GtkLabel</class>
+       <child_name>Notebook:tab</child_name>
+       <name>demo_tab</name>
+       <label>Graphics Demos</label>
+       <justify>GTK_JUSTIFY_CENTER</justify>
+       <wrap>False</wrap>
+       <xalign>0.5</xalign>
+       <yalign>0.5</yalign>
+       <xpad>0</xpad>
+       <ypad>0</ypad>
+      </widget>
+
+      <widget>
+       <class>GtkVBox</class>
+       <name>prefs_hbox</name>
+       <homogeneous>False</homogeneous>
+       <spacing>0</spacing>
+
+       <widget>
+         <class>GtkFrame</class>
+         <name>prefs_frame</name>
+         <border_width>10</border_width>
+         <label_xalign>0</label_xalign>
+         <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
+         <child>
+           <padding>0</padding>
+           <expand>True</expand>
+           <fill>True</fill>
+         </child>
+
+         <widget>
+           <class>GtkTable</class>
+           <name>prefs_table</name>
+           <border_width>10</border_width>
+           <rows>6</rows>
+           <columns>3</columns>
+           <homogeneous>False</homogeneous>
+           <row_spacing>2</row_spacing>
+           <column_spacing>10</column_spacing>
+
+           <widget>
+             <class>GtkEntry</class>
+             <name>timeout_text</name>
+             <tooltip>How long until the screensaver activates.</tooltip>
+             <can_focus>True</can_focus>
+             <editable>True</editable>
+             <text_visible>True</text_visible>
+             <text_max_length>8</text_max_length>
+             <text></text>
+             <child>
+               <left_attach>1</left_attach>
+               <right_attach>2</right_attach>
+               <top_attach>0</top_attach>
+               <bottom_attach>1</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkEntry</class>
+             <name>cycle_text</name>
+             <tooltip>How long each demo will be run before moving on to another.</tooltip>
+             <can_focus>True</can_focus>
+             <editable>True</editable>
+             <text_visible>True</text_visible>
+             <text_max_length>8</text_max_length>
+             <text></text>
+             <child>
+               <left_attach>1</left_attach>
+               <right_attach>2</right_attach>
+               <top_attach>1</top_attach>
+               <bottom_attach>2</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkEntry</class>
+             <name>fade_text</name>
+             <tooltip>How long (in seconds) it should take for the screen to fade to black (8-bit displays only.)</tooltip>
+             <can_focus>True</can_focus>
+             <editable>True</editable>
+             <text_visible>True</text_visible>
+             <text_max_length>8</text_max_length>
+             <text></text>
+             <child>
+               <left_attach>1</left_attach>
+               <right_attach>2</right_attach>
+               <top_attach>2</top_attach>
+               <bottom_attach>3</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkEntry</class>
+             <name>ticks_text</name>
+             <tooltip>How many steps are in the fade animation (8-bit displays only.)</tooltip>
+             <can_focus>True</can_focus>
+             <editable>True</editable>
+             <text_visible>True</text_visible>
+             <text_max_length>8</text_max_length>
+             <text></text>
+             <child>
+               <left_attach>1</left_attach>
+               <right_attach>2</right_attach>
+               <top_attach>3</top_attach>
+               <bottom_attach>4</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkEntry</class>
+             <name>lock_text</name>
+             <tooltip>How long after the screensaver has activated until a password will be required (if  `Require Password' is also set.)</tooltip>
+             <can_focus>True</can_focus>
+             <editable>True</editable>
+             <text_visible>True</text_visible>
+             <text_max_length>8</text_max_length>
+             <text></text>
+             <child>
+               <left_attach>1</left_attach>
+               <right_attach>2</right_attach>
+               <top_attach>4</top_attach>
+               <bottom_attach>5</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkEntry</class>
+             <name>pass_text</name>
+             <tooltip>How long the password dialog will wait.</tooltip>
+             <can_focus>True</can_focus>
+             <editable>True</editable>
+             <text_visible>True</text_visible>
+             <text_max_length>8</text_max_length>
+             <text></text>
+             <child>
+               <left_attach>1</left_attach>
+               <right_attach>2</right_attach>
+               <top_attach>5</top_attach>
+               <bottom_attach>6</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>timeout_label</name>
+             <label>Saver Timeout:</label>
+             <justify>GTK_JUSTIFY_RIGHT</justify>
+             <wrap>False</wrap>
+             <xalign>1</xalign>
+             <yalign>0.5</yalign>
+             <xpad>0</xpad>
+             <ypad>0</ypad>
+             <child>
+               <left_attach>0</left_attach>
+               <right_attach>1</right_attach>
+               <top_attach>0</top_attach>
+               <bottom_attach>1</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>cycle_label</name>
+             <label>Cycle Timeout:</label>
+             <justify>GTK_JUSTIFY_RIGHT</justify>
+             <wrap>False</wrap>
+             <xalign>1</xalign>
+             <yalign>0.5</yalign>
+             <xpad>0</xpad>
+             <ypad>0</ypad>
+             <child>
+               <left_attach>0</left_attach>
+               <right_attach>1</right_attach>
+               <top_attach>1</top_attach>
+               <bottom_attach>2</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>fade_label</name>
+             <label>Fade Duration:</label>
+             <justify>GTK_JUSTIFY_RIGHT</justify>
+             <wrap>False</wrap>
+             <xalign>1</xalign>
+             <yalign>0.5</yalign>
+             <xpad>0</xpad>
+             <ypad>0</ypad>
+             <child>
+               <left_attach>0</left_attach>
+               <right_attach>1</right_attach>
+               <top_attach>2</top_attach>
+               <bottom_attach>3</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>ticks_label</name>
+             <label>Fade Ticks:</label>
+             <justify>GTK_JUSTIFY_RIGHT</justify>
+             <wrap>False</wrap>
+             <xalign>1</xalign>
+             <yalign>0.5</yalign>
+             <xpad>0</xpad>
+             <ypad>0</ypad>
+             <child>
+               <left_attach>0</left_attach>
+               <right_attach>1</right_attach>
+               <top_attach>3</top_attach>
+               <bottom_attach>4</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>lock_label</name>
+             <label>Lock Timeout:</label>
+             <justify>GTK_JUSTIFY_RIGHT</justify>
+             <wrap>False</wrap>
+             <xalign>1</xalign>
+             <yalign>0.5</yalign>
+             <xpad>0</xpad>
+             <ypad>0</ypad>
+             <child>
+               <left_attach>0</left_attach>
+               <right_attach>1</right_attach>
+               <top_attach>4</top_attach>
+               <bottom_attach>5</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkLabel</class>
+             <name>pass_label</name>
+             <label>Password Timeout:</label>
+             <justify>GTK_JUSTIFY_RIGHT</justify>
+             <wrap>False</wrap>
+             <xalign>1</xalign>
+             <yalign>0.5</yalign>
+             <xpad>0</xpad>
+             <ypad>0</ypad>
+             <child>
+               <left_attach>0</left_attach>
+               <right_attach>1</right_attach>
+               <top_attach>5</top_attach>
+               <bottom_attach>6</bottom_attach>
+               <xpad>0</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkCheckButton</class>
+             <name>verbose_button</name>
+             <can_focus>True</can_focus>
+             <label>Verbose</label>
+             <active>False</active>
+             <draw_indicator>True</draw_indicator>
+             <child>
+               <left_attach>2</left_attach>
+               <right_attach>3</right_attach>
+               <top_attach>0</top_attach>
+               <bottom_attach>1</bottom_attach>
+               <xpad>10</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkCheckButton</class>
+             <name>install_button</name>
+             <can_focus>True</can_focus>
+             <label>Install Colormap</label>
+             <active>False</active>
+             <draw_indicator>True</draw_indicator>
+             <child>
+               <left_attach>2</left_attach>
+               <right_attach>3</right_attach>
+               <top_attach>1</top_attach>
+               <bottom_attach>2</bottom_attach>
+               <xpad>10</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkCheckButton</class>
+             <name>fade_button</name>
+             <can_focus>True</can_focus>
+             <label>Fade Colormap</label>
+             <active>False</active>
+             <draw_indicator>True</draw_indicator>
+             <child>
+               <left_attach>2</left_attach>
+               <right_attach>3</right_attach>
+               <top_attach>2</top_attach>
+               <bottom_attach>3</bottom_attach>
+               <xpad>10</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkCheckButton</class>
+             <name>unfade_button</name>
+             <can_focus>True</can_focus>
+             <label>Unfade Colormap</label>
+             <active>False</active>
+             <draw_indicator>True</draw_indicator>
+             <child>
+               <left_attach>2</left_attach>
+               <right_attach>3</right_attach>
+               <top_attach>3</top_attach>
+               <bottom_attach>4</bottom_attach>
+               <xpad>10</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+
+           <widget>
+             <class>GtkCheckButton</class>
+             <name>lock_button</name>
+             <can_focus>True</can_focus>
+             <label>Require Password</label>
+             <active>False</active>
+             <draw_indicator>True</draw_indicator>
+             <child>
+               <left_attach>2</left_attach>
+               <right_attach>3</right_attach>
+               <top_attach>4</top_attach>
+               <bottom_attach>5</bottom_attach>
+               <xpad>10</xpad>
+               <ypad>0</ypad>
+               <xexpand>False</xexpand>
+               <yexpand>False</yexpand>
+               <xshrink>False</xshrink>
+               <yshrink>False</yshrink>
+               <xfill>True</xfill>
+               <yfill>False</yfill>
+             </child>
+           </widget>
+         </widget>
+       </widget>
+
+       <widget>
+         <class>GtkHButtonBox</class>
+         <name>hbuttonbox3</name>
+         <border_width>10</border_width>
+         <layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
+         <spacing>30</spacing>
+         <child_min_width>85</child_min_width>
+         <child_min_height>27</child_min_height>
+         <child_ipad_x>7</child_ipad_x>
+         <child_ipad_y>0</child_ipad_y>
+         <child>
+           <padding>0</padding>
+           <expand>False</expand>
+           <fill>False</fill>
+         </child>
+
+         <widget>
+           <class>GtkButton</class>
+           <name>prefs_ok</name>
+           <can_default>True</can_default>
+           <can_focus>True</can_focus>
+           <signal>
+             <name>clicked</name>
+             <handler>prefs_ok_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 04:39:18 GMT</last_modification_time>
+           </signal>
+           <label>OK</label>
+         </widget>
+
+         <widget>
+           <class>GtkButton</class>
+           <name>prefs_cancel</name>
+           <can_default>True</can_default>
+           <can_focus>True</can_focus>
+           <signal>
+             <name>clicked</name>
+             <handler>prefs_cancel_cb</handler>
+             <last_modification_time>Mon, 08 Nov 1999 04:39:33 GMT</last_modification_time>
+           </signal>
+           <label>Cancel</label>
+         </widget>
+       </widget>
+      </widget>
+
+      <widget>
+       <class>GtkLabel</class>
+       <child_name>Notebook:tab</child_name>
+       <name>prefs_tab</name>
+       <label>Screensaver Options</label>
+       <justify>GTK_JUSTIFY_CENTER</justify>
+       <wrap>False</wrap>
+       <xalign>0.5</xalign>
+       <yalign>0.5</yalign>
+       <xpad>0</xpad>
+       <ypad>0</ypad>
+      </widget>
+    </widget>
+  </widget>
+</widget>
+
+</GTK-Interface>
index 3a89d4deab4f37e9173f74a33d90c634d98531fd..e087b12c368bf2d1de5693f3cf99784d60c7a1f4 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "30-Oct-99 (3.19)" "X Version 11"
+.TH XScreenSaver 1 "12-Nov-99 (3.20)" "X Version 11"
 .SH NAME
 xscreensaver-demo - interactively control the background xscreensaver daemon
 .SH SYNOPSIS
@@ -26,113 +26,168 @@ It is essentially two things: a tool for editing the \fI~/.xscreensaver\fP
 file; and a tool for demoing the various graphics hacks that 
 the \fIxscreensaver\fP daemon will launch.
 
-The main dialog box contains a scrolling list, a text field, and a number 
-of buttons.  
+.B Note:
+this manual describes the Gtk version of the \fIxscreensaver\-demo\fP
+command.  The UI of the Motif and Athena versions of \fIxscreensaver\-demo\fP
+is a bit different (for now.)
 
-Double-clicking on one of the programs in the list will run it.  The screen
-will go black, and the program will run in full-screen mode, just as it would
-if the \fIxscreensaver\fP daemon had launched it.  Clicking the mouse again
-will stop the demo and un-blank the screen, making the dialog box visible 
-again.
+The main window consists of a menu bar and two tabbed pages.  The first page
+is for editing the list of demos, and the second is for editing various other
+parameters of the screensaver.
+.SH MENU COMMANDS
+All of these commands are on either the \fBFile\fP or \fBHelp\fP menus:
+.TP 4
+.B Blank Screen Now
+Activates the background \fIxscreensaver\fP daemon, which will then run
+a demo at random.  This is the same as running
+.BR xscreensaver-command (1)
+with the \fI\-activate\fP option.
+.TP 4
+.B Lock Screen Now
+Just like \fBBlank Screen Now\fP, except the screen will be locked as 
+well (even if it is not configured to lock all the time.)  This is the
+same as running
+.BR xscreensaver-command (1)
+with the \fI\-lock\fP option.
+.TP 4
+.B Kill Daemon
+If the xscreensaver daemon is running on this screen, kill it.
+This is the same as running
+.BR xscreensaver-command (1)
+with the \fI\-exit\fP option.
+.TP 4
+.B Restart Daemon
+If the xscreensaver daemon is running on this screen, kill it.
+Then launch it again.  This is the same as doing
+``\fIxscreensaver-command -exit\fP'' followed by ``\fIxscreensaver\fP''.
 
-Single-clicking in the list will place the indicated program and its args
-in the text field to be edited.  Edit the arguments and hit return to run
-the program with the parameters you have specified.  This will also save
-your changes to your \fI~/.xscreensaver\fP file: so any changes you make
-in this way are persistent.
-
-If one of the lines in the scrolling list begins with the character "-",
-then that means that the program is disabled: \fIxscreensaver\fP will not
-select it to be run (though you can still try it out by clicking on it.)
-Rather than just deleting the programs you don't want to run, you might
-want to disable them in this way instead, so that you can more easily change
-your mind later.
+Note that it is \fInot\fP the same as doing
+``\fIxscreensaver-command -restart\fP''.
+.TP 4
+.B Exit
+Exits the \fIxscreensaver-demo\fP program (this program) without
+affecting the background \fIxscreensaver\fP daemon, if any.
+.TP 4
+.B About...
+Displays the version number of this program, \fIxscreensaver-demo\fP.
+.TP 4
+.B Documentation...
+Opens up a web browser looking at the XScreenSaver web page, where you
+can find online copies of the
+.BR xscreensaver (1),
+.BR xscreensaver\-demo (1),
+and
+.BR xscreensaver\-command (1)
+manuals.
+.SH GRAPHICS DEMOS TAB
+On the left is a list of the names of the various display modes, and
+on the right are some fields that let you edit their behavior.
+.TP 4
+.B Demo List
+Double-clicking in the list on the left will let you try out the indicated
+demo.  The screen will go black, and the program will run in full-screen
+mode, just as it would if the \fIxscreensaver\fP daemon had launched it.
+Clicking the mouse again will stop the demo and un-blank the screen, making
+the dialog box visible again.
 
-If the line begins with the name of a visual, followed by a colon, then
-that program will only be run on that kind of visual.  For example, you can
+Single-clicking in the list will populate the fields on the right side of
+the window.
+.TP 4
+.B Arrow Buttons
+Beneath the list are a pair of up and down arrows. Clicking on the down 
+arrow will select the next item in the list, and then run it in full-screen
+mode, just as if you had double-clicked on it.  The up arrow goes the other
+way.  This is just a shortcut for trying out all of the display modes in turn.
+.TP 4
+.B Program Description
+At the top will be a brief description of the program.  Below that is a
+text field where you can edit the arguments to the program as xscreensaver
+will invoke it.  (Note that most of these programs have their own man pages
+that describe the command-line options they take.)
+.TP 4
+.B Enabled
+The \fIEnabled\fI checkbox controls whether xscreensaver will use this
+display mode at all.  This way, all the modes can remain available, but
+you can choose which ones will be automatically run.
+.TP 4
+.B Visual
+The \fIVisual\fI field is where you can select the X visual type that this
+demo will require.  If you specify one (other than \fIAny\fP) then the
+program will only be run on that kind of visual.  For example, you can
 specify that a particular program should only be run if color is available,
-and another should only be run in monochrome.  See the discussion of 
-the \fIprograms\fP parameter in the \fIConfiguration\fP section of the
+and another should only be run in monochrome.  See the discussion of the
+\fIprograms\fP parameter in the \fIConfiguration\fP section of the
 .BR xscreensaver (1)
 manual.
 
-The buttons are:
-.TP 8
-.B Run Next
-Clicking this button will run the next program in the list after the 
-currently-selected one, and will wrap around to the top when it reaches
-the bottom.
-.TP 8
-.B Run Previous
-Opposite of Run Next; at the top, it wraps around to the bottom.
-.TP 8
-.B Preferences
-This pops up a second dialog box, in which you have the option to 
-interactively change most of the screensaver's operational parameters,
-such as its timeouts, and whether it should lock the screen.  When you
-click OK, your chosen settings will take effect immediately, and will
-also be saved to the \fI~/.xscreensaver\fP file in your home directory,
-so that the settings will persist next time.
-.TP 8
-.B Quit
-Exits the \fIxscreensaver-demo\fP program.  The background \fIxscreensaver\fP
-daemon will continue running as before.
-.P
-The Preferences dialog box lets you change the following settings.
-
-(There are more settings available, but these are the most commonly used
-ones; see the manual for
+This is a combo-box, so you can either select an item from the popup menu,
+or type in a specific visual's hexadecimal ID.
+.TP 4
+.B Demo
+This button saves your changes and runs the demo in full-screen mode so
+that you can try it out.  Click the mouse to dismiss it.
+.TP 4
+.B Apply
+This button saves your changes to your \fI~/.xscreensaver\fP file,
+where the
 .BR xscreensaver (1)
-for other parameters that can be set by editing the \fI~/.xscreensaver\fP
-file, or the X resource database.)
-.TP 8
+can see them.
+.TP 4
+.B Cancel
+This button discards any unsaved changes you have made, and reverts the
+settings for the selected demo back to what they were before.  Note that
+once you hit \fIDemo\fP or \fIApply\fP, that's it!
+.SH SCREENSAVER OPTIONS TAB
+This tab lets you change various settings used by the xscreensaver daemon
+itself, rather than its sub-programs.
+.TP 4
 .B Saver Timeout
 After the user has been idle this long, the \fIxscreensaver\fP daemon
 will blank the screen.
-.TP 8
+.TP 4
 .B Cycle Timeout
 After the screensaver has been running for this long, the currently
 running graphics demo will be killed, and a new one started.  
 If this is 0, then the graphics demo will never be changed:
 only one demo will run until the screensaver is deactivated by user 
 activity.
-.TP 8
+.TP 4
 .B Verbose\ 
 Whether to print lots of debugging information.
-.TP 8
+.TP 4
 .B Install Colormap
 Whether to install a private colormap while the screensaver is active, so
 that the graphics hacks can get as many colors as possible.  (This only
 applies when the screen's default visual is being used, since non-default
 visuals get their own colormaps automatically.)  This can also be overridden
 on a per-demo basis.
-.TP 8
+.TP 4
 .B Fade Colormap
 If selected, then when the screensaver activates, the current contents
 of the screen will fade to black instead of simply winking out.  This only
 works on displays with writable colormaps, that is, if the screen's default
 visual is a PseudoColor visual.  A fade will also be done when
 switching graphics hacks (when the \fICycle Timeout\fP expires.)
-.TP 8
+.TP 4
 .B Unfade Colormap
 The complement to \fIFade Colormap\fP: if selected, then when the screensaver
 deactivates, the original contents of the screen will fade in from black
 instead of appearing immediately.  This only works on displays with writable
 colormaps, and when \fIFade Colormap\fP is also selected.
-.TP 8
+.TP 4
 .B Fade Duration
 When fading or unfading are selected, this controls how long the fade will
 take.
-.TP 8
+.TP 4
 .B Fade Ticks
 This controls how many times a second the colormap will be changed to 
 effect a fade.  Higher numbers yield smoother fades, but may make the
 fades take longer than the specified number of seconds, if your server
 isn't fast enough to keep up.
-.TP 8
+.TP 4
 .B Require Password
 Whether the screen saver should lock the screen when it activates.
-.TP 8
+.TP 4
 .B Lock Timeout
 If \fIRequire Password\fP is selected, this controls the length of 
 the ``grace period'' between when the screensaver activates, and when the
@@ -144,11 +199,17 @@ at 15 minutes or later (that is, \fILock Timeout\fP minutes after
 activation) then a password would be required.  The default is 0, meaning
 that if locking is enabled, then a password will be required as soon as the 
 screen blanks.
-.TP 8
+.TP 4
 .B Password Timeout
 When the screensaver is prompting for a password, the prompt dialog box will
 stay on the screen for this long before giving up, and reverting to 
 screen-saving mode.
+.PP
+There are more settings than these available, but these are the most 
+commonly used ones; see the manual for
+.BR xscreensaver (1)
+for other parameters that can be set by editing the \fI~/.xscreensaver\fP
+file, or the X resource database.
 .SH COMMAND-LINE OPTIONS
 .I xscreensaver\-demo
 accepts the following command line options.
@@ -159,8 +220,8 @@ window on that display, and also control the \fIxscreensaver\fP daemon that
 is managing that same display.
 .TP 8
 .B \-prefs
-Start up in Preferences mode: this is just like launching the program with
-no arguments, and then pressing the \fIPreferences\fP button.
+Start up with the \fBScreensaver Options\fP tab selected by default
+instead of the \fBGraphics Demos\fP tab.
 .P
 It is important that the \fIxscreensaver\fP and \fIxscreensaver\-demo\fP
 processes be running on the same machine, or at least, on two machines
index c37cf32602e1c892f2139d143ad14ebffb6f46f8..fc8b89a47e4cd542f838f0e1636503b19b5abc54 100644 (file)
@@ -163,9 +163,9 @@ XrmDatabase db = 0;
 
 static Atom XA_SCREENSAVER_RESPONSE;
 static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV;
-static Atom XA_EXIT, XA_RESTART, XA_LOCK, XA_SELECT;
+static Atom XA_RESTART, XA_SELECT;
 static Atom XA_THROTTLE, XA_UNTHROTTLE;
-Atom XA_DEMO, XA_PREFS;
+Atom XA_DEMO, XA_PREFS, XA_EXIT, XA_LOCK, XA_BLANK;
 
 \f
 static XrmOptionDescRec options [] = {
@@ -315,16 +315,17 @@ saver_ehandler (Display *dpy, XErrorEvent *error)
                    "#######################################"
                    "#######################################\n\n");
           fprintf (real_stderr,
-   "    If at all possible, please re-run xscreensaver with the command line\n"
-   "    arguments `-sync -verbose', and reproduce this bug.  That will cause\n"
-   "    xscreensaver to dump a `core' file to the current directory.  Please\n"
-   "    include the stack trace from that core file in your bug report.\n"
-   "    Do NOT mail the core file itself!  That won't work.\n"
+   "    If at all possible, please re-run xscreensaver with the command\ e\n"
+   "    line arguments `-sync -verbose -no-capture', and reproduce this\n"
+   "    bug.  That will cause xscreensaver to dump a `core' file to the\n"
+   "    current directory.  Please include the stack trace from that core\n"
+   "    file in your bug report.  *DO NOT* mail the core file itself!\n"
+   "    That won't work.\n"
    "\n"
-   "    http://www.jwz.org/xscreensaver/bugs.html explains how to create the\n"
-   "    most useful bug reports, and how to examine core files.\n"
+   "    http://www.jwz.org/xscreensaver/bugs.html explains how to create\n"
+   "    the most useful bug reports, and how to examine core files.\n"
    "\n"
-   "    The more information you can provide, the better.  But please report\n"
+   "    The more information you can provide, the better.  But please\n"
    "    report this bug, regardless!\n"
    "\n");
           fprintf (real_stderr,
@@ -370,12 +371,13 @@ startup_ehandler (String name, String type, String class,
 
   describe_uids (si, stderr);
   fprintf (stderr, "\n"
-           "%s: Errors at startup are usually authorization problems.\n"
-           "              Did you read the manual?  Specifically, the parts\n"
-           "              that talk about XAUTH, XDM, and root logins?\n"
-           "\n"
-           "              http://www.jwz.org/xscreensaver/man.html\n"
-           "\n",
+          "%s: Errors at startup are usually authorization problems.\n"
+          "              Did you read the manual and the FAQ?  Specifically,\n"
+          "              the parts of the manual that talk about XAUTH, XDM,\n"
+          "              and root logins?\n"
+          "\n"
+          "              http://www.jwz.org/xscreensaver/man.html\n"
+          "\n",
            blurb());
 
   fflush (stderr);
@@ -481,7 +483,7 @@ connect_to_server (saver_info *si, int *argc, char **argv)
   XA_SCREENSAVER = XInternAtom (si->dpy, "SCREENSAVER", False);
   XA_SCREENSAVER_VERSION = XInternAtom (si->dpy, "_SCREENSAVER_VERSION",False);
   XA_SCREENSAVER_ID = XInternAtom (si->dpy, "_SCREENSAVER_ID", False);
-  XA_SCREENSAVER_TIME = XInternAtom (si->dpy, "_SCREENSAVER_TIME", False);
+  XA_SCREENSAVER_STATUS = XInternAtom (si->dpy, "_SCREENSAVER_STATUS", False);
   XA_SCREENSAVER_RESPONSE = XInternAtom (si->dpy, "_SCREENSAVER_RESPONSE",
                                         False);
   XA_XSETROOT_ID = XInternAtom (si->dpy, "_XSETROOT_ID", False);
@@ -496,6 +498,7 @@ connect_to_server (saver_info *si, int *argc, char **argv)
   XA_DEMO = XInternAtom (si->dpy, "DEMO", False);
   XA_PREFS = XInternAtom (si->dpy, "PREFS", False);
   XA_LOCK = XInternAtom (si->dpy, "LOCK", False);
+  XA_BLANK = XInternAtom (si->dpy, "BLANK", False);
   XA_THROTTLE = XInternAtom (si->dpy, "THROTTLE", False);
   XA_UNTHROTTLE = XInternAtom (si->dpy, "UNTHROTTLE", False);
 
@@ -1085,7 +1088,10 @@ main (int argc, char **argv)
 
   if (p->verbose_p) analyze_display (si);
   initialize_server_extensions (si);
+
+  si->blank_time = time ((time_t) 0); /* must be before ..._window */
   initialize_screensaver_window (si);
+
   select_events (si);
   init_sigchld ();
   disable_builtin_screensaver (si, True);
index 58f5214efb6319bcf572d8365a4c0189369badbb..cd797d47593ae07d3f2b57a4c9e309da5bf12c88 100644 (file)
@@ -87,6 +87,9 @@ struct saver_info {
   Bool fading_possible_p;      /* Whether fading to/from black is possible. */
   Bool throttled_p;             /* Whether we should temporarily just blank
                                    the screen, not run hacks. */
+  time_t blank_time;           /* The time at which the screen was blanked
+                                   (if currently blanked) or unblanked (if
+                                   not blanked.) */
 
 
   /* =======================================================================
@@ -371,6 +374,7 @@ extern void suspend_screenhack (saver_info *si, Bool suspend_p);
 extern Bool screenhack_running_p (saver_info *si);
 extern void emergency_kill_subproc (saver_info *si);
 extern Bool select_visual (saver_screen_info *ssi, const char *visual_name);
+extern void store_saver_status (saver_info *si);
 extern const char *signal_name (int signal);
 
 /* =======================================================================
@@ -401,7 +405,7 @@ extern Bool display_is_on_console_p (saver_info *si);
 
 extern Atom XA_VROOT, XA_XSETROOT_ID;
 extern Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID;
-extern Atom XA_SCREENSAVER_TIME;
+extern Atom XA_SCREENSAVER_STATUS, XA_LOCK, XA_BLANK;
 extern Atom XA_DEMO, XA_PREFS;
 
 #endif /* __XSCREENSAVER_H__ */
index 03ae437403c34abc00b3044da1b58930193528f0..013aff223fc6364fabcaed62610b7e4d12aa0a6c 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "30-Oct-99 (3.19)" "X Version 11"
+.TH XScreenSaver 1 "12-Nov-99 (3.20)" "X Version 11"
 .SH NAME
 xscreensaver - graphics hack and screen locker, launched when the user is idle
 .SH SYNOPSIS
@@ -876,7 +876,48 @@ popup menu.  Alternately, you could just put the xscreensaver menu items
 directly into the root menu.
 .RE
 
-Other window managers are guaranteed to do things gratuitously differently.
+For Fvwm2, the process is similar: first create a \fI~/.fvwm2rc\fP file
+if you don't already have one, by making a copy of
+the \fI/etc/X11/fvwm2/system.fvwm2rc\fP file.  Then, add a menu definition
+to it:
+.EX
+AddToMenu XScreenSaver "XScreenSaver" Title
++ "Blank Screen Now"          Exec xscreensaver-command -activate
++ "Lock Screen Now"           Exec xscreensaver-command -lock
++ "Screen Saver Demo"         Exec xscreensaver-command -demo
++ "Screen Saver Preferences"  Exec xscreensaver-command -prefs
++ "Reinitialize Screen Saver" Exec xscreensaver-command -restart
++ "Kill Screen Saver"         Exec xscreensaver-command -exit
++ "Launch Screen Saver"       Exec xscreensaver
++ "Run Next Demo"             Exec xscreensaver-command -next
++ "Run Previous Demo"         Exec xscreensaver-command -prev
+
+# To put the XScreenSaver sub-menu at the end of the root menu:
+AddToMenu RootMenu "XScreenSaver" Popup XScreenSaver
+.EE
+The Enlightenment window manager keeps each of its menus in a separate
+file. So, you need to create a file 
+named \fI~/.enlightenment/xscreensaver.menu\fP with the contents:
+.EX
+"XScreenSaver Commands"
+ "Blank Screen Now"    NULL exec "xscreensaver-command -activate"
+ "Lock Screen Now"     NULL exec "xscreensaver-command -lock"
+ "Screen Saver Demo"   NULL exec "xscreensaver-command -demo"
+ "Screen Saver Prefs"  NULL exec "xscreensaver-command -prefs"
+ "Reinitialize Saver"  NULL exec "xscreensaver-command -restart"
+ "Kill Screen Saver"   NULL exec "xscreensaver-command -exit"
+ "Launch Screen Saver" NULL exec "xscreensaver"
+.EE
+then add
+.EX
+ "XScreenSaver"        NULL menu "xscreensaver.menu"
+.EE
+to \fI~/.enlightenment/file.menu\fP to put the XScreenSaver submenu on 
+your left-button root-window menu.
+
+As you see, every window manager does this stuff gratuitously differently,
+just to make your life difficult.  You are in a maze of twisty menu
+configuration languages, all alike.
 .SH BUGS
 Bugs?  There are no bugs.  Ok, well, maybe.  If you find one, please let
 me know.  http://www.jwz.org/xscreensaver/bugs.html explains how to
index 2e167c1468dd6e463aa6c1ebb22d5fe0ade146c6..6dabdb2d156f9f3942ed070abbce2358f23a64ca 100644 (file)
@@ -223,7 +223,9 @@ disable_builtin_screensaver (saver_info *si, Bool unblank_screen_p)
       desired_prefer_blank != current_prefer_blank ||
       desired_allow_exp != current_allow_exp)
     {
-      if (unblank_screen_p)
+      if (p->verbose_p && unblank_screen_p)
+        /* Used to print this all the time, but really, nobody cares.
+           Now only print it when verbose. */
        fprintf (stderr,
                 "%s disabling server builtin screensaver.\n"
                 "%s: you can re-enable it with \"xset s on\".\n",
index c4a45bacdd5cb1756b61e1f081f6e129576e4460..72b8b52b6aa463bacd332f0c367c12cfae4040cb 100644 (file)
@@ -85,7 +85,7 @@ SRCS          = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
                  sonar.c demon.c loop.c t3d.c penetrate.c deluxe.c compass.c \
                  squiral.c xflame.c wander.c spotlight.c critical.c \
                  phosphor.c xmatrix.c petri.c shadebobs.c xsublim.c ccurve.c \
-                 blaster.c bumps.c
+                 blaster.c bumps.c ripples.c
 SCRIPTS                = vidwhacker webcollage
 
 OBJS           = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
@@ -104,7 +104,7 @@ OBJS                = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  sonar.o demon.o loop.o t3d.o penetrate.o deluxe.o compass.o \
                  squiral.o xflame.o wander.o spotlight.o critical.o \
                  phosphor.o xmatrix.o petri.o shadebobs.o xsublim.o ccurve.o \
-                 blaster.o bumps.o
+                 blaster.o bumps.o ripples.o
 
 EXES           = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
@@ -117,7 +117,7 @@ EXES                = attraction blitspin bouboule braid bubbles decayscreen deco \
                  interference truchet bsod crystal discrete distort kumppa \
                  sonar demon loop t3d penetrate deluxe compass squiral \
                  xflame wander spotlight critical phosphor xmatrix petri \
-                 shadebobs xsublim ccurve blaster bumps
+                 shadebobs xsublim ccurve blaster bumps ripples
 
 HACK_OBJS_1    = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
@@ -544,9 +544,12 @@ ccurve:            ccurve.o        $(HACK_OBJS) $(COL) $(SPL)
 blaster:       blaster.o       $(HACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(HACK_LIBS)
 
-bumps: bumps.o                 $(HACK_OBJS) $(GRAB)
+bumps:         bumps.o         $(HACK_OBJS) $(GRAB)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(GRAB) $(HACK_LIBS) $(GRAB_LIBS)
 
+ripples:       ripples.o       $(HACK_OBJS) $(SHM) $(GRAB)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(SHM) $(GRAB) $(HACK_LIBS) $(GRAB_LIBS)
+
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
@@ -1729,4 +1732,14 @@ bumps.o: $(UTILS_SRC)/hsv.h
 bumps.o: $(UTILS_SRC)/colors.h
 bumps.o: $(UTILS_SRC)/grabscreen.h
 bumps.o: $(UTILS_SRC)/visual.h
+ripples.o: $(srcdir)/screenhack.h
+ripples.o: ../config.h
+ripples.o: $(UTILS_SRC)/yarandom.h
+ripples.o: $(UTILS_SRC)/usleep.h
+ripples.o: $(UTILS_SRC)/resources.h
+ripples.o: $(UTILS_SRC)/hsv.h
+ripples.o: $(UTILS_SRC)/colors.h
+ripples.o: $(UTILS_SRC)/grabscreen.h
+ripples.o: $(UTILS_SRC)/visual.h
+ripples.o: $(UTILS_SRC)/xshm.h
 
index 462220e980995bb6808fa3f0627256024ab8be21..8209dc111ef1cc4dcb30ef64ab94e7b827ab3d50 100644 (file)
@@ -62,6 +62,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PYRO.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) QIX.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RD-BOMB.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RIPPLES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ROCKS.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RORSCHACH.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ROTOR.C
index 462220e980995bb6808fa3f0627256024ab8be21..8209dc111ef1cc4dcb30ef64ab94e7b827ab3d50 100644 (file)
@@ -62,6 +62,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PYRO.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) QIX.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RD-BOMB.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RIPPLES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ROCKS.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RORSCHACH.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ROTOR.C
index 4218418f201628b8b54c2969a506736196883d0e..97b4ffe829b1f4d76d72756a79905d4e45e36fb6 100644 (file)
@@ -533,9 +533,9 @@ static void plain_draw(int k)
                XShmPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
                                2*radius+speed+2, 2*radius+speed+2, False);
        else
-# endif
 
        if (!use_shm)
+# endif
                XPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
                                2*radius+speed+2, 2*radius+speed+2);
 
index 8c1bae01774cf128213e4e8f6ef831e60d84793d..f50e987d174dec002e059b7871228469aaa58b41 100644 (file)
@@ -71,7 +71,7 @@ SRCS          = atlantis.c b_draw.c b_lockglue.c b_sphere.c bubble3d.c \
                  xlock-gl.c xpm-ximage.c glplanet.c pulsar.c \
                  extrusion.c extrusion-helix2.c extrusion-helix3.c \
                  extrusion-helix4.c extrusion-joinoffset.c extrusion-screw.c \
-                 extrusion-taper.c extrusion-twistoid.c
+                 extrusion-taper.c extrusion-twistoid.c sierpinski3d.c
 
 OBJS           = atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
                  buildlwo.o cage.o dolphin.o gears.o lament.o moebius.o \
@@ -81,10 +81,11 @@ OBJS                = atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
                  xlock-gl.o xpm-ximage.o glplanet.o pulsar.o \
                  extrusion.o extrusion-helix2.o extrusion-helix3.o \
                  extrusion-helix4.o extrusion-joinoffset.o extrusion-screw.o \
-                 extrusion-taper.o extrusion-twistoid.o
+                 extrusion-taper.o extrusion-twistoid.o sierpinski3d.o
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
-                 morph3d rubik atlantis lament bubble3d glplanet pulsar
+                 morph3d rubik atlantis lament bubble3d glplanet pulsar \
+                 sierpinski3d
 GLE_EXES       = extrusion
 EXES           = @GL_EXES@ @GLE_EXES@
 
@@ -264,7 +265,7 @@ bubble3d:   bubble3d.o      $(HACK_OBJS) $(B3D)
 glplanet:      glplanet.o      $(HACK_OBJS) xpm-ximage.o
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) xpm-ximage.o $(XPM_LIBS)
 
-pulsar:                pulsar.o                $(HACK_OBJS)
+pulsar:                pulsar.o        $(HACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(HACK_LIBS)
 
 EXTRUSION_OBJS=extrusion.o extrusion-helix2.o extrusion-helix3.o    \
@@ -273,6 +274,9 @@ EXTRUSION_OBJS=extrusion.o extrusion-helix2.o extrusion-helix3.o    \
 extrusion:     $(EXTRUSION_OBJS) $(HACK_OBJS)
        $(CC_HACK) -o $@ $(EXTRUSION_OBJS) $(HACK_OBJS) $(GLE_LIBS)
 
+sierpinski3d:  sierpinski3d.o  $(HACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(HACK_LIBS)
+
 
 ##############################################################################
 #
@@ -553,4 +557,16 @@ extrusion.o: $(UTILS_SRC)/colors.h
 extrusion.o: $(UTILS_SRC)/grabscreen.h
 extrusion.o: $(UTILS_SRC)/visual.h
 extrusion.o: $(UTILS_SRC)/xshm.h
+sierpinski3d.o: $(HACK_SRC)/xlockmore.h
+sierpinski3d.o: ../../config.h
+sierpinski3d.o: $(HACK_SRC)/xlockmoreI.h
+sierpinski3d.o: $(HACK_SRC)/screenhack.h
+sierpinski3d.o: $(UTILS_SRC)/yarandom.h
+sierpinski3d.o: $(UTILS_SRC)/usleep.h
+sierpinski3d.o: $(UTILS_SRC)/resources.h
+sierpinski3d.o: $(UTILS_SRC)/hsv.h
+sierpinski3d.o: $(UTILS_SRC)/colors.h
+sierpinski3d.o: $(UTILS_SRC)/grabscreen.h
+sierpinski3d.o: $(UTILS_SRC)/visual.h
+sierpinski3d.o: $(UTILS_SRC)/xshm.h
 
index c79d45c17b12363610594eb46bf6f8e03d8d6764..48e57aeb884659aaf881e6d4b594937db7e655a6 100644 (file)
@@ -674,6 +674,7 @@ void SetupLight(void)
   glEnable (GL_LIGHTING);
 
   glColorMaterial (GL_FRONT, GL_DIFFUSE);
+  glColorMaterial (GL_BACK, GL_DIFFUSE);
   glEnable (GL_COLOR_MATERIAL);
 }
 
@@ -690,6 +691,8 @@ void resetProjection(void) {
 static void
 reshape(int width, int height)
 {
+  global_width=width;
+  global_height=height;
   glViewport( 0, 0, global_width, global_height );
   resetProjection();
 }
@@ -729,21 +732,21 @@ void initializeGL(GLsizei width, GLsizei height)
   int style;
   int mode;
 
-  global_width=width;
-  global_height=height;
-
+  reshape(width, height);
   glViewport( 0, 0, width, height ); 
 
   glEnable(GL_DEPTH_TEST);
   glClearColor(0,0,0,0);
-  glCullFace(GL_BACK);
-  glEnable(GL_CULL_FACE);
+/*    glCullFace(GL_BACK); */
+/*    glEnable(GL_CULL_FACE); */
   glShadeModel(GL_SMOOTH);
 
   if (do_light)
        SetupLight();
-  if (do_wire)
+  if (do_wire) {
        glPolygonMode(GL_FRONT,GL_LINE);
+       glPolygonMode(GL_BACK,GL_LINE);
+  }
   if (do_texture) {
        Create_Texture(which_image, do_mipmap, do_texture_quality);
        glEnable(GL_TEXTURE_2D);
diff --git a/hacks/glx/sierpinski3d.c b/hacks/glx/sierpinski3d.c
new file mode 100644 (file)
index 0000000..0f8e4df
--- /dev/null
@@ -0,0 +1,298 @@
+/* -*- Mode: C; tab-width: 4 -*- */
+/* Sierpinski3D --- 3D sierpinski gasket */
+
+#if !defined( lint ) && !defined( SABER )
+static const char sccsid[] = "@(#)sierpinski3D.c       00.01 99/11/04 xlockmore";
+
+#endif
+
+/*-
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind.  The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof.  In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * Revision History:
+ * 1999: written by Tim Robinson <the_luggage@bigfoot.com>
+ *       a 3-D representation of the Sierpinski gasket fractal.
+ */
+
+/*-
+ * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
+ * otherwise caddr_t is not defined correctly
+ */
+
+#include <X11/Intrinsic.h>
+
+#ifdef STANDALONE
+# define PROGCLASS                                     "Sierpinski3D"
+# define HACK_INIT                                     init_gasket
+# define HACK_DRAW                                     draw_gasket
+# define gasket_opts                           xlockmore_opts
+# define DEFAULTS      "*count:                1       \n"                     \
+                       "*cycles:               9999    \n"                     \
+                       "*delay:                100     \n"                     \
+                       "*wireframe:    False   \n"
+# include "xlockmore.h"                /* from the xscreensaver distribution */
+#else  /* !STANDALONE */
+# include "xlock.h"                    /* from the xlockmore distribution */
+#endif /* !STANDALONE */
+
+#ifdef USE_GL
+
+ModeSpecOpt gasket_opts =
+{0, NULL, 0, NULL, NULL};
+
+#ifdef USE_MODULES
+ModStruct   gasket_description =
+{"gasket", "init_gasket", "draw_gasket", "release_gasket",
+ "draw_gasket", "init_gasket", NULL, &gasket_opts,
+ 1000, 1, 2, 1, 4, 1.0, "",
+ "Shows GL's Sierpinski gasket", 0, NULL};
+
+#endif
+
+typedef struct{
+  GLfloat x;
+  GLfloat y;
+  GLfloat z;
+} GL_VECTOR;
+
+typedef struct {
+  GLfloat     view_rotx, view_roty, view_rotz;
+  GLfloat     light_colour[4];/* = {6.0, 6.0, 6.0, 1.0}; */
+  GLfloat     pos[3];/* = {0.0, 0.0, 0.0}; */
+  GLfloat     xinc,yinc,zinc;
+  GLfloat     angle;
+  GLuint      gasket1;
+  GLXContext *glx_context;
+  Window      window;
+#if 0
+  Window      win;
+#endif
+} gasketstruct;
+
+static gasketstruct *gasket = NULL;
+
+#include <GL/glu.h>
+
+/* static GLuint limit; */
+
+static void
+compile_gasket(ModeInfo *mi)
+{
+  int i,p;
+  int points = MI_CYCLES(mi) ? MI_CYCLES(mi) : 9999;
+  GL_VECTOR   vertex[5];
+
+  /* define verticies */
+  vertex[0].x =  0.5; 
+  vertex[0].y = -(1.0/3.0)*sqrt((2.0/3.0));
+  vertex[0].z = -sqrt(3.0)/6.0;
+
+  vertex[1].x = -0.5; 
+  vertex[1].y = -(1.0/3.0)*sqrt((2.0/3.0)); 
+  vertex[1].z = -sqrt(3.0)/6.0; 
+
+  vertex[2].x = 0.0; 
+  vertex[2].y = (2.0/3.0)*sqrt((2.0/3.0));
+  vertex[2].z = -sqrt(3.0)/6.0; 
+
+  vertex[3].x = 0.0; 
+  vertex[3].y = 0.0; 
+  vertex[3].z = sqrt(3.0)/3.0; 
+
+  vertex[4].x = 0.0;
+  vertex[4].y = 0.0; 
+  vertex[4].z = 0.0;
+  
+  glBegin(GL_POINTS);
+  for( i = 0; i < points ; i++ )
+  { 
+    p = NRAND(4);
+    vertex[4].x = ( vertex[4].x + vertex[p].x )/2.0;
+    vertex[4].y = ( vertex[4].y + vertex[p].y )/2.0;
+    vertex[4].z = ( vertex[4].z + vertex[p].z )/2.0;
+
+    glVertex4f( vertex[4].x, vertex[4].y, vertex[4].z, 1.0 );
+  }
+  glEnd();
+}
+
+static void
+draw(ModeInfo *mi)
+{
+  gasketstruct *gp = &gasket[MI_SCREEN(mi)];
+  
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  glLightfv(GL_LIGHT0, GL_AMBIENT, gp->light_colour);
+  glEnable(GL_LIGHTING);
+  glEnable(GL_LIGHT0);
+  glEnable(GL_DEPTH_TEST);
+
+  glPushMatrix();
+  glTranslatef( gp->pos[0], gp->pos[1], gp->pos[2] );  
+
+  glPushMatrix();
+  glRotatef(2*gp->angle, 1.0, 0.0, 0.0);
+  glRotatef(3*gp->angle, 0.0, 1.0, 0.0);
+  glRotatef(  gp->angle, 0.0, 0.0, 1.0);
+  glScalef( 8.0, 8.0, 8.0 );
+  glCallList(gp->gasket1);
+  
+  glPopMatrix();
+
+  glPopMatrix();
+
+}
+
+
+/* new window size or exposure */
+static void
+reshape(int width, int height)
+{
+  GLfloat h = (GLfloat) height / (GLfloat) width;
+
+  glViewport(0, 0, (GLint) width, (GLint) height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+
+  gluPerspective( 30.0, 1/h, 1.0, 100.0 );
+  gluLookAt( 0.0, 0.0, 15.0,
+             0.0, 0.0, 0.0,
+             0.0, 1.0, 0.0);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  glTranslatef(0.0, 0.0, -40.0);
+  
+  /* The depth buffer will be cleared, if needed, before the
+  * next frame.  Right now we just want to black the screen.
+  */
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+static void
+pinit(ModeInfo *mi)
+{
+  gasketstruct *gp = &gasket[MI_SCREEN(mi)];
+
+  gp->xinc = 0.1*(1.0*rand()/RAND_MAX);
+  gp->yinc = 0.1*(1.0*rand()/RAND_MAX);
+  gp->zinc = 0.1*(1.0*rand()/RAND_MAX);
+  gp->light_colour[0] = 6.0;
+  gp->light_colour[1] = 6.0;
+  gp->light_colour[2] = 6.0;
+  gp->light_colour[3] = 1.0;
+  gp->pos[0] = 0.0;     
+  gp->pos[1] = 0.0;
+  gp->pos[2] = 0.0;    
+  /* draw the gasket */
+  gp->gasket1 = glGenLists(1);
+  glNewList(gp->gasket1, GL_COMPILE);
+    compile_gasket(mi);
+  glEndList();
+}
+
+void
+init_gasket(ModeInfo *mi)
+{
+  int           screen = MI_SCREEN(mi);
+  gasketstruct *gp;
+
+  if (gasket == NULL)
+  {
+    if ((gasket = (gasketstruct *) calloc(MI_NUM_SCREENS(mi),
+                                             sizeof (gasketstruct))) == NULL)
+       return;
+  }
+  gp = &gasket[screen];
+
+  gp->window = MI_WINDOW(mi);
+  gp->view_rotx = NRAND(360);
+  gp->view_roty = NRAND(360);
+  gp->view_rotz = NRAND(360);
+  gp->angle = NRAND(360)/90.0;
+
+  if ((gp->glx_context = init_GL(mi)) != NULL)
+  {
+    reshape(MI_WIDTH(mi), MI_HEIGHT(mi));
+    pinit(mi);
+  }
+  else
+  {
+    MI_CLEARWINDOW(mi);
+  }
+}
+
+void
+draw_gasket(ModeInfo * mi)
+{
+  gasketstruct *gp = &gasket[MI_SCREEN(mi)];
+  Display      *display = MI_DISPLAY(mi);
+  Window        window = MI_WINDOW(mi);
+  int           angle_incr = 1;
+  int           rot_incr = 1;/*MI_COUNT(mi) ? MI_COUNT(mi) : 1;*/
+
+  if (!gp->glx_context) return;
+
+  glDrawBuffer(GL_BACK);
+
+  glXMakeCurrent(display, window, *(gp->glx_context));
+  draw(mi);
+
+  /* do the colour change & movement thing */
+  gp->angle = (int) (gp->angle + angle_incr) % 360;
+  gp->light_colour[0] = 3.0*SINF(gp->angle/20.0) + 4.0;
+  gp->light_colour[1] = 3.0*SINF(gp->angle/30.0) + 4.0;
+  gp->light_colour[2] = 3.0*SINF(gp->angle/60.0) + 4.0;
+  if ( FABSF( gp->pos[0] ) > 9.0 ) gp->xinc = -1.0 * gp->xinc;
+  if ( FABSF( gp->pos[1] ) > 7.0 ) gp->yinc = -1.0 * gp->yinc;
+  if ( FABSF( gp->pos[2] ) >15.0 ) gp->zinc = -1.0 * gp->zinc;
+  gp->pos[0] += gp->xinc;
+  gp->pos[1] += gp->yinc;
+  gp->pos[2] += gp->zinc;    
+  gp->view_rotx = (int) (gp->view_rotx + rot_incr) % 360;
+  gp->view_roty = (int) (gp->view_roty +(rot_incr/2.0)) % 360;
+  gp->view_rotz = (int) (gp->view_rotz +(rot_incr/3.0)) % 360;
+
+  glFinish();
+  glXSwapBuffers(display, window);
+}
+
+void
+release_gasket(ModeInfo * mi)
+{
+  if (gasket != NULL)
+  {
+    int         screen;
+
+    for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
+    {
+      gasketstruct *gp = &gasket[screen];
+
+      if (gp->glx_context)
+      {
+       /* Display lists MUST be freed while their glXContext is current. */
+        glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
+
+        if (glIsList(gp->gasket1)) glDeleteLists(gp->gasket1, 1);
+      }
+    }
+    (void) free((void *) gasket);
+    gasket = NULL;
+  }
+  FreeAllGL(mi);
+}
+
+
+/*********************************************************/
+
+#endif
index 8b7016507a2a99a33233d872dd6711a54860a746..b4c748f65f36b7c572b2b9d64604ba0f6a7df905 100644 (file)
 
 typedef struct cell_s 
 {
-    short x;                        /*  0    */
-    short y;                        /*  2    */
-    unsigned char col;              /*  4    */
-    unsigned char isnext;           /*  5    */
-    unsigned char nextcol;          /*  6    */
-                                    /*  7    */
-    struct cell_s *next;            /*  8    */
-    struct cell_s *prev;            /* 12    */
-    struct cell_s *(adj)[3][3];     /* 16    */
-    FLOAT speed;                    /* 52    */
-    FLOAT growth;                   /* 56 60 */
-    FLOAT nextspeed;                /* 60 68 */
-                                    /* 64 76 */
+    short x;                        /*  0    - */
+    short y;                        /*  2      */
+    unsigned char col;              /*  4      */
+    unsigned char isnext;           /*  5      */
+    unsigned char nextcol;          /*  6      */
+                                    /*  7      */
+    struct cell_s *next;            /*  8    - */
+    struct cell_s *prev;            /* 12      */
+    FLOAT speed;                    /* 16    - */
+    FLOAT growth;                   /* 20 24   */
+    FLOAT nextspeed;                /* 24 32 - */
+                                    /* 28 40   */
 } cell;
 
 static int arr_width;
@@ -136,7 +135,10 @@ static void setup_random_colormap (XWindowAttributes *xgwa)
     make_random_colormap (display, xgwa->visual, xgwa->colormap,
                          colors+1, &ncolors, True, True, 0, True);
     if (ncolors < 1)
+      {
+        fprintf (stderr, "%s: couldn't allocate any colors\n", progname);
        exit (-1);
+      }
     
     ncolors++;
     count = ncolors;
@@ -234,8 +236,37 @@ static void setup_display (void)
     Colormap cmap;
 
     int cell_size = get_integer_resource ("size", "Integer");
+    int osize, alloc_size, oalloc;
+    int mem_throttle = 0;
+    char *s;
+
     if (cell_size < 1) cell_size = 1;
 
+    osize = cell_size;
+
+    s = get_string_resource ("memThrottle", "MemThrottle");
+    if (s)
+      {
+        int n;
+        char c;
+        if (1 == sscanf (s, " %d M %c", &n, &c) ||
+            1 == sscanf (s, " %d m %c", &n, &c))
+          mem_throttle = n * (1 << 20);
+        else if (1 == sscanf (s, " %d K %c", &n, &c) ||
+                 1 == sscanf (s, " %d k %c", &n, &c))
+          mem_throttle = n * (1 << 10);
+        else if (1 == sscanf (s, " %d %c", &n, &c))
+          mem_throttle = n;
+        else
+          {
+            fprintf (stderr, "%s: invalid memThrottle \"%s\" (try \"10M\")\n",
+                     progname, s);
+            exit (1);
+          }
+        
+        free (s);
+      }
+
     XGetWindowAttributes (display, window, &xgwa);
 
     originalcolors = get_boolean_resource ("originalcolors", "Boolean");
@@ -358,6 +389,38 @@ static void setup_display (void)
     arr_width = windowWidth / cell_size;
     arr_height = windowHeight / cell_size;
 
+    alloc_size = sizeof(cell) * arr_width * arr_height;
+    oalloc = alloc_size;
+
+    if (mem_throttle > 0)
+      while (cell_size < windowWidth/10 &&
+             cell_size < windowHeight/10 &&
+             alloc_size > mem_throttle)
+        {
+          cell_size++;
+          arr_width = windowWidth / cell_size;
+          arr_height = windowHeight / cell_size;
+          alloc_size = sizeof(cell) * arr_width * arr_height;
+        }
+
+    if (osize != cell_size)
+      {
+        static int warned = 0;
+        if (!warned)
+          {
+            fprintf (stderr,
+             "%s: throttling cell size from %d to %d because of %dM limit.\n",
+                     progname, osize, cell_size, mem_throttle / (1 << 20));
+            fprintf (stderr, "%s: %dx%dx%d = %.1fM, %dx%dx%d = %.1fM.\n",
+                     progname,
+                     windowWidth, windowHeight, osize,
+                     ((float) oalloc) / (1 << 20),
+                     windowWidth, windowHeight, cell_size,
+                     ((float) alloc_size) / (1 << 20));
+            warned = 1;
+          }
+      }
+
     xSize = windowWidth / arr_width;
     ySize = windowHeight / arr_height;
     if (xSize > ySize)
@@ -395,8 +458,6 @@ static void drawblock (int x, int y, unsigned char c)
 static void setup_arr (void)
 {
     int x, y;
-    int i, j;
-    int a, b;
 
     if (arr != NULL)
     {
@@ -427,19 +488,6 @@ static void setup_arr (void)
            arr[row+x].isnext = 0;
            arr[row+x].next = 0;
            arr[row+x].prev = 0;
-           for (i = 0; i < 3; i++) 
-           {
-               a = x + i - 1;
-               if (a < 0) a = arr_width - 1;
-               else if (a >= arr_width) a = 0;
-               for (j = 0; j < 3; j++) 
-               {
-                   b = y + j - 1;
-                   if (b < 0) b = arr_height - 1;
-                   else if (b >= arr_height) b = 0;
-                   arr[row+x].adj[i][j] = &arr[(b * arr_width) + a];
-               }
-           }
        }
     }
 
@@ -548,23 +596,36 @@ static void update (void)
     
     for (a = head->next; a != tail; a = a->next) 
     {
-       if (a->speed == 0) continue;
-       a->growth += a->speed;
-       if (a->growth >= orthlim) 
-       {
-           newcell (a->adj[0][1], a->col, a->speed);
-           newcell (a->adj[2][1], a->col, a->speed);
-           newcell (a->adj[1][0], a->col, a->speed);
-           newcell (a->adj[1][2], a->col, a->speed);
-       }
+        static XPoint coords1[] = {{-1,  0}, { 1, 0}, {0, -1}, {0, 1}};
+        static XPoint coords2[] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
+        XPoint *coords = 0;
+        int i;
+
+        if (a->speed == 0) continue;
+        a->growth += a->speed;
+        if (a->growth >= orthlim) 
+          coords = coords1;
+
+       if (a->growth >= diaglim) 
+          coords = coords2;
+
+        if (coords)
+          for (i = 0; i < 4; i++)
+            {
+              int x = a->x + coords[i].x;
+              int y = a->y + coords[i].y;
+
+              if (x < 0) x = arr_width - 1;
+              else if (x >= arr_width) x = 0;
+
+              if (y < 0) y = arr_height - 1;
+              else if (y >= arr_height) y = 0;
+
+              newcell (&arr[y * arr_width + x], a->col, a->speed);
+            }
+
        if (a->growth >= diaglim) 
-       {
-           newcell (a->adj[0][0], a->col, a->speed);
-           newcell (a->adj[0][2], a->col, a->speed);
-           newcell (a->adj[2][0], a->col, a->speed);
-           newcell (a->adj[2][2], a->col, a->speed);
            killcell (a);
-       }
     }
     
     randblip ((head->next) == tail);
@@ -602,6 +663,8 @@ char *defaults [] = {
   "*mindeathspeed:     0.42",
   "*maxdeathspeed:     0.46",
   "*originalcolors:    false",
+  "*memThrottle:        22M",  /* don't malloc more than this much.
+                                   Scale the pixels up if necessary. */
     0
 };
 
@@ -620,6 +683,7 @@ XrmOptionDescRec options [] = {
   { "-mindeathspeed",   ".mindeathspeed",      XrmoptionSepArg, 0 },
   { "-maxdeathspeed",   ".maxdeathspeed",      XrmoptionSepArg, 0 },
   { "-originalcolors",  ".originalcolors",     XrmoptionNoArg,  "true" },
+  { "-mem-throttle",    ".memThrottle",        XrmoptionSepArg,  0 },
   { 0, 0, 0, 0 }
 };
 
@@ -642,5 +706,3 @@ void screenhack (Display *dpy, Window win)
        usleep (delay);
     }
 }
-
-
diff --git a/hacks/ripples.c b/hacks/ripples.c
new file mode 100644 (file)
index 0000000..f8996c4
--- /dev/null
@@ -0,0 +1,846 @@
+/* ripples, Copyright (c) 1999 Ian McConnell <ian@emit.demon.co.uk>
+ *
+ * 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.
+ */
+
+/*
+ * "Water" ripples that can cross and interfere with each other.
+ *
+ * I can't remember where I got this idea from, but it's been around for a
+ * while in various demos. Some inspiration from
+ *      water.txt by Tom Hammersley,tomh@globalnet.co.uk
+ *
+ * Options
+ * -delay      usleep every iteration
+ * -rate       Add one drop every "rate" iterations
+ * -water      Ripples on a grabbed background image
+ * -foreground  Interpolate ripples between these two colors
+ * -background
+ * -oily       Psychedelic colours like man
+ * -stir       Add a regular pattern of drops
+ * -fluidity   Between 0 and 16. 16 = big drops
+ * -light      Hack to add lighting effect (2 for 16bbp, 6 for 32bpp)
+ *
+ * Code mainly hacked from xflame and decayscreen.
+ */
+
+/* Version history:
+ * Speeded up graphics with dirty buffer. Returned to using putpixel for
+ * greater portability
+ * Added a variety of methods for splashing screen.
+ */
+
+
+#include <math.h>
+#include "screenhack.h"
+#include <X11/Xutil.h>
+
+typedef enum {ripple_drop, ripple_blob, ripple_box, ripple_stir} ripple_mode;
+
+#ifdef HAVE_XSHM_EXTENSION
+#include "xshm.h"
+static Bool use_shm;
+static XShmSegmentInfo shm_info;
+#endif /* HAVE_XSHM_EXTENSION */
+
+static Window window;
+static Display *display;
+static GC gc;
+static Visual *visual;
+
+static XImage *orig_map, *buffer_map;
+static int ctab[256];
+static Colormap colormap;
+static int ncolors;
+static int light;
+
+static int width, height; /* ripple size */
+static int bigwidth, bigheight; /* screen size */
+
+static Bool transparent;
+static short *bufferA, *bufferB, *temp;
+static char *dirty_buffer;
+
+#define TABLE 256
+static double cos_tab[TABLE];
+
+static double drop_dist[] = 
+{0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.2, 0.6};
+
+/* How hard to hit the water */
+#define SPLASH 512
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+#define DIRTY 2 /* 2 = dirty, 1 = restore original pixel, 0 = leave alone */
+
+
+/*      -------------------------------------------             */
+
+
+static int
+map_color(int grey)
+{
+  /* Clip it */
+  grey = ncolors * abs(grey) / (SPLASH/4);
+  if (grey > ncolors)
+    grey = ncolors;
+
+  /* Display it */
+  return ctab[grey];
+}
+
+
+static void
+draw_ripple(short *src)
+{
+  int across, down;
+  char *dirty = dirty_buffer;
+
+  for (down = 0; down < height - 1; down++, src += 1, dirty += 1)
+    for (across = 0; across < width - 1; across++, src++, dirty++) {
+      int v1, v2, v3, v4;
+      v1 = (int)*src;
+      v2 = (int)*(src + 1);
+      v3 = (int)*(src + width);
+      v4 = (int)*(src + width + 1);
+      if ((v1 == 0 && v2 == 0 && v3 == 0 && v4 == 0)) {
+        if (*dirty > 0)
+          (*dirty)--;
+      } else
+        *dirty = DIRTY;
+
+      if (*dirty > 0) {
+        int dx;
+        if (light > 0) {
+          /* dx = ((v2 - v1) + (v4 - v3)) << light; */ /* light from left */
+          dx = ((v3 - v1) + (v4 - v2)) << light; /* light from top */
+        } else
+          dx = 0;
+        XPutPixel(buffer_map,(across<<1),  (down<<1),  map_color(dx + v1));
+        XPutPixel(buffer_map,(across<<1)+1,(down<<1),  map_color(dx + ((v1 + v2) >> 1)));
+        XPutPixel(buffer_map,(across<<1),  (down<<1)+1,map_color(dx + ((v1 + v3) >> 1)));
+        XPutPixel(buffer_map,(across<<1)+1,(down<<1)+1,map_color(dx + ((v1 + v4) >> 1)));
+      }
+    }
+}
+
+
+/*      -------------------------------------------             */
+
+
+static unsigned long (*bright)(int dx, unsigned long color);
+static unsigned long rmask;
+static unsigned long gmask;
+static unsigned long bmask;
+static int rshift;
+static int gshift;
+static int bshift;
+
+
+static void 
+set_mask(unsigned long color, unsigned long *mask, int *shift)
+{
+  *shift = 0;
+  while (color != 0 && (color & 1) == 0) {
+    (*shift)++;
+    color >>= 1;
+  }
+  *mask = color;
+}
+
+
+static unsigned long
+cadd(unsigned long color, int dx, unsigned long mask, int shift)
+{
+  int x;
+  color >>= shift;
+  x = (color & mask);
+  x += dx;
+  if (x < 0) x = 0;
+  else if (x > (int)mask) x = mask;
+  color = x;
+  return color << shift;
+}
+
+
+static unsigned long
+dobright(int dx, unsigned long color)
+{
+  return (cadd(color, dx, rmask, rshift) |
+          cadd(color, dx, gmask, gshift) |
+          cadd(color, dx, bmask, bshift));
+}
+
+
+static unsigned long
+nobright(int dx, unsigned long color)
+{
+  return color;
+}
+
+
+static void
+draw_transparent(short *src)
+{
+  int across, down, pixel;
+  char *dirty = dirty_buffer;
+
+  pixel = 0;
+  for (down = 0; down < height - 2; down++, pixel += 2)
+    for (across = 0; across < width-2; across++, pixel++) {
+      int gradx, grady, gradx1, grady1;
+      int x0, x1, x2, y1, y2;
+
+      x0 = src[pixel];
+      x1 = src[pixel + 1];
+      x2 = src[pixel + 2];
+      y1 = src[pixel + width];
+      y2 = src[pixel + 2*width];
+
+      gradx = (x1 - x0);
+      grady = (y1 - x0);
+      gradx1= (x2 - x1);
+      grady1= (y2 - y1);
+      gradx1 = 1 + (gradx + gradx1) / 2;
+      grady1 = 1 + (grady + grady1) / 2;
+
+      if ((2*across+MIN(gradx,gradx1) < 0) ||
+          (2*across+MAX(gradx,gradx1) >= bigwidth)) {
+        gradx = 0;
+        gradx1= 1;
+      }
+      if ((2*down+MIN(grady,grady1) < 0) ||
+          (2*down+MAX(grady,grady1) >= bigheight)) {
+        grady = 0;
+        grady1 = 1;
+      }
+
+      if ((gradx == 0 && gradx1 == 1 && grady == 0 && grady1 == 1)) {
+        if (dirty[pixel] > 0)
+          dirty[pixel]--;
+      } else
+        dirty[pixel] = DIRTY;
+
+      if (dirty[pixel] > 0) {
+        int dx;
+        if (light > 0) {
+          if (4-light >= 0)
+            dx = (grady + (src[pixel+width+1]-x1)) >> (4-light); /* light from top */
+          else
+            dx = (grady + (src[pixel+width+1]-x1)) << (light-4); /* light from top */
+        } else
+          dx = 0;
+        XPutPixel(buffer_map, (across<<1),  (down<<1),
+                  bright(dx, XGetPixel(orig_map, (across<<1) + gradx, (down<<1) + grady)));
+        XPutPixel(buffer_map, (across<<1)+1,(down<<1),
+                  bright(dx, XGetPixel(orig_map, (across<<1) + gradx1,(down<<1) + grady)));
+        XPutPixel(buffer_map, (across<<1),  (down<<1)+1,
+                  bright(dx, XGetPixel(orig_map, (across<<1) + gradx, (down<<1) + grady1)));
+        XPutPixel(buffer_map, (across<<1)+1,(down<<1)+1,
+                  bright(dx, XGetPixel(orig_map, (across<<1) + gradx1,(down<<1) + grady1)));
+      }
+    }
+}
+
+
+/*      -------------------------------------------             */
+
+
+/*
+static void
+draw_ripple16(short *src)
+{
+  int across, down;
+  unsigned short *dest;
+
+  dest = (unsigned short *) buffer_map->data;
+
+  for (down = 0; down < height - 1; down++, src += 1, dest += bigwidth+2)
+    for (across = 0; across < width - 1; across++, src++) {
+      int v1, v2, v3, v4;
+      v1 = (int)*src;
+      v2 = (int)*(src + 1);
+      v3 = (int)*(src + width);
+      v4 = (int)*(src + width + 1);
+      if (!(v1 == 0 && v2 == 0 && v3 == 0 && v4 == 0)) {
+        *dest++ = map_color(v1);
+        *dest   = map_color((v1 + v2) >> 1);
+        dest   += bigwidth - 1;
+        *dest++ = map_color((v1 + v3) >> 1);
+        *dest   = map_color((v1 + v4) >> 1);
+        dest   -= bigwidth - 1;
+      } else
+        dest += 2;
+    }
+}
+*/
+
+
+/*      -------------------------------------------             */
+
+
+static void
+setup_X(Display * disp, Window win)
+{
+  XWindowAttributes xwa;
+  int depth;
+
+  XGetWindowAttributes(disp, win, &xwa);
+  window = win;
+  display = disp;
+  depth = xwa.depth;
+  colormap = xwa.colormap;
+  bigwidth = xwa.width;
+  bigheight = xwa.height;
+  visual = xwa.visual;
+
+#if 1 /* I'm not entirely sure if I need this */
+  if (bigwidth % 2)
+    bigwidth++;
+  if (bigheight % 2)
+    bigheight++;
+#endif
+  width = bigwidth / 2;
+  height = bigheight / 2;
+
+  if (transparent) {
+    XGCValues gcv;
+    long gcflags;
+
+    gcv.function = GXcopy;
+    gcv.subwindow_mode = IncludeInferiors;
+
+    gcflags = GCForeground | GCFunction;
+    if (use_subwindow_mode_p(xwa.screen, window))      /* see grabscreen.c */
+      gcflags |= GCSubwindowMode;
+    gc = XCreateGC(display, window, gcflags, &gcv);
+
+    grab_screen_image(xwa.screen, window);
+
+    orig_map = XGetImage(display, window, 0, 0, xwa.width, xwa.height,
+                        ~0L, ZPixmap);
+  } else {
+    XGCValues gcv;
+
+    gc = XCreateGC(display, window, 0, &gcv);
+    if (!gc) {
+      fprintf(stderr, "XCreateGC failed\n");
+      exit(1);
+    }
+
+    orig_map = 0;
+  }
+
+  buffer_map = 0;
+
+#ifdef HAVE_XSHM_EXTENSION
+  if (use_shm) {
+    buffer_map = create_xshm_image(display, xwa.visual, depth,
+                                  ZPixmap, 0, &shm_info, bigwidth, bigheight);
+    if (!buffer_map) {
+      use_shm = False;
+      fprintf(stderr, "create_xshm_image failed\n");
+    }
+  }
+#endif /* HAVE_XSHM_EXTENSION */
+
+  if (!buffer_map) {
+    buffer_map = XCreateImage(display, xwa.visual,
+                             depth, ZPixmap, 0, 0,
+                             bigwidth, bigheight, 8, 0);
+    buffer_map->data = (char *)
+      calloc(buffer_map->height, buffer_map->bytes_per_line);
+  }
+}
+
+
+static void
+DisplayImage(void)
+{
+#ifdef HAVE_XSHM_EXTENSION
+  if (use_shm)
+    XShmPutImage(display, window, gc, buffer_map, 0, 0, 0, 0,
+                bigwidth, bigheight, False);
+  else
+#endif /* HAVE_XSHM_EXTENSION */
+    XPutImage(display, window, gc, buffer_map, 0, 0, 0, 0,
+             bigwidth, bigheight);
+}
+
+
+/*      -------------------------------------------             */
+
+
+static int
+cinterp(double a, int bg, int fg)
+{
+  int result;
+  result = (int)((1-a) * bg + a * fg + 0.5);
+  if (result < 0) result = 0;
+  if (result > 255) result = 255;
+  return result;
+}
+
+
+/* Interpolate the ripple colours between the background colour and
+   foreground colour */
+static void
+init_linear_colors(void)
+{
+  int i, j, red, green, blue, bred, bgreen, bblue;
+  XColor fg, bg;
+
+  if (ncolors < 2 || mono_p)
+    ncolors = 2;
+  if (ncolors <= 2)
+    mono_p = True;
+
+  /* Make it possible to set the color of the ripples,
+     Based on work by Raymond Medeiros <ray@stommel.marine.usf.edu> and jwz.
+   */
+  fg.pixel = get_pixel_resource("foreground", "Foreground",
+                               display, colormap);
+  XQueryColor(display, colormap, &fg);
+  red = (fg.red >> 8);
+  green = (fg.green >> 8);
+  blue = (fg.blue >> 8);
+
+  bg.pixel = get_pixel_resource("background", "Background",
+                               display, colormap);
+  XQueryColor(display, colormap, &bg);
+  bred = (bg.red >> 8);
+  bgreen = (bg.green >> 8);
+  bblue = (bg.blue >> 8);
+
+  j = 0;
+  for (i = 0; i < ncolors+1; i++) {
+    XColor xcl;
+    double a = (double)i / ncolors;
+    int r = cinterp(a, bred, red);
+    int g = cinterp(a, bgreen, green);
+    int b = cinterp(a, bblue, blue);
+
+    xcl.red = (unsigned short) ((r << 8) | r);
+    xcl.green = (unsigned short) ((g << 8) | g);
+    xcl.blue = (unsigned short) ((b << 8) | b);
+    xcl.flags = DoRed | DoGreen | DoBlue;
+
+    XAllocColor(display, colormap, &xcl);
+
+    ctab[j++] = (int) xcl.pixel;
+  }
+}
+
+
+static void
+init_oily_colors(void)
+{
+  XColor *colors = NULL;
+
+  if (ncolors < 2 || mono_p)
+    ncolors = 2;
+  if (ncolors <= 2)
+    mono_p = True;
+  colors = 0;
+
+  if (!mono_p) {
+    colors = (XColor *)malloc(sizeof(*colors) * (ncolors+1));
+    make_smooth_colormap(display, visual, colormap, colors, &ncolors,
+                         True, /* allocate */
+                         False, /* not writable */
+                         True); /* verbose (complain about failure) */
+    if (ncolors <= 2) {
+      if (colors)
+        free (colors);
+      colors = 0;
+      mono_p = True;
+    }
+  }
+  if (!mono_p) {
+    int i, j = 0;
+    for (i = 0; i < ncolors+1; i++) {
+      XAllocColor(display, colormap, colors+i);
+      ctab[j++] = (int) colors[i].pixel;
+    }
+    free (colors);
+  } else {
+    ncolors = 2;
+    ctab[1] = get_pixel_resource("foreground", "Foreground", display, colormap);
+    ctab[0] = get_pixel_resource("background", "Background", display, colormap);
+  }
+}
+
+
+/*      -------------------------------------------             */
+
+
+/* Shape of drop to add */
+static double
+sinc(double x)
+{
+#if 1
+  int i;
+  i = (int)(x * TABLE + 0.5);
+  if (i >= TABLE) i = (TABLE-1) - (i-(TABLE-1));
+  return cos_tab[i];
+#elif 0
+  return cos(x * M_PI/2);
+#else
+  if (fabs(x) < 0.1)
+    return 1 - x*x;
+  else
+    return sin(x) / x;
+#endif
+}
+
+
+static void
+add_circle_drop(int x, int y, int radius, int dheight)
+{
+  int i, r2, cx, cy;
+  short *buf = (random()&1) ? bufferA : bufferB;
+
+  i = y * width + x;
+  r2 = radius * radius;
+
+  for (cy = -radius; cy <= radius; cy++)
+    for (cx = -radius; cx <= radius; cx++) {
+      int r = cx*cx + cy*cy;
+      if (r <= r2) {
+        buf[i + cx + cy*width] =
+          (short)(dheight * sinc(sqrt(r)/radius));
+      }
+    }
+}
+
+
+static void
+add_drop(ripple_mode mode, int drop)
+{
+  int newx, newy, dheight;
+  int radius = MIN(width, height) / 50;
+  /* Don't put drops too near the edge of the screen or they get stuck */
+  int border = 6;
+
+  switch (mode) {
+  default:
+  case ripple_drop: {
+    int x;
+
+    dheight = 1 + (random() % drop);
+    newx = border + (random() % (width - 2*border));
+    newy = border + (random() % (height - 2*border));
+    x = newy * width + newx;
+    bufferA[x + 1] = bufferA[x] = bufferA[x + width] = bufferA[x + width + 1] =
+      bufferB[x + 1] = bufferB[x] = bufferB[x + width] = bufferB[x + width + 1] =
+      dheight;
+  }
+  break;
+  case ripple_blob: {
+    double power;
+
+    power = drop_dist[random() % (sizeof(drop_dist)/sizeof(drop_dist[0]))]; /* clumsy */
+    dheight = (int)(drop * (power + 0.01));
+    newx = radius + border + (random() % (int)(width - 2*border - 2*radius*power));
+    newy = radius + border + (random() % (int)(height - 2*border - 2*radius*power));
+    add_circle_drop(newx, newy, radius, dheight);
+  }
+  break;
+  /* Adding too many boxes too quickly (-box 1) doesn't give the waves time
+     to disperse and the waves build up (and overflow) */
+  case ripple_box: {
+    int x;
+    int cx, cy;
+    short *buf = (random()&1) ? bufferA : bufferB;
+
+    radius = (1 + (random() % 5)) * (1 + (random() % 5));
+    dheight = drop / 128;
+    if (random() & 1) dheight = -dheight;
+    newx = radius + border + (random() % (width - 2*border - 2*radius));
+    newy = radius + border + (random() % (height - 2*border - 2*radius));
+    x = newy * width + newx;
+    for (cy = -radius; cy <= radius; cy++)
+      for (cx = -radius; cx <= radius; cx++)
+        buf[x + cx + cy*width] = (short)(dheight);
+  }
+  break;
+  case ripple_stir: {
+    static double ang = 0;
+    border += radius;
+    newx = border + (int)((width-2*border) * (1+cos(3*ang)) / 2);
+    newy = border + (int)((height-2*border) * (1+sin(2*ang)) / 2);
+    add_circle_drop(newx, newy, radius, drop / 10);
+    ang += 0.02;
+    if (ang > 12*M_PI) ang = 0;
+  }
+  break;
+  }
+}
+
+
+static void
+init_ripples(int ndrops, int splash)
+{
+  int i;
+
+  bufferA = (short *)calloc(width * height, sizeof(*bufferA));
+  bufferB = (short *)calloc(width * height, sizeof(*bufferB));
+  temp = (short *)calloc(width * height, sizeof(*temp));
+
+  dirty_buffer = (char *)malloc(width * height);
+  memset(dirty_buffer, DIRTY, width * height);
+
+  for (i = 0; i < ndrops; i++)
+    add_drop(ripple_blob, splash);
+
+  if (transparent) {
+    /* There's got to be a better way of doing this  XCopyArea? */
+    int across, down;
+    for (down = 0; down < bigheight-4; down++)
+      for (across = bigwidth-4; across < bigwidth; across++)
+       XPutPixel(buffer_map, across, down,
+                 XGetPixel(orig_map, across, down));
+    for (down = bigheight-4; down < bigheight; down++)
+      for (across = 0; across < bigwidth; across++)
+       XPutPixel(buffer_map, across, down,
+                 XGetPixel(orig_map, across, down));
+  } else {
+    int across, down, color;
+
+    color = map_color(0); /* background colour */
+    for (down = 0; down < bigheight; down++)
+      for (across = 0; across < bigwidth; across++)
+        XPutPixel(buffer_map,across,  down,  color);
+  }
+
+  DisplayImage();
+}
+
+
+/*
+ Explanation from hq_water.zip (Arturo R Montesinos (ARM) arami@fi.upm.es)
+
+ Differential equation is:  u  = a ( u  + u  )
+                             tt       xx   yy
+
+ Where a = tension * gravity / surface_density.
+
+ Approximating second derivatives by central differences:
+
+  [ u(t+1)-2u(t)+u(t-1) ] / dt = a [ u(x+1)+u(x-1)+u(y+1)+u(y-1)-4u ] / h
+
+ where dt = time step squared, h= dx*dy = mesh resolution squared.
+
+ From where u(t+1) may be calculated as:
+
+            dt  |   1   |                   dt
+ u(t+1) = a --  | 1 0 1 |u - u(t-1) + (2-4a --)u
+            h   |   1   |                    h
+
+ When a*dt/h = 1/2 last term vanishes, giving:
+
+                 1 |   1   |
+        u(t+1) = - | 1 0 1 |u - u(t-1)
+                 2 |   1   |
+
+ (note that u(t-1,x,y) is only used to calculate u(t+1,x,y) so
+  we can use the same array for both t-1 and t+1, needing only
+  two arrays, U[0] and U[1])
+
+ Dampening is simulated by subtracting 1/2^n of result.
+ n=4 gives best-looking result
+ n<4 (eg 2 or 3) thicker consistency, waves die out immediately
+ n>4 (eg 8 or 12) more fluid, waves die out slowly
+ */
+
+static void
+ripple(int fluidity)
+{
+  int across, down, pixel;
+  static int toggle;
+  static int count;
+  short *src, *dest;
+
+  if (toggle == 0) {
+    src = bufferA;
+    dest = bufferB;
+    toggle = 1;
+  } else {
+    src = bufferB;
+    dest = bufferA;
+    toggle = 0;
+  }
+
+#if 1
+  /* Traditional, squarer ripples */
+  switch (count) {
+  case 0: case 1:
+    pixel = 1 * width + 1;
+    for (down = 1; down < height - 1; down++, pixel += 2 * 1)
+      for (across = 1; across < width - 1; across++, pixel++) {
+        temp[pixel] =
+          (((src[pixel - 1] + src[pixel + 1] +
+             src[pixel - width] + src[pixel + width]) / 2)) - dest[pixel];
+      }
+
+    /* Smooth the output */
+    pixel = 1 * width + 1;
+    for (down = 1; down < height - 1; down++, pixel += 2 * 1)
+      for (across = 1; across < width - 1; across++, pixel++) {
+        int damp =
+          (temp[pixel - 1] + temp[pixel + 1] +
+           temp[pixel - width] + temp[pixel + width] +
+           temp[pixel - width - 1] + temp[pixel - width + 1] +
+           temp[pixel + width - 1] + temp[pixel + width + 1] +
+           temp[pixel]) / 9;
+        dest[pixel] = damp - (damp >> fluidity);
+      }
+    break;
+  case 2: case 3:
+    pixel = 1 * width + 1;
+    for (down = 1; down < height - 1; down++, pixel += 2 * 1)
+      for (across = 1; across < width - 1; across++, pixel++) {
+        int damp =
+          (((src[pixel - 1] + src[pixel + 1] +
+             src[pixel - width] + src[pixel + width]) / 2)) - dest[pixel];
+        dest[pixel] = damp - (damp >> fluidity);
+      }
+    break;
+  }
+  if (++count > 3) count = 0;
+#else
+  /* Rounder ripples, but with strange cross effect in center */
+  pixel = 1 * width + 1;
+  for (down = 1; down < height - 1; down++, pixel += 2 * 1)
+    for (across = 1; across < width - 1; across++, pixel++) {
+      int grad;
+      grad =
+        (src[pixel - 1] + src[pixel + 1] +
+         src[pixel - width] + src[pixel + width] +
+         src[pixel - width - 1] + src[pixel - width + 1] +
+         src[pixel + width - 1] + src[pixel + width + 1]) / 2;
+      dest[pixel] = grad/2 - dest[pixel];
+      dest[pixel] -= (dest[pixel] >> fluidity);
+    }
+#endif
+
+  if (transparent)
+    draw_transparent(dest);
+  else
+    draw_ripple(dest);
+}
+
+
+/*      -------------------------------------------             */
+
+
+char *progclass = "Ripples";
+
+char *defaults[] =
+{
+  ".background:                black",
+  ".foreground:                #FFAF5F",
+  "*colors:            200",
+  "*dontClearRoot:     True",
+  "*delay:             50000",
+  "*rate:              5",
+  "*box:               0",
+  "*water:             False",
+  "*oily:              False",
+  "*stir:              False",
+  "*fluidity:          6",
+  "*light:             0",
+#ifdef HAVE_XSHM_EXTENSION
+  "*useSHM: True",
+#endif                         /* HAVE_XSHM_EXTENSION */
+  0
+};
+
+XrmOptionDescRec options[] =
+{
+  { "-colors", ".colors",      XrmoptionSepArg, 0},
+  { "-colours",        ".colors",      XrmoptionSepArg, 0},
+  {"-delay",   ".delay",       XrmoptionSepArg, 0},
+  {"-rate",    ".rate",        XrmoptionSepArg, 0},
+  {"-box",     ".box",         XrmoptionSepArg, 0},
+  {"-water",   ".water",       XrmoptionNoArg, "True"},
+  {"-oily",    ".oily",        XrmoptionNoArg, "True"},
+  {"-stir",    ".stir",        XrmoptionNoArg, "True"},
+  {"-fluidity",        ".fluidity",    XrmoptionSepArg, 0},
+  {"-light",   ".light",       XrmoptionSepArg, 0},
+#ifdef HAVE_XSHM_EXTENSION
+  {"-shm",     ".useSHM",      XrmoptionNoArg, "True"},
+  {"-no-shm",  ".useSHM",      XrmoptionNoArg, "False"},
+#endif                         /* HAVE_XSHM_EXTENSION */
+  {0, 0, 0, 0}
+};
+
+
+void screenhack(Display *disp, Window win)
+{
+  int iterations = 0;
+  int delay = get_integer_resource("delay", "Integer");
+  int rate = get_integer_resource("rate", "Integer");
+  int box = get_integer_resource("box", "Integer");
+  int oily = get_boolean_resource("oily", "Boolean");
+  int stir = get_boolean_resource("stir", "Boolean");
+  int fluidity = get_integer_resource("fluidity", "Integer");
+  transparent = get_boolean_resource("water", "Boolean");
+  use_shm = get_boolean_resource("useSHM", "Boolean");
+  light = get_integer_resource("light", "Integer");
+
+  if (fluidity <= 1) fluidity = 1;
+  if (fluidity > 16) fluidity = 16; /* 16 = sizeof(short) */
+  if (light < 0) light = 0;
+
+  { int i;
+  for (i = 0; i < TABLE; i++)
+    cos_tab[i] = cos(i * M_PI/2 / TABLE);
+  }
+
+  setup_X(disp, win);
+
+  ncolors = get_integer_resource ("colors", "Colors");
+  if (0 == ncolors)            /* English spelling? */
+    ncolors = get_integer_resource ("colours", "Colors");
+  if (oily)
+    init_oily_colors();
+  else
+    init_linear_colors();
+
+  if (transparent && light > 0) {
+    bright = dobright;
+    set_mask(visual->red_mask,   &rmask, &rshift);
+    set_mask(visual->green_mask, &gmask, &gshift);
+    set_mask(visual->blue_mask,  &bmask, &bshift);
+    if (rmask == 0) bright = nobright;
+  } else
+    bright = nobright;
+
+  init_ripples(0, -SPLASH); /* Start off without any drops */
+
+  while (1) {
+    if (rate > 0 && (iterations % rate) == 0)
+      add_drop(ripple_blob, -SPLASH);
+    if (stir)
+      add_drop(ripple_stir, -SPLASH);
+    if (box > 0 && (random() % box) == 0)
+      add_drop(ripple_box, -SPLASH);
+
+    ripple(fluidity);
+    DisplayImage();
+
+    XSync(display,False);
+    screenhack_handle_events(display);
+    if (delay)
+      usleep(delay);
+
+    iterations++;
+  }
+}
index 5a70760d53d81e99ae3e3bf71b21a9d0ba9f190d..786d24b4cc5ddf95a3f02eb4186c5c5fecedb0e8 100644 (file)
 #include "version.h"
 #include "vroot.h"
 
+#ifndef isupper
+# define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
+#endif
+#ifndef _tolower
+# define _tolower(c)  ((c) - 'A' + 'a')
+#endif
+
+
 char *progname;
 XrmDatabase db;
 XtAppContext app;
@@ -244,6 +252,11 @@ pick_visual (Screen *screen)
    */
   Visual *v = 0;
   char *string = get_string_resource ("visualID", "VisualID");
+  char *s;
+
+  if (string)
+    for (s = string; *s; s++)
+      if (isupper (*s)) *s = _tolower (*s);
 
   if (!string || !*string ||
       !strcmp (string, "gl") ||
@@ -262,12 +275,61 @@ pick_visual (Screen *screen)
 }
 
 
+/* Notice when the user has requested a different visual or colormap
+   on a pre-existing window (e.g., "-root -visual truecolor" or
+   "-window-id 0x2c00001 -install") and complain, since when drawing
+   on an existing window, we have no choice about these things.
+ */
+static void
+visual_warning (Screen *screen, Window window, Visual *visual, Colormap cmap,
+                Bool window_p)
+{
+  char *visual_string = get_string_resource ("visualID", "VisualID");
+  Visual *desired_visual = pick_visual (screen);
+  char win[100];
+  char why[100];
+
+  if (window == RootWindowOfScreen (screen))
+    strcpy (win, "root window");
+  else
+    sprintf (win, "window 0x%x", (unsigned long) window);
+
+  if (window_p)
+    sprintf (why, "-window-id 0x%x", (unsigned long) window);
+  else
+    strcpy (why, "-root");
+
+  if (visual_string && *visual_string)
+    {
+      if (visual != desired_visual)
+        {
+          fprintf (stderr, "%s: ignoring `-visual %s' because of `%s'.\n",
+                   progname, visual_string, why);
+          fprintf (stderr, "%s: using %s's visual 0x%x.\n",
+                   progname, win, XVisualIDFromVisual (visual));
+        }
+      free (visual_string);
+    }
+
+  if (visual == DefaultVisualOfScreen (screen) &&
+      has_writable_cells (screen, visual) &&
+      get_boolean_resource ("installColormap", "InstallColormap"))
+    {
+      fprintf (stderr, "%s: ignoring `-install' because of `%s'.\n",
+               progname, why);
+      fprintf (stderr, "%s: using %s's colormap 0x%x.\n",
+               progname, win, (unsigned long) cmap);
+    }
+}
+
+
 int
 main (int argc, char **argv)
 {
   Widget toplevel;
   Display *dpy;
   Window window;
+  Screen *screen;
   Visual *visual;
   Colormap cmap;
   Bool root_p;
@@ -297,7 +359,9 @@ main (int argc, char **argv)
                              merged_options_size, &argc, argv,
                              merged_defaults, 0, 0);
   dpy = XtDisplay (toplevel);
+  screen = XtScreen (toplevel);
   db = XtDatabase (dpy);
+
   XtGetApplicationNameAndClass (dpy, &progname, &progclass);
 
   /* half-assed way of avoiding buffer-overrun attacks. */
@@ -378,6 +442,7 @@ main (int argc, char **argv)
       XGetWindowAttributes (dpy, window, &xgwa);
       cmap = xgwa.colormap;
       visual = xgwa.visual;
+      visual_warning (screen, window, visual, cmap, True);
     }
   else if (root_p)
     {
@@ -387,11 +452,11 @@ main (int argc, char **argv)
       XGetWindowAttributes (dpy, window, &xgwa);
       cmap = xgwa.colormap;
       visual = xgwa.visual;
+      visual_warning (screen, window, visual, cmap, False);
     }
   else
     {
       Boolean def_visual_p;
-      Screen *screen = XtScreen (toplevel);
       visual = pick_visual (screen);
 
       if (toplevel->core.width <= 0)
index 3a8cf468cf668f1ac8b4f0a709a89120bfc5bdf0..c4169f663dbd362d0a02dc8d492f40fb951d38c9 100644 (file)
@@ -28,7 +28,7 @@
  *   - plot the process table, by process size, cpu usage, or total time;
  *   - plot the logged on users by idle time or cpu usage.
  *
- * Copyright (C) 1998 by Stephen Martin (smartin@canada.com).
+ * Copyright (C) 1998 by Stephen Martin (smartin@vanderfleet-martin.net).
  * 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
@@ -37,7 +37,7 @@
  * software for any purpose.  It is provided "as is" without express or 
  * implied warranty.
  *
- * $Revision: 1.13 $
+ * $Revision: 1.14 $
  *
  * Version 1.0 April 27, 1998.
  * - Initial version
@@ -192,7 +192,7 @@ typedef struct {
        centrex, centrey, radius; /* Parts of the scope circle */
     Bogie *visable;            /* List of visable objects */
     int current;               /* Current position of sweep */
-
+    int sweepnum;               /* The current id of the sweep */
     int delay;                 /* how long between each frame of the anim */
 
 } sonar_info;
@@ -234,7 +234,6 @@ typedef struct {
 
 static int timer_expired;
 
-
 #endif /* HAVE_PING */
 
 /*
@@ -245,7 +244,7 @@ typedef struct sim_target {
     char *name;                        /* The name of the target */
     int nexttick;              /* The next tick that this will be seen */
     int nextdist;              /* The distance on that tick */
-    int movedlasttick;         /* Flag to indicate we just moved this one */
+    int movedonsweep;          /* The number of the sweep this last moved */
 } sim_target;
 
 /*
@@ -587,7 +586,7 @@ readPingHostsFile(char *fname)
               addr = NULL;
             }
         }
-        printf ("\"%s\" \"%s\"\n", name, addr);
+        /*printf ("\"%s\" \"%s\"\n", name, addr);*/
 
        /* Create a new target using first the name then the address */
 
@@ -1096,6 +1095,11 @@ static Bogie *
 ping(sonar_info *si, void *vpi) 
 {
 
+    /*
+     * This tries to distribute the targets evely around the field of the
+     * sonar.
+     */
+
     ping_info *pi = (ping_info *) vpi;
     static ping_target *ptr = NULL;
 
@@ -1184,6 +1188,7 @@ init_sim(void)
        sprintf(si->teamA[i].name, "%s%03d", si->teamAID, i+1);
        si->teamA[i].nexttick = (int) (90.0 * random() / RAND_MAX);
        si->teamA[i].nextdist = (int) (100.0 * random() / RAND_MAX);
+       si->teamA[i].movedonsweep = -1;
     }
 
     /* Team B */
@@ -1206,6 +1211,7 @@ init_sim(void)
        sprintf(si->teamB[i].name, "%s%03d", si->teamBID, i+1);
        si->teamB[i].nexttick = (int) (90.0 * random() / RAND_MAX);
        si->teamB[i].nextdist = (int) (100.0 * random() / RAND_MAX);
+       si->teamB[i].movedonsweep = -1;
     }
 
     /* Done */
@@ -1261,6 +1267,7 @@ init_sonar(Display *dpy, Window win)
     si->miny = si->centrey - MY_MIN(si->centrex, si->centrey) + 10;
     si->radius = si->maxx - si->centrex;
     si->current = 0;
+    si->sweepnum = 0;
 
     /* Get the font */
 
@@ -1348,7 +1355,6 @@ updateLocation(sim_target *t)
 
     int xdist, xtick;
 
-    t->movedlasttick = 1;
     xtick = (int) (3.0 * random() / RAND_MAX) - 1;
     xdist = (int) (11.0 * random() / RAND_MAX) - 5;
     if (((t->nexttick + xtick) < 90) && ((t->nexttick + xtick) >= 0))
@@ -1387,29 +1393,30 @@ simulator(sonar_info *si, void *vinfo)
 
     for (i = 0; i < info->numA; i++) {
        t = &info->teamA[i];
-       if (!t->movedlasttick && (t->nexttick == (si->current * -1))) {
+       if ((t->movedonsweep != si->sweepnum) &&
+           (t->nexttick == (si->current * -1))) {
            new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
            if (list != NULL)
                new->next = list;
            list = new;
            updateLocation(t);
-       } else
-           t->movedlasttick = 0;
+           t->movedonsweep = si->sweepnum;
+       }
     }
 
     /* Team B */
 
     for (i = 0; i < info->numB; i++) {
        t = &info->teamB[i];
-       if (!t->movedlasttick && (t->nexttick == (si->current * -1))) {
+       if ((t->movedonsweep != si->sweepnum) &&
+           (t->nexttick == (si->current * -1))) {
            new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
            if (list != NULL)
                new->next = list;
            list = new;
-           t->movedlasttick = 1;
            updateLocation(t);
-       } else
-           t->movedlasttick = 0;
+           t->movedonsweep = si->sweepnum;
+       }
     }
 
     /* Done */
@@ -1743,11 +1750,14 @@ screenhack(Display *dpy, Window win)
         /* Set up and sleep for the next one */
 
        si->current = (si->current - 1) % 90;
+       if (si->current == 0)
+         si->sweepnum++;
        XSync (dpy, False);
        gettimeofday(&finish, (struct timezone *) 0);
        sleeptime = si->delay - delta(&start, &finish);
         screenhack_handle_events (dpy);
        if (sleeptime > 0L)
            usleep(sleeptime);
+
     }
 }
index 45175a921ba88c96f36e7e753dad6d2073dcff19..a82da03ef9b1803856424d1a3e80c8a7e5c5439d 100755 (executable)
@@ -12,9 +12,9 @@
 #
 #
 # This script grabs a frame of video, then uses various pbm filters to
-# munge the image in random nefarious ways, then uses xli or xv to put it
-# on the root window.  This works out really nicely if you just feed some
-# random TV station into it...
+# munge the image in random nefarious ways, then uses xloadimage, xli, or xv
+# to put it on the root window.  This works out really nicely if you just
+# feed some random TV station into it...
 #
 # The video grabbing part is SGI-specific -- if you want to use this on
 # another system, add a new clause to the grab() procedure.
@@ -42,30 +42,37 @@ tmp_ppm4=$tmp-4.ppm
 tmp_ppmS=$tmp-S.ppm
 
 
-# Figure out whether to use xli or xv.
+# Figure out whether to use xloadimage, xli, or xv.
 pick_displayer() {
-  IFS=:
-  for p in $PATH; do
-    if [ "$p" = "" ]; then p=. ; fi
-    if [ -x $p/xli ]; then
-      displayer=$p/xli
-      displayer_args="-quiet"
-      displayer_win_args=""
-      displayer_root_args="-onroot -center -border black"
-      return
-    elif [ -x $p/xv ]; then
-      displayer=$p/xv
-      displayer_args="-quick24"
-      displayer_win_args="-geom +0+0"
-      displayer_root_args="-root -rmode 5 -noresetroot -rfg black -rbg black -viewonly"
-
-      return
-    fi
+  displayer=
+  for prog in xloadimage xli xv ; do
+    IFS=:
+    for p in $PATH; do
+      IFS=
+      if [ "$p" = "" ]; then p=. ; fi
+      if [ -x $p/$prog ]; then
+        displayer=$prog
+        break 2
+      fi
+    done
   done
-  IFS=
 
-  echo "$0: neither xli nor xv found on \$PATH"
-  exit -1
+  if [ "$displayer" = "xloadimage" ]; then
+    displayer_args="-quiet"
+    displayer_win_args=""
+    displayer_root_args="-onroot"
+  elif [ "$displayer" = "xli" ]; then
+    displayer_args="-quiet"
+    displayer_win_args=""
+    displayer_root_args="-onroot -center -border black"
+  elif [ "$displayer" = "xv" ]; then
+    displayer_args="-quick24"
+    displayer_win_args="-geom +0+0"
+    displayer_root_args="-root -rmode 5 -noresetroot -rfg black -rbg black -viewonly"
+  else
+    echo "$0: neither xli nor xv found on \$PATH"
+    exit -1
+  fi
 }
 
 # Process command-line args
index d5c4ff1354ae0209a6cc62106aa248533ae2f1c2..587bb41615233e1fe29f05b4657cd9ea2122f087 100755 (executable)
@@ -27,7 +27,7 @@ require POSIX;
 use Fcntl ':flock'; # import LOCK_* constants
 
 
-my $version = q{ $Revision: 1.40 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.41 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 my $copyright = "WebCollage $version, Copyright (c) 1999" .
     " Jamie Zawinski <jwz\@jwz.org>\n" .
     "            http://www.jwz.org/xscreensaver/\n";
@@ -75,10 +75,11 @@ my $http_proxy = undef;
 my $http_timeout = 30;
 my $cvt_timeout = 10;
 
-# if we have xli, use it to write to the root window.  else use xv.
-my $ppm_to_root_window_cmd_1 = "xli -quiet -onroot -center" .
+# programs we can use to write to the root window (tried in ascending order.)
+my $ppm_to_root_window_cmd_1 = "xloadimage -onroot -quiet %%PPM%%";
+my $ppm_to_root_window_cmd_2 = "xli -quiet -onroot -center" .
                                " -border black %%PPM%%";
-my $ppm_to_root_window_cmd_2 = "xv -root -rmode 5 -viewonly" .
+my $ppm_to_root_window_cmd_3 = "xv -root -rmode 5 -viewonly" .
                                " +noresetroot %%PPM%% -quit";
 
 my $ppm_to_root_window_cmd = undef;     # initialized by x_output()
@@ -1052,8 +1053,10 @@ sub x_output {
 
     my $win_cmd_1 = $ppm_to_root_window_cmd_1;
     my $win_cmd_2 = $ppm_to_root_window_cmd_2;
+    my $win_cmd_3 = $ppm_to_root_window_cmd_3;
     $win_cmd_1 =~ s/^([^ \t\r\n]+).*$/$1/;
     $win_cmd_2 =~ s/^([^ \t\r\n]+).*$/$1/;
+    $win_cmd_3 =~ s/^([^ \t\r\n]+).*$/$1/;
 
     # make sure the various programs we execute exist, right up front.
     foreach ("ppmmake", "giftopnm", "djpeg", "pnmpaste", "pnmscale",
@@ -1065,8 +1068,10 @@ sub x_output {
         $ppm_to_root_window_cmd = $ppm_to_root_window_cmd_1;
     } elsif (which($win_cmd_2)) {
         $ppm_to_root_window_cmd = $ppm_to_root_window_cmd_2;
-    } else {
-        die "$progname: neither $win_cmd_1 nor $win_cmd_2 found on \$PATH.\n";
+    } elsif (which($win_cmd_3)) {
+        $ppm_to_root_window_cmd = $ppm_to_root_window_cmd_3;
+     } else {
+        die "$progname: didn't find $win_cmd_1, $win_cmd_2, or $win_cmd_3 on \$PATH.\n";
     }
 
     $SIG{HUP}  = \&x_cleanup;
index 10eb69d1bf1f112dfe00ea2abf94784a3eda3311..4b41df383ce3058f586a7798184b76aec09f983c 100644 (file)
@@ -26,10 +26,13 @@ and scatters them on the root window.  One satisfied customer described it
 as "a nonstop pop culture brainbath."  This program finds its images by
 doing random web searches, and extracting images from the returned pages.
 It places the images on the root window by using the
-.BR xv (1),
 .BR giftopnm (1),
+.BR djpeg (1),
 and
-.BR djpeg (1)
+.BR xli (1),
+.BR xv (1),
+or
+.BR xloadimage (1)
 tools.
 
 \fIwebcollage\fP is written in
@@ -118,7 +121,9 @@ because most of the web is pictures of text.  Which is pretty sad.
 .SH SEE ALSO
 .BR X (1),
 .BR xscreensaver (1),
+.BR xli (1),
 .BR xv (1),
+.BR xloadimage (1),
 .BR ppmmake (1),
 .BR giftopnm (1),
 .BR pnmpaste (1),
index 81104d7fea13038182ccf183a1e2c005176ab5b1..b4cd5ba212d42f2c984656e8e45fbda792b42d1c 100644 (file)
 */
 
 
+/* Changelog ******************************************************************
+
+       1.0.1  19990716  Assume that XGetImage()/XDestroyImage() don't leak,
+                         which they apparently don't.  I have no idea how I
+                         convinced myself that they did.  Huh.  (greg@eod.com)
+       1.0.0  19990716  Initial release
+*/
+
+
 /* Arguments ******************************************************************
 
        -font font           Font to use
@@ -742,11 +751,8 @@ int main(int argc,char* argv[])
                                         image_Y,image_Width,image_Height);
                                }
 
-                               /* Free the image (and it's goddamned structure
-                                  -- the man page for XCreateImage() lies,
-                                  lies, lies!) */
+                               /* Free the image */
                                XDestroyImage(image_Image);
-                               XFree(image_Image);
                        }
 
                        /* Restore the error handler, ungrab the server */
index f21daea02c3b49842603ada6529c89e06668ea54..dbd8dc10800716774bcaa8ba926b74f993e77322 100644 (file)
--- a/setup.com
+++ b/setup.com
@@ -66,6 +66,7 @@ $ phosphor    :== $'mydir'phosphor
 $ pyro         :== $'mydir'pyro
 $ qix          :== $'mydir'qix
 $ rd-bomb      :== $'mydir'rd-bomb
+$ ripples      :== $'mydir'ripples
 $ rocks                :== $'mydir'rocks
 $ rorschach    :== $'mydir'rorschach
 $ rotor                :== $'mydir'rotor
index 5bcd2c27c3c8b4d0df0585640cecb6ce253276ba..e0925d0fc783792eb1403a835c916d218030ed2d 100644 (file)
@@ -167,7 +167,7 @@ get_pixel_resource (char *res_name, char *res_class,
 
 
 int
-parse_time (char *string, Bool seconds_default_p, Bool silent_p)
+parse_time (const char *string, Bool seconds_default_p, Bool silent_p)
 {
   unsigned int h, m, s;
   char c;
index 14ce1acb617b04f8fb9bc01c1029d12eb17e0f3c..0d97d569852073b8010ff78769957ce7e47dd7f4 100644 (file)
@@ -19,6 +19,7 @@ extern double get_float_resource (char*,char*);
 extern unsigned int get_pixel_resource (char*,char*,Display*,Colormap);
 extern unsigned int get_minutes_resource (char*,char*);
 extern unsigned int get_seconds_resource (char*,char*);
-extern int parse_time (char *string, Bool seconds_default_p, Bool silent_p);
+extern int parse_time (const char *string, Bool seconds_default_p,
+                       Bool silent_p);
 
 #endif /* __XSCREENSAVER_RESOURCES_H__ */
index 0c28fefd138f2c87cba58452b3d94cdbe102eb3a..e061b98b97609ddc0f5cafcc9bfd0c76ba329a1d 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
-       "@(#)xscreensaver 3.19 (30-Oct-99), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 3.20 (12-Nov-99), by Jamie Zawinski (jwz@jwz.org)";
index c37b6baa5e899628f12ff94e18398190a9bb1b33..1bf4942126cd264802fe8392e8f3f32ff92189a3 100644 (file)
@@ -263,7 +263,8 @@ pick_best_visual_of_class (Screen *screen, int visual_class)
       /* choose the 'best' one, if multiple */
       int i, best;
       Visual *visual;
-      for (i = 0, best = 0; i < out_count; i++)
+/*      for (i = 0, best = 0; i < out_count; i++) */
+      for (i = out_count-1, best = i; i >= 0; i--) /* go backwards */
        /* It's better if it's deeper, or if it's the same depth with
           more cells (does that ever happen?  Well, it could...) */
        if ((vi_out [i].depth > vi_out [best].depth) ||
index fab2d30dfc1276ff70a16387af0df9eceadd8b9d..89eb4b6ac6dc30bbd4f9491d3e8f2fbf623fc5ec 100644 (file)
@@ -1,7 +1,7 @@
 Begin3
 Title:          xscreensaver
-Version:        3.19
-Entered-date:   30OCT99
+Version:        3.20
+Entered-date:   12NOV99
 Description:    A modular screen saver and locker for the X Window System.
                 Highly customizable: allows the use of any program that
                 can draw on the root window as a display mode.
@@ -10,16 +10,16 @@ Keywords:       screen saver, screen lock, lock, xlock, X11
 Author:         jwz@jwz.org (Jamie Zawinski)
 Maintained-by:  jwz@jwz.org (Jamie Zawinski)
 Primary-site:   http://www.jwz.org/xscreensaver/
-                1163K xscreensaver-3.19.tar.gz
-                37K  xscreensaver.README
+                1257K xscreensaver-3.20.tar.gz
+                38K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
-                1163K xscreensaver-3.19.tar.gz
-                37K  xscreensaver.README
+                1257K xscreensaver-3.20.tar.gz
+                38K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: ftp.x.org /contrib/applications/
-                1163K xscreensaver-3.19.tar.gz
-                37K  xscreensaver.README
+                1257K xscreensaver-3.20.tar.gz
+                38K  xscreensaver.README
                 1K   xscreensaver.lsm
 Platforms:      Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
                 BSDI, SCO, OSF1, Ultrix, VMS.
index 8fab8fac83ca2e17ddd3bfc30eb8700ea7c82980..63a1ad84dc40a52477c2be47104772798e63a81a 100644 (file)
@@ -1,7 +1,7 @@
 Name: xscreensaver
 Summary: X screen saver and locker
 Vendor: Jamie Zawinski <jwz@jwz.org>
-Version: 3.19
+Version: 3.20
 Release: 1
 URL: http://www.jwz.org/xscreensaver/
 Source: xscreensaver-%{version}.tar.gz
@@ -60,10 +60,10 @@ install -m 4755 driver/xscreensaver $RPM_BUILD_ROOT/usr/X11R6/bin
       install -c -s $exe $RPM_BUILD_ROOT/usr/X11R6/bin
     done
     cd $RPM_BUILD_ROOT/usr/X11R6/bin
-    if [ -x xscreensaver-demo-Xaw3d ]; then target=Xaw3d; fi
     if [ -x xscreensaver-demo-Xaw   ]; then target=Xaw;   fi
-    if [ -x xscreensaver-demo-Gtk   ]; then target=Gtk;   fi
+    if [ -x xscreensaver-demo-Xaw3d ]; then target=Xaw3d; fi
     if [ -x xscreensaver-demo-Xm    ]; then target=Xm;    fi
+    if [ -x xscreensaver-demo-Gtk   ]; then target=Gtk;   fi
     rm -f xscreensaver-demo
     ln -s xscreensaver-demo-$target xscreensaver-demo
   fi