============
+Changes since 3.17: * New versions of `shadebobs', `lmorph', and `distort'.
+ * Added `ccurve', `blaster', and `bumps' hacks.
+ * Replaced `forest' hack with a rewritten version.
+ * Worked around a Xinerama server bug.
+ * Fixed a bug I introduced in 3.10 that caused some
+ hacks to print out superfluous warnings about not
+ having gotten enough colors.
+ * Made `sproingies' obey the `-delay' option.
+ * Fixed a portability bug in `shadebobs'.
+ * Made `webcollage' and `vidwhacker' use `xli' in
+ preference to `xv', if it is available.
+ * Added a new source of images to `webcollage'.
+ * If running under KDE, xscreensaver will add itself to
+ KDE's list of screensavers (via xscreensaver.kss.)
+ * Improved detection of GL libraries.
+ * Made the password dialog include the date and time.
Changes since 3.16: * New version of `webcollage' -- deals better with
corrupted images, and can use an http proxy.
* New hack, `xsublim' (run it in the background,
#
if test "$have_gl" = yes ; then
- cat >> confdefs.h <<\EOF
-#define HAVE_GL 1
-EOF
-
-
# We need to know whether it's MesaGL so that we know which libraries
# to link against.
#
echo $ac_n "checking whether GL is really MesaGL""... $ac_c" 1>&6
-echo "configure:7035: checking whether GL is really MesaGL" >&5
+echo "configure:7030: checking whether GL is really MesaGL" >&5
if eval "test \"`echo '$''{'ac_cv_have_mesa_gl'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
cat > conftest.$ac_ext <<EOF
-#line 7047 "configure"
+#line 7042 "configure"
#include "confdefs.h"
#include <GL/glx.h>
EOF
echo "$ac_t""$ac_cv_have_mesa_gl" 1>&6
ac_have_mesa_gl=$ac_cv_have_mesa_gl
- if test "$ac_have_mesa_gl" = no ; then
- gl_lib_1="GL"
- GL_LIBS="-lGL -lGLU"
+
+ # If we have Mesa headers, check to see if we can link against -lMesaGL.
+ # If we don't have Mesa headers, or we don't have -lMesaGL, try -lGL.
+ # Else, warn that GL is busted. (We have the headers, but no libs.)
+ #
+ gl_lib_1=""
+ GL_LIBS=""
+
+ if test "$ac_have_mesa_gl" = yes ; then
+
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ ac_save_LDFLAGS="$LDFLAGS"
+# ac_save_LIBS="$LIBS"
+
+ if test \! -z "$includedir" ; then
+ CPPFLAGS="$CPPFLAGS -I$includedir"
+ fi
+ # note: $X_CFLAGS includes $x_includes
+ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+ if test \! -z "$libdir" ; then
+ LDFLAGS="$LDFLAGS -L$libdir"
+ fi
+ # note: $X_LIBS includes $x_libraries
+ LDFLAGS="$LDFLAGS $X_LIBS"
+
+ echo $ac_n "checking for glXCreateContext in -lMesaGL""... $ac_c" 1>&6
+echo "configure:7087: checking for glXCreateContext in -lMesaGL" >&5
+ac_lib_var=`echo MesaGL'_'glXCreateContext | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lMesaGL -lMesaGLU -lX11 -lXext -lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7095 "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 glXCreateContext();
+
+int main() {
+glXCreateContext()
+; return 0; }
+EOF
+if { (eval echo configure:7106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ gl_lib_1="MesaGL"
+ GL_LIBS="-lMesaGL -lMesaGLU"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LDFLAGS="$ac_save_LDFLAGS"
+# LIBS="$ac_save_LIBS"
+
+ fi
+
+ if test "$gl_lib_1" = "" ; then
+
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ ac_save_LDFLAGS="$LDFLAGS"
+# ac_save_LIBS="$LIBS"
+
+ if test \! -z "$includedir" ; then
+ CPPFLAGS="$CPPFLAGS -I$includedir"
+ fi
+ # note: $X_CFLAGS includes $x_includes
+ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+ if test \! -z "$libdir" ; then
+ LDFLAGS="$LDFLAGS -L$libdir"
+ fi
+ # note: $X_LIBS includes $x_libraries
+ LDFLAGS="$LDFLAGS $X_LIBS"
+
+ echo $ac_n "checking for glXCreateContext in -lGL""... $ac_c" 1>&6
+echo "configure:7152: checking for glXCreateContext in -lGL" >&5
+ac_lib_var=`echo GL'_'glXCreateContext | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lGL -lGLU -lX11 -lXext -lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7160 "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 glXCreateContext();
+
+int main() {
+glXCreateContext()
+; return 0; }
+EOF
+if { (eval echo configure:7171: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ gl_lib_1="GL"
+ GL_LIBS="-lGL -lGLU"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LDFLAGS="$ac_save_LDFLAGS"
+# LIBS="$ac_save_LIBS"
+
+ fi
+
+ if test "$gl_lib_1" = "" ; then
+ # we have headers, but no libs -- bail.
+ have_gl=no
+ ac_have_mesa_gl=no
else
+ # linking works -- we can build the GL hacks.
cat >> confdefs.h <<\EOF
+#define HAVE_GL 1
+EOF
+
+ if test "$ac_have_mesa_gl" = yes ; then
+ cat >> confdefs.h <<\EOF
#define HAVE_MESA_GL 1
EOF
- gl_lib_1="MesaGL"
- GL_LIBS="-lMesaGL -lMesaGLU"
+ fi
fi
+ fi
+ # Now that we know we have GL headers and libs, do some more GL testing.
+ #
+
+ if test "$have_gl" = yes ; then
# If it's MesaGL, we'd like to issue a warning if the version number
# is less than or equal to 2.6, because that version had a security bug.
#
if test "$ac_have_mesa_gl" = yes; then
echo $ac_n "checking MesaGL version number""... $ac_c" 1>&6
-echo "configure:7084: checking MesaGL version number" >&5
+echo "configure:7228: checking MesaGL version number" >&5
if eval "test \"`echo '$''{'ac_cv_mesagl_version_string'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7089 "configure"
+#line 7233 "configure"
#include "confdefs.h"
#include <GL/gl.h>
configure: MESA_MAJOR_VERSION MESA_MINOR_VERSION
if test "$ac_have_mesa_gl" = yes; then
echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:7142: checking for pthread_create in -lpthread" >&5
+echo "configure:7286: checking for pthread_create in -lpthread" >&5
ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lpthread $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7150 "configure"
+#line 7294 "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
pthread_create()
; return 0; }
EOF
-if { (eval echo configure:7161: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7305: \"$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
LDFLAGS="$LDFLAGS $X_LIBS"
echo $ac_n "checking for gl_get_thread_context in -l$gl_lib_1""... $ac_c" 1>&6
-echo "configure:7200: checking for gl_get_thread_context in -l$gl_lib_1" >&5
+echo "configure:7344: checking for gl_get_thread_context in -l$gl_lib_1" >&5
ac_lib_var=`echo $gl_lib_1'_'gl_get_thread_context | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-l$gl_lib_1 $GL_LIBS -lpthread -lX11 -lXext -lm $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7208 "configure"
+#line 7352 "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
gl_get_thread_context()
; return 0; }
EOF
-if { (eval echo configure:7219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7363: \"$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
LDFLAGS="$LDFLAGS $X_LIBS"
echo $ac_n "checking for glBindTexture in -l$gl_lib_1""... $ac_c" 1>&6
-echo "configure:7271: checking for glBindTexture in -l$gl_lib_1" >&5
+echo "configure:7415: checking for glBindTexture in -l$gl_lib_1" >&5
ac_lib_var=`echo $gl_lib_1'_'glBindTexture | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-l$gl_lib_1 $GL_LIBS -lX11 -lXext -lm $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7279 "configure"
+#line 7423 "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
glBindTexture()
; return 0; }
EOF
-if { (eval echo configure:7290: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7434: \"$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
# See comments in utils/visual-gl.c for why this is sometimes necessary.
#
echo $ac_n "checking whether drastic GL measures must be taken""... $ac_c" 1>&6
-echo "configure:7324: checking whether drastic GL measures must be taken" >&5
+echo "configure:7468: checking whether drastic GL measures must be taken" >&5
case "$host" in
*-sgi*)
echo "$ac_t""yes -- hello, SGI." 1>&6
/*)
echo $ac_n "checking for XPM headers""... $ac_c" 1>&6
-echo "configure:7376: checking for XPM headers" >&5
+echo "configure:7520: checking for XPM headers" >&5
d=$with_xpm/include
if test -d $d; then
X_CFLAGS="-I$d $X_CFLAGS"
fi
echo $ac_n "checking for XPM libs""... $ac_c" 1>&6
-echo "configure:7386: checking for XPM libs" >&5
+echo "configure:7530: checking for XPM libs" >&5
d=$with_xpm/lib
if test -d $d; then
X_LIBS="-L$d $X_LIBS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
ac_safe=`echo "X11/xpm.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for X11/xpm.h""... $ac_c" 1>&6
-echo "configure:7419: checking for X11/xpm.h" >&5
+echo "configure:7563: 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 7424 "configure"
+#line 7568 "configure"
#include "confdefs.h"
#include <X11/xpm.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7429: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7573: \"$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*
/*)
echo $ac_n "checking for XSHM headers""... $ac_c" 1>&6
-echo "configure:7495: checking for XSHM headers" >&5
+echo "configure:7639: checking for XSHM headers" >&5
d=$with_xshm/include
if test -d $d; then
X_CFLAGS="-I$d $X_CFLAGS"
fi
echo $ac_n "checking for XSHM libs""... $ac_c" 1>&6
-echo "configure:7505: checking for XSHM libs" >&5
+echo "configure:7649: checking for XSHM libs" >&5
d=$with_xshm/lib
if test -d $d; then
X_LIBS="-L$d $X_LIBS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
ac_safe=`echo "X11/extensions/XShm.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for X11/extensions/XShm.h""... $ac_c" 1>&6
-echo "configure:7540: checking for X11/extensions/XShm.h" >&5
+echo "configure:7684: 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 7545 "configure"
+#line 7689 "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:7550: \"$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*
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
ac_safe=`echo "sys/ipc.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for sys/ipc.h""... $ac_c" 1>&6
-echo "configure:7584: checking for sys/ipc.h" >&5
+echo "configure:7728: 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 7589 "configure"
+#line 7733 "configure"
#include "confdefs.h"
#include <sys/ipc.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7594: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7738: \"$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*
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
ac_safe=`echo "sys/shm.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for sys/shm.h""... $ac_c" 1>&6
-echo "configure:7629: checking for sys/shm.h" >&5
+echo "configure:7773: 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 7634 "configure"
+#line 7778 "configure"
#include "confdefs.h"
#include <sys/shm.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7639: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7783: \"$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*
LDFLAGS="$LDFLAGS $X_LIBS"
echo $ac_n "checking for XShmQueryExtension in -lXextSam""... $ac_c" 1>&6
-echo "configure:7690: checking for XShmQueryExtension in -lXextSam" >&5
+echo "configure:7834: 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
ac_save_LIBS="$LIBS"
LIBS="-lXextSam -lX11 -lXext -lm $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7698 "configure"
+#line 7842 "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
XShmQueryExtension()
; return 0; }
EOF
-if { (eval echo configure:7709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7853: \"$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 $ac_n "checking for DOUBLE-BUFFER headers""... $ac_c" 1>&6
-echo "configure:7775: checking for DOUBLE-BUFFER headers" >&5
+echo "configure:7919: checking for DOUBLE-BUFFER headers" >&5
d=$with_xdbe/include
if test -d $d; then
X_CFLAGS="-I$d $X_CFLAGS"
fi
echo $ac_n "checking for DOUBLE-BUFFER libs""... $ac_c" 1>&6
-echo "configure:7785: checking for DOUBLE-BUFFER libs" >&5
+echo "configure:7929: checking for DOUBLE-BUFFER libs" >&5
d=$with_xdbe/lib
if test -d $d; then
X_LIBS="-L$d $X_LIBS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
ac_safe=`echo "X11/extensions/Xdbe.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for X11/extensions/Xdbe.h""... $ac_c" 1>&6
-echo "configure:7819: checking for X11/extensions/Xdbe.h" >&5
+echo "configure:7963: 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 7824 "configure"
+#line 7968 "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:7829: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7973: \"$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*
/*)
echo $ac_n "checking for XReadDisplay headers""... $ac_c" 1>&6
-echo "configure:7892: checking for XReadDisplay headers" >&5
+echo "configure:8036: checking for XReadDisplay headers" >&5
d=$with_readdisplay/include
if test -d $d; then
X_CFLAGS="-I$d $X_CFLAGS"
fi
echo $ac_n "checking for XReadDisplay libs""... $ac_c" 1>&6
-echo "configure:7902: checking for XReadDisplay libs" >&5
+echo "configure:8046: checking for XReadDisplay libs" >&5
d=$with_readdisplay/lib
if test -d $d; then
X_LIBS="-L$d $X_LIBS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
ac_safe=`echo "X11/extensions/readdisplay.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for X11/extensions/readdisplay.h""... $ac_c" 1>&6
-echo "configure:7935: checking for X11/extensions/readdisplay.h" >&5
+echo "configure:8079: 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 7940 "configure"
+#line 8084 "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:7945: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8089: \"$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*
/*)
echo $ac_n "checking for Iris Video headers""... $ac_c" 1>&6
-echo "configure:8000: checking for Iris Video headers" >&5
+echo "configure:8144: checking for Iris Video headers" >&5
d=$with_sgivideo/include
if test -d $d; then
X_CFLAGS="-I$d $X_CFLAGS"
fi
echo $ac_n "checking for Iris Video libs""... $ac_c" 1>&6
-echo "configure:8010: checking for Iris Video libs" >&5
+echo "configure:8154: checking for Iris Video libs" >&5
d=$with_sgivideo/lib
if test -d $d; then
X_LIBS="-L$d $X_LIBS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
ac_safe=`echo "dmedia/vl.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for dmedia/vl.h""... $ac_c" 1>&6
-echo "configure:8043: checking for dmedia/vl.h" >&5
+echo "configure:8187: 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 8048 "configure"
+#line 8192 "configure"
#include "confdefs.h"
#include <dmedia/vl.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8197: \"$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*
if test "$have_sgivideo" = yes; then
have_sgivideo=no
echo $ac_n "checking for vlOpenVideo in -lvl""... $ac_c" 1>&6
-echo "configure:8078: checking for vlOpenVideo in -lvl" >&5
+echo "configure:8222: 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
ac_save_LIBS="$LIBS"
LIBS="-lvl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8086 "configure"
+#line 8230 "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
vlOpenVideo()
; return 0; }
EOF
-if { (eval echo configure:8097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8241: \"$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
case "$with_zippy_req" in
/*)
echo $ac_n "checking for $with_zippy_req""... $ac_c" 1>&6
-echo "configure:8168: checking for $with_zippy_req" >&5
+echo "configure:8312: checking for $with_zippy_req" >&5
if test -x "$with_zippy_req" ; then
echo "$ac_t""yes" 1>&6
else
# Extract the first word of "$with_zippy_req", so it can be a program name with args.
set dummy $with_zippy_req; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8182: checking for $ac_word" >&5
+echo "configure:8326: 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
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8232: checking for $ac_word" >&5
+echo "configure:8376: 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
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8266: checking for $ac_word" >&5
+echo "configure:8410: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_xemacs_exe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$emacs_exe" ; then
echo $ac_n "checking for emacs yow""... $ac_c" 1>&6
-echo "configure:8301: checking for emacs yow" >&5
+echo "configure:8445: checking for emacs yow" >&5
#
# get emacs to tell us where the libexec directory is.
#
if test -z "$ac_cv_zippy_program" ; then
echo $ac_n "checking for xemacs yow""... $ac_c" 1>&6
-echo "configure:8323: checking for xemacs yow" >&5
+echo "configure:8467: checking for xemacs yow" >&5
if test -n "$xemacs_exe" ; then
#
# get xemacs to tell us where the libexec directory is.
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8382: checking for $ac_word" >&5
+echo "configure:8526: 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
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8418: checking for $ac_word" >&5
+echo "configure:8562: 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
echo ' "xscreensaver-demo", and "xscreensaver-command" executables'
echo " will be installed in ${bindir}."
echo ""
- echo " The various graphics demos (90+ different executables) will"
+ echo " The various graphics demos (100+ different executables) will"
echo " also be installed in ${HACKDIR}."
echo ""
echo " If you would prefer the demos to be installed elsewhere"
#
if test "$have_gl" = yes ; then
- AC_DEFINE(HAVE_GL)
-
# We need to know whether it's MesaGL so that we know which libraries
# to link against.
#
])
ac_have_mesa_gl=$ac_cv_have_mesa_gl
- if test "$ac_have_mesa_gl" = no ; then
- gl_lib_1="GL"
- GL_LIBS="-lGL -lGLU"
+
+ # If we have Mesa headers, check to see if we can link against -lMesaGL.
+ # If we don't have Mesa headers, or we don't have -lMesaGL, try -lGL.
+ # Else, warn that GL is busted. (We have the headers, but no libs.)
+ #
+ gl_lib_1=""
+ GL_LIBS=""
+
+ if test "$ac_have_mesa_gl" = yes ; then
+ AC_CHECK_X_LIB(MesaGL, glXCreateContext,
+ [gl_lib_1="MesaGL"
+ GL_LIBS="-lMesaGL -lMesaGLU"],
+ [], -lMesaGLU -lX11 -lXext -lm)
+ fi
+
+ if test "$gl_lib_1" = "" ; then
+ AC_CHECK_X_LIB(GL, glXCreateContext,
+ [gl_lib_1="GL"
+ GL_LIBS="-lGL -lGLU"],
+ [], -lGLU -lX11 -lXext -lm)
+ fi
+
+ if test "$gl_lib_1" = "" ; then
+ # we have headers, but no libs -- bail.
+ have_gl=no
+ ac_have_mesa_gl=no
else
- AC_DEFINE(HAVE_MESA_GL)
- gl_lib_1="MesaGL"
- GL_LIBS="-lMesaGL -lMesaGLU"
+ # linking works -- we can build the GL hacks.
+ AC_DEFINE(HAVE_GL)
+ if test "$ac_have_mesa_gl" = yes ; then
+ AC_DEFINE(HAVE_MESA_GL)
+ fi
fi
+ fi
+ # Now that we know we have GL headers and libs, do some more GL testing.
+ #
+
+ if test "$have_gl" = yes ; then
# If it's MesaGL, we'd like to issue a warning if the version number
# is less than or equal to 2.6, because that version had a security bug.
#
echo ' "xscreensaver-demo", and "xscreensaver-command" executables'
echo " will be installed in ${bindir}."
echo ""
- echo " The various graphics demos (90+ different executables) will"
+ echo " The various graphics demos (100+ different executables) will"
echo " also be installed in ${HACKDIR}."
echo ""
echo " If you would prefer the demos to be installed elsewhere"
MEN = xscreensaver.man xscreensaver-demo.man \
xscreensaver-command.man
EXTRAS = README Makefile.in XScreenSaver.ad.in xscreensaver.pam \
- .gdbinit
+ xscreensaver.kss .gdbinit
VMSFILES = compile_axp.com compile_decc.com link_axp.com link_decc.com \
vms-getpwnam.c vms-pwd.h vms-hpwd.c vms-validate.c \
vms_axp.opt vms_axp_12.opt vms_decc.opt vms_decc_12.opt
default: $(EXES)
all: $(EXES) $(EXES2)
-install: install-program install-ad install-man @INSTALL_PAM@
-uninstall: uninstall-program uninstall-ad uninstall-man
+install: install-program install-ad install-kde install-man @INSTALL_PAM@
+uninstall: uninstall-program uninstall-ad uninstall-kde uninstall-man
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
fi ; \
fi
+install-kde:
+ @src="$(srcdir)/xscreensaver.kss" ; \
+ if [ "$$KDEDIR" != "" ]; then \
+ dir="$$KDEDIR/bin" ; \
+ dest="$$dir/xscreensaver.kss" ; \
+ echo $(INSTALL_PROGRAM) $$src $$dest ; \
+ if $(INSTALL_PROGRAM) $$src $$dest ; then \
+ true ; \
+ else \
+ e=echo ; \
+ $$e "" ;\
+ $$e " ####################################################################";\
+ $$e " Warning: unable to install $$dest" ;\
+ if [ ! -d $$KDEDIR ]; then \
+ $$e " $$KDEDIR (\$$KDEDIR) does not exist." ;\
+ elif [ ! -d $$KDEDIR/bin ]; then \
+ $$e " $$KDEDIR/bin (\$$KDEDIR/bin) does not exist." ;\
+ elif [ -f $$dest ]; then \
+ $$e " That file exists, and is unwritable." ;\
+ else \
+ $$e " The directory is unwritable." ;\
+ fi ;\
+ $$e " ####################################################################";\
+ $$e "" ;\
+ exit 1 ; \
+ fi ; \
+ fi
+
+uninstall-kde:
+ @if [ "$$KDEDIR" != "" ]; then \
+ dest="$$KDEDIR/bin/xscreensaver.kss" ; \
+ echo rm -f $$dest ; \
+ rm -f $$dest ; \
+ fi
clean:
-rm -f *.o a.out core $(EXES) $(EXES2) XScreenSaver_ad.h
! a screen saver and locker for the X window system
! by Jamie Zawinski
!
-! version 3.17
-! 15-Jul-99
+! version 3.18
+! 13-Oct-99
!
! See "man xscreensaver" for more info. The latest version is always
! available at http://www.jwz.org/xscreensaver/
*loadURL: netscape -remote 'openURL(%s)' || netscape '%s'
+! The format used for printing the date and time in the password dialog box
+! (see the strftime(3) manual page for details.)
+*dateFormat: %d-%b-%y (%a); %I:%M %p
+! To show the time only:
+! *dateFormat: %I:%M %p
+! For 24 hour time:
+! *dateFormat: %H:%M
+
+
! Turning on "installColormap" interacts erratically with twm and tvtwm,
! but seems to work fine with mwm and olwm. Try it and see. If your
! screen turns some color other than black, the window manager is buggy,
-minlifespan 1 -maxlifespan 1 -instantdeathchan 0 \
-minorchan 0 -anychan 0.3 \n\
shadebobs -root \n\
+ ccurve -root \n\
+ blaster -root \n\
+ bumps -root \n\
default-n: webcollage -root \n\
- default-n: webcollage -root -filter 'vidwhacker -stdin -stdout' \n\
- default-n: vidwhacker -root \n\
! default-n: xv -root -rmode 5 -random -viewonly -wloop \
! -wait 30 $HOME/bitmaps/*.jpg \n\
!
+! or, if you prefer "xli" to "xv", like this: (but note that xli's "-delay"
+! option doesn't work in conjunction with "-onroot", so you need to add a
+! line for each image individually... "xv" is better in this respect.)
+!
+! default-n: xli -quiet -onroot -center -border black \
+! $HOME/bitmaps/pic1.jpg \n\
+! default-n: xli -quiet -onroot -center -border black \
+! $HOME/bitmaps/pic2.jpg \n\
+! default-n: xli -quiet -onroot -center -border black \
+! $HOME/bitmaps/pic3.jpg \n\
+!
! Note that we've used "default-n" as the visual name, rather than just
! "default": this means "default visual, no install", that is, it's like
! specifying the command-line arguments "-visual default -no-install".
-! This is necessary because, when XV is running in "-root" mode, it always
-! assumes that the default visual and colormap are being used, rather than
-! examining the window it is drawing on to see what visual and colormap it
-! has. If we didn't force the default visual to be used, xv would get an
+! This is necessary because, when XV or XLI arerunning in "-root" mode, they
+! always assume that the default visual and colormap are being used, rather
+! than examining the window it is drawing on to see what visual and colormap
+! it has. If we didn't force the default visual to be used, we would get an
! X error. If we didn't force the default colormap to be installed, the
! colors would be all wrong. "default-i" may also be used as a visual name
! (meaning, "-visual default -install") but you probably won't ever need
*Dialog.bodyFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1
*Dialog.labelFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1
*Dialog.buttonFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1
+*Dialog.dateFont: *-courier-medium-r-*-*-*-80-*-*-*-iso8859-1
*Dialog.foreground: #000000
*Dialog.background: #BFBFBF
*Dialog.Button.foreground: #000000
"*prefsCommand: xscreensaver-demo -prefs",
"*helpURL: http://www.jwz.org/xscreensaver/man.html",
"*loadURL: netscape -remote 'openURL(%s)' || netscape '%s'",
+"*dateFormat: %d-%b-%y (%a); %I:%M %p",
"*installColormap: True",
"*programs: qix -root -solid -delay 0 -segments 100 \\n\
qix -root -count 4 -solid -transparent \\n\
-minlifespan 1 -maxlifespan 1 -instantdeathchan 0 \
-minorchan 0 -anychan 0.3 \\n\
shadebobs -root \\n\
+ ccurve -root \\n\
+ blaster -root \\n\
+ bumps -root \\n\
default-n: webcollage -root \\n\
- default-n: webcollage -root -filter 'vidwhacker -stdin -stdout' \\n\
- default-n: vidwhacker -root \\n\
"*Dialog.bodyFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1",
"*Dialog.labelFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1",
"*Dialog.buttonFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1",
+"*Dialog.dateFont: *-courier-medium-r-*-*-*-80-*-*-*-iso8859-1",
"*Dialog.foreground: #000000",
"*Dialog.background: #BFBFBF",
"*Dialog.Button.foreground: #000000",
#ifndef NO_LOCKING /* whole file */
#include <X11/Intrinsic.h>
+#include <X11/Xos.h> /* for time() */
#include "xscreensaver.h"
#include "resources.h"
char *body_label;
char *user_label;
char *passwd_label;
+ char *date_label;
char *user_string;
char *passwd_string;
XFontStruct *body_font;
XFontStruct *label_font;
XFontStruct *passwd_font;
+ XFontStruct *date_font;
Pixel foreground;
Pixel background;
"Dialog.Label.Label");
pw->passwd_label = get_string_resource ("passwd.passwd.label",
"Dialog.Label.Label");
+ pw->date_label = get_string_resource ("dateFormat", "DateFormat");
if (!pw->heading_label)
pw->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
pw->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
if (!pw->user_label) pw->user_label = strdup("ERROR");
if (!pw->passwd_label) pw->passwd_label = strdup("ERROR");
+ if (!pw->date_label) pw->date_label = strdup("ERROR");
/* Put the version number in the label. */
{
if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed");
if (f) free (f);
+ f = get_string_resource("passwd.dateFont", "Dialog.Font");
+ pw->date_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
+ if (!pw->date_font) pw->date_font = XLoadQueryFont (si->dpy, "fixed");
+ if (f) free (f);
+
pw->foreground = get_pixel_resource ("passwd.foreground",
"Dialog.Foreground",
si->dpy, cmap);
pw->body_font->ascent + pw->body_font->descent +
(2 * MAX ((pw->label_font->ascent + pw->label_font->descent),
(pw->passwd_font->ascent + pw->passwd_font->descent +
- (pw->shadow_width * 4)))));
+ (pw->shadow_width * 4)))) +
+ pw->date_font->ascent + pw->date_font->descent
+ );
spacing = ((pw->height - (2 * pw->shadow_width) -
pw->internal_border - height)) / 8;
if (spacing < 0) spacing = 0;
pw->shadow_width,
pw->shadow_bottom, pw->shadow_top);
+
+ /* The date, below the text fields
+ */
+ {
+ char buf[100];
+ time_t now = time ((time_t *) 0);
+ struct tm *tm = localtime (&now);
+ memset (buf, 0, sizeof(buf));
+ strftime (buf, sizeof(buf)-1, pw->date_label, tm);
+
+ XSetFont (si->dpy, gc1, pw->date_font->fid);
+ y1 += pw->shadow_width;
+ y1 += (spacing + tb_height);
+ y1 += spacing/2;
+ sw = string_width (pw->date_font, buf);
+ x2 = x1 + x2 - sw;
+ XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, buf, strlen(buf));
+ }
+
+
/* the logo
*/
XSetForeground (si->dpy, gc1, pw->logo_foreground);
#ifdef HAVE_XF86VMODE
saver_info *si = ssi->global;
int screen_no = screen_number (ssi->screen);
- int event, error;
+ int op, event, error;
int dot;
XF86VidModeModeLine ml;
int x, y;
- if (XF86VidModeQueryExtension (si->dpy, &event, &error) &&
+ /* Check for Xinerama first, because the VidModeExtension is broken
+ when Xinerama is present. Wheee!
+ */
+
+ if (!XQueryExtension (si->dpy, "XINERAMA", &op, &event, &error) &&
+ XF86VidModeQueryExtension (si->dpy, &event, &error) &&
XF86VidModeGetModeLine (si->dpy, screen_no, &dot, &ml) &&
XF86VidModeGetViewPort (si->dpy, screen_no, &x, &y))
{
/* There is no viewport -- the screen does not scroll. */
return;
+
+ /* Apparently some versions of XFree86 return nonsense here!
+ I've had reports of 1024x768 viewports at -1936862040, -1953705044.
+ So, sanity-check the values and give up if they are out of range.
+ */
+ if (*x_ret < 0 || *x_ret >= w ||
+ *y_ret < 0 || *y_ret >= h ||
+ *w_ret <= 0 || *w_ret > w ||
+ *h_ret <= 0 || *h_ret > h)
+ {
+ static int warned_once = 0;
+ if (!warned_once)
+ {
+ fprintf (stderr, "\n"
+ "%s: X SERVER BUG: %dx%d viewport at %d,%d is impossible.\n"
+ "%s: The XVidMode server extension is returning nonsense.\n"
+ "%s: Please report this bug to your X server vendor.\n\n",
+ blurb(), *w_ret, *h_ret, *x_ret, *y_ret,
+ blurb(), blurb());
+ warned_once = 1;
+ }
+ *x_ret = 0;
+ *y_ret = 0;
+ *w_ret = w;
+ *h_ret = h;
+ return;
+ }
+
+
sprintf (msg, "%s: vp is %dx%d+%d+%d",
blurb(), *w_ret, *h_ret, *x_ret, *y_ret);
.if n .sp 1
.if t .sp .5
..
-.TH XScreenSaver 1 "15-Jul-99 (3.17)" "X Version 11"
+.TH XScreenSaver 1 "13-Oct-99 (3.18)" "X Version 11"
.SH NAME
xscreensaver-command - control a running xscreensaver process
.SH SYNOPSIS
.if n .sp 1
.if t .sp .5
..
-.TH XScreenSaver 1 "15-Jul-99 (3.17)" "X Version 11"
+.TH XScreenSaver 1 "13-Oct-99 (3.18)" "X Version 11"
.SH NAME
xscreensaver-demo - interactively control the background xscreensaver daemon
.SH SYNOPSIS
{ "DOUBLE-BUFFER", "Double-Buffering" },
{ "DPMS", "Power Management" },
{ "GLX", "GLX" },
- { "XFree86-VidModeExtension", "XF86 Video-Mode" }
+ { "XFree86-VidModeExtension", "XF86 Video-Mode" },
+ { "XINERAMA", "Xinerama" }
};
fprintf (stderr, "%s: running on display \"%s\"\n", blurb(),
extern Bool lock_priv_init (int argc, char **argv, Bool verbose_p);
extern Bool lock_init (int argc, char **argv, Bool verbose_p);
extern Bool passwd_valid_p (const char *typed_passwd, Bool verbose_p);
-extern void set_locked_p (saver_info *si, Bool locked_p);
#endif /* NO_LOCKING */
+extern void set_locked_p (saver_info *si, Bool locked_p);
extern int move_mouse_grab (saver_info *si, Window to, Cursor cursor);
--- /dev/null
+#!/bin/bash -
+
+# script - "xscreensaver.kss"
+#
+# Author: Shane Smit <shane_smit@calderasystems.com>
+#
+# Modification History:
+# [08/23/1999] - Shane Smit: Creation
+#
+# Description:
+# This script file enables users to use XScreenSaver via the
+# KDE Display Properties.
+
+# 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.
+
+
+# Locking is turned off by default.
+lockmode="-no-lock-mode"
+
+while [ -n "$1" ]; do
+ case "$1" in
+
+ -desc)
+ # This is the name in the list box.
+ echo "XScreenSaver"
+ exit
+ ;;
+
+ -preview)
+ # This simply runs xroger in the preview window. For this to be "real",
+ # it needs to run xscreensaver with a -window-id parameter for each hack.
+ # There are two ways to do this:
+ # 1) Hack xscreensaver to allow global parameters.
+ # 2) Hack xscreensaver to accept alternate setup files, and create one on
+ # the fly here.
+ shift
+ /usr/X11R6/lib/xscreensaver/xroger -delay 1 -window-id $1 & # Start new preview
+ echo "$!" > $HOME/.kss-preview$1.pid.`hostname` # Write PID
+ wait $! # Wait for it to get killed
+ exit
+ ;;
+
+ -setup)
+ /usr/X11R6/bin/xscreensaver -no-splash & # daemon must be started
+ /usr/X11R6/bin/xscreensaver-demo # or the setup will produce
+ kill $! # a warning.
+ exit
+ ;;
+
+ -test)
+ # I was unable to grep stdout because xscreensaver nabs it. But I was able
+ # to output it to a file, and grep the file.
+ TEMP_FILE=/tmp/xsc.$RANDOM
+ /usr/X11R6/bin/xscreensaver -no-splash -verbose -no-capture-stderr 2> $TEMP_FILE &
+ /usr/X11R6/bin/xscreensaver-command -activate
+ while true; do
+ ExitNow=$(grep -E -c unblanking\|already $TEMP_FILE)
+ if [ $ExitNow != 0 ]; then
+ kill $!
+ rm $TEMP_FILE
+ exit
+ fi
+ sleep 1
+ done
+ exit # It should never get this far.
+ ;;
+
+# -corners)
+# echo "Not yet supported"
+# ;;
+ -delay)
+ shift
+ timeout="-timeout $1"
+ ;;
+ -install)
+ Install="TRUE"
+ ;;
+ -lock)
+ if [ ! -f "/etc/shadow" ]; then
+ lockmode="-lock-mode"
+ fi
+ ;;
+# -allow-root)
+# echo "Not yet supported"
+# ;;
+ -nice)
+ shift
+ Nice="-nice $1"
+ ;;
+# -inroot)
+# echo "Not yet supported"
+# ;;
+ *)
+ echo "Unknown parameter: $1"
+ ;;
+ esac
+ shift
+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
+ 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
+ trap "kill $!" SIGKILL
+
+ if [ -f "/etc/shadow" ]; then
+ # xscreensaver is run as the user, which has no access to the /etc/shadow file. Other
+ # .kss screensavers use kcheckpass, which would have to be hacked into xscreensaver to
+ # work correctly. This just activates the screensaver with no password lock.
+ trap "/usr/X11R6/bin/xscreensaver-command -activate" SIGUSR1
+ else
+ # xscreensaver can be locked, because it can read the /etc/passwd file.
+ trap "/usr/X11R6/bin/xscreensaver-command -lock" SIGUSR1
+ fi
+
+ wait $! # Do not exit, just wait for signals.
+
+else
+ echo "Usage: ./xscreensaver.kss -install|-setup|-test|-desc [-delay num] [-lock] [-nice num]"
+# echo " -corners xxxx Placing cursor in corner performs action:"
+# echo " x = i no action (ignore)"
+# echo " x = s save screen"
+# echo " x = l lock screen"
+# echo " order: top-left, top-right, bottom-left, bottom-right"
+ echo " -delay num Amount of idle time before screen saver starts (default 10min)"
+ echo " -desc Print the screen saver's description to stdout"
+ echo " -install Install screen saver"
+ echo " -lock Require password to stop screen saver"
+# echo " -allow-root Accept root password to unlock"
+ echo " -nice num Run with specified nice value"
+ echo " -preview wid Run in the specified XWindow"
+# echo " -inroot Run in the root window"
+ echo " -setup Setup screen saver"
+ echo " -test Invoke the screen saver immediately"
+fi
+
+# End of script - "xscreensaver.kss"
.if n .sp 1
.if t .sp .5
..
-.TH XScreenSaver 1 "15-Jul-99 (3.17)" "X Version 11"
+.TH XScreenSaver 1 "13-Oct-99 (3.18)" "X Version 11"
.SH NAME
xscreensaver - graphics hack and screen locker, launched when the user is idle
.SH SYNOPSIS
truchet.c bsod.c crystal.c discrete.c distort.c kumppa.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
+ phosphor.c xmatrix.c petri.c shadebobs.c xsublim.c ccurve.c \
+ blaster.c bumps.c
SCRIPTS = vidwhacker webcollage
OBJS = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
truchet.o bsod.o crystal.o discrete.o distort.o kumppa.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
+ phosphor.o xmatrix.o petri.o shadebobs.o xsublim.o ccurve.o \
+ blaster.o bumps.o
EXES = attraction blitspin bouboule braid bubbles decayscreen deco \
drift flag flame forest vines galaxy grav greynetic halo \
interference truchet bsod crystal discrete distort kumppa \
sonar demon loop t3d penetrate deluxe compass squiral \
xflame wander spotlight critical phosphor xmatrix petri \
- shadebobs xsublim
+ shadebobs xsublim ccurve blaster bumps
HACK_OBJS_1 = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
$(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
XDBE_OBJS = $(UTILS_BIN)/xdbe.o
GRAB_LIBS = $(SGI_VIDEO_LIBS)
-HDRS = bubbles.h screenhack.h xlockmore.h xlockmoreI.h automata.h
+HDRS = bubbles.h screenhack.h xlockmore.h xlockmoreI.h automata.h \
+ bumps.h
MEN = attraction.man blitspin.man bouboule.man braid.man \
bubbles.man decayscreen.man deco.man drift.man flag.man \
flame.man forest.man vines.man galaxy.man grav.man \
xroger.man goop.man starfish.man munch.man rd-bomb.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
+ vidwhacker.man webcollage.man xsublim.man
STAR = *
EXTRAS = README Makefile.in xlock_23.h .gdbinit \
images/$(STAR).xbm \
shadebobs: shadebobs.o $(HACK_OBJS) $(COL) $(SPL)
$(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(SPL) $(HACK_LIBS)
+ccurve: ccurve.o $(HACK_OBJS) $(COL) $(SPL)
+ $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS)
+
+blaster: blaster.o $(HACK_OBJS)
+ $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(HACK_LIBS)
+
+bumps: bumps.o $(HACK_OBJS) $(GRAB)
+ $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(HACK_LIBS) $(GRAB_LIBS)
+
# The rules for those hacks which follow the `xlockmore' API.
#
flame.o: $(UTILS_SRC)/colors.h
flame.o: $(UTILS_SRC)/grabscreen.h
flame.o: $(UTILS_SRC)/visual.h
-forest.o: $(srcdir)/xlockmore.h
forest.o: ../config.h
+forest.o: $(srcdir)/xlockmore.h
forest.o: $(srcdir)/xlockmoreI.h
forest.o: $(srcdir)/screenhack.h
forest.o: $(UTILS_SRC)/yarandom.h
forest.o: $(UTILS_SRC)/grabscreen.h
forest.o: $(UTILS_SRC)/visual.h
forest.o: $(UTILS_SRC)/xshm.h
-forest.o: $(UTILS_SRC)/erase.h
vines.o: $(srcdir)/xlockmore.h
vines.o: ../config.h
vines.o: $(srcdir)/xlockmoreI.h
shadebobs.o: $(UTILS_SRC)/visual.h
xsublim.o: $(UTILS_SRC)/usleep.h
xsublim.o: $(UTILS_SRC)/resources.h
+ccurve.o: $(srcdir)/screenhack.h
+ccurve.o: ../config.h
+ccurve.o: $(UTILS_SRC)/yarandom.h
+ccurve.o: $(UTILS_SRC)/usleep.h
+ccurve.o: $(UTILS_SRC)/resources.h
+ccurve.o: $(UTILS_SRC)/hsv.h
+ccurve.o: $(UTILS_SRC)/colors.h
+ccurve.o: $(UTILS_SRC)/grabscreen.h
+ccurve.o: $(UTILS_SRC)/visual.h
+ccurve.o: $(UTILS_SRC)/erase.h
+blaster.o: $(srcdir)/screenhack.h
+blaster.o: ../config.h
+blaster.o: $(UTILS_SRC)/yarandom.h
+blaster.o: $(UTILS_SRC)/usleep.h
+blaster.o: $(UTILS_SRC)/resources.h
+blaster.o: $(UTILS_SRC)/hsv.h
+blaster.o: $(UTILS_SRC)/colors.h
+blaster.o: $(UTILS_SRC)/grabscreen.h
+blaster.o: $(UTILS_SRC)/visual.h
+bumps.o: $(srcdir)/bumps.h
+bumps.o: $(srcdir)/screenhack.h
+bumps.o: ../config.h
+bumps.o: $(UTILS_SRC)/yarandom.h
+bumps.o: $(UTILS_SRC)/usleep.h
+bumps.o: $(UTILS_SRC)/resources.h
+bumps.o: $(UTILS_SRC)/hsv.h
+bumps.o: $(UTILS_SRC)/colors.h
+bumps.o: $(UTILS_SRC)/grabscreen.h
+bumps.o: $(UTILS_SRC)/visual.h
--- /dev/null
+/* -*- mode: C; tab-width: 2 -*-
+ * blaster, Copyright (c) 1999 Jonathan H. Lin <jonlin@tesuji.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Robots that move randomly and shoot lasers at each other. If the
+ * mothership is active, it will fly back and forth horizontally,
+ * firing 8 lasers in the 8 cardinal directions. The explosions are
+ * a 20 frame animation. Robots regenerate after the explosion is finished
+ * and all of its lasers have left the screen.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "screenhack.h"
+
+static Display *dpy;
+static Window window;
+static GC r_color0, r_color1, r_color2, r_color3, r_color4, r_color5, l_color0, l_color1;
+static GC s_color;
+static GC black;
+
+static int delay;
+
+static int NUM_ROBOTS=5;
+static int NUM_LASERS=3;
+
+static int MOTHER_SHIP=0;
+static int MOTHER_SHIP_WIDTH=25;
+static int MOTHER_SHIP_HEIGHT=7;
+static int MOTHER_SHIP_LASER=15;
+static int MOTHER_SHIP_PERIOD=150;
+static int MOTHER_SHIP_HITS=10;
+
+static int LINE_MOVE_STYLE=0;
+static int RANDOM_MOVE_STYLE=1;
+static int NUM_MOVE_STYLES=2;
+
+static int EXPLODE_SIZE_1=27;
+static int EXPLODE_SIZE_2=19;
+static int EXPLODE_SIZE_3=7;
+static GC EXPLODE_COLOR_1;
+static GC EXPLODE_COLOR_2;
+
+struct laser_state {
+ int active;
+ int start_x,start_y;
+ int end_x, end_y;
+};
+
+struct robot_state {
+ int alive;
+ int death;
+
+ int move_style;
+ int target;
+
+ int old_x, old_y;
+ int new_x, new_y;
+
+ int radius;
+ GC robot_color;
+ GC laser_color;
+ struct laser_state *lasers;
+};
+
+struct mother_ship_state {
+ int active;
+ int death;
+ int old_x,new_x;
+ int y;
+ GC ship_color;
+ GC laser_color;
+ struct laser_state *lasers;
+};
+
+static XArc *stars;
+static int NUM_STARS;
+static int MOVE_STARS;
+static int MOVE_STARS_X;
+static int MOVE_STARS_Y;
+static int MOVE_STARS_RANDOM;
+
+static struct mother_ship_state *mother;
+
+static struct robot_state *robots;
+
+XWindowAttributes xgwa;
+
+
+
+
+/* creates a new robot. It starts out on one of the edges somewhere and
+ has no initial velocity. A target is randomly picked. */
+static void make_new_robot(int index)
+{
+ int laser_check = 0;
+ int x=0;
+
+ for(x=0;x<NUM_LASERS;x++) {
+ if(robots[index].lasers[x].active) {
+ x=NUM_LASERS;
+ laser_check = 1;
+ }
+ }
+ if(laser_check==0) {
+ robots[index].alive=1;
+
+ robots[index].radius = 7+(random()%7);
+
+ robots[index].move_style = random()%NUM_MOVE_STYLES;
+ if(random()%2==0) {
+ robots[index].new_x=random()%(xgwa.width-robots[index].radius);
+ robots[index].old_x=robots[index].new_x;
+ if(random()%2==0) {
+ robots[index].new_y=0;
+ robots[index].old_y=0;
+ }
+ else {
+ robots[index].new_y=xgwa.height-robots[index].radius;
+ robots[index].old_y = robots[index].new_y;
+ }
+ }
+ else {
+ robots[index].new_y=random()%(xgwa.height-robots[index].radius);
+ robots[index].old_y = robots[index].new_y;
+ if(random()%2) {
+ robots[index].new_x=0;
+ robots[index].old_x=0;
+ }
+ else {
+ robots[index].new_x=xgwa.width-robots[index].radius;
+ robots[index].old_x=robots[index].new_x;
+ }
+ }
+
+ x=random()%6;
+ if(x==0) {
+ robots[index].robot_color = r_color0;
+ }
+ else if(x==1) {
+ robots[index].robot_color = r_color1;
+ }
+ else if(x==2) {
+ robots[index].robot_color = r_color2;
+ }
+ else if(x==3) {
+ robots[index].robot_color = r_color3;
+ }
+ else if(x==4) {
+ robots[index].robot_color = r_color4;
+ }
+ else if(x==5) {
+ robots[index].robot_color = r_color5;
+ }
+
+ if(random()%2==0) {
+ robots[index].laser_color = l_color0;
+ }
+ else {
+ robots[index].laser_color = l_color1;
+ }
+
+ if(NUM_ROBOTS>1) {
+ robots[index].target = random()%NUM_ROBOTS;
+ while(robots[index].target==index) {
+ robots[index].target = random()%NUM_ROBOTS;
+ }
+ }
+ }
+}
+
+/* moves each robot, randomly changing its direction and velocity.
+ At random a laser is shot toward that robot's target. Also at random
+ the target can change. */
+static void move_robots(void)
+{
+ int x=0;
+ int y=0;
+ int dx=0;
+ int dy=0;
+ int target_x = 0;
+ int target_y = 0;
+ double slope = 0;
+
+ for(x=0;x<NUM_ROBOTS;x++) {
+ if(robots[x].alive) {
+ if((robots[x].new_x == robots[x].old_x) && (robots[x].new_y == robots[x].old_y)) {
+ if(robots[x].new_x==0) {
+ robots[x].old_x = -((random()%3)+1);
+ }
+ else {
+ robots[x].old_x = robots[x].old_x + (random()%3)+1;
+ }
+ if(robots[x].new_y==0) {
+ robots[x].old_y = -((random()%3)+1);
+ }
+ else {
+ robots[x].old_y = robots[x].old_y + (random()%3)+1;
+ }
+ }
+ if(robots[x].move_style==LINE_MOVE_STYLE) {
+ dx = robots[x].new_x - robots[x].old_x;
+ dy = robots[x].new_y - robots[x].old_y;
+ if(dx > 3) {
+ dx = 3;
+ }
+ else if(dx < -3) {
+ dx = -3;
+ }
+ if(dy > 3) {
+ dy = 3;
+ }
+ else if(dy < -3) {
+ dy = -3;
+ }
+ robots[x].old_x = robots[x].new_x;
+ robots[x].old_y = robots[x].new_y;
+
+ robots[x].new_x = robots[x].new_x + dx;
+ robots[x].new_y = robots[x].new_y + dy;
+ }
+ else if(robots[x].move_style==RANDOM_MOVE_STYLE) {
+ dx = robots[x].new_x - robots[x].old_x;
+ dy = robots[x].new_y - robots[x].old_y;
+ y=random()%3;
+ if(y==0) {
+ dx = dx - ((random()%7)+1);
+ }
+ else if(y==1){
+ dx = dx + ((random()%7)+1);
+ }
+ else {
+ dx = (-1)*dx;
+ }
+ if(dx > 3) {
+ dx = 3;
+ }
+ else if(dx < -3) {
+ dx = -3;
+ }
+
+ y = random()%3;
+ if(y==0) {
+ dy = dy - ((random()%7)+1);
+ }
+ else if(y==1){
+ dy = dy + ((random()%7)+1);
+ }
+ else {
+ dx = (-1)*dx;
+ }
+ if(dy > 3) {
+ dy = 3;
+ }
+ else if(dy < -3) {
+ dy = -3;
+ }
+ robots[x].old_x = robots[x].new_x;
+ robots[x].old_y = robots[x].new_y;
+
+ robots[x].new_x = robots[x].new_x + dx;
+ robots[x].new_y = robots[x].new_y + dy;
+ }
+
+ /* bounds corrections */
+ if(robots[x].new_x >= xgwa.width-robots[x].radius) {
+ robots[x].new_x = xgwa.width - robots[x].radius;
+ }
+ else if(robots[x].new_x < 0) {
+ robots[x].new_x = 0;
+ }
+ if(robots[x].new_y >= xgwa.height-robots[x].radius) {
+ robots[x].new_y = xgwa.height - robots[x].radius;
+ }
+ else if(robots[x].new_y < 0) {
+ robots[x].new_y = 0;
+ }
+
+ if(random()%10==0) {
+ robots[x].move_style = 1;
+ }
+ else {
+ robots[x].move_style = 0;
+ }
+
+ if(NUM_ROBOTS>1) {
+ if(random()%2==0) {
+ if(random()%200==0) {
+ robots[x].target = random()%NUM_ROBOTS;
+ while(robots[x].target==x) {
+ robots[x].target = random()%NUM_ROBOTS;
+ }
+ for(y=0;y<NUM_LASERS;y++) {
+ if(robots[x].lasers[y].active == 0) {
+ robots[x].lasers[y].active = 1;
+ if(random()%2==0) {
+ if(random()%2==0) {
+ robots[x].lasers[y].start_x = robots[x].new_x+robots[x].radius;
+ robots[x].lasers[y].start_y = robots[x].new_y+robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].lasers[y].start_x+7;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y+7;
+ }
+ else {
+ robots[x].lasers[y].start_x = robots[x].new_x-robots[x].radius;
+ robots[x].lasers[y].start_y = robots[x].new_y+robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].lasers[y].start_x-7;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y+7;
+ }
+ }
+ else {
+ if(random()%2==0) {
+ robots[x].lasers[y].start_x = robots[x].new_x-robots[x].radius;
+ robots[x].lasers[y].start_y = robots[x].new_y-robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].lasers[y].start_x-7;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y-7;
+ }
+ else {
+ robots[x].lasers[y].start_x = robots[x].new_x+robots[x].radius;
+ robots[x].lasers[y].start_y = robots[x].new_y-robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].lasers[y].start_x+7;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y-7;
+ }
+ }
+ y = NUM_LASERS;
+ }
+ }
+ }
+ else {
+ for(y=0;y<NUM_LASERS;y++) {
+ if(robots[x].lasers[y].active==0) {
+ target_x = robots[robots[x].target].new_x;
+ target_y = robots[robots[x].target].new_y;
+ if((target_x-robots[x].new_x)!=0) {
+ slope = ((double)target_y-robots[x].new_y)/((double)(target_x-robots[x].new_x));
+
+ if((slope<1) && (slope>-1)) {
+ if(target_x>robots[x].new_x) {
+ robots[x].lasers[y].start_x = robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].lasers[y].start_x + 7;
+ }
+ else {
+ robots[x].lasers[y].start_x = -robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].lasers[y].start_x - 7;
+ }
+ robots[x].lasers[y].start_y = (int)(robots[x].lasers[y].start_x * slope);
+ robots[x].lasers[y].end_y = (int)(robots[x].lasers[y].end_x * slope);
+ }
+ else {
+ slope = (target_x-robots[x].new_x)/(target_y-robots[x].new_y);
+ if(target_y>robots[x].new_y) {
+ robots[x].lasers[y].start_y = robots[x].radius;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y + 7;
+ }
+ else {
+ robots[x].lasers[y].start_y = -robots[x].radius;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y + 7;
+ }
+ robots[x].lasers[y].start_x = (int)(robots[x].lasers[y].start_y * slope);;
+ robots[x].lasers[y].start_x = (int)(robots[x].lasers[y].end_y * slope);
+ }
+ robots[x].lasers[y].start_x = robots[x].lasers[y].start_x + robots[x].new_x;
+ robots[x].lasers[y].start_y = robots[x].lasers[y].start_y + robots[x].new_y;
+ robots[x].lasers[y].end_x = robots[x].lasers[y].end_x + robots[x].new_x;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].end_y + robots[x].new_y;
+ }
+ else {
+ if(target_y > robots[x].new_y) {
+ robots[x].lasers[y].start_x = robots[x].new_x;
+ robots[x].lasers[y].start_y = robots[x].new_y+robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].new_x;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y+7;
+ }
+ else {
+ robots[x].lasers[y].start_x = robots[x].new_x;
+ robots[x].lasers[y].start_y = robots[x].new_y-robots[x].radius;
+ robots[x].lasers[y].end_x = robots[x].new_x;
+ robots[x].lasers[y].end_y = robots[x].lasers[y].start_y-7;
+ }
+ }
+
+ if((((robots[x].lasers[y].start_x - robots[x].lasers[y].end_x) > 7) ||
+ ((robots[x].lasers[y].end_x - robots[x].lasers[y].start_x) > 7)) &&
+ (((robots[x].lasers[y].start_y - robots[x].lasers[y].end_y) > 7) ||
+ ((robots[x].lasers[y].end_y - robots[x].lasers[y].start_y) > 7))) {
+ }
+ else {
+ robots[x].lasers[y].active = 1;
+ y = NUM_LASERS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ if(robots[x].death==0) {
+ make_new_robot(x);
+ }
+ }
+ }
+
+}
+
+/* This moves a single laser one frame. collisions with other robots or
+ the mothership is checked. */
+static void move_laser(int rindex, int index)
+{
+ int x=0;
+ int y=0;
+ int z=0;
+ int dx=0;
+ int dy=0;
+ struct laser_state *laser;
+ if(rindex>=0) {
+ laser = robots[rindex].lasers;
+ }
+ else {
+ laser = mother->lasers;
+ }
+ if(laser[index].active) {
+ /* collision with other robots are checked here */
+ for(x=0;x<NUM_ROBOTS;x++) {
+ if(x!=rindex) {
+ if(robots[x].alive) {
+ y = laser[index].start_x-robots[x].new_x;
+ if(y<0) {
+ y = robots[x].new_x-laser[index].start_x;
+ }
+ z = laser[index].start_y-robots[x].new_y;
+ if(z<0) {
+ z = robots[x].new_y-laser[index].start_y;
+ }
+ if((z<robots[x].radius-1)&&(y<robots[x].radius-1)) {
+ robots[x].alive = 0;
+ robots[x].death = 20;
+ XFillArc(dpy, window, black, robots[x].old_x, robots[x].old_y, robots[x].radius, robots[x].radius, 0, 360*64);
+ XFillArc(dpy, window, black, robots[x].new_x, robots[x].new_y, robots[x].radius, robots[x].radius, 0, 360*64);
+ laser[index].active = 0;
+ x = NUM_ROBOTS;
+ }
+ else {
+ y = laser[index].end_x-robots[x].new_x;
+ if(y<0) {
+ y = robots[x].new_x-laser[index].end_x;
+ }
+ z = laser[index].end_y-robots[x].new_y;
+ if(z<0) {
+ z = robots[x].new_y-laser[index].end_y;
+ }
+ if((z<robots[x].radius-1)&&(y<robots[x].radius-1)) {
+ robots[x].alive = 0;
+ robots[x].death = 20;
+ XFillArc(dpy, window, black, robots[x].old_x, robots[x].old_y, robots[x].radius, robots[x].radius, 0, 360*64);
+ XFillArc(dpy, window, black, robots[x].new_x, robots[x].new_y, robots[x].radius, robots[x].radius, 0, 360*64);
+ laser[index].active = 0;
+ x = NUM_ROBOTS;
+ }
+ }
+ }
+ }
+ }
+ if((MOTHER_SHIP)&&(rindex!=-1)) {
+ if(laser[index].active) {
+ if(mother->active) {
+ y = laser[index].start_x-mother->new_x;
+ if(y<0) {
+ y = mother->new_x-laser[index].start_x;
+ }
+ z = laser[index].start_y-mother->y;
+ if(z<0) {
+ z = mother->y-laser[index].start_y;
+ }
+ if((z<MOTHER_SHIP_HEIGHT-1)&&(y<MOTHER_SHIP_WIDTH-1)) {
+ laser[index].active = 0;
+ mother->active--;
+ }
+ else {
+ y = laser[index].end_x-mother->new_x;
+ if(y<0) {
+ y = mother->new_x-laser[index].end_x;
+ }
+ z = laser[index].end_y-mother->y;
+ if(z<0) {
+ z = mother->y-laser[index].end_y;
+ }
+ if((z<MOTHER_SHIP_HEIGHT-1)&&(y<MOTHER_SHIP_WIDTH-1)) {
+ laser[index].active = 0;
+ mother->active--;
+ }
+ }
+
+ if(mother->active==0) {
+ mother->death=20;
+ }
+ }
+ }
+ }
+
+ if(laser[index].active) {
+ dx = laser[index].start_x - laser[index].end_x;
+ dy = laser[index].start_y - laser[index].end_y;
+
+ laser[index].start_x = laser[index].end_x;
+ laser[index].start_y = laser[index].end_y;
+ laser[index].end_x = laser[index].end_x-dx;
+ laser[index].end_y = laser[index].end_y-dy;
+
+ if((laser[index].end_x < 0) || (laser[index].end_x >= xgwa.width) ||
+ (laser[index].end_y < 0) || (laser[index].end_y >= xgwa.height)) {
+ laser[index].active = 0;
+ }
+ }
+ }
+}
+
+/* All the robots are drawn, including the mother ship and the explosions.
+ After all the robots have been drawn, their laser banks are check and
+ the active lasers are drawn. */
+static void draw_robots(void)
+{
+ int x=0;
+ int y=0;
+
+ for(x=0;x<NUM_ROBOTS;x++) {
+ if(robots[x].alive) {
+ XFillArc(dpy, window, black, robots[x].old_x, robots[x].old_y, robots[x].radius, robots[x].radius, 0, 360*64);
+ XFillArc(dpy, window, robots[x].robot_color, robots[x].new_x, robots[x].new_y, robots[x].radius, robots[x].radius, 0, 360*64);
+ }
+ else {
+ XFillArc(dpy, window, black, robots[x].old_x, robots[x].old_y, robots[x].radius, robots[x].radius, 0, 360*64);
+ if(robots[x].death) {
+ if(robots[x].death==20) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==18) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==17) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==15) {
+ XFillArc(dpy, window, black, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==14) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==13) {
+ XFillArc(dpy, window, black, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==12) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==11) {
+ XFillArc(dpy, window, black, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==10) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==9) {
+ XFillArc(dpy, window, black, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==8) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==7) {
+ XFillArc(dpy, window, black, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(robots[x].death==6) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ }
+ else if(robots[x].death==4) {
+ XFillArc(dpy, window, black, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ }
+ else if(robots[x].death==3) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ }
+ else if(robots[x].death==2) {
+ XFillArc(dpy, window, black, robots[x].new_x+(robots[x].radius/3), robots[x].new_y+(robots[x].radius/3), EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ XFillArc(dpy, window, EXPLODE_COLOR_2, robots[x].new_x+(1.7*robots[x].radius/2), robots[x].new_y+(1.7*robots[x].radius/2), EXPLODE_SIZE_3, EXPLODE_SIZE_3, 0, 360*64);
+ }
+ else if(robots[x].death==1) {
+ XFillArc(dpy, window, black, robots[x].new_x+(1.7*robots[x].radius/2), robots[x].new_y+(1.7*robots[x].radius/2), EXPLODE_SIZE_3, EXPLODE_SIZE_3, 0, 360*64);
+ }
+ robots[x].death--;
+ }
+ }
+ }
+
+ for(x=0;x<NUM_ROBOTS;x++) {
+ for(y=0;y<NUM_LASERS;y++) {
+ if(robots[x].lasers[y].active) {
+ XDrawLine(dpy, window, black, robots[x].lasers[y].start_x,
+ robots[x].lasers[y].start_y,
+ robots[x].lasers[y].end_x,
+ robots[x].lasers[y].end_y);
+ move_laser(x, y);
+ if(robots[x].lasers[y].active) {
+ XDrawLine(dpy, window, robots[x].laser_color, robots[x].lasers[y].start_x,
+ robots[x].lasers[y].start_y,
+ robots[x].lasers[y].end_x,
+ robots[x].lasers[y].end_y);
+ }
+ else {
+ XDrawLine(dpy, window, black, robots[x].lasers[y].start_x,
+ robots[x].lasers[y].start_y,
+ robots[x].lasers[y].end_x,
+ robots[x].lasers[y].end_y);
+ }
+ }
+ }
+ }
+
+ if(MOTHER_SHIP) {
+ if(mother->active) {
+ XFillArc(dpy, window, black, mother->old_x, mother->y, MOTHER_SHIP_WIDTH, MOTHER_SHIP_HEIGHT, 0 , 360*64);
+ XFillArc(dpy, window, mother->ship_color, mother->new_x, mother->y, MOTHER_SHIP_WIDTH, MOTHER_SHIP_HEIGHT, 0 , 360*64);
+ }
+ else {
+ if(mother->death) {
+ XFillArc(dpy, window, black, mother->old_x, mother->y, MOTHER_SHIP_WIDTH, MOTHER_SHIP_HEIGHT, 0 , 360*64);
+ if(mother->death==20) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==18) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==17) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==15) {
+ XFillArc(dpy, window, black, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==14) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==13) {
+ XFillArc(dpy, window, black, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==12) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==11) {
+ XFillArc(dpy, window, black, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==10) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==9) {
+ XFillArc(dpy, window, black, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==8) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==7) {
+ XFillArc(dpy, window, black, mother->new_x+1, mother->y+1, EXPLODE_SIZE_1, EXPLODE_SIZE_1, 0, 360*64);
+ }
+ else if(mother->death==6) {
+ XFillArc(dpy, window, EXPLODE_COLOR_2, mother->new_x+1, mother->y+1, EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ }
+ else if(mother->death==4) {
+ XFillArc(dpy, window, black, mother->new_x+1, mother->y+1, EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ }
+ else if(mother->death==3) {
+ XFillArc(dpy, window, EXPLODE_COLOR_1, mother->new_x+1, mother->y+1, EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ }
+ else if(mother->death==2) {
+ XFillArc(dpy, window, black, mother->new_x+1, mother->y+1, EXPLODE_SIZE_2, EXPLODE_SIZE_2, 0, 360*64);
+ XFillArc(dpy, window, EXPLODE_COLOR_2, mother->new_x+(1.7*MOTHER_SHIP_WIDTH/2), mother->y+(1.7*MOTHER_SHIP_HEIGHT/2), EXPLODE_SIZE_3, EXPLODE_SIZE_3, 0, 360*64);
+ }
+ else if(mother->death==1) {
+ XFillArc(dpy, window, black, mother->new_x+(1.7*MOTHER_SHIP_WIDTH/2), mother->y+(1.7*MOTHER_SHIP_HEIGHT/2), EXPLODE_SIZE_3, EXPLODE_SIZE_3, 0, 360*64);
+ }
+ mother->death--;
+ }
+ }
+ for(y=0;y<8;y++) {
+ if(mother->lasers[y].active) {
+ XDrawLine(dpy, window, black, mother->lasers[y].start_x,
+ mother->lasers[y].start_y,
+ mother->lasers[y].end_x,
+ mother->lasers[y].end_y);
+ move_laser(-1,y);
+ if(mother->lasers[y].active) {
+ XDrawLine(dpy, window, mother->laser_color, mother->lasers[y].start_x,
+ mother->lasers[y].start_y,
+ mother->lasers[y].end_x,
+ mother->lasers[y].end_y);
+ }
+ else {
+ XDrawLine(dpy, window, black, mother->lasers[y].start_x,
+ mother->lasers[y].start_y,
+ mother->lasers[y].end_x,
+ mother->lasers[y].end_y);
+ }
+ }
+ }
+ }
+}
+
+/* This is the main loop. The mothership movement and laser firing happens inside
+ this loop. */
+static void
+start_blaster(void)
+{
+ int x=0;
+ int y=0;
+ int z=0;
+ robots = (struct robot_state *) malloc(NUM_ROBOTS * sizeof (struct robot_state));
+ for(x=0;x<NUM_ROBOTS;x++) {
+ robots[x].alive = 0;
+ robots[x].death = 0;
+ robots[x].lasers = (struct laser_state *) malloc (NUM_LASERS * sizeof(struct laser_state));
+ for(y=0;y<NUM_LASERS;y++) {
+ robots[x].lasers[y].active = 0;
+ }
+ }
+
+ if(NUM_STARS) {
+ stars = (XArc *) malloc (NUM_STARS * sizeof(XArc));
+ for(x=0;x<NUM_STARS;x++) {
+ stars[x].x = random()%xgwa.width;
+ stars[x].y = random()%xgwa.height;
+ stars[x].width = random()%4 + 1;
+ stars[x].height = stars[x].width;
+ stars[x].angle1 = 0;
+ stars[x].angle2 = 360 * 64;
+ }
+ }
+
+ while(1) {
+ if(NUM_STARS) {
+ if(MOVE_STARS) {
+ XFillArcs(dpy,window,black,stars,NUM_STARS);
+ if(MOVE_STARS_RANDOM) {
+ y = MOVE_STARS_X;
+ z = MOVE_STARS_Y;
+ if(random()%167==0) {
+ y = (-1)*y;
+ }
+ if(random()%173==0) {
+ z = (-1)*z;
+ }
+ if(random()%50==0) {
+ if(random()%2) {
+ y++;
+ if(y>MOVE_STARS_RANDOM) {
+ y = MOVE_STARS_RANDOM;
+ }
+ }
+ else {
+ y--;
+ if(y < -(MOVE_STARS_RANDOM)) {
+ y = -(MOVE_STARS_RANDOM);
+ }
+ }
+ }
+ if(random()%50==0) {
+ if(random()%2) {
+ z++;
+ if(z>MOVE_STARS_RANDOM) {
+ z = MOVE_STARS_RANDOM;
+ }
+ }
+ else {
+ z--;
+ if(z < -MOVE_STARS_RANDOM) {
+ z = -MOVE_STARS_RANDOM;
+ }
+ }
+ }
+ MOVE_STARS_X = y;
+ MOVE_STARS_Y = z;
+ for(x=0;x<NUM_STARS;x++) {
+ stars[x].x = stars[x].x + y;
+ stars[x].y = stars[x].y + z;
+ if(stars[x].x<0) {
+ stars[x].x = stars[x].x + xgwa.width;
+ }
+ else if(stars[x].x>xgwa.width) {
+ stars[x].x = stars[x].x - xgwa.width;
+ }
+ if(stars[x].y<0) {
+ stars[x].y = stars[x].y + xgwa.height;
+ }
+ else if(stars[x].y>xgwa.height) {
+ stars[x].y = stars[x].y - xgwa.height;
+ }
+ }
+ }
+ else {
+ for(x=0;x<NUM_STARS;x++) {
+ stars[x].x = stars[x].x + MOVE_STARS_X;
+ stars[x].y = stars[x].y + MOVE_STARS_Y;
+ if(stars[x].x<0) {
+ stars[x].x = stars[x].x + xgwa.width;
+ }
+ else if(stars[x].x>xgwa.width) {
+ stars[x].x = stars[x].x - xgwa.width;
+ }
+ if(stars[x].y<0) {
+ stars[x].y = stars[x].y + xgwa.height;
+ }
+ else if(stars[x].y>xgwa.height) {
+ stars[x].y = stars[x].y - xgwa.height;
+ }
+ }
+ }
+ XFillArcs(dpy,window,s_color,stars,NUM_STARS);
+ }
+ else {
+ XFillArcs(dpy,window,s_color,stars,NUM_STARS);
+ }
+ }
+
+ if(MOTHER_SHIP) {
+ if(random()%MOTHER_SHIP_PERIOD==0) {
+ if((mother->active==0)&&(mother->death==0)) {
+ mother->active = MOTHER_SHIP_HITS;
+ mother->y = random()%(xgwa.height-7);
+ if(random()%2==0) {
+ mother->old_x=0;
+ mother->new_x=0;
+ }
+ else {
+ mother->old_x=xgwa.width-25;
+ mother->new_x=xgwa.width-25;
+ }
+ }
+ }
+ }
+ move_robots();
+ if(MOTHER_SHIP) {
+ if(mother->active) {
+ if(mother->old_x==mother->new_x) {
+ if(mother->old_x==0) {
+ mother->new_x=3;
+ }
+ else {
+ mother->new_x=mother->new_x-3;
+ }
+ }
+ else {
+ if(mother->old_x>mother->new_x) {
+ mother->old_x = mother->new_x;
+ mother->new_x = mother->new_x-3;
+ if(mother->new_x<0) {
+ mother->active=0;
+ XFillArc(dpy, window, black, mother->old_x, mother->y, MOTHER_SHIP_WIDTH, MOTHER_SHIP_HEIGHT, 0 , 360*64);
+ XFillArc(dpy, window, black, mother->new_x, mother->y, MOTHER_SHIP_WIDTH, MOTHER_SHIP_HEIGHT, 0 , 360*64);
+ }
+ }
+ else {
+ mother->old_x = mother->new_x;
+ mother->new_x = mother->new_x+3;
+ if(mother->new_x>xgwa.width) {
+ mother->active=0;
+ XFillArc(dpy, window, black, mother->old_x, mother->y, MOTHER_SHIP_WIDTH, MOTHER_SHIP_HEIGHT, 0 , 360*64);
+ XFillArc(dpy, window, black, mother->new_x, mother->y, MOTHER_SHIP_WIDTH, MOTHER_SHIP_HEIGHT, 0 , 360*64);
+ }
+ }
+ }
+ y=0;
+ for(x=0;x<8;x++) {
+ if(mother->lasers[x].active) {
+ y=1;
+ x=8;
+ }
+ }
+ if(y==0) {
+ for(x=0;x<8;x++) {
+ mother->lasers[x].active = 1;
+ mother->lasers[x].start_x=mother->new_x+(MOTHER_SHIP_WIDTH/2);
+ mother->lasers[x].start_y=mother->y+(MOTHER_SHIP_HEIGHT/2);
+ }
+ y = (int)(MOTHER_SHIP_LASER/1.5);
+ mother->lasers[0].end_x=mother->lasers[0].start_x-MOTHER_SHIP_LASER;
+ mother->lasers[0].end_y=mother->lasers[0].start_y;
+ mother->lasers[1].end_x=mother->lasers[1].start_x-y;
+ mother->lasers[1].end_y=mother->lasers[1].start_y-y;
+ mother->lasers[2].end_x=mother->lasers[2].start_x;
+ mother->lasers[2].end_y=mother->lasers[2].start_y-MOTHER_SHIP_LASER;
+ mother->lasers[3].end_x=mother->lasers[3].start_x+y;
+ mother->lasers[3].end_y=mother->lasers[3].start_y-y;
+ mother->lasers[4].end_x=mother->lasers[4].start_x+MOTHER_SHIP_LASER;
+ mother->lasers[4].end_y=mother->lasers[4].start_y;
+ mother->lasers[5].end_x=mother->lasers[5].start_x+y;
+ mother->lasers[5].end_y=mother->lasers[5].start_y+y;
+ mother->lasers[6].end_x=mother->lasers[6].start_x;
+ mother->lasers[6].end_y=mother->lasers[6].start_y+MOTHER_SHIP_LASER;
+ mother->lasers[7].end_x=mother->lasers[7].start_x-y;
+ mother->lasers[7].end_y=mother->lasers[7].start_y+y;
+ }
+ }
+ }
+ draw_robots();
+
+ XSync(dpy, False);
+ screenhack_handle_events(dpy);
+ if(delay) usleep(delay);
+ }
+}
+
+
+
+
+
+
+
+
+char *progclass = "Blaster";
+
+char *defaults [] = {
+ ".background: black",
+ ".foreground: white",
+ "*r_color0: magenta",
+ "*r_color1: orange",
+ "*r_color2: yellow",
+ "*r_color3: white",
+ "*r_color4: blue",
+ "*r_color5: cyan",
+ "*l_color0: green",
+ "*l_color1: red",
+ "*mother_ship_color0: darkblue",
+ "*mother_ship_color1: white",
+ "*explode_color_1: yellow",
+ "*explode_color_2: orange",
+ "*delay: 10000",
+ "*num_robots: 5",
+ "*num_lasers: 3",
+ "*mother_ship: false",
+ "*mother_ship_width: 25",
+ "*mother_ship_height: 7",
+ "*mother_ship_laser: 15",
+ "*mother_ship_period: 150",
+ "*mother_ship_hits: 10",
+ "*explode_size_1: 27",
+ "*explode_size_2: 19",
+ "*explode_size_3: 7",
+ "*num_stars: 50",
+ "*star_color: white",
+ "*move_stars: true",
+ "*move_stars_x: 2",
+ "*move_stars_y: 1",
+ "*move_stars_random: 0",
+ 0
+};
+
+XrmOptionDescRec options [] = {
+ /* These are the 6 robot colors */
+ { "-r_color0", ".r_color0", XrmoptionSepArg, 0 },
+ { "-r_color1", ".r_color1", XrmoptionSepArg, 0 },
+ { "-r_color2", ".r_color2", XrmoptionSepArg, 0 },
+ { "-r_color3", ".r_color3", XrmoptionSepArg, 0 },
+ { "-r_color4", ".r_color4", XrmoptionSepArg, 0 },
+ { "-r_color5", ".r_color5", XrmoptionSepArg, 0 },
+ /* These are the 2 laser colors that robots have */
+ { "-l_color0", ".l_color0", XrmoptionSepArg, 0 },
+ { "-l_color1", ".l_color1", XrmoptionSepArg, 0 },
+ /* These are the colors for the mothership and the mothership lasers */
+ { "-mother_ship_color0", ".mother_ship_color0", XrmoptionSepArg, 0},
+ { "-mother_ship_color1", ".mother_ship_color1", XrmoptionSepArg, 0},
+ /* These are the two colors of the animated explosion */
+ { "-explode_color_1", ".explode_color_1", XrmoptionSepArg, 0 },
+ { "-explode_color_2", ".explode_color_2", XrmoptionSepArg, 0 },
+ /* This is the delay in the main loop */
+ { "-delay", ".delay", XrmoptionSepArg, 0 },
+ /* The number of robots and the number of lasers each robot has */
+ { "-num_robots", ".num_robots", XrmoptionSepArg, 0},
+ { "-num_lasers", ".num_lasers", XrmoptionSepArg, 0},
+ /* If this is set, a mothership will appear, otherwise no mothership */
+ { "-mother_ship", ".mother_ship", XrmoptionNoArg, "true"},
+ { "-no_mother_ship", ".mother_ship", XrmoptionNoArg, "false"},
+ /* This is the width, height, and laser length of the mothership */
+ { "-mother_ship_width", ".mother_ship_width", XrmoptionSepArg, 0},
+ { "-mother_ship_height", ".mother_ship_height", XrmoptionSepArg, 0},
+ { "-mother_ship_laser", ".mother_ship_laser", XrmoptionSepArg, 0},
+ /* This is the period which the mothership comes out, higher period==less often */
+ { "-mother_ship_period", ".mother_ship_period", XrmoptionSepArg, 0},
+ /* This is the number of hits it takes to destroy the mothership */
+ { "-mother_ship_hits", ".mother_ship_hits", XrmoptionSepArg, 0},
+ /* These are the size of the radius of the animated explosions */
+ { "-explode_size_1", ".explode_size_1", XrmoptionSepArg, 0},
+ { "-explode_size_2", ".explode_size_2", XrmoptionSepArg, 0},
+ { "-explode_size_3", ".explode_size_3", XrmoptionSepArg, 0},
+ /* This sets the number of stars in the star field, if this is set to 0, there will be no stars */
+ { "-num_stars", ".num_stars", XrmoptionSepArg, 0},
+ /* This is the color of the stars */
+ { "-star_color", ".star_color", XrmoptionSepArg, 0},
+ /* If this is true, the stars will move */
+ { "-move_stars", ".move_stars", XrmoptionNoArg, "true"},
+ /* This is the amount the stars will move in the x and y direction */
+ { "-move_stars_x", ".move_stars_x", XrmoptionSepArg, 0},
+ { "-move_stars_y", ".move_stars_y", XrmoptionSepArg, 0},
+ /* If this is non-zero, the stars will move randomly, but will not move more than this number in
+ either the x or y direction */
+ { "-move_stars_random", ".move_stars_random", XrmoptionSepArg, 0},
+ { 0, 0, 0, 0 }
+};
+
+
+
+void screenhack(Display *d, Window w)
+{
+ XGCValues gcv;
+ Colormap cmap;
+ unsigned long bg;
+
+ dpy = d;
+ window = w;
+ XGetWindowAttributes(dpy, window, &xgwa);
+ cmap = xgwa.colormap;
+
+ delay = get_integer_resource("delay", "Integer");
+ if(delay==0) {
+ delay=10000;
+ }
+ NUM_ROBOTS = get_integer_resource("num_robots","Integer");
+ if(NUM_ROBOTS==0) {
+ NUM_ROBOTS=5;
+ }
+ NUM_LASERS = get_integer_resource("num_lasers","Integer");
+ EXPLODE_SIZE_1 = get_integer_resource("explode_size_1","Integer");
+ EXPLODE_SIZE_2 = get_integer_resource("explode_size_2","Integer");
+ EXPLODE_SIZE_3 = get_integer_resource("explode_size_3","Integer");
+
+ NUM_STARS = get_integer_resource("num_stars","Integer");
+ if(get_boolean_resource("move_stars","Boolean")) {
+ MOVE_STARS = 1;
+ MOVE_STARS_X = get_integer_resource("move_stars_x","Integer");
+ MOVE_STARS_Y = get_integer_resource("move_stars_y","Integer");
+ MOVE_STARS_RANDOM = get_integer_resource("move_stars_random","Integer");
+ }
+ else {
+ MOVE_STARS = 0;
+ }
+
+
+ bg = get_pixel_resource("background","Background", dpy, cmap);
+ gcv.function = GXcopy;
+
+#define make_gc(color,name) \
+ gcv.foreground = bg ^ get_pixel_resource ((name), "Foreground", \
+ dpy, cmap); \
+ color = XCreateGC (dpy, window, GCForeground|GCFunction, &gcv)
+
+ if(mono_p) {
+ gcv.foreground = bg;
+ black = XCreateGC(dpy, window, GCForeground|GCFunction, &gcv);
+ gcv.foreground = get_pixel_resource("foreground", "Foreground", dpy, cmap);
+ r_color0 = r_color1 = r_color2 = r_color3 = r_color4 = r_color5 = l_color0 = l_color1 = s_color=
+ XCreateGC(dpy, window, GCForeground|GCFunction, &gcv);
+ if(get_boolean_resource("mother_ship","Boolean")) {
+ MOTHER_SHIP_WIDTH=get_integer_resource("mother_ship_width","Integer");
+ MOTHER_SHIP_HEIGHT=get_integer_resource("mother_ship_height","Integer");
+ MOTHER_SHIP_LASER=get_integer_resource("mother_ship_laser","Integer");
+ MOTHER_SHIP_PERIOD=get_integer_resource("mother_ship_period","Integer");
+ MOTHER_SHIP_HITS=get_integer_resource("mother_ship_hits","Integer");
+ MOTHER_SHIP=1;
+ mother = (struct mother_ship_state *) malloc(sizeof(struct mother_ship_state));
+ mother->lasers = (struct laser_state *) malloc(8*sizeof(struct laser_state));
+ mother->active = 0;
+ mother->death = 0;
+ mother->ship_color = r_color0;
+ mother->laser_color = r_color0;
+ }
+ }
+ else {
+ if(get_boolean_resource("mother_ship","Boolean")) {
+ MOTHER_SHIP_WIDTH=get_integer_resource("mother_ship_width","Integer");
+ MOTHER_SHIP_HEIGHT=get_integer_resource("mother_ship_height","Integer");
+ MOTHER_SHIP_LASER=get_integer_resource("mother_ship_laser","Integer");
+ MOTHER_SHIP_PERIOD=get_integer_resource("mother_ship_period","Integer");
+ MOTHER_SHIP_HITS=get_integer_resource("mother_ship_hits","Integer");
+ MOTHER_SHIP=1;
+ mother = (struct mother_ship_state *) malloc(sizeof(struct mother_ship_state));
+ mother->lasers = (struct laser_state *) malloc(8*sizeof(struct laser_state));
+ mother->active = 0;
+ mother->death = 0;
+ make_gc(mother->ship_color,"mother_ship_color0");
+ make_gc(mother->laser_color,"mother_ship_color1");
+ }
+
+ make_gc (s_color,"star_color");
+
+ make_gc (EXPLODE_COLOR_1,"explode_color_1");
+ make_gc (EXPLODE_COLOR_2,"explode_color_2");
+
+ make_gc (r_color0,"r_color0");
+ make_gc (r_color1,"r_color1");
+ make_gc (r_color2,"r_color2");
+ make_gc (r_color3,"r_color3");
+ make_gc (r_color4,"r_color4");
+ make_gc (r_color5,"r_color5");
+ make_gc (l_color0,"l_color0");
+ make_gc (l_color1,"l_color1");
+ make_gc (black,"background");
+ }
+
+ start_blaster();
+}
"\n"
"_Press any key to continue");
- const char *wnt =
+ const char *wnt = /* from Jim Niemira <urmane@urmane.org> */
("*** STOP: 0x0000001E (0x80000003,0x80106fc0,0x8025ea21,0xfd6829e8)\n"
"Unhandled Kernel exception c0000047 from fa8418b4 (8025ea21,fd6829e8)\n"
"\n"
--- /dev/null
+/* Bumps, Copyright (c) 1999 Shane Smit <blackend@inconnect.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Module: "Bumps.cpp"
+ * Tab Size: 4
+ *
+ * Description:
+ * This is typical bump-mapping. The actual bump map is generated by a screen
+ * grab. The light source is represented by a spotlight of random color. This
+ * spotlight randomly traverses the bump map in a sinus pattern.
+ *
+ * Essentially, it 3D-izes your desktop, based on color intensity.
+ *
+ * Modification History:
+ * [10/01/99] - Shane Smit: Creation
+ * [10/08/99] - Shane Smit: Port to C. (Ick)
+ */
+
+
+#include "bumps.h"
+
+
+void CreateSpotLight( SSpotLight *pSpotLight, uint16_ iWinWidth, uint16_ nColorCount )
+{
+ double nDelta;
+ int16_ iHeight, iWidth;
+
+ pSpotLight->nDiameter = iWinWidth / 3;
+#ifdef VERBOSE
+ printf( "%s: Light Diameter: %d\n", progclass, pSpotLight->nDiameter );
+#endif
+
+ pSpotLight->aLightMap = calloc( pSpotLight->nDiameter * pSpotLight->nDiameter, sizeof(uint8_) );
+ memset( pSpotLight->aLightMap, 0, pSpotLight->nDiameter * pSpotLight->nDiameter );
+
+ /* The falloff max values... 3/4 of the entire lightmap. */
+ pSpotLight->nRadius = (uint16_)(pSpotLight->nDiameter / 2.5F);
+
+ for( iHeight=-pSpotLight->nRadius; iHeight<pSpotLight->nRadius; iHeight++ )
+ for( iWidth=-pSpotLight->nRadius; iWidth<pSpotLight->nRadius; iWidth++ )
+ {
+ nDelta = ( nColorCount * 2.5F ) - ( ( sqrt( pow( iWidth+0.5F, 2 ) + pow( iHeight+0.5F, 2 ) ) / pSpotLight->nRadius ) * ( nColorCount * 2.5F ) );
+ nDelta += nColorCount;
+ if( nDelta >= ( nColorCount * 2 ) ) nDelta = ( nColorCount * 2 ) - 1;
+ if( nDelta >= nColorCount )
+ pSpotLight->aLightMap[ ( ( iHeight + (pSpotLight->nDiameter/2) ) * pSpotLight->nDiameter ) + iWidth + (pSpotLight->nDiameter/2) ] = (uint8_)nDelta;
+ }
+
+ /* The actual lightmap... 1/2 of the entire lightmap. */
+ pSpotLight->nRadius = pSpotLight->nDiameter / 4;
+
+ for( iHeight=-pSpotLight->nRadius; iHeight<pSpotLight->nRadius; iHeight++ )
+ for( iWidth=-pSpotLight->nRadius; iWidth<pSpotLight->nRadius; iWidth++ )
+ {
+ nDelta = nColorCount - ( ( sqrt( pow( iWidth+0.5F, 2 ) + pow( iHeight+0.5F, 2 ) ) / pSpotLight->nRadius ) * ( nColorCount - 1 ) );
+ if( nDelta >= 1 )
+ pSpotLight->aLightMap[ ( ( iHeight + (pSpotLight->nDiameter/2) ) * pSpotLight->nDiameter ) + iWidth + (pSpotLight->nDiameter/2) ] = (uint8_)nDelta;
+ }
+
+ CreateTables( pSpotLight );
+
+ pSpotLight->nRadius = pSpotLight->nDiameter / 2; /* Now set the radius back to what it should be. */
+ pSpotLight->nAngleX = RANDOM() % pSpotLight->nDegreeCount;
+ pSpotLight->nAngleY = RANDOM() % pSpotLight->nDegreeCount;
+ pSpotLight->nVelocityX = ( RANDOM() % 3 ) + 1;
+ pSpotLight->nVelocityY = ( RANDOM() % 3 ) + 1;
+}
+
+
+void CreateTables( SSpotLight *pSpotLight )
+{
+ long double nUnit;
+ uint16_ iDegree;
+
+ pSpotLight->nDegreeCount = get_integer_resource( "degrees", "Integer" );
+ if( pSpotLight->nDegreeCount < 180 ) pSpotLight->nDegreeCount = 180; /* Less than 180 will show trails in higher resolutions. */
+#ifdef VERBOSE
+ printf( "%s: Using a %d degree circle.\n", progclass, pSpotLight->nDegreeCount );
+#endif
+
+ pSpotLight->aSinTable = calloc( pSpotLight->nDegreeCount, sizeof(double) );
+
+ /* This funtion builds the Sine Lookup Tables. */
+ nUnit = (long double)( PI * 2.0F ) / (long double)( pSpotLight->nDegreeCount );
+
+ for( iDegree=0; iDegree<pSpotLight->nDegreeCount; iDegree++)
+ pSpotLight->aSinTable[ iDegree ] = sin( nUnit * (long double)iDegree );
+}
+
+
+void CalcLightPos( SSpotLight *pSpotLight, uint16_ *pXPos, uint16_ *pYPos )
+{
+ pSpotLight->nVelocityX += ( RANDOM() % 2 ) ? 0.05F : -0.05F;
+ if( pSpotLight->nVelocityX < 1 ) pSpotLight->nVelocityX = 1;
+ else if( pSpotLight->nVelocityX > 3 ) pSpotLight->nVelocityX = 3;
+
+ pSpotLight->nVelocityX += ( RANDOM() % 2 ) ? 0.05F : -0.05F;
+ if( pSpotLight->nVelocityY < 1 ) pSpotLight->nVelocityX = 1;
+ else if( pSpotLight->nVelocityY > 3 ) pSpotLight->nVelocityX = 3;
+
+ pSpotLight->nAngleX += pSpotLight->nVelocityX;
+ if( pSpotLight->nAngleX >= pSpotLight->nDegreeCount ) pSpotLight->nAngleX -= pSpotLight->nDegreeCount;
+
+ pSpotLight->nAngleY += pSpotLight->nVelocityY;
+ if( pSpotLight->nAngleY >= pSpotLight->nDegreeCount ) pSpotLight->nAngleY -= pSpotLight->nDegreeCount;
+
+ *pXPos = (uint16_)( ( pSpotLight->iWinXCenter - pSpotLight->nRadius ) * pSpotLight->aSinTable[ (uint16_)pSpotLight->nAngleX ] ) + pSpotLight->iWinXCenter;
+ *pYPos = (uint16_)( ( pSpotLight->iWinYCenter - pSpotLight->nRadius ) * pSpotLight->aSinTable[ (uint16_)pSpotLight->nAngleY ] ) + pSpotLight->iWinYCenter;
+
+ /* Offset to upper left hand corner. */
+ *pXPos -= pSpotLight->nRadius;
+ *pYPos -= pSpotLight->nRadius;
+}
+
+
+void CreateBumps( SBumps *pBumps, Display *pNewDisplay, Window NewWin )
+{
+ XWindowAttributes XWinAttribs;
+ XGCValues GCValues;
+ int32_ nGCFlags;
+ uint16_ iWidth, iHeight;
+
+ XGetWindowAttributes( pNewDisplay, NewWin, &XWinAttribs );
+ pBumps->iWinWidth = XWinAttribs.width;
+ pBumps->iWinHeight = XWinAttribs.height;
+ pBumps->SpotLight.iWinXCenter = XWinAttribs.width / 2;
+ pBumps->SpotLight.iWinYCenter = XWinAttribs.height / 2;
+ pBumps->pDisplay = pNewDisplay;
+ pBumps->Win = NewWin;
+
+ pBumps->pXImage = XCreateImage( pBumps->pDisplay, XWinAttribs.visual, XWinAttribs.depth, ZPixmap, 0, NULL,
+ pBumps->iWinWidth, pBumps->iWinHeight, BitmapPad( pBumps->pDisplay ), 0 );
+ pBumps->pXImage->data = calloc( pBumps->pXImage->bytes_per_line * pBumps->pXImage->height, sizeof(int8_) );
+
+ GCValues.function = GXcopy;
+ GCValues.subwindow_mode = IncludeInferiors;
+ nGCFlags = GCForeground | GCFunction;
+ if( use_subwindow_mode_p( XWinAttribs.screen, pBumps->Win ) ) /* See grabscreen.c */
+ nGCFlags |= GCSubwindowMode;
+ pBumps->GraphicsContext = XCreateGC( pBumps->pDisplay, pBumps->Win, nGCFlags, &GCValues );
+
+ SetPalette( pBumps, &XWinAttribs );
+ CreateSpotLight( &pBumps->SpotLight, pBumps->iWinWidth, pBumps->nColorCount );
+ InitBumpMap( pBumps, &XWinAttribs );
+
+ /* Clear the image. */
+ if (pBumps->aXColors[ 0 ].pixel == 0)
+ memset (pBumps->pXImage->data, 0,
+ pBumps->pXImage->bytes_per_line * pBumps->pXImage->height);
+ else
+ for( iHeight=0; iHeight<pBumps->iWinHeight; iHeight++ )
+ for( iWidth=0; iWidth<pBumps->iWinWidth; iWidth++ )
+ XPutPixel( pBumps->pXImage, iWidth, iHeight,
+ pBumps->aXColors[ 0 ].pixel );
+ XSetWindowBackground( pBumps->pDisplay, pBumps->Win,
+ pBumps->aXColors[ 0 ].pixel );
+ XClearWindow (pBumps->pDisplay, pBumps->Win);
+}
+
+
+void SetPalette( SBumps *pBumps, XWindowAttributes *pXWinAttribs )
+{
+ XColor Color;
+ char *sColor; /* Spotlight Color */
+ int16_ iColor;
+ uint32_ *aPixels;
+
+ sColor = get_string_resource( "color", "Color" );
+
+ Color.red = RANDOM() % 0xFFFF;
+ Color.green = RANDOM() % 0xFFFF;
+ Color.blue = RANDOM() % 0xFFFF;
+
+ if( strcasecmp( sColor, "random" ) && !XParseColor( pBumps->pDisplay, pXWinAttribs->colormap, sColor, &Color ) )
+ fprintf( stderr, "%s: color %s not found in database. Choosing random...\n", progname, sColor );
+
+#ifdef VERBOSE
+ printf( "%s: Spotlight color is <%d,%d,%d> RGB.\n", progclass, Color.red, Color.green, Color.blue );
+#endif /* VERBOSE */
+
+ pBumps->nColorCount = get_integer_resource( "colorcount", "Integer" );
+ if( pBumps->nColorCount < 2 ) pBumps->nColorCount = 2;
+ if( pBumps->nColorCount > 128 ) pBumps->nColorCount = 128;
+
+ pBumps->aXColors = calloc( pBumps->nColorCount, sizeof(XColor ) );
+ aPixels = calloc( pBumps->nColorCount, sizeof(uint32_) );
+
+ /* Creates a phong shade: / SpotColor \ Index/ColorCount
+ * PhongShade = | ------------ | Index + ( 65535 - SpotColor )^
+ * \ ColorCount / */
+ pBumps->nColorCount--;
+ for( iColor=0; iColor<=pBumps->nColorCount; iColor++ )
+ {
+ pBumps->aXColors[ iColor ].red = (uint16_)( ( ( Color.red / (double)pBumps->nColorCount ) * iColor ) + pow( 0xFFFF - Color.red, iColor/(double)pBumps->nColorCount ) );
+ pBumps->aXColors[ iColor ].green = (uint16_)( ( ( Color.green / (double)pBumps->nColorCount ) * iColor ) + pow( 0xFFFF - Color.green, iColor/(double)pBumps->nColorCount ) );
+ pBumps->aXColors[ iColor ].blue = (uint16_)( ( ( Color.blue / (double)pBumps->nColorCount ) * iColor ) + pow( 0xFFFF - Color.blue, iColor/(double)pBumps->nColorCount ) );
+
+ if( !XAllocColor( pBumps->pDisplay, pXWinAttribs->colormap, &pBumps->aXColors[ iColor ] ) )
+ {
+ XFreeColors( pBumps->pDisplay, pXWinAttribs->colormap, aPixels, iColor, 0 );
+ free( pBumps->aXColors );
+ free( aPixels );
+ pBumps->nColorCount--;
+ pBumps->aXColors = calloc( pBumps->nColorCount, sizeof(XColor) );
+ aPixels = calloc( pBumps->nColorCount, sizeof(uint32_) );
+ iColor = -1;
+ }
+ else
+ aPixels[ iColor ] = pBumps->aXColors[ iColor ].pixel;
+ }
+ pBumps->nColorCount++;
+
+#ifdef VERBOSE
+ printf( "%s: Allocated %d colors.\n", progclass, pBumps->nColorCount );
+#endif /* VERBOSE */
+
+ XSetWindowBackground( pBumps->pDisplay, pBumps->Win, pBumps->aXColors[ 0 ].pixel );
+}
+
+
+void InitBumpMap( SBumps *pBumps, XWindowAttributes *pXWinAttribs )
+{
+ XImage *pScreenImage;
+ XColor aColors[ pBumps->iWinWidth ];
+ uint8_ nSoften;
+ uint16_ iWidth, iHeight;
+ BOOL bInvert = (BOOL)get_boolean_resource( "invert", "Boolean" );
+
+ grab_screen_image( pXWinAttribs->screen, pBumps->Win );
+ pScreenImage = XGetImage( pBumps->pDisplay, pBumps->Win, 0, 0, pBumps->iWinWidth, pBumps->iWinHeight, ~0L, ZPixmap );
+
+ /* jwz: get the grabbed bits off the screen fast */
+ XClearWindow (pBumps->pDisplay, pBumps->Win);
+ XSync (pBumps->pDisplay, 0);
+
+ pBumps->aBumpMap = calloc( pBumps->iWinWidth * pBumps->iWinHeight, sizeof(uint16_) );
+ for( iHeight=0; iHeight<pBumps->iWinHeight; iHeight++ )
+ {
+ for( iWidth=0; iWidth<pBumps->iWinWidth; iWidth++ )
+ aColors[ iWidth ].pixel = XGetPixel( pScreenImage, iWidth, iHeight );
+
+ XQueryColors( pBumps->pDisplay, pXWinAttribs->colormap, aColors, pBumps->iWinWidth );
+
+ if( bInvert )
+ for( iWidth=0; iWidth<pBumps->iWinWidth; iWidth++ )
+ pBumps->aBumpMap[ ( iHeight * pBumps->iWinWidth ) + iWidth ] = (uint16_)
+ ( ( aColors[ iWidth ].red + aColors[ iWidth ].green + aColors[ iWidth ].blue ) / ( 0x2FFFD / (double)pBumps->SpotLight.nDiameter ) );
+ else
+ for( iWidth=0; iWidth<pBumps->iWinWidth; iWidth++ )
+ pBumps->aBumpMap[ ( iHeight * pBumps->iWinWidth ) + iWidth ] = (uint16_)
+ ( pBumps->SpotLight.nDiameter - ( ( aColors[ iWidth ].red + aColors[ iWidth ].green + aColors[ iWidth ].blue ) / ( 0x2FFFD / (double)pBumps->SpotLight.nDiameter ) ) );
+ }
+
+ XDestroyImage( pScreenImage );
+
+ nSoften = get_integer_resource( "soften", "Integer" );
+#ifdef VERBOSE
+ if( nSoften ) printf( "%s: Softening Bump Map %d time(s)...\n", progclass, nSoften );
+#endif
+ while( nSoften-- )
+ SoftenBumpMap( pBumps );
+}
+
+
+void SoftenBumpMap( SBumps *pBumps )
+{
+ uint16_ *pOffset;
+ uint16_ nHeight;
+ uint16_ iWidth, iHeight;
+ uint16_ *pTempBuffer = calloc( pBumps->iWinWidth * pBumps->iWinHeight, sizeof(uint16_) );
+
+ for( iHeight=1; iHeight<pBumps->iWinHeight-1; iHeight++ )
+ {
+ pOffset = pBumps->aBumpMap + ( iHeight * pBumps->iWinWidth );
+ for( iWidth=1; iWidth<pBumps->iWinWidth-1; iWidth++ )
+ {
+ nHeight = 0;
+ nHeight += pOffset[ iWidth ];
+ nHeight += pOffset[ iWidth - pBumps->iWinWidth ];
+ nHeight += pOffset[ iWidth + 1 ];
+ nHeight += pOffset[ iWidth + pBumps->iWinWidth ];
+ nHeight += pOffset[ iWidth - 1 ];
+ nHeight /= 5;
+ pTempBuffer[ ( iHeight * pBumps->iWinWidth ) + iWidth ] = nHeight;
+ }
+ }
+
+ memcpy( pBumps->aBumpMap, pTempBuffer, pBumps->iWinWidth * pBumps->iWinHeight * 2 );
+ free( pTempBuffer );
+}
+
+
+void Execute( SBumps *pBumps )
+{
+ uint16_ nLightXPos, nLightYPos;
+ uint16_ iWidth, iHeight;
+ uint16_ iLightWidth, iLightHeight;
+ uint16_ *pBOffset;
+ uint8_ *pLOffset;
+ int16_ nX, nY;
+ uint16_ nColor;
+ CalcLightPos( &pBumps->SpotLight, &nLightXPos, &nLightYPos );
+
+ for( iHeight=nLightYPos, iLightHeight=0; iLightHeight<pBumps->SpotLight.nDiameter; iHeight++, iLightHeight++ )
+ {
+ pBOffset = pBumps->aBumpMap + ( iHeight * pBumps->iWinWidth );
+ pLOffset = pBumps->SpotLight.aLightMap + ( iLightHeight * pBumps->SpotLight.nDiameter );
+ for( iWidth=nLightXPos, iLightWidth=0; iLightWidth<pBumps->SpotLight.nDiameter; iWidth++, iLightWidth++ )
+ {
+ if( pLOffset[ iLightWidth ] )
+ {
+ nX = pBOffset[ iWidth + 1 ] - pBOffset[ iWidth ] + iLightWidth;
+ nY = pBOffset[ iWidth + pBumps->iWinWidth ] - pBOffset[ iWidth ] + iLightHeight;
+
+ if( nX < 0 ) nX = 0;
+ else if( nX >= pBumps->SpotLight.nDiameter ) nX = pBumps->SpotLight.nDiameter - 1;
+
+ if( nY < 0 ) nY = 0;
+ else if( nY >= pBumps->SpotLight.nDiameter ) nY = pBumps->SpotLight.nDiameter - 1;
+
+ nColor = pBumps->SpotLight.aLightMap[ ( nY * pBumps->SpotLight.nDiameter ) + nX ];
+ if( nColor >= pBumps->nColorCount )
+ nColor = 1;
+
+ if( pLOffset[ iLightWidth ] >= pBumps->nColorCount )
+ if( nColor > pLOffset[ iLightWidth ] - pBumps->nColorCount )
+ nColor = pLOffset[ iLightWidth ] - pBumps->nColorCount;
+
+ XPutPixel( pBumps->pXImage, iWidth, iHeight, pBumps->aXColors[ nColor ].pixel );
+ }
+ else
+ XPutPixel( pBumps->pXImage, iWidth, iHeight, pBumps->aXColors[ 0 ].pixel );
+ }
+ }
+
+ XPutImage( pBumps->pDisplay, pBumps->Win, pBumps->GraphicsContext, pBumps->pXImage, nLightXPos, nLightYPos, nLightXPos, nLightYPos, pBumps->SpotLight.nDiameter, pBumps->SpotLight.nDiameter );
+ XSync( pBumps->pDisplay, False );
+}
+
+
+void DestroyBumps( SBumps *pBumps )
+{
+ DestroySpotLight( &pBumps->SpotLight );
+ free( pBumps->aXColors );
+ free( pBumps->aBumpMap );
+ XDestroyImage( pBumps->pXImage );
+}
+
+
+/* All messages to the screensaver are processed here. */
+void screenhack( Display *pDisplay, Window Win )
+{
+ SBumps Bumps;
+ uint32_ iDelay;
+#ifdef VERBOSE
+ time_t Time = time( NULL );
+ uint16_ iFrame = 0;
+#endif /* VERBOSE */
+
+ CreateBumps( &Bumps, pDisplay, Win );
+ iDelay = get_integer_resource( "delay", "Integer" );
+
+ while( 1 )
+ {
+ screenhack_handle_events( pDisplay );
+ Execute( &Bumps );
+ usleep( iDelay );
+
+#ifdef VERBOSE
+ iFrame++;
+ if( Time - time( NULL ) )
+ {
+ printf( "FPS: %d\n", iFrame );
+ Time = time( NULL );
+ iFrame = 0;
+ }
+#endif /* VERBOSE */
+ }
+
+ DestroyBumps( &Bumps );
+}
+
+
+/*
+ * End of Module: "Bumps.cpp"
+ */
+
+/* vim: ts=4
+ */
--- /dev/null
+/* Bumps, Copyright (c) 1999 Shane Smit <blackend@inconnect.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Module: "Bumps.h"
+ * Tab Size: 4
+ *
+ * Description:
+ * Header file for module "Bumps.cpp"
+ *
+ * Modification History:
+ * [10/01/99] - Shane Smit: Creation
+ * [10/08/99] - Shane Smit: Port to C. (Ick)
+ */
+
+
+#ifndef _BUMPS_H
+#define _BUMPS_H
+
+
+#include <math.h>
+#include "screenhack.h"
+#include <X11/Xutil.h>
+
+
+/* Defines: */
+/* #define VERBOSE */
+#define PI 3.141592654
+#define RANDOM() ((int) (random() & 0X7FFFFFFFL))
+
+typedef char int8_;
+typedef unsigned char uint8_;
+typedef short int16_;
+typedef unsigned short uint16_;
+typedef long int32_;
+typedef unsigned long uint32_;
+typedef unsigned char BOOL;
+
+
+// Globals:
+char *progclass = "Bumps";
+
+char *defaults [] = {
+ "*degrees: 360",
+ "*color: random",
+ "*colorcount: 64",
+ "*delay: 50000",
+ "*soften: 1",
+ "*invert: FALSE",
+ 0
+};
+
+XrmOptionDescRec options [] = {
+ { "-degrees", ".degrees", XrmoptionSepArg, 0 },
+ { "-color", ".color", XrmoptionSepArg, 0 },
+ { "-colorcount", ".colorcount", XrmoptionSepArg, 0 },
+ { "-delay", ".delay", XrmoptionSepArg, 0 },
+ { "-soften", ".soften", XrmoptionSepArg, 0 },
+ { "-invert", ".invert", XrmoptionNoArg, "TRUE" },
+ { 0, 0, 0, 0 }
+};
+
+
+/* This structure handles everything to do with the spotlight, and is designed to be
+ * a member of TBumps. */
+typedef struct
+{
+ uint16_ nDegreeCount;
+ double *aSinTable;
+
+ uint8_ *aLightMap;
+ uint16_ nDiameter, nRadius;
+ float nAngleX, nAngleY; /* Spotlight's movement direction. */
+ float nVelocityX, nVelocityY;
+ uint16_ iWinXCenter, iWinYCenter;
+} SSpotLight;
+
+void CreateSpotLight( SSpotLight *, uint16_, uint16_ );
+void CreateTables( SSpotLight * );
+void CalcLightPos( SSpotLight *, uint16_ *, uint16_ * );
+void DestroySpotLight( SSpotLight *pSpotLight ) { free( pSpotLight->aLightMap ); free( pSpotLight->aSinTable ); }
+
+
+/* The entire program's operation is contained within this structure. */
+typedef struct
+{
+ /* XWindows specific variables. */
+ Display *pDisplay;
+ Window Win;
+ GC GraphicsContext;
+ XColor *aXColors;
+ XImage *pXImage;
+
+ uint8_ nColorCount; /* Number of colors used. */
+ uint16_ iWinWidth, iWinHeight;
+ uint16_ *aBumpMap; /* The actual bump map. */
+
+ SSpotLight SpotLight;
+} SBumps;
+
+void CreateBumps( SBumps *, Display *, Window );
+void Execute( SBumps * );
+void DestroyBumps( SBumps * );
+
+void SetPalette( SBumps *, XWindowAttributes * );
+void InitBumpMap( SBumps *, XWindowAttributes * );
+void SoftenBumpMap( SBumps * );
+
+
+#endif /* _BUMPS_H */
+
+
+/*
+ * End of Module: "Bumps.h"
+ */
+
+/* vim: ts=4
+ */
--- /dev/null
+/* ccurve, Copyright (c) 1998, 1999
+ * Rick Campbell <rick@campbellcentral.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ */
+
+/* Draw self-similar linear fractals including the classic ``C Curve''
+ *
+ * 16 Aug 1999 Rick Campbell <rick@campbellcentral.org>
+ * Eliminated sub-windows-with-backing-store-double-buffering crap in
+ * favor of drawing the new image in a pixmap and then splatting that on
+ * the window.
+ *
+ * 19 Dec 1998 Rick Campbell <rick@campbellcentral.org>
+ * Original version.
+ */
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "screenhack.h"
+#include "colors.h"
+#include "erase.h"
+
+#define SQRT3 (1.73205080756887729353)
+#define MAXIMUM_COLOR_COUNT (256)
+#define EPSILON (1e-5)
+
+typedef struct Position_struct
+{
+ double x;
+ double y;
+}
+Position;
+
+typedef struct Segment_struct
+{
+ double angle;
+ double length;
+}
+Segment;
+
+static int color_count = 0;
+static int color_index = 0;
+static Colormap color_map = (Colormap)NULL;
+static XColor colors [MAXIMUM_COLOR_COUNT];
+static int line_count = 0;
+static int maximum_lines = 0;
+static double plot_maximum_x = -1000.00;
+static double plot_maximum_y = -1000.00;
+static double plot_minimum_x = 1000.00;
+static double plot_minimum_y = 1000.00;
+static int total_lines = 0;
+
+/* normalize alters the sequence to go from (0,0) to (1,0) */
+static
+void
+normalized_plot (int segment_count,
+ Segment* segments,
+ Position* points)
+{
+ double angle = 0.0;
+ double cosine = 0.0;
+ int index = 0;
+ double length = 0.0;
+ double sine = 0.0;
+ double x = 0.0;
+ double y = 0.0;
+
+ for (index = 0; index < segment_count; ++index)
+ {
+ Segment* segment = segments + index;
+ double length = segment->length;
+ double angle = segment->angle;
+
+ x += length * cos (angle);
+ y += length * sin (angle);
+ points [index].x = x;
+ points [index].y = y;
+ }
+ angle = -(atan2 (y, x));
+ cosine = cos (angle);
+ sine = sin (angle);
+ length = sqrt ((x * x) + (y * y));
+ /* rotate and scale */
+ for (index = 0; index < segment_count; ++index)
+ {
+ double temp_x = points [index].x;
+ double temp_y = points [index].y;
+ points [index].x = ((temp_x * cosine) + (temp_y * (-sine))) / length;
+ points [index].y = ((temp_x * sine) + (temp_y * cosine)) / length;
+ }
+}
+
+static
+void
+copy_points (int segment_count,
+ Position* source,
+ Position* target)
+{
+ int index = 0;
+
+ for (index = 0; index < segment_count; ++index)
+ {
+ target [index] = source [index];
+ }
+}
+
+static
+void
+realign (double x1,
+ double y1,
+ double x2,
+ double y2,
+ int segment_count,
+ Position* points)
+{
+ double angle = 0.0;
+ double cosine = 0.0;
+ double delta_x = 0.0;
+ double delta_y = 0.0;
+ int index = 0;
+ double length = 0.0;
+ double sine = 0.0;
+
+ delta_x = x2 - x1;
+ delta_y = y2 - y1;
+ angle = atan2 (delta_y, delta_x);
+ cosine = cos (angle);
+ sine = sin (angle);
+ length = sqrt ((delta_x * delta_x) + (delta_y * delta_y));
+ /* rotate, scale, then shift */
+ for (index = 0; index < segment_count; ++index)
+ {
+ double temp_x = points [index].x;
+ double temp_y = points [index].y;
+ points [index].x
+ = (length * ((temp_x * cosine) + (temp_y * (-sine)))) + x1;
+ points [index].y
+ = (length * ((temp_x * sine) + (temp_y * cosine))) + y1;
+ }
+}
+
+static
+void
+self_similar_normalized (Display* display,
+ Pixmap pixmap,
+ GC context,
+ int width,
+ int height,
+ int iterations,
+ double x1,
+ double y1,
+ double x2,
+ double y2,
+ double maximum_x,
+ double maximum_y,
+ double minimum_x,
+ double minimum_y,
+ int segment_count,
+ Position* points)
+{
+ if (iterations == 0)
+ {
+ double delta_x = maximum_x - minimum_x;
+ double delta_y = maximum_y - minimum_y;
+ color_index = (int)(((double)(line_count * color_count))
+ / ((double)total_lines));
+ ++line_count;
+ XSetForeground (display, context, colors [color_index].pixel);
+ if (plot_maximum_x < x1) plot_maximum_x = x1;
+ if (plot_maximum_x < x2) plot_maximum_x = x2;
+ if (plot_maximum_y < y1) plot_maximum_y = y1;
+ if (plot_maximum_y < y2) plot_maximum_y = y2;
+ if (plot_minimum_x > x1) plot_minimum_x = x1;
+ if (plot_minimum_x > x2) plot_minimum_x = x2;
+ if (plot_minimum_y > y1) plot_minimum_y = y1;
+ if (plot_minimum_y > y2) plot_minimum_y = y2;
+ XDrawLine (display, pixmap, context,
+ (int)(((x1 - minimum_x) / delta_x) * width),
+ (int)(((maximum_y - y1) / delta_y) * height),
+ (int)(((x2 - minimum_x) / delta_x) * width),
+ (int)(((maximum_y - y2) / delta_y) * height));
+ }
+ else
+ {
+ int index = 0;
+ double next_x = 0.0;
+ double next_y = 0.0;
+ Position* replacement = (Position*)NULL;
+ double x = 0.0;
+ double y = 0.0;
+
+ replacement = (Position*)(alloca (segment_count * sizeof (Segment)));
+ copy_points (segment_count, points, replacement);
+ assert (fabs ((replacement [segment_count - 1].x) - 1.0) < EPSILON);
+ assert (fabs (replacement [segment_count - 1].y) < EPSILON);
+ realign (x1, y1, x2, y2, segment_count, replacement);
+ assert (fabs (x2 - (replacement [segment_count - 1].x)) < EPSILON);
+ assert (fabs (y2 - (replacement [segment_count - 1].y)) < EPSILON);
+ x = x1;
+ y = y1;
+ for (index = 0; index < segment_count; ++index)
+ {
+ next_x = replacement [index].x;
+ next_y = replacement [index].y;
+ self_similar_normalized (display, pixmap, context, width, height,
+ iterations - 1, x, y, next_x, next_y,
+ maximum_x, maximum_y,
+ minimum_x, minimum_y,
+ segment_count, points);
+ x = next_x;
+ y = next_y;
+ }
+ }
+}
+
+static
+void
+self_similar (Display* display,
+ Pixmap pixmap,
+ GC context,
+ int width,
+ int height,
+ int iterations,
+ double x1,
+ double y1,
+ double x2,
+ double y2,
+ double maximum_x,
+ double maximum_y,
+ double minimum_x,
+ double minimum_y,
+ int segment_count,
+ Segment* segments)
+{
+ Position* points = (Position*)NULL;
+
+ points = (Position*)(alloca (segment_count * sizeof (Position)));
+ normalized_plot (segment_count, segments, points);
+ assert (fabs ((points [segment_count - 1].x) - 1.0) < EPSILON);
+ assert (fabs (points [segment_count - 1].y) < EPSILON);
+ self_similar_normalized (display, pixmap, context,
+ width, height, iterations,
+ x1, y1, x2, y2,
+ maximum_x, maximum_y,
+ minimum_x, minimum_y,
+ segment_count, points);
+}
+
+static
+double
+random_double (double base,
+ double limit,
+ double epsilon)
+{
+ double range = 0.0;
+ unsigned int steps = 0;
+
+ assert (base < limit);
+ assert (epsilon > 0.0);
+ range = limit - base;
+ steps = (unsigned int)(floor (range / epsilon));
+ return base + ((random () % steps) * epsilon);
+}
+
+static
+void
+select_2_pattern (Segment* segments)
+{
+ if ((random () % 2) == 0)
+ {
+ if ((random () % 2) == 0)
+ {
+ segments [0].angle = -M_PI_4;
+ segments [0].length = M_SQRT2;
+ segments [1].angle = M_PI_4;
+ segments [1].length = M_SQRT2;
+ }
+ else
+ {
+ segments [0].angle = M_PI_4;
+ segments [0].length = M_SQRT2;
+ segments [1].angle = -M_PI_4;
+ segments [1].length = M_SQRT2;
+ }
+ }
+ else
+ {
+ segments [0].angle
+ = random_double (M_PI / 6.0, M_PI / 3.0, M_PI / 180.0);
+ segments [0].length = random_double (0.25, 0.67, 0.001);
+ if ((random () % 2) == 0)
+ {
+ segments [1].angle = -(segments [0].angle);
+ segments [1].length = segments [0].length;
+ }
+ else
+ {
+ segments [1].angle = random_double ((-M_PI) / 3.0,
+ (-M_PI) / 6.0,
+ M_PI / 180.0);
+ segments [1].length = random_double (0.25, 0.67, 0.001);
+ }
+ }
+}
+
+static
+void
+select_3_pattern (Segment* segments)
+{
+ switch (random () % 5)
+ {
+ case 0:
+ if ((random () % 2) == 0)
+ {
+ segments [0].angle = M_PI_4;
+ segments [0].length = M_SQRT2 / 4.0;
+ segments [1].angle = -M_PI_4;
+ segments [1].length = M_SQRT2 / 2.0;
+ segments [2].angle = M_PI_4;
+ segments [2].length = M_SQRT2 / 4.0;
+ }
+ else
+ {
+ segments [0].angle = -M_PI_4;
+ segments [0].length = M_SQRT2 / 4.0;
+ segments [1].angle = M_PI_4;
+ segments [1].length = M_SQRT2 / 2.0;
+ segments [2].angle = -M_PI_4;
+ segments [2].length = M_SQRT2 / 4.0;
+ }
+ break;
+ case 1:
+ if ((random () % 2) == 0)
+ {
+ segments [0].angle = M_PI / 6.0;
+ segments [0].length = 1.0;
+ segments [1].angle = -M_PI_2;
+ segments [1].length = 1.0;
+ segments [2].angle = M_PI / 6.0;
+ segments [2].length = 1.0;
+ }
+ else
+ {
+ segments [0].angle = -M_PI / 6.0;
+ segments [0].length = 1.0;
+ segments [1].angle = M_PI_2;
+ segments [1].length = 1.0;
+ segments [2].angle = -M_PI / 6.0;
+ segments [2].length = 1.0;
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ segments [0].angle
+ = random_double (M_PI / 6.0, M_PI / 3.0, M_PI / 180.0);
+ segments [0].length = random_double (0.25, 0.67, 0.001);
+ segments [1].angle
+ = random_double (-M_PI / 3.0, -M_PI / 6.0, M_PI / 180.0);
+ segments [1].length = random_double (0.25, 0.67, 0.001);
+ if ((random () % 3) == 0)
+ {
+ if ((random () % 2) == 0)
+ {
+ segments [2].angle = segments [0].angle;
+ }
+ else
+ {
+ segments [2].angle = -(segments [0].angle);
+ }
+ segments [2].length = segments [0].length;
+ }
+ else
+ {
+ segments [2].angle
+ = random_double (-M_PI / 3.0, -M_PI / 6.0, M_PI / 180.0);
+ segments [2].length = random_double (0.25, 0.67, 0.001);
+ }
+ break;
+ }
+}
+
+static
+void
+select_4_pattern (Segment* segments)
+{
+ switch (random () % 9)
+ {
+ case 0:
+ if ((random () % 2) == 0)
+ {
+ double length = random_double (0.25, 0.50, 0.001);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 0.5;
+ segments [1].angle = M_PI_2;
+ segments [1].length = length;
+ segments [2].angle = -M_PI_2;
+ segments [2].length = length;
+ segments [3].angle = 0.0;
+ segments [3].length = 0.5;
+ }
+ else
+ {
+ double length = random_double (0.25, 0.50, 0.001);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 0.5;
+ segments [1].angle = -M_PI_2;
+ segments [1].length = length;
+ segments [2].angle = M_PI_2;
+ segments [2].length = length;
+ segments [3].angle = 0.0;
+ segments [3].length = 0.5;
+ }
+ break;
+ case 1:
+ if ((random () % 2) == 0)
+ {
+ segments [0].angle = 0.0;
+ segments [0].length = 0.5;
+ segments [1].angle = M_PI_2;
+ segments [1].length = 0.45;
+ segments [2].angle = -M_PI_2;
+ segments [2].length = 0.45;
+ segments [3].angle = 0.0;
+ segments [3].length = 0.5;
+ }
+ else
+ {
+ segments [0].angle = 0.0;
+ segments [0].length = 0.5;
+ segments [1].angle = -M_PI_2;
+ segments [1].length = 0.45;
+ segments [2].angle = M_PI_2;
+ segments [2].length = 0.45;
+ segments [3].angle = 0.0;
+ segments [3].length = 0.5;
+ }
+ break;
+ case 2:
+ if ((random () % 2) == 0)
+ {
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = (5.0 * M_PI) / 12.0;
+ segments [1].length = 1.2;
+ segments [2].angle = (-5.0 * M_PI) / 12.0;
+ segments [2].length = 1.2;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ else
+ {
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = (-5.0 * M_PI) / 12.0;
+ segments [1].length = 1.2;
+ segments [2].angle = (5.0 * M_PI) / 12.0;
+ segments [2].length = 1.2;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ break;
+ case 3:
+ if ((random () % 2) == 0)
+ {
+ double angle
+ = random_double (M_PI / 4.0,
+ M_PI_2,
+ M_PI / 180.0);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = angle;
+ segments [1].length = 1.2;
+ segments [2].angle = (-angle);
+ segments [2].length = 1.2;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ else
+ {
+ double angle
+ = random_double (M_PI / 4.0,
+ M_PI_2,
+ M_PI / 180.0);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = (-angle);
+ segments [1].length = 1.2;
+ segments [2].angle = angle;
+ segments [2].length = 1.2;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ break;
+ case 4:
+ if ((random () % 2) == 0)
+ {
+ double angle
+ = random_double (M_PI / 4.0,
+ M_PI_2,
+ M_PI / 180.0);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = angle;
+ segments [1].length = 1.2;
+ segments [2].angle = (-angle);
+ segments [2].length = 1.2;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ else
+ {
+ double angle
+ = random_double (M_PI / 4.0,
+ M_PI_2,
+ M_PI / 180.0);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = (-angle);
+ segments [1].length = 1.2;
+ segments [2].angle = angle;
+ segments [2].length = 1.2;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ break;
+ case 5:
+ if ((random () % 2) == 0)
+ {
+ double angle
+ = random_double (M_PI / 4.0,
+ M_PI_2,
+ M_PI / 180.0);
+ double length = random_double (0.25, 0.50, 0.001);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = angle;
+ segments [1].length = length;
+ segments [2].angle = (-angle);
+ segments [2].length = length;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ else
+ {
+ double angle
+ = random_double (M_PI / 4.0,
+ M_PI_2,
+ M_PI / 180.0);
+ double length = random_double (0.25, 0.50, 0.001);
+
+ segments [0].angle = 0.0;
+ segments [0].length = 1.0;
+ segments [1].angle = (-angle);
+ segments [1].length = length;
+ segments [2].angle = angle;
+ segments [2].length = length;
+ segments [3].angle = 0.0;
+ segments [3].length = 1.0;
+ }
+ break;
+ case 6:
+ case 7:
+ case 8:
+ segments [0].angle
+ = random_double (M_PI / 12.0, (11.0 * M_PI) / 12.0, 0.001);
+ segments [0].length = random_double (0.25, 0.50, 0.001);
+ segments [1].angle
+ = random_double (M_PI / 12.0, (11.0 * M_PI) / 12.0, 0.001);
+ segments [1].length = random_double (0.25, 0.50, 0.001);
+ if ((random () % 3) == 0)
+ {
+ segments [2].angle
+ = random_double (M_PI / 12.0, (11.0 * M_PI) / 12.0, 0.001);
+ segments [2].length = random_double (0.25, 0.50, 0.001);
+ segments [3].angle
+ = random_double (M_PI / 12.0, (11.0 * M_PI) / 12.0, 0.001);
+ segments [3].length = random_double (0.25, 0.50, 0.001);
+ }
+ else
+ {
+ if ((random () % 2) == 0)
+ {
+ segments [2].angle = -(segments [1].angle);
+ segments [2].length = segments [1].length;
+ segments [3].angle = -(segments [0].angle);
+ segments [3].length = segments [0].length;
+ }
+ else
+ {
+ segments [2].angle = segments [1].angle;
+ segments [2].length = segments [1].length;
+ segments [3].angle = segments [0].angle;
+ segments [3].length = segments [0].length;
+ }
+ }
+ break;
+ }
+}
+
+static void
+select_pattern (int segment_count,
+ Segment* segments)
+{
+ switch (segment_count)
+ {
+ case 2:
+ select_2_pattern (segments);
+ break;
+ case 3:
+ select_3_pattern (segments);
+ break;
+ case 4:
+ select_4_pattern (segments);
+ break;
+ default:
+ fprintf (stderr, "\nBad segment count, must be 2, 3, or 4.\n");
+ exit (1);
+ }
+}
+
+char *progclass = "Ccurve";
+
+char *defaults [] =
+{
+ ".delay: 1",
+ ".pause: 3",
+ ".limit: 200000",
+ 0
+};
+
+XrmOptionDescRec options [] =
+{
+ { "-delay", ".delay", XrmoptionSepArg, 0 },
+ { "-pause", ".pause", XrmoptionSepArg, 0 },
+ { "-limit", ".limit", XrmoptionSepArg, 0 },
+ { 0, 0, 0, 0 }
+};
+
+#define Y_START (0.5)
+
+void
+screenhack (Display* display,
+ Window window)
+{
+ unsigned long int background = 0;
+ unsigned long int black = 0;
+ GC context;
+ int delay = 0;
+ int depth = 0;
+ Pixmap pixmap = (Pixmap)NULL;
+ XWindowAttributes hack_attributes;
+ int height = 0;
+ int iterations = 0;
+ int pause = 0;
+ XGCValues values;
+ unsigned long int white = 0;
+ int width = 0;
+
+ delay = get_integer_resource ("delay", "Integer");
+ pause = get_integer_resource ("pause", "Integer");
+ maximum_lines = get_integer_resource ("limit", "Integer");
+ black = BlackPixel (display, DefaultScreen (display));
+ white = WhitePixel (display, DefaultScreen (display));
+ background = black;
+ XGetWindowAttributes (display, window, &hack_attributes);
+ width = hack_attributes.width;
+ height = hack_attributes.height;
+ depth = hack_attributes.depth;
+ color_map = hack_attributes.colormap;
+ pixmap = XCreatePixmap (display, window, width, height, depth);
+ values.foreground = white;
+ values.background = black;
+ context = XCreateGC (display, window, GCForeground | GCBackground,
+ &values);
+ color_count = MAXIMUM_COLOR_COUNT;
+ make_color_loop (display, color_map,
+ 0, 1, 1,
+ 120, 1, 1,
+ 240, 1, 1,
+ colors, &color_count, True, False);
+ if (color_count <= 0)
+ {
+ color_count = 1;
+ colors [0].red = colors [0].green = colors [0].blue = 0xFFFF;
+ XAllocColor (display, color_map, &colors [0]);
+ }
+
+ while (1)
+ {
+ int index = 0;
+ double maximum_x = 1.20;
+ double maximum_y = 0.525;
+ double minimum_x = -0.20;
+ double minimum_y = -0.525;
+ static int lengths [] = { 4, 4, 4, 4, 4, 3, 3, 3, 2 };
+ int segment_count = 0;
+ Segment* segments = (Segment*)NULL;
+ double x1 = 0.0;
+ double y1 = 0.0;
+ double x2 = 1.0;
+ double y2 = 0.0;
+
+ segment_count
+ = lengths [random () % (sizeof (lengths) / sizeof (int))];
+ segments
+ = (Segment*)(alloca ((segment_count) * sizeof (Segment)));
+ select_pattern (segment_count, segments);
+ iterations = floor (log (maximum_lines)
+ / log (((double)(segment_count))));
+ if ((random () % 3) != 0)
+ {
+ double factor = 0.45;
+ x1 += random_double (-factor, factor, 0.001);
+ y1 += random_double (-factor, factor, 0.001);
+ x2 += random_double (-factor, factor, 0.001);
+ y2 += random_double (-factor, factor, 0.001);
+ }
+/* background = (random () % 2) ? black : white; */
+ for (index = 0; index < iterations; ++index)
+ {
+ double delta_x = 0.0;
+ double delta_y = 0.0;
+
+ XSetForeground (display, context, background);
+ XFillRectangle (display, pixmap, context, 0, 0, width, height);
+ line_count = 0;
+ total_lines = (int)(pow ((double)(segment_count),
+ (double)index));
+ plot_maximum_x = -1000.00;
+ plot_maximum_y = -1000.00;
+ plot_minimum_x = 1000.00;
+ plot_minimum_y = 1000.00;
+ self_similar (display, pixmap, context, width, height, index,
+ x1, y1, x2, y2,
+ maximum_x,
+ maximum_y,
+ minimum_x,
+ minimum_y,
+ segment_count, segments);
+ delta_x = plot_maximum_x - plot_minimum_x;
+ delta_y = plot_maximum_y - plot_minimum_y;
+ maximum_x = plot_maximum_x + (delta_x * 0.2);
+ maximum_y = plot_maximum_y + (delta_y * 0.2);
+ minimum_x = plot_minimum_x - (delta_x * 0.2);
+ minimum_y = plot_minimum_y - (delta_y * 0.2);
+ delta_x = maximum_x - minimum_x;
+ delta_y = maximum_y - minimum_y;
+ if ((delta_y / delta_x) > (((double)height) / ((double)width)))
+ {
+ double new_delta_x
+ = (delta_y * ((double)width)) / ((double)height);
+ minimum_x -= (new_delta_x - delta_x) / 2.0;
+ maximum_x += (new_delta_x - delta_x) / 2.0;
+ }
+ else
+ {
+ double new_delta_y
+ = (delta_x * ((double)height)) / ((double)width);
+ minimum_y -= (new_delta_y - delta_y) / 2.0;
+ maximum_y += (new_delta_y - delta_y) / 2.0;
+ }
+ XCopyArea (display, pixmap, window, context, 0, 0, width, height,
+ 0, 0);
+ if (delay) sleep (delay);
+ screenhack_handle_events (display);
+ }
+ if (pause) sleep (pause);
+ erase_full_window (display, window);
+ }
+}
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ANT.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ATTRACTION.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLASTER.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLITSPIN.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BOUBOULE.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BRAID.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BSOD.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES-DEFAULT.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUMPS.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CCURVE.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) COMPASS.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CORAL.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CRITICAL.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ANT.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ATTRACTION.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLASTER.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLITSPIN.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BOUBOULE.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BRAID.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BSOD.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES-DEFAULT.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUBBLES.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BUMPS.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CCURVE.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) COMPASS.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CORAL.C
$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CRITICAL.C
* -more distortion matrices (fortunately, I'm out of ideas :)
* Stuff that would be cool but probably too much of a resource hog:
* -some kind of interpolation to avoid jaggies
+ * -large speed values leaves the image distorted
* program idea borrowed from a screensaver on a non-*NIX OS,
+ *
+ * 28 Sep 1999 Jonas Munsin (jmunsin@iki.fi)
+ * Added about 10x faster algortim for 8, 16 and 32 bpp (modifies pixels
+ * directly avoiding costly XPutPixle(XGetPixel()) calls, inspired by
+ * xwhirl made by horvai@clipper.ens.fr (Peter Horvai) and the XFree86
+ * Xlib sources.
+ * This piece of code is really horrible, but it works, and at the moment
+ * I don't have time or inspiration to fix something that works (knock
+ * on wood).
+ * 08 Oct 1999 Jonas Munsin (jmunsin@iki.fi)
+ * Corrected several bugs causing references beyond allocated memory.
*/
#include <math.h>
#include "screenhack.h"
#include <X11/Xutil.h>
+#include <X11/Xmd.h>
#ifdef HAVE_XSHM_EXTENSION
# include "xshm.h"
-static Bool use_shm;
+static Bool use_shm = False;
static XShmSegmentInfo shm_info;
#endif /* HAVE_XSHM_EXTENSION */
};
static struct coo xy_coo[10];
-static int delay, radius, speed, number, blackhole, vortex, magnify, reflect;
+static int delay, radius, speed, number, blackhole, vortex, magnify, reflect, slow;
static XWindowAttributes xgwa;
static GC gc;
static Window g_window;
static unsigned long black_pixel;
static XImage *orig_map, *buffer_map;
+static unsigned long *buffer_map_cache;
static int ***from;
static int ****from_array;
+static int *fast_from = NULL;
static void (*effect) (int) = NULL;
static void move_lense(int);
static void swamp_thing(int);
static void reflect_draw(int);
static void plain_draw(int);
+static void (*draw_routine)(XImage *, XImage *, int, int, int *) = NULL;
+static void fast_draw_8(XImage *, XImage *, int, int, int *);
+static void fast_draw_16(XImage *, XImage *, int, int, int *);
+static void fast_draw_32(XImage *, XImage *, int, int, int *);
+static void generic_draw(XImage *, XImage *, int, int, int *);
+static int bpp_size = 0;
+
+
static void init_distort(Display *dpy, Window window)
{
XGCValues gcv;
vortex = get_boolean_resource("vortex", "Boolean");
magnify = get_boolean_resource("magnify", "Boolean");
reflect = get_boolean_resource("reflect", "Boolean");
+ slow = get_boolean_resource("slow", "Boolean");
if (get_boolean_resource("swamp", "Boolean"))
effect = &swamp_thing;
* -radius 100 -number 1 -speed 2 -vortex
* -radius 100 -number 1 -speed 2 -vortex -magnify
* -radius 100 -number 1 -speed 2 -vortex -magnify -blackhole
- * -radius 50 -number 4 -speed 2 -swamp
- * -radius 50 -number 4 -speed 2 -swamp -blackhole
- * -radius 50 -number 4 -speed 2 -swamp -vortex
- * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify
- * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify -blackhole
* -radius 80 -number 1 -speed 2 -reflect
* -radius 50 -number 3 -speed 2 -reflect
+ * jwz: not these
+ * -radius 50 -number 4 -speed 2 -swamp
+ * -radius 50 -number 4 -speed 2 -swamp -blackhole
+ * -radius 50 -number 4 -speed 2 -swamp -vortex
+ * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify
+ * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify -blackhole
*/
- i = (random() % 17);
+ i = (random() % 12 /* 17 */);
draw = &plain_draw;
case 9:
radius=100;number=1;speed=2;vortex=1;magnify=1;blackhole=1;
effect=&move_lense;break;
+
case 10:
+ radius=80;number=1;speed=2;reflect=1;
+ draw = &reflect_draw;effect = &move_lense;break;
+ case 11:
+ radius=50;number=4;speed=2;reflect=1;
+ draw = &reflect_draw;effect = &move_lense;break;
+
+#if 0 /* jwz: not these */
+ case 12:
radius=50;number=4;speed=2;
effect=&swamp_thing;break;
- case 11:
+ case 13:
radius=50;number=4;speed=2;blackhole=1;
effect=&swamp_thing;break;
- case 12:
+ case 14:
radius=50;number=4;speed=2;vortex=1;
effect=&swamp_thing;break;
- case 13:
+ case 15:
radius=50;number=4;speed=2;vortex=1;magnify=1;
effect=&swamp_thing;break;
- case 14:
+ case 16:
radius=50;number=4;speed=2;vortex=1;magnify=1;blackhole=1;
effect=&swamp_thing;break;
- case 15:
- radius=80;number=1;speed=2;reflect=1;
- draw = &reflect_draw;effect = &move_lense;break;
- case 16: default:
- radius=50;number=4;speed=2;reflect=1;
- draw = &reflect_draw;effect = &move_lense;break;
+#endif
+
+ default:
+ abort(); break;
}
}
buffer_map = 0;
orig_map = XGetImage(dpy, window, 0, 0, xgwa.width, xgwa.height,
~0L, ZPixmap);
+ buffer_map_cache = malloc(sizeof(unsigned long)*(2*radius+speed+2)*(2*radius+speed+2));
+
+ if (buffer_map_cache == NULL) {
+ perror("distort");
+ exit(EXIT_FAILURE);
+ }
# ifdef HAVE_XSHM_EXTENSION
calloc(buffer_map->height, buffer_map->bytes_per_line);
}
+ if ((buffer_map->byte_order == orig_map->byte_order)
+ && (buffer_map->depth == orig_map->depth)
+ && (buffer_map->format == ZPixmap)
+ && (orig_map->format == ZPixmap)
+ && !slow) {
+ switch (orig_map->bits_per_pixel) {
+ case 32:
+ draw_routine = &fast_draw_32;
+ bpp_size = sizeof(CARD32);
+ break;
+ case 16:
+ draw_routine = &fast_draw_16;
+ bpp_size = sizeof(CARD16);
+ break;
+ case 8:
+ draw_routine = &fast_draw_8;
+ bpp_size = sizeof(CARD8);
+ break;
+ default:
+ draw_routine = &generic_draw;
+ break;
+ }
+ } else {
+ draw_routine = &generic_draw;
+ }
init_round_lense();
for (i = 0; i < number; i++) {
xy_coo[i].xmove = speed + (i%2)*2*(-speed);
xy_coo[i].ymove = speed + (i%2)*2*(-speed);
}
+
}
/* example: initializes a "see-trough" matrix */
}
}
*/
+static void convert(void) {
+ int *p;
+ int i, j;
+ fast_from = calloc(1, sizeof(int)*((buffer_map->bytes_per_line/bpp_size)*(2*radius+speed+2) + 2*radius+speed+2));
+ if (fast_from == NULL) {
+ perror("distort");
+ exit(EXIT_FAILURE);
+ }
+ p = fast_from;
+ for (i = 0; i < 2*radius+speed+2; i++) {
+ for (j = 0; j < 2*radius+speed+2; j++) {
+ *(p + i + j*buffer_map->bytes_per_line/bpp_size)
+ = from[i][j][0] + xgwa.width*from[i][j][1];
+ if (*(p + i + j*buffer_map->bytes_per_line/bpp_size) < 0
+ || *(p + i + j*buffer_map->bytes_per_line/bpp_size) >= orig_map->height*orig_map->width) {
+ *(p + i + j*buffer_map->bytes_per_line/bpp_size) = 0;
+ }
+ }
+ }
+}
/* makes a lense with the Radius=loop and centred in
* the point (radius, radius)
int i, j;
for (i = 0; i < 2*radius+speed+2; i++) {
- for(j = 0; j < 2*radius+speed+2; j++) {
+ for(j = 0; j < ((0 == bpp_size) ? (2*radius+speed+2) : (buffer_map->bytes_per_line/bpp_size)); j++) {
double r, d;
r = sqrt ((i-radius)*(i-radius)+(j-radius)*(j-radius));
if (loop == 0)
* (with permission) from the whirl plugin for gimp,
* Copyright (C) 1996 Federico Mena Quintero
*/
- /* 2.5 is just a constant used because it looks good :) */
- angle = 2.5*(1-d)*(1-d);
+ /* 5 is just a constant used because it looks good :) */
+ angle = 5*(1-d)*(1-d);
/* Avoid atan2: DOMAIN error message */
if ((radius-j) == 0.0 && (radius-i) == 0.0) {
from[i][j][0] = radius + cos(angle)*r;
from[i][j][1] = radius + sin(angle)*r;
} else {
- from[i][j][0] = radius +
- cos(angle - atan2(radius-j, -(radius-i)))*r;
- from[i][j][1] = radius +
- sin(angle - atan2(radius-j, -(radius-i)))*r;
+ from[i][j][0] = radius +
+ cos(angle - atan2(radius-j, -(radius-i)))*r;
+ from[i][j][1] = radius +
+ sin(angle - atan2(radius-j, -(radius-i)))*r;
}
if (magnify) {
r = sin(d*M_PI_2);
}
}
}
+
+ /* this is really just a quick hack to keep both the compability mode with all depths and still
+ * allow the custom optimized draw routines with the minimum amount of work */
+ if (0 != bpp_size) {
+ convert();
+ }
}
#ifndef EXIT_FAILURE
static void allocate_lense(void)
{
int i, j;
+ int s = ((0 != bpp_size) ? (buffer_map->bytes_per_line/bpp_size) : (2*radius+speed+2));
/* maybe this should be redone so that from[][][] is in one block;
* then pointers could be used instead of arrays in some places (and
* maybe give a speedup - maybe also consume less memory)
*/
-
- from = (int ***)malloc((2*radius+speed+2) * sizeof(int **));
+ from = (int ***)malloc(s*sizeof(int **));
if (from == NULL) {
perror("distort");
exit(EXIT_FAILURE);
}
- for (i = 0; i < 2*radius+speed+2; i++) {
+ for (i = 0; i < s; i++) {
from[i] = (int **)malloc((2*radius+speed+2) * sizeof(int *));
if (from[i] == NULL) {
perror("distort");
exit(EXIT_FAILURE);
}
- for (j = 0; j < 2*radius+speed+2; j++) {
+ for (j = 0; j < s; j++) {
from[i][j] = (int *)malloc(2 * sizeof(int));
if (from[i][j] == NULL) {
perror("distort");
}
}
+/* If fast_draw_8, fast_draw_16 or fast_draw_32 are to be used, the following properties
+ * of the src and dest XImages must hold (otherwise the generic, slooow, method provided
+ * by X is to be used):
+ * src->byte_order == dest->byte_order
+ * src->format == ZPixmap && dest->format == ZPixmap
+ * src->depth == dest->depth == the depth the function in question asumes
+ * x and y is the coordinates in src from where to cut out the image from,
+ * distort_matrix is a precalculated array of how to distort the matrix
+ */
+
+static void fast_draw_8(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ CARD8 *u = (CARD8 *)dest->data;
+ CARD8 *t = (CARD8 *)src->data + x + y*src->bytes_per_line/sizeof(CARD8);
+
+ while (u < (CARD8 *)(dest->data + sizeof(CARD8)*dest->height
+ *dest->bytes_per_line/sizeof(CARD8))) {
+ *u++ = t[*distort_matrix++];
+ }
+}
+
+static void fast_draw_16(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ CARD16 *u = (CARD16 *)dest->data;
+ CARD16 *t = (CARD16 *)src->data + x + y*src->bytes_per_line/sizeof(CARD16);
+
+ while (u < (CARD16 *)(dest->data + sizeof(CARD16)*dest->height
+ *dest->bytes_per_line/sizeof(CARD16))) {
+ *u++ = t[*distort_matrix++];
+ }
+}
+
+static void fast_draw_32(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ CARD32 *u = (CARD32 *)dest->data;
+ CARD32 *t = (CARD32 *)src->data + x + y*src->bytes_per_line/sizeof(CARD32);
+
+ while (u < (CARD32 *)(dest->data + sizeof(CARD32)*dest->height
+ *dest->bytes_per_line/sizeof(CARD32))) {
+ *u++ = t[*distort_matrix++];
+ }
+}
+
+static void generic_draw(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ int i, j;
+ for (i = 0; i < dest->width; i++)
+ for (j = 0; j < dest->height; j++)
+ if (from[i][j][0] + x >= 0 &&
+ from[i][j][0] + x < src->width &&
+ from[i][j][1] + y >= 0 &&
+ from[i][j][1] + y < src->height)
+ XPutPixel(dest, i, j,
+ XGetPixel(src,
+ from[i][j][0] + x,
+ from[i][j][1] + y));
+}
/* generate an XImage of from[][][] and draw it on the screen */
static void plain_draw(int k)
{
- int i, j;
- for(i = 0 ; i < 2*radius+speed+2; i++) {
- for(j = 0 ; j < 2*radius+speed+2 ; j++) {
- if (xy_coo[k].x+from[i][j][0] >= 0 &&
- xy_coo[k].x+from[i][j][0] < xgwa.width &&
- xy_coo[k].y+from[i][j][1] >= 0 &&
- xy_coo[k].y+from[i][j][1] < xgwa.height)
- XPutPixel(buffer_map, i, j,
- XGetPixel(orig_map,
- xy_coo[k].x+from[i][j][0],
- xy_coo[k].y+from[i][j][1]));
- }
- }
+ if (xy_coo[k].x+2*radius+speed+2 > orig_map->width ||
+ xy_coo[k].y+2*radius+speed+2 > orig_map->height)
+ return;
+
+ draw_routine(orig_map, buffer_map, xy_coo[k].x, xy_coo[k].y, fast_from);
+
+# ifdef HAVE_XSHM_EXTENSION
+ if (use_shm)
+ XShmPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
+ 2*radius+speed+2, 2*radius+speed+2, False);
+ else
+# endif
+
+ if (!use_shm)
+ XPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
+ 2*radius+speed+2, 2*radius+speed+2);
- XPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y,
- 2*radius+speed+2, 2*radius+speed+2);
}
+
/* generate an XImage from the reflect algoritm submitted by
* Randy Zack <randy@acucorp.com>
* draw really got too big and ugly so I split it up
xy_coo[k].x = xy_coo[k].x + xy_coo[k].xmove;
xy_coo[k].y = xy_coo[k].y + xy_coo[k].ymove;
+ /* bounce against othe lenses */
for (i = 0; i < number; i++) {
if ((i != k)
"*visualID: Best",
#endif
- "*delay: 10000",
+ "*delay: 1000",
"*radius: 0",
"*speed: 0",
"*number: 0",
{ "-vortex", ".vortex", XrmoptionNoArg, "True" },
{ "-magnify", ".magnify", XrmoptionNoArg, "True" },
{ "-blackhole", ".blackhole", XrmoptionNoArg, "True" },
+ { "-slow", ".slow", XrmoptionNoArg, "True" },
#ifdef HAVE_XSHM_EXTENSION
{ "-shm", ".useSHM", XrmoptionNoArg, "True" },
{ "-no-shm", ".useSHM", XrmoptionNoArg, "False" },
-/* -*- Mode: C; tab-width: 4 -*-
- * forest.c --- draw a fractal forest.
- */
-#if !defined( lint ) && !defined( SABER )
-static const char sccsid[] = "@(#)forest.c 4.03 97/05/10 xlockmore";
-#endif
-
-/* Copyright (c) 1995 Pascal Pensa <pensa@aurora.unice.fr>
- *
- * Original idea : Guillaume Ramey <ramey@aurora.unice.fr>
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
+/* forest.c (aka xtree.c), Copyright (c) 1999
+ * Peter Baumung <unn6@rz.uni-karlsruhe.de>
*
- * This file is provided AS IS with no warranties of any kind. The author
- * shall have no liability with respect to the infringement of copyrights,
- * trade secrets or any patents by this file or any part thereof. In no
- * event will the author be liable for any lost revenue or profits or
- * other special, indirect and consequential damages.
+ * Most code taken from
+ * xscreensaver, Copyright (c) 1992, 1995, 1997
+ * Jamie Zawinski <jwz@netscape.com>
*
- * Revision History:
- * 10-May-97: Compatible with xscreensaver
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
*/
+#include "config.h"
+
#ifdef STANDALONE
-# define PROGCLASS "Forest"
-# define HACK_INIT init_forest
-# define HACK_DRAW draw_forest
-# define forest_opts xlockmore_opts
-# define DEFAULTS "*count: 100 \n" \
- "*cycles: 200 \n" \
- "*delay: 400000 \n" \
- "*ncolors: 100 \n"
-# define UNIFORM_COLORS
-# include "xlockmore.h" /* from the xscreensaver distribution */
-# include "erase.h"
+# define PROGCLASS "Forest" /*"XTree"*/
+# define HACK_INIT init_trees
+# define HACK_DRAW draw_trees
+# define trees_opts xlockmore_opts
+# define DEFAULTS "*delay: 500000 \n" \
+ "*ncolors: 20 \n" \
+ "*eraseSpeed: 400 \n" \
+ "*eraseMode: -1 \n" \
+ "*installColormap False"
+# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
# include "xlock.h" /* from the xlockmore distribution */
#endif /* !STANDALONE */
-ModeSpecOpt forest_opts = {
- 0, NULL, 0, NULL, NULL };
-
-
-#define MINTREES 1
-
-#define MINHEIGHT 20 /* Tree height range */
-#define MAXHEIGHT 40
-
-#define MINANGLE 15 /* (degree) angle between soon */
-#define MAXANGLE 35
-#define RANDANGLE 15 /* (degree) Max random angle from default */
-
-#define REDUCE 90 /* Height % from father */
-
-#define ITERLEVEL 10 /* Tree iteration */
-
-#define COLORSPEED 2 /* Color increment */
-
-/* degree to radian */
-#define DEGTORAD(x) (((float)(x)) * M_PI / 180.0)
-
-#define RANGE_RAND(min,max) ((min) + NRAND((max) - (min)))
+ModeSpecOpt trees_opts = {0, NULL, 0, NULL, NULL};
typedef struct {
- int width;
- int height;
- int time; /* up time */
- int ntrees;
-} foreststruct;
-
-static foreststruct *forests = NULL;
-
-static void
-draw_tree(ModeInfo * mi,
- short int x, short int y, short int len,
- float a, float as, short int c, short int level)
- /* Father's end */
- /* Length */
- /* color */
- /* Height level */
- /* Father's angle */
- /* Father's angle step */
-{
- Display *display = MI_DISPLAY(mi);
- Window window = MI_WINDOW(mi);
- GC gc = MI_GC(mi);
- short x_1, y_1, x_2, y_2;
- float a1, a2;
-
- /* left */
-
- a1 = a + as + DEGTORAD(NRAND(2 * RANDANGLE) - RANDANGLE);
-
- x_1 = x + (short) (COSF(a1) * ((float) len));
- y_1 = y + (short) (SINF(a1) * ((float) len));
-
- /* right */
-
- a2 = a - as + DEGTORAD(NRAND(2 * RANDANGLE) - RANDANGLE);
-
- x_2 = x + (short) (COSF(a2) * ((float) len));
- y_2 = y + (short) (SINF(a2) * ((float) len));
-
- if (MI_NPIXELS(mi) > 2) {
- XSetForeground(display, gc, MI_PIXEL(mi, c));
- c = (c + COLORSPEED) % MI_NPIXELS(mi);
- } else
- XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
-
- XDrawLine(display, window, gc, x, y, x_1, y_1);
- XDrawLine(display, window, gc, x, y, x_2, y_2);
-
- if (level < 2) {
- XDrawLine(display, window, gc, x + 1, y, x_1 + 1, y_1);
- XDrawLine(display, window, gc, x + 1, y, x_2 + 1, y_2);
- }
- len = (len * REDUCE * 10) / 1000;
-
- if (level < ITERLEVEL) {
- draw_tree(mi, x_1, y_1, len, a1, as, c, level + 1);
- draw_tree(mi, x_2, y_2, len, a2, as, c, level + 1);
- }
+ int x;
+ int y;
+ int thick;
+ double size;
+ long color;
+ int toDo;
+ int season;
+} treestruct;
+
+static treestruct *trees = NULL;
+
+XColor colors[20];
+int color;
+
+static long colorM[12] = {0xff0000, 0xff8000, 0xffff00, 0x80ff00,
+ 0x00ff00, 0x00ff80, 0x00ffff, 0x0080ff,
+ 0x0000ff, 0x8000ff, 0xff00ff, 0xff0080};
+
+static long colorV[12] = {0x0a0000, 0x0a0500, 0x0a0a00, 0x050a00,
+ 0x000a00, 0x000a05, 0x000a0a, 0x00050a,
+ 0x00000a, 0x05000a, 0x0a000a, 0x0a0005};
+
+void init_trees(ModeInfo * mi) {
+ unsigned long pixels[20];
+ treestruct *tree;
+ Display *display = MI_DISPLAY(mi);
+ GC gc = MI_GC(mi);
+ int i;
+
+ if (trees == NULL) {
+ trees = (treestruct *) calloc(MI_NUM_SCREENS(mi), sizeof (treestruct));
+ if (trees == NULL) {
+ return;
+ }
+
+ if (mi->npixels > 20) {
+ printf("%d colors selected. Setting limit to 20...\n", mi->npixels);
+ mi->npixels = 20;
+ }
+
+ if (mi->npixels < 4) {
+ for (i = 0; i < mi->npixels; i++) {
+ colors[i].red = 65535 * (i & 1);
+ colors[i].green = 65535 * (i & 1);
+ colors[i].blue = 65535 * (i & 1);
+ colors[i].flags = DoRed | DoGreen | DoBlue;
+ }
+ } else {
+ if (mi->npixels < 8) {
+ for (i = 0; i < mi->npixels; i++) {
+ colors[i].red = 32768 + 4096 * (i % 4);
+ colors[i].green = 32768 + 4096 * (i % 4);
+ colors[i].blue = 32768 + 4096 * (i % 4);
+ colors[i].flags = DoRed | DoGreen | DoBlue;
+ }
+ } else {
+ for (i = 0; i < mi->npixels; i++) {
+ colors[i].red = 24576 + 4096 * (i % 4);
+ colors[i].green = 10240 + 2048 * (i % 4);
+ colors[i].blue = 0;
+ colors[i].flags = DoRed | DoGreen | DoBlue;
+ }
+ }
+ }
+
+ for (i = 0; i < mi->npixels; i++)
+ if (!XAllocColor(display, mi->xgwa.colormap, &colors[i])) break;
+ color = i;
+
+ XSetForeground(display, gc, colors[1].pixel);
+ }
+
+ XClearWindow(display, MI_WINDOW(mi));
+ XSetLineAttributes(display, gc, 2, LineSolid, CapButt, JoinMiter);
+ tree = &trees[MI_SCREEN(mi)];
+ tree->toDo = 25;
+ tree->season = NRAND(12);
+
+ for (i = 4; i < mi->npixels; i++) {
+ int sIndex = (tree->season + (i-4) / 4) % 12;
+ long color = colorM[sIndex] - 2 * colorV[sIndex] * (i % 4);
+ colors[i].red = (color & 0xff0000) / 256;
+ colors[i].green = (color & 0x00ff00);
+ colors[i].blue = (color & 0x0000ff) * 256;
+ colors[i].flags = DoRed | DoGreen | DoBlue;
+ }
+
+ for (i = 0; i < color; i++)
+ pixels[i] = colors[i].pixel;
+
+ XFreeColors(display, mi->xgwa.colormap, pixels, mi->npixels, 0L);
+
+ for (i = 0; i < mi->npixels; i++)
+ if (!XAllocColor(display, mi->xgwa.colormap, &colors[i])) break;
+
+ color = i;
}
-void
-init_forest(ModeInfo * mi)
-{
- foreststruct *fp;
-
- if (forests == NULL) {
- if ((forests = (foreststruct *) calloc(MI_NUM_SCREENS(mi),
- sizeof (foreststruct))) == NULL)
- return;
- }
- fp = &forests[MI_SCREEN(mi)];
-
- fp->width = MI_WIN_WIDTH(mi);
- fp->height = MI_WIN_HEIGHT(mi);
- fp->time = 0;
-
- fp->ntrees = MI_BATCHCOUNT(mi);
- if (fp->ntrees < -MINTREES)
- fp->ntrees = NRAND(-fp->ntrees - MINTREES + 1) + MINTREES;
- else if (fp->ntrees < MINTREES)
- fp->ntrees = MINTREES;
- XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
+double rRand(double a, double b) {
+ return (a+(b-a)*NRAND(10001)/10000.0);
}
-void
-draw_forest(ModeInfo * mi)
-{
- Display *display = MI_DISPLAY(mi);
- GC gc = MI_GC(mi);
- foreststruct *fp = &forests[MI_SCREEN(mi)];
- short x, y, x_2, y_2, len, c = 0;
- float a, as;
-
- if (fp->time < fp->ntrees) {
-
- x = RANGE_RAND(0, fp->width);
- y = RANGE_RAND(0, fp->height + MAXHEIGHT);
- a = -M_PI / 2.0 + DEGTORAD(NRAND(2 * RANDANGLE) - RANDANGLE);
- as = DEGTORAD(RANGE_RAND(MINANGLE, MAXANGLE));
- len = ((RANGE_RAND(MINHEIGHT, MAXHEIGHT) * (fp->width / 20)) / 50) + 2;
-
- if (MI_NPIXELS(mi) > 2) {
- c = NRAND(MI_NPIXELS(mi));
- XSetForeground(display, gc, MI_PIXEL(mi, c));
- c = (c + COLORSPEED) % MI_NPIXELS(mi);
- } else
- XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
-
- x_2 = x + (short) (COSF(a) * ((float) len));
- y_2 = y + (short) (SINF(a) * ((float) len));
-
- XDrawLine(display, MI_WINDOW(mi), gc, x, y, x_2, y_2);
- XDrawLine(display, MI_WINDOW(mi), gc, x + 1, y, x_2 + 1, y_2);
-
- draw_tree(mi, x_2, y_2, (len * REDUCE) / 100, a, as, c, 1);
- }
- if (++fp->time > MI_CYCLES(mi)) {
-#ifdef STANDALONE
- erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
-#endif /* STANDALONE */
- init_forest(mi);
- }
+void draw_line(ModeInfo * mi,
+ int x1, int y1, int x2, int y2,
+ double angle, int widths, int widthe) {
+
+ Display *display = MI_DISPLAY(mi);
+ GC gc = MI_GC(mi);
+ double sns = 0.5*widths*sin(angle + M_PI_2);
+ double css = 0.5*widths*cos(angle + M_PI_2);
+ double sne = 0.5*widthe*sin(angle + M_PI_2);
+ double cse = 0.5*widthe*cos(angle + M_PI_2);
+
+ int xs1 = (int) (x1-sns);
+ int xs2 = (int) (x1+sns);
+ int ys1 = (int) (y1-css);
+ int ys2 = (int) (y1+css);
+ int xe1 = (int) (x2-sne);
+ int xe2 = (int) (x2+sne);
+ int ye1 = (int) (y2-cse);
+ int ye2 = (int) (y2+cse);
+ int i;
+
+ for (i = 0; i < widths; i++) {
+ if (color >= 4)
+ XSetForeground(display, gc, colors[i*4/widths].pixel);
+ XDrawLine(display, MI_WINDOW(mi), gc,
+ xs1+(xs2-xs1)*i/widths, ys1+(ys2-ys1)*i/widths,
+ xe1+(xe2-xe1)*i/widths, ye1+(ye2-ye1)*i/widths);
+ }
}
-void
-release_forest(ModeInfo * mi)
-{
- if (forests != NULL) {
- (void) free((void *) forests);
- forests = NULL;
- }
+void draw_tree_rec(ModeInfo * mi, double thick, int x, int y, double angle) {
+ treestruct *tree = &trees[MI_SCREEN(mi)];
+ Display *display = MI_DISPLAY(mi);
+ GC gc = MI_GC(mi);
+ int length = (24+NRAND(12))*tree->size;
+ int a = (int) (x - length*sin(angle));
+ int b = (int) (y - length*cos(angle));
+ int i;
+
+ draw_line(mi, x, y, a, b, angle, thick*tree->size, 0.68*thick*tree->size);
+
+ if (thick > 2) {
+ draw_tree_rec(mi, 0.68*thick, a, b, 0.8*angle+rRand(-0.2, 0.2));
+ if (thick < tree->thick-1) {
+ draw_tree_rec(mi, 0.68*thick, a, b, angle+rRand(0.2, 0.9));
+ draw_tree_rec(mi, 0.68*thick, (a+x)/2, (b+y)/2, angle-rRand(0.2, 0.9));
+ }
+ }
+
+ if (thick < 0.5*tree->thick) {
+ int nleaf = 12 + NRAND(4);
+ XArc leaf[16];
+ for (i = 0; i < nleaf; i++) {
+ leaf[i].x = a + (int) (tree->size * rRand(-12, 12));
+ leaf[i].y = b + (int) (tree->size * rRand(-12, 12));
+ leaf[i].width = (int) (tree->size * rRand(2, 6));
+ leaf[i].height = leaf[i].width;
+ leaf[i].angle1 = 0;
+ leaf[i].angle2 = 360 * 64;
+ }
+ if (mi->npixels >= 4)
+ XSetForeground(display, gc, colors[tree->color+NRAND(4)].pixel);
+ XFillArcs(display, MI_WINDOW(mi), gc, leaf, nleaf);
+ }
}
-void
-refresh_forest(ModeInfo * mi)
-{
- foreststruct *fp = &forests[MI_SCREEN(mi)];
+void draw_trees(ModeInfo * mi) {
+ treestruct *tree = &trees[MI_SCREEN(mi)];
+ int width = MI_WIN_WIDTH(mi);
+ int height = MI_WIN_HEIGHT(mi);
+
+ if (--(tree->toDo) == 0) {
+ usleep(3000000);
+ init_trees(mi);
+ }
+
+ tree->x = NRAND(width);
+ tree->y = (int) (1.25 * height * (1 - tree->toDo / 23.0));
+ tree->thick = rRand(7, 12);
+ tree->size = height / 480.0;
+ if (color < 8) {
+ tree->color = 0;
+ } else {
+ tree->color = 4 * (1 + NRAND(color / 4 - 1));
+ }
+
+ draw_tree_rec(mi, tree->thick, tree->x, tree->y, rRand(-0.1, 0.1));
+}
- if (fp->time < fp->ntrees)
- XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
- else
- init_forest(mi);
+void release_trees(ModeInfo * mi) {
+ if (trees != NULL) {
+ (void) free((void *) trees);
+ trees = NULL;
+ }
}
* 10-May-97: jwz@jwz.org: turned into a standalone program.
* 18-Apr-97: Memory leak fixed by Tom Schmidt <tschmidt@micron.com>
* 07-Apr-97: Modified by Dave Mitchell <davem@magnet.com>
- * 23-Oct-94: Modified by David Bagley <bagleyd@bigfoot.com>
- * random star sizes
- * colors change depending on velocity
+ * random star sizes
+ * colors change depending on velocity
+ * 23-Oct-94: Modified by David Bagley <bagleyd@tux.org>
* 10-Oct-94: Add colors by Hubert Feyer
* 30-Sep-94: Initial port by Hubert Feyer
* 09-Mar-94: VMS can generate a random number 0.0 which results in a
* division by zero, corrected by Jouk Jansen
- * <joukj@crys.chem.uva.nl>
+ * <joukj@hrem.stm.tudelft.nl>
*/
#ifdef STANDALONE
}
void
-DisplaySproingies(int screen)
+DisplaySproingies(int screen,int pause)
{
sp_instance *si = &si_list[screen];
int t;
}
void
-NextSproingieDisplay(int screen)
+NextSproingieDisplay(int screen,int pause)
{
NextSproingie(screen);
- DisplaySproingies(screen);
+ if (pause) usleep(pause);
+ DisplaySproingies(screen,pause);
}
#if 0
# define HACK_INIT init_sproingies
# define HACK_DRAW draw_sproingies
# define sproingies_opts xlockmore_opts
-# define DEFAULTS "*delay: 100 \n" \
+# define DEFAULTS "*delay: 0 \n" \
"*count: 5 \n" \
"*cycles: 0 \n" \
"*size: 0 \n" \
#include <time.h>
void NextSproingie(int screen);
-void NextSproingieDisplay(int screen);
-void DisplaySproingies(int screen);
+void NextSproingieDisplay(int screen,int pause);
+void DisplaySproingies(int screen,int pause);
#if 0
void ReshapeSproingies(int w, int h);
swap_display = display;
swap_window = window;
- DisplaySproingies(MI_SCREEN(mi));
+ DisplaySproingies(MI_SCREEN(mi),mi->pause);
} else {
MI_CLEARWINDOW(mi);
}
swap_display = display;
swap_window = window;
- NextSproingieDisplay(MI_SCREEN(mi)); /* It will swap. */
+ NextSproingieDisplay(MI_SCREEN(mi),mi->pause); /* It will swap. */
}
void
-
-/**************************************************************************
- *
- * FILE lmorph.c
- * MODULE OF xscreensaver
- *
- * DESCRIPTION Bilinear interpolation for morphing line shapes.
- *
- * WRITTEN BY Sverre H. Huseby Glenn T. Lines
- * Kurvn. 30 Østgaardsgt. 5
- * N-0495 Oslo N-0474 Oslo
- * Norway Norway
- *
- * Phone: +47 901 63 579 Phone: +47 22 04 67 28
- * E-mail: sverrehu@online.no E-mail: gtl@si.sintef.no
- * URL: http://home.sol.no/~sverrehu/
- *
- * The original idea, and the bilinear interpolation
- * mathematics used, emerged in the head of the wise
- * Glenn T. Lines.
- *
- * MODIFICATIONS june 1998 (shh)
- * * Minor code cleanup.
- *
- * march 1997 (shh)
- * * Added -mailfile option to allow checking for
- * new mail while the screensaver is active.
- *
- * january 1997 (shh)
- * * Some code reformatting.
- * * Added possibility to use float arithmetic.
- * * Added -figtype option.
- * * Made color blue default.
+/* lmorph, Copyright (c) 1993-1999 Sverre H. Huseby and Glenn T. Lines
*
- * december 1995 (jwz)
- * * Function headers converted from ANSI to K&R.
- * * Added posibility for random number of steps, and
- * made this the default.
- *
- * march 1995 (shh)
- * * Converted from an MS-Windows program to X Window.
- *
- **************************************************************************/
+ * 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.
+ */
+
+/*------------------------------------------------------------------------
+ |
+ | FILE lmorph.c
+ | MODULE OF xscreensaver
+ |
+ | DESCRIPTION Smooth and non-linear morphing between 1D curves.
+ |
+ | WRITTEN BY Sverre H. Huseby Glenn T. Lines
+ | Kurvn. 30 Østgaardsgt. 5
+ | N-0495 Oslo N-0474 Oslo
+ | Norway Norway
+ |
+ | Phone: +47 901 63 579 Phone: +47 22 04 67 28
+ | E-mail: sverrehu@online.no E-mail: glennli@ifi.uio.no
+ | URL: http://home.sol.no/~sverrehu/
+ |
+ | The original idea, and the bilinear interpolation
+ | mathematics used, emerged in the head of the wise
+ | Glenn T. Lines.
+ |
+ | MODIFICATIONS october 1999 (shh)
+ | * Removed option to use integer arithmetic.
+ | * Increased default number of points, and brightened
+ | the foreground color a little bit.
+ | * Minor code cleanup (very minor, that is).
+ | * Default number of steps is no longer random.
+ | * Added -linewidth option (and resource).
+ |
+ | october 1999 (gtl)
+ | * Added cubic interpolation between shapes
+ | * Added non-linear transformation speed
+ |
+ | june 1998 (shh)
+ | * Minor code cleanup.
+ |
+ | january 1997 (shh)
+ | * Some code reformatting.
+ | * Added possibility to use float arithmetic.
+ | * Added -figtype option.
+ | * Made color blue default.
+ |
+ | december 1995 (jwz)
+ | * Function headers converted from ANSI to K&R.
+ | * Added posibility for random number of steps, and
+ | made this the default.
+ |
+ | march 1995 (shh)
+ | * Converted from an MS-Windows program to X Window.
+ |
+ | november 1993 (gtl, shh, lots of beer)
+ | * Original Windows version (we didn't know better).
+ +----------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "screenhack.h"
-/**************************************************************************
- * *
- * P R I V A T E D A T A *
- * *
- **************************************************************************/
+/*-----------------------------------------------------------------------+
+| PRIVATE DATA |
++-----------------------------------------------------------------------*/
/* define MARGINS to make some space around the figure. */
#define MARGINS
-/* define USE_FLOAT to avoid using integer calculations in
- createPoints. integer calculation is supposed to be faster, but it
- won't work for displays larger than 2048x2048 or so pixels. */
-#undef USE_FLOAT
-
#define MAXFIGS 20
#define TWO_PI (2.0 * M_PI)
#define RND(x) (random() % (x))
nWork, /* current work array number. */
nFrom, /* current from array number. */
nTo, /* current to array number. */
+ nNext, /* current next array number (after to).*/
+ shift, /* shifts the starting point of a figure */
figType;
static long delay; /* usecs to wait between updates. */
static XPoint
*aPrev, /* previous points displayed. */
*aCurr, /* the current points displayed. */
*aFrom, /* figure converting from. */
- *aTo; /* figure converting to. */
+ *aTo, /* figure converting to. */
+ *aNext, /* figure converting to next time. */
+ *aSlopeFrom, /* slope at start of morph */
+ *aSlopeTo; /* slope at end of morph */
static int scrWidth, scrHeight;
static double currGamma, maxGamma = 1.0, deltaGamma;
static GC gcDraw, gcClear;
static Display *dpy;
static Window window;
-
-
-/**************************************************************************
- * *
- * P U B L I C D A T A *
- * *
- **************************************************************************/
+/*-----------------------------------------------------------------------+
+| PUBLIC DATA |
++-----------------------------------------------------------------------*/
char *progclass = "LMorph";
char *defaults [] = {
".background: black",
- ".foreground: blue",
- "*points: 150",
- "*steps: 0",
- "*delay: 50000",
+ ".foreground: #4444FF",
+ "*points: 200",
+ "*steps: 150",
+ "*delay: 70000",
"*figtype: all",
+ "*linewidth: 5",
0
};
XrmOptionDescRec options [] = {
- { "-points", ".points", XrmoptionSepArg, 0 },
- { "-steps", ".steps", XrmoptionSepArg, 0 },
- { "-delay", ".delay", XrmoptionSepArg, 0 },
- { "-figtype", ".figtype", XrmoptionSepArg, 0 },
- { 0, 0, 0, 0 }
+ { "-points", ".points", XrmoptionSepArg, 0 },
+ { "-steps", ".steps", XrmoptionSepArg, 0 },
+ { "-delay", ".delay", XrmoptionSepArg, 0 },
+ { "-figtype", ".figtype", XrmoptionSepArg, 0 },
+ { "-linewidth", ".linewidth", XrmoptionSepArg, 0 },
+ { 0, 0, 0, 0 }
};
int options_size = (sizeof (options) / sizeof (options[0]));
-
-
-/**************************************************************************
- * *
- * P R I V A T E F U N C T I O N S *
- * *
- **************************************************************************/
+/*-----------------------------------------------------------------------+
+| PRIVATE FUNCTIONS |
++-----------------------------------------------------------------------*/
static void *
xmalloc(size_t size)
static void
initPointArrays(void)
{
- int q, w,
- mx, my, /* max screen coordinates. */
- mp, /* max point number. */
- s, rx, ry,
- marginx, marginy;
+ int q, w;
+ int mx, my; /* max screen coordinates. */
+ int mp; /* max point number. */
+ int s, rx, ry;
+ int marginx, marginy;
double scalex, scaley;
mx = scrWidth - 1;
a[numFigs][mp].y = a[numFigs][0].y;
++numFigs;
- /* */
+
+ /* */
a[numFigs] = (XPoint *) xmalloc(numPoints * sizeof(XPoint));
rx = mx / 2;
ry = my / 2;
a[numFigs][mp].y = a[numFigs][0].y;
++numFigs;
+
/* */
a[numFigs] = (XPoint *) xmalloc(numPoints * sizeof(XPoint));
rx = mx / 2;
XWindowAttributes wa;
Colormap cmap;
char *ft;
-
+ int i;
+
numPoints = get_integer_resource("points", "Integer");
steps = get_integer_resource("steps", "Integer");
delay = get_integer_resource("delay", "Integer");
aPrev = NULL;
currGamma = maxGamma + 1.0; /* force creation of new figure at startup */
nTo = RND(numFigs);
+ do {
+ nNext = RND(numFigs);
+ } while (nNext == nTo);
+
+ aSlopeTo = (XPoint *) xmalloc(numPoints * sizeof(XPoint));
+ aSlopeFrom = (XPoint *) xmalloc(numPoints * sizeof(XPoint));
+ aNext = (XPoint *) xmalloc(numPoints * sizeof(XPoint));
+
+ for (i = 0; i < numPoints ; i++) {
+ aSlopeTo[i].x = 0.0;
+ aSlopeTo[i].y = 0.0;
+ }
- { /* jwz for version 2.11 */
- int width = random() % 10;
- int style = LineSolid;
- int cap = (width > 1 ? CapRound : CapButt);
- int join = (width > 1 ? JoinRound : JoinBevel);
- if (width == 1) width = 0;
- XSetLineAttributes(dpy, gcDraw, width, style, cap, join);
- XSetLineAttributes(dpy, gcClear, width, style, cap, join);
+ { /* jwz for version 2.11 */
+ /* int width = random() % 10;*/
+ int width = get_integer_resource("linewidth", "Integer");
+ int style = LineSolid;
+ int cap = (width > 1 ? CapRound : CapButt);
+ int join = (width > 1 ? JoinRound : JoinBevel);
+ if (width == 1)
+ width = 0;
+ XSetLineAttributes(dpy, gcDraw, width, style, cap, join);
+ XSetLineAttributes(dpy, gcClear, width, style, cap, join);
}
}
static void
createPoints(void)
{
- int q;
+ int q;
XPoint *pa = aCurr, *pa1 = aFrom, *pa2 = aTo;
-#ifdef USE_FLOAT
- float fg, f1g;
-#else
- long lg, l1g;
-#endif
+ XPoint *qa1 = aSlopeFrom, *qa2 = aSlopeTo;
+ float fg, f1g;
+ float speed;
-#ifdef USE_FLOAT
fg = currGamma;
f1g = 1.0 - currGamma;
-#else
- lg = 8192L * currGamma;
- l1g = 8192L * (1.0 - currGamma);
-#endif
for (q = numPoints; q; q--) {
-#ifdef USE_FLOAT
- pa->x = (short) (f1g * pa1->x + fg * pa2->x);
- pa->y = (short) (f1g * pa1->y + fg * pa2->y);
-#else
- pa->x = (short) ((l1g * pa1->x + lg * pa2->x) / 8192L);
- pa->y = (short) ((l1g * pa1->y + lg * pa2->y) / 8192L);
-#endif
+ speed = 0.45 * sin(TWO_PI * (double) (q + shift) / (numPoints - 1));
+ fg = currGamma + 1.67 * speed
+ * exp(-200.0 * (currGamma - 0.5 + 0.7 * speed)
+ * (currGamma - 0.5 + 0.7 * speed));
+
+ f1g = 1.0 - fg;
+ pa->x = (short) (f1g * f1g * f1g * pa1->x + f1g * f1g * fg
+ * (3 * pa1->x + qa1->x) + f1g * fg * fg
+ * (3 * pa2->x - qa2->x) + fg * fg * fg * pa2->x);
+ pa->y = (short) (f1g * f1g * f1g * pa1->y + f1g * f1g * fg
+ * (3 * pa1->y + qa1->y) + f1g * fg * fg
+ * (3 * pa2->y - qa2->y) + fg * fg * fg * pa2->y);
+
++pa;
++pa1;
++pa2;
+ ++qa1;
+ ++qa2;
}
}
static void
drawImage(void)
{
- int q;
+ int q;
XPoint *old0, *old1, *new0, *new1;
/* Problem: update the window without too much flickering. I do
* this by handling each linesegment separately. First remove a
* line, then draw the new line. The problem is that this leaves
- * small black pixels on the figure. To fix this, I draw the
+ * small black pixels on the figure. To fix this, we draw the
* entire figure using XDrawLines() afterwards. */
if (aPrev) {
old0 = aPrev;
new0 = aCurr;
new1 = aCurr + 1;
for (q = numPoints - 1; q; q--) {
- XDrawLine(dpy, window, gcClear,
- old0->x, old0->y, old1->x, old1->y);
+ XDrawLine(dpy, window, gcClear,
+ old0->x, old0->y, old1->x, old1->y);
XDrawLine(dpy, window, gcDraw,
new0->x, new0->y, new1->x, new1->y);
++old0;
static void
animateLMorph(void)
{
+ int i;
if (currGamma > maxGamma) {
currGamma = 0.0;
- if (maxGamma == 1.0) {
- nFrom = nTo;
- aFrom = a[nFrom];
- } else {
- memcpy(aTmp, aCurr, numPoints * sizeof(XPoint));
- aFrom = aTmp;
- nFrom = -1;
- }
+ nFrom = nTo;
+ nTo = nNext;
+ aFrom = a[nFrom];
+ aTo = a[nTo];
do {
- nTo = RND(numFigs);
- } while (nTo == nFrom);
- aTo = a[nTo];
+ nNext = RND(numFigs);
+ } while (nNext == nTo);
+ aNext = a[nNext];
+
+ shift = RND(numPoints);
if (RND(2)) {
/* reverse the array to get more variation. */
int i1, i2;
XPoint p;
for (i1 = 0, i2 = numPoints - 1; i1 < numPoints / 2; i1++, i2--) {
- p = aTo[i1];
- aTo[i1] = aTo[i2];
- aTo[i2] = p;
+ p = aNext[i1];
+ aNext[i1] = aNext[i2];
+ aNext[i2] = p;
}
}
- /* occationally interrupt the next run. */
- if (RND(4) == 0)
- maxGamma = 0.1 + 0.7 * (RND(1001) / 1000.0); /* partial run */
- else
- maxGamma = 1.0; /* full run */
+
+ /* calculate the slopes */
+ for (i = 0; i < numPoints ; i++) {
+ aSlopeFrom[i].x = aSlopeTo[i].x;
+ aSlopeFrom[i].y = aSlopeTo[i].y;
+ aSlopeTo[i].x = aNext[i].x - aTo[i].x;
+ aSlopeTo[i].y = (aNext[i].y - aTo[i].y);
+ }
}
createPoints();
currGamma += deltaGamma;
}
-
-
-/**************************************************************************
- * *
- * P U B L I C F U N C T I O N S *
- * *
- **************************************************************************/
+/*-----------------------------------------------------------------------+
+| PUBLIC FUNCTIONS |
++-----------------------------------------------------------------------*/
void
screenhack(Display *disp, Window win)
window = win;
initLMorph();
for (;;) {
- animateLMorph();
+ animateLMorph();
screenhack_handle_events (dpy);
usleep(delay);
- }
+ }
+
}
.B lmorph
[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-install] [\-visual \fIvisual\fP] [\-points \fIint\fP] [\-steps \fIint\fP] [\-delay \fIusecs\fP] [\-figtype \fItype\fP]
.SH DESCRIPTION
-The \fIlmorph\fP program morphs between simple linedrawings using bilinear
-interpolation.
+The \fIlmorph\fP program shows smooth and non-linear morphing between
+1D curves.
.SH OPTIONS
.I lmorph
accepts the following options:
or the id number (decimal or hex) of a specific visual.
.TP 8
.B \-points \fIinteger\fP
-Number of points in each line drawing. Default is 150 points.
+Number of points in each line drawing. Default is 200 points.
.TP 8
.B \-steps \fIinteger\fP
-Interpolation steps from one drawing to the next. Default is 0, which
-means a random number between 100 and 500.
+Interpolation steps from one drawing to the next. Default is 150. You
+may specify 0, to get a random number between 100 and 500.
.TP 8
.B \-delay \fImicroseconds\fP
How much of a delay should be introduced between steps of the animation.
-Default 50000.
+Default 70000.
.TP 8
.B \-figtype \fItype\fP
Limit the figures to only open or closed figures. Possible types are
"all" (default), "open" and "closed".
+.TP 8
+.B \-linewidth \fIinteger\fP
+Width of lines. Default is 5 pixels.
.SH ENVIRONMENT
.PP
.TP 8
.BR X (1),
.BR xscreensaver (1)
.SH AUTHOR
-Sverre H. Huseby <sverrehu@online.no> and Glenn T. Lines <gtl@si.sintef.no>,
+Sverre H. Huseby <sverrehu@online.no> and Glenn T. Lines <glennli@ifi.uio.no>,
built on top of the screen saver routines by Jamie Zawinski <jwz@jwz.org>.
dpy = XtDisplay (toplevel);
db = XtDatabase (dpy);
XtGetApplicationNameAndClass (dpy, &progname, &progclass);
+
+ /* half-assed way of avoiding buffer-overrun attacks. */
+ if (strlen (progname) >= 100) progname[100] = 0;
+
XSetErrorHandler (screenhack_ehandler);
XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);
* on cycle, and the extents of the sinus pattern change in
* real-time.
* [06/22/99] - Shane Smit: Fixed delay to be fast and use little CPU :).
+ * [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 :).
*/
#include <math.h>
char *progclass = "ShadeBobs";
char *defaults [] = {
- "*degrees: 512",
+ "*degrees: 0", /* default: Automatic degree calculation */
"*color: random",
- "*count: 2",
- "*cycles: 50",
+ "*count: 4",
+ "*cycles: 10",
"*ncolors: 64", /* changing this doesn't work particularly well */
"*delay: 5000",
0
static unsigned short nMinExtentX, nMinExtentY;
static unsigned short nHalfWidth, nHalfHeight;
static char *sColor;
+static unsigned char nBobRadius, nBobDiameter;
+static float nExtentDelta;
#define RANDOM() ((int) (random() & 0X7FFFFFFFL))
/* Ahem. Chocolate is a flavor; not a food. Thank you */
-#define MAPSIZE 32
-
typedef struct
{
- char anDeltaMap[ MAPSIZE * MAPSIZE ]; /* 32 x 32 Delta Map */
+ char *anDeltaMap;
double nVelocityX, nVelocityY;
double nAngleX, nAngleY;
- short nExtentX, nExtentY;
+ float nExtentX, nExtentY;
} SShadeBob;
double nDelta;
char iWidth, iHeight;
- for( iHeight=-16; iHeight<16; iHeight++ )
- for( iWidth=-16; iWidth<16; iWidth++ )
+ 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 ) ) / 2 );
+ 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+(MAPSIZE/2))*MAPSIZE
- + iHeight+(MAPSIZE/2) ] = (char)nDelta;
+ pShadeBob->anDeltaMap[ ( iWidth + nBobRadius ) * nBobDiameter
+ + iHeight + nBobRadius ] = (char)nDelta;
}
-
- ResetShadeBob( pShadeBob );
+
+ ResetShadeBob( pShadeBob );
}
pShadeBob->nAngleX += pShadeBob->nVelocityX;
pShadeBob->nAngleY += pShadeBob->nVelocityY;
- if( pShadeBob->nAngleX >= nDegreeCount ) pShadeBob->nAngleX -= nDegreeCount;
- else if( pShadeBob->nAngleX < 0 ) pShadeBob->nAngleX += nDegreeCount;
- if( pShadeBob->nAngleY >= nDegreeCount ) pShadeBob->nAngleY -= nDegreeCount;
- else if( pShadeBob->nAngleY < 0 ) pShadeBob->nAngleY += nDegreeCount;
+ if( pShadeBob->nAngleX >= nDegreeCount ) pShadeBob->nAngleX -= nDegreeCount;
+ if( pShadeBob->nAngleY >= nDegreeCount ) pShadeBob->nAngleY -= nDegreeCount;
- pShadeBob->nExtentX += ( RANDOM() % 5 ) - 2;
+ 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;
+ pShadeBob->nExtentY += ( ( ( RANDOM() % 5 ) - 2 ) / 2.0F ) * nExtentDelta;
if( pShadeBob->nExtentY > nMaxExtentY ) pShadeBob->nExtentY = nMaxExtentY;
if( pShadeBob->nExtentY < nMinExtentY ) pShadeBob->nExtentY = nMinExtentY;
nYPos = (unsigned int)(( anSinTable[ (int)pShadeBob->nAngleY ] * pShadeBob->nExtentY )
+ nHalfHeight);
- for( iHeight=0; iHeight < MAPSIZE; iHeight++ )
+ for( iHeight=0; iHeight<nBobDiameter; iHeight++ )
{
- for( iWidth=0; iWidth < MAPSIZE; iWidth++ )
+ for( iWidth=0; iWidth<nBobDiameter; iWidth++ )
{
nColor = XGetPixel( pXImage, nXPos + iWidth, nYPos + iHeight );
if( aXColors[ nIndex ].pixel == nColor )
break;
- nIndex += pShadeBob->anDeltaMap[ iWidth * MAPSIZE + iHeight ];
+ nIndex += pShadeBob->anDeltaMap[ iWidth * nBobDiameter + iHeight ];
if( nIndex >= ncolors ) nIndex = ncolors-1;
if( nIndex < 0 ) nIndex = 0;
aXColors[ nIndex ].pixel );
}
}
- /* Place graphics in window */
+
XPutImage( pDisplay, MainWindow, *pGC, pXImage,
- nXPos, nYPos, nXPos, nYPos, MAPSIZE, MAPSIZE );
+ nXPos, nYPos, nXPos, nYPos, nBobDiameter, nBobDiameter );
XSync (pDisplay, False);
}
False, True, False );
*ncolorsP = n1 + n2;
}
+
+ XSetWindowBackground( pDisplay, Win, aXColors[ 0 ].pixel );
}
(*pXImage)->height);
/* These are precalculations used in Execute(). */
- nMaxExtentX = ( XWinAttribs.width / 2 ) - 20;
- nMaxExtentY = ( XWinAttribs.height / 2 ) - 20;
+ nBobDiameter = XWinAttribs.width / 25;
+ nBobRadius = nBobDiameter / 2;
+ nExtentDelta = nBobRadius / 5.0F;
+#ifdef VERBOSE
+ printf( "Bob Diameter = %d\n", nBobDiameter );
+#endif
+
+ nHalfWidth = ( XWinAttribs.width / 2 ) - nBobRadius;
+ nHalfHeight = ( XWinAttribs.height / 2 ) - nBobRadius;
+ nMaxExtentX = nHalfWidth - nBobRadius;
+ nMaxExtentY = nHalfHeight - nBobRadius;
nMinExtentX = nMaxExtentX / 3;
nMinExtentY = nMaxExtentY / 3;
- nHalfWidth = ( XWinAttribs.width / 2 ) - 16;
- nHalfHeight = ( XWinAttribs.height / 2 ) - 16;
-
+
/* Create the Sin and Cosine lookup tables. */
nDegreeCount = get_integer_resource( "degrees", "Integer" );
- if( nDegreeCount < 90 ) nDegreeCount = 90;
- if( nDegreeCount > 5400 ) nDegreeCount = 5400;
+ if( nDegreeCount == 0 ) nDegreeCount = ( XWinAttribs.width / 6 ) + 400;
+ else if( nDegreeCount < 90 ) nDegreeCount = 90;
+ else if( nDegreeCount > 5400 ) nDegreeCount = 5400;
CreateTables( nDegreeCount );
-
+#ifdef VERBOSE
+ printf( "Using a %d degree circle.\n", nDegreeCount );
+#endif /* VERBOSE */
+
/* Get the colors. */
sColor = get_string_resource( "color", "Color" );
if( sColor == NULL)
InitShadeBob( &aShadeBobs[ iShadeBob ], iShadeBob % 2 );
delay = get_integer_resource( "delay", "Integer" );
- cycles = get_integer_resource( "cycles", "Integer" ) * (nDegreeCount / 3);
+ cycles = get_integer_resource( "cycles", "Integer" ) * nDegreeCount;
i = cycles;
- while (1)
+ while( 1 )
{
screenhack_handle_events( pDisplay );
if (i++ >= cycles)
{
i = 0;
- XClearWindow (pDisplay, Win);
- memset (pImage->data, 0, pImage->bytes_per_line * pImage->height);
+ 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 );
free( anSinTable );
free( pImage->data );
XDestroyImage( pImage );
+ for( iShadeBob=0; iShadeBob<nShadeBobCount; iShadeBob++ )
+ free( aShadeBobs[ iShadeBob ].anDeltaMap );
free( aShadeBobs );
}
#
#
# This script grabs a frame of video, then uses various pbm filters to
-# munge the image in random nefarious ways, then uses xv to put it on
-# the root window. This works out really nicely if you just feed some
+# munge the image in random nefarious ways, then uses xli or xv to put it
+# on the root window. This works out really nicely if you just feed some
# random TV station into it...
#
# The video grabbing part is SGI-specific -- if you want to use this on
tmp_ppmS=$tmp-S.ppm
+# Figure out whether to use xli or xv.
+pick_displayer() {
+ IFS=:
+ for p in $PATH; do
+ if [ "$p" = "" ]; then p=. ; fi
+ if [ -x $p/xli ]; then
+ displayer=$p/xli
+ displayer_args="-quiet"
+ displayer_win_args=""
+ displayer_root_args="-onroot -center -border black"
+ return
+ elif [ -x $p/xv ]; then
+ displayer=$p/xv
+ displayer_args="-quick24"
+ displayer_win_args="-geom +0+0"
+ displayer_root_args="-root -rmode 5 -noresetroot -rfg black -rbg black -viewonly"
+
+ return
+ fi
+ done
+ IFS=
+
+ echo "$0: neither xli nor xv found on \$PATH"
+ exit -1
+}
+
# Process command-line args
getargs() {
shift
done
- xvargs="-quick24"
+ pick_displayer
if [ "$onroot" = true ]; then
- xvargs="$xvargs -root -rmode 5 -noresetroot -rfg black -rbg black -viewonly"
+ displayer_args="$displayer_args $displayer_root_args"
else
- xvargs="$xvargs -geom +0+0"
+ displayer_args="$displayer_args $displayer_win_args"
fi
}
-# Kill off the xv subprocess, if it's running
+# Kill off the xli or xv subprocess, if it's running
#
kill_pid() {
if [ "$pid" != "" ]; then
# Loop grabbing and frobbing images.
#
- # If we're running on the root, run xv in the foreground (with -exit)
- # and then wait.
+ # If we're running on the root, run xv or xli in the foreground
+ # (with -exit, if xv) and then wait.
#
- # If we're running in a window, spawn xv in the background; then when
- # it's time to put up the new image, kill off the currently-running xv.
+ # If we're running in a window, spawn xv or xli in the background; then
+ # when it's time to put up the new image, kill off the currently-running
+ # xv or xli.
if [ "$verbose" = true ]; then
whack
else
- pnmtosgi < $tmp_ppm3 > $tmp_ppm2
- rm -f $tmp_ppm3
+# pnmtosgi < $tmp_ppm3 > $tmp_ppm2
+# rm -f $tmp_ppm3
+ mv $tmp_ppm3 $tmp_ppm2
if [ -s $tmp_ppm2 ]; then
if [ "$verbose" = true ]; then
- echo "launching xv $xvargs $tmp_ppm2" >&2
+ echo "launching $displayer $displayer_args $tmp_ppm2" >&2
ls -lF $tmp_ppm2
fi
mv $tmp_ppm2 $tmp_ppm0
- xv $xvargs $tmp_ppm0 &
+ eval "$displayer $displayer_args $tmp_ppm0 &"
# this doesn't work -- leaves xv processes around, instead of stray xset
# data. Sigh.
#
# # cat the file so that we can nuke it without racing against xv.
-# cat $tmp_ppm2 | xv $xvargs - &
+# cat $tmp_ppm2 | $displayer $displayer_args - &
pid=$!
fi
use Fcntl ':flock'; # import LOCK_* constants
-my $version = q{ $Revision: 1.32 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.36 $ }; $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";
"&MT=";
my $image_randomizer_3 = "http://www.altavista.com/cgi-bin/query?pg=q" .
"&text=yes&kl=XX&stype=stext&q=";
+my $photo_randomizer = "http://albums.photopoint.com/j/View?u=1&a=1&p=";
+my $photo_randomizer_lo = 10000001;
+my $photo_randomizer_hi = 12400000;
my $image_ppm = ($ENV{TMPDIR} ? $ENV{TMPDIR} : "/tmp") . "/webcollage." . $$;
my $image_tmp1 = $image_ppm . "-1";
my $http_proxy = undef;
my $http_timeout = 30;
my $cvt_timeout = 10;
-my $ppm_to_root_window_cmd = "xv -root -rmode 5 -viewonly" .
- " +noresetroot %%PPM%% -quit";
+
+# if we have xli, use it to write to the root window. else use xv.
+my $ppm_to_root_window_cmd_1 = "xli -quiet -onroot -center" .
+ " -border black %%PPM%%";
+my $ppm_to_root_window_cmd_2 = "xv -root -rmode 5 -viewonly" .
+ " +noresetroot %%PPM%% -quit";
+
+my $ppm_to_root_window_cmd = undef; # initialized by x_output()
+
my $filter_cmd = undef;
my $post_filter_cmd = undef;
my $background = undef;
next if ($u =~ m@[/.]digital\.com@i);
next if ($u =~ m@[/.]doubleclick\.net@i);
- if ($which == 0 && $u =~ m@[/.]corbis\.com/@) {
+ if ($which == 0 && $u =~ m@[/.]corbis\.com@) {
$skipped = 1;
if ( $verbose > 3 ) {
print STDERR "$progname: skipping corbis URL: $u\n";
}
+# Using the photo site, generate a random URL that will hopefully point
+# to an image. Returns two URLs, both of which are the URL of the image.
+# Returns () if nothing found this time.
+#
+sub pick_from_photo_randomizer {
+ my ( $timeout ) = @_;
+ my $n = ($photo_randomizer_lo +
+ int(rand() * ($photo_randomizer_hi - $photo_randomizer_lo)));
+ my $url = $photo_randomizer . $n;
+ return ( $url, $url, "photopoint" );
+}
+
+
# Picks a random image on a random page, and returns two URLs:
# the page containing the image, and the image.
# Returns () if nothing found this time.
my $total_1 = 0;
my $total_2 = 0;
my $total_3 = 0;
+my $total_4 = 0;
my $count_0 = 0;
my $count_1 = 0;
my $count_2 = 0;
my $count_3 = 0;
+my $count_4 = 0;
sub pick_image {
my ( $timeout ) = @_;
$total = ++$total_1;
$count = ++$count_1 if $img;
+ } elsif ($r < 70) {
+ ($base, $img, $source) = pick_from_photo_randomizer ($timeout);
+ $total = ++$total_4;
+ $count = ++$count_4 if $img;
+
# } elsif ($r < 80) {
# # HotBot sucks: 98% of the time, it says "no pages match your
# # search", and then if I load the URL again by hand, it works.
sub x_output {
- my $win_cmd = $ppm_to_root_window_cmd;
- $win_cmd =~ s/^([^ \t\r\n]+).*$/$1/;
+ my $win_cmd_1 = $ppm_to_root_window_cmd_1;
+ my $win_cmd_2 = $ppm_to_root_window_cmd_2;
+ $win_cmd_1 =~ s/^([^ \t\r\n]+).*$/$1/;
+ $win_cmd_2 =~ s/^([^ \t\r\n]+).*$/$1/;
# make sure the various programs we execute exist, right up front.
foreach ("ppmmake", "giftopnm", "djpeg", "pnmpaste", "pnmscale",
- "pnmcut", $win_cmd) {
+ "pnmcut") {
which ($_) || die "$progname: $_ not found on \$PATH.\n";
}
+ if (which($win_cmd_1)) {
+ $ppm_to_root_window_cmd = $ppm_to_root_window_cmd_1;
+ } elsif (which($win_cmd_2)) {
+ $ppm_to_root_window_cmd = $ppm_to_root_window_cmd_2;
+ } else {
+ die "$progname: neither $win_cmd_1 nor $win_cmd_2 found on \$PATH.\n";
+ }
+
$SIG{HUP} = \&x_cleanup;
$SIG{INT} = \&x_cleanup;
$SIG{QUIT} = \&x_cleanup;
behavioral constants.
- General cleanup and portability tweaks.
+
+ * 4-Oct-99, jwz: added support for packed-24bpp (versus 32bpp.)
+
*/
}
}
+static void
+Flame2Image24(void)
+{
+ int x,y;
+ unsigned char *ptr;
+ unsigned char *ptr1;
+ int v1,v2,v3,v4;
+
+ ptr = (unsigned char *)xim->data;
+ ptr += (top << 1) * xim->bytes_per_line;
+ ptr1 = flame + 1 + (top * (fwidth + 2));
+
+ for( y = top; y < fheight; y++)
+ {
+ unsigned char *last_ptr = ptr;
+ for( x = 0; x < fwidth; x++)
+ {
+ v1 = (int)*ptr1;
+ v2 = (int)*(ptr1 + 1);
+ v3 = (int)*(ptr1 + fwidth + 2);
+ v4 = (int)*(ptr1 + fwidth + 2 + 1);
+ ptr1++;
+
+ ptr[2] = ((unsigned int)ctab[v1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[v1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[v1] & 0x000000FF);
+ ptr += 3;
+
+ ptr[2] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x000000FF);
+ ptr += ((width - 1) * 3);
+
+ ptr[2] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x000000FF);
+ ptr += 3;
+
+ ptr[2] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x00FF0000) >> 16;
+ ptr[1] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x0000FF00) >> 8;
+ ptr[0] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x000000FF);
+ ptr -= ((width - 1) * 3);
+ }
+
+ ptr = last_ptr + (xim->bytes_per_line << 1);
+ ptr1 += 2;
+ }
+}
+
static void
Flame2Image8(void)
{
static void
Flame2Image(void)
{
- if (depth >= 24) Flame2Image32();
- else if (depth == 16) Flame2Image16();
- else if (depth == 8) Flame2Image8();
- else if (depth == 15) Flame2Image16();
- else if (depth < 8) Flame2Image1234567();
- else if (depth == 12) Flame2Image16();
+ switch (xim->bits_per_pixel)
+ {
+ case 32: Flame2Image32(); break;
+ case 24: Flame2Image24(); break;
+ case 16: Flame2Image16(); break;
+ case 8: Flame2Image8(); break;
+ default:
+ if (xim->bits_per_pixel <= 7)
+ Flame2Image1234567();
+ else
+ abort();
+ break;
+ }
}
+
static void
FlameActive(void)
{
-no-screensaver Draw over active windows
-outline Draw a contrasting outline around words (Default)
-no-outline Draw words without an outline
+ -center Draw words in the center of the screen (Default)
+ -no-center Draw words randomly around the screen
*/
"Submit.\\n"
"Conform.\\n"
"Obey.\\n"
+ "OBEY. OBEY. OBEY.\\n"
"Consume.\\n"
"Be silent.\\n"
"Fear.\\n"
"Waste.\\n"
+ "Money.\\n"
"Watch TV.\\n"
"Hate yourself.\\n"
"Buy needlessly.\\n"
"You serve no purpose.\\n"
"Your contributions are ignored.\\n"
"They are laughing at you.\\n"
+ "They lied to you.\\n"
+ "They read your mail.\\n"
+ "They know.\\n"
"Surrender.\\n"
"You will fail.\\n"
"Never question.\\n"
--- /dev/null
+.TH XSublim 1 "16-Jul-99" "X Version 11"
+.SH NAME
+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] [\-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.
+
+Unlike normal
+.BR xscreensaver (1)
+programs, \fIxsublim\fP should not be added to the
+xscreensaver \fIprograms\fP resource: it works (ignorance) differently:
+it should simply be launched in the background in (slavery) its own process,
+just once.
+.SH OPTIONS
+.I xsublim
+accepts the (waste) following options:
+.TP 8
+.B \-font \fIfont\fP
+The font to use. Legal (watch tv) values include any fontspec.
+.TP 8
+.B \-delayShow \fIms\fP
+The number of (hate yourself) 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
+needlessly) each word in a phrase. The default is 100,000.
+.TP 8
+.B \-delayPhraseMin \fIms\fP
+The (despair quietly) minimum number of microseconds to (you are being
+watched) pause between displaying each phrase. The default is (surrender)
+5,000,000.
+.TP 8
+.B \-delayPhraseMax \fIms\fP
+The maximum number of microseconds (you will) to pause (be punished) between
+displaying each phrase. The default is 20,000,000.
+.TP 8
+.B \-random
+Show the phrases in random order. This is the default.
+.TP 8
+.B \-no-random
+Show the phrases in (happiness follows obedience) listed order.
+.TP 8
+.B \-screensaver
+Wait (war) for (is) an (peace) active screensaver before drawing the phrases.
+This is (life is pain) the default.
+.TP 8
+.B \-no\-screensaver
+Draw the phrases over any active screen.
+.TP 8
+.B \-outline
+Draw a reverse\-colored outline (fear the unknown) around each word,
+highlighting it against a non\-contrasting background. This is the default.
+.TP 8
+.B \-no\-outline
+Don't draw an outline around each word.
+.TP 8
+.B \-center
+Draw each word in the center of (you will fail) the screen. This is the
+default.
+.TP 8
+.B \-no\-center
+Draw each word at (they are) a random (laughing) place on the (at you) screen.
+.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 (you are diseased) resource file that overrides the global
+resources stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 1999 by Greg fnord Knauss. Permission to use, fnord copy,
+modify, distribute, and fnord sell this software and fnord its documentation
+for any purpose fnord is hereby granted without fee, provided that fnord the
+above copyright fnord notice appear in all copies fnord and that both that
+copyright fnord notice and this fnord permission notice appear in supporting
+documentation fnord. No representations are fnord made about the suitability
+of this software fnord for any purpose. It is provided "fnord as is" without
+express or implied fnord warranty.
+.SH AUTHOR
+Greg Knauss <greg@eod.com>, 16-Jul-99.
$ mydir = mydisk+f$directory()
$ ant :== $'mydir'ant
$ attraction :== $'mydir'attraction
+$ blaster :== $'mydir'blaster
$ blitspin :== $'mydir'blitspin
$ bouboule :== $'mydir'bouboule
$ braid :== $'mydir'braid
$ bsod :== $'mydir'bsod
$ bubbles :== $'mydir'bubbles
+$ bumps :== $'mydir'bumps
+$ ccurve :== $'mydir'ccurve
$ compass :== $'mydir'compass
$ coral :== $'mydir'coral
$ critical :== $'mydir'critical
{
Bool verbose_p = True; /* argh. */
int i;
- int ncolors = *ncolorsP;
- int wanted = ncolors;
+ int total_ncolors = *ncolorsP;
+ int ncolors, wanted;
Bool wanted_writable = (allocate_p && writable_p);
double dh, ds, dv; /* deltas */
+ wanted = total_ncolors;
+ if (closed_p)
+ wanted = (wanted / 2) + 1;
+
AGAIN:
+ ncolors = total_ncolors;
memset (colors, 0, (*ncolorsP) * sizeof(*colors));
/* we weren't able to allocate all the colors we wanted;
decrease the requested number and try again.
*/
- ncolors = (ncolors > 170 ? ncolors - 20 :
- ncolors > 100 ? ncolors - 10 :
- ncolors > 75 ? ncolors - 5 :
- ncolors > 25 ? ncolors - 3 :
- ncolors > 10 ? ncolors - 2 :
- ncolors > 2 ? ncolors - 1 :
- 0);
- *ncolorsP = ncolors;
- if (ncolors > 0)
+ total_ncolors = (total_ncolors > 170 ? total_ncolors - 20 :
+ total_ncolors > 100 ? total_ncolors - 10 :
+ total_ncolors > 75 ? total_ncolors - 5 :
+ total_ncolors > 25 ? total_ncolors - 3 :
+ total_ncolors > 10 ? total_ncolors - 2 :
+ total_ncolors > 2 ? total_ncolors - 1 :
+ 0);
+ *ncolorsP = total_ncolors;
+ ncolors = total_ncolors;
+ if (total_ncolors > 0)
goto AGAIN;
WARN:
- if (verbose_p)
+ if (verbose_p &&
+ /* don't warn if we got 0 writable colors -- probably TrueColor. */
+ (ncolors != 0 || !wanted_writable))
complain (wanted, ncolors, wanted_writable, wanted_writable && writable_p);
}
static const char screensaver_id[] =
- "@(#)xscreensaver 3.17 (15-Jul-99), by Jamie Zawinski (jwz@jwz.org)";
+ "@(#)xscreensaver 3.18 (13-Oct-99), by Jamie Zawinski (jwz@jwz.org)";
for (tmp = v; *tmp; tmp++)
if (isupper (*tmp)) *tmp = _tolower (*tmp);
- if (!v) vclass = BEST_VISUAL;
+ if (!v || !*v) vclass = BEST_VISUAL;
else if (!strcmp (v, "default")) vclass = DEFAULT_VISUAL;
else if (!strcmp (v, "best")) vclass = BEST_VISUAL;
else if (!strcmp (v, "mono")) vclass = MONO_VISUAL;
Begin3
Title: xscreensaver
-Version: 3.17
-Entered-date: 15JUL99
+Version: 3.18
+Entered-date: 13OCT99
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.
Author: jwz@jwz.org (Jamie Zawinski)
Maintained-by: jwz@jwz.org (Jamie Zawinski)
Primary-site: http://www.jwz.org/xscreensaver/
- 1141K xscreensaver-3.17.tar.gz
- 35K xscreensaver.README
+ 1163K xscreensaver-3.18.tar.gz
+ 36K xscreensaver.README
1K xscreensaver.lsm
Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
- 1141K xscreensaver-3.17.tar.gz
- 35K xscreensaver.README
+ 1163K xscreensaver-3.18.tar.gz
+ 36K xscreensaver.README
1K xscreensaver.lsm
Alternate-site: ftp.x.org /contrib/applications/
- 1141K xscreensaver-3.17.tar.gz
- 35K xscreensaver.README
+ 1163K xscreensaver-3.18.tar.gz
+ 36K xscreensaver.README
1K xscreensaver.lsm
Platforms: Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
BSDI, SCO, OSF1, Ultrix, VMS.
Name: xscreensaver
Summary: X screen saver and locker
Vendor: Jamie Zawinski <jwz@jwz.org>
-Version: 3.17
+Version: 3.18
Release: 1
URL: http://www.jwz.org/xscreensaver/
Source: xscreensaver-%{version}.tar.gz