http://ftp.x.org/contrib/applications/xscreensaver-3.25.tar.gz
authorZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:42 +0000 (00:42 -0500)
committerZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:42 +0000 (00:42 -0500)
-rw-r--r-- 1 zblaxell zblaxell 1296507 Jul 17  2000 xscreensaver-3.25.tar.gz
682d0044dca27efa7e66315e8781015587b3f606  xscreensaver-3.25.tar.gz

51 files changed:
README
config.h.in
configure
configure.in
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/demo-Gtk.c
driver/lock.c
driver/screensaver-properties.desktop.in
driver/xscreensaver-command.man
driver/xscreensaver-demo.man
driver/xscreensaver.c
driver/xscreensaver.kss
driver/xscreensaver.man
hacks/Makefile.in
hacks/bsod.c
hacks/bubbles.c
hacks/bubbles.h
hacks/bumps.c
hacks/compile_axp.com
hacks/compile_decc.com
hacks/flow.c
hacks/glx/Makefile.in
hacks/glx/extrusion-helix2.c
hacks/glx/extrusion-helix3.c
hacks/glx/extrusion-helix4.c
hacks/glx/extrusion-joinoffset.c
hacks/glx/extrusion-screw.c
hacks/glx/extrusion-taper.c
hacks/glx/extrusion-twistoid.c
hacks/glx/extrusion.c
hacks/glx/pulsar.c
hacks/glx/sierpinski3d.c
hacks/maze.c
hacks/nerverot.c [new file with mode: 0644]
hacks/nerverot.man [new file with mode: 0644]
hacks/petri.c
hacks/petri.man [new file with mode: 0644]
hacks/screenhack.c
hacks/shadebobs.c
hacks/sonar.c
hacks/sonar.man
hacks/webcollage
hacks/xjack.c
hacks/xsublim.c
hacks/xsublim.man
setup.com
utils/version.h
xscreensaver.lsm
xscreensaver.spec

diff --git a/README b/README
index 5ff523c7fec208f34743f1aefc6c1cb38064982d..58ffc4e684a8557f853af293d39f0add70058c17 100644 (file)
--- a/README
+++ b/README
@@ -77,6 +77,20 @@ http://www.jwz.org/xscreensaver/.
 
                               ============
 
+Changes since 3.24:   * New hack, `nerverot'.
+                      * Added BSD kernel panic to `bsod'.
+                      * New version of `shadebobs'.
+                      * New version of `petri'.
+                      * Updated `webcollage' to handle recent Altavista URL
+                        format changes; made it search the AP photo gallery.
+                      * Revamped command-line options of `sonar' and made it
+                        properly handle subnets.
+                      * The `bubbles' hack can now trickle up or down the screen.
+                      * The `xsublim' hack can now read its text from programs.
+                      * Support for GLE version 3 in `extrusion'.
+                      * Fixed compilation problems in `maze'.
+                      * Fixed a rare crash in `flow'.
+                      * Fixes for minor installation problems.
 Changes since 3.23:   * Added `-ignorant' option to `maze' hack.
                       * Updates to `critical', `bsod', `xflame', and `flow'.
                       * Added support for Kerberos 5 (via its Kerberos 4
index b35e89a056e294c65e84c5caa9d42b6302313b8b..3e95a542dd10926b65bcf405e8ab292b7aa37cb7 100644 (file)
  */
 #undef HAVE_GLE
 
+/*  Define this if you have the -lgle from GLE version 3
+ */
+#undef HAVE_GLE3
+
 /*  Define this if the `xscreensaver' process itself (the driver process)
     should be linked against GL.  Most systems won't want this (in particular,
     if you're using Linux and/or Mesa, you don't want this) but SGI systems
index e6ae69898723b28fa9536164432ea57b8d5cd918..110c9606f6626ea83614c40080e829a1064b2b89 100755 (executable)
--- a/configure
+++ b/configure
@@ -7578,6 +7578,49 @@ GLE_LIBS=""
 if test "$with_gle" = yes; then
 
   
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  if test \! -z "$includedir" ; then 
+    CPPFLAGS="$CPPFLAGS -I$includedir"
+  fi
+  CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+  ac_safe=`echo "GL/gle.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for GL/gle.h""... $ac_c" 1>&6
+echo "configure:7600: checking for GL/gle.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 7605 "configure"
+#include "confdefs.h"
+#include <GL/gle.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7610: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  have_gle3=yes
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  CPPFLAGS="$ac_save_CPPFLAGS"
+  if test "$have_gle3" = yes ; then
+    have_gle=yes;
+  else
+    
   ac_save_CPPFLAGS="$CPPFLAGS"
   if test \! -z "$includedir" ; then 
     CPPFLAGS="$CPPFLAGS -I$includedir"
@@ -7585,17 +7628,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:7600: checking for GL/gutil.h" >&5
+echo "configure:7643: 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 7605 "configure"
+#line 7648 "configure"
 #include "confdefs.h"
 #include <GL/gutil.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7610: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7653: \"$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*
@@ -7617,8 +7660,8 @@ else
 fi
 
   CPPFLAGS="$ac_save_CPPFLAGS"
-  if test "$have_gle" = yes ; then
-    
+    if test "$have_gle" = yes ; then
+      
   ac_save_CPPFLAGS="$CPPFLAGS"
   if test \! -z "$includedir" ; then 
     CPPFLAGS="$CPPFLAGS -I$includedir"
@@ -7626,17 +7669,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:7641: checking for GL/tube.h" >&5
+echo "configure:7684: 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 7646 "configure"
+#line 7689 "configure"
 #include "confdefs.h"
 #include <GL/tube.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7651: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7694: \"$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*
@@ -7658,6 +7701,7 @@ else
 fi
 
   CPPFLAGS="$ac_save_CPPFLAGS"
+    fi
   fi
 
   if test "$have_gle" = yes ; then
@@ -7681,7 +7725,7 @@ fi
   LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for gleCreateGC in -lgle""... $ac_c" 1>&6
-echo "configure:7696: checking for gleCreateGC in -lgle" >&5
+echo "configure:7740: 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
@@ -7689,7 +7733,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgle $GL_LIBS -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7704 "configure"
+#line 7748 "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
@@ -7700,7 +7744,7 @@ int main() {
 gleCreateGC()
 ; return 0; }
 EOF
-if { (eval echo configure:7715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7759: \"$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
@@ -7739,6 +7783,71 @@ fi
 #                   [have_gle=yes; gle_halfassed=no],
 #                   [], $GL_LIBS -lX11 -lXext -lm)
 
+    # As of GLE 3 this is in libgle, and has changed name to uview_direction!
+    # *sigh*
+    if test "$have_gle3" = 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 $X_EXTRA_LIBS"
+
+  echo $ac_n "checking for uview_direction in -lgle""... $ac_c" 1>&6
+echo "configure:7819: checking for uview_direction in -lgle" >&5
+ac_lib_var=`echo gle'_'uview_direction | 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="-lgle $GL_LIBS -lX11 -lXext -lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7827 "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 uview_direction();
+
+int main() {
+uview_direction()
+; return 0; }
+EOF
+if { (eval echo configure:7838: \"$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_gle=yes; gle_halfassed=no
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  CPPFLAGS="$ac_save_CPPFLAGS"
+  LDFLAGS="$ac_save_LDFLAGS"
+#  LIBS="$ac_save_LIBS"
+  
+    fi
     # if it wasn't in libgle, then look in libmatrix.
     if test "$have_gle" = no ; then
       
@@ -7759,7 +7868,7 @@ fi
   LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for uview_direction_d in -lmatrix""... $ac_c" 1>&6
-echo "configure:7774: checking for uview_direction_d in -lmatrix" >&5
+echo "configure:7883: 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
@@ -7767,7 +7876,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lmatrix $GL_LIBS -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7782 "configure"
+#line 7891 "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
@@ -7778,7 +7887,7 @@ int main() {
 uview_direction_d()
 ; return 0; }
 EOF
-if { (eval echo configure:7793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7902: \"$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
@@ -7811,6 +7920,12 @@ fi
 #define HAVE_GLE 1
 EOF
 
+    if test "$have_gle3" = yes ; then
+      cat >> confdefs.h <<\EOF
+#define HAVE_GLE3 1
+EOF
+
+    fi
   fi
 
 elif test "$with_gle" != no; then
@@ -7845,7 +7960,7 @@ fi
 
     /*)
      echo $ac_n "checking for XPM headers""... $ac_c" 1>&6
-echo "configure:7860: checking for XPM headers" >&5
+echo "configure:7975: checking for XPM headers" >&5
      d=$with_xpm/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -7855,7 +7970,7 @@ echo "configure:7860: checking for XPM headers" >&5
      fi
 
      echo $ac_n "checking for XPM libs""... $ac_c" 1>&6
-echo "configure:7870: checking for XPM libs" >&5
+echo "configure:7985: checking for XPM libs" >&5
      d=$with_xpm/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -7888,17 +8003,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:7903: checking for X11/xpm.h" >&5
+echo "configure:8018: 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 7908 "configure"
+#line 8023 "configure"
 #include "confdefs.h"
 #include <X11/xpm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8028: \"$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*
@@ -7964,7 +8079,7 @@ fi
 
     /*)
      echo $ac_n "checking for XSHM headers""... $ac_c" 1>&6
-echo "configure:7979: checking for XSHM headers" >&5
+echo "configure:8094: checking for XSHM headers" >&5
      d=$with_xshm/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -7974,7 +8089,7 @@ echo "configure:7979: checking for XSHM headers" >&5
      fi
 
      echo $ac_n "checking for XSHM libs""... $ac_c" 1>&6
-echo "configure:7989: checking for XSHM libs" >&5
+echo "configure:8104: checking for XSHM libs" >&5
      d=$with_xshm/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -8009,17 +8124,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:8024: checking for X11/extensions/XShm.h" >&5
+echo "configure:8139: 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 8029 "configure"
+#line 8144 "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:8034: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8149: \"$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*
@@ -8053,17 +8168,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:8068: checking for sys/ipc.h" >&5
+echo "configure:8183: 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 8073 "configure"
+#line 8188 "configure"
 #include "confdefs.h"
 #include <sys/ipc.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8078: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8193: \"$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*
@@ -8098,17 +8213,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:8113: checking for sys/shm.h" >&5
+echo "configure:8228: 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 8118 "configure"
+#line 8233 "configure"
 #include "confdefs.h"
 #include <sys/shm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8123: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8238: \"$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*
@@ -8160,7 +8275,7 @@ fi
   LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS"
 
   echo $ac_n "checking for XShmQueryExtension in -lXextSam""... $ac_c" 1>&6
-echo "configure:8175: checking for XShmQueryExtension in -lXextSam" >&5
+echo "configure:8290: 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
@@ -8168,7 +8283,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lXextSam -lX11 -lXext -lm $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8183 "configure"
+#line 8298 "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
@@ -8179,7 +8294,7 @@ int main() {
 XShmQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:8194: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8309: \"$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
@@ -8246,7 +8361,7 @@ fi
 
     /*)
      echo $ac_n "checking for DOUBLE-BUFFER headers""... $ac_c" 1>&6
-echo "configure:8261: checking for DOUBLE-BUFFER headers" >&5
+echo "configure:8376: checking for DOUBLE-BUFFER headers" >&5
      d=$with_xdbe/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -8256,7 +8371,7 @@ echo "configure:8261: checking for DOUBLE-BUFFER headers" >&5
      fi
 
      echo $ac_n "checking for DOUBLE-BUFFER libs""... $ac_c" 1>&6
-echo "configure:8271: checking for DOUBLE-BUFFER libs" >&5
+echo "configure:8386: checking for DOUBLE-BUFFER libs" >&5
      d=$with_xdbe/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -8290,17 +8405,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:8305: checking for X11/extensions/Xdbe.h" >&5
+echo "configure:8420: 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 8310 "configure"
+#line 8425 "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:8315: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8430: \"$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*
@@ -8363,7 +8478,7 @@ fi
 
     /*)
      echo $ac_n "checking for XReadDisplay headers""... $ac_c" 1>&6
-echo "configure:8378: checking for XReadDisplay headers" >&5
+echo "configure:8493: checking for XReadDisplay headers" >&5
      d=$with_readdisplay/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -8373,7 +8488,7 @@ echo "configure:8378: checking for XReadDisplay headers" >&5
      fi
 
      echo $ac_n "checking for XReadDisplay libs""... $ac_c" 1>&6
-echo "configure:8388: checking for XReadDisplay libs" >&5
+echo "configure:8503: checking for XReadDisplay libs" >&5
      d=$with_readdisplay/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -8406,17 +8521,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:8421: checking for X11/extensions/readdisplay.h" >&5
+echo "configure:8536: 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 8426 "configure"
+#line 8541 "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:8431: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8546: \"$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*
@@ -8471,7 +8586,7 @@ fi
 
     /*)
      echo $ac_n "checking for Iris Video headers""... $ac_c" 1>&6
-echo "configure:8486: checking for Iris Video headers" >&5
+echo "configure:8601: checking for Iris Video headers" >&5
      d=$with_sgivideo/include
      if test -d $d; then
        X_CFLAGS="-I$d $X_CFLAGS"
@@ -8481,7 +8596,7 @@ echo "configure:8486: checking for Iris Video headers" >&5
      fi
 
      echo $ac_n "checking for Iris Video libs""... $ac_c" 1>&6
-echo "configure:8496: checking for Iris Video libs" >&5
+echo "configure:8611: checking for Iris Video libs" >&5
      d=$with_sgivideo/lib
      if test -d $d; then
        X_LIBS="-L$d $X_LIBS"
@@ -8514,17 +8629,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:8529: checking for dmedia/vl.h" >&5
+echo "configure:8644: 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 8534 "configure"
+#line 8649 "configure"
 #include "confdefs.h"
 #include <dmedia/vl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8539: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8654: \"$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*
@@ -8549,7 +8664,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:8564: checking for vlOpenVideo in -lvl" >&5
+echo "configure:8679: 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
@@ -8557,7 +8672,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lvl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8572 "configure"
+#line 8687 "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
@@ -8568,7 +8683,7 @@ int main() {
 vlOpenVideo()
 ; return 0; }
 EOF
-if { (eval echo configure:8583: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8698: \"$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
@@ -8639,7 +8754,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:8654: checking for $with_zippy_req" >&5
+echo "configure:8769: checking for $with_zippy_req" >&5
       if test -x "$with_zippy_req" ; then
         echo "$ac_t""yes" 1>&6
       else
@@ -8653,7 +8768,7 @@ echo "configure:8654: 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:8668: checking for $ac_word" >&5
+echo "configure:8783: 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
@@ -8703,7 +8818,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:8718: checking for $ac_word" >&5
+echo "configure:8833: 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
@@ -8737,7 +8852,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:8752: checking for $ac_word" >&5
+echo "configure:8867: 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
@@ -8772,7 +8887,7 @@ done
 
   if test -n "$emacs_exe" ; then
     echo $ac_n "checking for emacs yow""... $ac_c" 1>&6
-echo "configure:8787: checking for emacs yow" >&5
+echo "configure:8902: checking for emacs yow" >&5
     #
     # get emacs to tell us where the libexec directory is.
     #
@@ -8794,7 +8909,7 @@ echo "configure:8787: 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:8809: checking for xemacs yow" >&5
+echo "configure:8924: checking for xemacs yow" >&5
     if test -n "$xemacs_exe" ; then
       #
       # get xemacs to tell us where the libexec directory is.
@@ -8853,7 +8968,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:8868: checking for $ac_word" >&5
+echo "configure:8983: 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
@@ -8889,7 +9004,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:8904: checking for $ac_word" >&5
+echo "configure:9019: 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
index 57529eb7cb1da1af5bf15217308be81a962e70bb..c6688070bf6646bba305ae7d07de19987aad6c09 100644 (file)
@@ -2066,9 +2066,14 @@ GLE_LIBS=""
 
 if test "$with_gle" = yes; then
 
-  AC_CHECK_X_HEADER(GL/gutil.h, have_gle=yes, have_gle=no)
-  if test "$have_gle" = yes ; then
-    AC_CHECK_X_HEADER(GL/tube.h, have_gle=yes, have_gle=no)
+  AC_CHECK_X_HEADER(GL/gle.h, have_gle3=yes, have_gle3=no)
+  if test "$have_gle3" = yes ; then
+    have_gle=yes;
+  else
+    AC_CHECK_X_HEADER(GL/gutil.h, have_gle=yes, have_gle=no)
+    if test "$have_gle" = yes ; then
+      AC_CHECK_X_HEADER(GL/tube.h, have_gle=yes, have_gle=no)
+    fi
   fi
 
   if test "$have_gle" = yes ; then
@@ -2092,6 +2097,13 @@ if test "$with_gle" = yes; then
 #                   [have_gle=yes; gle_halfassed=no],
 #                   [], $GL_LIBS -lX11 -lXext -lm)
 
+    # As of GLE 3 this is in libgle, and has changed name to uview_direction!
+    # *sigh*
+    if test "$have_gle3" = yes ; then
+      AC_CHECK_X_LIB(gle, uview_direction, 
+                     [have_gle=yes; gle_halfassed=no],
+                    [], $GL_LIBS -lX11 -lXext -lm)
+    fi
     # if it wasn't in libgle, then look in libmatrix.
     if test "$have_gle" = no ; then
       AC_CHECK_X_LIB(matrix, uview_direction_d, 
@@ -2103,6 +2115,9 @@ if test "$with_gle" = yes; then
 
   if test "$have_gle" = yes ; then
     AC_DEFINE(HAVE_GLE)
+    if test "$have_gle3" = yes ; then
+      AC_DEFINE(HAVE_GLE3)
+    fi
   fi
 
 elif test "$with_gle" != no; then
index 393bc2188d919b4d88e3b3c262869339dbe81f9e..3c2dbced1a30fb397b39d6b065f0d39a156750ea 100644 (file)
@@ -35,6 +35,7 @@ SHELL         = /bin/sh
 INSTALL                = @INSTALL@
 SUID_FLAGS      = -o root -m 4755
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT  = @INSTALL_PROGRAM@
 INSTALL_SETUID  = @INSTALL_SETUID@
 INSTALL_DATA   = @INSTALL_DATA@
 INSTALL_DIRS   = @INSTALL_DIRS@
@@ -323,23 +324,55 @@ install-pam:
        fi
 
 install-gnome: screensaver-properties.desktop
-       @if [ "$(GNOME_DATADIR)" != "" ]; then                               \
-          echo $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop      \
-                          $(GNOME_CCDIR)/screensaver-properties.desktop    ; \
-               $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop      \
-                          $(GNOME_CCDIR)/screensaver-properties.desktop    ; \
-          echo $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop      \
-                       $(GNOME_PANELDIR)/screensaver-properties.desktop    ; \
-               $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop      \
-                       $(GNOME_PANELDIR)/screensaver-properties.desktop    ; \
-       fi
+       @lost1=""                                                            ;\
+         lost2=""                                                            ;\
+         if [ "$(install_prefix)$(GNOME_DATADIR)" != "" ]; then               \
+           echo    $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop   \
+             $(install_prefix)$(GNOME_CCDIR)/screensaver-properties.desktop  ;\
+           if      $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop   \
+             $(install_prefix)$(GNOME_CCDIR)/screensaver-properties.desktop  ;\
+             then true                                                       ;\
+           else                                                               \
+             lost1="$(install_prefix)$(GNOME_CCDIR)"                         ;\
+           fi                                                                ;\
+           echo $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop      \
+                        $(GNOME_PANELDIR)/screensaver-properties.desktop     ;\
+           if   $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop      \
+       $(install_prefix)$(GNOME_PANELDIR)/screensaver-properties.desktop     ;\
+             then true                                                       ;\
+           else                                                               \
+             lost2="$(install_prefix)$(GNOME_PANELDIR)"                      ;\
+           fi                                                                ;\
+           if [ "$$lost1" != "" -o "$$lost2" != "" ]; then                    \
+             e=echo ;                                                         \
+ $$e ""                                                                      ;\
+ $$e "  ####################################################################";\
+ $$e "  Warning: unable to install screensaver-properties.desktop into"      ;\
+                 plurality="this file"                                       ;\
+          if [ "$$lost1" != "" -a "$$lost2" != "" ]; then                     \
+ $$e "           $$lost1/ or into"                                           ;\
+ $$e "           $$lost2/."                                                  ;\
+                 plurality="these files"                                     ;\
+          elif [ "$$lost1" != "" ]; then                                      \
+ $$e "           $$lost1/."                                                  ;\
+          else                                                                \
+ $$e "           $$lost2/."                                                  ;\
+          fi                                                                 ;\
+ $$e "           Without $$plurality," 'the "Screen Saver" section of the'   ;\
+ $$e "           Gnome Control Center (gnomecc) will not work properly."     ;\
+ $$e "  ####################################################################";\
+ $$e ""                                                                      ;\
+             exit 1 ;                                                         \
+           fi                                                                ;\
+         fi
 
 uninstall-gnome:
-       @if [ "$(GNOME_DATADIR)" != "" ]; then                                \
-         echo rm -f $(GNOME_CCDIR)/screensaver-properties.desktop          ; \
-              rm -f $(GNOME_CCDIR)/screensaver-properties.desktop          ; \
-         echo rm -f $(GNOME_PANELDIR)/screensaver-properties.desktop       ; \
-              rm -f $(GNOME_PANELDIR)/screensaver-properties.desktop       ; \
+       @if [ "$(install_prefix)$(GNOME_DATADIR)" != "" ]; then               \
+          f=screensaver-properties.desktop                                   ;\
+          echo rm -f $(install_prefix)$(GNOME_CCDIR)/$$f                     ;\
+               rm -f $(install_prefix)$(GNOME_CCDIR)/$$f                     ;\
+          echo rm -f $(install_prefix)$(GNOME_PANELDIR)/$$f                  ;\
+               rm -f $(install_prefix)$(GNOME_PANELDIR)/$$f                  ;\
         fi
 
 install-kde:
@@ -347,8 +380,8 @@ install-kde:
        if [ "$$KDEDIR" != "" ]; then                                         \
          dir="$(install_prefix)$$KDEDIR/bin" ;                               \
          dest="$$dir/xscreensaver.kss" ;                                     \
-         echo $(INSTALL_PROGRAM) $$src $$dest ;                              \
-         if $(INSTALL_PROGRAM) $$src $$dest ; then                           \
+         echo $(INSTALL_SCRIPT) $$src $$dest ;                               \
+         if $(INSTALL_SCRIPT) $$src $$dest ; then                            \
            true ;                                                            \
          else                                                                \
            e=echo ;                                                          \
@@ -425,7 +458,7 @@ update_ad_version::
        echo -n "Updating version number in $$S to $$V $$D... " ;           \
        T=/tmp/xs.$$$$ ;                                                    \
        sed -e "s/\(.*version \)[0-9][0-9]*\.[0-9]*\(.*\)/\1$$V\2/"         \
-           -e "s/\([0-9][0-9]-[A-Z][a-z][a-z]-[0-9][0-9]\)/$$D/"           \
+           -e "s/\([0-9][0-9]-[A-Z][a-z][a-z]-[0-9][0-9][0-9]*\)/$$D/"     \
          < $$S > $$T ;                                                     \
        if cmp -s $$S $$T ; then                                            \
          echo "unchanged." ;                                               \
index 4dd691ff7ef54b75c6ebaa12ed1829e50fd625a0..03c4231bcd959a95871b40066571ef19ddf3fcdc 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 3.24
-!                              03-Apr-200000
+!                              version 3.25
+!                              19-Jul-2000
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
                                bumps -root                                 \n\
                                xteevee -root                               \n\
                                xspirograph -root                           \n\
+                               nerverot -root                              \n\
+-          "NerveRot (dense)"  nerverot -root -count 1000                  \n\
+-          "NerveRot (thick)"  nerverot -root -count 64 -line-width 4      \n\
   color:                       bubbles -root                               \n\
   default-n:                   webcollage -root                            \n\
   default-n:  "WebCollage (whacked)"                                         \
@@ -1071,6 +1074,11 @@ loss of vertical hold, and a test pattern.  By Greg Knauss.
 Simulates that pen-in-nested-plastic-gears toy from your childhood.     \
 By Rohit Singh.
 
+*hacks.nerverot.name: NerveRot
+*hacks.nerverot.documentation:                                          \
+Draws a rolling tube, composed of nervously vibrating squiggles.       \
+By Dan Bornstein.
+
 *hacks.webcollage.name: WebCollage
 *hacks.webcollage.documentation:                                       \
 This program makes collages out of random images pulled off of the     \
@@ -1269,5 +1277,4 @@ connection to the Internet.                                               \
 By Scott Draves.  You can find it at <http://www.electricsheep.org/>.   \
 See that web site for configuration information.
 
-
 ! (xrdb prevention kludge: whole file) */
index 667edf9001cb6ddef7d5c0b614038df082a47082..550600cbe05fff5f167cfaed721c39e7687686a9 100644 (file)
                                bumps -root                                 \\n\
                                xteevee -root                               \\n\
                                xspirograph -root                           \\n\
+                               nerverot -root                              \\n\
+-          \"NerveRot (dense)\"        nerverot -root -count 1000                  \\n\
+-          \"NerveRot (thick)\"        nerverot -root -count 64 -line-width 4      \\n\
   color:                       bubbles -root                               \\n\
   default-n:                   webcollage -root                            \\n\
   default-n:  \"WebCollage (whacked)\"                                       \
@@ -789,6 +792,10 @@ loss of vertical hold, and a test pattern.  By Greg Knauss.",
 "*hacks.xspirograph.documentation:                                     \
 Simulates that pen-in-nested-plastic-gears toy from your childhood.     \
 By Rohit Singh.",
+"*hacks.nerverot.name: NerveRot",
+"*hacks.nerverot.documentation:                                          \
+Draws a rolling tube, composed of nervously vibrating squiggles.       \
+By Dan Bornstein.",
 "*hacks.webcollage.name: WebCollage",
 "*hacks.webcollage.documentation:                                      \
 This program makes collages out of random images pulled off of the     \
index 11c64d8985de896a76f8c47856559f4da3c80aae..02eb701f3e2d616ca3c696ce0be61b27f1d3789d 100644 (file)
@@ -257,12 +257,16 @@ warning_dialog (GtkWidget *parent, const char *message,
       sprintf (name, "label%d", i++);
 
       {
+#if 0
         char buf[255];
+#endif
         label = gtk_label_new (head);
+#if 0
         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"));
+#endif
         if (center <= 0)
           gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
@@ -1268,7 +1272,7 @@ static char *down_arrow_xpm[] = {
 };
 
 static void
-pixmapify_buttons (GtkWidget *toplevel)
+pixmapify_button (GtkWidget *toplevel, int down_p)
 {
   GdkPixmap *pixmap;
   GdkBitmap *mask;
@@ -1276,27 +1280,31 @@ pixmapify_buttons (GtkWidget *toplevel)
   GtkStyle *style;
   GtkWidget *w;
 
-  w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel), "next"));
+  w = GTK_WIDGET (name_to_widget (GTK_WIDGET (toplevel),
+                                  (down_p ? "next" : "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 **) down_arrow_xpm);
+                                         (down_p
+                                          ? (gchar **) down_arrow_xpm
+                                          : (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);
+}
 
-  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);
+static void
+map_next_button_cb (GtkWidget *w, gpointer user_data)
+{
+  pixmapify_button (w, 1);
+}
+
+static void
+map_prev_button_cb (GtkWidget *w, gpointer user_data)
+{
+  pixmapify_button (w, 0);
 }
 
 
@@ -1764,7 +1772,6 @@ map_window_cb (GtkWidget *w, gpointer user_data)
 {
   Boolean oi = initializing_p;
   initializing_p = True;
-  pixmapify_buttons (w);
   eschew_gtk_lossage (w);
   ensure_selected_item_visible (GTK_WIDGET(name_to_widget(w, "list")));
   initializing_p = oi;
@@ -1775,11 +1782,6 @@ int
 main (int argc, char **argv)
 {
   XtAppContext app;
-# ifdef HAVE_CRAPPLET
-  GnomeClient *client;
-  GnomeClientFlags flags;
-  int init_results;
-# endif /* HAVE_CRAPPLET */
   prefs_pair Pair, *pair;
   saver_preferences P, P2, *p, *p2;
   Bool prefs = False;
@@ -1858,9 +1860,21 @@ main (int argc, char **argv)
 # ifdef HAVE_CRAPPLET
   if (crapplet_p)
     {
-      init_results = gnome_capplet_init ("screensaver-properties",
-                                         short_version,
-                                         argc, argv, NULL, 0, NULL);
+      GnomeClient *client;
+      GnomeClientFlags flags = 0;
+
+      int init_results = gnome_capplet_init ("screensaver-properties",
+                                             short_version,
+                                             argc, argv, NULL, 0, NULL);
+      /* init_results is:
+         0 upon successful initialization;
+         1 if --init-session-settings was passed on the cmdline;
+         2 if --ignore was passed on the cmdline;
+        -1 on error.
+
+         So the 1 signifies just to init the settings, and quit, basically.
+         (Meaning launch the xscreensaver daemon.)
+       */
 
       if (init_results < 0)
         {
@@ -1878,14 +1892,38 @@ main (int argc, char **argv)
 
       if (client)
         flags = gnome_client_get_flags (client);
-      else
-        flags = 0;
 
       if (flags & GNOME_CLIENT_IS_CONNECTED)
         {
-          gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
+          int token =
+            gnome_startup_acquire_token ("GNOME_SCREENSAVER_PROPERTIES",
+                                         gnome_client_get_id (client));
+          if (token)
+            {
+              char *session_args[20];
+              int i = 0;
+              session_args[i++] = real_progname;
+              session_args[i++] = "--capplet";
+              session_args[i++] = "--init-session-settings";
+              session_args[i] = 0;
+              gnome_client_set_priority (client, 20);
+              gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY);
+              gnome_client_set_restart_command (client, i, session_args);
+            }
+          else
+            {
+              gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
+            }
+
           gnome_client_flush (client);
         }
+
+      if (init_results == 1)
+       {
+         system ("xscreensaver -nosplash &");
+         return 0;
+       }
+
     }
   else
 # endif /* HAVE_CRAPPLET */
@@ -2022,6 +2060,12 @@ main (int argc, char **argv)
   gtk_signal_connect (
               GTK_OBJECT (name_to_widget (GTK_WIDGET (gtk_window), "list")),
               "map", GTK_SIGNAL_FUNC(map_window_cb), 0);
+  gtk_signal_connect (
+              GTK_OBJECT (name_to_widget (GTK_WIDGET (gtk_window), "prev")),
+              "map", GTK_SIGNAL_FUNC(map_prev_button_cb), 0);
+  gtk_signal_connect (
+              GTK_OBJECT (name_to_widget (GTK_WIDGET (gtk_window), "next")),
+              "map", GTK_SIGNAL_FUNC(map_next_button_cb), 0);
 
 
   /* Handle the -prefs command-line argument. */
@@ -2046,10 +2090,6 @@ main (int argc, char **argv)
       gtk_container_remove (GTK_CONTAINER (gtk_window), top_vbox);
       GTK_OBJECT_SET_FLAGS (top_vbox, GTK_FLOATING);
 
-      /* This is a crock, but otherwise, the Control Center expands to
-         be as tall as the screen. */
-      gtk_window_set_default_size (GTK_WINDOW (top_vbox), 600, 400);
-
       /* In crapplet-mode, take off the menubar. */
       gtk_widget_hide (name_to_widget (gtk_window, "menubar"));
 
index 194752d1cf5e4404882a4b95ef725dc0b6a8f4f1..bd44a1afc3eb5f3eaf7ca2513b1e8a706bd3b8c8 100644 (file)
@@ -170,7 +170,7 @@ make_passwd_window (saver_info *si)
     pw->heading_label = s;
   }
 
-  pw->user_string = (p->pw_name ? p->pw_name : "???");
+  pw->user_string = (p && p->pw_name ? p->pw_name : "???");
   pw->passwd_string = strdup("");
 
   f = get_string_resource ("passwd.headingFont", "Dialog.Font");
index cdcd3e09b26a82d35a5a4b677bf1246886669565..85328e0792b5ea55931422af109e3bfd839feef5 100644 (file)
@@ -36,7 +36,7 @@ Comment[pt]=Configura as op
 Comment[ru]=îÁÓÔÒÏÊËÁ ÈÒÁÎÉÔÅÌÑ ÜËÒÁÎÁ.
 Comment[sv]=Ändra inställningar för skärmsläckare
 Comment[wa]=Apontiaedje do spårgneu di waitroûle
-Exec=@bindir@/xscreensaver-demo --crapplet
+Exec=xscreensaver-demo --crapplet
 Icon=gnome-ccscreensaver.png
 Terminal=0
 Type=Application
index 5e66859f6958d458b4bf972618772fe5aa8a6499..fcd0dc7ae73b515aac60f978437c71863036ec8f 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "03-Apr-2000 (3.24)" "X Version 11"
+.TH XScreenSaver 1 "19-Jul-2000 (3.25)" "X Version 11"
 .SH NAME
 xscreensaver-command - control a running xscreensaver process
 .SH SYNOPSIS
index 578ad9c0798e903d1c17047cc1161aadd792c623..d1e0feebfff19656251980d01364234d60a3ebae 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "03-Apr-2000 (3.24)" "X Version 11"
+.TH XScreenSaver 1 "19-Jul-2000 (3.25)" "X Version 11"
 .SH NAME
 xscreensaver-demo - interactively control the background xscreensaver daemon
 .SH SYNOPSIS
index 9b26390bd6b40c092003ed5e65d192cac371fa42..5ed966ecb819e444705abcaf219ec6783b81b75d 100644 (file)
@@ -1071,7 +1071,7 @@ main (int argc, char **argv)
   global_si_kludge = si;       /* I hate C so much... */
 
 # undef ya_rand_init
-  ya_rand_init ((int) time ((time_t *) 0));
+  ya_rand_init (0);
 
   save_argv (argc, argv);
   set_version_string (si, &argc, argv);
index dac4d9841ca9c7687f4b3f950449078044814788..1b22f0b30709292b5f18cae4d94298232f485d6a 100755 (executable)
@@ -104,9 +104,10 @@ while [ -n "$1" ]; do
 done
 
 if [ -n "$Install" ] ; then
-  rm $HOME/.kss-preview*                                # Remove old preview files
   PID_FILE=$HOME/.kss-install.pid.`hostname`
-  kill `cat $PID_FILE`                                  # Kill old screensaver 
+  if [ -r "$PID_FILE" ] ; then
+    kill `cat $PID_FILE`                                # Kill old screensaver 
+  fi
   echo "$$" > $PID_FILE                                 # Write PID of this script
   /usr/X11R6/bin/xscreensaver -no-splash $timeout $lockmode $Nice &    # Start XScreenSaver daemon
   trap "kill $!" SIGTERM                                # Set these to kill the daemon
index f15cd3bc23588bec0397bed9e2f201d9dd4fc36e..98931f7b99272210ac6fb0ab43a6fc534750a99f 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "03-Apr-2000 (3.24)" "X Version 11"
+.TH XScreenSaver 1 "19-Jul-2000 (3.25)" "X Version 11"
 .SH NAME
 xscreensaver - graphics hack and screen locker, launched when the user is idle
 .SH SYNOPSIS
index 24927d93d3d3d0b8dadb91cbaef8defdd3bcaf41..80d2377e30b2d223d2506be1c3cf897591628128 100644 (file)
@@ -86,7 +86,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 ripples.c xteevee.c xspirograph.c
+                 blaster.c bumps.c ripples.c xteevee.c xspirograph.c nerverot.c
 SCRIPTS                = vidwhacker webcollage
 
 OBJS           = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
@@ -105,7 +105,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 ripples.o xteevee.o xspirograph.o
+                 blaster.o bumps.o ripples.o xteevee.o xspirograph.o nerverot.o
 
 EXES           = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
@@ -119,7 +119,7 @@ EXES                = attraction blitspin bouboule braid bubbles decayscreen deco \
                  sonar demon loop t3d penetrate deluxe compass squiral \
                  xflame wander spotlight critical phosphor xmatrix petri \
                  shadebobs xsublim ccurve blaster bumps ripples xteevee \
-                 xspirograph
+                 xspirograph nerverot
 
 HACK_OBJS_1    = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
@@ -147,7 +147,8 @@ MEN         = attraction.man blitspin.man bouboule.man braid.man \
                  xjack.man xlyap.man jigsaw.man epicycle.man bsod.man \
                  sonar.man t3d.man squiral.man spotlight.man critical.man \
                  vidwhacker.man webcollage.man xsublim.man distort.man \
-                 phosphor.man xmatrix.man xteevee.man xflame.man
+                 phosphor.man xmatrix.man xteevee.man xflame.man petri.man \
+                 nerverot.man
 STAR           = *
 EXTRAS         = README Makefile.in xlock_23.h .gdbinit \
                  images/$(STAR).xbm \
@@ -568,6 +569,9 @@ xteevee:    xteevee.o       $(HACK_OBJS) $(GRAB)
 xspirograph:   xspirograph.o   $(HACK_OBJS) $(COL) $(ERASE)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS)
 
+nerverot:      nerverot.o      $(HACK_OBJS) $(COL)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(HACK_LIBS)
+
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
@@ -1780,4 +1784,13 @@ xspirograph.o: $(UTILS_SRC)/colors.h
 xspirograph.o: $(UTILS_SRC)/grabscreen.h
 xspirograph.o: $(UTILS_SRC)/visual.h
 xspirograph.o: $(UTILS_SRC)/erase.h
+nerverot.o: $(srcdir)/screenhack.h
+nerverot.o: ../config.h
+nerverot.o: $(UTILS_SRC)/yarandom.h
+nerverot.o: $(UTILS_SRC)/usleep.h
+nerverot.o: $(UTILS_SRC)/resources.h
+nerverot.o: $(UTILS_SRC)/hsv.h
+nerverot.o: $(UTILS_SRC)/colors.h
+nerverot.o: $(UTILS_SRC)/grabscreen.h
+nerverot.o: $(UTILS_SRC)/visual.h
 
index 5decc5c61dddcf0170ff682a904ad8b010c557c2..a65684615ccdf12f69d8d4682fbefe5567a75fee 100644 (file)
@@ -510,6 +510,150 @@ sparc_linux (Display *dpy, Window window, int delay)
   return True;
 }
 
+/* BSD Panic by greywolf@starwolf.com - modeled after the Linux panic above.
+   By Grey Wolf <greywolf@siteROCK.com>
+ */
+static Bool
+bsd (Display *dpy, Window window, int delay)
+{
+  XGCValues gcv;
+  XWindowAttributes xgwa;
+  char *fontname;
+  const char *def_font = "fixed";
+  XFontStruct *font;
+  GC gc;
+  int lines = 1;
+  int i, n, b;
+  const char *rbstr, *panicking;
+  char syncing[80], bbuf[5], *bp;
+
+  const char *panicstr[] =
+   {"panic: ifree: freeing free inode",
+    "panic: blkfree: freeing free block",
+    "panic: improbability coefficient below zero",
+    "panic: cgsixmmap",
+    "panic: crazy interrupts",
+    "panic: nmi",
+    "panic: attempted windows install",
+    "panic: don't",
+    "panic: free inode isn't",
+    "panic: cpu_fork: curproc",
+    "panic: malloc: out of space in kmem_map",
+    "panic: vogon starship detected",
+    "panic: teleport chamber: out of order",
+    "panic: Brain fried - core dumped"};
+     
+  if (!get_boolean_resource("doBSD", "DoBSD"))
+    return False;
+
+  for (i = 0; i < sizeof(syncing); i++)
+    syncing[i] = 0;
+
+  i = (random() & 0xffff) % (sizeof(panicstr) / sizeof(*panicstr));
+
+  panicking = panicstr[i];
+  strcpy(syncing, "Syncing disks: ");
+
+  b = (random() & 0xff) % 40;
+  for (n = 0; (n < 20) && (b > 0); n++)
+    {
+      if (i)
+        {
+          i = (random() & 0x7);
+          b -= (random() & 0xff) % 20;
+          if (b < 0)
+            b = 0;
+        }
+      sprintf (bbuf, "%d ", b);
+      strcat (syncing, bbuf);
+    }
+
+  if (b)
+    rbstr = "damn!";
+  else
+    rbstr = "sunk!";
+
+  lines = 5;
+
+  XGetWindowAttributes (dpy, window, &xgwa);
+
+  fontname = get_string_resource ((xgwa.height > 600
+                                  ? "bsd.font2"
+                                  : "bsd.font"),
+                                 "BSD.Font");
+  if (!fontname || !*fontname) fontname = (char *)def_font;
+  font = XLoadQueryFont (dpy, fontname);
+  if (!font) font = XLoadQueryFont (dpy, def_font);
+  if (!font) exit(-1);
+  if (fontname && fontname != def_font)
+    free (fontname);
+
+  gcv.font = font->fid;
+  gcv.foreground = get_pixel_resource(("bsd.foreground"),
+                                     "BSD.Foreground",
+                                     dpy, xgwa.colormap);
+  gcv.background = get_pixel_resource(("bsd.background"),
+                                     "BSD.Background",
+                                     dpy, xgwa.colormap);
+  XSetWindowBackground(dpy, window, gcv.background);
+  XClearWindow(dpy, window);
+
+  gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
+
+  draw_string(dpy, window, gc, &gcv, font,
+             10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
+             10, 10,
+             panicking, 0);
+  XSync(dpy, False);
+  lines--;
+
+  for (bp = syncing; *bp;)
+    {
+      char *bsd_bufs, oc;
+      for (;*bp && (*bp != ' '); bp++)
+        ;
+      if (*bp == ' ')
+        {
+          oc = *bp;
+          *bp = 0;
+        }
+      bsd_bufs = strdup(syncing);
+      draw_string(dpy, window, gc, &gcv, font,
+                  10,
+                  xgwa.height - (lines * (font->ascent + font->descent + 1)),
+                  10, 10,
+                  bsd_bufs, 0);
+      XSync(dpy, False);
+      free(bsd_bufs);
+      if (oc)
+       *bp = oc;
+      if (bsod_sleep(dpy, -1))
+        goto DONE;
+      bp++;
+    }
+
+  lines--;
+  
+  draw_string(dpy, window, gc, &gcv, font,
+             10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
+             10, 10,
+             rbstr, 0);
+  lines--;
+  draw_string(dpy, window, gc, &gcv, font,
+             10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
+             10, 10,
+             "Rebooting", 0);
+
+  XFreeGC(dpy, gc);
+  XSync(dpy, False);
+  bsod_sleep(dpy, delay);
+
+DONE:
+  XClearWindow(dpy, window);
+  XFreeFont(dpy, font);
+  return True;
+}
+
 static Bool
 amiga (Display *dpy, Window window, int delay)
 {
@@ -1112,6 +1256,7 @@ char *defaults [] = {
   "*doAtari:              False",      /* boring */
   "*doMacsBug:            True",
   "*doSCO:                True",
+  "*doBSD:                False",      /* boring */
   "*doSparcLinux:         False",      /* boring */
   "*doBlitDamage:          True",
 
@@ -1149,6 +1294,13 @@ char *defaults [] = {
   ".SparcLinux.font2:     -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
   ".SparcLinux.foreground: White",
   ".SparcLinux.background: Black",
+
+  ".BSD.font:              vga",
+  ".BSD.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
+  ".BSD.font2:             -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+/* ".BSD.font2:                    -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*", */
+  ".BSD.foreground:        #c0c0c0",
+  ".BSD.background:        Black",
   0
 };
 
@@ -1178,7 +1330,7 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       Bool did;
-      do {  i = (random() & 0xFF) % 9; } while (i == j);
+      do {  i = (random() & 0xFF) % 10; } while (i == j);
       switch (i)
        {
        case 0: did = windows(dpy, window, delay, True); break;
@@ -1188,8 +1340,9 @@ screenhack (Display *dpy, Window window)
        case 4: did = macsbug(dpy, window, delay); break;
        case 5: did = sco(dpy, window, delay); break;
        case 6: did = sparc_linux(dpy, window, delay); break;
-       case 7: did = atari(dpy, window, delay); break;
-       case 8: did = blitdamage(dpy, window, delay); break;
+       case 7: did = bsd(dpy, window, delay); break;
+       case 8: did = atari(dpy, window, delay); break;
+       case 9: did = blitdamage(dpy, window, delay); break;
        default: abort(); break;
        }
       loop++;
index 913fe03726df2c676d19b80902dfd24cbdb2a5db..f92b433466714751ae2d0a78a8c90f1f37df8d47 100644 (file)
@@ -1,6 +1,6 @@
 /* bubbles.c - frying pan / soft drink in a glass simulation */
 
-/*$Id: bubbles.c,v 1.16 1998/11/19 07:25:01 jwz Exp $*/
+/*$Id: bubbles.c,v 1.17 2000/07/19 06:38:42 jwz Exp $*/
 
 /*
  *  Copyright (C) 1995-1996 James Macnicol
@@ -36,7 +36,7 @@
  * and things are _much_ nicer.)
  *
  * Author:           James Macnicol 
- * Internet E-mail : J.Macnicol@student.anu.edu.au
+ * Internet E-mail : j-macnicol@adfa.edu.au
  */
 
 #include <math.h>
@@ -72,6 +72,7 @@
 extern void init_default_bubbles(void);
 extern int num_default_bubbles;
 extern char **default_bubbles[];
+static int drop_bubble( Bubble *bb );
 
 char *progclass = "Bubbles";
 
@@ -83,6 +84,8 @@ char *defaults [] = {
   "*delay:             800",
   "*quiet:             false", 
   "*nodelay:           false",
+  "*drop:              false",
+  "*trails:            false",
   "*3D:                        false",
   0
 };
@@ -96,6 +99,9 @@ XrmOptionDescRec options [] = {
   { "-nodelay",         ".nodelay",     XrmoptionNoArg, "true" },
   { "-3D",          ".3D",      XrmoptionNoArg, "true" },
   { "-delay",           ".delay",       XrmoptionSepArg, 0 },
+  { "-drop",            ".drop",        XrmoptionNoArg, "true" },
+  { "-rise",            ".rise",        XrmoptionNoArg, "true" },
+  { "-trails",          ".trails",      XrmoptionNoArg, "true" },
   { 0, 0, 0, 0 }
 };
 
@@ -128,6 +134,7 @@ static Visual *defvisual;
 static int bubble_min_radius;
 static int bubble_max_radius;
 static long *bubble_areas;
+static int *bubble_droppages;
 static GC draw_gc, erase_gc;
 
 #ifdef HAVE_XPM
@@ -144,6 +151,9 @@ static Bool simple = True;
 static Bool broken = False;
 static Bool quiet = False;
 static Bool threed = False;
+static Bool drop = False;
+static Bool trails = False;
+static int drop_dir;
 static int delay;
 
 /* 
@@ -747,24 +757,36 @@ bubble_eat(Bubble *diner, Bubble *food)
   diner->area += food->area;
   delete_bubble_in_mesh(food, DELETE_BUBBLE);
 
-  if ((simple) && (diner->area > bubble_areas[bubble_max_radius])) {
-    delete_bubble_in_mesh(diner, DELETE_BUBBLE);
-    return 0;
-  }
+  if (drop) {
+       if ((simple) && (diner->area > bubble_areas[bubble_max_radius])) {
+         diner->area = bubble_areas[bubble_max_radius];
+       }
 #ifdef HAVE_XPM
-  if ((! simple) && (diner->area > 
-                    step_pixmaps[num_bubble_pixmaps]->area)) {
-    delete_bubble_in_mesh(diner, DELETE_BUBBLE);
-    return 0;
+       if ((! simple) && (diner->area > step_pixmaps[num_bubble_pixmaps]->area)) {
+         diner->area = step_pixmaps[num_bubble_pixmaps]->area;
+       }
+#endif /* HAVE_XPM */
   }
+  else {
+       if ((simple) && (diner->area > bubble_areas[bubble_max_radius])) {
+         delete_bubble_in_mesh(diner, DELETE_BUBBLE);
+         return 0;
+       }
+#ifdef HAVE_XPM
+       if ((! simple) && (diner->area > 
+                                          step_pixmaps[num_bubble_pixmaps]->area)) {
+         delete_bubble_in_mesh(diner, DELETE_BUBBLE);
+         return 0;
+       }
 #endif /* HAVE_XPM */
+  }
 
   if (simple) {
     if (diner->area > bubble_areas[diner->radius + 1]) {
       /* Move the bubble to a new radius */
       i = diner->radius;
-      while (diner->area > bubble_areas[i+1])
-       ++i;
+      while ((i < bubble_max_radius - 1) && (diner->area > bubble_areas[i+1]))
+               ++i;
       diner->radius = i;
     }
     show_bubble(diner);
@@ -772,8 +794,8 @@ bubble_eat(Bubble *diner, Bubble *food)
   } else {
     if (diner->area > step_pixmaps[diner->step+1]->area) {
       i = diner->step;
-      while (diner->area > step_pixmaps[i+1]->area)
-       ++i;
+      while ((i < num_bubble_pixmaps - 1) && (diner->area > step_pixmaps[i+1]->area))
+               ++i;
       diner->step = i;
       diner->radius = step_pixmaps[diner->step]->radius;
     }
@@ -883,33 +905,133 @@ insert_new_bubble(Bubble *tmp)
   
   nextbub = tmp;
   touch = get_closest_bubble(nextbub);
-  while (! null_bubble(touch)) {
-    switch (merge_bubbles(nextbub, touch)) {
-    case 2:
-      /* touch ate nextbub and survived */
-      nextbub = touch;
-      break;
-    case 1:
-      /* nextbub ate touch and survived */
-      break;
-    case 0:
-      /* somebody ate someone else but they exploded */
-      nextbub = (Bubble *)NULL;
-      break;
-    default:
-      /* something went wrong */
-      fprintf(stderr, "Error occurred in insert_new_bubble()\n");
-      exit(1);
-    }
-    /* Check to see if there are any other bubbles still in the area
-       and if we need to do this all over again for them. */
-    if (! null_bubble(nextbub))
-      touch = get_closest_bubble(nextbub);
-    else
-      touch = (Bubble *)NULL;
+  if (null_bubble(touch))
+       return;
+
+  while (1) {
+
+       /* Merge all touching bubbles */
+       while (! null_bubble(touch)) {
+         switch (merge_bubbles(nextbub, touch)) {
+         case 2:
+               /* touch ate nextbub and survived */
+               nextbub = touch;
+               break;
+         case 1:
+               /* nextbub ate touch and survived */
+               break;
+         case 0:
+               /* somebody ate someone else but they exploded */
+               nextbub = (Bubble *)NULL;
+               break;
+         default:
+               /* something went wrong */
+               fprintf(stderr, "Error occurred in insert_new_bubble()\n");
+               exit(1);
+         }
+       
+         /* Check to see if any bubble survived. */
+         if (null_bubble(nextbub))
+               break;
+
+         /* Check to see if there are any other bubbles still in the area
+                and if we need to do this all over again for them. */
+         touch = get_closest_bubble(nextbub);
+       }
+       
+       if (null_bubble(nextbub))
+         break;
+
+       /* Shift bubble down.  Break if we run off the screen. */
+       if (drop) {
+         if (drop_bubble( nextbub ) == -1)
+               break;
+       }
+
+       /* Check to see if there are any other bubbles still in the area
+          and if we need to do this all over again for them. */
+       touch = get_closest_bubble(nextbub);
+       if (null_bubble(touch)) {
+         /* We also continue every so often if we're dropping and the bubble is at max size */
+         if (drop) {
+               if (simple) {
+                 if ((nextbub->area >= bubble_areas[bubble_max_radius - 1]) && (random() % 2 == 0))
+                       continue;
+               }
+#ifdef HAVE_XPM
+               else {
+                 if ((nextbub->step >= num_bubble_pixmaps - 1) && (random() % 2 == 0))
+                       continue;
+               }
+#endif /* HAVE_XPM */
+      }
+         break;
+       }
+
   }
 }
 
+
+static void
+leave_trail( Bubble *bb ) 
+{
+  Bubble *tmp;
+
+  tmp = new_bubble();
+  tmp->x = bb->x;
+  tmp->y = bb->y - ((bb->radius + 10) * drop_dir);
+  tmp->cell_index = pixel_to_mesh(tmp->x, tmp->y);
+  add_to_mesh(tmp);
+  insert_new_bubble(tmp);
+  show_bubble( tmp );  
+}
+
+
+static int
+drop_bubble( Bubble *bb )
+{
+  int newmi;
+
+  hide_bubble( bb );
+
+  if (simple)
+       (bb->y) += (bubble_droppages[bb->radius] * drop_dir);
+#ifdef HAVE_XPM
+  else
+       (bb->y) += (step_pixmaps[bb->step]->droppage * drop_dir);
+#endif /* HAVE_XPM */
+  if ((bb->y < 0) || (bb->y > screen_height)) {
+       delete_bubble_in_mesh( bb, DELETE_BUBBLE );
+       return -1;
+  }
+
+  show_bubble( bb );
+
+  /* Now adjust locations and cells if need be */
+  newmi = pixel_to_mesh(bb->x, bb->y);
+  if (newmi != bb->cell_index) {
+    delete_bubble_in_mesh(bb, KEEP_BUBBLE);
+    bb->cell_index = newmi;
+    add_to_mesh(bb);
+  }
+
+  if (trails) {
+       if (simple) {
+         if ((bb->area >= bubble_areas[bubble_max_radius - 1]) && (random() % 2 == 0)) 
+               leave_trail( bb );
+       }
+#ifdef HAVE_XPM
+       else { 
+         if ((bb->step >= num_bubble_pixmaps - 1) && (random() % 2 == 0))
+               leave_trail( bb );
+       }
+#endif /* HAVE_XPM */
+  }
+
+  return 0;
+}
+
+
 #ifdef DEBUG
 static int
 get_length_of_bubble_list(Bubble *bb)
@@ -1042,6 +1164,10 @@ make_pixmap_array(Bubble_Step *list)
     prevrad = step_pixmaps[ind]->radius;
   }
 #endif /* DEBUG */
+
+  /* Now populate the droppage values */
+  for (ind = 0; ind < num_bubble_pixmaps; ind++)
+         step_pixmaps[ind]->droppage = MAX_DROPPAGE * ind / num_bubble_pixmaps;
 }
 
 static void
@@ -1165,7 +1291,7 @@ static void
 get_resources(Display *dpy, Window window)
 /* Get the appropriate X resources and warn about any inconsistencies. */
 {
-  Bool nodelay;
+  Bool nodelay, rise;
   XWindowAttributes xgwa;
   Colormap cmap;
   XGetWindowAttributes (dpy, window, &xgwa);
@@ -1188,6 +1314,17 @@ get_resources(Display *dpy, Window window)
   if (delay < 0)
     delay = 0;
 
+  drop = get_boolean_resource("drop", "Boolean");
+  rise = get_boolean_resource("rise", "Boolean");
+  trails = get_boolean_resource("trails", "Boolean");
+  if (drop && rise) {
+       fprintf( stderr, "Sorry, bubbles can't both drop and rise\n" );
+       exit(1);
+  }
+  drop_dir = (drop ? 1 : -1);
+  if (drop || rise)
+       drop = 1;
+
   default_fg_pixel = get_pixel_resource ("foreground", "Foreground", dpy,
                                         cmap);
   default_bg_pixel = get_pixel_resource ("background", "Background", dpy,
@@ -1255,6 +1392,13 @@ init_bubbles (Display *dpy, Window window)
     for (i = bubble_min_radius; i <= (bubble_max_radius+1); i++)
       bubble_areas[i] = calc_bubble_area(i);
 
+       /* Now populate the droppage values */
+    bubble_droppages = (int *)xmalloc((bubble_max_radius + 2) * sizeof(int));
+    for (i = 0; i < bubble_min_radius; i++)
+      bubble_droppages[i] = 0;
+    for (i = bubble_min_radius; i <= (bubble_max_radius+1); i++)
+      bubble_droppages[i] = MAX_DROPPAGE * (i - bubble_min_radius) / (bubble_max_radius - bubble_min_radius);
+
     mesh_length = (2 * bubble_max_radius) + 3;
   } else {
 #ifndef HAVE_XPM
index 89935f4552ba0bde58458cc109cd2e37b978bef0..6bca1c67543aba8c6a3a7cc4488251a3808232fb 100644 (file)
@@ -1,6 +1,6 @@
 /* bubbles.h - definitions for bubbles screensaver */
 
-/* $Id: bubbles.h,v 1.2 1997/05/19 03:26:05 jwz Exp $ */
+/* $Id: bubbles.h,v 1.3 2000/07/19 06:38:42 jwz Exp $ */
 
 #ifndef _BUBBLES_H_
 #define _BUBBLES_H_
 /* Size increments for read_line() buffers */
 #define READ_LINE_BUF_SIZE 24
 
+/* Maximum amount to drop a bubble */
+#define MAX_DROPPAGE 20
+
 /****************************************************************************
  *                        End of options                                    *
  ****************************************************************************/
@@ -188,6 +191,7 @@ typedef struct bub Bubble;
 struct bub_step {
   int radius;
   long area;
+  int droppage;
   Pixmap ball, shape_mask;
   GC draw_gc, erase_gc;
   XpmAttributes xpmattrs;
index 0b7e4e4ed0084b591bf64e801ebd39049f8575f9..5eedaf7c107c23586c6728f77e545c5e080d5aa1 100644 (file)
 #include "bumps.h"
 
 
-void CreateSpotLight( SSpotLight *pSpotLight, uint16_ iWinWidth, uint16_ nColorCount )
+void CreateSpotLight( SSpotLight *pSpotLight, uint16_ iDiameter, uint16_ nColorCount )
 {
        double nDelta;
        int16_ iHeight, iWidth;
        
-       pSpotLight->nDiameter = iWinWidth / 3;
+       pSpotLight->nDiameter = iDiameter;
 #ifdef VERBOSE
        printf( "%s: Light Diameter: %d\n", progclass, pSpotLight->nDiameter );
 #endif
@@ -126,7 +126,8 @@ void CreateBumps( SBumps *pBumps, Display *pNewDisplay, Window NewWin )
        XGCValues GCValues;
        int32_ nGCFlags;
        uint16_ iWidth, iHeight;
-
+       uint16_ iDiameter;
+       
        XGetWindowAttributes( pNewDisplay, NewWin, &XWinAttribs );
        pBumps->iWinWidth = XWinAttribs.width;
        pBumps->iWinHeight = XWinAttribs.height;
@@ -147,7 +148,8 @@ void CreateBumps( SBumps *pBumps, Display *pNewDisplay, Window NewWin )
        pBumps->GraphicsContext = XCreateGC( pBumps->pDisplay, pBumps->Win, nGCFlags, &GCValues );
        
        SetPalette( pBumps, &XWinAttribs );
-       CreateSpotLight( &pBumps->SpotLight, pBumps->iWinWidth, pBumps->nColorCount );
+       iDiameter = ( ( pBumps->iWinWidth < pBumps->iWinHeight ) ? pBumps->iWinWidth : pBumps->iWinHeight ) / 3;
+       CreateSpotLight( &pBumps->SpotLight, iDiameter, pBumps->nColorCount );
        InitBumpMap( pBumps, &XWinAttribs );
 
        /* Clear the image. */
index 9d1922cab626fc6f96686cf82dd2463d9cbfee9d..08850c7e1b485aac921e9e0e53847f93d23d2c21 100644 (file)
@@ -53,6 +53,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]) MOIRE2.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MOUNTAIN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MUNCH.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) NERVEROT.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) NOSEGUY.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PEDAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENETRATE.C
index 9d1922cab626fc6f96686cf82dd2463d9cbfee9d..08850c7e1b485aac921e9e0e53847f93d23d2c21 100644 (file)
@@ -53,6 +53,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]) MOIRE2.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MOUNTAIN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MUNCH.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) NERVEROT.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) NOSEGUY.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PEDAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENETRATE.C
index 0f8c2f4aee2914762d3ccd952b1ebd042219fe4a..b5fdfcc4d858361e06967e7ab205c37bcdf50627 100644 (file)
@@ -472,7 +472,7 @@ static double box_orig[][3] = {
 static double box[BOX_P][3];
 
 /* Lines connecting the box dots */
-static double lines[0][2] = {
+static double lines[][2] = {
        {0,1}, {1,2}, {2,3}, {3,0}, /* box */
        {4,5}, {5,6}, {6,7}, {7,4},
        {0,4}, {1,5}, {2,6}, {3,7},
@@ -496,8 +496,17 @@ void init_clip(flowstruct *sp)
        /* Scale the planes to the screen. I had to invert the projection
         * algorithms so that when projected they would be right at the edge of the
         * screen. */
-       double width = sp->size/sp->view.depth/2;
-       double height = sp->size/sp->view.depth/2*sp->view.height/sp->view.height;
+
+    /* #### jwz: I'm not really sure what it means when sp->view.depth is 0
+       in here -- what's the right thing to do? */
+
+       double width = (sp->view.depth
+                    ? sp->size/sp->view.depth/2
+                    : 1);
+       double height = (sp->view.depth
+                     ? (sp->size/sp->view.depth/2*
+                        sp->view.height/sp->view.height)
+                     : 1);
        for (i = 0; i < PLANES; i++) {
                /* Copy orig planes into planes, expanding <-> clippings */
                plane[i][0][0] = plane_orig[i][0][0];
index 626f2926899da542ca3da31bb78314a7db283b8f..e32391f2560607c28242c0c7290f3c29f90a0495 100644 (file)
@@ -554,8 +554,8 @@ pulsar.o: $(UTILS_SRC)/colors.h
 pulsar.o: $(UTILS_SRC)/grabscreen.h
 pulsar.o: $(UTILS_SRC)/visual.h
 pulsar.o: $(UTILS_SRC)/xshm.h
-extrusion.o: $(HACK_SRC)/xlockmore.h
 extrusion.o: ../../config.h
+extrusion.o: $(HACK_SRC)/xlockmore.h
 extrusion.o: $(HACK_SRC)/xlockmoreI.h
 extrusion.o: $(HACK_SRC)/screenhack.h
 extrusion.o: $(UTILS_SRC)/yarandom.h
@@ -566,6 +566,13 @@ extrusion.o: $(UTILS_SRC)/colors.h
 extrusion.o: $(UTILS_SRC)/grabscreen.h
 extrusion.o: $(UTILS_SRC)/visual.h
 extrusion.o: $(UTILS_SRC)/xshm.h
+extrusion-helix2.o: ../../config.h
+extrusion-helix3.o: ../../config.h
+extrusion-helix4.o: ../../config.h
+extrusion-joinoffset.o: ../../config.h
+extrusion-screw.o: ../../config.h
+extrusion-taper.o: ../../config.h
+extrusion-twistoid.o: ../../config.h
 sierpinski3d.o: $(HACK_SRC)/xlockmore.h
 sierpinski3d.o: ../../config.h
 sierpinski3d.o: $(HACK_SRC)/xlockmoreI.h
index 2b2c41d4622913eb07ebb7a7be6ba49f153ad5f8..9220133ef253a766b16025c90a20cb06b31a6c9d 100644 (file)
  */
 
 /* required include files */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <GL/gl.h>
 #include <GL/glut.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 /*  most recent mouse postion */
 extern float lastx;
index 7924663933bf97d416db117523065aeedb514d21..003e4bd666977ce5bca342715d5f6499afa4cdbf 100644 (file)
  */
 
 /* required include files */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <GL/gl.h>
 #include <GL/glut.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 /*  most recent mouse postion */
 extern float lastx;
index 6c81607cc30d9eb5256f1838536998c8445e34d9..d6a786a78b860e800d3e6b47c8a679d61969df9b 100644 (file)
  */
 
 /* required include files */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <GL/gl.h>
 #include <GL/glut.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 /*  most recent mouse postion */
 extern float lastx;
index 786d0c755c8e878a62fdada6b42f8f1eeef2af54..c48bad4a887bd881999760f2257d3aea17bf2449 100644 (file)
@@ -3,9 +3,17 @@
 /* this demo demonstrates the various join styles */
 
 /* required include files */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <GL/gl.h>
 #include <GL/glut.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 /* ------------------------------------------------------- */
 
index 16f12b1286cacdd7b9ec2296d9b255209d420109..112eaca7217ec0f3f65a30ff92c770138ffae736 100644 (file)
  */
 
 /* required include files */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <math.h>
 #include <stdlib.h>
 #include <GL/gl.h>
 #include <GL/glut.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 #ifndef NULL
 #define NULL ((void *) 0x0)
index 8cf51cae5ae016dc44b7a391117e08daa55d2625..234853ee064bf31ba9479fd7298fe517950dceae 100644 (file)
  */
 
 /* required include files */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <math.h>
 #include <stdlib.h>
 #include <GL/gl.h>
 #include <GL/glut.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 #ifndef NULL
 #define NULL ((void *) 0x0)
index 2de65370f060d1433fddc3d21199bcfc43de9520..4f388d01136cf8c61485a964ed0f901bb981bcb2 100644 (file)
  */
 
 /* required include files */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <math.h>
 #include <stdlib.h>
 #include <GL/gl.h>
 #include <GL/glut.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 /* Some <math.h> files do not define M_PI... */
 #ifndef M_PI
index 86facfb6f79dbaf98eb5b9f61789838ce75c3c29..726177e6787ceeed530fdc0e634b64ab313900ad 100644 (file)
@@ -29,7 +29,9 @@
 
 #include <X11/Intrinsic.h>
 
-
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #ifdef STANDALONE
 # define PROGCLASS                                             "Screensaver"
 #include <malloc.h>
 #include <GL/gl.h>
 #include <GL/glu.h>
+#ifdef HAVE_GLE3
+#include <GL/gle.h>
+#else
 #include <GL/tube.h>
+#endif
 
 #undef countof
 #define countof(x) (sizeof((x))/sizeof((*x)))
index 8129f903803dd733e053bf412d2d5c8ac63d4d63..a6b971b77e8d1b7f7ac889c557d79b4aa31e3f1e 100644 (file)
@@ -735,7 +735,7 @@ void drawQuads(void) {
     }
 }
 
-GLvoid drawScene(GLvoid) 
+GLvoid drawScene(void) 
 {
 
   checkError(__LINE__, __FILE__);
index d11daf1aeed98a98498b861af1262f56744baff5..2df2a39b85ef532176a6de5179947be80e963392 100644 (file)
@@ -341,12 +341,10 @@ draw(ModeInfo *mi)
   static float position0[] = {-0.5,  1.2, 0.5, 0.0};
   static float ambient0[]  = {0.4, 0.6, 0.4, 1.0};
   static float spec[]      = {0.7, 0.7, 0.7, 1.0};
-  static float shine[]     = {70.0};
 
   glLightfv(GL_LIGHT0, GL_POSITION,  position0);
   glLightfv(GL_LIGHT0, GL_AMBIENT,   ambient0);
   glLightfv(GL_LIGHT0, GL_SPECULAR,  spec);
-  glLightfv(GL_LIGHT0, GL_SHININESS, shine);
   glLightfv(GL_LIGHT0, GL_DIFFUSE,   gp->light_colour);
 
   glShadeModel(GL_SMOOTH);
index 9d22778fb87ac6d5c4d300bc186ad416ab5a8a79..004c9396c92a3ab26bb68f22e2eaaf82aad377f6 100644 (file)
@@ -1477,7 +1477,7 @@ solve_maze (void)                     /* solve it with graphical feedback */
            if(!dir)
              goto backtrack;
            
-         found:
+         found: ;
          }
        else
          {
diff --git a/hacks/nerverot.c b/hacks/nerverot.c
new file mode 100644 (file)
index 0000000..dcacb5a
--- /dev/null
@@ -0,0 +1,1014 @@
+/* nerverot, nervous rotation of random thingies, v1.0
+ * by Dan Bornstein, danfuzz@milk.com
+ * Copyright (c) 2000 Dan Bornstein.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * The goal of this screensaver is to be interesting and compelling to
+ * watch, yet induce a state of nervous edginess in the viewer.
+ *
+ * Brief description of options/resources:
+ *
+ *   -fg <color>: foreground color
+ *   -bg <color>: background color
+ *   -delay <usec>: delay between frames
+ *   -event-chance <frac>: chance, per iteration, that an interesting event
+ *     will happen (range 0..1)
+ *   -iter-amt <frac>: amount, per iteration, to move towards rotation and
+ *     scale targets (range 0..1)
+ *   -count <n>: number of blots
+ *   -colors <n>: number of colors to use
+ *   -lineWidth <n>: width of lines (0 means an optimized thin line)
+ *   -nervousness <frac>: amount of nervousness (range 0..1)
+ *   -min-scale <frac>: minimum scale of drawing as fraction of base scale
+ *     (which is the minumum of the width or height of the screen) (range
+ *     0..10)
+ *   -max-scale <frac>: maximum scale of drawing as fraction of base scale
+ *     (which is the minumum of the width or height of the screen) (range
+ *     0..10)
+ *   -min-radius <n>: minimum radius for drawing blots (range 1..100)
+ *   -max-radius <n>: maximum radius for drawing blots (range 1..100)
+ *   -max-nerve-radius <frac>: maximum nervousness radius (range 0..1)
+ */
+
+#include <math.h>
+#include "screenhack.h"
+
+#define FLOAT double
+
+/* random float in the range (-1..1) */
+#define RAND_FLOAT_PM1 \
+        (((FLOAT) (random() & 0xffff)) / ((FLOAT) 0x10000) * 2 - 1)
+
+/* random float in the range (0..1) */
+#define RAND_FLOAT_01 \
+        (((FLOAT) (random() & 0xffff)) / ((FLOAT) 0x10000))
+
+
+
+/* parameters that are user configurable */
+
+/* number of blots */
+static int requestedBlotCount;
+
+/* delay (usec) between iterations */
+int delay;
+
+/* variability of xoff/yoff per iteration (0..1) */
+static FLOAT nervousness;
+
+/* max nervousness radius (0..1) */
+static FLOAT maxNerveRadius;
+
+/* chance per iteration that an event will happen */
+static FLOAT eventChance;
+
+/* fraction (0..1) towards rotation target or scale target to move each
+ * iteration */
+static FLOAT iterAmt;
+
+/* min and max scale for drawing, as fraction of baseScale */
+static FLOAT minScale;
+static FLOAT maxScale;
+
+/* min and max radius of blot drawing */
+static int minRadius;
+static int maxRadius;
+
+/* the number of colors to use */
+static int colorCount;
+
+/* width of lines */
+static int lineWidth;
+
+
+
+/* non-user-modifiable immutable definitions */
+
+/* base scale factor for drawing, calculated as
+ * max(screenWidth,screenHeight) */
+static int baseScale;
+
+/* width and height of the window */
+static int windowWidth;
+static int windowHeight;
+
+/* center position of the window */
+static int centerX;
+static int centerY;
+
+static Display *display; /* the display to draw on */
+static Window window;    /* the window to draw on */
+static GC *gcs;          /* array of gcs, one per color used */
+
+
+
+/* structure of the model */
+
+/* each point-like thingy to draw is represented as a blot */
+typedef struct blot_s
+{
+    FLOAT x;           /* 3d x position (-1..1) */
+    FLOAT y;           /* 3d y position (-1..1) */
+    FLOAT z;           /* 3d z position (-1..1) */
+    FLOAT xoff[3][3];  /* display x offset per drawn point (-1..1) */
+    FLOAT yoff[3][3];  /* display x offset per drawn point (-1..1) */
+} Blot;
+
+/* each drawn line is represented as a LineSegment */
+typedef struct linesegment_s
+{
+    GC gc;
+    int x1;
+    int y1;
+    int x2;
+    int y2;
+} LineSegment;
+
+/* array of the blots in the model */
+static Blot *blots = NULL;
+static int blotCount;
+
+/* each blot draws as a simple 2d shape with each coordinate as an int
+ * in the range (-1..1); this is the base shape */
+static XPoint blotShape[] = { { 0, 0}, { 1, 0}, { 1, 1}, 
+                             { 0, 1}, {-1, 1}, {-1, 0}, 
+                             {-1,-1}, { 0,-1}, { 1,-1} };
+static int blotShapeCount = sizeof (blotShape) / sizeof (XPoint);
+
+/* two arrays of line segments; one for the ones to erase, and one for the
+ * ones to draw */
+static int segCount;
+static LineSegment *segsToDraw = NULL;
+static LineSegment *segsToErase = NULL;
+
+/* current rotation values per axis, scale factor, and light position */
+static FLOAT xRot;
+static FLOAT yRot;
+static FLOAT zRot;
+static FLOAT curScale;
+static FLOAT lightX;
+static FLOAT lightY;
+static FLOAT lightZ;
+
+/* target rotation values per axis, scale factor, and light position */
+static FLOAT xRotTarget;
+static FLOAT yRotTarget;
+static FLOAT zRotTarget;
+static FLOAT scaleTarget;
+static FLOAT lightXTarget;
+static FLOAT lightYTarget;
+static FLOAT lightZTarget;
+
+/* current absolute offsets from the center */
+static int centerXOff = 0;
+static int centerYOff = 0;
+
+/* iterations until the model changes */
+static int itersTillNext;
+
+
+
+/*
+ * blot setup stuff
+ */
+
+/* initialize a blot with the given coordinates and random display offsets */
+static void initBlot (Blot *b, FLOAT x, FLOAT y, FLOAT z)
+{
+    int i, j;
+
+    b->x = x;
+    b->y = y;
+    b->z = z;
+
+    for (i = 0; i < 3; i++)
+    {
+       for (j = 0; j < 3; j++)
+       {
+           b->xoff[i][j] = RAND_FLOAT_PM1;
+           b->yoff[i][j] = RAND_FLOAT_PM1;
+       }
+    }
+}
+
+/* scale the blots to have a max distance of 1 from the center */
+static void scaleBlotsToRadius1 (void)
+{
+    FLOAT max = 0.0;
+    int n;
+
+    for (n = 0; n < blotCount; n++)
+    {
+       FLOAT distSquare = 
+           blots[n].x * blots[n].x +
+           blots[n].y * blots[n].y +
+           blots[n].z * blots[n].z;
+       if (distSquare > max)
+       {
+           max = distSquare;
+       }
+    }
+
+    if (max == 0.0)
+    {
+       return;
+    }
+
+    max = sqrt (max);
+
+    for (n = 0; n < blotCount; n++)
+    {
+       blots[n].x /= max;
+       blots[n].y /= max;
+       blots[n].z /= max;
+    }
+}
+
+/* randomly reorder the blots */
+static void randomlyReorderBlots (void)
+{
+    int n;
+
+    for (n = 0; n < blotCount; n++)
+    {
+       int m = RAND_FLOAT_01 * (blotCount - n) + n;
+       Blot tmpBlot = blots[n];
+       blots[n] = blots[m];
+       blots[m] = tmpBlot;
+    }
+}
+
+/* set up the initial array of blots to be a at the edge of a sphere */
+static void setupBlotsSphere (void)
+{
+    int n;
+
+    blotCount = requestedBlotCount;
+    blots = calloc (sizeof (Blot), blotCount);
+
+    for (n = 0; n < blotCount; n++)
+    {
+       /* pick a spot, but reject if its radius is < 0.2 or > 1 to
+        * avoid scaling problems */
+       FLOAT x, y, z, radius;
+
+       for (;;)
+       {
+           x = RAND_FLOAT_PM1;
+           y = RAND_FLOAT_PM1;
+           z = RAND_FLOAT_PM1;
+
+           radius = sqrt (x * x + y * y + z * z);
+           if ((radius >= 0.2) && (radius <= 1.0))
+           {
+               break;
+           }
+       }
+
+       x /= radius;
+       y /= radius;
+       z /= radius;
+
+       initBlot (&blots[n], x, y, z);
+    }
+
+}
+
+/* set up the initial array of blots to be a simple cube */
+static void setupBlotsCube (void)
+{
+    int i, j, k, n;
+
+    /* derive blotsPerEdge from blotCount, but then do the reverse
+     * since roundoff may have changed blotCount */
+    int blotsPerEdge = ((requestedBlotCount - 8) / 12) + 2;
+    FLOAT distBetween;
+
+    if (blotsPerEdge < 2)
+    {
+       blotsPerEdge = 2;
+    }
+
+    distBetween = 2.0 / (blotsPerEdge - 1.0);
+
+    blotCount = 8 + (blotsPerEdge - 2) * 12;
+    blots = calloc (sizeof (Blot), blotCount);
+    n = 0;
+
+    /* define the corners */
+    for (i = -1; i < 2; i += 2)
+    {
+       for (j = -1; j < 2; j += 2)
+       {
+           for (k = -1; k < 2; k += 2)
+           {
+               initBlot (&blots[n], i, j, k);
+               n++;
+           } 
+       }
+    }
+
+    /* define the edges */
+    for (i = 1; i < (blotsPerEdge - 1); i++)
+    {
+       FLOAT varEdge = distBetween * i - 1;
+       initBlot (&blots[n++], varEdge, -1, -1);
+       initBlot (&blots[n++], varEdge,  1, -1);
+       initBlot (&blots[n++], varEdge, -1,  1);
+       initBlot (&blots[n++], varEdge,  1,  1);
+       initBlot (&blots[n++], -1, varEdge, -1);
+       initBlot (&blots[n++],  1, varEdge, -1);
+       initBlot (&blots[n++], -1, varEdge,  1);
+       initBlot (&blots[n++],  1, varEdge,  1);
+       initBlot (&blots[n++], -1, -1, varEdge);
+       initBlot (&blots[n++],  1, -1, varEdge);
+       initBlot (&blots[n++], -1,  1, varEdge);
+       initBlot (&blots[n++],  1,  1, varEdge);
+    }
+
+    scaleBlotsToRadius1 ();
+    randomlyReorderBlots ();
+}
+
+
+/* set up the initial array of blots to be a cylinder */
+static void setupBlotsCylinder (void)
+{
+    int i, j, n;
+
+    /* derive blotsPerEdge from blotCount, but then do the reverse
+     * since roundoff may have changed blotCount */
+    int blotsPerEdge = requestedBlotCount / 32;
+    FLOAT distBetween;
+
+    if (blotsPerEdge < 2)
+    {
+       blotsPerEdge = 2;
+    }
+
+    distBetween = 2.0 / (blotsPerEdge - 1);
+
+    blotCount = blotsPerEdge * 32;
+    blots = calloc (sizeof (Blot), blotCount);
+    n = 0;
+
+    /* define the edges */
+    for (i = 0; i < 32; i++)
+    {
+       FLOAT x = sin (2 * M_PI / 32 * i);
+       FLOAT y = cos (2 * M_PI / 32 * i);
+       for (j = 0; j < blotsPerEdge; j++)
+       {
+           initBlot (&blots[n], x, y, j * distBetween - 1);
+           n++;
+       }
+    }
+
+    scaleBlotsToRadius1 ();
+    randomlyReorderBlots ();
+}
+
+
+
+/* set up the initial array of blots to be a squiggle */
+static void setupBlotsSquiggle (void)
+{
+    FLOAT x, y, z, xv, yv, zv, len;
+    int n;
+
+    blotCount = requestedBlotCount;
+    blots = calloc (sizeof (Blot), blotCount);
+
+    x = RAND_FLOAT_PM1;
+    y = RAND_FLOAT_PM1;
+    z = RAND_FLOAT_PM1;
+
+    xv = RAND_FLOAT_PM1;
+    yv = RAND_FLOAT_PM1;
+    zv = RAND_FLOAT_PM1;
+    len = sqrt (xv * xv + yv * yv + zv * zv);
+    xv /= len;
+    yv /= len;
+    zv /= len;
+    
+    for (n = 0; n < blotCount; n++)
+    {
+       FLOAT newx, newy, newz;
+       initBlot (&blots[n], x, y, z);
+
+       for (;;)
+       {
+           xv += RAND_FLOAT_PM1 * 0.1;
+           yv += RAND_FLOAT_PM1 * 0.1;
+           zv += RAND_FLOAT_PM1 * 0.1;
+           len = sqrt (xv * xv + yv * yv + zv * zv);
+           xv /= len;
+           yv /= len;
+           zv /= len;
+
+           newx = x + xv * 0.1;
+           newy = y + yv * 0.1;
+           newz = z + zv * 0.1;
+
+           if (   (newx >= -1) && (newx <= 1)
+               && (newy >= -1) && (newy <= 1)
+               && (newz >= -1) && (newz <= 1))
+           {
+               break;
+           }
+       }
+
+       x = newx;
+       y = newy;
+       z = newz;
+    }
+
+    scaleBlotsToRadius1 ();
+    randomlyReorderBlots ();
+}
+
+
+
+/* free the blots, in preparation for a new shape */
+static void freeBlots (void)
+{
+    if (blots != NULL)
+    {
+       free (blots);
+       blots = NULL;
+    }
+
+    if (segsToErase != NULL)
+    {
+       free (segsToErase);
+       segsToErase = NULL;
+    }
+
+    if (segsToDraw != NULL)
+    {
+       free (segsToDraw);
+       segsToDraw = NULL;
+    }
+}
+
+
+
+/* set up the initial arrays of blots */
+static void setupBlots (void)
+{
+    int which = RAND_FLOAT_01 * 4;
+
+    freeBlots ();
+
+    switch (which)
+    {
+       case 0:
+           setupBlotsCube ();
+           break;
+       case 1:
+           setupBlotsSphere ();
+           break;
+       case 2:
+           setupBlotsCylinder ();
+           break;
+       case 3:
+           setupBlotsSquiggle ();
+           break;
+    }
+
+    /* there are blotShapeCount - 1 line segments per blot */
+    segCount = blotCount * (blotShapeCount - 1);
+    segsToErase = calloc (sizeof (LineSegment), segCount);
+    segsToDraw = calloc (sizeof (LineSegment), segCount);
+
+    /* erase the world */
+    XFillRectangle (display, window, gcs[0], 0, 0, windowWidth, windowHeight);
+}
+
+
+
+/*
+ * color setup stuff
+ */
+
+/* set up the colormap */
+static void setupColormap (XWindowAttributes *xgwa)
+{
+    int n;
+    XGCValues gcv;
+    XColor *colors = (XColor *) calloc (sizeof (XColor), colorCount + 1);
+
+    unsigned short r, g, b;
+    int h1, h2;
+    double s1, s2, v1, v2;
+
+    r = RAND_FLOAT_01 * 0x10000;
+    g = RAND_FLOAT_01 * 0x10000;
+    b = RAND_FLOAT_01 * 0x10000;
+    rgb_to_hsv (r, g, b, &h1, &s1, &v1);
+    v1 = 1.0;
+    s1 = 1.0;
+
+    r = RAND_FLOAT_01 * 0x10000;
+    g = RAND_FLOAT_01 * 0x10000;
+    b = RAND_FLOAT_01 * 0x10000;
+    rgb_to_hsv (r, g, b, &h2, &s2, &v2);
+    s2 = 0.7;
+    v2 = 0.7;
+    
+    colors[0].pixel = get_pixel_resource ("background", "Background",
+                                         display, xgwa->colormap);
+    
+    make_color_ramp (display, xgwa->colormap, h1, s1, v1, h2, s2, v2,
+                    colors + 1, &colorCount, False, True, False);
+
+    if (colorCount < 1)
+    {
+        fprintf (stderr, "%s: couldn't allocate any colors\n", progname);
+       exit (-1);
+    }
+    
+    gcs = (GC *) calloc (sizeof (GC), colorCount + 1);
+
+    for (n = 0; n <= colorCount; n++) 
+    {
+       gcv.foreground = colors[n].pixel;
+       gcv.line_width = lineWidth;
+       gcs[n] = XCreateGC (display, window, GCForeground | GCLineWidth, &gcv);
+    }
+
+    free (colors);
+}
+
+
+
+/*
+ * overall setup stuff
+ */
+
+/* set up the system */
+static void setup (void)
+{
+    XWindowAttributes xgwa;
+
+    XGetWindowAttributes (display, window, &xgwa);
+
+    windowWidth = xgwa.width;
+    windowHeight = xgwa.height;
+    centerX = windowWidth / 2;
+    centerY = windowHeight / 2;
+    baseScale = (xgwa.height < xgwa.width) ? xgwa.height : xgwa.width;
+
+    setupColormap (&xgwa);
+    setupBlots ();
+
+    /* set up the initial rotation, scale, and light values as random, but
+     * with the targets equal to where it is */
+    xRot = xRotTarget = RAND_FLOAT_01 * M_PI;
+    yRot = yRotTarget = RAND_FLOAT_01 * M_PI;
+    zRot = zRotTarget = RAND_FLOAT_01 * M_PI;
+    curScale = scaleTarget = RAND_FLOAT_01 * (maxScale - minScale) + minScale;
+    lightX = lightXTarget = RAND_FLOAT_PM1;
+    lightY = lightYTarget = RAND_FLOAT_PM1;
+    lightZ = lightZTarget = RAND_FLOAT_PM1;
+
+    itersTillNext = RAND_FLOAT_01 * 1234;
+}
+
+
+
+/*
+ * the simulation
+ */
+
+/* "render" the blots into segsToDraw, with the current rotation factors */
+static void renderSegs (void)
+{
+    int n;
+    int m = 0;
+
+    /* rotation factors */
+    FLOAT sinX = sin (xRot);
+    FLOAT cosX = cos (xRot);
+    FLOAT sinY = sin (yRot);
+    FLOAT cosY = cos (yRot);
+    FLOAT sinZ = sin (zRot);
+    FLOAT cosZ = cos (zRot);
+
+    for (n = 0; n < blotCount; n++)
+    {
+       Blot *b = &blots[n];
+       int i, j;
+       int baseX, baseY;
+       FLOAT radius;
+       int x[3][3];
+       int y[3][3];
+       int color;
+
+       FLOAT x1 = blots[n].x;
+       FLOAT y1 = blots[n].y;
+       FLOAT z1 = blots[n].z;
+       FLOAT x2, y2, z2;
+
+       /* rotate on z axis */
+       x2 = x1 * cosZ - y1 * sinZ;
+       y2 = x1 * sinZ + y1 * cosZ;
+       z2 = z1;
+
+       /* rotate on x axis */
+       y1 = y2 * cosX - z2 * sinX;
+       z1 = y2 * sinX + z2 * cosX;
+       x1 = x2;
+
+       /* rotate on y axis */
+       z2 = z1 * cosY - x1 * sinY;
+       x2 = z1 * sinY + x1 * cosY;
+       y2 = y1;
+
+       /* the color to draw is based on the distance from the light of
+        * the post-rotation blot */
+       x1 = x2 - lightX;
+       y1 = y2 - lightY;
+       z1 = z2 - lightZ;
+       color = 1 + (x1 * x1 + y1 * y1 + z1 * z1) / 4 * colorCount;
+       if (color > colorCount)
+       {
+           color = colorCount;
+       }
+
+       /* set up the base screen coordinates for drawing */
+       baseX = x2 / 2 * baseScale * curScale + centerX + centerXOff;
+       baseY = y2 / 2 * baseScale * curScale + centerY + centerYOff;
+       
+       radius = (z2 + 1) / 2 * (maxRadius - minRadius) + minRadius;
+
+       for (i = 0; i < 3; i++)
+       {
+           for (j = 0; j < 3; j++)
+           {
+               x[i][j] = baseX + 
+                   ((i - 1) + (b->xoff[i][j] * maxNerveRadius)) * radius;
+               y[i][j] = baseY + 
+                   ((j - 1) + (b->yoff[i][j] * maxNerveRadius)) * radius;
+           }
+       }
+
+       for (i = 1; i < blotShapeCount; i++)
+       {
+           segsToDraw[m].gc = gcs[color];
+           segsToDraw[m].x1 = x[blotShape[i-1].x + 1][blotShape[i-1].y + 1];
+           segsToDraw[m].y1 = y[blotShape[i-1].x + 1][blotShape[i-1].y + 1];
+           segsToDraw[m].x2 = x[blotShape[i].x   + 1][blotShape[i].y   + 1];
+           segsToDraw[m].y2 = y[blotShape[i].x   + 1][blotShape[i].y   + 1];
+           m++;
+       }
+    }
+}
+
+/* update blots, adjusting the offsets and rotation factors. */
+static void updateWithFeeling (void)
+{
+    int n, i, j;
+
+    /* pick a new model if the time is right */
+    itersTillNext--;
+    if (itersTillNext < 0)
+    {
+       itersTillNext = RAND_FLOAT_01 * 1234;
+       setupBlots ();
+       renderSegs ();
+    }
+
+    /* update the rotation factors by moving them a bit toward the targets */
+    xRot = xRot + (xRotTarget - xRot) * iterAmt; 
+    yRot = yRot + (yRotTarget - yRot) * iterAmt;
+    zRot = zRot + (zRotTarget - zRot) * iterAmt;
+
+    /* similarly the scale factor */
+    curScale = curScale + (scaleTarget - curScale) * iterAmt;
+
+    /* and similarly the light position */
+    lightX = lightX + (lightXTarget - lightX) * iterAmt; 
+    lightY = lightY + (lightYTarget - lightY) * iterAmt; 
+    lightZ = lightZ + (lightZTarget - lightZ) * iterAmt; 
+
+    /* for each blot... */
+    for (n = 0; n < blotCount; n++)
+    {
+       /* add a bit of random jitter to xoff/yoff */
+       for (i = 0; i < 3; i++)
+       {
+           for (j = 0; j < 3; j++)
+           {
+               FLOAT newOff;
+
+               newOff = blots[n].xoff[i][j] + RAND_FLOAT_PM1 * nervousness;
+               if (newOff < -1) newOff = -(newOff + 1) - 1;
+               else if (newOff > 1) newOff = -(newOff - 1) + 1;
+               blots[n].xoff[i][j] = newOff;
+
+               newOff = blots[n].yoff[i][j] + RAND_FLOAT_PM1 * nervousness;
+               if (newOff < -1) newOff = -(newOff + 1) - 1;
+               else if (newOff > 1) newOff = -(newOff - 1) + 1;
+               blots[n].yoff[i][j] = newOff;
+           }
+       }
+    }
+
+    /* depending on random chance, update one or more factors */
+    if (RAND_FLOAT_01 <= eventChance)
+    {
+       int which = RAND_FLOAT_01 * 14;
+       switch (which)
+       {
+           case 0:
+           {
+               xRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               break;
+           }
+           case 1:
+           {
+               yRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               break;
+           }
+           case 2:
+           {
+               zRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               break;
+           }
+           case 3:
+           {
+               xRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               yRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               break;
+           }
+           case 4:
+           {
+               xRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               zRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               break;
+           }
+           case 5:
+           {
+               yRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               zRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               break;
+           }
+           case 6:
+           {
+               xRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               yRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               zRotTarget = RAND_FLOAT_PM1 * M_PI * 2;
+               break;
+           }
+           case 7:
+           {
+               centerXOff = RAND_FLOAT_PM1 * maxRadius / 2;
+               break;
+           }
+           case 8:
+           {
+               centerYOff = RAND_FLOAT_PM1 * maxRadius / 2;
+               break;
+           }
+           case 9:
+           {
+               centerXOff = RAND_FLOAT_PM1 * maxRadius / 2;
+               centerYOff = RAND_FLOAT_PM1 * maxRadius / 2;
+               break;
+           }
+           case 10:
+           {
+               scaleTarget = 
+                   RAND_FLOAT_01 * (maxScale - minScale) + minScale;
+               break;
+           }
+           case 11:
+           {
+               curScale = 
+                   RAND_FLOAT_01 * (maxScale - minScale) + minScale;
+               break;
+           }
+           case 12:
+           {
+               lightX = RAND_FLOAT_PM1;
+               lightY = RAND_FLOAT_PM1;
+               lightZ = RAND_FLOAT_PM1;
+               break;
+           }
+           case 13:
+           {
+               lightXTarget = RAND_FLOAT_PM1;
+               lightYTarget = RAND_FLOAT_PM1;
+               lightZTarget = RAND_FLOAT_PM1;
+               break;
+           }
+       }
+    }
+}
+
+/* erase segsToErase and draw segsToDraw */
+static void eraseAndDraw (void)
+{
+    int n;
+
+    for (n = 0; n < segCount; n++)
+    {
+       LineSegment *seg = &segsToErase[n];
+       XDrawLine (display, window, gcs[0], 
+                  seg->x1, seg->y1, seg->x2, seg->y2);
+       seg = &segsToDraw[n];
+       XDrawLine (display, window, seg->gc,
+                  seg->x1, seg->y1, seg->x2, seg->y2);
+    }
+}
+
+/* do one iteration */
+static void oneIteration (void)
+{
+    /* switch segsToErase and segsToDraw */
+    LineSegment *temp = segsToDraw;
+    segsToDraw = segsToErase;
+    segsToErase = temp;
+
+    /* update the model */
+    updateWithFeeling ();
+
+    /* render new segments */
+    renderSegs ();
+
+    /* erase old segments and draw new ones */
+    eraseAndDraw ();
+}
+
+char *progclass = "NerveRot";
+
+char *defaults [] = {
+    ".background:      black",
+    ".foreground:      white",
+    "*count:           250",
+    "*colors:          4",
+    "*delay:           10000",
+    "*eventChance:      0.2",
+    "*iterAmt:          0.01",
+    "*lineWidth:        0",
+    "*minScale:         0.6",
+    "*maxScale:         1.75",
+    "*minRadius:        3",
+    "*maxRadius:        25",
+    "*maxNerveRadius:  0.7",
+    "*nervousness:     0.3",
+    0
+};
+
+XrmOptionDescRec options [] = {
+  { "-count",            ".count",          XrmoptionSepArg, 0 },
+  { "-colors",           ".colors",         XrmoptionSepArg, 0 },
+  { "-cube",             ".cube",           XrmoptionNoArg,  "true" },
+  { "-delay",            ".delay",          XrmoptionSepArg, 0 },
+  { "-event-chance",     ".eventChance",    XrmoptionSepArg, 0 },
+  { "-iter-amt",         ".iterAmt",        XrmoptionSepArg, 0 },
+  { "-line-width",       ".lineWidth",      XrmoptionSepArg, 0 },
+  { "-min-scale",        ".minScale",       XrmoptionSepArg, 0 },
+  { "-max-scale",        ".maxScale",       XrmoptionSepArg, 0 },
+  { "-min-radius",       ".minRadius",      XrmoptionSepArg, 0 },
+  { "-max-radius",       ".maxRadius",      XrmoptionSepArg, 0 },
+  { "-max-nerve-radius", ".maxNerveRadius", XrmoptionSepArg, 0 },
+  { "-nervousness",      ".nervousness",    XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+/* initialize the user-specifiable params */
+static void initParams (void)
+{
+    int problems = 0;
+
+    delay = get_integer_resource ("delay", "Delay");
+    if (delay < 0)
+    {
+       fprintf (stderr, "error: delay must be at least 0\n");
+       problems = 1;
+    }
+
+    requestedBlotCount = get_integer_resource ("count", "Count");
+    if (requestedBlotCount <= 0)
+    {
+       fprintf (stderr, "error: count must be at least 0\n");
+       problems = 1;
+    }
+
+    colorCount = get_integer_resource ("colors", "Colors");
+    if (colorCount <= 0)
+    {
+       fprintf (stderr, "error: colors must be at least 1\n");
+       problems = 1;
+    }
+
+    lineWidth = get_integer_resource ("lineWidth", "LineWidth");
+    if (lineWidth < 0)
+    {
+       fprintf (stderr, "error: line width must be at least 0\n");
+       problems = 1;
+    }
+
+    nervousness = get_float_resource ("nervousness", "Float");
+    if ((nervousness < 0) || (nervousness > 1))
+    {
+       fprintf (stderr, "error: nervousness must be in the range 0..1\n");
+       problems = 1;
+    }
+
+    maxNerveRadius = get_float_resource ("maxNerveRadius", "Float");
+    if ((maxNerveRadius < 0) || (maxNerveRadius > 1))
+    {
+       fprintf (stderr, "error: maxNerveRadius must be in the range 0..1\n");
+       problems = 1;
+    }
+
+    eventChance = get_float_resource ("eventChance", "Float");
+    if ((eventChance < 0) || (eventChance > 1))
+    {
+       fprintf (stderr, "error: eventChance must be in the range 0..1\n");
+       problems = 1;
+    }
+
+    iterAmt = get_float_resource ("iterAmt", "Float");
+    if ((iterAmt < 0) || (iterAmt > 1))
+    {
+       fprintf (stderr, "error: iterAmt must be in the range 0..1\n");
+       problems = 1;
+    }
+
+    minScale = get_float_resource ("minScale", "Float");
+    if ((minScale < 0) || (minScale > 10))
+    {
+       fprintf (stderr, "error: minScale must be in the range 0..10\n");
+       problems = 1;
+    }
+
+    maxScale = get_float_resource ("maxScale", "Float");
+    if ((maxScale < 0) || (maxScale > 10))
+    {
+       fprintf (stderr, "error: maxScale must be in the range 0..10\n");
+       problems = 1;
+    }
+
+    if (maxScale < minScale)
+    {
+       fprintf (stderr, "error: maxScale must be >= minScale\n");
+       problems = 1;
+    }  
+
+    minRadius = get_integer_resource ("minRadius", "Integer");
+    if ((minRadius < 1) || (minRadius > 100))
+    {
+       fprintf (stderr, "error: minRadius must be in the range 1..100\n");
+       problems = 1;
+    }
+
+    maxRadius = get_integer_resource ("maxRadius", "Integer");
+    if ((maxRadius < 1) || (maxRadius > 100))
+    {
+       fprintf (stderr, "error: maxRadius must be in the range 1..100\n");
+       problems = 1;
+    }
+
+    if (maxRadius < minRadius)
+    {
+       fprintf (stderr, "error: maxRadius must be >= minRadius\n");
+       problems = 1;
+    }  
+
+    if (problems)
+    {
+       exit (1);
+    }
+}
+
+/* main function */
+void screenhack (Display *dpy, Window win)
+{
+    display = dpy;
+    window = win;
+
+    initParams ();
+    setup ();
+
+    /* make a valid set to erase at first */
+    renderSegs ();
+    
+    for (;;) 
+    {
+       oneIteration ();
+        XSync (dpy, False);
+        screenhack_handle_events (dpy);
+       usleep (delay);
+    }
+}
diff --git a/hacks/nerverot.man b/hacks/nerverot.man
new file mode 100644 (file)
index 0000000..c080b40
--- /dev/null
@@ -0,0 +1,110 @@
+.TH XScreenSaver 1 "05-Jul-2000" "X Version 11"
+.SH NAME
+nerverot - induces edginess in the viewer
+.SH SYNOPSIS
+.B nerverot
+[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-install] [\-visual \fIvisual\fP] [\-colors \fIinteger\fP] [\-delay \fImicroseconds\fP] [\-count \fIinteger\fP] [\-line-width \fIinteger\fP] [\-event-chance \fIfraction\fP] [\-iter-amt \fIfraction\fP] [\-nervousness \fIfraction\fP] [\-max-nerve-radius \fIfraction\fP] [\-min-radius \fIinteger\fP] [\-max-radius \fIinteger\fP] [\-min-scale \fIfraction\fP] [\-max-scale \fIfraction\fP]
+.SH DESCRIPTION
+The goal of \fInerverot\fP is to be interesting and compelling to
+watch, yet induce a state of nervous edginess in the viewer.
+.SH OPTIONS
+.I nerverot
+accepts the following options:
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-mono 
+If on a color display, pretend we're on a monochrome display.
+.TP 8
+.B \-install
+Install a private colormap for the window.
+.TP 8
+.B \-visual \fIvisual\fP
+Which visual to use.  Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-colors \fIinteger\fP
+How many colors should be used (if possible). The colors
+form a smooth ramp between two randomly-chosen colors. Defaults to 4,
+resource \fIcolors\fP.
+.TP 8
+.B \-delay \fImicroseconds\fP
+The interframe delay, in microseconds. Defaults to 10000, resource
+\fIdelay\fP.
+.TP 8
+.B \-count \fIinteger\fP
+How many "blots" to draw at a time. This number may be rounded down to
+fit the particularly chosen model, and has a fixed minimum per-model.
+Defaults to 250, resource \fIcount\fP.
+.TP 8
+.B \-line-width \fIinteger\fP
+The width of the lines to draw. 0 means an optimized pixel-thick line.
+Defaults to 0, resource \fIlineWidth\fP.
+.TP 8
+.B \-event-chance \fIfraction\fP
+The chance, per iteration, for a life-altering event to occur (such as
+picking a new rotation target), in the range 0..1. Defaults to 0.2,
+resource \fIeventChance\fP.
+.TP 8 
+.B \-iter-amt \fIfraction\fP
+The fraction of movement towards a target (such as rotation angle or scale)
+that happens per iteration, in the range 0..1. Defaults to 0.01,
+resource \fiterAmt\fP.
+.TP 8
+.B \-nervousness \fIfraction\fP
+How nervous the drawing is, in the range 0..1. This is how jumpy the points
+on each blot are. Defaults to 0.3, resource \fInervousness\fP.
+.TP 8
+.B \-max-nerve-radius \fIfraction\fP
+The maximum radius of blot nervousness, as a fraction of the radius of the
+blot, in the range 0..1. Defaults to 0.7, resource \fImaxNerveRadius\fP.
+.TP 8
+.B \-min-radius \fIinteger\fP
+The minimum radius for a blot, in the range 1..100. Defaults to 3,
+resource \fIminRadius\fP.
+.TP 8
+.B \-max-radius \fIinteger\fP
+The maximum radius for a blot, in the range 1..100. Defaults to 25,
+resource \fImaxRadius\fP.
+.TP 8
+.B \-min-scale \fIfraction\fP
+The minimum overall scale of drawing, as a fraction of
+\fImin(windowHeight,windowWidth)\fP, in the range 0..10. Defaults to 0.6,
+resource \fIminScale\fP.
+.TP 8
+.B \-max-scale \fIfraction\fP
+The maximum overall scale of drawing, as a fraction of
+\fImin(windowHeight,windowWidth)\fP, in the range 0..10. Defaults to 1.75,
+resource \fImaxScale\fP.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH X RESOURCES
+There are resource equivalents for each option, noted above.
+.SH BUGS
+.I nerverot
+should have more models.
+.SH SEE ALSO
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2000 by Dan Bornstein.
+
+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
+Dan Bornstein <danfuzz@milk.com>, 05-Jul-2000.
index 78a9de7fc538e8ef72355c13ce8fdefdb34e65b0..b9da70ad7cec69c48d17fe10fdea1c9ed715dbc7 100644 (file)
@@ -1,4 +1,4 @@
-/* petri, simulate mold in a petri dish. v2.6
+/* petri, simulate mold in a petri dish. v2.7
  * by Dan Bornstein, danfuzz@milk.com
  * with help from Jamie Zawinski, jwz@jwz.org
  * Copyright (c) 1992-1999 Dan Bornstein.
@@ -603,33 +603,42 @@ static void update (void)
     
     for (a = head->next; a != tail; a = a->next) 
     {
-        static XPoint coords1[] = {{-1,  0}, { 1, 0}, {0, -1}, {0, 1}};
-        static XPoint coords2[] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
+       static XPoint all_coords[] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1},
+                                     {-1,  0}, { 1, 0}, {0, -1}, {0, 1},
+                                     {99, 99}};
+
         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 = cell_x(a) + coords[i].x;
-              int y = cell_y(a) + 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;
+       {
+           coords = all_coords;
+       }
+        else if (a->growth >= orthlim)
+       {
+           coords = &all_coords[4];
+       }
+       else
+       {
+           continue;
+       }
 
-              newcell (&arr[y * arr_width + x], a->col, a->speed);
-            }
+       while (coords->x != 99)
+       {
+           int x = cell_x(a) + coords->x;
+           int y = cell_y(a) + coords->y;
+           coords++;
+           
+           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) 
            killcell (a);
diff --git a/hacks/petri.man b/hacks/petri.man
new file mode 100644 (file)
index 0000000..32750e4
--- /dev/null
@@ -0,0 +1,125 @@
+.TH XScreenSaver 1 "06-Jul-2000" "X Version 11"
+.SH NAME
+petri - simulates mold growing in a petri dish
+.SH SYNOPSIS
+.B petri
+[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-install] [\-visual \fIvisual\fP] [\-delay \fImicroseconds\fP] [\-size \fIinteger\fP] [\-mem-throttle \fIamount\fP] [\-count \fIinteger\fP] [\-originalcolors] [\-diaglim \fIreal\fP] [\-anychan \fIreal\fP] [\-minorchan \fIreal\fP] [\-instantdeathchan \fIreal\fP] [\-minlifespeed \fIreal\fP] [\-maxlifespeed \fIreal\fP] [\-mindeathspeed \fIreal\fP] [\-maxdeathspeed \fIreal\fP] [\-minlifespan \fIinteger\fP] [\-maxlifespan \fIinteger\fP]
+.SH DESCRIPTION
+\fIpetri\fP simulates mold growing in a petri dish via a state-heavy grid
+of automata (vaguely like Conway's Life, only with much more state per
+cell).
+.SH OPTIONS
+.I petri
+accepts the following options:
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-mono 
+If on a color display, pretend we're on a monochrome display.
+.TP 8
+.B \-install
+Install a private colormap for the window.
+.TP 8
+.B \-visual \fIvisual\fP
+Which visual to use.  Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-delay \fImicroseconds\fP
+The interframe delay, in microseconds. Defaults to 10000, resource
+\fIdelay\fP.
+.TP 8
+.B \-size \fIinteger\fP
+The size of a cell in pixels. Defaults to 4, resource \fIsize\fP.
+.TP 8
+.B \-mem-throttle \fIamount\fP
+The maximum amount of memory to consume, specified either in megabytes
+(suffix "M"), kilobytes (suffix "K"), or bytes (sans suffix). In order
+to meet the memory requirement, the cell size may be increased.
+Defaults to 22M, resource \fImemThrottle\fP.
+.TP 8
+.B \-count \fIinteger\fP
+How many different varieties of mold to grow (including Black Death).
+Defaults to 8, resource \fIcount\fP.
+.TP 8
+.B \-originalcolors
+If specified, indicates that the colors used should be the artist's
+original choices (a fixed set of primary and secondary colors). In this
+case, count must be 8 or less. Defaults to not specified (i.e., false), 
+resource \fIoriginalcolors\fP.
+.TP 8
+.B \-diaglim \fIreal\fP 
+The age limit for diagonal growth as a multiplier of
+orthogonal growth (range 1..2). 1 means square growth, 1.414
+(i.e., \fIsqrt(2)\fP) means approximately circular growth, 2 means
+diamond growth. Defaults to 1.414, resource \fIdiaglim\fP.
+.TP 8
+.B \-anychan \fIreal\fP 
+The chance (range 0..1) that at each iteration, one or more
+new cells will be born. Defaults to 0.0015, resource \fIanychan\fP.
+.TP 8
+.B \-minorchan \fIreal\fP
+The chance (range 0..1) that, given that new cells will be born, that only
+two will be added (hence being a minor cell birth event).
+Defaults to 0.5, resource \fIminorchan\fP.
+.TP 8
+.B \-instantdeathchan \fIreal\fP
+The chance (range 0..1) that, given that death and destruction will happen,
+that instead of using Black Death cells, death will come instantaneously.
+Defaults to 0.2, resource \fIinstantdeathchan\fP.
+.TP 8
+.B \-minlifespeed \fIreal\fP 
+The minimum speed for living cells as a fraction of the maximum possible
+speed (range 0..1). Defaults to 0.04, resource \fIminlifespeed\fP.
+.TP 8
+.B \-maxlifespeed \fIreal\fP
+The maximum speed for living cells as a fraction of the maximum possible
+speed (range 0..1). Defaults to 0.13, resource \fImaxlifespeed\fP.
+.TP 8
+.B \-mindeathspeed \fIreal\fP
+The minimum speed for Black Death cells as a fraction of the maximum possible
+speed (range 0..1). Defaults to 0.42, resource \fImindeathspeed\fP.
+.TP 8
+.B \-maxdeathspeed \fIreal\fP
+The maximum speed for Black Death cells as a fraction of the maximum possible
+speed (range 0..1). Defaults to 0.46, resource \fImaxdeathspeed\fP.
+.TP 8
+.B \-minlifespan \fIinteger\fP 
+The minimum lifespan for a colony, in iterations, before Black Death
+comes. Defaults to 500, resource \fIminlifespan\fP.
+.TP 8
+.B \-maxlifespan \fIinteger\fP
+The maximum lifespan for a colony, in iterations, before Black Death
+comes. Defaults to 1500, resource \fImaxlifespan\fP.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH X RESOURCES
+There are resource equivalents for each option, noted above.
+.SH BUGS
+There are no known bugs in
+.I petri
+as of this writing.
+.SH SEE ALSO
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 1992-2000 by Dan Bornstein.
+
+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
+Dan Bornstein <danfuzz@milk.com>, 06-Jul-2000.
index 9664f803f7ff25d7fc58c4bad700e2c3bc6bd545..793c6e3ac7e6a6616d041c232a04aae9fec28a6d 100644 (file)
@@ -569,7 +569,7 @@ main (int argc, char **argv)
      seeded in any screenhack.  You do not need to seed the RNG again,
      it is done for you before your code is invoked. */
 # undef ya_rand_init
-  ya_rand_init ((int) time ((time_t *) 0));
+  ya_rand_init (0);
 
   screenhack (dpy, window); /* doesn't return */
   return 0;
index 422bc1b2abbd3b0ab55067d886fdfef0f49e64f5..670d667750f6abd2e445212f7dc1634913edc2bd 100644 (file)
@@ -31,6 +31,9 @@
  * [09/17/99] - Shane Smit: Made all calculations based on the size of the
  *                window. Thus, it'll look the same at 100x100 as it does at
  *                1600x1200 ( Only smaller :).
+ * [04/24/00] - Shane Smit: Revamped entire source code:
+ *                Shade Bob movement is calculated very differently.
+ *                Base color can be any color now.
  */
 
 #include <math.h>
@@ -54,20 +57,20 @@ char *defaults [] = {
 XrmOptionDescRec options [] = {
   { "-degrees", ".degrees", XrmoptionSepArg, 0 },
   { "-color",   ".color",   XrmoptionSepArg, 0 },
+  { "-ncolors", ".ncolors", XrmoptionSepArg, 0 },
   { "-count",   ".count",   XrmoptionSepArg, 0 },
   { "-delay",   ".delay",   XrmoptionSepArg, 0 },
   { "-cycles",  ".cycles",  XrmoptionSepArg, 0 },
   { 0, 0, 0, 0 }
 };
 
-static unsigned short nDegreeCount;
-static double *anSinTable;
-static unsigned short nMaxExtentX, nMaxExtentY;
-static unsigned short nMinExtentX, nMinExtentY;
-static unsigned short nHalfWidth, nHalfHeight;
+static unsigned short iDegreeCount;
+static double *anSinTable, *anCosTable;
+static unsigned short iWinWidth, iWinHeight;
+static unsigned short iWinCenterX, iWinCenterY;
 static char *sColor;
-static unsigned char nBobRadius, nBobDiameter; 
-static float nExtentDelta; 
+static unsigned char iBobRadius, iBobDiameter; 
+static unsigned char iVelocity;
 
 #define RANDOM() ((int) (random() & 0X7FFFFFFFL))
 
@@ -77,328 +80,348 @@ static float nExtentDelta;
 
 typedef struct
 {
-  signed char *anDeltaMap;
-  double nVelocityX, nVelocityY;
-  double nAngleX, nAngleY;
-  float nExtentX, nExtentY;
+       signed char *anDeltaMap;
+       double nAngle, nAngleDelta, nAngleInc;
+       double nPosX, nPosY;
 } SShadeBob;
 
 
 static void ResetShadeBob( SShadeBob *pShadeBob )
 {
-  pShadeBob->nAngleX = RANDOM() % nDegreeCount;
-  pShadeBob->nAngleY = RANDOM() % nDegreeCount;
-
-  pShadeBob->nExtentX = (RANDOM() % (nMaxExtentX - nMinExtentX)) + nMinExtentX;
-  pShadeBob->nExtentY = (RANDOM() % (nMaxExtentY - nMinExtentY)) + nMinExtentY;
+       pShadeBob->nPosX = RANDOM() % iWinWidth;
+       pShadeBob->nPosY = RANDOM() % iWinHeight;
+       pShadeBob->nAngle = RANDOM() % iDegreeCount;
+       pShadeBob->nAngleDelta = ( RANDOM() % iDegreeCount ) - ( iDegreeCount / 2.0F );
+       pShadeBob->nAngleInc = pShadeBob->nAngleDelta / 50.0F; 
+       if( pShadeBob->nAngleInc == 0.0F )      
+               pShadeBob->nAngleInc = ( pShadeBob->nAngleDelta > 0.0F ) ? 0.0001F : -0.0001F;
 }
 
 
 static void InitShadeBob( SShadeBob *pShadeBob, Bool bDark )
 {
-  double nDelta;
-  int iWidth, iHeight;
-
-  if( ( pShadeBob->anDeltaMap = calloc( nBobDiameter * nBobDiameter, sizeof(char) ) ) == NULL )
-  {
-    fprintf( stderr, "Could not allocate Delta Map!\n" );
-    return;
-  }
-
-  for( iHeight=-nBobRadius; iHeight<nBobRadius; iHeight++ )
-    for( iWidth=-nBobRadius; iWidth<nBobRadius; iWidth++ )
-    {
-      nDelta = 9 - ( ( sqrt( pow( iWidth+0.5, 2 ) + pow( iHeight+0.5, 2 ) ) / nBobRadius ) * 8 );
-      if( nDelta < 0 )  nDelta = 0;
-      if( bDark ) nDelta = -nDelta;
-      pShadeBob->anDeltaMap[ ( iWidth + nBobRadius ) * nBobDiameter
-                           + iHeight + nBobRadius ] = (char)nDelta;
-    }
+       double nDelta;
+       int iWidth, iHeight;
+
+       if( ( pShadeBob->anDeltaMap = calloc( iBobDiameter * iBobDiameter, sizeof(char) ) ) == NULL )
+       {
+               fprintf( stderr, "%s: Could not allocate Delta Map!\n", progclass );
+               return;
+       }
+
+       for( iHeight=-iBobRadius; iHeight<iBobRadius; iHeight++ )
+               for( iWidth=-iBobRadius; iWidth<iBobRadius; iWidth++ )
+               {
+                       nDelta = 9 - ( ( sqrt( pow( iWidth+0.5, 2 ) + pow( iHeight+0.5, 2 ) ) / iBobRadius ) * 8 );
+                       if( nDelta < 0 )  nDelta = 0;
+                       if( bDark ) nDelta = -nDelta;
+                       pShadeBob->anDeltaMap[ ( iWidth + iBobRadius ) * iBobDiameter + iHeight + iBobRadius ] = (char)nDelta;
+               }
   
-  ResetShadeBob( pShadeBob );
+       ResetShadeBob( pShadeBob );
+}
+
+
+/* A delta is calculated, and the shadebob turns at an increment.  When the delta
+ * falls to 0, a new delta and increment are calculated. */
+static void MoveShadeBob( SShadeBob *pShadeBob )
+{
+       pShadeBob->nAngle          += pShadeBob->nAngleInc;
+       pShadeBob->nAngleDelta -= pShadeBob->nAngleInc;
+
+       if( pShadeBob->nAngle >= iDegreeCount ) pShadeBob->nAngle -= iDegreeCount;
+       else if( pShadeBob->nAngle < 0 )                pShadeBob->nAngle += iDegreeCount;
+       
+       if( ( pShadeBob->nAngleInc>0.0F  && pShadeBob->nAngleDelta<pShadeBob->nAngleInc ) ||
+           ( pShadeBob->nAngleInc<=0.0F && pShadeBob->nAngleDelta>pShadeBob->nAngleInc ) )
+       {
+               pShadeBob->nAngleDelta = ( RANDOM() % iDegreeCount ) - ( iDegreeCount / 2.0F );
+               pShadeBob->nAngleInc = pShadeBob->nAngleDelta / 50.0F;
+               if( pShadeBob->nAngleInc == 0.0F )
+                       pShadeBob->nAngleInc = ( pShadeBob->nAngleDelta > 0.0F ) ? 0.0001F : -0.0001F;
+       }
+       
+       pShadeBob->nPosX = ( anSinTable[ (int)pShadeBob->nAngle ] * iVelocity ) + pShadeBob->nPosX;
+       pShadeBob->nPosY = ( anCosTable[ (int)pShadeBob->nAngle ] * iVelocity ) + pShadeBob->nPosY;
+
+       /* This wraps it around the screen. */
+       if( pShadeBob->nPosX >= iWinWidth )     pShadeBob->nPosX -= iWinWidth;
+       else if( pShadeBob->nPosX < 0 )         pShadeBob->nPosX += iWinWidth;
+       
+       if( pShadeBob->nPosY >= iWinHeight )    pShadeBob->nPosY -= iWinHeight;
+       else if( pShadeBob->nPosY < 0 )                 pShadeBob->nPosY += iWinHeight;
 }
 
 
 static void Execute( SShadeBob *pShadeBob, Display *pDisplay,
                      Window MainWindow,
-                     GC *pGC, XImage *pXImage,
-                     int ncolors, XColor *aXColors )
+                     GC *pGC, XImage *pImage,
+                     signed short iColorCount, unsigned long *aiColorVals )
 {
-  long nColor;
-  short nIndex;
-  unsigned int nXPos, nYPos;
-  unsigned int iWidth, iHeight;
-
-  pShadeBob->nVelocityX += ( ( RANDOM() % 200 ) - 100 ) / 1000.0F;
-  pShadeBob->nVelocityY += ( ( RANDOM() % 200 ) - 100 ) / 1000.0F;
-
-  if(      pShadeBob->nVelocityX > 4 )  pShadeBob->nVelocityX = 4;
-  else if( pShadeBob->nVelocityX < 3 )  pShadeBob->nVelocityX = 3;
-  if(      pShadeBob->nVelocityY > 4 )  pShadeBob->nVelocityY = 4;
-  else if( pShadeBob->nVelocityY < 3 )  pShadeBob->nVelocityY = 3;
-
-  pShadeBob->nAngleX += pShadeBob->nVelocityX;
-  pShadeBob->nAngleY += pShadeBob->nVelocityY;
-
-  if( pShadeBob->nAngleX >= nDegreeCount ) pShadeBob->nAngleX -= nDegreeCount;
-  if( pShadeBob->nAngleY >= nDegreeCount ) pShadeBob->nAngleY -= nDegreeCount;
-
-  pShadeBob->nExtentX += ( ( ( RANDOM() % 5 ) - 2 ) / 2.0F ) * nExtentDelta;
-  if( pShadeBob->nExtentX > nMaxExtentX ) pShadeBob->nExtentX = nMaxExtentX;
-  if( pShadeBob->nExtentX < nMinExtentX ) pShadeBob->nExtentX = nMinExtentX;
-  pShadeBob->nExtentY += ( ( ( RANDOM() % 5 ) - 2 ) / 2.0F ) * nExtentDelta;
-  if( pShadeBob->nExtentY > nMaxExtentY ) pShadeBob->nExtentY = nMaxExtentY;
-  if( pShadeBob->nExtentY < nMinExtentY ) pShadeBob->nExtentY = nMinExtentY;
-
-  /* Trig is your friend :) */
-  nXPos = (unsigned int)(( anSinTable[ (int)pShadeBob->nAngleX ] * pShadeBob->nExtentX )
-                         + nHalfWidth);
-  nYPos = (unsigned int)(( anSinTable[ (int)pShadeBob->nAngleY ] * pShadeBob->nExtentY )
-                         + nHalfHeight);
-
-  for( iHeight=0; iHeight<nBobDiameter; iHeight++ )
-  {
-    for( iWidth=0; iWidth<nBobDiameter; iWidth++ )
-    {
-      nColor = XGetPixel( pXImage, nXPos + iWidth, nYPos + iHeight );
-
-      /*  FIXME: Here is a loop I'd love to take out. */
-      for( nIndex=0; nIndex < ncolors; nIndex++ )
-        if( aXColors[ nIndex ].pixel == nColor )
-          break;
-
-      nIndex += pShadeBob->anDeltaMap[ iWidth * nBobDiameter + iHeight ];
-      if( nIndex >= ncolors ) nIndex = ncolors-1;
-      if( nIndex < 0 )  nIndex = 0;
-
-      XPutPixel( pXImage, nXPos + iWidth, nYPos + iHeight,
-                 aXColors[ nIndex ].pixel );
-    }
-  }
-
-  XPutImage( pDisplay, MainWindow, *pGC, pXImage,
-             nXPos, nYPos, nXPos, nYPos, nBobDiameter, nBobDiameter );
-  XSync (pDisplay, False);
+       unsigned long iColor;
+       short iColorVal;
+       int iPixelX, iPixelY;
+       unsigned int iWidth, iHeight;
+
+       MoveShadeBob( pShadeBob );
+       
+       for( iHeight=0; iHeight<iBobDiameter; iHeight++ )
+       {
+               iPixelY = pShadeBob->nPosY + iHeight;
+               if( iPixelY >= iWinHeight )     iPixelY -= iWinHeight;
+
+               for( iWidth=0; iWidth<iBobDiameter; iWidth++ )
+               {
+                       iPixelX = pShadeBob->nPosX + iWidth;
+                       if( iPixelX >= iWinWidth )      iPixelX -= iWinWidth;
+
+                       iColor = XGetPixel( pImage, iPixelX, iPixelY );
+
+                       /*  FIXME: Here is a loop I'd love to take out. */
+                       for( iColorVal=0; iColorVal<iColorCount; iColorVal++ )
+                               if( aiColorVals[ iColorVal ] == iColor )
+                                       break;
+
+                       iColorVal += pShadeBob->anDeltaMap[ iWidth * iBobDiameter + iHeight ];
+                       if( iColorVal >= iColorCount ) iColorVal = iColorCount - 1;
+                       if( iColorVal < 0 )                        iColorVal = 0;
+
+                       XPutPixel( pImage, iPixelX, iPixelY, aiColorVals[ iColorVal ] );
+               }
+       }
+
+       /* FIXME: if it's next to the top or left sides of screen this will break. However, it's not noticable. */
+       XPutImage( pDisplay, MainWindow, *pGC, pImage,
+             pShadeBob->nPosX, pShadeBob->nPosY, pShadeBob->nPosX, pShadeBob->nPosY, iBobDiameter, iBobDiameter );
+       XSync( pDisplay, False );
 }
 
 
 static void CreateTables( unsigned int nDegrees )
 {
-  double nRadian;
-  unsigned int iDegree;
-  anSinTable = calloc( nDegrees, sizeof(double) );
-
-  for( iDegree=0; iDegree<nDegrees; iDegree++ )
-  {
-    nRadian = ( (double)(2*iDegree) / (double)nDegrees ) * M_PI;
-    anSinTable[ iDegree ] = sin( nRadian );
-  }
+       double nRadian;
+       unsigned int iDegree;
+       anSinTable = calloc( nDegrees, sizeof(double) );
+       anCosTable = calloc( nDegrees, sizeof(double) );
+
+       for( iDegree=0; iDegree<nDegrees; iDegree++ )
+       {
+               nRadian = ( (double)(2*iDegree) / (double)nDegrees ) * M_PI;
+               anSinTable[ iDegree ] = sin( nRadian );
+               anCosTable[ iDegree ] = cos( nRadian );
+       }
 }
 
 
-static void SetPalette(Display *pDisplay, Window Win, char *sColor,
-                       int *ncolorsP, XColor *aXColors )
+static unsigned long * SetPalette(Display *pDisplay, Window Win, char *sColor, signed short *piColorCount )
 {
-  XWindowAttributes XWinAttrib;
-  Colormap CMap;
-  XColor Color;
-  int nHue;
-  double nSat, nVal;
-
-  XGetWindowAttributes( pDisplay, Win, &XWinAttrib );
-  CMap = XWinAttrib.colormap;
-
-  Color.red = ( RANDOM() % 3 ) * 0x7FFF;    /*  Either full, half or none. */
-  Color.green = ( RANDOM() % 3 ) * 0x7FFF;
-  Color.blue = ( RANDOM() % 3 ) * 0x7FFF;
-
-  /*  If Color is black, grey, or white, then make SURE its a color */
-  if( Color.red == Color.green && Color.green == Color.blue )
-  { Color.red = 0xFFFF;
-    Color.green = ( RANDOM() % 3 ) * 0x7FFF;
-    Color.blue = 0; }
-
-  if( strcasecmp( sColor, "random" ) &&
-      !XParseColor( pDisplay, CMap, sColor, &Color ) )
-    fprintf( stderr,
-             "%s: color %s not found in database. Choosing to random...\n",
-             progname, sColor );
-
-  rgb_to_hsv( Color.red, Color.green, Color.blue, &nHue, &nSat, &nVal );
+       XWindowAttributes XWinAttribs;
+       XColor Color, *aColors;
+       unsigned long *aiColorVals;
+       signed short iColor;
+       float nHalfColors;
+       
+       XGetWindowAttributes( pDisplay, Win, &XWinAttribs );
+       
+       Color.red =   RANDOM() % 0xFFFF;
+       Color.green = RANDOM() % 0xFFFF;
+       Color.blue =  RANDOM() % 0xFFFF;
+
+       if( strcasecmp( sColor, "random" ) && !XParseColor( pDisplay, XWinAttribs.colormap, sColor, &Color ) )
+               fprintf( stderr, "%s: color %s not found in database. Choosing to random...\n", progname, sColor );
+
 #ifdef VERBOSE
-  printf( "RGB (%d, %d, %d) = HSV (%d, %g, %g)\n",
-          Color.red, Color.green, Color.blue, nHue, nSat, nVal );
+       printf( "%s: Base color (RGB): <%d, %d, %d>\n", progclass, Color.red, Color.green, Color.blue );
 #endif  /*  VERBOSE */
 
-  if (*ncolorsP != 0)
-    free_colors (pDisplay, CMap, aXColors, *ncolorsP);
-
-  *ncolorsP = get_integer_resource ("ncolors", "Integer");
-  if (*ncolorsP <= 0) *ncolorsP = 64;
-
-  /* allocate two color ramps, black -> color -> white. */
-  {
-    int n1, n2;
-    n1 = *ncolorsP / 2;
-    make_color_ramp( pDisplay, CMap, 0, 0, 0, nHue, nSat, nVal,
-                     aXColors, &n1,
-                     False, True, False );
-    n2 = *ncolorsP - n1;
-    make_color_ramp( pDisplay, CMap, nHue, nSat, nVal, 0, 0, 1,
-                     aXColors + n1, &n2,
-                     False, True, False );
-    *ncolorsP = n1 + n2;
-  }
-
-  XSetWindowBackground( pDisplay, Win, aXColors[ 0 ].pixel );
+       *piColorCount = get_integer_resource( "ncolors", "Integer" );
+       if( *piColorCount <   2 )       *piColorCount = 2;
+       if( *piColorCount > 255 )       *piColorCount = 255;
+
+       aColors    = calloc( *piColorCount, sizeof(XColor) );
+       aiColorVals = calloc( *piColorCount, sizeof(unsigned long) );
+       
+       for( iColor=0; iColor<*piColorCount; iColor++ )
+       {
+               nHalfColors = *piColorCount / 2.0F;
+               /* Black -> Base Color */
+               if( iColor < (*piColorCount/2) )
+               {
+                       aColors[ iColor ].red   = ( Color.red   / nHalfColors ) * iColor;
+                       aColors[ iColor ].green = ( Color.green / nHalfColors ) * iColor;
+                       aColors[ iColor ].blue  = ( Color.blue  / nHalfColors ) * iColor;
+               }
+               /* Base Color -> White */
+               else
+               {
+                       aColors[ iColor ].red   = ( ( ( 0xFFFF - Color.red )   / nHalfColors ) * ( iColor - nHalfColors ) ) + Color.red;
+                       aColors[ iColor ].green = ( ( ( 0xFFFF - Color.green ) / nHalfColors ) * ( iColor - nHalfColors ) ) + Color.green;
+                       aColors[ iColor ].blue  = ( ( ( 0xFFFF - Color.blue )  / nHalfColors ) * ( iColor - nHalfColors ) ) + Color.blue;
+               }
+
+               if( !XAllocColor( pDisplay, XWinAttribs.colormap, &aColors[ iColor ] ) )
+               {
+                       /* start all over with less colors */   
+                       XFreeColors( pDisplay, XWinAttribs.colormap, aiColorVals, iColor, 0 );
+                       free( aColors );
+                       free( aiColorVals );
+                       piColorCount--;
+                       aColors     = calloc( *piColorCount, sizeof(XColor) );
+                       aiColorVals = calloc( *piColorCount, sizeof(unsigned long) );
+                       iColor = -1;
+               }
+               else
+                       aiColorVals[ iColor ] = aColors[ iColor ].pixel;
+       }
+
+       free( aColors );
+
+       XSetWindowBackground( pDisplay, Win, aiColorVals[ 0 ] );
+
+       return aiColorVals;
 }
 
 
-static void Initialize( Display *pDisplay, Window Win,
-                        GC *pGC, XImage **pXImage,
-                        int *ncolorsP, XColor *aXColors )
+static void Initialize( Display *pDisplay, Window Win, GC *pGC, XImage **ppImage )
 {
-  XGCValues gcValues;
-  XWindowAttributes XWinAttribs;
-  int bpp;
-
-  /* Create the Image for drawing */
-  XGetWindowAttributes( pDisplay, Win, &XWinAttribs );
-
-  /* Find the preferred bits-per-pixel. */
-  {
-    int i, pfvc = 0;
-    XPixmapFormatValues *pfv = XListPixmapFormats (pDisplay, &pfvc);
-    for (i = 0; i < pfvc; i++)
-      if (pfv[i].depth == XWinAttribs.depth)
-        {
-          bpp = pfv[i].bits_per_pixel;
-          break;
-        }
-    if (pfv)
-      XFree (pfv);
-  }
-
-  /*  Create the GC. */
-  *pGC = XCreateGC( pDisplay, Win, 0, &gcValues );
-
-  *pXImage = XCreateImage(pDisplay, XWinAttribs.visual,
-                         XWinAttribs.depth,
-                         ZPixmap, 0, NULL,
-                         XWinAttribs.width, XWinAttribs.height,
-                         BitmapPad(pDisplay), 0);
-  (*pXImage)->data = calloc((*pXImage)->bytes_per_line,
-                           (*pXImage)->height);
-
-  /*  These are precalculations used in Execute(). */
-  nBobDiameter = XWinAttribs.width / 25;
-  nBobRadius = nBobDiameter / 2;
-  nExtentDelta = nBobRadius / 5.0F;
+       XGCValues gcValues;
+       XWindowAttributes XWinAttribs;
+       int iBitsPerPixel;
+
+       /* Create the Image for drawing */
+       XGetWindowAttributes( pDisplay, Win, &XWinAttribs );
+
+       /* Find the preferred bits-per-pixel. (jwz) */
+       {
+               int i, pfvc = 0;
+               XPixmapFormatValues *pfv = XListPixmapFormats( pDisplay, &pfvc );
+               for( i=0; i<pfvc; i++ )
+                       if( pfv[ i ].depth == XWinAttribs.depth )
+                       {
+                               iBitsPerPixel = pfv[ i ].bits_per_pixel;
+                               break;
+                       }
+               if( pfv )
+                       XFree (pfv);
+       }
+
+       /*  Create the GC. */
+       *pGC = XCreateGC( pDisplay, Win, 0, &gcValues );
+
+       *ppImage = XCreateImage( pDisplay, XWinAttribs.visual, XWinAttribs.depth, ZPixmap, 0, NULL,
+                                                         XWinAttribs.width, XWinAttribs.height, BitmapPad( pDisplay ), 0 );
+       (*ppImage)->data = calloc((*ppImage)->bytes_per_line, (*ppImage)->height);
+
+       iWinWidth = XWinAttribs.width;
+       iWinHeight = XWinAttribs.height;
+
+       /*  These are precalculations used in Execute(). */
+       iBobDiameter = ( ( iWinWidth < iWinHeight ) ? iWinWidth : iWinHeight ) / 25;
+       iBobRadius = iBobDiameter / 2;
 #ifdef VERBOSE
-  printf( "Bob Diameter = %d\n", nBobDiameter );
+       printf( "%s: Bob Diameter = %d\n", progclass, iBobDiameter );
 #endif
 
-  nHalfWidth = ( XWinAttribs.width / 2 ) - nBobRadius;
-  nHalfHeight = ( XWinAttribs.height / 2 ) - nBobRadius;
-  nMaxExtentX = nHalfWidth - nBobRadius;
-  nMaxExtentY = nHalfHeight - nBobRadius;
-  nMinExtentX = nMaxExtentX / 3;
-  nMinExtentY = nMaxExtentY / 3;
-  
-  /*  Create the Sin and Cosine lookup tables. */
-  nDegreeCount = get_integer_resource( "degrees", "Integer" );
-  if(      nDegreeCount == 0   ) nDegreeCount = ( XWinAttribs.width / 6 ) + 400;
-  else if( nDegreeCount < 90   ) nDegreeCount = 90;
-  else if( nDegreeCount > 5400 ) nDegreeCount = 5400;
-  CreateTables( nDegreeCount );
+       iWinCenterX = ( XWinAttribs.width / 2 ) - iBobRadius;
+       iWinCenterY = ( XWinAttribs.height / 2 ) - iBobRadius;
+
+       iVelocity = ( ( iWinWidth < iWinHeight ) ? iWinWidth : iWinHeight ) / 150;
+       
+       /*  Create the Sin and Cosine lookup tables. */
+       iDegreeCount = get_integer_resource( "degrees", "Integer" );
+       if(      iDegreeCount == 0   ) iDegreeCount = ( XWinAttribs.width / 6 ) + 400;
+       else if( iDegreeCount < 90   ) iDegreeCount = 90;
+       else if( iDegreeCount > 5400 ) iDegreeCount = 5400;
+       CreateTables( iDegreeCount );
 #ifdef VERBOSE
-  printf( "Using a %d degree circle.\n", nDegreeCount );
+       printf( "%s: Using a %d degree circle.\n", progclass );
 #endif /* VERBOSE */
   
-  /*  Get the colors. */
-  sColor = get_string_resource( "color", "Color" );
-  if( sColor == NULL)
-    SetPalette( pDisplay, Win, "random", ncolorsP, aXColors );
-  else
-    SetPalette( pDisplay, Win, sColor, ncolorsP, aXColors );
+       /*  Get the base color. */
+       sColor = get_string_resource( "color", "Color" );
 }
 
 
 void screenhack(Display *pDisplay, Window Win )
 {
-  GC gc;
-  int ncolors = 0;
-  XColor aXColors[ 256 ];
-  XImage *pImage;
-  unsigned char nShadeBobCount, iShadeBob;
-  SShadeBob *aShadeBobs;
+       GC gc;
+       signed short iColorCount = 0;
+       unsigned long *aiColorVals = NULL;
+       XImage *pImage = NULL;
+       unsigned char nShadeBobCount, iShadeBob;
+       SShadeBob *aShadeBobs;
 #ifdef VERBOSE
-  time_t nTime = time( NULL );
-  unsigned short iFrame = 0;
+       time_t nTime = time( NULL );
+       unsigned short iFrame = 0;
 #endif  /*  VERBOSE */
-  int delay, cycles, i;
+       int delay, cycles, i;
 
-  nShadeBobCount = get_integer_resource( "count", "Integer" );
-  if( nShadeBobCount > 64 ) nShadeBobCount = 64;
-  if( nShadeBobCount < 1 )  nShadeBobCount = 1;
+       nShadeBobCount = get_integer_resource( "count", "Integer" );
+       if( nShadeBobCount > 64 ) nShadeBobCount = 64;
+       if( nShadeBobCount <  1 ) nShadeBobCount = 1;
 
-  if( ( aShadeBobs = calloc( nShadeBobCount, sizeof(SShadeBob) ) ) == NULL )
-  {
-    fprintf( stderr, "Could not allocate %d ShadeBobs\n", nShadeBobCount );
-    return;
-  }
+       if( ( aShadeBobs = calloc( nShadeBobCount, sizeof(SShadeBob) ) ) == NULL )
+       {
+               fprintf( stderr, "%s: Could not allocate %d ShadeBobs\n", progclass, nShadeBobCount );
+               return;
+       }
 #ifdef VERBOSE 
-  printf( "Allocated %d ShadeBobs\n", nShadeBobCount );
+       printf( "%s: Allocated %d ShadeBobs\n", progclass, nShadeBobCount );
 #endif  /*  VERBOSE */
 
-  Initialize( pDisplay, Win, &gc, &pImage, &ncolors, aXColors );
+       Initialize( pDisplay, Win, &gc, &pImage );
 
-  for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
-    InitShadeBob( &aShadeBobs[ iShadeBob ], iShadeBob % 2 );
+       for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
+               InitShadeBob( &aShadeBobs[ iShadeBob ], iShadeBob % 2 );
 
-  delay = get_integer_resource( "delay", "Integer" );
-  cycles = get_integer_resource( "cycles", "Integer" ) * nDegreeCount;
-  i = cycles;
+       delay = get_integer_resource( "delay", "Integer" );
+       cycles = get_integer_resource( "cycles", "Integer" ) * iDegreeCount;
+       i = cycles;
 
-  while( 1 )
-  {
-    screenhack_handle_events( pDisplay );
+       while( 1 )
+       {
+               screenhack_handle_events( pDisplay );
 
-    if (i++ >= cycles)
-    {
-      i = 0;
-      XClearWindow( pDisplay, Win );
-      memset( pImage->data, 0, pImage->bytes_per_line * pImage->height );
-      for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
-        ResetShadeBob( &aShadeBobs[ iShadeBob ] );
-      SetPalette( pDisplay, Win, sColor, &ncolors, aXColors );
-    }
+               if( i++ >= cycles )
+               {
+                       i = 0;
+                       XClearWindow( pDisplay, Win );
+                       memset( pImage->data, 0, pImage->bytes_per_line * pImage->height );
+                       for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
+                               ResetShadeBob( &aShadeBobs[ iShadeBob ] );
+                       free( aiColorVals );
+                       aiColorVals = SetPalette( pDisplay, Win, sColor, &iColorCount );
+               }
 
-    for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
-      Execute( &aShadeBobs[ iShadeBob ], pDisplay, Win, &gc,
-               pImage, ncolors, aXColors );
+               for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
+                       Execute( &aShadeBobs[ iShadeBob ], pDisplay, Win, &gc, pImage, iColorCount, aiColorVals );
 
-    if( delay && !(i % 4) )
-               usleep(delay);
+               if( delay && !(i % 4) )
+                       usleep(delay);
 
 #ifdef VERBOSE
-    iFrame++;
-    if( nTime - time( NULL ) )
-    {
-      printf( "FPS: %d\n", iFrame );
-      nTime = time( NULL );
-      iFrame = 0;
-    }
+               iFrame++;
+               if( nTime - time( NULL ) )
+               {
+                       printf( "%s: %d FPS\n", progclass, iFrame );
+                       nTime = time( NULL );
+                       iFrame = 0;
+               }
 #endif  /*  VERBOSE */
-  }
-
-  free( anSinTable );
-  free( pImage->data );
-  XDestroyImage( pImage );
-  for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
-    free( aShadeBobs[ iShadeBob ].anDeltaMap );
-  free( aShadeBobs );
+       }
+
+       free( anSinTable );
+       free( anCosTable );
+       free( pImage->data );
+       XDestroyImage( pImage );
+       for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
+               free( aShadeBobs[ iShadeBob ].anDeltaMap );
+       free( aShadeBobs );
+       free( aiColorVals );
 }
 
 
 /* End of Module - "shadebobs.c" */
+
+/* vim: ts=4
+ */
index c4169f663dbd362d0a02dc8d492f40fb951d38c9..0608ac5bf668e94c0f92ccd4add89a4aab495cea 100644 (file)
@@ -37,7 +37,7 @@
  * software for any purpose.  It is provided "as is" without express or 
  * implied warranty.
  *
- * $Revision: 1.14 $
+ * $Revision: 1.16 $
  *
  * Version 1.0 April 27, 1998.
  * - Initial version
@@ -86,6 +86,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
+#include <sys/stat.h>
 
 #include "screenhack.h"
 #include "colors.h"
@@ -149,6 +150,7 @@ static u_short checksum(u_short *, int);
 #endif
 static long delta(struct timeval *, struct timeval *);
 
+
 /* Data Structures */
 
 /*
@@ -195,8 +197,13 @@ typedef struct {
     int sweepnum;               /* The current id of the sweep */
     int delay;                 /* how long between each frame of the anim */
 
+    int TTL;                   /* The number of ticks that bogies are visible
+                                   on the screen before they fade away. */
 } sonar_info;
 
+static Bool debug_p = False;
+
+
 /* 
  * Variables to support the differnt Sonar modes.
  */
@@ -283,16 +290,15 @@ char *defaults [] = {
     "*textSteps:       80",    /* npixels */
     "*sweepSegments:   80",    /* npixels */
 
-#ifdef HAVE_PING
     "*pingTimeout:     3000",
-    "*pingSource:      file",
-    "*pingFile:        /etc/hosts",
-    "*pingList:        localhost",
-#endif /* HAVE_PING */
+
     "*teamAName:       F18",
     "*teamBName:       MIG",
     "*teamACount:      4",
     "*teamBCount:      4",
+
+    "*ping:           default",
+    ".debug:          false",
     0
 };
 
@@ -305,28 +311,20 @@ XrmOptionDescRec options [] = {
     {"-grid-color",   ".gridColor",    XrmoptionSepArg, 0 },
     {"-text-color",   ".textColor",    XrmoptionSepArg, 0 },
     {"-ttl",          ".ttl",          XrmoptionSepArg, 0 },
-    {"-mode",         ".mode",         XrmoptionSepArg, 0 },
     {"-font",         ".font",         XrmoptionSepArg, 0 },
 #ifdef HAVE_PING
     {"-ping-timeout", ".pingTimeout",  XrmoptionSepArg, 0 },
-    {"-ping-source",  ".pingSource",   XrmoptionSepArg, 0 },
-    {"-ping-file",    ".pingFile",     XrmoptionSepArg, 0 },
-    {"-ping-list",    ".pingList",     XrmoptionSepArg, 0 },
 #endif /* HAVE_PING */
     {"-team-a-name",   ".teamAName",   XrmoptionSepArg, 0 },
     {"-team-b-name",   ".teamBName",   XrmoptionSepArg, 0 },
     {"-team-a-count",  ".teamACount",  XrmoptionSepArg, 0 },
     {"-team-b-count",  ".teamBCount",  XrmoptionSepArg, 0 },
+
+    {"-ping",          ".ping",        XrmoptionSepArg, 0 },
+    {"-debug",         ".debug",       XrmoptionNoArg, "True" },
     { 0, 0, 0, 0 }
 };
 
-/*
- * The number of ticks that bogies are visable on the screen before they
- * fade away.
- */
-
-static int TTL;
-
 /*
  * Create a new Bogie and set some initial values.
  *
@@ -370,6 +368,7 @@ newBogie(char *name, int distance, int tick, int ttl)
  *    b - The bogie to free.
  */
 
+
 static void
 freeBogie(Bogie *b) 
 {
@@ -434,6 +433,8 @@ static int
 lookupHost(ping_target *target) 
 {
 
+  struct hostent *hent;
+
     /* Local Variables */
 
     struct sockaddr_in *iaddr;
@@ -443,19 +444,29 @@ lookupHost(ping_target *target)
 
     iaddr = (struct sockaddr_in *) &(target->address);
     iaddr->sin_family = AF_INET;
-    if ((iaddr->sin_addr.s_addr = inet_addr(target->name)) == -1) {
+    if ((iaddr->sin_addr.s_addr = inet_addr(target->name)) >= 0) {
+      char ip[4];
+      ip[3] = iaddr->sin_addr.s_addr >> 24 & 255;
+      ip[2] = iaddr->sin_addr.s_addr >> 16 & 255;
+      ip[1] = iaddr->sin_addr.s_addr >>  8 & 255;
+      ip[0] = iaddr->sin_addr.s_addr       & 255;
+      hent = gethostbyaddr (ip, 4, AF_INET);
+      if (hent && hent->h_name && *hent->h_name) {
+        target->name = strdup (hent->h_name);
+        return 1;
+      }
+    }
 
-       /* Conversion of IP address failed, try to look the host up by name */
+    /* Conversion of IP address failed, try to look the host up by name */
 
-       struct hostent *hent = gethostbyname(target->name);
-       if (hent == NULL) {
-           fprintf(stderr, "%s: could not resolve host %s\n",
-                    progname, target->name);
-           return 0;
-       }
-       memcpy(&iaddr->sin_addr, hent->h_addr_list[0],
-              sizeof(iaddr->sin_addr));
+    hent = gethostbyname(target->name);
+    if (hent == NULL) {
+      fprintf(stderr, "%s: could not resolve host %s\n",
+              progname, target->name);
+      return 0;
     }
+    memcpy(&iaddr->sin_addr, hent->h_addr_list[0],
+           sizeof(iaddr->sin_addr));
 
     /* Done */
 
@@ -498,6 +509,15 @@ newHost(char *name)
 
     /* Done */
 
+    if (debug_p)
+      {
+        struct sockaddr_in *iaddr = (struct sockaddr_in *) &(target->address);
+        unsigned long ip = iaddr->sin_addr.s_addr;
+        fprintf (stderr, "%s:   added host %d.%d.%d.%d (%s)\n", progname,
+                 ip & 255, ip >> 8 & 255, ip >> 16 & 255, ip >> 24 & 255, 
+                 target->name);
+      }
+
     return target;
 
     /* Handle errors here */
@@ -522,7 +542,6 @@ target_init_error:
 static ping_target *
 readPingHostsFile(char *fname) 
 {
-
     /* Local Variables */
 
     FILE *fp;
@@ -548,6 +567,9 @@ readPingHostsFile(char *fname)
        return NULL;
     }
 
+    if (debug_p)
+      fprintf (stderr, "%s:  reading file %s\n", progname, fname);
+
     /* Read the file line by line */
 
     while ((p = fgets(buf, LINE_MAX, fp)) != NULL) {
@@ -610,47 +632,43 @@ readPingHostsFile(char *fname)
     return list;
 }
 
-/*
- * Generate a list of ping targets from the entries in a string.
- *
- * Args:
- *    list - A list of comma separated host names.
- *
- * Returns:
- *    A list of targets to ping or null if an error occured.
- */
 
 static ping_target *
-readPingHostsList(char *list) 
+delete_duplicate_hosts (ping_target *list)
 {
+  ping_target *head = list;
+  ping_target *rest;
 
-    /* Local Variables */
-
-    char *host;
-    ping_target *hostlist = NULL;
-    ping_target *new;
+  for (rest = head; rest; rest = rest->next)
+    {
+      struct sockaddr_in *i1 = (struct sockaddr_in *) &(rest->address);
+      unsigned long ip1 = i1->sin_addr.s_addr;
 
-    /* Check that there is a list */
+      static ping_target *rest2;
+      for (rest2 = rest; rest2; rest2 = rest2->next)
+        {
+          if (rest2 && rest2->next)
+            {
+              struct sockaddr_in *i2 = (struct sockaddr_in *)
+                &(rest2->next->address);
+              unsigned long ip2 = i2->sin_addr.s_addr;
 
-    if ((list == NULL) || (list[0] == '\0'))
-       return NULL;
+              if (ip1 == ip2)
+                {
+                  if (debug_p)
+                    fprintf (stderr, "%s: deleted duplicate: %s\n",
+                             progname, rest2->next->name);
+                  rest2->next = rest2->next->next;
+                }
+            }
+        }
+    }
 
-    /* Loop through the hosts and add them to the list to return */
+  return head;
+}
 
-    host = strtok(list, ",");
-    while (host != NULL) {
-       new = newHost(host);
-       if (new != NULL) {
-           new->next = hostlist;
-           hostlist = new;
-       }
-       host = strtok(NULL, ",");
-    }
 
-    /* Done */
 
-    return hostlist;
-}
 
 /*
  * Generate a list ping targets consisting of all of the entries on
@@ -661,8 +679,9 @@ readPingHostsList(char *list)
  */
 
 static ping_target *
-subnetHostsList(void
+subnetHostsList(int base, int subnet_width
 {
+    unsigned long mask;
 
     /* Local Variables */
 
@@ -674,6 +693,26 @@ subnetHostsList(void)
     ping_target *new;
     ping_target *list = NULL;
 
+    if (subnet_width < 24)
+      {
+        fprintf (stderr,
+    "%s: pinging %u hosts is a bad idea; please use a subnet mask of 24 bits\n"
+                 "       or more (255 hosts max.)\n",
+                 progname, 1L << (32 - subnet_width));
+        exit (1);
+      }
+    else if (subnet_width > 30)
+      {
+        fprintf (stderr, "%s: a subnet of %d bits doesn't make sense:"
+                 " try \"subnet/24\" or \"subnet/29\".\n",
+                 progname, subnet_width);
+        exit (1);
+      }
+
+
+    if (debug_p)
+      fprintf (stderr, "%s:   adding %d-bit subnet\n", progname, subnet_width);
+
     /* Get our hostname */
 
     if (gethostname(hostname, BUFSIZ)) {
@@ -689,29 +728,50 @@ subnetHostsList(void)
     }
     strcpy(address, inet_ntoa(*((struct in_addr *)hent->h_addr_list[0])));
 
-    /* Get a pointer to the last "." in the string */
-
-    if ((p = strrchr(address, '.')) == NULL) {
-       fprintf(stderr, "%s: can't parse IP address %s\n", progname, address);
-       return NULL;
-    }
-    p++;
-
     /* Construct targets for all addresses in this subnet */
 
-    /* #### jwz: actually, this is wrong, since it assumes a
-       netmask of 255.255.255.0.  But I'm not sure how to find
-       the local netmask.
-     */
-    for (i = 254; i > 0; i--) {
+    mask = 0;
+    for (i = 0; i < subnet_width; i++)
+      mask |= (1L << (31-i));
+
+    /* If no base IP specified, assume localhost. */
+    if (base == 0)
+      base = ((((unsigned char) hent->h_addr_list[0][0]) << 24) |
+              (((unsigned char) hent->h_addr_list[0][1]) << 16) |
+              (((unsigned char) hent->h_addr_list[0][2]) <<  8) |
+              (((unsigned char) hent->h_addr_list[0][3])));
+
+    for (i = 255; i >= 0; i--) {
+        int ip = (base & 0xFFFFFF00) | i;
+      
+        if ((ip & mask) != (base & mask))   /* not in the mask range at all */
+          continue;
+        if ((ip & ~mask) == 0)              /* broadcast address */
+          continue;
+        if ((ip & ~mask) == ~mask)          /* broadcast address */
+          continue;
+
+        sprintf (address, "%d.%d.%d.%d", 
+                 (ip>>24)&255, (ip>>16)&255, (ip>>8)&255, (ip)&255);
+
+        if (debug_p > 1)
+          fprintf(stderr, "%s:  subnet: %s (%d.%d.%d.%d & %d.%d.%d.%d / %d)\n",
+                  progname,
+                  address,
+                  (base>>24)&255, (base>>16)&255, (base>>8)&255, base&mask&255,
+                  (mask>>24)&255, (mask>>16)&255, (mask>>8)&255, mask&255,
+                  subnet_width);
+
+        p = address + strlen(address) + 1;
        sprintf(p, "%d", i);
+
        new = newHost(address);
        if (new != NULL) {
            new->next = list;
            list = new;
        }
     }
-  
+
     /* Done */
 
     return list;
@@ -724,14 +784,17 @@ subnetHostsList(void)
  *    A newly allocated ping_info structure or null if an error occured.
  */
 
+static ping_target *parse_mode (Bool ping_works_p);
+
 static ping_info *
 init_ping(void) 
 {
 
+  Bool socket_initted_p = False;
+
     /* Local Variables */
 
     ping_info *pi = NULL;              /* The new ping_info struct */
-    char *src;                         /* The source of the ping hosts */
     ping_target *pt;                   /* Used to count the targets */
 
     /* Create the ping info structure */
@@ -741,61 +804,31 @@ init_ping(void)
        goto ping_init_error;
     }
 
-    /* Create the ICMP socket and turn off SUID */
+    /* Create the ICMP socket */
 
-    if ((pi->icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
-       char msg[1024];
-       sprintf(msg, "%s: can't create ICMP socket", progname);
-       perror(msg);
-       fprintf(stderr,
-         "%s: this program must be setuid to root for `ping mode' to work.\n",
-                progname);
-       goto ping_init_error;
+    if ((pi->icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) >= 0) {
+      socket_initted_p = True;
     }
+
+    /* Disavow privs */
+
     setuid(getuid());
+
+
     pi->pid = getpid() & 0xFFFF;
     pi->seq = 0;
     pi->timeout = get_integer_resource("pingTimeout", "PingTimeout");
 
     /* Generate a list of targets */
 
-    src = get_string_resource("pingSource", "PingSource");
-    if (strcmp(src, "file") == 0) {
-
-       /*
-         * The list of ping targets is to come from a file in
-        * /etc/hosts format
-        */
-
-       pi->targets = readPingHostsFile(get_string_resource("pingFile",
-                                                           "PingFile"));
-
-    } else if (strcmp(src, "list") == 0) {
-
-       /* The list of hosts is to come from the pinghostlist resource */
-
-       pi->targets = readPingHostsList(get_string_resource("pingList",
-                                                           "PingList"));
-
-    } else if (strcmp(src, "subnet") == 0) {
+    pi->targets = parse_mode (socket_initted_p);
+    pi->targets = delete_duplicate_hosts (pi->targets);
 
-       pi->targets = subnetHostsList();
-
-    } else {
-
-       /* Unknown source */
-
-       fprintf(stderr,
-               "%s: pingSource must be `file', `list', or `subnet', not: %s\n",
-                progname, src);
-        exit (1);
-    }
 
     /* Make sure there is something to ping */
 
     if (pi->targets == NULL) {
-       fprintf(stderr, "%s: nothing to ping", progname);
-       goto ping_init_error;
+      goto ping_init_error;
     }
 
     /* Count the targets */
@@ -819,6 +852,7 @@ ping_init_error:
     return NULL;
 }
 
+
 /*
  * Ping a host.
  *
@@ -955,7 +989,7 @@ checksum(u_short *packet, int size)
  */
 
 static Bogie *
-getping(sonar_info *si, ping_info *pi, int ttl
+getping(sonar_info *si, ping_info *pi) 
 {
 
     /* Local Variables */
@@ -1061,7 +1095,7 @@ getping(sonar_info *si, ping_info *pi, int ttl)
 
        /* Create the new Bogie and add it to the list we are building */
 
-       if ((new = newBogie(name, 0, si->current, ttl)) == NULL)
+       if ((new = newBogie(name, 0, si->current, si->TTL)) == NULL)
            return bl;
        new->next = bl;
        bl = new;
@@ -1125,7 +1159,7 @@ ping(sonar_info *si, void *vpi)
 
     /* Get the results */
 
-    return getping(si, pi, TTL);
+    return getping(si, pi);
 }
 
 #endif /* HAVE_PING */
@@ -1281,7 +1315,9 @@ init_sonar(Display *dpy, Window win)
     /* Get the delay between animation frames */
 
     si->delay = get_integer_resource ("delay", "Integer");
+
     if (si->delay < 0) si->delay = 0;
+    si->TTL = get_integer_resource("ttl", "TTL");
 
     /* Create the Graphics Contexts that will be used to draw things */
 
@@ -1395,7 +1431,7 @@ simulator(sonar_info *si, void *vinfo)
        t = &info->teamA[i];
        if ((t->movedonsweep != si->sweepnum) &&
            (t->nexttick == (si->current * -1))) {
-           new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
+           new = newBogie(strdup(t->name), t->nextdist, si->current, si->TTL);
            if (list != NULL)
                new->next = list;
            list = new;
@@ -1410,7 +1446,7 @@ simulator(sonar_info *si, void *vinfo)
        t = &info->teamB[i];
        if ((t->movedonsweep != si->sweepnum) &&
            (t->nexttick == (si->current * -1))) {
-           new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
+           new = newBogie(strdup(t->name), t->nextdist, si->current, si->TTL);
            if (list != NULL)
                new->next = list;
            list = new;
@@ -1670,6 +1706,118 @@ Sonar(sonar_info *si, Bogie *bl)
     drawGrid(si);
 }
 
+
+static ping_target *
+parse_mode (Bool ping_works_p)
+{
+  char *source = get_string_resource ("ping", "Ping");
+  char *token, *end;
+
+  ping_target *hostlist = 0;
+
+  if (!source) source = strdup("");
+
+  if (!*source || !strcmp (source, "default"))
+    {
+# ifdef HAVE_PING
+      if (ping_works_p)                /* if root or setuid, ping will work. */
+        source = strdup("subnet/29,/etc/hosts");
+      else
+# endif
+        source = strdup("simulation");
+    }
+
+  token = source;
+  end = source + strlen(source);
+  while (token < end)
+    {
+      char *next;
+      ping_target *new;
+      struct stat st;
+      unsigned int n0=0, n1=0, n2=0, n3=0, m=0;
+      char d;
+
+      for (next = token;
+           *next != ',' && *next != ' ' && *next != '\t' && *next != '\n';
+           next++)
+        ;
+      *next = 0;
+
+
+      if (debug_p)
+        fprintf (stderr, "%s: parsing %s\n", progname, token);
+
+      if (!strcmp (token, "simulation"))
+        return 0;
+
+      if (!ping_works_p)
+        {
+          fprintf(stderr,
+           "%s: this program must be setuid to root for `ping mode' to work.\n"
+             "       Running in `simulation mode' instead.\n",
+                  progname);
+          return 0;
+        }
+
+      if ((4 == sscanf (token, "%d.%d.%d/%d %c",    &n0,&n1,&n2,    &m,&d)) ||
+          (5 == sscanf (token, "%d.%d.%d.%d/%d %c", &n0,&n1,&n2,&n3,&m,&d)))
+        {
+          /* subnet: A.B.C.D/M
+             subnet: A.B.C/M
+           */
+          unsigned long ip = (n0 << 24) | (n1 << 16) | (n2 << 8) | n3;
+          new = subnetHostsList(ip, m);
+        }
+      else if (4 == sscanf (token, "%d.%d.%d.%d %c", &n0, &n1, &n2, &n3, &d))
+        {
+          /* IP: A.B.C.D
+           */
+          new = newHost (token);
+        }
+      else if (!strcmp (token, "subnet"))
+        {
+          new = subnetHostsList(0, 24);
+        }
+      else if (1 == sscanf (token, "subnet/%d %c", &m))
+        {
+          new = subnetHostsList(0, m);
+        }
+      else if (*token == '.' || *token == '/' || !stat (token, &st))
+        {
+          /* file name
+           */
+          new = readPingHostsFile (token);
+        }
+      else
+        {
+          /* not an existant file - must be a host name
+           */
+          new = newHost (token);
+        }
+
+      if (new)
+        {
+          ping_target *nn = new;
+          while (nn && nn->next)
+            nn = nn->next;
+          nn->next = hostlist;
+          hostlist = new;
+
+          sensor = ping;
+        }
+
+      token = next + 1;
+      while (token < end &&
+             (*token == ',' || *token == ' ' ||
+              *token == '\t' || *token == '\n'))
+        token++;
+    }
+
+  return hostlist;
+}
+
+
+
 /*
  * Main screen saver hack.
  *
@@ -1688,56 +1836,24 @@ screenhack(Display *dpy, Window win)
     struct timeval start, finish;
     Bogie *bl;
     long sleeptime;
-    char *mode;
 
-    /* 
-     * Initialize 
-     * Adding new sensors would involve supporting more modes other than
-     * ping and initiailizing the sensor in the same way.
-     */
+    debug_p = get_boolean_resource ("debug", "Debug");
 
-    mode = get_string_resource("mode", "Mode");
+    sensor = 0;
+    sensor_info = (void *) init_ping();
 
-    if (!mode || !*mode || !strcmp(mode, "default")) /* Pick a good default. */
+    if (sensor == 0)
       {
-#ifdef HAVE_PING
-        if (geteuid() == 0)    /* we're root or setuid -- ping will work. */
-          mode = "ping";
-        else
-#endif
-          mode = "simulation";
+        sensor = simulator;
+        if ((sensor_info = (void *) init_sim()) == NULL)
+          exit(1);
       }
 
-#ifdef HAVE_PING
-    if (strcmp(mode, "ping") == 0) {
-       sensor = ping;
-       if ((sensor_info = (void *) init_ping()) == (void *) 0)
-          {
-            fprintf (stderr, "%s: running in `simulation mode' instead.\n",
-                     progname);
-           goto SIM;
-          }
-    } else
-#endif /* HAVE_PING */
-    if (strcmp(mode, "simulation") == 0) {
-#ifdef HAVE_PING
-    SIM:
-#endif
-       sensor = simulator;
-       if ((sensor_info = (void *) init_sim()) == NULL)
-           exit(1);
-    } else {
-       fprintf(stderr, "%s: unsupported Sonar mode: %s\n", progname, mode);
-       fprintf(stderr,
-                "\tCurrently supported modes are `ping' and `simulation'\n");
-       exit(1);
-    }
     if ((si = init_sonar(dpy, win)) == (sonar_info *) 0)
        exit(1);
-  
-    /* Sonar loop */
 
-    TTL = get_integer_resource("ttl", "TTL");
+
+    /* Sonar loop */
 
     while (1) {
 
index 13139720fe4f3cad1e7bb78c88ee28248340b210..1db5982abd20a6bf760a5f3e1a1f1214621119ce 100644 (file)
@@ -16,6 +16,7 @@
 sonar - display a sonar scope
 .SH SYNOPSIS
 .B sonar
+[\-ping \fIhosts-or-subnets\fP]
 [\-background \fIcolor\fP]
 [\-sweep\-color \fIcolor\fP]
 [\-low\-color \fIcolor\fP] 
@@ -23,16 +24,13 @@ sonar - display a sonar scope
 [\-grid\-color \fIcolor\fP]
 [\-text\-color \fIcolor\fP]
 [\-ttl \fIinteger\fP]
-[\-mode ping]
 [\-font \fIfont\fP]
 [\-ping\-timeout \fIint\fP]
-[\-ping\-source list | file | subnet ] 
-[\-ping\-file \fIhosts-file\fP]
-[\-ping\-list \fIhost-name-list\fP]
 [\-team-a-name \fIstring\fP] 
 [\-team-b-name \fIstring\fP]
 [\-team-a-count \fIint\fP]
 [\-team-b-count \fIint\fP]
+[\-debug] 
 .SH DESCRIPTION
 The \fIsonar\fP program displays a sonar scope on the computer's screen.
 This scope polls a sensor as the sweep goes around the scope and displays
@@ -63,10 +61,6 @@ The color of the text identifying bogies on the scope.
 "Time to live": visible time of a Bogie. Try values between 10 (very short)
 and 100. 
 .TP 8
-.B \-mode \fIsimulation | ping\fP
-The sensor mode to use, the currently supported modes \fIsimulate\fP (the
-default) and \fIping\fP.
-.TP 8
 .B \-font \fIfont\fP
 The font used to display text on the scope.  Default "fixed".
 .TP 8
@@ -74,37 +68,52 @@ The font used to display text on the scope.  Default "fixed".
 The amount of time in milliseconds the program will wait for an answer
 to a ping.
 .TP 8
-.B \-ping\-source list | file | subnet
-Th source of the list of hosts to ping. Valid values are: \fIlist\fP,
-\fIfile\fP, \fIsubnet\fP.  The first two values are described below;
-and \fIsubnet\fP indicates that the sonar should ping all hosts in the
-same subnet as the current machine.  (All addresses are treated
-as class C nets, therefore this will at most ping 254 hosts.)
-.TP 8
-.B \-ping\-file \fIfilename\fP
-The path to a file listing the hosts to ping.  This file can be in the
+.B \-ping \fIhosts-or-subnets\fP
+The list of things to ping, separated by commas or spaces. 
+Elements of this list may be:
+.RS 8
+.TP 12
+.B simulation
+to run in simulation mode, instead of pinging real hosts (this is the default
+if the program is not installed setuid);
+.TP 12
+.I hostname
+to ping the given host;
+.TP 12
+.I A.B.C.D
+to ping the given IP address;
+.TP 12
+.B subnet
+to ping the local class C subnet (the nearest 255 addresses);
+.TP 12
+.B subnet/\fINN\fP
+to ping a different-sized local subnet: e.g., \fBsubnet/28\fP would ping
+a 4-bit subnet (the nearest 15 addresses);
+.TP 12
+.I A.B.C.D/NN
+to ping an arbitrary other subnet: the IP address specifies the base address,
+and the part after the slash is how wide the subnet is.  Typical values
+are /24 (for 255 addresses) and /28 (for 15 addresses.)
+.TP 12
+.I filename
+to ping the hosts listed in the given file.  This file can be in the
 format used by \fI/etc/hosts\fP, or it can be any file that has host
 names as the first element on each line.  If you use ssh, try this:
-.EX
-sonar -mode ping -ping-file $HOME/.ssh/known_hosts
-.EE
-This is used only used when \fIpingSource\fP is set to \fBfile\fP.
-.TP 8
-.B \-ping\-list \fIlist\fP
-A comma separated list of hostnames, eg \fI"pinky,brain,dot"\fP.
-Only used when \fIpingSource\fP is set to \fBlist\fP.
+
+  sonar -ping $HOME/.ssh/known_hosts
+.RE
 .TP 8
 .B \-team-a-name \fIstring\fP
-The name of team A, in simulation-mode.
+In simulation mode, the name of team A.
 .TP 8
 .B \-team-b-name \fIstring\fP
-The name of team B, in simulation-mode.
+In simulation mode, the name of team B.
 .TP 8
 .B \-team-a-count \fIint\fP
-The number of bogies on team A, in simulation-mode.
+In simulation mode, the number of bogies on team A.
 .TP 8
 .B \-team-b-count \fIint\fP
-The number of bogies on team B, in simulation-mode.
+In simulation mode, the number of bogies on team B.
 .SH RESOURCES
 Configuration of the targets to ping is best done by setting X Resources.
 .PP
@@ -127,9 +136,10 @@ See option \-text\-color, above; default value is \fI#ffff00\fP.
 .B ttl \fI(integer)\fP
 See option \-ttl, above; default value is \fI90\fP or one sweep.
 .TP 8
-.B mode \fI(ping)\fP
-See option \-mode, above.  If set to \fBdefault\fP, it will ping hosts if
-possible, otherwise, will run in simulation-mode.
+.B ping \fI(string)\fP
+See option \-ping, above.  If set to \fBdefault\fP, it will ping
+the contents of /etc/hosts if possible, otherwise, will run in
+simulation-mode.
 .TP 8
 .B font \fI(font)\fP
 See option \-font, above; default value is \fIfixed\fP.
@@ -137,15 +147,6 @@ See option \-font, above; default value is \fIfixed\fP.
 .B pingTimeout \fI(Integer)\fP
 See option \-pingtimeout, above; default value is 3000.
 .TP 8
-.B pingSource \fIlist | file | subnet\fP
-See option \-ping\-source, above.  Default value is \fIfile\fP.
-.TP 8
-.B pingFile \fIpathname\fP
-See option \-ping\-file, above.  Default value is \fI/etc/hosts\fP.
-.TP 8
-.B pingList \fIhost,host,host...\fP
-See option \-ping\-list, above; default value is \fBlocalhost\fP.
-.TP 8
 .B teamAName \fIstring\fP
 See option \-team\-a\-name, above.  Default value is \fBF18\fP.
 .TP 8
@@ -183,3 +184,4 @@ amoung other things.
 
 Thomas Bahls <thommy@cs.tu-berlin.de> hacked the "ttl" option, 12-jul-98.
 
+Better subnet support and command-line processing by Jamie Zawinski, 17-Jul-00.
index 880dfb933f6125a3d9494783765932e19616a830..289cd5be48579ca1acfb80bb809545985ecdbe46 100755 (executable)
@@ -27,7 +27,7 @@ require POSIX;
 use Fcntl ':flock'; # import LOCK_* constants
 
 
-my $version = q{ $Revision: 1.44 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.54 $ }; $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";
@@ -56,6 +56,8 @@ my $image_randomizer_2 = "http://www.hotbot.com/?clickSrc=search" .
                          "&MT=";
 my $image_randomizer_3 = "http://www.altavista.com/cgi-bin/query?pg=q" .
                          "&text=yes&kl=XX&stype=stext&q=";
+my $image_randomizer_4 = "http://search.news.yahoo.com/search/news_photos?" .
+                         "&z=&n=100&o=o&2=&3=&p=";
 
 # I guess Photopoint got wise to me, because now they are doing error
 # checking on the user ("u=") and album ("a=") parameters.  Oh well.
@@ -608,7 +610,8 @@ sub pick_from_image_randomizer {
 
     my $search_url = ($which == 0 ? $image_randomizer_1 :
                       $which == 1 ? $image_randomizer_2 :
-                      $image_randomizer_3) .
+                      $which == 2 ? $image_randomizer_3 :
+                      $image_randomizer_4) .
         $words;
 
     # Pick a random search-result page instead of always taking the first.
@@ -659,8 +662,8 @@ sub pick_from_image_randomizer {
 
     $_ = $body;
 
-    s/Result [Pp]ages:.*$//s;            # trim off page footer
-    s/^.*?IMAGE RESULTS//s;              # trim off page header
+#    s/Result [Pp]ages:.*$//s;            # trim off page footer
+#    s/^.*?IMAGE RESULTS//s;              # trim off page header
 
     s/[\r\n\t ]+/ /g;
 
@@ -691,6 +694,8 @@ sub pick_from_image_randomizer {
         next if ($u =~ m@[/.]wildweb\.com@i);
         next if ($u =~ m@[/.]digital\.com@i);
         next if ($u =~ m@[/.]doubleclick\.net@i);
+        next if ($u =~ m@[/.]freeim\.org@i);
+        next if ($u =~ m@[/.]clicktomarket\.com@i);  # you cretins
 
         if ($which == 0 && $u =~ m@[/.]corbis\.com@) {
             $skipped = 1;
@@ -699,6 +704,16 @@ sub pick_from_image_randomizer {
             }
             next;
 
+        } elsif ($which == 3 &&
+                 ($u =~ m@^http://[^/]+$@ ||             # no slashes
+                  $u =~ m@/$@ ||                         # ends in /
+                  ! ($u =~ m@dailynews\.yahoo\.com@))) {  # not dailynews
+#            $skipped = 1;
+            if ( $verbose > 3 ) {
+                print STDERR "$progname: skipping non-AP URL: $u\n";
+            }
+            next;
+
         } elsif ( $rejected_urls{$u} ) {
             if ( $verbose > 3 ) {
                 my $L = $rejected_urls{$u};
@@ -748,7 +763,9 @@ sub pick_from_image_randomizer {
     if ($img) {
         return ($base2, $img,
                 ($which == 0 ? "imagevista" :
-                 $which == 1 ? "hotbot" : "altavista") .
+                 $which == 1 ? "hotbot" :
+                 $which == 2 ? "altavista" :
+                 "ap") .
                 "/$search_count");
     } else {
         return ();
@@ -789,6 +806,7 @@ sub pick_image {
     my ( $timeout ) = @_;
 
     my $r = int(rand(100));
+
     my ($base, $img, $source, $total, $count);
 
     if ($r < 20) {
@@ -801,6 +819,11 @@ sub pick_image {
         $total = ++$total_1;
         $count = ++$count_1 if $img;
 
+     } elsif ($r < 70) {
+         ($base, $img, $source) = pick_from_image_randomizer ($timeout, 3);
+         $total = ++$total_4;
+         $count = ++$count_4 if $img;
+
 #    } elsif ($r < 70) {
 #        ($base, $img, $source) = pick_from_photo_randomizer ($timeout);
 #        $total = ++$total_4;
@@ -1023,7 +1046,14 @@ sub image_to_pnm {
 
     $cmd2 = "exec $cmd";        # yes, this really is necessary.  if we don't
                                 # do this, the process doesn't die properly.
-    if ($verbose == 0) {
+    if ($verbose <= 1) {
+        #
+        # We get a "giftopnm: got a 'Application Extension' extension"
+        # warning any time it's an animgif.
+        #
+        # Note that "giftopnm: EOF / read error on image data" is not
+        # always a fatal error -- sometimes the image looks fine anyway.
+        #
         $cmd2 .= " 2>/dev/null";
     }
 
index 623103c0e3f5c8e47dd3eb3f74279a8058c7ae71..6279000dcef5424a61a48e304a198305d932492d 100644 (file)
@@ -222,7 +222,7 @@ screenhack (Display *dpy, Window window)
              while (typo[i] && typo[i][0] != c)
                i++;
              if (typo[i])
-               c = typo[i][0xFF & (random() % strlen(typo[i]+1))];
+                c = typo[i][0xFF & ((random() % strlen(typo[i]+1)) + 1)];
            }
 
          /* caps typo */
index ca4fb9e0d0a02f4d423398777cbeed092a76d0b7..3ebf585e640cc77e3a1390087ef974aebf4f2321 100644 (file)
@@ -1,8 +1,8 @@
-/*****************************************************************************
+/****************************************************************************
  *                                                                           *
  * xsublim -- Submit.  Conform.  Obey.                                       *
  *                                                                           *
- * Copyright (c) 1999 Greg Knauss (greg@eod.com)                             *
+ * Copyright (c) 1999 - 2000 Greg Knauss (greg@eod.com)                      *
  *                                                                           *
  * Thanks to Jamie Zawinski, whose suggestions and advice made what was a    *
  * boring little program into a less boring (and a _lot_ less little)        *
@@ -32,6 +32,7 @@
 
        -font font           Font to use
        -file filename       New-line delimited phrase file
+       -program executable  New-line delimited phrase-producing executable
        -delayShow ms        Microsecs for display of each word
        -delayWord ms        Microsecs for blank between words
        -delayPhraseMin ms   Microsecs for min blank between phrases
@@ -49,6 +50,7 @@
 
 /* Changelog ******************************************************************
 
+       1.1.1  20000407  Added -program
        1.1.0  19991221  Added -file
        1.0.1  19990716  Assume that XGetImage()/XDestroyImage() don't leak,
                          which they apparently don't.  I have no idea how I
 #define XSUBLIM_TEXT_COUNT         1000
 #define XSUBLIM_TEXT_LENGTH        128
 #define XSUBLIM_TEXT_OUTLINE       1
+#define XSUBLIM_PROGRAM_SIZE       1024*10
 #define XSUBLIM_ARG_DELAYSHOW      "delayShow"
 #define XSUBLIM_ARG_DELAYWORD      "delayWord"
 #define XSUBLIM_ARG_DELAYPHRASEMIN "delayPhraseMin"
 #define XSUBLIM_ARG_DELAYPHRASEMAX "delayPhraseMax"
 #define XSUBLIM_ARG_RANDOM         "random"
 #define XSUBLIM_ARG_FILE           "file"
+#define XSUBLIM_ARG_PROGRAM        "program"
 #define XSUBLIM_ARG_SCREENSAVER    "screensaver"
 #define XSUBLIM_ARG_OUTLINE        "outline"
 #define XSUBLIM_ARG_CENTER         "center"
@@ -186,6 +190,10 @@ XrmOptionDescRec options[] =
         XrmoptionNoArg,"false"},
        {"-" XSUBLIM_ARG_FILE,          "." XSUBLIM_ARG_FILE,
         XrmoptionSepArg,0 },
+#if !defined(VMS)
+       {"-" XSUBLIM_ARG_PROGRAM,       "." XSUBLIM_ARG_PROGRAM,
+        XrmoptionSepArg,0 },
+#endif
        {"-" XSUBLIM_ARG_SCREENSAVER,   "." XSUBLIM_ARG_SCREENSAVER,
         XrmoptionNoArg,"true"},
        {"-no-" XSUBLIM_ARG_SCREENSAVER,"." XSUBLIM_ARG_SCREENSAVER,
@@ -450,6 +458,7 @@ int main(int argc,char* argv[])
        int               arg_DelayPhraseMin;
        int               arg_DelayPhraseMax;
        char*             arg_Text;
+       char*             arg_Source;
 
        /* Set-up ---------------------------------------------------------- */
 
@@ -463,7 +472,7 @@ int main(int argc,char* argv[])
        /* Randomize -- only need to do this here because this program
            doesn't use the `screenhack.h' or `lockmore.h' APIs. */
 # undef ya_rand_init
-        ya_rand_init ((int) time ((time_t *) 0));
+        ya_rand_init (0);
 
        /* Handle all the X nonsense */
 #if defined(__sgi)
@@ -532,23 +541,23 @@ int main(int argc,char* argv[])
        text_Item = 0;
        text_Count = 0;
        memset(text_Used,0,sizeof(text_Used));
-       arg_Text = get_string_resource(XSUBLIM_ARG_FILE,"Filename");
-       if (arg_Text != NULL)
+       arg_Source = get_string_resource(XSUBLIM_ARG_FILE,"Filename");
+       if (arg_Source != NULL)
        {
                FILE*       file_Fs;
                struct stat file_Stat;
 
-               file_Fs = fopen(arg_Text,"rb");
+               file_Fs = fopen(arg_Source,"rb");
                if (file_Fs == NULL)
                {
                        fprintf(stderr,"%s: Could not open '%s'\n",progname,
-                        arg_Text);
+                        arg_Source);
                        exit(-1);
                }
                if (fstat(fileno(file_Fs),&file_Stat) != 0)
                {
                        fprintf(stderr,"%s: Could not stat '%s'\n",progname,
-                        arg_Text);
+                        arg_Source);
                        exit(-1);
                }
                arg_Text = calloc(1,file_Stat.st_size+1);
@@ -557,7 +566,7 @@ int main(int argc,char* argv[])
                        if (fread(arg_Text,file_Stat.st_size,1,file_Fs) != 1)
                        {
                                fprintf(stderr,"%s: Could not read '%s'\n",
-                                progname,arg_Text);
+                                progname,arg_Source);
                                exit(-1);
                        }
                }
@@ -565,10 +574,62 @@ int main(int argc,char* argv[])
        }
        else
        {
-               arg_Text = get_string_resource(XSUBLIM_ARG_PHRASES,"Phrases");
-               if (arg_Text != NULL)
+               arg_Source = get_string_resource(XSUBLIM_ARG_PROGRAM,
+                "Executable");
+               if (arg_Source != NULL)
+               {
+                       char* exe_Command = calloc(1,strlen(arg_Source)+10);
+                       FILE* exe_Fs;
+
+                       if (exe_Command == NULL)
+                       {
+                               fprintf(stderr,
+                                "%s: Could not allocate space for '%s'\n",
+                                progname,arg_Source);
+                               exit(-1);
+                       }
+                       sprintf(exe_Command,"( %s ) 2>&1",arg_Source);
+
+                       exe_Fs = popen(exe_Command,"r");
+                       if (exe_Fs == NULL)
+                       {
+                               fprintf(stderr,"%s: Could not run '%s'\n",
+                                progname,arg_Source);
+                               exit(-1);
+                       }
+                       arg_Text = calloc(1,XSUBLIM_PROGRAM_SIZE);
+                       if (arg_Text != NULL)
+                       {
+                               if (fread(arg_Text,1,XSUBLIM_PROGRAM_SIZE,
+                                exe_Fs) <= 0)
+                               {
+                                       fprintf(stderr,
+                                        "%s: Could not read output of '%s'\n",
+                                        progname,arg_Source);
+                                       exit(-1);
+                               }
+                               if (
+                                strstr(arg_Text,": not found") ||
+                                strstr(arg_Text,": Not found") ||
+                                strstr(arg_Text,": command not found") ||
+                                strstr(arg_Text,": Command not found"))
+                               {
+                                       fprintf(stderr,
+                                        "%s: Could not find '%s'\n",
+                                        progname,arg_Source);
+                                       exit(-1);
+                               }
+                       }
+                       fclose(exe_Fs);
+               }
+               else
                {
-                       arg_Text = strdup(arg_Text);
+                       arg_Text =
+                        get_string_resource(XSUBLIM_ARG_PHRASES,"Phrases");
+                       if (arg_Text != NULL)
+                       {
+                               arg_Text = strdup(arg_Text);
+                       }
                }
        }
        if (arg_Text != NULL)
index bbae1c2cb0995d95445a97b1e20b4314a48ab1c5..dea4ae905e67699f9c81e15f6dc9ca0596d5b56b 100644 (file)
@@ -3,7 +3,7 @@
 xsublim - Display (submit) "subliminal" (conform) messages (obey)
 .SH SYNOPSIS
 .B xsublim
-[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-font \fIfont\fP] [\-file \fIfilename\fP] [\-delayShow \fIms\fP] [\-delayWord \fIms\fP] [\-delayPhraseMin \fIms\fP] [\-delayPhraseMax \fIms\fP] [\-random] [\-no\-random] [\-screensaver] [\-no\-screensaver] [\-outline] [\-no\-outline] [\-center] [\-no\-center]
+[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-font \fIfont\fP] [\-file \fIfilename\fP] [\-program \fIexecutable\fP] [\-delayShow \fIms\fP] [\-delayWord \fIms\fP] [\-delayPhraseMin \fIms\fP] [\-delayPhraseMax \fIms\fP] [\-random] [\-no\-random] [\-screensaver] [\-no\-screensaver] [\-outline] [\-no\-outline] [\-center] [\-no\-center]
 .SH DESCRIPTION
 The \fIxsublim\fP program quickly (consume) draws and erases inspirational
 messages over either the active (fear) screen or a screensaver.
@@ -16,11 +16,15 @@ The font to use.  Legal (watch tv) values include any fontspec.
 .TP 8
 .B \-file \fIfilename\fP
 A new-line delimited phrase file.  Specifying this argument will over-ride
-the "phrases" resource entry.
+the "program" command-line argument and the "phrases" resource entry.
+.TP 8
+.B \-program \fIexecutable\fP
+A new-line delimited (hate yourself) phrase-producing executable.  Specifying
+this argument will over-ride the "phrases" resource entry.
 .TP 8
 .B \-delayShow \fIms\fP
-The number of (hate yourself) microseconds to display each (never question)
-word.  The default is 40,000.
+The number of microseconds to display each (never question) word.  The default
+is 40,000.
 .TP 8
 .B \-delayWord \fIms\fP
 The number (be silent) of microseconds to pause between displaying (buy
index fdb259dfe91155281e24c8a45ff1c360edca9652..5119f319dd6c6b0a4b34f7c52e1da557bf5cb2cd 100644 (file)
--- a/setup.com
+++ b/setup.com
@@ -57,6 +57,7 @@ $ moire               :== $'mydir'moire
 $ moire2       :== $'mydir'moire2
 $ mountain     :== $'mydir'mountain
 $ munch                :== $'mydir'munch
+$ nerverot     :== $'mydir'nerverot
 $ noseguy      :== $'mydir'noseguy
 $ pedal                :== $'mydir'pedal
 $ penetrate    :== $'mydir'penetrate
index a3dc37e39e83403dd1e07928cc8e30311b0c31b8..ef0ef62f3e48a6e37992dfe5ce23b634572999bf 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
-       "@(#)xscreensaver 3.24 (03-Apr-2000), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 3.25 (18-Jul-2000), by Jamie Zawinski (jwz@jwz.org)";
index e04d2cb9f0a80704c07862abe50e75d05c0b5eb4..e746d0f702e595eda0fc1b54974febb839b8ea0f 100644 (file)
@@ -1,7 +1,7 @@
 Begin3
 Title:          xscreensaver
-Version:        3.24
-Entered-date:   03APR00
+Version:        3.25
+Entered-date:   19JUL00
 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/
-                1284K xscreensaver-3.24.tar.gz
-                40K  xscreensaver.README
+                1284K xscreensaver-3.25.tar.gz
+                41K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
-                1284K xscreensaver-3.24.tar.gz
-                40K  xscreensaver.README
+                1284K xscreensaver-3.25.tar.gz
+                41K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: ftp.x.org /contrib/applications/
-                1284K xscreensaver-3.24.tar.gz
-                40K  xscreensaver.README
+                1284K xscreensaver-3.25.tar.gz
+                41K  xscreensaver.README
                 1K   xscreensaver.lsm
 Platforms:      Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
                 BSDI, SCO, OSF1, Ultrix, VMS.
index 6dc9021048af66666770df16d160589e5b2a4908..d4cfb709f18cb714d1670cd9cda0e0bac437e770 100644 (file)
@@ -1,5 +1,5 @@
 %define        name    xscreensaver
-%define        version 3.24
+%define        version 3.25
 %define        release 1
 %define        serial  1
 %define        prefix  /usr/X11R6
@@ -84,6 +84,11 @@ mkdir -p $RPM_BUILD_ROOT/etc/pam.d
 if [ -z "$KDEDIR" ]; then export KDEDIR=/usr; fi
 mkdir -p $RPM_BUILD_ROOT$KDEDIR/bin
 
+# And two more for Gnome (same reason...)
+#
+mkdir -p $RPM_BUILD_ROOT/usr/share/control-center/Desktop
+mkdir -p $RPM_BUILD_ROOT/usr/share/gnome/apps/Settings/Desktop
+
 make  install_prefix=$RPM_BUILD_ROOT \
       AD_DIR=%{prefix}/lib/X11/app-defaults \
       install-strip
@@ -117,26 +122,6 @@ install -m 4755 driver/xscreensaver $RPM_BUILD_ROOT%{prefix}/bin
 ( cd driver ;
   make install_prefix=$RPM_BUILD_ROOT PAM_DIR=/etc/pam.d install-pam )
 
-# This is for wmconfig, a tool that generates init files for window managers.
-#
-mkdir -p $RPM_BUILD_ROOT/etc/X11/wmconfig
-cat > $RPM_BUILD_ROOT/etc/X11/wmconfig/xscreensaver <<EOF
-xscreensaver name "xscreensaver (1min timeout)"
-xscreensaver description "xscreensaver"
-xscreensaver group "Amusements/Screen Savers"
-xscreensaver exec "xscreensaver -timeout 1 -cycle 1 &"
-EOF
-
-# This is for the GNOME desktop:
-#
-mkdir -p "$RPM_BUILD_ROOT/usr/share/apps/Amusements/Screen Savers"
-cat > "$RPM_BUILD_ROOT/usr/share/apps/Amusements/Screen Savers/xscreensaver.desktop" <<EOF
-[Desktop Entry]
-Name=xscreensaver (1min timeout)
-Description=xscreensaver
-Exec=xscreensaver -timeout 1 -cycle 1
-EOF
-
 # Make sure all files are readable by all, and writable only by owner.
 #
 chmod -R a+r,u+w,og-w $RPM_BUILD_ROOT
@@ -157,8 +142,8 @@ if [ -d $RPM_BUILD_ROOT-gl ]; then rm -r $RPM_BUILD_ROOT-gl ; fi
                     %{prefix}/man/man1/xscreensaver*
                     /etc/pam.d/*
 %config(missingok)  /usr/bin/*.kss
-%config(missingok)  /etc/X11/wmconfig/*
-%config(missingok)  "/usr/share/apps/Amusements/Screen Savers/*"
+%config(missingok)  "/usr/share/control-center/Desktop/screensaver-properties.desktop"
+%config(missingok)  "/usr/share/gnome/apps/Settings/Desktop/screensaver-properties.desktop"
 
 # Files for the "xscreensaver-gl" package:
 #