From: Zygo Blaxell Date: Mon, 2 Mar 2009 05:42:52 +0000 (-0500) Subject: http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=commitdiff_plain;h=a94197e76a5dea5cb60542840809d6c20d0abbf3 packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz -rw-r--r-- 1 zblaxell zblaxell 2156101 Feb 26 2002 xscreensaver-4.01.tar.gz 09f087d653c9c8d6b3777aa3f348c5e2f7217686 xscreensaver-4.01.tar.gz --- diff --git a/Makefile.in b/Makefile.in index c68875c5..aa66e317 100644 --- a/Makefile.in +++ b/Makefile.in @@ -174,18 +174,23 @@ rpm:: DIR=`pwd`/rpm_build ; \ ARCH=`rpm --showrc | sed -n 's/^build arch *: //p'` ; \ ADIR=archive/ ; \ + TGZ=xscreensaver-$$VERS.tar.gz ; \ + if [ ! -f $${ADIR}$$TGZ ]; then \ + echo "$${ADIR}$$TGZ does not exist! Did you forget to \`make tar'?" ; \ + exit 1 ; \ + fi ; \ rm -rf /var/tmp/xscreensaver-$$VERS-root ; \ rm -rf $$DIR ; \ mkdir $$DIR ; \ ( cd $$DIR; mkdir BUILD RPMS RPMS/$$ARCH SOURCES SPECS SRPMS ) ; \ - cp -p $${ADIR}xscreensaver-$$VERS.tar.gz $$DIR/SOURCES/ ; \ + cp -p $${ADIR}$$TGZ $$DIR/SOURCES/ ; \ rpm --define "_topdir $$DIR" \ --define "USE_GL yes" \ -v -ba xscreensaver.spec ; \ echo '' ; \ echo 'RPM build complete' ; \ echo '' ; \ - rm -f $$DIR/xscreensaver-$$VERS.tar.gz ; \ + rm -f $$DIR/$$TGZ ; \ rm -rf $$DIR/BUILD/xscreensaver-$$VERS ; \ mv $$DIR/SRPMS/xscreensaver*-$$VERS-*.rpm . ; \ mv $$DIR/RPMS/$$ARCH/xscreensaver*-$$VERS-*.rpm . ; \ diff --git a/README b/README index d9d3abf4..bd6de77d 100644 --- a/README +++ b/README @@ -60,7 +60,7 @@ Along with the xscreensaver daemon itself, this package also includes numerous graphics hacks for use as screensavers. There is nothing magic about these: they are just programs that draw on the root window. -More than 120 such programs are included. For details, see the xscreensaver +More than 140 such programs are included. For details, see the xscreensaver web page, or the enclosed manual pages. The latest version of xscreensaver is always available on the web at @@ -68,7 +68,39 @@ http://www.jwz.org/xscreensaver/. ============ -Changes since 3.34: * Redesigned `xscreensaver-demo' GUI. +Changes since 4.00: * New hacks: `twang', `glsnake', `boxed', `sballs', + and `glforestfire'. + * New hacks `apollonian', `euler2d', `juggle', + `polyominoes' and `thornbird', from xlockmore. + * Merged recent xlockmore changes into `ant', `braid', + `demon', `discrete', `drift', `fadeplot', `forest', + `grav', `hopalong', `ifs', `laser', `lightning', + `lisa', `lissie', `loop', `mountain', `penrose', + `rotor', `sierpinski', `slip', `sphere', `spiral', + `strange', and `vines'. + * Fixed the `gltext' bug that sometimes caused + horizontal lines to vanish again. This time for sure. + * Sped up `webcollage' by adding a C helper program to + replace the PPM pipeline. It also pastes images + semi-transparently now. + * Added support for the gdk_pixbuf library: if this lib + is available, then `blitspin', `xflame', and `flag' + can load GIF, JPEG, and PNG images in addition to XPM + and XBM. + * Fixed a rare race condition where the desktop-grabbing + hacks could sometimes leave the screen wedged, if the + user moved the mouse exactly when they were grabbing + the screen image (it would un-wedge the next time the + saver timed out or was activated.) + * Fixed incorrect colors in the screen-grabbing GL hacks + (`gflux' and `flipscreen3d'.) + * Made SIGHUP restart the daemon process (though using + `xscreensaver-command -restart' is still the preferred + way.) + * Tweaks to `xspirograph'. + * Minor configure and portability tweaks. +Changes since 3.34: * Redesigned `xscreensaver-demo' GUI: it now includes + small-preview and per-hack configuration dialogs. * Added three new modes of operation: `One Screen Saver', `Blank Screen', and `Don't Blank' (in addition to the historical `Random Screen Saver'). @@ -173,7 +205,7 @@ Changes since 3.30: * Put in more sensible defaults for DPMS, and updated is no longer needed. * New versions of `rotzoomer' and `nerverot'. * Fixed an OSF/1 compilation problem in `molecule'. -Changes since 3.29: * New hacks, `molecule' `dangerball', and `rotzoomer'. +Changes since 3.29: * New hacks, `molecule', `dangerball', and `rotzoomer'. * New version of `gflux'. * Made `gltext' able to display the current time. * Fixed a floating-point-precision problem in `gltext' diff --git a/config.h.in b/config.h.in index 9692f5da..bb1d1040 100644 --- a/config.h.in +++ b/config.h.in @@ -148,6 +148,11 @@ */ #undef HAVE_CRAPPLET +/* Define this if HAVE_CRAPPLET is defined, and the function + capplet_widget_changes_are_immediate() is available. + */ +#undef HAVE_CRAPPLET_IMMEDIATE + /* Define this if you have the XML library. */ #undef HAVE_XML @@ -157,6 +162,16 @@ */ #undef HAVE_XPM +/* Define this if you have the GDK_Pixbuf library installed. Some of the + * demos can make use of this if it is available. + */ +#undef HAVE_GDK_PIXBUF + +/* Define this if you have the Independent JPEG Group's JPEG library + * installed. Some of the demos can make use of this if it is available. + */ +#undef HAVE_JPEGLIB + /* Define this if you have the Xmu library. This is standard part of X, and * if your vendor doesn't ship it, you should report that as a bug. */ @@ -368,11 +383,6 @@ /* Define if you have that defines fd_set and FD_SET. */ #undef HAVE_SYS_SELECT_H -/* Define to use sigaction() instead of signal() for SIGCHLD-related activity. - This is necessary at least on SCO OpenServer 5, due to a Unix kernel bug. - */ -#undef USE_SIGACTION - /* Define this if you do pings with a `struct icmp' and a `icmp_id' slot. */ #undef HAVE_ICMP diff --git a/configure b/configure index 297ce8af..14fcbb04 100755 --- a/configure +++ b/configure @@ -95,7 +95,15 @@ ac_help="$ac_help ac_help="$ac_help --with-xpm Include support for XPM files in some demos." ac_help="$ac_help - --with-xshm-ext Include support for the XSHM extension." + --with-pixbuf Include support for the GDK-Pixbuf library in some + demos, which will make it possible for them to read + GIF, JPEG, and PNG files as well." +ac_help="$ac_help + --with-jpeg Include support for the JPEG library in some demos, + which will make it possible for them to read JPEG + files as well." +ac_help="$ac_help + --with-xshm-ext Include support for the Shared Memory extension." ac_help="$ac_help --with-xdbe-ext Include support for the DOUBLE-BUFFER extension." ac_help="$ac_help @@ -821,7 +829,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:836: checking host system type" >&5 +echo "configure:844: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -844,7 +852,7 @@ echo "$ac_t""$host" 1>&6 # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:859: checking for $ac_word" >&5 +echo "configure:867: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -874,7 +882,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:889: checking for $ac_word" >&5 +echo "configure:897: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -925,7 +933,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:940: checking for $ac_word" >&5 +echo "configure:948: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -957,7 +965,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:972: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:980: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -968,12 +976,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 983 "configure" +#line 991 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:996: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -999,12 +1007,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1014: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1022: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1019: checking whether we are using GNU C" >&5 +echo "configure:1027: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1013,7 +1021,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1028: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1036: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1032,7 +1040,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1047: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1055: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1066,7 +1074,7 @@ fi if test -z "$GCC"; then echo $ac_n "checking how to request ANSI compilation""... $ac_c" 1>&6 -echo "configure:1081: checking how to request ANSI compilation" >&5 +echo "configure:1089: checking how to request ANSI compilation" >&5 case "$host" in *-hpux* ) echo "$ac_t""HPUX: adding -Ae" 1>&6 @@ -1089,16 +1097,16 @@ echo "configure:1081: checking how to request ANSI compilation" >&5 fi echo $ac_n "checking whether the compiler works on ANSI C""... $ac_c" 1>&6 -echo "configure:1104: checking whether the compiler works on ANSI C" >&5 +echo "configure:1112: checking whether the compiler works on ANSI C" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Couldn't build even a trivial ANSI C program: check CC." 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 else @@ -1133,7 +1141,7 @@ fi if test -n "$GCC"; then if test -n "$GCC"; then echo $ac_n "checking whether gcc accepts -std""... $ac_c" 1>&6 -echo "configure:1148: checking whether gcc accepts -std" >&5 +echo "configure:1156: checking whether gcc accepts -std" >&5 if eval "test \"`echo '$''{'ac_cv_gcc_accepts_std'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1177,7 +1185,7 @@ echo "$ac_t""$ac_cv_gcc_accepts_std" 1>&6 fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1192: checking how to run the C preprocessor" >&5 +echo "configure:1200: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1192,13 +1200,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1213: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1221: \"$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 : @@ -1209,13 +1217,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1230: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1238: \"$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 : @@ -1226,13 +1234,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1247: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1255: \"$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 : @@ -1257,12 +1265,12 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:1272: checking for working const" >&5 +echo "configure:1280: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1334: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -1332,21 +1340,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:1347: checking for inline" >&5 +echo "configure:1355: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1369: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -1373,7 +1381,7 @@ esac ac_bc_result=`echo 6+9 | bc 2>/dev/null` echo $ac_n "checking for bc""... $ac_c" 1>&6 -echo "configure:1388: checking for bc" >&5 +echo "configure:1396: checking for bc" >&5 if test "$ac_bc_result" = "15" ; then echo "$ac_t""yes" 1>&6 else @@ -1398,7 +1406,7 @@ echo "configure:1388: checking for bc" >&5 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1413: checking for a BSD compatible install" >&5 +echo "configure:1421: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1451,7 +1459,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether \"\${INSTALL} -d\" creates intermediate directories""... $ac_c" 1>&6 -echo "configure:1466: checking whether \"\${INSTALL} -d\" creates intermediate directories" >&5 +echo "configure:1474: checking whether \"\${INSTALL} -d\" creates intermediate directories" >&5 if eval "test \"`echo '$''{'ac_cv_install_d_creates_dirs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1473,7 +1481,7 @@ echo "$ac_t""$ac_cv_install_d_creates_dirs" 1>&6 if test "$ac_cv_install_d_creates_dirs" = no ; then echo $ac_n "checking whether \"mkdir -p\" creates intermediate directories""... $ac_c" 1>&6 -echo "configure:1488: checking whether \"mkdir -p\" creates intermediate directories" >&5 +echo "configure:1496: checking whether \"mkdir -p\" creates intermediate directories" >&5 if eval "test \"`echo '$''{'ac_cv_mkdir_p_creates_dirs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1504,7 +1512,7 @@ echo "$ac_t""$ac_cv_mkdir_p_creates_dirs" 1>&6 fi echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:1519: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:1527: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1540,12 +1548,12 @@ INSTALL_SCRIPT='${INSTALL}' # random libc stuff echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1555: checking for ANSI C header files" >&5 +echo "configure:1563: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1553,7 +1561,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1568: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1576: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1570,7 +1578,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1588,7 +1596,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1609,7 +1617,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1620,7 +1628,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1647,17 +1655,17 @@ for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1662: checking for $ac_hdr" >&5 +echo "configure:1670: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1672: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1680: \"$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* @@ -1684,12 +1692,12 @@ fi done echo $ac_n "checking for mode_t""... $ac_c" 1>&6 -echo "configure:1699: checking for mode_t" >&5 +echo "configure:1707: checking for mode_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1717,12 +1725,12 @@ EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:1732: checking for pid_t" >&5 +echo "configure:1740: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1750,12 +1758,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:1765: checking for size_t" >&5 +echo "configure:1773: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1783,12 +1791,12 @@ EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:1798: checking return type of signal handlers" >&5 +echo "configure:1806: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1805,7 +1813,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:1820: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1828: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -1824,12 +1832,12 @@ EOF echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:1839: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:1847: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1838,7 +1846,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:1853: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1861: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -1859,12 +1867,12 @@ EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 -echo "configure:1874: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo "configure:1882: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1880,7 +1888,7 @@ wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF -if { (eval echo configure:1895: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1903: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else @@ -1905,12 +1913,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:1920: checking for $ac_hdr that defines DIR" >&5 +echo "configure:1928: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -1918,7 +1926,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:1933: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1941: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -1943,7 +1951,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:1958: checking for opendir in -ldir" >&5 +echo "configure:1966: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1951,7 +1959,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1985: \"$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 @@ -1984,7 +1992,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:1999: checking for opendir in -lx" >&5 +echo "configure:2007: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1992,7 +2000,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2026: \"$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 @@ -2026,12 +2034,12 @@ fi fi echo $ac_n "checking how to call gettimeofday""... $ac_c" 1>&6 -echo "configure:2041: checking how to call gettimeofday" >&5 +echo "configure:2049: checking how to call gettimeofday" >&5 if eval "test \"`echo '$''{'ac_cv_gettimeofday_args'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2040,7 +2048,7 @@ struct timeval tv; struct timezone tzp; gettimeofday(&tv, &tzp); ; return 0; } EOF -if { (eval echo configure:2055: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2063: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_gettimeofday_args=2 else @@ -2048,7 +2056,7 @@ else cat conftest.$ac_ext >&5 rm -rf conftest* cat > conftest.$ac_ext < #include @@ -2056,7 +2064,7 @@ int main() { struct timeval tv; gettimeofday(&tv); ; return 0; } EOF -if { (eval echo configure:2071: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2079: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_gettimeofday_args=1 else @@ -2095,12 +2103,12 @@ EOF for ac_func in select fcntl uname nice setpriority getcwd getwd putenv do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2110: checking for $ac_func" >&5 +echo "configure:2118: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2146: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2151,12 +2159,12 @@ done for ac_func in sigaction syslog realpath setrlimit do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2166: checking for $ac_func" >&5 +echo "configure:2174: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2202: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2204,12 +2212,12 @@ fi done echo $ac_n "checking for struct icmp""... $ac_c" 1>&6 -echo "configure:2219: checking for struct icmp" >&5 +echo "configure:2227: checking for struct icmp" >&5 if eval "test \"`echo '$''{'ac_cv_have_icmp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2249,7 +2257,7 @@ struct icmp i; ; return 0; } EOF -if { (eval echo configure:2264: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2272: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_icmp=yes else @@ -2269,12 +2277,12 @@ EOF fi echo $ac_n "checking for struct icmphdr""... $ac_c" 1>&6 -echo "configure:2284: checking for struct icmphdr" >&5 +echo "configure:2292: checking for struct icmphdr" >&5 if eval "test \"`echo '$''{'ac_cv_have_icmphdr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2309,7 +2317,7 @@ struct icmphdr i; ip.ip_hl = 0; ; return 0; } EOF -if { (eval echo configure:2324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2332: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_icmphdr=yes else @@ -2332,17 +2340,17 @@ for ac_hdr in crypt.h sys/select.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2347: checking for $ac_hdr" >&5 +echo "configure:2355: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2357: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2365: \"$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* @@ -2373,7 +2381,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2388: checking for $ac_word" >&5 +echo "configure:2396: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2412,7 +2420,7 @@ done PERL_VERSION=0 else echo $ac_n "checking perl version""... $ac_c" 1>&6 -echo "configure:2427: checking perl version" >&5 +echo "configure:2435: checking perl version" >&5 if eval "test \"`echo '$''{'ac_cv_perl_version'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2434,7 +2442,7 @@ fi # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 -echo "configure:2449: checking for X" >&5 +echo "configure:2457: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then @@ -2496,12 +2504,12 @@ if test "$ac_x_includes" = NO; then # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2516: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2524: \"$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* @@ -2570,14 +2578,14 @@ if test "$ac_x_libraries" = NO; then ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. @@ -2683,17 +2691,17 @@ else case "`(uname -sr) 2>/dev/null`" in "SunOS 5"*) echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 -echo "configure:2698: checking whether -R must be followed by a space" >&5 +echo "configure:2706: checking whether -R must be followed by a space" >&5 ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2716: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_nospace=yes else @@ -2709,14 +2717,14 @@ rm -f conftest* else LIBS="$ac_xsave_LIBS -R $x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2739: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_space=yes else @@ -2748,7 +2756,7 @@ rm -f conftest* # libraries were built with DECnet support. And karl@cs.umb.edu says # the Alpha needs dnet_stub (dnet does not exist). echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 -echo "configure:2763: checking for dnet_ntoa in -ldnet" >&5 +echo "configure:2771: checking for dnet_ntoa in -ldnet" >&5 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2756,7 +2764,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2790: \"$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 @@ -2789,7 +2797,7 @@ fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 -echo "configure:2804: checking for dnet_ntoa in -ldnet_stub" >&5 +echo "configure:2812: checking for dnet_ntoa in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2797,7 +2805,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2831: \"$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 @@ -2837,12 +2845,12 @@ fi # The nsl library prevents programs from opening the X display # on Irix 5.2, according to dickey@clark.net. echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:2852: checking for gethostbyname" >&5 +echo "configure:2860: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else @@ -2886,7 +2894,7 @@ fi if test $ac_cv_func_gethostbyname = no; then echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 -echo "configure:2901: checking for gethostbyname in -lnsl" >&5 +echo "configure:2909: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2894,7 +2902,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2928: \"$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 @@ -2935,12 +2943,12 @@ fi # -lsocket must be given before -lnsl if both are needed. # We assume that if connect needs -lnsl, so does gethostbyname. echo $ac_n "checking for connect""... $ac_c" 1>&6 -echo "configure:2950: checking for connect" >&5 +echo "configure:2958: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_connect=yes" else @@ -2984,7 +2992,7 @@ fi if test $ac_cv_func_connect = no; then echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 -echo "configure:2999: checking for connect in -lsocket" >&5 +echo "configure:3007: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2992,7 +3000,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3026: \"$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 @@ -3027,12 +3035,12 @@ fi # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. echo $ac_n "checking for remove""... $ac_c" 1>&6 -echo "configure:3042: checking for remove" >&5 +echo "configure:3050: checking for remove" >&5 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_remove=yes" else @@ -3076,7 +3084,7 @@ fi if test $ac_cv_func_remove = no; then echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 -echo "configure:3091: checking for remove in -lposix" >&5 +echo "configure:3099: checking for remove in -lposix" >&5 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3084,7 +3092,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lposix $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3118: \"$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 @@ -3119,12 +3127,12 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. echo $ac_n "checking for shmat""... $ac_c" 1>&6 -echo "configure:3134: checking for shmat" >&5 +echo "configure:3142: checking for shmat" >&5 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shmat=yes" else @@ -3168,7 +3176,7 @@ fi if test $ac_cv_func_shmat = no; then echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 -echo "configure:3183: checking for shmat in -lipc" >&5 +echo "configure:3191: checking for shmat in -lipc" >&5 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3176,7 +3184,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lipc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3210: \"$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 @@ -3220,7 +3228,7 @@ fi # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 -echo "configure:3235: checking for IceConnectionNumber in -lICE" >&5 +echo "configure:3243: checking for IceConnectionNumber in -lICE" >&5 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3228,7 +3236,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3262: \"$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 @@ -3270,7 +3278,7 @@ fi echo $ac_n "checking for X app-defaults directory""... $ac_c" 1>&6 -echo "configure:3285: checking for X app-defaults directory" >&5 +echo "configure:3293: checking for X app-defaults directory" >&5 if eval "test \"`echo '$''{'ac_cv_x_app_defaults'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3477,7 +3485,7 @@ case "$host" in # Some versions of Slowlaris Motif require -lgen. But not all. Why? echo $ac_n "checking for regcmp in -lgen""... $ac_c" 1>&6 -echo "configure:3492: checking for regcmp in -lgen" >&5 +echo "configure:3500: checking for regcmp in -lgen" >&5 ac_lib_var=`echo gen'_'regcmp | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3485,7 +3493,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgen $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3519: \"$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 @@ -3520,7 +3528,7 @@ fi ;; esac echo $ac_n "checking for XPointer""... $ac_c" 1>&6 -echo "configure:3535: checking for XPointer" >&5 +echo "configure:3543: checking for XPointer" >&5 if eval "test \"`echo '$''{'ac_cv_xpointer'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3531,14 +3539,14 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < int main() { XPointer foo = (XPointer) 0; ; return 0; } EOF -if { (eval echo configure:3553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3561: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_xpointer=yes else @@ -3576,17 +3584,17 @@ have_xmu=no CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/Xmu/Error.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Xmu/Error.h""... $ac_c" 1>&6 -echo "configure:3591: checking for X11/Xmu/Error.h" >&5 +echo "configure:3599: checking for X11/Xmu/Error.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3601: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3609: \"$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* @@ -3635,7 +3643,7 @@ if test "$have_xmu" = yes ; then case "$host" in *-sunos4*) echo $ac_n "checking for the SunOS 4.1.x _get_wmShellWidgetClass bug""... $ac_c" 1>&6 -echo "configure:3650: checking for the SunOS 4.1.x _get_wmShellWidgetClass bug" >&5 +echo "configure:3658: checking for the SunOS 4.1.x _get_wmShellWidgetClass bug" >&5 if eval "test \"`echo '$''{'ac_cv_sunos_xmu_bug'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3648,14 +3656,14 @@ else # with X libraries because we know it's SunOS. LDFLAGS="$LDFLAGS -lXmu -lXt -lX11 -lXext -lm" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_sunos_xmu_bug=no else @@ -3671,21 +3679,21 @@ fi echo "$ac_t""$ac_cv_sunos_xmu_bug" 1>&6 if test "$ac_cv_sunos_xmu_bug" = yes ; then echo $ac_n "checking whether the compiler understands -static""... $ac_c" 1>&6 -echo "configure:3686: checking whether the compiler understands -static" >&5 +echo "configure:3694: checking whether the compiler understands -static" >&5 if eval "test \"`echo '$''{'ac_cv_ld_static'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -static" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_ld_static=yes else @@ -3790,16 +3798,13 @@ else # there must be a better way than this... if test -z "`echo $with_configdir | sed 's@^/.*@@'`" ; then # absolute path - CONFIGDIR=$with_configdir + HACK_CONF_DIR=$with_configdir else # relative path - CONFIGDIR="\${exec_prefix}$with_configdir" + HACK_CONF_DIR="\${exec_prefix}$with_configdir" fi fi -# canonicalize slashes. -CONFIGDIR=`echo "${CONFIGDIR}" | sed 's@/$@@;s@//*@/@g'` - @@ -3827,7 +3832,7 @@ fi /*) echo $ac_n "checking for SGI SCREEN_SAVER headers""... $ac_c" 1>&6 -echo "configure:3842: checking for SGI SCREEN_SAVER headers" >&5 +echo "configure:3847: checking for SGI SCREEN_SAVER headers" >&5 d=$with_sgi/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -3837,7 +3842,7 @@ echo "configure:3842: checking for SGI SCREEN_SAVER headers" >&5 fi echo $ac_n "checking for SGI SCREEN_SAVER libs""... $ac_c" 1>&6 -echo "configure:3852: checking for SGI SCREEN_SAVER libs" >&5 +echo "configure:3857: checking for SGI SCREEN_SAVER libs" >&5 d=$with_sgi/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -3870,17 +3875,17 @@ if test "$with_sgi" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/XScreenSaver.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/XScreenSaver.h""... $ac_c" 1>&6 -echo "configure:3885: checking for X11/extensions/XScreenSaver.h" >&5 +echo "configure:3890: checking for X11/extensions/XScreenSaver.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3895: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3900: \"$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* @@ -3937,7 +3942,7 @@ fi /*) echo $ac_n "checking for MIT-SCREEN-SAVER headers""... $ac_c" 1>&6 -echo "configure:3952: checking for MIT-SCREEN-SAVER headers" >&5 +echo "configure:3957: checking for MIT-SCREEN-SAVER headers" >&5 d=$with_mit/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -3947,7 +3952,7 @@ echo "configure:3952: checking for MIT-SCREEN-SAVER headers" >&5 fi echo $ac_n "checking for MIT-SCREEN-SAVER libs""... $ac_c" 1>&6 -echo "configure:3962: checking for MIT-SCREEN-SAVER libs" >&5 +echo "configure:3967: checking for MIT-SCREEN-SAVER libs" >&5 d=$with_mit/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -3980,17 +3985,17 @@ if test "$with_mit" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/scrnsaver.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/scrnsaver.h""... $ac_c" 1>&6 -echo "configure:3995: checking for X11/extensions/scrnsaver.h" >&5 +echo "configure:4000: checking for X11/extensions/scrnsaver.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4005: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4010: \"$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* @@ -4035,7 +4040,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XScreenSaverRegister in -lXext""... $ac_c" 1>&6 -echo "configure:4050: checking for XScreenSaverRegister in -lXext" >&5 +echo "configure:4055: checking for XScreenSaverRegister in -lXext" >&5 ac_lib_var=`echo Xext'_'XScreenSaverRegister | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4043,7 +4048,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4074: \"$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 @@ -4101,7 +4106,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XScreenSaverRegister in -lXExExt""... $ac_c" 1>&6 -echo "configure:4116: checking for XScreenSaverRegister in -lXExExt" >&5 +echo "configure:4121: checking for XScreenSaverRegister in -lXExExt" >&5 ac_lib_var=`echo XExExt'_'XScreenSaverRegister | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4109,7 +4114,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXExExt -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4140: \"$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 @@ -4170,7 +4175,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XScreenSaverRegister in -lXss""... $ac_c" 1>&6 -echo "configure:4185: checking for XScreenSaverRegister in -lXss" >&5 +echo "configure:4190: checking for XScreenSaverRegister in -lXss" >&5 ac_lib_var=`echo Xss'_'XScreenSaverRegister | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4178,7 +4183,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXss -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4209: \"$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 @@ -4255,7 +4260,7 @@ fi /*) echo $ac_n "checking for XIDLE headers""... $ac_c" 1>&6 -echo "configure:4270: checking for XIDLE headers" >&5 +echo "configure:4275: checking for XIDLE headers" >&5 d=$with_xidle/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -4265,7 +4270,7 @@ echo "configure:4270: checking for XIDLE headers" >&5 fi echo $ac_n "checking for XIDLE libs""... $ac_c" 1>&6 -echo "configure:4280: checking for XIDLE libs" >&5 +echo "configure:4285: checking for XIDLE libs" >&5 d=$with_xidle/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -4298,17 +4303,17 @@ if test "$with_xidle" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/xidle.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/xidle.h""... $ac_c" 1>&6 -echo "configure:4313: checking for X11/extensions/xidle.h" >&5 +echo "configure:4318: checking for X11/extensions/xidle.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4323: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4328: \"$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* @@ -4364,7 +4369,7 @@ fi /*) echo $ac_n "checking for SGI-VIDEO-CONTROL headers""... $ac_c" 1>&6 -echo "configure:4379: checking for SGI-VIDEO-CONTROL headers" >&5 +echo "configure:4384: checking for SGI-VIDEO-CONTROL headers" >&5 d=$with_sgivc/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -4374,7 +4379,7 @@ echo "configure:4379: checking for SGI-VIDEO-CONTROL headers" >&5 fi echo $ac_n "checking for SGI-VIDEO-CONTROL libs""... $ac_c" 1>&6 -echo "configure:4389: checking for SGI-VIDEO-CONTROL libs" >&5 +echo "configure:4394: checking for SGI-VIDEO-CONTROL libs" >&5 d=$with_sgivc/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -4409,17 +4414,17 @@ if test "$with_sgivc" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/XSGIvc.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/XSGIvc.h""... $ac_c" 1>&6 -echo "configure:4424: checking for X11/extensions/XSGIvc.h" >&5 +echo "configure:4429: checking for X11/extensions/XSGIvc.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4434: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4439: \"$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* @@ -4463,7 +4468,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XSGIvcQueryGammaMap in -lXsgivc""... $ac_c" 1>&6 -echo "configure:4478: checking for XSGIvcQueryGammaMap in -lXsgivc" >&5 +echo "configure:4483: checking for XSGIvcQueryGammaMap in -lXsgivc" >&5 ac_lib_var=`echo Xsgivc'_'XSGIvcQueryGammaMap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4471,7 +4476,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXsgivc -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4502: \"$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 @@ -4547,7 +4552,7 @@ fi /*) echo $ac_n "checking for DPMS headers""... $ac_c" 1>&6 -echo "configure:4562: checking for DPMS headers" >&5 +echo "configure:4567: checking for DPMS headers" >&5 d=$with_dpms/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -4557,7 +4562,7 @@ echo "configure:4562: checking for DPMS headers" >&5 fi echo $ac_n "checking for DPMS libs""... $ac_c" 1>&6 -echo "configure:4572: checking for DPMS libs" >&5 +echo "configure:4577: checking for DPMS libs" >&5 d=$with_dpms/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -4592,17 +4597,17 @@ if test "$with_dpms" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/dpms.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/dpms.h""... $ac_c" 1>&6 -echo "configure:4607: checking for X11/extensions/dpms.h" >&5 +echo "configure:4612: checking for X11/extensions/dpms.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4617: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4622: \"$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* @@ -4648,7 +4653,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for DPMSInfo in -lXext""... $ac_c" 1>&6 -echo "configure:4663: checking for DPMSInfo in -lXext" >&5 +echo "configure:4668: checking for DPMSInfo in -lXext" >&5 ac_lib_var=`echo Xext'_'DPMSInfo | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4656,7 +4661,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXext -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4687: \"$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 @@ -4713,7 +4718,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for DPMSInfo in -lXdpms""... $ac_c" 1>&6 -echo "configure:4728: checking for DPMSInfo in -lXdpms" >&5 +echo "configure:4733: checking for DPMSInfo in -lXdpms" >&5 ac_lib_var=`echo Xdpms'_'DPMSInfo | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4721,7 +4726,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXdpms -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4752: \"$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 @@ -4799,7 +4804,7 @@ fi /*) echo $ac_n "checking for XINERAMA headers""... $ac_c" 1>&6 -echo "configure:4814: checking for XINERAMA headers" >&5 +echo "configure:4819: checking for XINERAMA headers" >&5 d=$with_xinerama/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -4809,7 +4814,7 @@ echo "configure:4814: checking for XINERAMA headers" >&5 fi echo $ac_n "checking for XINERAMA libs""... $ac_c" 1>&6 -echo "configure:4824: checking for XINERAMA libs" >&5 +echo "configure:4829: checking for XINERAMA libs" >&5 d=$with_xinerama/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -4844,17 +4849,17 @@ if test "$with_xinerama" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/Xinerama.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/Xinerama.h""... $ac_c" 1>&6 -echo "configure:4859: checking for X11/extensions/Xinerama.h" >&5 +echo "configure:4864: checking for X11/extensions/Xinerama.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4869: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4874: \"$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* @@ -4900,7 +4905,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XineramaQueryExtension in -lXext""... $ac_c" 1>&6 -echo "configure:4915: checking for XineramaQueryExtension in -lXext" >&5 +echo "configure:4920: checking for XineramaQueryExtension in -lXext" >&5 ac_lib_var=`echo Xext'_'XineramaQueryExtension | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4908,7 +4913,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXext -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4939: \"$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 @@ -4965,7 +4970,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XineramaQueryExtension in -lXinerama""... $ac_c" 1>&6 -echo "configure:4980: checking for XineramaQueryExtension in -lXinerama" >&5 +echo "configure:4985: checking for XineramaQueryExtension in -lXinerama" >&5 ac_lib_var=`echo Xinerama'_'XineramaQueryExtension | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4973,7 +4978,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXinerama -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5004: \"$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 @@ -5050,7 +5055,7 @@ fi /*) echo $ac_n "checking for xf86vmode headers""... $ac_c" 1>&6 -echo "configure:5065: checking for xf86vmode headers" >&5 +echo "configure:5070: checking for xf86vmode headers" >&5 d=$with_xf86vmode/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -5060,7 +5065,7 @@ echo "configure:5065: checking for xf86vmode headers" >&5 fi echo $ac_n "checking for xf86vmode libs""... $ac_c" 1>&6 -echo "configure:5075: checking for xf86vmode libs" >&5 +echo "configure:5080: checking for xf86vmode libs" >&5 d=$with_xf86vmode/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -5095,17 +5100,17 @@ if test "$with_xf86vmode" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/xf86vmode.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/xf86vmode.h""... $ac_c" 1>&6 -echo "configure:5110: checking for X11/extensions/xf86vmode.h" >&5 +echo "configure:5115: checking for X11/extensions/xf86vmode.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5125: \"$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* @@ -5149,7 +5154,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XF86VidModeGetViewPort in -lXxf86vm""... $ac_c" 1>&6 -echo "configure:5164: checking for XF86VidModeGetViewPort in -lXxf86vm" >&5 +echo "configure:5169: checking for XF86VidModeGetViewPort in -lXxf86vm" >&5 ac_lib_var=`echo Xxf86vm'_'XF86VidModeGetViewPort | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5157,7 +5162,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXxf86vm -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5188: \"$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 @@ -5234,7 +5239,7 @@ fi /*) echo $ac_n "checking for xf86gamma headers""... $ac_c" 1>&6 -echo "configure:5249: checking for xf86gamma headers" >&5 +echo "configure:5254: checking for xf86gamma headers" >&5 d=$with_xf86gamma/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -5244,7 +5249,7 @@ echo "configure:5249: checking for xf86gamma headers" >&5 fi echo $ac_n "checking for xf86gamma libs""... $ac_c" 1>&6 -echo "configure:5259: checking for xf86gamma libs" >&5 +echo "configure:5264: checking for xf86gamma libs" >&5 d=$with_xf86gamma/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -5282,17 +5287,17 @@ if test "$with_xf86gamma" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/xf86vmode.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/xf86vmode.h""... $ac_c" 1>&6 -echo "configure:5297: checking for X11/extensions/xf86vmode.h" >&5 +echo "configure:5302: checking for X11/extensions/xf86vmode.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5307: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5312: \"$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* @@ -5337,7 +5342,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XF86VidModeSetGamma in -lXxf86vm""... $ac_c" 1>&6 -echo "configure:5352: checking for XF86VidModeSetGamma in -lXxf86vm" >&5 +echo "configure:5357: checking for XF86VidModeSetGamma in -lXxf86vm" >&5 ac_lib_var=`echo Xxf86vm'_'XF86VidModeSetGamma | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5345,7 +5350,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXxf86vm -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5376: \"$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 @@ -5404,7 +5409,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XF86VidModeSetGammaRamp in -lXxf86vm""... $ac_c" 1>&6 -echo "configure:5419: checking for XF86VidModeSetGammaRamp in -lXxf86vm" >&5 +echo "configure:5424: checking for XF86VidModeSetGammaRamp in -lXxf86vm" >&5 ac_lib_var=`echo Xxf86vm'_'XF86VidModeSetGammaRamp | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5412,7 +5417,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXxf86vm -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5443: \"$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 @@ -5489,7 +5494,7 @@ fi fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < EOF @@ -5527,7 +5532,7 @@ fi if test "$with_proc_interrupts" = yes; then echo $ac_n "checking whether /proc/interrupts contains keyboard data""... $ac_c" 1>&6 -echo "configure:5542: checking whether /proc/interrupts contains keyboard data" >&5 +echo "configure:5547: checking whether /proc/interrupts contains keyboard data" >&5 if eval "test \"`echo '$''{'ac_cv_have_proc_interrupts'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5660,7 +5665,7 @@ fi /*) echo $ac_n "checking for PAM headers""... $ac_c" 1>&6 -echo "configure:5675: checking for PAM headers" >&5 +echo "configure:5680: checking for PAM headers" >&5 d=$with_pam/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -5670,7 +5675,7 @@ echo "configure:5675: checking for PAM headers" >&5 fi echo $ac_n "checking for PAM libs""... $ac_c" 1>&6 -echo "configure:5685: checking for PAM libs" >&5 +echo "configure:5690: checking for PAM libs" >&5 d=$with_pam/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -5696,7 +5701,7 @@ echo "configure:5685: checking for PAM libs" >&5 if test "$enable_locking" = yes -a "$with_pam" = yes; then echo $ac_n "checking for PAM""... $ac_c" 1>&6 -echo "configure:5711: checking for PAM" >&5 +echo "configure:5716: checking for PAM" >&5 if eval "test \"`echo '$''{'ac_cv_pam'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5707,14 +5712,14 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < int main() { ; return 0; } EOF -if { (eval echo configure:5729: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5734: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_pam=yes else @@ -5739,7 +5744,7 @@ EOF # libpam typically requires dlopen and dlsym. On FreeBSD, # those are in libc. On Linux and Solaris, they're in libdl. echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:5754: checking for dlopen in -ldl" >&5 +echo "configure:5759: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5747,7 +5752,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5778: \"$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 @@ -5780,12 +5785,12 @@ fi echo $ac_n "checking how to call pam_strerror""... $ac_c" 1>&6 -echo "configure:5795: checking how to call pam_strerror" >&5 +echo "configure:5800: checking how to call pam_strerror" >&5 if eval "test \"`echo '$''{'ac_cv_pam_strerror_args'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5795,7 +5800,7 @@ pam_handle_t *pamh = 0; char *s = pam_strerror(pamh, PAM_SUCCESS); ; return 0; } EOF -if { (eval echo configure:5810: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5815: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_pam_strerror_args=2 else @@ -5803,7 +5808,7 @@ else cat conftest.$ac_ext >&5 rm -rf conftest* cat > conftest.$ac_ext < #include @@ -5813,7 +5818,7 @@ char *s = pam_strerror(PAM_SUCCESS); ; return 0; } EOF -if { (eval echo configure:5828: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5833: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_pam_strerror_args=1 else @@ -5870,7 +5875,7 @@ fi /*) echo $ac_n "checking for Kerberos headers""... $ac_c" 1>&6 -echo "configure:5885: checking for Kerberos headers" >&5 +echo "configure:5890: checking for Kerberos headers" >&5 d=$with_kerberos/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -5880,7 +5885,7 @@ echo "configure:5885: checking for Kerberos headers" >&5 fi echo $ac_n "checking for Kerberos libs""... $ac_c" 1>&6 -echo "configure:5895: checking for Kerberos libs" >&5 +echo "configure:5900: checking for Kerberos libs" >&5 d=$with_kerberos/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -5906,7 +5911,7 @@ echo "configure:5895: checking for Kerberos libs" >&5 if test "$enable_locking" = yes -a "$with_kerberos" = yes; then echo $ac_n "checking for Kerberos 4""... $ac_c" 1>&6 -echo "configure:5921: checking for Kerberos 4" >&5 +echo "configure:5926: checking for Kerberos 4" >&5 if eval "test \"`echo '$''{'ac_cv_kerberos'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5917,14 +5922,14 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < int main() { ; return 0; } EOF -if { (eval echo configure:5939: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5944: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_kerberos=yes else @@ -5939,7 +5944,7 @@ fi echo "$ac_t""$ac_cv_kerberos" 1>&6 echo $ac_n "checking for Kerberos 5""... $ac_c" 1>&6 -echo "configure:5954: checking for Kerberos 5" >&5 +echo "configure:5959: checking for Kerberos 5" >&5 if eval "test \"`echo '$''{'ac_cv_kerberos5'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5950,14 +5955,14 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < int main() { ; return 0; } EOF -if { (eval echo configure:5972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_kerberos5=yes else @@ -5998,18 +6003,18 @@ EOF # (who got it from amu@mit.edu) PASSWD_LIBS="$PASSWD_LIBS -lkrb4 -ldes425 -lkrb5 -lk5crypto -lcrypt -lcom_err" elif test "$have_kerberos" = yes ; then - # from Tim Showalter - PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes" + # from Tim Showalter for FreeBSD 4.2 + PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes -lcom_err" fi if test "$have_kerberos" = yes ; then echo $ac_n "checking for res_search""... $ac_c" 1>&6 -echo "configure:6019: checking for res_search" >&5 +echo "configure:6024: checking for res_search" >&5 if eval "test \"`echo '$''{'ac_cv_func_res_search'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_res_search=yes" else @@ -6050,7 +6055,7 @@ if eval "test \"`echo '$ac_cv_func_'res_search`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for res_search in -lresolv""... $ac_c" 1>&6 -echo "configure:6065: checking for res_search in -lresolv" >&5 +echo "configure:6070: checking for res_search in -lresolv" >&5 ac_lib_var=`echo resolv'_'res_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6058,7 +6063,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6089: \"$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 @@ -6124,7 +6129,7 @@ fi /*) echo $ac_n "checking for shadow password headers""... $ac_c" 1>&6 -echo "configure:6139: checking for shadow password headers" >&5 +echo "configure:6144: checking for shadow password headers" >&5 d=$with_shadow/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -6134,7 +6139,7 @@ echo "configure:6139: checking for shadow password headers" >&5 fi echo $ac_n "checking for shadow password libs""... $ac_c" 1>&6 -echo "configure:6149: checking for shadow password libs" >&5 +echo "configure:6154: checking for shadow password libs" >&5 d=$with_shadow/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -6172,7 +6177,7 @@ fi if test "$with_shadow" = yes ; then echo $ac_n "checking for Sun-style shadow passwords""... $ac_c" 1>&6 -echo "configure:6187: checking for Sun-style shadow passwords" >&5 +echo "configure:6192: checking for Sun-style shadow passwords" >&5 if eval "test \"`echo '$''{'ac_cv_sun_adjunct'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6183,7 +6188,7 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < #include @@ -6196,7 +6201,7 @@ struct passwd_adjunct *p = getpwanam("nobody"); const char *pw = p->pwa_passwd; ; return 0; } EOF -if { (eval echo configure:6211: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6216: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_sun_adjunct=yes else @@ -6226,7 +6231,7 @@ fi if test "$with_shadow" = yes ; then echo $ac_n "checking for DEC-style shadow passwords""... $ac_c" 1>&6 -echo "configure:6241: checking for DEC-style shadow passwords" >&5 +echo "configure:6246: checking for DEC-style shadow passwords" >&5 if eval "test \"`echo '$''{'ac_cv_enhanced_passwd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6237,7 +6242,7 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < #include @@ -6254,7 +6259,7 @@ struct pr_passwd *p; pw = p->ufld.fd_encrypt; ; return 0; } EOF -if { (eval echo configure:6269: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6274: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_enhanced_passwd=yes else @@ -6278,7 +6283,7 @@ echo "$ac_t""$ac_cv_enhanced_passwd" 1>&6 # But on DEC, it's in -lsecurity. # echo $ac_n "checking for getprpwnam in -lprot""... $ac_c" 1>&6 -echo "configure:6293: checking for getprpwnam in -lprot" >&5 +echo "configure:6298: checking for getprpwnam in -lprot" >&5 ac_lib_var=`echo prot'_'getprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6286,7 +6291,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lprot -lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6317: \"$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 @@ -6316,7 +6321,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:6331: checking for getprpwnam in -lsecurity" >&5 +echo "configure:6336: checking for getprpwnam in -lsecurity" >&5 ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6324,7 +6329,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6355: \"$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 @@ -6368,7 +6373,7 @@ fi if test "$with_shadow" = yes ; then echo $ac_n "checking for HP-style shadow passwords""... $ac_c" 1>&6 -echo "configure:6383: checking for HP-style shadow passwords" >&5 +echo "configure:6388: checking for HP-style shadow passwords" >&5 if eval "test \"`echo '$''{'ac_cv_hpux_passwd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6379,7 +6384,7 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < #include @@ -6392,7 +6397,7 @@ struct s_passwd *p = getspwnam("nobody"); const char *pw = p->pw_passwd; ; return 0; } EOF -if { (eval echo configure:6407: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6412: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_hpux_passwd=yes else @@ -6413,7 +6418,7 @@ echo "$ac_t""$ac_cv_hpux_passwd" 1>&6 # on HPUX, bigcrypt is in -lsec echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6 -echo "configure:6428: checking for bigcrypt in -lsec" >&5 +echo "configure:6433: checking for bigcrypt in -lsec" >&5 ac_lib_var=`echo sec'_'bigcrypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6421,7 +6426,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6470,7 +6475,7 @@ fi if test "$with_shadow" = yes ; then echo $ac_n "checking for FreeBSD-style shadow passwords""... $ac_c" 1>&6 -echo "configure:6485: checking for FreeBSD-style shadow passwords" >&5 +echo "configure:6490: checking for FreeBSD-style shadow passwords" >&5 if eval "test \"`echo '$''{'ac_cv_master_passwd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6496,7 +6501,7 @@ fi if test "$with_shadow" = yes ; then echo $ac_n "checking for generic shadow passwords""... $ac_c" 1>&6 -echo "configure:6511: checking for generic shadow passwords" >&5 +echo "configure:6516: checking for generic shadow passwords" >&5 if eval "test \"`echo '$''{'ac_cv_shadow'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6507,7 +6512,7 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < #include @@ -6519,7 +6524,7 @@ struct spwd *p = getspnam("nobody"); const char *pw = p->sp_pwdp; ; return 0; } EOF -if { (eval echo configure:6534: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6539: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_shadow=yes else @@ -6540,7 +6545,7 @@ echo "$ac_t""$ac_cv_shadow" 1>&6 # On some systems (UnixWare 2.1), getspnam() is in -lgen instead of -lc. have_getspnam=no echo $ac_n "checking for getspnam in -lc""... $ac_c" 1>&6 -echo "configure:6555: checking for getspnam in -lc" >&5 +echo "configure:6560: checking for getspnam in -lc" >&5 ac_lib_var=`echo c'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6548,7 +6553,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6579: \"$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 @@ -6581,7 +6586,7 @@ fi if test "$have_getspnam" = no ; then echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6 -echo "configure:6596: checking for getspnam in -lgen" >&5 +echo "configure:6601: checking for getspnam in -lgen" >&5 ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6589,7 +6594,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgen $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6620: \"$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 @@ -6636,7 +6641,7 @@ if test "$enable_locking" = yes ; then # On some systems (UnixWare 2.1), crypt() is in -lcrypt instead of -lc. have_crypt=no echo $ac_n "checking for crypt in -lc""... $ac_c" 1>&6 -echo "configure:6651: checking for crypt in -lc" >&5 +echo "configure:6656: checking for crypt in -lc" >&5 ac_lib_var=`echo c'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6644,7 +6649,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6675: \"$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 @@ -6677,7 +6682,7 @@ fi if test "$have_crypt" = no ; then echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:6692: checking for crypt in -lcrypt" >&5 +echo "configure:6697: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6685,7 +6690,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6716: \"$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 @@ -6780,7 +6785,7 @@ fi /*) echo $ac_n "checking for Motif headers""... $ac_c" 1>&6 -echo "configure:6795: checking for Motif headers" >&5 +echo "configure:6800: checking for Motif headers" >&5 d=$with_motif/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -6790,7 +6795,7 @@ echo "configure:6795: checking for Motif headers" >&5 fi echo $ac_n "checking for Motif libs""... $ac_c" 1>&6 -echo "configure:6805: checking for Motif libs" >&5 +echo "configure:6810: checking for Motif libs" >&5 d=$with_motif/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -6829,17 +6834,17 @@ if test "$with_motif" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "Xm/Xm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for Xm/Xm.h""... $ac_c" 1>&6 -echo "configure:6844: checking for Xm/Xm.h" >&5 +echo "configure:6849: checking for Xm/Xm.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6854: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6859: \"$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* @@ -6878,17 +6883,17 @@ if test "$have_motif" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "Xm/ComboBox.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for Xm/ComboBox.h""... $ac_c" 1>&6 -echo "configure:6893: checking for Xm/ComboBox.h" >&5 +echo "configure:6898: checking for Xm/ComboBox.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6903: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6908: \"$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* @@ -6951,7 +6956,7 @@ esac /*) echo $ac_n "checking for Gtk headers""... $ac_c" 1>&6 -echo "configure:6966: checking for Gtk headers" >&5 +echo "configure:6971: checking for Gtk headers" >&5 d=$with_gtk/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -6961,7 +6966,7 @@ echo "configure:6966: checking for Gtk headers" >&5 fi echo $ac_n "checking for Gtk libs""... $ac_c" 1>&6 -echo "configure:6976: checking for Gtk libs" >&5 +echo "configure:6981: checking for Gtk libs" >&5 d=$with_gtk/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -7019,7 +7024,7 @@ esac /*) echo $ac_n "checking for Gnome headers""... $ac_c" 1>&6 -echo "configure:7034: checking for Gnome headers" >&5 +echo "configure:7039: checking for Gnome headers" >&5 d=$with_gnome/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -7029,7 +7034,7 @@ echo "configure:7034: checking for Gnome headers" >&5 fi echo $ac_n "checking for Gnome libs""... $ac_c" 1>&6 -echo "configure:7044: checking for Gnome libs" >&5 +echo "configure:7049: checking for Gnome libs" >&5 d=$with_gnome/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -7085,7 +7090,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7100: checking for $ac_word" >&5 +echo "configure:7105: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_glib_config'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7125,7 +7130,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7140: checking for $ac_word" >&5 +echo "configure:7145: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_gtk_config'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7167,7 +7172,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7182: checking for $ac_word" >&5 +echo "configure:7187: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_gnome_config'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7213,7 +7218,7 @@ done if test "$have_gtk" = yes; then echo $ac_n "checking Gtk version number""... $ac_c" 1>&6 -echo "configure:7228: checking Gtk version number" >&5 +echo "configure:7233: checking Gtk version number" >&5 if eval "test \"`echo '$''{'ac_cv_gtk_version_string'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7242,7 +7247,7 @@ echo "$ac_t""$ac_cv_gtk_version_string" 1>&6 if test "$have_gtk" = yes; then echo $ac_n "checking for Gtk includes""... $ac_c" 1>&6 -echo "configure:7257: checking for Gtk includes" >&5 +echo "configure:7262: checking for Gtk includes" >&5 if eval "test \"`echo '$''{'ac_cv_gtk_config_cflags'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7251,7 +7256,7 @@ fi echo "$ac_t""$ac_cv_gtk_config_cflags" 1>&6 echo $ac_n "checking for Gtk libs""... $ac_c" 1>&6 -echo "configure:7266: checking for Gtk libs" >&5 +echo "configure:7271: checking for Gtk libs" >&5 if eval "test \"`echo '$''{'ac_cv_gtk_config_libs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7266,9 +7271,9 @@ echo "$ac_t""$ac_cv_gtk_config_libs" 1>&6 # Check for Gnome Capplet support. # if test "$have_gnome" = yes -a "$have_gtk" = yes; then - gnome_config_libs="gtk capplet gnomeui xml" + gnome_config_libs="gtk capplet gnomeui xml gdk_pixbuf" echo $ac_n "checking for Gnome capplet includes""... $ac_c" 1>&6 -echo "configure:7283: checking for Gnome capplet includes" >&5 +echo "configure:7288: checking for Gnome capplet includes" >&5 if eval "test \"`echo '$''{'ac_cv_gnome_config_cflags'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7291,7 +7296,7 @@ fi if test "$have_gnome" = yes -a "$have_gtk" = yes; then echo $ac_n "checking for Gnome capplet libs""... $ac_c" 1>&6 -echo "configure:7306: checking for Gnome capplet libs" >&5 +echo "configure:7311: checking for Gnome capplet libs" >&5 if eval "test \"`echo '$''{'ac_cv_gnome_config_libs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7328,6 +7333,73 @@ fi #define HAVE_CRAPPLET 1 EOF + + # check for this function that was not in libcapplet 1.2. + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + echo $ac_n "checking for capplet_widget_changes_are_immediate in -lcapplet""... $ac_c" 1>&6 +echo "configure:7368: checking for capplet_widget_changes_are_immediate in -lcapplet" >&5 +ac_lib_var=`echo capplet'_'capplet_widget_changes_are_immediate | 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="-lcapplet $ac_gnome_config_libs $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_CRAPPLET_IMMEDIATE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + fi @@ -7349,7 +7421,7 @@ if test "$have_gnome" = yes; then # Extract the first word of "gnome-help-browser", so it can be a program name with args. set dummy gnome-help-browser; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7364: checking for $ac_word" >&5 +echo "configure:7436: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_have_gnome_help'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7389,6 +7461,7 @@ fi have_xml=no with_xml_req=unspecified +xml_halfassed=no # Check whether --with-xml or --without-xml was given. if test "${with_xml+set}" = set; then withval="$with_xml" @@ -7405,7 +7478,7 @@ fi /*) echo $ac_n "checking for XML headers""... $ac_c" 1>&6 -echo "configure:7420: checking for XML headers" >&5 +echo "configure:7493: checking for XML headers" >&5 d=$with_xml/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -7415,7 +7488,7 @@ echo "configure:7420: checking for XML headers" >&5 fi echo $ac_n "checking for XML libs""... $ac_c" 1>&6 -echo "configure:7430: checking for XML libs" >&5 +echo "configure:7503: checking for XML libs" >&5 d=$with_xml/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -7466,17 +7539,17 @@ if test "$with_xml" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "xmlIO.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for xmlIO.h""... $ac_c" 1>&6 -echo "configure:7481: checking for xmlIO.h" >&5 +echo "configure:7554: checking for xmlIO.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7491: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7564: \"$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* @@ -7502,6 +7575,7 @@ fi if test "$have_xml" = yes; then # we have the header, now check for the library have_xml=no + xml_halfassed=yes ac_save_CPPFLAGS="$CPPFLAGS" ac_save_LDFLAGS="$LDFLAGS" @@ -7520,7 +7594,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for xmlParseChunk in -lxml""... $ac_c" 1>&6 -echo "configure:7535: checking for xmlParseChunk in -lxml" >&5 +echo "configure:7609: checking for xmlParseChunk in -lxml" >&5 ac_lib_var=`echo xml'_'xmlParseChunk | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7528,7 +7602,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lxml $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7628: \"$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 @@ -7555,6 +7629,7 @@ fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 have_xml=yes + xml_halfassed=no XML_LIBS="-lxml" cat >> confdefs.h <<\EOF #define HAVE_XML 1 @@ -7585,7 +7660,7 @@ fi have_lesstif=no if test "$have_motif" = yes ; then echo $ac_n "checking whether Motif is really LessTif""... $ac_c" 1>&6 -echo "configure:7600: checking whether Motif is really LessTif" >&5 +echo "configure:7675: checking whether Motif is really LessTif" >&5 if eval "test \"`echo '$''{'ac_cv_have_lesstif'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7596,14 +7671,14 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < int main() { long vers = LesstifVersion; ; return 0; } EOF -if { (eval echo configure:7618: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7693: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_lesstif=yes else @@ -7628,7 +7703,7 @@ if test "$have_lesstif" = yes ; then ltv=unknown echo unknown > conftest-lt echo $ac_n "checking LessTif version number""... $ac_c" 1>&6 -echo "configure:7643: checking LessTif version number" >&5 +echo "configure:7718: checking LessTif version number" >&5 if eval "test \"`echo '$''{'ac_cv_lesstif_version_string'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7643,7 +7718,7 @@ else ac_cv_lesstif_version_string=unknown else cat > conftest.$ac_ext < #include @@ -7656,7 +7731,7 @@ else exit(0); } EOF -if { (eval echo configure:7671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:7746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ltv=`cat conftest-lt` ac_cv_lesstif_version=`echo $ltv | sed 's/ .*//'` @@ -7686,7 +7761,7 @@ if test "$have_motif" = yes ; then mtv=unknown echo unknown > conftest-mt echo $ac_n "checking Motif version number""... $ac_c" 1>&6 -echo "configure:7701: checking Motif version number" >&5 +echo "configure:7776: checking Motif version number" >&5 if eval "test \"`echo '$''{'ac_cv_motif_version_string'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7701,7 +7776,7 @@ else ac_cv_motif_version_string=unknown else cat > conftest.$ac_ext < #include @@ -7714,7 +7789,7 @@ else exit(0); } EOF -if { (eval echo configure:7729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:7804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then mtv=`cat conftest-mt` ac_cv_motif_version=`echo $mtv | sed 's/ .*//'` @@ -7758,7 +7833,7 @@ fi motif_requires_xpm=no if test "$have_motif" = yes ; then echo $ac_n "checking whether Motif requires XPM""... $ac_c" 1>&6 -echo "configure:7773: checking whether Motif requires XPM" >&5 +echo "configure:7848: checking whether Motif requires XPM" >&5 if test "$motif_version" = "unknown" || test "$motif_version" -ge 2000 then motif_requires_xpm=yes @@ -7800,7 +7875,7 @@ if test "$have_motif" = yes ; then LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XpQueryExtension in -lXp""... $ac_c" 1>&6 -echo "configure:7815: checking for XpQueryExtension in -lXp" >&5 +echo "configure:7890: checking for XpQueryExtension in -lXp" >&5 ac_lib_var=`echo Xp'_'XpQueryExtension | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7808,7 +7883,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXp -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7909: \"$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 @@ -7873,7 +7948,7 @@ if test "$have_motif" = yes ; then LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for _Xsetlocale in -lXintl""... $ac_c" 1>&6 -echo "configure:7888: checking for _Xsetlocale in -lXintl" >&5 +echo "configure:7963: checking for _Xsetlocale in -lXintl" >&5 ac_lib_var=`echo Xintl'_'_Xsetlocale | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7881,7 +7956,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXintl -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7982: \"$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 @@ -7949,7 +8024,7 @@ fi /*) echo $ac_n "checking for GL headers""... $ac_c" 1>&6 -echo "configure:7964: checking for GL headers" >&5 +echo "configure:8039: checking for GL headers" >&5 d=$with_gl/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -7959,7 +8034,7 @@ echo "configure:7964: checking for GL headers" >&5 fi echo $ac_n "checking for GL libs""... $ac_c" 1>&6 -echo "configure:7974: checking for GL libs" >&5 +echo "configure:8049: checking for GL libs" >&5 d=$with_gl/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -7995,17 +8070,17 @@ if test "$with_gl" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "GL/gl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for GL/gl.h""... $ac_c" 1>&6 -echo "configure:8010: checking for GL/gl.h" >&5 +echo "configure:8085: checking for GL/gl.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8020: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8095: \"$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* @@ -8036,17 +8111,17 @@ fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "GL/glx.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for GL/glx.h""... $ac_c" 1>&6 -echo "configure:8051: checking for GL/glx.h" >&5 +echo "configure:8126: checking for GL/glx.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8061: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8136: \"$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* @@ -8078,7 +8153,7 @@ fi # to link against. # echo $ac_n "checking whether GL is really MesaGL""... $ac_c" 1>&6 -echo "configure:8093: checking whether GL is really MesaGL" >&5 +echo "configure:8168: 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 @@ -8090,7 +8165,7 @@ else fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" cat > conftest.$ac_ext < EOF @@ -8119,7 +8194,7 @@ echo "$ac_t""$ac_cv_have_mesa_gl" 1>&6 # if test "$ac_have_mesa_gl" = yes; then echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 -echo "configure:8134: checking for pthread_create in -lpthread" >&5 +echo "configure:8209: 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 @@ -8127,7 +8202,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8228: \"$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 @@ -8185,7 +8260,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for glXCreateContext in -lMesaGL""... $ac_c" 1>&6 -echo "configure:8200: checking for glXCreateContext in -lMesaGL" >&5 +echo "configure:8275: 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 @@ -8193,7 +8268,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lMesaGL -lMesaGLU $GL_LIBS -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8294: \"$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 @@ -8250,7 +8325,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for glXCreateContext in -lGL""... $ac_c" 1>&6 -echo "configure:8265: checking for glXCreateContext in -lGL" >&5 +echo "configure:8340: 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 @@ -8258,7 +8333,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lGL -lGLU $GL_LIBS -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8359: \"$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 @@ -8327,12 +8402,12 @@ EOF if test "$ac_have_mesa_gl" = yes; then echo $ac_n "checking MesaGL version number""... $ac_c" 1>&6 -echo "configure:8342: checking MesaGL version number" >&5 +echo "configure:8417: 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 < #ifndef MESA_MAJOR_VERSION @@ -8403,7 +8478,7 @@ echo "$ac_t""$ac_cv_mesagl_version_string" 1>&6 LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for glBindTexture in -l$gl_lib_1""... $ac_c" 1>&6 -echo "configure:8418: checking for glBindTexture in -l$gl_lib_1" >&5 +echo "configure:8493: 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 @@ -8411,7 +8486,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$gl_lib_1 $GL_LIBS -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8512: \"$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 @@ -8483,7 +8558,7 @@ fi /*) echo $ac_n "checking for GLE headers""... $ac_c" 1>&6 -echo "configure:8498: checking for GLE headers" >&5 +echo "configure:8573: checking for GLE headers" >&5 d=$with_gle/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -8493,7 +8568,7 @@ echo "configure:8498: checking for GLE headers" >&5 fi echo $ac_n "checking for GLE libs""... $ac_c" 1>&6 -echo "configure:8508: checking for GLE libs" >&5 +echo "configure:8583: checking for GLE libs" >&5 d=$with_gle/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -8529,17 +8604,17 @@ if test "$with_gle" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "GL/gle.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for GL/gle.h""... $ac_c" 1>&6 -echo "configure:8544: checking for GL/gle.h" >&5 +echo "configure:8619: checking for GL/gle.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8554: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8629: \"$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* @@ -8572,17 +8647,17 @@ fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "GL/gutil.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for GL/gutil.h""... $ac_c" 1>&6 -echo "configure:8587: checking for GL/gutil.h" >&5 +echo "configure:8662: checking for GL/gutil.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8597: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8672: \"$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* @@ -8613,17 +8688,17 @@ fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "GL/tube.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for GL/tube.h""... $ac_c" 1>&6 -echo "configure:8628: checking for GL/tube.h" >&5 +echo "configure:8703: checking for GL/tube.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8638: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8713: \"$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* @@ -8669,7 +8744,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for gleCreateGC in -lgle""... $ac_c" 1>&6 -echo "configure:8684: checking for gleCreateGC in -lgle" >&5 +echo "configure:8759: checking for gleCreateGC in -lgle" >&5 ac_lib_var=`echo gle'_'gleCreateGC | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8677,7 +8752,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgle $GL_LIBS -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8778: \"$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 @@ -8748,7 +8823,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for uview_direction in -lgle""... $ac_c" 1>&6 -echo "configure:8763: checking for uview_direction in -lgle" >&5 +echo "configure:8838: checking for uview_direction in -lgle" >&5 ac_lib_var=`echo gle'_'uview_direction | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8756,7 +8831,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgle $GL_LIBS -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8857: \"$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 @@ -8812,7 +8887,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for uview_direction_d in -lmatrix""... $ac_c" 1>&6 -echo "configure:8827: checking for uview_direction_d in -lmatrix" >&5 +echo "configure:8902: checking for uview_direction_d in -lmatrix" >&5 ac_lib_var=`echo matrix'_'uview_direction_d | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8820,7 +8895,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmatrix $GL_LIBS -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8921: \"$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 @@ -8904,7 +8979,7 @@ fi /*) echo $ac_n "checking for XPM headers""... $ac_c" 1>&6 -echo "configure:8919: checking for XPM headers" >&5 +echo "configure:8994: checking for XPM headers" >&5 d=$with_xpm/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -8914,7 +8989,7 @@ echo "configure:8919: checking for XPM headers" >&5 fi echo $ac_n "checking for XPM libs""... $ac_c" 1>&6 -echo "configure:8929: checking for XPM libs" >&5 +echo "configure:9004: checking for XPM libs" >&5 d=$with_xpm/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -8947,17 +9022,17 @@ if test "$with_xpm" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/xpm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/xpm.h""... $ac_c" 1>&6 -echo "configure:8962: checking for X11/xpm.h" >&5 +echo "configure:9037: checking for X11/xpm.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8972: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9047: \"$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* @@ -8999,6 +9074,356 @@ if test "$have_motif" = yes -a "$have_xpm" = yes ; then fi +############################################################################### +# +# Check for -lgdk_pixbuf. +# +############################################################################### + +have_gdk_pixbuf=no +with_gdk_pixbuf_req=unspecified +# Check whether --with-pixbuf or --without-pixbuf was given. +if test "${with_pixbuf+set}" = set; then + withval="$with_pixbuf" + with_gdk_pixbuf="$withval"; with_gdk_pixbuf_req="$withval" +else + with_gdk_pixbuf=yes +fi + + + + case "$with_gdk_pixbuf" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for GDK_PIXBUF headers""... $ac_c" 1>&6 +echo "configure:9113: checking for GDK_PIXBUF headers" >&5 + d=$with_gdk_pixbuf/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for GDK_PIXBUF libs""... $ac_c" 1>&6 +echo "configure:9123: checking for GDK_PIXBUF libs" >&5 + d=$with_gdk_pixbuf/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_gdk_pixbuf_req="yes" + with_gdk_pixbuf=$with_gdk_pixbuf_req + ;; + + *) + echo "" + echo "error: argument to --with-pixbuf must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_gdk_pixbuf" = yes; then + + if test "$have_gtk" = yes; then + + ac_save_gdk_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ac_gtk_config_cflags" + + have_gdk_pixbuf=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "gdk-pixbuf/gdk-pixbuf.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for gdk-pixbuf/gdk-pixbuf.h""... $ac_c" 1>&6 +echo "configure:9163: checking for gdk-pixbuf/gdk-pixbuf.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:9173: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_gdk_pixbuf=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "gdk-pixbuf/gdk-pixbuf-xlib.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for gdk-pixbuf/gdk-pixbuf-xlib.h""... $ac_c" 1>&6 +echo "configure:9205: checking for gdk-pixbuf/gdk-pixbuf-xlib.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:9215: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_gdk_pixbuf=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + + CPPFLAGS="$ac_save_gdk_CPPFLAGS" + + if test "$have_gdk_pixbuf" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_GDK_PIXBUF 1 +EOF + + XPM_LIBS="-lgdk_pixbuf -lgdk_pixbuf_xlib" + fi + fi + +elif test "$with_gdk_pixbuf" != no; then + echo "error: must be yes or no: --with-pixbuf=$with_gdk_pixbuf" + exit 1 +fi + + +############################################################################### +# +# Check for -ljpeg +# +############################################################################### + +have_jpeg=no +with_jpeg_req=unspecified +jpeg_halfassed=no +# Check whether --with-jpeg or --without-jpeg was given. +if test "${with_jpeg+set}" = set; then + withval="$with_jpeg" + with_jpeg="$withval"; with_jpeg_req="$withval" +else + with_jpeg=yes +fi + + + + case "$with_jpeg" in + yes) ;; + no) ;; + + /*) + echo $ac_n "checking for JPEG headers""... $ac_c" 1>&6 +echo "configure:9281: checking for JPEG headers" >&5 + d=$with_jpeg/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + echo $ac_n "checking for JPEG libs""... $ac_c" 1>&6 +echo "configure:9291: checking for JPEG libs" >&5 + d=$with_jpeg/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + echo "$ac_t""$d" 1>&6 + else + echo "$ac_t""not found ($d: no such directory)" 1>&6 + fi + + # replace the directory string with "yes". + with_jpeg_req="yes" + with_jpeg=$with_jpeg_req + ;; + + *) + echo "" + echo "error: argument to --with-jpeg must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_jpeg" != yes -a "$with_jpeg" != no ; then + echo "error: must be yes or no: --with-jpeg=$with_jpeg" + exit 1 +fi + +if test "$with_jpeg" = yes; then + + have_jpeg=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + ac_safe=`echo "jpeglib.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for jpeglib.h""... $ac_c" 1>&6 +echo "configure:9331: checking for jpeglib.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:9341: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_jpeg=yes +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + + if test "$have_jpeg" = yes; then + # we have the header, now check for the library + have_jpeg=no + jpeg_halfassed=yes + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + echo $ac_n "checking for jpeg_start_compress in -ljpeg""... $ac_c" 1>&6 +echo "configure:9386: checking for jpeg_start_compress in -ljpeg" >&5 +ac_lib_var=`echo jpeg'_'jpeg_start_compress | 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="-ljpeg $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + have_jpeg=yes + jpeg_halfassed=no + JPEG_LIBS="-ljpeg" + cat >> confdefs.h <<\EOF +#define HAVE_JPEGLIB 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi +fi + + ############################################################################### # # Check for the XSHM server extension. @@ -9023,7 +9448,7 @@ fi /*) echo $ac_n "checking for XSHM headers""... $ac_c" 1>&6 -echo "configure:9038: checking for XSHM headers" >&5 +echo "configure:9463: checking for XSHM headers" >&5 d=$with_xshm/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -9033,7 +9458,7 @@ echo "configure:9038: checking for XSHM headers" >&5 fi echo $ac_n "checking for XSHM libs""... $ac_c" 1>&6 -echo "configure:9048: checking for XSHM libs" >&5 +echo "configure:9473: checking for XSHM libs" >&5 d=$with_xshm/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -9068,17 +9493,17 @@ if test "$with_xshm" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/XShm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/XShm.h""... $ac_c" 1>&6 -echo "configure:9083: checking for X11/extensions/XShm.h" >&5 +echo "configure:9508: checking for X11/extensions/XShm.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9093: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9518: \"$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* @@ -9112,17 +9537,17 @@ fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "sys/ipc.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/ipc.h""... $ac_c" 1>&6 -echo "configure:9127: checking for sys/ipc.h" >&5 +echo "configure:9552: checking for sys/ipc.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9562: \"$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* @@ -9157,17 +9582,17 @@ fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "sys/shm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/shm.h""... $ac_c" 1>&6 -echo "configure:9172: checking for sys/shm.h" >&5 +echo "configure:9597: checking for sys/shm.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9607: \"$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* @@ -9219,7 +9644,7 @@ fi LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" echo $ac_n "checking for XShmQueryExtension in -lXextSam""... $ac_c" 1>&6 -echo "configure:9234: checking for XShmQueryExtension in -lXextSam" >&5 +echo "configure:9659: 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 @@ -9227,7 +9652,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXextSam -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9678: \"$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 @@ -9305,7 +9730,7 @@ fi /*) echo $ac_n "checking for DOUBLE-BUFFER headers""... $ac_c" 1>&6 -echo "configure:9320: checking for DOUBLE-BUFFER headers" >&5 +echo "configure:9745: checking for DOUBLE-BUFFER headers" >&5 d=$with_xdbe/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -9315,7 +9740,7 @@ echo "configure:9320: checking for DOUBLE-BUFFER headers" >&5 fi echo $ac_n "checking for DOUBLE-BUFFER libs""... $ac_c" 1>&6 -echo "configure:9330: checking for DOUBLE-BUFFER libs" >&5 +echo "configure:9755: checking for DOUBLE-BUFFER libs" >&5 d=$with_xdbe/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -9349,17 +9774,17 @@ if test "$with_xdbe" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/Xdbe.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/Xdbe.h""... $ac_c" 1>&6 -echo "configure:9364: checking for X11/extensions/Xdbe.h" >&5 +echo "configure:9789: checking for X11/extensions/Xdbe.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9374: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9799: \"$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* @@ -9422,7 +9847,7 @@ fi /*) echo $ac_n "checking for XReadDisplay headers""... $ac_c" 1>&6 -echo "configure:9437: checking for XReadDisplay headers" >&5 +echo "configure:9862: checking for XReadDisplay headers" >&5 d=$with_readdisplay/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -9432,7 +9857,7 @@ echo "configure:9437: checking for XReadDisplay headers" >&5 fi echo $ac_n "checking for XReadDisplay libs""... $ac_c" 1>&6 -echo "configure:9447: checking for XReadDisplay libs" >&5 +echo "configure:9872: checking for XReadDisplay libs" >&5 d=$with_readdisplay/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -9465,17 +9890,17 @@ if test "$with_readdisplay" = yes; then CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_safe=`echo "X11/extensions/readdisplay.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/readdisplay.h""... $ac_c" 1>&6 -echo "configure:9480: checking for X11/extensions/readdisplay.h" >&5 +echo "configure:9905: checking for X11/extensions/readdisplay.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9490: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9915: \"$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* @@ -9540,7 +9965,7 @@ if test -n "$with_fortune_req" ; then set dummy $with_fortune_req ; fortune_tmp=$2 echo $ac_n "checking for $fortune_tmp""... $ac_c" 1>&6 -echo "configure:9555: checking for $fortune_tmp" >&5 +echo "configure:9980: checking for $fortune_tmp" >&5 if test -x "$fortune_tmp" ; then echo "$ac_t""yes" 1>&6 else @@ -9555,7 +9980,7 @@ echo "configure:9555: checking for $fortune_tmp" >&5 # Extract the first word of "$fortune_tmp", so it can be a program name with args. set dummy $fortune_tmp; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:9570: checking for $ac_word" >&5 +echo "configure:9995: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_fortune_tmp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9609,7 +10034,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:9624: checking for $ac_word" >&5 +echo "configure:10049: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_fortune_tmp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9652,7 +10077,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:9667: checking for $ac_word" >&5 +echo "configure:10092: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_fortune_tmp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9694,7 +10119,7 @@ done # fortune_tmp="$fortune_tmp zippy" echo $ac_n "checking for zippy quotes""... $ac_c" 1>&6 -echo "configure:9709: checking for zippy quotes" >&5 +echo "configure:10134: checking for zippy quotes" >&5 if ( $fortune_tmp >/dev/null 2>&1 ); then ac_cv_fortune_program="$fortune_tmp" echo "$ac_t""$fortune_tmp" 1>&6 @@ -9738,7 +10163,7 @@ fi /*) echo $ac_n "checking for setuid hacks headers""... $ac_c" 1>&6 -echo "configure:9753: checking for setuid hacks headers" >&5 +echo "configure:10178: checking for setuid hacks headers" >&5 d=$setuid_hacks/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" @@ -9748,7 +10173,7 @@ echo "configure:9753: checking for setuid hacks headers" >&5 fi echo $ac_n "checking for setuid hacks libs""... $ac_c" 1>&6 -echo "configure:9763: checking for setuid hacks libs" >&5 +echo "configure:10188: checking for setuid hacks libs" >&5 d=$setuid_hacks/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" @@ -9866,6 +10291,10 @@ else GLE_KLUDGE="-${tab} " fi +if test "$have_jpeg" = yes -a "$have_gdk_pixbuf" = yes; then + JPEG_EXES='$(JPEG_EXES)' +fi + # Another substitution in the XScreenSaver.ad.in file: # @@ -9888,6 +10317,10 @@ if test -z "$HACK_CONF_DIR" ; then fi fi +# canonicalize slashes. +HACK_CONF_DIR=`echo "${HACK_CONF_DIR}" | sed 's@/$@@;s@//*@/@g'` + + ############################################################################### # @@ -9935,6 +10368,8 @@ fi + + @@ -10112,6 +10547,7 @@ s%@SAVER_LIBS@%$SAVER_LIBS%g s%@MOTIF_LIBS@%$MOTIF_LIBS%g s%@GTK_LIBS@%$GTK_LIBS%g s%@XML_LIBS@%$XML_LIBS%g +s%@JPEG_LIBS@%$JPEG_LIBS%g s%@HACK_LIBS@%$HACK_LIBS%g s%@XPM_LIBS@%$XPM_LIBS%g s%@GL_LIBS@%$GL_LIBS%g @@ -10133,6 +10569,7 @@ s%@SAVER_GL_OBJS@%$SAVER_GL_OBJS%g s%@SAVER_GL_LIBS@%$SAVER_GL_LIBS%g s%@LOCK_SRCS@%$LOCK_SRCS%g s%@LOCK_OBJS@%$LOCK_OBJS%g +s%@JPEG_EXES@%$JPEG_EXES%g s%@GL_EXES@%$GL_EXES%g s%@GL_UTIL_EXES@%$GL_UTIL_EXES%g s%@GL_MEN@%$GL_MEN%g @@ -10506,17 +10943,33 @@ if test "$with_gnome_req" = yes -a "$have_gnome" = no ; then warn2 'headers and/or libraries were not found.' fi -if test "$with_xml_req" = yes -a "$have_xml" = no ; then - warn 'Use of the XML library was requested, but the necessary' - warn2 'headers and/or libraries were not found.' -elif test "$have_gtk" = yes -a "$have_xml" = no ; then - warn 'GTK is being used, but the XML library was not found.' - warn2 'Some functionality will be disabled.' +if test "$have_gtk" = yes ; then + if test "$have_xml" = no ; then + if test "$with_xml_req" = yes ; then + warn 'Use of the XML library was requested, but the necessary' + warn2 'headers and/or libraries were not found.' + else + warn 'GTK is being used, but the XML library was not found.' + fi + + if test "$xml_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either XML is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 "Without XML, the per-display-mode \`Settings' dialogs" + warn2 'will not be available. Specify the location of the XML' + warn2 'library through the --with-xml option to configure.' + fi fi if test "$have_motif" = yes -a "$have_lesstif" = yes ; then - preferred_lesstif=0.86 + preferred_lesstif=0.92 if test "$lesstif_version" = unknown; then warnL "Unable to determine the LessTif version number!" @@ -10533,22 +10986,77 @@ if test "$have_motif" = yes -a "$have_lesstif" = yes ; then fi +if test "$have_motif" = yes -a "$have_gtk" = no ; then + warn 'Motif is being used, and GTK is not.' + echo '' + warn2 'Though the Motif front-end to xscreensaver is still' + warn2 'maintained, it is no longer being updated with new' + warn2 'features: all new development on the xscreensaver-demo' + warn2 'program is happening in the GTK version, and not in the' + warn2 'Motif version. It is recommended that you build against' + warn2 'GTK instead of Motif. See .' +fi + + +if test "$with_xpm_req" = yes ; then + warnL 'Use of XPM was requested, but it was not found.' +fi + +if test "$with_gdk_pixbuf_req" = yes ; then + warnL 'Use of GDK-Pixbuf was requested, but it was not found.' +fi + +if test "$have_xpm" = no -a "$have_gdk_pixbuf" = no; then -if test "$have_xpm" = no ; then if test "$with_xpm_req" = yes ; then - warnL 'Use of XPM was requested, but it was not found.' + true elif test "$with_xpm_req" = no ; then - noteL 'The XPM library is not being used.' + warnL 'The XPM library is not being used.' + else + warnL 'The XPM library was not found.' + fi + + if test "$with_gdk_pixbuf_req" = yes ; then + true + elif test "$with_gdk_pixbuf_req" = no ; then + warnL 'The GDK-Pixbuf library is not being used.' else - noteL 'The XPM library was not found.' + warnL 'The GDK-Pixbuf library was not found.' fi echo '' warn2 'Some of the demos will not be as colorful as they' - warn2 'could be. You might want to consider installing XPM' - warn2 'and re-running configure. (Remember to delete the' - warn2 'config.cache file first.) You can find XPM at most' - warn2 'X11 archive sites, such as .' + warn2 'could be. You should consider installing Pixbuf or' + warn2 'XPM and re-running configure. (Remember to delete' + warn2 'the config.cache file first.) The Pixbuf library is' + warn2 'a part of GNOME. The XPM library comes with most' + warn2 'X11 installations; you can also find it at the X11' + warn2 'archive sites, such as .' + echo '' + warn2 'GDK-Pixbuf is recommended over XPM, as it provides' + warn2 'support for more image formats.' +fi + + +if test "$have_jpeg" = no ; then + if test "$with_jpeg_req" = yes ; then + warnL 'Use of libjpeg was requested, but it was not found.' + elif test "$with_jpeg_req" = no ; then + noteL 'The JPEG library is not being used.' + else + noteL 'The JPEG library was not found.' + fi + + if test "$jpeg_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'library; so either JPEG is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + echo '' + fi + + warn2 "This means the \`webcollage' program will be much slower." fi @@ -10723,10 +11231,10 @@ if test \! -z "$rpmv" ; then echo "" if test "$rpmbdir" = "$rpmhdir" ; then - warn2 "The RPM version was installed in $rpmbdir." + warn2 "The RPM version was installed in $rpmbdir/." else - warn2 "The RPM version was installed in $rpmbdir," - warn2 "with demos in $rpmhdir." + warn2 "The RPM version was installed in $rpmbdir/," + warn2 "with demos in $rpmhdir/." fi do_dir_warning=yes @@ -10743,10 +11251,10 @@ if test "$do_dir_warning" = yes; then echo "" echo ' When you run "make install", the "xscreensaver",' echo ' "xscreensaver-demo", and "xscreensaver-command" executables' - echo " will be installed in ${bindir}." + echo " will be installed in ${bindir}/." echo "" - echo " The various graphics demos (120+ different executables) will" - echo " also be installed in ${HACKDIR}." + echo " The various graphics demos (140+ different executables) will" + echo " also be installed in ${HACKDIR}/." echo "" echo " If you would prefer the demos to be installed elsewhere" echo " (for example, in a dedicated directory) you should re-run" diff --git a/configure.in b/configure.in index 68a89a58..335afa2f 100644 --- a/configure.in +++ b/configure.in @@ -934,16 +934,13 @@ else # there must be a better way than this... if test -z "`echo $with_configdir | sed 's@^/.*@@'`" ; then # absolute path - CONFIGDIR=$with_configdir + HACK_CONF_DIR=$with_configdir else # relative path - CONFIGDIR="\${exec_prefix}$with_configdir" + HACK_CONF_DIR="\${exec_prefix}$with_configdir" fi fi -# canonicalize slashes. -CONFIGDIR=`echo "${CONFIGDIR}" | sed 's@/$@@;s@//*@/@g'` - @@ -1516,8 +1513,8 @@ if test "$enable_locking" = yes -a "$with_kerberos" = yes; then # (who got it from amu@mit.edu) PASSWD_LIBS="$PASSWD_LIBS -lkrb4 -ldes425 -lkrb5 -lk5crypto -lcrypt -lcom_err" elif test "$have_kerberos" = yes ; then - # from Tim Showalter - PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes" + # from Tim Showalter for FreeBSD 4.2 + PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes -lcom_err" fi if test "$have_kerberos" = yes ; then @@ -1904,7 +1901,7 @@ if test "$with_gtk" = yes; then # Check for Gnome Capplet support. # if test "$have_gnome" = yes -a "$have_gtk" = yes; then - gnome_config_libs="gtk capplet gnomeui xml" + gnome_config_libs="gtk capplet gnomeui xml gdk_pixbuf" AC_MSG_CHECKING(for Gnome capplet includes) AC_CACHE_VAL(ac_cv_gnome_config_cflags, [if ( $gnome_config --cflags $gnome_config_libs 2>&1 >/dev/null | \ @@ -1953,6 +1950,11 @@ if test "$with_gtk" = yes; then ac_gtk_config_cflags=$ac_gnome_config_cflags ac_gtk_config_libs=$ac_gnome_config_libs AC_DEFINE(HAVE_CRAPPLET) + + # check for this function that was not in libcapplet 1.2. + AC_CHECK_X_LIB(capplet, capplet_widget_changes_are_immediate, + [AC_DEFINE(HAVE_CRAPPLET_IMMEDIATE)], [true], + $ac_gnome_config_libs) fi @@ -1982,6 +1984,7 @@ fi have_xml=no with_xml_req=unspecified +xml_halfassed=no AC_ARG_WITH(xml, [ --with-xml The XML toolkit is needed for some parts of the Gtk interface.], @@ -2013,8 +2016,10 @@ if test "$with_xml" = yes; then if test "$have_xml" = yes; then # we have the header, now check for the library have_xml=no + xml_halfassed=yes AC_CHECK_X_LIB(xml, xmlParseChunk, [have_xml=yes + xml_halfassed=no XML_LIBS="-lxml" AC_DEFINE(HAVE_XML)]) fi @@ -2442,6 +2447,92 @@ if test "$have_motif" = yes -a "$have_xpm" = yes ; then fi +############################################################################### +# +# Check for -lgdk_pixbuf. +# +############################################################################### + +have_gdk_pixbuf=no +with_gdk_pixbuf_req=unspecified +AC_ARG_WITH(pixbuf, +[ --with-pixbuf Include support for the GDK-Pixbuf library in some + demos, which will make it possible for them to read + GIF, JPEG, and PNG files as well.], + [with_gdk_pixbuf="$withval"; with_gdk_pixbuf_req="$withval"], + [with_gdk_pixbuf=yes]) + +HANDLE_X_PATH_ARG(with_gdk_pixbuf, --with-pixbuf, GDK_PIXBUF) + +if test "$with_gdk_pixbuf" = yes; then + + if test "$have_gtk" = yes; then + + ac_save_gdk_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ac_gtk_config_cflags" + + have_gdk_pixbuf=no + AC_CHECK_X_HEADER(gdk-pixbuf/gdk-pixbuf.h, [have_gdk_pixbuf=yes]) + if test "$have_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + AC_CHECK_X_HEADER(gdk-pixbuf/gdk-pixbuf-xlib.h, [have_gdk_pixbuf=yes]) + fi + + CPPFLAGS="$ac_save_gdk_CPPFLAGS" + + if test "$have_gdk_pixbuf" = yes; then + AC_DEFINE(HAVE_GDK_PIXBUF) + XPM_LIBS="-lgdk_pixbuf -lgdk_pixbuf_xlib" + fi + fi + +elif test "$with_gdk_pixbuf" != no; then + echo "error: must be yes or no: --with-pixbuf=$with_gdk_pixbuf" + exit 1 +fi + + +############################################################################### +# +# Check for -ljpeg +# +############################################################################### + +have_jpeg=no +with_jpeg_req=unspecified +jpeg_halfassed=no +AC_ARG_WITH(jpeg, +[ --with-jpeg Include support for the JPEG library in some demos, + which will make it possible for them to read JPEG + files as well.], + [with_jpeg="$withval"; with_jpeg_req="$withval"], + [with_jpeg=yes]) + +HANDLE_X_PATH_ARG(with_jpeg, --with-jpeg, JPEG) + +if test "$with_jpeg" != yes -a "$with_jpeg" != no ; then + echo "error: must be yes or no: --with-jpeg=$with_jpeg" + exit 1 +fi + +if test "$with_jpeg" = yes; then + + have_jpeg=no + AC_CHECK_X_HEADER(jpeglib.h, [have_jpeg=yes]) + + if test "$have_jpeg" = yes; then + # we have the header, now check for the library + have_jpeg=no + jpeg_halfassed=yes + AC_CHECK_X_LIB(jpeg, jpeg_start_compress, + [have_jpeg=yes + jpeg_halfassed=no + JPEG_LIBS="-ljpeg" + AC_DEFINE(HAVE_JPEGLIB)]) + fi +fi + + ############################################################################### # # Check for the XSHM server extension. @@ -2451,7 +2542,7 @@ fi have_xshm=no with_xshm_req=unspecified AC_ARG_WITH(xshm-ext, -[ --with-xshm-ext Include support for the XSHM extension.], +[ --with-xshm-ext Include support for the Shared Memory extension.], [with_xshm="$withval"; with_xshm_req="$withval"],[with_xshm=yes]) HANDLE_X_PATH_ARG(with_xshm, --with-xshm-ext, XSHM) @@ -2761,6 +2852,10 @@ else GLE_KLUDGE="-${tab} " fi +if test "$have_jpeg" = yes -a "$have_gdk_pixbuf" = yes; then + JPEG_EXES='$(JPEG_EXES)' +fi + # Another substitution in the XScreenSaver.ad.in file: # @@ -2783,6 +2878,10 @@ if test -z "$HACK_CONF_DIR" ; then fi fi +# canonicalize slashes. +HACK_CONF_DIR=`echo "${HACK_CONF_DIR}" | sed 's@/$@@;s@//*@/@g'` + + ############################################################################### # @@ -2798,6 +2897,7 @@ AC_SUBST(SAVER_LIBS) AC_SUBST(MOTIF_LIBS) AC_SUBST(GTK_LIBS) AC_SUBST(XML_LIBS) +AC_SUBST(JPEG_LIBS) AC_SUBST(HACK_LIBS) AC_SUBST(XPM_LIBS) AC_SUBST(GL_LIBS) @@ -2820,6 +2920,7 @@ AC_SUBST(SAVER_GL_OBJS) AC_SUBST(SAVER_GL_LIBS) AC_SUBST(LOCK_SRCS) AC_SUBST(LOCK_OBJS) +AC_SUBST(JPEG_EXES) AC_SUBST(GL_EXES) AC_SUBST(GL_UTIL_EXES) AC_SUBST(GL_MEN) @@ -2980,17 +3081,33 @@ if test "$with_gnome_req" = yes -a "$have_gnome" = no ; then warn2 'headers and/or libraries were not found.' fi -if test "$with_xml_req" = yes -a "$have_xml" = no ; then - warn 'Use of the XML library was requested, but the necessary' - warn2 'headers and/or libraries were not found.' -elif test "$have_gtk" = yes -a "$have_xml" = no ; then - warn 'GTK is being used, but the XML library was not found.' - warn2 'Some functionality will be disabled.' +if test "$have_gtk" = yes ; then + if test "$have_xml" = no ; then + if test "$with_xml_req" = yes ; then + warn 'Use of the XML library was requested, but the necessary' + warn2 'headers and/or libraries were not found.' + else + warn 'GTK is being used, but the XML library was not found.' + fi + + if test "$xml_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either XML is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 "Without XML, the per-display-mode \`Settings' dialogs" + warn2 'will not be available. Specify the location of the XML' + warn2 'library through the --with-xml option to configure.' + fi fi if test "$have_motif" = yes -a "$have_lesstif" = yes ; then - preferred_lesstif=0.86 + preferred_lesstif=0.92 if test "$lesstif_version" = unknown; then warnL "Unable to determine the LessTif version number!" @@ -3007,22 +3124,77 @@ if test "$have_motif" = yes -a "$have_lesstif" = yes ; then fi +if test "$have_motif" = yes -a "$have_gtk" = no ; then + warn 'Motif is being used, and GTK is not.' + echo '' + warn2 'Though the Motif front-end to xscreensaver is still' + warn2 'maintained, it is no longer being updated with new' + warn2 'features: all new development on the xscreensaver-demo' + warn2 'program is happening in the GTK version, and not in the' + warn2 'Motif version. It is recommended that you build against' + warn2 'GTK instead of Motif. See .' +fi + + +if test "$with_xpm_req" = yes ; then + warnL 'Use of XPM was requested, but it was not found.' +fi + +if test "$with_gdk_pixbuf_req" = yes ; then + warnL 'Use of GDK-Pixbuf was requested, but it was not found.' +fi + +if test "$have_xpm" = no -a "$have_gdk_pixbuf" = no; then -if test "$have_xpm" = no ; then if test "$with_xpm_req" = yes ; then - warnL 'Use of XPM was requested, but it was not found.' + true elif test "$with_xpm_req" = no ; then - noteL 'The XPM library is not being used.' + warnL 'The XPM library is not being used.' else - noteL 'The XPM library was not found.' + warnL 'The XPM library was not found.' + fi + + if test "$with_gdk_pixbuf_req" = yes ; then + true + elif test "$with_gdk_pixbuf_req" = no ; then + warnL 'The GDK-Pixbuf library is not being used.' + else + warnL 'The GDK-Pixbuf library was not found.' fi echo '' warn2 'Some of the demos will not be as colorful as they' - warn2 'could be. You might want to consider installing XPM' - warn2 'and re-running configure. (Remember to delete the' - warn2 'config.cache file first.) You can find XPM at most' - warn2 'X11 archive sites, such as .' + warn2 'could be. You should consider installing Pixbuf or' + warn2 'XPM and re-running configure. (Remember to delete' + warn2 'the config.cache file first.) The Pixbuf library is' + warn2 'a part of GNOME. The XPM library comes with most' + warn2 'X11 installations; you can also find it at the X11' + warn2 'archive sites, such as .' + echo '' + warn2 'GDK-Pixbuf is recommended over XPM, as it provides' + warn2 'support for more image formats.' +fi + + +if test "$have_jpeg" = no ; then + if test "$with_jpeg_req" = yes ; then + warnL 'Use of libjpeg was requested, but it was not found.' + elif test "$with_jpeg_req" = no ; then + noteL 'The JPEG library is not being used.' + else + noteL 'The JPEG library was not found.' + fi + + if test "$jpeg_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'library; so either JPEG is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + echo '' + fi + + warn2 "This means the \`webcollage' program will be much slower." fi @@ -3197,10 +3369,10 @@ if test \! -z "$rpmv" ; then echo "" if test "$rpmbdir" = "$rpmhdir" ; then - warn2 "The RPM version was installed in $rpmbdir." + warn2 "The RPM version was installed in $rpmbdir/." else - warn2 "The RPM version was installed in $rpmbdir," - warn2 "with demos in $rpmhdir." + warn2 "The RPM version was installed in $rpmbdir/," + warn2 "with demos in $rpmhdir/." fi do_dir_warning=yes @@ -3217,10 +3389,10 @@ if test "$do_dir_warning" = yes; then echo "" echo ' When you run "make install", the "xscreensaver",' echo ' "xscreensaver-demo", and "xscreensaver-command" executables' - echo " will be installed in ${bindir}." + echo " will be installed in ${bindir}/." echo "" - echo " The various graphics demos (120+ different executables) will" - echo " also be installed in ${HACKDIR}." + echo " The various graphics demos (140+ different executables) will" + echo " also be installed in ${HACKDIR}/." echo "" echo " If you would prefer the demos to be installed elsewhere" echo " (for example, in a dedicated directory) you should re-run" diff --git a/driver/Makefile.in b/driver/Makefile.in index 6df5137c..563e9028 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -17,7 +17,8 @@ man1dir = $(mandir)/man1 mansuffix = 1 GNOME_DATADIR = @GNOME_DATADIR@ -GNOME_CCDIR = $(GNOME_DATADIR)/control-center/Desktop +GNOME_CCDIR_1 = $(GNOME_DATADIR)/control-center/Desktop +GNOME_CCDIR_2 = $(GNOME_DATADIR)/control-center/capplets GNOME_PANELDIR = $(GNOME_DATADIR)/gnome/apps/Settings/Desktop GNOME_ICONDIR = $(GNOME_DATADIR)/pixmaps GNOME_BINDIR = $(bindir) @@ -157,9 +158,9 @@ GETIMG_OBJS = $(GETIMG_OBJS_1) \ $(UTILS_BIN)/colors.o $(UTILS_BIN)/grabscreen.o \ $(UTILS_BIN)/logo.o prefs.o $(XMU_OBJS) -SAVER_SRCS_1 = xscreensaver.c windows.c timers.c subprocs.c \ +SAVER_SRCS_1 = xscreensaver.c windows.c timers.c subprocs.c exec.c \ xset.c splash.c setuid.c stderr.c -SAVER_OBJS_1 = xscreensaver.o windows.o timers.o subprocs.o \ +SAVER_OBJS_1 = xscreensaver.o windows.o timers.o subprocs.o exec.o \ xset.o splash.o setuid.o stderr.o SAVER_SRCS = $(SAVER_SRCS_1) prefs.c dpms.c $(LOCK_SRCS) \ @@ -173,8 +174,8 @@ CMD_OBJS = remote.o xscreensaver-command.o DEMO_SRCS_1 = prefs.c dpms.c $(XMU_SRCS) DEMO_OBJS_1 = prefs.o dpms.o $(XMU_OBJS) -DEMO_SRCS = prefs.c dpms.c remote.c $(DEMO_UTIL_SRCS) -DEMO_OBJS = prefs.o dpms.o remote.o $(DEMO_UTIL_OBJS) +DEMO_SRCS = prefs.c dpms.c remote.c exec.c $(DEMO_UTIL_SRCS) +DEMO_OBJS = prefs.o dpms.o remote.o exec.o $(DEMO_UTIL_OBJS) SAVER_LIBS = $(LIBS) $(X_LIBS) $(XMU_LIBS) @SAVER_LIBS@ \ $(XDPMS_LIBS) $(GL_LIBS) $(X_PRE_LIBS) \ @@ -425,23 +426,36 @@ install-pam: fi install-gnome:: screensaver-properties.desktop - @lost1="" ;\ - lost2="" ;\ + @lost="" ;\ if [ "$(GNOME_DATADIR)" != "" ]; then \ \ - if [ ! -d "$(install_prefix)$(GNOME_CCDIR)" ]; then \ - echo $(INSTALL_DIRS) "$(install_prefix)$(GNOME_CCDIR)" ;\ - $(INSTALL_DIRS) "$(install_prefix)$(GNOME_CCDIR)" ;\ + if [ ! -d "$(install_prefix)$(GNOME_CCDIR_1)" ]; then \ + echo $(INSTALL_DIRS) "$(install_prefix)$(GNOME_CCDIR_1)" ;\ + $(INSTALL_DIRS) "$(install_prefix)$(GNOME_CCDIR_1)" ;\ + fi ;\ + if [ ! -d "$(install_prefix)$(GNOME_CCDIR_2)" ]; then \ + echo $(INSTALL_DIRS) "$(install_prefix)$(GNOME_CCDIR_2)" ;\ + $(INSTALL_DIRS) "$(install_prefix)$(GNOME_CCDIR_2)" ;\ + fi ;\ + \ + echo $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop \ + $(install_prefix)$(GNOME_CCDIR_1)/screensaver-properties.desktop;\ + \ + if $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop \ + $(install_prefix)$(GNOME_CCDIR_1)/screensaver-properties.desktop;\ + then true ;\ + else \ + lost="$$lost $(install_prefix)$(GNOME_CCDIR_1)" ;\ fi ;\ \ echo $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop \ - $(install_prefix)$(GNOME_CCDIR)/screensaver-properties.desktop ;\ + $(install_prefix)$(GNOME_CCDIR_2)/screensaver.desktop ;\ \ if $(INSTALL_DATA) $(srcdir)/screensaver-properties.desktop \ - $(install_prefix)$(GNOME_CCDIR)/screensaver-properties.desktop ;\ + $(install_prefix)$(GNOME_CCDIR_2)/screensaver.desktop ;\ then true ;\ else \ - lost1="$(install_prefix)$(GNOME_CCDIR)" ;\ + lost="$$lost $(install_prefix)$(GNOME_CCDIR_2)" ;\ fi ;\ \ if [ ! -d "$(install_prefix)$(GNOME_PANELDIR)" ]; then \ @@ -455,26 +469,18 @@ install-gnome:: screensaver-properties.desktop $(install_prefix)$(GNOME_PANELDIR)/screensaver-properties.desktop ;\ then true ;\ else \ - lost2="$(install_prefix)$(GNOME_PANELDIR)" ;\ + lost="$$lost $(install_prefix)$(GNOME_PANELDIR)" ;\ fi ;\ \ - if [ "$$lost1" != "" -o "$$lost2" != "" ]; then \ + if [ "$$lost" != "" ]; then \ e=echo ; \ $$e "" ;\ $$e " ####################################################################";\ - $$e " Warning: unable to install screensaver-properties.desktop into" ;\ - plurality="this file" ;\ - if [ "$$lost1" != "" -a "$$lost2" != "" ]; then \ - $$e " $$lost1/ or into" ;\ - $$e " $$lost2/." ;\ - plurality="these files" ;\ - elif [ "$$lost1" != "" ]; then \ - $$e " $$lost1/." ;\ - else \ - $$e " $$lost2/." ;\ - fi ;\ - $$e " Without $$plurality," 'the "Screen Saver" section of the' ;\ - $$e " Gnome Control Center (gnomecc) will not work properly." ;\ + $$e " Warning: unable to install screensaver-properties.desktop into:" ;\ + set - $$lost ;\ + for f in $$@ ; do echo " $$f/" ; done ;\ + $$e ' This means the "Screen Saver" section of the Gnome' ;\ + $$e " Control Center (gnomecc) may not work properly." ;\ $$e " ####################################################################";\ $$e "" ;\ exit 1 ; \ @@ -756,7 +762,7 @@ xscreensaver-command: $(CMD_OBJS) xscreensaver-demo: @PREFERRED_DEMO_PROGRAM@ - cp -p @PREFERRED_DEMO_PROGRAM@ $@ + $(INSTALL_PROGRAM) @PREFERRED_DEMO_PROGRAM@ $@ xscreensaver-demo-Xm: $(DEMO_OBJS) $(MOTIF_OBJS) $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(MOTIF_OBJS) $(LIBS) $(X_LIBS) \ @@ -826,6 +832,7 @@ timers.o: $(srcdir)/prefs.h subprocs.o: ../config.h subprocs.o: $(srcdir)/xscreensaver.h subprocs.o: $(srcdir)/prefs.h +exec.o: ../config.h xset.o: ../config.h xset.o: $(srcdir)/xscreensaver.h xset.o: $(srcdir)/prefs.h diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in index 77bd854d..cf6cef16 100644 --- a/driver/XScreenSaver.ad.in +++ b/driver/XScreenSaver.ad.in @@ -4,8 +4,8 @@ ! a screen saver and locker for the X window system ! by Jamie Zawinski ! -! version 4.00 -! 02-Jan-2002 +! version 4.01 +! 24-Feb-2002 ! ! See "man xscreensaver" for more info. The latest version is always ! available at http://www.jwz.org/xscreensaver/ @@ -272,6 +272,14 @@ "SpeedMine" speedmine -root \n\ "SpeedWorm" speedmine -root -worm \n\ vermiculate -root \n\ + twang -root \n\ + apollonian -root \n\ + euler2d -root \n\ + "Euler2d (dense)" euler2d -root -count 4000 -eulertail 400 \ + -ncolors 230 \n\ +- juggle -root \n\ + polyominoes -root \n\ + thornbird -root \n\ color: bubbles -root \n\ default-n: webcollage -root \n\ default-n: "WebCollage (whacked)" \ @@ -312,6 +320,10 @@ @GL_KLUDGE@ GL: circuit -root \n\ @GL_KLUDGE@ GL: engine -root \n\ @GL_KLUDGE@ GL: flipscreen3d -root \n\ +@GL_KLUDGE@ GL: glsnake -root \n\ +@GL_KLUDGE@ GL: boxed -root \n\ +@GL_KLUDGE@ GL: glforestfire -root \n\ +@GL_KLUDGE@ GL: sballs -root \n\ \ - xdaliclock -root -builtin3 -cycle \n\ - default-n: xearth -nofork -nostars -ncolors 50 \ @@ -319,7 +331,6 @@ sunrel/38/-30 \n\ - xplanetbg -xscreensaver -moonside \ -markerfile earth -wait 1 -timewarp 400 \n\ -- ssystem -fullscreen :32 \n\ - xmountains -b -M -Z 0 -r 1 \n\ - "XMountains (top)" xmountains -b -M -Z 0 -r 1 -m \n\ - xaos -fullscreen -autopilot \ @@ -595,9 +606,11 @@ XScreenSaver*doc.fontList: *-helvetica-medium-r-*-*-*-100-*-*-*-iso8859-1 *hacks.dangerball.name: DangerBall *hacks.whirlygig.name: WhirlyGig *hacks.speedmine.name: SpeedMine +*hacks.glsnake.name: GLSnake +*hacks.glforestfire.name: GLForestFire +*hacks.sballs.name: SBalls *hacks.xdaliclock.name: XDaliClock *hacks.xplanetbg.name: XPlanet -*hacks.ssystem.name: SSystem *hacks.xaos.name: XaoS *hacks.xfishtank.name: XFishTank *hacks.electricsheep.name: ElectricSheep diff --git a/driver/XScreenSaver_ad.h b/driver/XScreenSaver_ad.h index b06511d9..68a28183 100644 --- a/driver/XScreenSaver_ad.h +++ b/driver/XScreenSaver_ad.h @@ -175,6 +175,14 @@ \"SpeedMine\" speedmine -root \\n\ \"SpeedWorm\" speedmine -root -worm \\n\ vermiculate -root \\n\ + twang -root \\n\ + apollonian -root \\n\ + euler2d -root \\n\ + \"Euler2d (dense)\" euler2d -root -count 4000 -eulertail 400 \ + -ncolors 230 \\n\ +- juggle -root \\n\ + polyominoes -root \\n\ + thornbird -root \\n\ color: bubbles -root \\n\ default-n: webcollage -root \\n\ default-n: \"WebCollage (whacked)\" \ @@ -215,6 +223,10 @@ GL: circuit -root \\n\ GL: engine -root \\n\ GL: flipscreen3d -root \\n\ + GL: glsnake -root \\n\ + GL: boxed -root \\n\ + GL: glforestfire -root \\n\ + GL: sballs -root \\n\ \ - xdaliclock -root -builtin3 -cycle \\n\ - default-n: xearth -nofork -nostars -ncolors 50 \ @@ -222,7 +234,6 @@ sunrel/38/-30 \\n\ - xplanetbg -xscreensaver -moonside \ -markerfile earth -wait 1 -timewarp 400 \\n\ -- ssystem -fullscreen :32 \\n\ - xmountains -b -M -Z 0 -r 1 \\n\ - \"XMountains (top)\" xmountains -b -M -Z 0 -r 1 -m \\n\ - xaos -fullscreen -autopilot \ @@ -407,9 +418,11 @@ "*hacks.dangerball.name: DangerBall", "*hacks.whirlygig.name: WhirlyGig", "*hacks.speedmine.name: SpeedMine", +"*hacks.glsnake.name: GLSnake", +"*hacks.glforestfire.name: GLForestFire", +"*hacks.sballs.name: SBalls", "*hacks.xdaliclock.name: XDaliClock", "*hacks.xplanetbg.name: XPlanet", -"*hacks.ssystem.name: SSystem", "*hacks.xaos.name: XaoS", "*hacks.xfishtank.name: XFishTank", "*hacks.electricsheep.name: ElectricSheep", diff --git a/driver/demo-Gtk-conf.c b/driver/demo-Gtk-conf.c index b8bb1ee6..d51d1df7 100644 --- a/driver/demo-Gtk-conf.c +++ b/driver/demo-Gtk-conf.c @@ -32,6 +32,11 @@ #include "demo-Gtk-conf.h" +#if (LIBXML_VERSION >= 20000) /* illiteracy finally fixed */ +# define childs children +# define root children +#endif + extern const char *blurb (void); diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c index 3c83e8ab..26c69db6 100644 --- a/driver/demo-Gtk.c +++ b/driver/demo-Gtk.c @@ -33,7 +33,9 @@ #endif /* HAVE_UNAME */ #include +#include #include +#include #include @@ -90,6 +92,10 @@ #include #include + +/* from exec.c */ +extern void exec_command (const char *shell, const char *command, int nice); + #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -125,7 +131,6 @@ typedef struct { int subproc_timer_id; /* timer to delay subproc launch */ int subproc_check_timer_id; /* timer to check whether it started up */ int subproc_check_countdown; /* how many more checks left */ - int preview_nice_level; int *list_elt_to_hack_number; /* table for sorting the hack list */ int *hack_number_to_list_elt; /* the inverse table */ @@ -2783,38 +2788,6 @@ kill_preview_subproc (state *s) } -static void -exec_program (const char *cmd, int nice_level) -{ - char *av[1024]; - int ac = 0; - char *token = strtok (strdup(cmd), " \t"); - while (token) - { - av[ac++] = token; - token = strtok(0, " \t"); - } - av[ac] = 0; - - nice (nice_level - nice (0)); - - usleep (250000); /* pause for 1/4th second before launching, to give the - previous program time to die and flush its X buffer, - so we don't get leftover turds on the window. */ - - execvp (av[0], av); /* shouldn't return. */ - - { - char buf [512]; - sprintf (buf, "%s: could not execute \"%s\"", blurb(), av[0]); - perror (buf); - } - fflush(stderr); - fflush(stdout); - exit (1); /* Note that this only exits a child fork. */ -} - - /* Immediately and unconditionally launches the given process, after appending the -window-id option; sets running_preview_pid. */ @@ -2823,10 +2796,8 @@ launch_preview_subproc (state *s) { saver_preferences *p = &s->prefs; Window id; - Bool hairy_p; char *new_cmd; pid_t forked; - int nice_level = nice (0) - p->nice_inferior; const char *cmd = s->desired_preview_cmd; GtkWidget *pr = name_to_widget (s, "preview"); @@ -2855,16 +2826,6 @@ launch_preview_subproc (state *s) sprintf (new_cmd + strlen (new_cmd), " -window-id 0x%X", id); } - hairy_p = (new_cmd && !!strpbrk (new_cmd, "*?$&!<>[];`'\\\"=")); - if (hairy_p) - { - /* Command requires a full shell? Forget it. */ - free (new_cmd); - new_cmd = 0; - if (s->debug_p) - fprintf (stderr, "%s: command is hairy: not previewing\n", blurb()); - } - kill_preview_subproc (s); if (! new_cmd) { @@ -2886,8 +2847,16 @@ launch_preview_subproc (state *s) case 0: { close (ConnectionNumber (GDK_DISPLAY())); - exec_program (new_cmd, nice_level); - abort(); + + usleep (250000); /* pause for 1/4th second before launching, to give + the previous program time to die and flush its X + buffer, so we don't get leftover turds on the + window. */ + + exec_command (p->shell, new_cmd, p->nice_inferior); + /* Don't bother printing an error message when we are unable to + exec subprocesses; we handle that by polling the pid later. */ + exit (1); /* exits child fork */ break; default: @@ -3773,12 +3742,12 @@ main (int argc, char **argv) capplet = capplet_widget_new (); /* Make there be a "Close" button instead of "OK" and "Cancel" */ +# ifdef HAVE_CRAPPLET_IMMEDIATE capplet_widget_changes_are_immediate (CAPPLET_WIDGET (capplet)); +# endif /* HAVE_CRAPPLET_IMMEDIATE */ -# if 1 - /* In crapplet-mode, take off the menubar. */ - gtk_widget_hide (name_to_widget (s, "menubar")); -# endif + /* In crapplet-mode, take off the menubar. */ + gtk_widget_hide (name_to_widget (s, "menubar")); /* Reparent our top-level container to be a child of the capplet window. diff --git a/driver/exec.c b/driver/exec.c new file mode 100644 index 00000000..0798ea83 --- /dev/null +++ b/driver/exec.c @@ -0,0 +1,248 @@ +/* exec.c --- executes a program in *this* pid, without an intervening process. + * xscreensaver, Copyright (c) 1991-2002 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + + +/* I don't believe what a sorry excuse for an operating system UNIX is! + + - I want to spawn a process. + - I want to know it's pid so that I can kill it. + - I would like to receive a message when it dies of natural causes. + - I want the spawned process to have user-specified arguments. + + If shell metacharacters are present (wildcards, backquotes, etc), the + only way to parse those arguments is to run a shell to do the parsing + for you. + + And the only way to know the pid of the process is to fork() and exec() + it in the spawned side of the fork. + + But if you're running a shell to parse your arguments, this gives you + the pid of the *shell*, not the pid of the *process* that you're + actually interested in, which is an *inferior* of the shell. This also + means that the SIGCHLD you get applies to the shell, not its inferior. + (Why isn't that sufficient? I don't remember any more, but it turns + out that it isn't.) + + So, the only solution, when metacharacters are present, is to force the + shell to exec() its inferior. What a fucking hack! We prepend "exec " + to the command string, and hope it doesn't contain unquoted semicolons + or ampersands (we don't search for them, because we don't want to + prohibit their use in quoted strings (messages, for example) and parsing + out the various quote characters is too much of a pain.) + + (Actually, Clint Wong points out that process groups + might be used to take care of this problem; this may be worth considering + some day, except that, 1: this code works now, so why fix it, and 2: from + what I've seen in Emacs, dealing with process groups isn't especially + portable.) + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#ifndef ESRCH +# include +#endif + +#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) +# include /* for setpriority() and PRIO_PROCESS */ + /* and also setrlimit() and RLIMIT_AS */ +#endif + +#ifdef VMS +# include +# include /* for close */ +# include /* for getpid */ +# define pid_t int +# define fork vfork +#endif /* VMS */ + + +extern const char *blurb (void); + +static void nice_process (int nice_level); + + +#ifndef VMS + +static void +exec_simple_command (const char *command) +{ + char *av[1024]; + int ac = 0; + char *token = strtok (strdup(command), " \t"); + while (token) + { + av[ac++] = token; + token = strtok(0, " \t"); + } + av[ac] = 0; + + execvp (av[0], av); /* shouldn't return. */ +} + + +static void +exec_complex_command (const char *shell, const char *command) +{ + char *av[5]; + int ac = 0; + char *command2 = (char *) malloc (strlen (command) + 10); + const char *s; + int got_eq = 0; + const char *after_vars; + + /* Skip leading whitespace. + */ + while (*command == ' ' || *command == '\t') + command++; + + /* If the string has a series of tokens with "=" in them at them, set + `after_vars' to point into the string after those tokens and any + trailing whitespace. Otherwise, after_vars == command. + */ + after_vars = command; + for (s = command; *s; s++) + { + if (*s == '=') got_eq = 1; + else if (*s == ' ') + { + if (got_eq) + { + while (*s == ' ' || *s == '\t') + s++; + after_vars = s; + got_eq = 0; + } + else + break; + } + } + + *command2 = 0; + strncat (command2, command, after_vars - command); + strcat (command2, "exec "); + strcat (command2, after_vars); + + /* We have now done these transformations: + "foo -x -y" ==> "exec foo -x -y" + "BLAT=foop foo -x" ==> "BLAT=foop exec foo -x" + "BLAT=foop A=b foo -x" ==> "BLAT=foop A=b exec foo -x" + */ + + + /* Invoke the shell as "/bin/sh -c 'exec prog -arg -arg ...'" */ + av [ac++] = (char *) shell; + av [ac++] = "-c"; + av [ac++] = command2; + av [ac] = 0; + + execvp (av[0], av); /* shouldn't return. */ +} + +#else /* VMS */ + +static void +exec_vms_command (const char *command) +{ + system (command); + fflush (stderr); + fflush (stdout); + exit (1); /* Note that this only exits a child fork. */ +} + +#endif /* !VMS */ + + +void +exec_command (const char *shell, const char *command, int nice_level) +{ + int hairy_p; + +#ifndef VMS + if (nice != 0) + nice_process (nice_level); + + hairy_p = !!strpbrk (command, "*?$&!<>[];`'\\\"="); + /* note: = is in the above because of the sh syntax "FOO=bar cmd". */ + + if (getuid() == (uid_t) 0 || geteuid() == (uid_t) 0) + { + /* If you're thinking of commenting this out, think again. + If you do so, you will open a security hole. Mail jwz + so that he may enlighten you as to the error of your ways. + */ + fprintf (stderr, "%s: we're still running as root! Disaster!\n", + blurb()); + exit (-1); + } + + if (hairy_p) + /* If it contains any shell metacharacters, do it the hard way, + and fork a shell to parse the arguments for us. */ + exec_complex_command (shell, command); + else + /* Otherwise, we can just exec the program directly. */ + exec_simple_command (command); + +#else /* VMS */ + exec_vms_command (command); +#endif /* VMS */ +} + + +/* Setting process priority + */ + +static void +nice_process (int nice_level) +{ + if (nice_level == 0) + return; + +#if defined(HAVE_NICE) + { + int old_nice = nice (0); + int n = nice_level - old_nice; + errno = 0; + if (nice (n) == -1 && errno != 0) + { + char buf [512]; + sprintf (buf, "%s: nice(%d) failed", blurb(), n); + perror (buf); + } + } +#elif defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) + if (setpriority (PRIO_PROCESS, getpid(), nice_level) != 0) + { + char buf [512]; + sprintf (buf, "%s: setpriority(PRIO_PROCESS, %lu, %d) failed", + blurb(), (unsigned long) getpid(), nice_level); + perror (buf); + } +#else + fprintf (stderr, + "%s: don't know how to change process priority on this system.\n", + blurb()); + +#endif +} diff --git a/driver/lock.c b/driver/lock.c index aad2cc6f..277cfc3c 100644 --- a/driver/lock.c +++ b/driver/lock.c @@ -19,6 +19,8 @@ #include #include /* for time() */ +#include +#include #include "xscreensaver.h" #include "resources.h" diff --git a/driver/prefs.c b/driver/prefs.c index 7dcb768a..46b93886 100644 --- a/driver/prefs.c +++ b/driver/prefs.c @@ -1337,15 +1337,28 @@ char * format_hack (screenhack *hack, Bool wrap_p) { int tab = 32; - int size = (2 * (strlen(hack->command) + - (hack->visual ? strlen(hack->visual) : 0) + - (hack->name ? strlen(hack->name) : 0) + - tab)); - char *h2 = (char *) malloc (size); - char *out = h2; - char *s; + int size; + char *h2, *out, *s; int col = 0; + char *def_name = make_hack_name (hack->command); + + /* Don't ever write out a name for a hack if it's the same as the default. + */ + if (hack->name && !strcmp (hack->name, def_name)) + { + free (hack->name); + hack->name = 0; + } + free (def_name); + + size = (2 * (strlen(hack->command) + + (hack->visual ? strlen(hack->visual) : 0) + + (hack->name ? strlen(hack->name) : 0) + + tab)); + h2 = (char *) malloc (size); + out = h2; + if (!hack->enabled_p) *out++ = '-'; /* write disabled flag */ if (hack->visual && *hack->visual) /* write visual name */ diff --git a/driver/remote.c b/driver/remote.c index 592d5d03..38bc4c8b 100644 --- a/driver/remote.c +++ b/driver/remote.c @@ -16,6 +16,7 @@ #include #include +#include #include #include diff --git a/driver/screensaver-properties-capplet b/driver/screensaver-properties-capplet index a2bb0da0..85557f89 100755 --- a/driver/screensaver-properties-capplet +++ b/driver/screensaver-properties-capplet @@ -1,6 +1,6 @@ #!/bin/sh # screensaver-properties-capplet --- interface to gnome-session. -# xscreensaver, Copyright (c) 1993-2001 Jamie Zawinski +# xscreensaver, Copyright (c) 1991-2002 Jamie Zawinski # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that @@ -16,4 +16,4 @@ # xscreensaver-demo accepts the same arguments that Gnome's capplet does, # except that "--capplet" must be the first argument. -exec xscreensaver-demo --capplet "$@" +exec xscreensaver-demo --crapplet "$@" diff --git a/driver/screensaver-properties.desktop.in b/driver/screensaver-properties.desktop.in index 85328e07..275d4d5d 100644 --- a/driver/screensaver-properties.desktop.in +++ b/driver/screensaver-properties.desktop.in @@ -1,42 +1,61 @@ [Desktop Entry] Name=Screensaver +Name[az]=Ekran Qoruyucular +Name[ca]=Protector de pantalla Name[da]=Pauseskærm Name[ca]=Protector de pantalla Name[de]=Bildschirmschoner -Name[es]=Propiedades Salvapantallas +Name[es]=Salvapantalla Name[et]=Ekraanisäästja -Name[fi]=Ruudunsäästäjä -Name[fr]=Propriétés Économiseur d'écran +Name[fi]=Näytönsäästäjä +Name[fr]=Économiseur d'écran Name[hu]=Képernyõvédõ Name[it]=Salvaschermo Name[ja]=¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼ Name[ko]=È­¸é º¸È£±â +Name[nn]=Skjermsparar Name[no]=Skjermsparer Name[pl]=Wygaszacz ekranu Name[pt]=Propriedades da protecção de ecrã -Name[pt_BR]=Propriedades da proteção de tela +Name[pt_BR]=Proteção de tela Name[ru]=èÒÁÎÉÔÅÌØ ÜËÒÁÎÁ +Name[sk]=©etriè obrazovky +Name[sl]=Ohranjevalnik zaslona Name[sv]=Skärmsläckare -Name[wa]=Spårgneu di waitroûle -Comment=Configure the settings of the screensaver. -Comment[da]=Indstil din pauseskærm. +Name[tr]=Ekran Koruyucusu +Name[wa]=Sipårgneu di waitroûle +Name[zh_TW]=¿Ã¹õ«OÅ@µ{¦¡ +Comment=Configure the settings of the screensaver +Comment[az]=Ekran qoruyucu qurğularını aparın +Comment[ca]=Configurar el protector de pantalla. +Comment[cs]=Konfigurace ¹etøièe obrazovky +Comment[da]=Indstil pauseskærmen Comment[ca]=Configurar el protector de pantalla. Comment[de]=Bildschirmschoner einrichten +Comment[el]=Ñýèìéóç ôùí éäéïôÞôùí ôçò ðñïöýëáîçò ïèüíçò Comment[es]=Configurar el salvapantalla Comment[et]=Ekraanisäästja häälestus -Comment[fi]=Aseta ruudunsäästäjän asetukset. -Comment[fr]=Configurer l'économiseur d'écran +Comment[fi]=Muuta näytönsäästäjän asetuksia +Comment[fr]=Configuration des propriétés de l'économiseur d'écran Comment[hu]=Képernyõvédõ beállítások Comment[it]=Impostazioni del salvaschermo Comment[ja]=¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼¤ÎÀßÄê Comment[ko]=È­¸é º¸È£±â ¼³Á¤ +Comment[nn]=Set opp skjermspararen Comment[no]=Endre innstillingene for skjermspareren -Comment[pl]=Konfiguracja wygaszacza ekranu +Comment[pl]=Konfiguruje ustawienia wygaszacza ekranu Comment[pt]=Configura as opções da protecção de ecrã. +Comment[pt_BR]=Configurar os parâmetros da proteção de tela Comment[ru]=îÁÓÔÒÏÊËÁ ÈÒÁÎÉÔÅÌÑ ÜËÒÁÎÁ. +Comment[ro]=Configuraþi setãrile protectorului de ecran +Comment[sk]=Nastaví ¹etriè +Comment[sl]=Nastavi ohranjevalnik zaslona Comment[sv]=Ändra inställningar för skärmsläckare -Comment[wa]=Apontiaedje do spårgneu di waitroûle +Comment[tr]=Ekran koruyucu ayarlarýný yap +Comment[uk]=îÁÌÁÇÏÄÖÅÎÎÑ ÚÂÅÒ¦ÇÁÞÁ ÅËÒÁÎÁ +Comment[wa]=Fjhoz l' apontiaedje do spårgneu di waitroûle +Comment[zh_TW]=³]©w¿Ã¹õ«OÅ@µ{¦¡ Exec=xscreensaver-demo --crapplet -Icon=gnome-ccscreensaver.png +Icon=xscreensaver.xpm Terminal=0 Type=Application diff --git a/driver/stderr.c b/driver/stderr.c index d4361df8..5f337c00 100644 --- a/driver/stderr.c +++ b/driver/stderr.c @@ -1,5 +1,5 @@ /* stderr.c --- capturing stdout/stderr output onto the screensaver window. - * xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-1998, 2001 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -478,6 +478,9 @@ initialize_stderr (saver_info *si) void shutdown_stderr (saver_info *si) { + fflush (stdout); + fflush (stderr); + if (!real_stderr || stderr_stdout_read_fd < 0) return; @@ -489,7 +492,16 @@ shutdown_stderr (saver_info *si) { *stderr_tail = 0; fprintf (real_stderr, "%s", stderr_buffer); - fflush (real_stderr); stderr_tail = stderr_buffer; } + + if (real_stdout) fflush (real_stdout); + if (real_stderr) fflush (real_stderr); + + if (stdout != real_stdout) + dup2 (fileno(real_stdout), fileno(stdout)); + if (stderr != real_stderr) + dup2 (fileno(real_stderr), fileno(stderr)); + + stderr_stdout_read_fd = -1; } diff --git a/driver/subprocs.c b/driver/subprocs.c index e97fc928..62ae9ae9 100644 --- a/driver/subprocs.c +++ b/driver/subprocs.c @@ -30,10 +30,8 @@ # include /* for waitpid() and associated macros */ #endif -#if (defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)) || \ - defined(HAVE_SETRLIMIT) -# include /* for setpriority() and PRIO_PROCESS */ - /* and also setrlimit() and RLIMIT_AS */ +#ifdef HAVE_SETRLIMIT +# include /* for setrlimit() and RLIMIT_AS */ #endif #ifdef VMS @@ -72,44 +70,16 @@ extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ extern saver_info *global_si_kludge; /* I hate C so much... */ -static void -nice_subproc (int nice_level) -{ - if (nice_level == 0) - return; - -#if defined(HAVE_NICE) - { - int old_nice = nice (0); - int n = nice_level - old_nice; - errno = 0; - if (nice (n) == -1 && errno != 0) - { - char buf [512]; - sprintf (buf, "%s: nice(%d) failed", blurb(), n); - perror (buf); - } - } -#elif defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) - if (setpriority (PRIO_PROCESS, getpid(), nice_level) != 0) - { - char buf [512]; - sprintf (buf, "%s: setpriority(PRIO_PROCESS, %lu, %d) failed", - blurb(), (unsigned long) getpid(), nice_level); - perror (buf); - } -#else - fprintf (stderr, - "%s: don't know how to change process priority on this system.\n", - blurb()); - -#endif -} - /* RLIMIT_AS (called RLIMIT_VMEM on some systems) controls the maximum size of a process's address space, i.e., the maximal brk(2) and mmap(2) values. Setting this lets you put a cap on how much memory a process can allocate. + + Except the "and mmap()" part kinda makes this useless, since many GL + implementations end up using mmap() to pull the whole frame buffer into + memory (or something along those lines) making it appear processes are + using hundreds of megabytes when in fact they're using very little, and + we end up capping their mallocs prematurely. YAY! */ #if defined(RLIMIT_VMEM) && !defined(RLIMIT_AS) # define RLIMIT_AS RLIMIT_VMEM @@ -163,227 +133,6 @@ limit_subproc_memory (int address_space_limit, Bool verbose_p) #endif /* HAVE_SETRLIMIT && RLIMIT_AS */ } - - -#ifndef VMS - -static void -exec_simple_command (const char *command) -{ - char *av[1024]; - int ac = 0; - char *token = strtok (strdup(command), " \t"); - while (token) - { - av[ac++] = token; - token = strtok(0, " \t"); - } - av[ac] = 0; - - execvp (av[0], av); /* shouldn't return. */ - - { - char buf [512]; - sprintf (buf, "%s: could not execute \"%s\"", blurb(), av[0]); - perror (buf); - - if (errno == ENOENT && - (token = getenv("PATH"))) - { -# ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# else -# define PATH_MAX 2048 -# endif -# endif - char path[PATH_MAX]; - fprintf (stderr, "\n"); - *path = 0; -# if defined(HAVE_GETCWD) - getcwd (path, sizeof(path)); -# elif defined(HAVE_GETWD) - getwd (path); -# endif - if (*path) - fprintf (stderr, " Current directory is: %s\n", path); - fprintf (stderr, " PATH is:\n"); - token = strtok (strdup(token), ":"); - while (token) - { - fprintf (stderr, " %s\n", token); - token = strtok(0, ":"); - } - fprintf (stderr, "\n"); - } - } - fflush(stderr); - fflush(stdout); - exit (1); /* Note that this only exits a child fork. */ -} - - -static void -exec_complex_command (const char *shell, const char *command) -{ - char *av[5]; - int ac = 0; - char *command2 = (char *) malloc (strlen (command) + 10); - const char *s; - int got_eq = 0; - const char *after_vars; - - /* Skip leading whitespace. - */ - while (*command == ' ' || *command == '\t') - command++; - - /* If the string has a series of tokens with "=" in them at them, set - `after_vars' to point into the string after those tokens and any - trailing whitespace. Otherwise, after_vars == command. - */ - after_vars = command; - for (s = command; *s; s++) - { - if (*s == '=') got_eq = 1; - else if (*s == ' ') - { - if (got_eq) - { - while (*s == ' ' || *s == '\t') - s++; - after_vars = s; - got_eq = 0; - } - else - break; - } - } - - *command2 = 0; - strncat (command2, command, after_vars - command); - strcat (command2, "exec "); - strcat (command2, after_vars); - - /* We have now done these transformations: - "foo -x -y" ==> "exec foo -x -y" - "BLAT=foop foo -x" ==> "BLAT=foop exec foo -x" - "BLAT=foop A=b foo -x" ==> "BLAT=foop A=b exec foo -x" - */ - - - /* Invoke the shell as "/bin/sh -c 'exec prog -arg -arg ...'" */ - av [ac++] = (char *) shell; - av [ac++] = "-c"; - av [ac++] = command2; - av [ac] = 0; - - execvp (av[0], av); /* shouldn't return. */ - - { - char buf [512]; - sprintf (buf, "%s: execvp(\"%s\") failed", blurb(), av[0]); - perror (buf); - fflush(stderr); - fflush(stdout); - exit (1); /* Note that this only exits a child fork. */ - } -} - -#else /* VMS */ - -static void -exec_vms_command (const char *command) -{ - system (command); - fflush (stderr); - fflush (stdout); - exit (1); /* Note that this only exits a child fork. */ -} - -#endif /* !VMS */ - - -static void -exec_screenhack (saver_screen_info *ssi, const char *command) -{ - /* I don't believe what a sorry excuse for an operating system UNIX is! - - - I want to spawn a process. - - I want to know it's pid so that I can kill it. - - I would like to receive a message when it dies of natural causes. - - I want the spawned process to have user-specified arguments. - - If shell metacharacters are present (wildcards, backquotes, etc), the - only way to parse those arguments is to run a shell to do the parsing - for you. - - And the only way to know the pid of the process is to fork() and exec() - it in the spawned side of the fork. - - But if you're running a shell to parse your arguments, this gives you - the pid of the *shell*, not the pid of the *process* that you're - actually interested in, which is an *inferior* of the shell. This also - means that the SIGCHLD you get applies to the shell, not its inferior. - (Why isn't that sufficient? I don't remember any more, but it turns - out that it isn't.) - - So, the only solution, when metacharacters are present, is to force the - shell to exec() its inferior. What a fucking hack! We prepend "exec " - to the command string, and hope it doesn't contain unquoted semicolons - or ampersands (we don't search for them, because we don't want to - prohibit their use in quoted strings (messages, for example) and parsing - out the various quote characters is too much of a pain.) - - (Actually, Clint Wong points out that process groups - might be used to take care of this problem; this may be worth considering - some day, except that, 1: this code works now, so why fix it, and 2: from - what I've seen in Emacs, dealing with process groups isn't especially - portable.) - */ - saver_info *si = ssi->global; - saver_preferences *p = &si->prefs; - -#ifndef VMS - Bool hairy_p = !!strpbrk (command, "*?$&!<>[];`'\\\"="); - /* note: = is in the above because of the sh syntax "FOO=bar cmd". */ - - if (getuid() == (uid_t) 0 || geteuid() == (uid_t) 0) - { - /* If you're thinking of commenting this out, think again. - If you do so, you will open a security hole. Mail jwz - so that he may enlighten you as to the error of your ways. - */ - fprintf (stderr, "%s: we're still running as root! Disaster!\n", - blurb()); - saver_exit (si, 1, 0); - } - - if (p->verbose_p) - fprintf (stderr, "%s: %d: spawning \"%s\" in pid %lu%s.\n", - blurb(), ssi->number, command, - (unsigned long) getpid (), - (hairy_p ? " (via shell)" : "")); - - if (hairy_p) - /* If it contains any shell metacharacters, do it the hard way, - and fork a shell to parse the arguments for us. */ - exec_complex_command (p->shell, command); - else - /* Otherwise, we can just exec the program directly. */ - exec_simple_command (command); - -#else /* VMS */ - if (p->verbose_p) - fprintf (stderr, "%s: %d: spawning \"%s\" in pid %lu.\n", - blurb(), ssi->number, command, getpid()); - exec_vms_command (command); -#endif /* VMS */ - - abort(); /* that shouldn't have returned. */ -} - - /* Management of child processes, and de-zombification. */ @@ -844,6 +593,50 @@ select_visual_of_hack (saver_screen_info *ssi, screenhack *hack) } +static void +print_path_error (const char *program) +{ + char buf [512]; + char *cmd = strdup (program); + char *token = strchr (cmd, ' '); + + if (token) *token = 0; + sprintf (buf, "%s: could not execute \"%.100s\"", blurb(), cmd); + free (cmd); + perror (buf); + + if (errno == ENOENT && + (token = getenv("PATH"))) + { +# ifndef PATH_MAX +# ifdef MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# else +# define PATH_MAX 2048 +# endif +# endif + char path[PATH_MAX]; + fprintf (stderr, "\n"); + *path = 0; +# if defined(HAVE_GETCWD) + getcwd (path, sizeof(path)); +# elif defined(HAVE_GETWD) + getwd (path); +# endif + if (*path) + fprintf (stderr, " Current directory is: %s\n", path); + fprintf (stderr, " PATH is:\n"); + token = strtok (strdup(token), ":"); + while (token) + { + fprintf (stderr, " %s\n", token); + token = strtok(0, ":"); + } + fprintf (stderr, "\n"); + } +} + + static void spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p) { @@ -963,11 +756,18 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p) case 0: close (ConnectionNumber (si->dpy)); /* close display fd */ - nice_subproc (p->nice_inferior); /* change process priority */ limit_subproc_memory (p->inferior_memory_limit, p->verbose_p); hack_subproc_environment (ssi); /* set $DISPLAY */ - exec_screenhack (ssi, hack->command); /* this does not return */ - abort(); + + if (p->verbose_p) + fprintf (stderr, "%s: %d: spawning \"%s\" in pid %lu.\n", + blurb(), ssi->number, hack->command, + (unsigned long) getpid ()); + + exec_command (p->shell, hack->command, p->nice_inferior); + /* If that returned, we were unable to exec the subprocess. */ + print_path_error (hack->command); + exit (1); /* exits child fork */ break; default: @@ -1251,31 +1051,33 @@ save_argv (int argc, char **argv) } -/* Re-execs the process with the arguments in saved_argv. - Does not return unless there was an error. +/* Re-execs the process with the arguments in saved_argv. Does not return. */ void restart_process (saver_info *si) { + fflush (stdout); + fflush (stderr); + shutdown_stderr (si); if (si->prefs.verbose_p) { int i; - fprintf (real_stderr, "%s: re-executing", blurb()); + fprintf (stderr, "%s: re-executing", blurb()); for (i = 0; saved_argv[i]; i++) - fprintf (real_stderr, " %s", saved_argv[i]); - fprintf (real_stderr, "\n"); + fprintf (stderr, " %s", saved_argv[i]); + fprintf (stderr, "\n"); } - describe_uids (si, real_stderr); - fprintf (real_stderr, "\n"); + describe_uids (si, stderr); + fprintf (stderr, "\n"); - fflush (real_stdout); - fflush (real_stderr); + fflush (stdout); + fflush (stderr); execvp (saved_argv [0], saved_argv); /* shouldn't return */ { char buf [512]; sprintf (buf, "%s: could not restart process", blurb()); perror(buf); fflush(stderr); + abort(); } - XBell(si->dpy, 0); } diff --git a/driver/timers.c b/driver/timers.c index 7c2c363a..9f3877e5 100644 --- a/driver/timers.c +++ b/driver/timers.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #ifdef HAVE_XMU # ifndef VMS # include @@ -131,6 +133,12 @@ notice_events (saver_info *si, Window window, Bool top_p) the mouse or touching the keyboard, we won't know that they've been active, and the screensaver will come on. That sucks, but I don't know how to get around it. + + Since X presents mouse wheels as clicks, this applies to those, too: + scrolling through a document using only the mouse wheel doesn't + count as activity... Fortunately, /proc/interrupts helps, on + systems that have it. Oh, if it's a PS/2 mouse, not serial or USB. + This sucks! */ XSelectInput (si->dpy, window, SubstructureNotifyMask | events); diff --git a/driver/windows.c b/driver/windows.c index 8598e7e0..d6cb192e 100644 --- a/driver/windows.c +++ b/driver/windows.c @@ -36,6 +36,8 @@ #include #include /* for time() */ #include /* for the signal names */ +#include +#include #ifdef HAVE_MIT_SAVER_EXTENSION # include @@ -65,7 +67,7 @@ extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ -Atom XA_VROOT, XA_XSETROOT_ID; +Atom XA_VROOT, XA_XSETROOT_ID, XA_ESETROOT_PMAP_ID, XA_XROOTPMAP_ID; Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID; Atom XA_SCREENSAVER_STATUS; @@ -357,8 +359,12 @@ remove_vroot_property (Display *dpy, Window win) } +static Bool safe_XKillClient (Display *dpy, XID id); + static void -kill_xsetroot_data (Display *dpy, Window window, Bool verbose_p) +kill_xsetroot_data_1 (Display *dpy, Window window, + Atom prop, const char *atom_name, + Bool verbose_p) { Atom type; int format; @@ -376,8 +382,12 @@ kill_xsetroot_data (Display *dpy, Window window, Bool verbose_p) delete of the _XSETROOT_ID property, and if it held a pixmap, then we cause the RetainPermanent resources of the client which created it (and which no longer exists) to be freed. + + Update: it seems that Gnome and KDE do this same trick, but with the + properties "ESETROOT_PMAP_ID" and/or "_XROOTPMAP_ID" instead of + "_XSETROOT_ID". So, we'll kill those too. */ - if (XGetWindowProperty (dpy, window, XA_XSETROOT_ID, 0, 1, + if (XGetWindowProperty (dpy, window, prop, 0, 1, True, AnyPropertyType, &type, &format, &nitems, &bytesafter, (unsigned char **) &dataP) == Success @@ -387,20 +397,31 @@ kill_xsetroot_data (Display *dpy, Window window, Bool verbose_p) nitems == 1 && bytesafter == 0) { if (verbose_p) - fprintf (stderr, "%s: destroying xsetroot data (0x%lX).\n", - blurb(), *dataP); - XKillClient (dpy, *dataP); + fprintf (stderr, "%s: destroying %s data (0x%lX).\n", + blurb(), atom_name, *dataP); + safe_XKillClient (dpy, *dataP); } else - fprintf (stderr, "%s: deleted unrecognised _XSETROOT_ID property: \n\ - %lu, %lu; type: %lu, format: %d, nitems: %lu, bytesafter %ld\n", - blurb(), (unsigned long) dataP, (dataP ? *dataP : 0), type, + fprintf (stderr, + "%s: deleted unrecognised %s property: \n" + "\t%lu, %lu; type: %lu, format: %d, " + "nitems: %lu, bytesafter %ld\n", + blurb(), atom_name, + (unsigned long) dataP, (dataP ? *dataP : 0), type, format, nitems, bytesafter); } } -static void handle_signals (saver_info *si, Bool on_p); +static void +kill_xsetroot_data (Display *dpy, Window w, Bool verbose_p) +{ + kill_xsetroot_data_1 (dpy, w, XA_XSETROOT_ID, "_XSETROOT_ID", verbose_p); + kill_xsetroot_data_1 (dpy, w, XA_ESETROOT_PMAP_ID, "ESETROOT_PMAP_ID", + verbose_p); + kill_xsetroot_data_1 (dpy, w, XA_XROOTPMAP_ID, "_XROOTPMAP_ID", verbose_p); +} + static void save_real_vroot (saver_screen_info *ssi) @@ -463,7 +484,6 @@ save_real_vroot (saver_screen_info *ssi) if (ssi->real_vroot) { - handle_signals (si, True); remove_vroot_property (si->dpy, ssi->real_vroot); XSync (dpy, False); } @@ -473,7 +493,7 @@ save_real_vroot (saver_screen_info *ssi) static Bool -restore_real_vroot_2 (saver_screen_info *ssi) +restore_real_vroot_1 (saver_screen_info *ssi) { saver_info *si = ssi->global; saver_preferences *p = &si->prefs; @@ -496,27 +516,20 @@ restore_real_vroot_2 (saver_screen_info *ssi) return False; } -static Bool -restore_real_vroot_1 (saver_info *si) +Bool +restore_real_vroot (saver_info *si) { int i; Bool did_any = False; for (i = 0; i < si->nscreens; i++) { saver_screen_info *ssi = &si->screens[i]; - if (restore_real_vroot_2 (ssi)) + if (restore_real_vroot_1 (ssi)) did_any = True; } return did_any; } -void -restore_real_vroot (saver_info *si) -{ - if (restore_real_vroot_1 (si)) - handle_signals (si, False); -} - /* Signal hackery to ensure that the vroot doesn't get left in an inconsistent state @@ -603,67 +616,102 @@ restore_real_vroot_handler (int sig) saver_info *si = global_si_kludge; /* I hate C so much... */ signal (sig, SIG_DFL); - if (restore_real_vroot_1 (si)) + if (restore_real_vroot (si)) fprintf (real_stderr, "\n%s: %s intercepted, vroot restored.\n", blurb(), signal_name(sig)); kill (getpid (), sig); } static void -catch_signal (saver_info *si, int sig, Bool on_p) +catch_signal (saver_info *si, int sig, RETSIGTYPE (*handler) (int)) { - if (! on_p) - signal (sig, SIG_DFL); - else +# ifdef HAVE_SIGACTION + + struct sigaction a; + a.sa_handler = handler; + sigemptyset (&a.sa_mask); + a.sa_flags = 0; + + /* On Linux 2.4.9 (at least) we need to tell the kernel to not mask delivery + of this signal from inside its handler, or else when we execvp() the + process again, it starts up with SIGHUP blocked, meaning that killing + it with -HUP only works *once*. You'd think that execvp() would reset + all the signal masks, but it doesn't. + */ +# if defined(SA_NOMASK) + a.sa_flags |= SA_NOMASK; +# elif defined(SA_NODEFER) + a.sa_flags |= SA_NODEFER; +# endif + + if (sigaction (sig, &a, 0) < 0) +# else /* !HAVE_SIGACTION */ + if (((long) signal (sig, handler)) == -1L) +# endif /* !HAVE_SIGACTION */ { - if (((long) signal (sig, restore_real_vroot_handler)) == -1L) - { - char buf [255]; - sprintf (buf, "%s: couldn't catch %s", blurb(), signal_name(sig)); - perror (buf); - saver_exit (si, 1, 0); - } + char buf [255]; + sprintf (buf, "%s: couldn't catch %s", blurb(), signal_name(sig)); + perror (buf); + saver_exit (si, 1, 0); } } -static void -handle_signals (saver_info *si, Bool on_p) +static RETSIGTYPE saver_sighup_handler (int sig); + +void +handle_signals (saver_info *si) { -#if 0 - if (on_p) fprintf (stderr, "handling signals\n"); - else fprintf (stderr, "unhandling signals\n"); -#endif + catch_signal (si, SIGHUP, saver_sighup_handler); - catch_signal (si, SIGHUP, on_p); - catch_signal (si, SIGINT, on_p); - catch_signal (si, SIGQUIT, on_p); - catch_signal (si, SIGILL, on_p); - catch_signal (si, SIGTRAP, on_p); + catch_signal (si, SIGINT, restore_real_vroot_handler); + catch_signal (si, SIGQUIT, restore_real_vroot_handler); + catch_signal (si, SIGILL, restore_real_vroot_handler); + catch_signal (si, SIGTRAP, restore_real_vroot_handler); #ifdef SIGIOT - catch_signal (si, SIGIOT, on_p); + catch_signal (si, SIGIOT, restore_real_vroot_handler); #endif - catch_signal (si, SIGABRT, on_p); + catch_signal (si, SIGABRT, restore_real_vroot_handler); #ifdef SIGEMT - catch_signal (si, SIGEMT, on_p); + catch_signal (si, SIGEMT, restore_real_vroot_handler); #endif - catch_signal (si, SIGFPE, on_p); - catch_signal (si, SIGBUS, on_p); - catch_signal (si, SIGSEGV, on_p); + catch_signal (si, SIGFPE, restore_real_vroot_handler); + catch_signal (si, SIGBUS, restore_real_vroot_handler); + catch_signal (si, SIGSEGV, restore_real_vroot_handler); #ifdef SIGSYS - catch_signal (si, SIGSYS, on_p); + catch_signal (si, SIGSYS, restore_real_vroot_handler); #endif - catch_signal (si, SIGTERM, on_p); + catch_signal (si, SIGTERM, restore_real_vroot_handler); #ifdef SIGXCPU - catch_signal (si, SIGXCPU, on_p); + catch_signal (si, SIGXCPU, restore_real_vroot_handler); #endif #ifdef SIGXFSZ - catch_signal (si, SIGXFSZ, on_p); + catch_signal (si, SIGXFSZ, restore_real_vroot_handler); #endif #ifdef SIGDANGER - catch_signal (si, SIGDANGER, on_p); + catch_signal (si, SIGDANGER, restore_real_vroot_handler); #endif } + +static RETSIGTYPE +saver_sighup_handler (int sig) +{ + saver_info *si = global_si_kludge; /* I hate C so much... */ + + /* Re-establish SIGHUP handler */ + catch_signal (si, SIGHUP, saver_sighup_handler); + + fprintf (stderr, "%s: %s received: restarting...\n", + blurb(), signal_name(sig)); + unblank_screen (si); + kill_screenhack (si); + XSync (si->dpy, False); + restart_process (si); /* Does not return */ + abort (); +} + + + void saver_exit (saver_info *si, int status, const char *dump_core_reason) { @@ -677,7 +725,7 @@ saver_exit (saver_info *si, int status, const char *dump_core_reason) exiting = True; - vrs = restore_real_vroot_1 (si); + vrs = restore_real_vroot (si); emergency_kill_subproc (si); shutdown_stderr (si); @@ -1097,6 +1145,24 @@ safe_XDestroyWindow (Display *dpy, Window window) } +static Bool +safe_XKillClient (Display *dpy, XID id) +{ + XErrorHandler old_handler; + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + XKillClient (dpy, id); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + return (!error_handler_hit_p); +} + + static void initialize_screensaver_window_1 (saver_screen_info *ssi) { diff --git a/driver/xscreensaver-command.c b/driver/xscreensaver-command.c index 53712ee2..8cd1928c 100644 --- a/driver/xscreensaver-command.c +++ b/driver/xscreensaver-command.c @@ -16,6 +16,7 @@ #include #include +#include #include #include diff --git a/driver/xscreensaver-command.man b/driver/xscreensaver-command.man index e9faa1e8..207f2fa9 100644 --- a/driver/xscreensaver-command.man +++ b/driver/xscreensaver-command.man @@ -11,7 +11,7 @@ .if n .sp 1 .if t .sp .5 .. -.TH XScreenSaver 1 "02-Jan-2002 (4.00)" "X Version 11" +.TH XScreenSaver 1 "24-Feb-2002 (4.01)" "X Version 11" .SH NAME xscreensaver-command - control a running xscreensaver process .SH SYNOPSIS @@ -88,10 +88,14 @@ the screensaver comes on. (Because if you jiggle the mouse, xscreensaver will notice, and deactivate.) .TP 8 .B \-deactivate -If the screensaver is active (the screen is blanked), this command will -deactivate it just as if there had been keyboard or mouse activity. -If locking is enabled, then the screensaver will prompt for a password -as usual. +This tells xscreensaver to pretend that there has just been user activity. +This means that if the screensaver is active (the screen is blanked), +then this command will cause the screen to un-blank as if there had been +keyboard or mouse activity. If the screen is locked, then the password +dialog will pop up first, as usual. If the screen is not blanked, then +this simulated user activity will re-start the countdown (so, issuing +the \fI\-deactivate\fP command periodically is \fIone\fP way to prevent +the screen from blanking.) .TP 8 .B \-cycle If the screensaver is active (the screen is blanked), then stop the current @@ -252,7 +256,7 @@ and related tools can always be found at http://www.jwz.org/xscreensaver/ .BR xscreensaver (1) .BR xscreensaver\-demo (1) .SH COPYRIGHT -Copyright \(co 1992, 1993, 1997, 1998, 1999, 2000, 2001 +Copyright \(co 1992, 1993, 1997, 1998, 1999, 2000, 2001, 2002 by Jamie Zawinski. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that diff --git a/driver/xscreensaver-demo.man b/driver/xscreensaver-demo.man index f4f6d246..a275a2ca 100644 --- a/driver/xscreensaver-demo.man +++ b/driver/xscreensaver-demo.man @@ -11,7 +11,7 @@ .if n .sp 1 .if t .sp .5 .. -.TH XScreenSaver 1 "02-Jan-2002 (4.00)" "X Version 11" +.TH XScreenSaver 1 "24-Feb-2002 (4.01)" "X Version 11" .SH NAME xscreensaver-demo - interactively control the background xscreensaver daemon .SH SYNOPSIS @@ -338,7 +338,7 @@ http://www.jwz.org/xscreensaver/ .BR xscreensaver\-command (1), .BR xscreensaver\-getimage (1) .SH COPYRIGHT -Copyright \(co 1992, 1993, 1997, 1998, 1999, 2000, 2001 +Copyright \(co 1992, 1993, 1997, 1998, 1999, 2000, 2001, 2002 by Jamie Zawinski. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that diff --git a/driver/xscreensaver-getimage-file b/driver/xscreensaver-getimage-file index 6370db1c..2da17d59 100755 --- a/driver/xscreensaver-getimage-file +++ b/driver/xscreensaver-getimage-file @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# Copyright © 2001 Jamie Zawinski , all rights reserved. +# Copyright © 2001, 2002 Jamie Zawinski . # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that @@ -29,10 +29,10 @@ use strict; use POSIX; use Fcntl; - +use Fcntl ':mode'; my $progname = $0; $progname =~ s@.*/@@g; -my $version = q{ $Revision: 1.6 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; +my $version = q{ $Revision: 1.8 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; my $verbose = 0; @@ -99,8 +99,21 @@ sub find_all_files { next if ($file eq "core"); $file = "$dir/$file"; + my @st = stat($file); my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, - $atime,$mtime,$ctime,$blksize,$blocks) = stat($file); + $atime,$mtime,$ctime,$blksize,$blocks) = @st; + + if ($#st == -1) { + if ($verbose) { + my $ll = readlink $file; + if (defined ($ll)) { + print STDERR "$progname: dangling symlink: $file -> $ll\n"; + } else { + print STDERR "$progname: unreadable: $file\n"; + } + } + next; + } next if ($seen_inodes{$ino}); # break symlink loops $seen_inodes{$ino} = 1; @@ -129,10 +142,16 @@ sub find_random_file { print STDERR "$progname: recursively reading $dir...\n" if ($verbose > 1); find_all_files ($dir); - print STDERR "$progname: found $#all_files files\n" if ($verbose > 1); + print STDERR "$progname: found " . ($#all_files+1) . " files\n" + if ($verbose > 1); @all_files = sort(@all_files); + if ($#all_files < 0) { + print STDERR "$progname: no files in $dir\n"; + exit 1; + } + my $n = int (rand ($#all_files + 1)); my $file = $all_files[$n]; diff --git a/driver/xscreensaver-getimage-file.man b/driver/xscreensaver-getimage-file.man index 175e744e..ca0e92cb 100644 --- a/driver/xscreensaver-getimage-file.man +++ b/driver/xscreensaver-getimage-file.man @@ -1,4 +1,4 @@ -.TH XScreenSaver 1 "02-Jan-2002 (4.00)" "X Version 11" +.TH XScreenSaver 1 "24-Feb-2002 (4.01)" "X Version 11" .SH NAME xscreensaver-getimage-file - put a randomly-selected image on the root window .SH SYNOPSIS diff --git a/driver/xscreensaver-getimage-video b/driver/xscreensaver-getimage-video index 4dc449ff..7612b123 100755 --- a/driver/xscreensaver-getimage-video +++ b/driver/xscreensaver-getimage-video @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# Copyright © 2001 Jamie Zawinski , all rights reserved. +# Copyright © 2001, 2002 Jamie Zawinski . # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that @@ -29,7 +29,7 @@ use diagnostics; use strict; my $progname = $0; $progname =~ s@.*/@@g; -my $version = q{ $Revision: 1.6 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; +my $version = q{ $Revision: 1.7 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; my $verbose = 0; @@ -57,6 +57,9 @@ my @programs = ( "streamer -s 768x576 -o $tmpfile", # XawTV "atitv snap $tmpfile", # ATI video capture card + "grab -type ppm -format ntsc -source 1 " . + "-settle 0.75 -output $tmpfile", # *BSD BT848 module + "vidtomem -f $tmpfile 2>&- && mv $sgi_bogosity $tmpfile", # Silicon Graphics ); diff --git a/driver/xscreensaver-getimage-video.man b/driver/xscreensaver-getimage-video.man index e6674b17..2f051282 100644 --- a/driver/xscreensaver-getimage-video.man +++ b/driver/xscreensaver-getimage-video.man @@ -1,4 +1,4 @@ -.TH XScreenSaver 1 "02-Jan-2002 (4.00)" "X Version 11" +.TH XScreenSaver 1 "24-Feb-2002 (4.01)" "X Version 11" .SH NAME xscreensaver-getimage-video - put a video frame on the root window .SH SYNOPSIS diff --git a/driver/xscreensaver-getimage.c b/driver/xscreensaver-getimage.c index c5c30299..46e3019e 100644 --- a/driver/xscreensaver-getimage.c +++ b/driver/xscreensaver-getimage.c @@ -16,6 +16,7 @@ #include "utils.h" #include +#include #include #ifdef HAVE_XMU @@ -32,6 +33,7 @@ #include "grabscreen.h" #include "resources.h" #include "colorbars.h" +#include "visual.h" #include "prefs.h" #include "vroot.h" @@ -129,6 +131,10 @@ get_image (Screen *screen, Window window, Bool verbose_p) enum { do_desk, do_video, do_image, do_bars } which = do_bars; int count = 0; + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + screen = xgwa.screen; + if (verbose_p) { fprintf (stderr, "%s: grabDesktopImages: %s\n", @@ -195,13 +201,17 @@ get_image (Screen *screen, Window window, Bool verbose_p) if (count == 0) which = do_bars; else - while (1) /* loop until we get one that's permitted */ - { - which = (random() % 3); - if (which == do_desk && desk_p) break; - if (which == do_video && video_p) break; - if (which == do_image && image_p) break; - } + { + int i = 0; + while (1) /* loop until we get one that's permitted */ + { + which = (random() % 3); + if (which == do_desk && desk_p) break; + if (which == do_video && video_p) break; + if (which == do_image && image_p) break; + if (++i > 200) abort(); + } + } if (which == do_desk) { @@ -215,8 +225,6 @@ get_image (Screen *screen, Window window, Bool verbose_p) } else if (which == do_bars) { - XWindowAttributes xgwa; - XGetWindowAttributes (dpy, window, &xgwa); if (verbose_p) fprintf (stderr, "%s: drawing colorbars\n", progname); draw_colorbars (dpy, window, 0, 0, xgwa.width, xgwa.height); @@ -271,8 +279,20 @@ get_image (Screen *screen, Window window, Bool verbose_p) { const char *odpy = DisplayString (dpy); char *ndpy = (char *) malloc(strlen(odpy) + 20); + char *s; + int screen_no = screen_number (screen); /* might not be default now */ + strcpy (ndpy, "DISPLAY="); - strcat (ndpy, odpy); + s = ndpy + strlen(ndpy); + strcpy (s, odpy); + + while (*s && *s != ':') s++; /* skip to colon */ + while (*s == ':') s++; /* skip over colons */ + while (isdigit(*s)) s++; /* skip over dpy number */ + while (*s == '.') s++; /* skip over dot */ + if (s[-1] != '.') *s++ = '.'; /* put on a dot */ + sprintf(s, "%d", screen_no); /* put on screen number */ + if (putenv (ndpy)) abort (); } diff --git a/driver/xscreensaver-getimage.man b/driver/xscreensaver-getimage.man index 37791f54..682c3512 100644 --- a/driver/xscreensaver-getimage.man +++ b/driver/xscreensaver-getimage.man @@ -1,4 +1,4 @@ -.TH XScreenSaver 1 "02-Jan-2002 (4.00)" "X Version 11" +.TH XScreenSaver 1 "24-Feb-2002 (4.01)" "X Version 11" .SH NAME xscreensaver-getimage - put some randomly-selected image on the root window .SH SYNOPSIS diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index 67daea81..628bcf1d 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -132,6 +132,8 @@ #include #include #include +#include +#include #include /* for gethostbyname() */ #ifdef HAVE_XMU # ifndef VMS @@ -471,6 +473,16 @@ lock_initialization (saver_info *si, int *argc, char **argv) si->locking_disabled_p = True; si->nolock_reason = "error getting password"; } + + /* If locking is currently enabled, but the environment indicates that + we have been launched as GDM's "Background" program, then disable + locking just in case. + */ + if (!si->locking_disabled_p && getenv ("RUNNING_UNDER_GDM")) + { + si->locking_disabled_p = True; + si->nolock_reason = "running under GDM"; + } #endif /* NO_LOCKING */ hack_uid (si); @@ -523,6 +535,8 @@ connect_to_server (saver_info *si, int *argc, char **argv) XA_SCREENSAVER_RESPONSE = XInternAtom (si->dpy, "_SCREENSAVER_RESPONSE", False); XA_XSETROOT_ID = XInternAtom (si->dpy, "_XSETROOT_ID", False); + XA_ESETROOT_PMAP_ID = XInternAtom (si->dpy, "ESETROOT_PMAP_ID", False); + XA_XROOTPMAP_ID = XInternAtom (si->dpy, "_XROOTPMAP_ID", False); XA_ACTIVATE = XInternAtom (si->dpy, "ACTIVATE", False); XA_DEACTIVATE = XInternAtom (si->dpy, "DEACTIVATE", False); XA_RESTART = XInternAtom (si->dpy, "RESTART", False); @@ -1121,6 +1135,53 @@ main_loop (saver_info *si) si->lock_id = 0; } + /* It's possible that a race condition could have led to the saver + window being unexpectedly still mapped. This can happen like so: + + - screen is blanked + - hack is launched + - that hack tries to grab a screen image( it does this by + first unmapping the saver window, then remapping it.) + - hack unmaps window + - hack waits + - user becomes active + - hack re-maps window (*) + - driver kills subprocess + - driver unmaps window (**) + + The race is that (*) might have been sent to the server before + the client process was killed, but, due to scheduling randomness, + might not have been received by the server until after (**). + In other words, (*) and (**) might happen out of order, meaning + the driver will unmap the window, and then after that, the + recently-dead client will re-map it. This leaves the user + locked out (it looks like a desktop, but it's not!) + + To avoid this: after un-blanking the screen, sleep for a second, + and then really make sure the window is unmapped. + */ + { + int i; + XSync (si->dpy, False); + sleep (1); + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + Window w = ssi->screensaver_window; + XWindowAttributes xgwa; + XGetWindowAttributes (si->dpy, w, &xgwa); + if (xgwa.map_state != IsUnmapped) + { + if (p->verbose_p) + fprintf (stderr, + "%s: %d: client race! emergency unmap 0x%lx.\n", + blurb(), i, (unsigned long) w); + XUnmapWindow (si->dpy, w); + } + } + XSync (si->dpy, False); + } + if (p->verbose_p) fprintf (stderr, "%s: awaiting idleness.\n", blurb()); } @@ -1190,6 +1251,7 @@ main (int argc, char **argv) False); initialize_stderr (si); + handle_signals (si); make_splash_dialog (si); @@ -1281,6 +1343,60 @@ clientmessage_response (saver_info *si, Window w, Bool error, free (proto); } + +static void +bogus_clientmessage_warning (saver_info *si, XEvent *event) +{ + char *str = XGetAtomName_safe (si->dpy, event->xclient.message_type); + Window w = event->xclient.window; + char wdesc[255]; + int screen = 0; + + *wdesc = 0; + for (screen = 0; screen < si->nscreens; screen++) + if (w == si->screens[screen].screensaver_window) + { + strcpy (wdesc, "xscreensaver"); + break; + } + else if (w == RootWindow (si->dpy, screen)) + { + strcpy (wdesc, "root"); + break; + } + + if (!*wdesc) + { + XErrorHandler old_handler; + XClassHint hint; + XWindowAttributes xgwa; + memset (&hint, 0, sizeof(hint)); + memset (&xgwa, 0, sizeof(xgwa)); + + XSync (si->dpy, False); + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + XGetClassHint (si->dpy, w, &hint); + XGetWindowAttributes (si->dpy, w, &xgwa); + XSync (si->dpy, False); + XSetErrorHandler (old_handler); + XSync (si->dpy, False); + + screen = (xgwa.screen ? screen_number (xgwa.screen) : -1); + + sprintf (wdesc, "%.20s / %.20s", + (hint.res_name ? hint.res_name : "(null)"), + (hint.res_class ? hint.res_class : "(null)")); + if (hint.res_name) XFree (hint.res_name); + if (hint.res_class) XFree (hint.res_class); + } + + fprintf (stderr, "%s: %d: unrecognised ClientMessage \"%s\" received\n", + blurb(), screen, (str ? str : "(null)")); + fprintf (stderr, "%s: %d: for window 0x%lx (%s)\n", + blurb(), screen, (unsigned long) w, wdesc); + if (str) XFree (str); +} + Bool handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) { @@ -1291,19 +1407,10 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) /* Preferences might affect our handling of client messages. */ maybe_reload_init_file (si); - if (event->xclient.message_type != XA_SCREENSAVER) - { - char *str; - str = XGetAtomName_safe (si->dpy, event->xclient.message_type); - fprintf (stderr, "%s: unrecognised ClientMessage type %s received\n", - blurb(), (str ? str : "(null)")); - if (str) XFree (str); - return False; - } - if (event->xclient.format != 32) + if (event->xclient.message_type != XA_SCREENSAVER || + event->xclient.format != 32) { - fprintf (stderr, "%s: ClientMessage of format %d received, not 32\n", - blurb(), event->xclient.format); + bogus_clientmessage_warning (si, event); return False; } @@ -1476,17 +1583,8 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) XSync (si->dpy, False); } - fflush (stdout); - fflush (stderr); - if (real_stdout) fflush (real_stdout); - if (real_stderr) fflush (real_stderr); - /* make sure error message shows up before exit. */ - if (real_stderr && stderr != real_stderr) - dup2 (fileno(real_stderr), fileno(stderr)); - - restart_process (si); - exit (1); /* shouldn't get here; but if restarting didn't work, - make this command be the same as EXIT. */ + restart_process (si); /* does not return */ + abort(); } else clientmessage_response (si, window, True, diff --git a/driver/xscreensaver.h b/driver/xscreensaver.h index 3ab14eaa..41b1d718 100644 --- a/driver/xscreensaver.h +++ b/driver/xscreensaver.h @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1993-2001 Jamie Zawinski +/* xscreensaver, Copyright (c) 1993-2002 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -270,7 +270,7 @@ struct saver_screen_info { server extensions and virtual roots ======================================================================= */ -extern void restore_real_vroot (saver_info *si); +extern Bool restore_real_vroot (saver_info *si); extern void disable_builtin_screensaver (saver_info *, Bool unblank_screen_p); extern Bool ensure_no_screensaver_running (Display *, Screen *); @@ -373,6 +373,7 @@ extern void maybe_reload_init_file (saver_info *); subprocs ======================================================================= */ +extern void handle_signals (saver_info *si); extern void block_sigchld (void); extern void unblock_sigchld (void); extern void hack_environment (saver_info *si); @@ -386,6 +387,8 @@ extern void emergency_kill_subproc (saver_info *si); extern Bool select_visual (saver_screen_info *ssi, const char *visual_name); extern void store_saver_status (saver_info *si); extern const char *signal_name (int signal); +extern void exec_command (const char *shell, const char *command, + int nice_level); /* ======================================================================= subprocs diagnostics @@ -415,7 +418,7 @@ extern char *timestring (void); extern Bool display_is_on_console_p (saver_info *si); extern Visual *get_best_gl_visual (saver_screen_info *ssi); -extern Atom XA_VROOT, XA_XSETROOT_ID; +extern Atom XA_VROOT, XA_XSETROOT_ID, XA_ESETROOT_PMAP_ID, XA_XROOTPMAP_ID; extern Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID; extern Atom XA_SCREENSAVER_STATUS, XA_LOCK, XA_BLANK; extern Atom XA_DEMO, XA_PREFS; diff --git a/driver/xscreensaver.man b/driver/xscreensaver.man index 77b960bb..93d9adf3 100644 --- a/driver/xscreensaver.man +++ b/driver/xscreensaver.man @@ -11,7 +11,7 @@ .if n .sp 1 .if t .sp .5 .. -.TH XScreenSaver 1 "02-Jan-2002 (4.00)" "X Version 11" +.TH XScreenSaver 1 "24-Feb-2002 (4.01)" "X Version 11" .SH NAME xscreensaver - extensible screen saver framework, plus locking .SH SYNOPSIS @@ -599,6 +599,11 @@ settings has no effect: many laptops have monitor power-saving behavior built in at a very low level that is invisible to Unix and X. On such systems, you can typically adjust the power-saving delays only by changing settings in the BIOS in some hardware-specific way. + +If DPMS seems not to be working with XFree86, make sure the "DPMS" +option is set in your \fI/etc/X11/XF86Config\fP file. See the +.BR XF86Config (5) +manual for details. .SH USING XDM(1) You can run \fIxscreensaver\fP from your .BR xdm (1) @@ -715,23 +720,20 @@ man pages for and .BR xhost (1). .SH USING GDM(1) -The instructions for using \fIxscreensaver\fP with -.BR gdm (1) -are almost the same as for using -.BR xdm (1), -above. There are only two differences, really: instead -of editing \fI/usr/lib/X11/xdm/Xsetup\fP, edit the -file \fI/etc/X11/gdm/Init/Default\fP; and instead of -editing \fI/usr/lib/X11/xdm/Xsession\fP, edit one or all of the -files in the \fI/etc/X11/gdm/Sessions/\fP directory. (Note that -the default session (\fI/etc/X11/gdm/Sessions/Default\fP) usually -simply executes \fI/usr/lib/X11/xdm/Xsession\fP, so be careful -you aren't initializing xscreensaver twice.) - -All the same caveats apply for +Using xscreensaver with .BR gdm (1) -as for -.BR xdm (1). +is easy, because gdm has a configuration tool. Just fire up +.BR gdmconfig (1) +and on the \fIBackground\fP page, type \fB"xscreensaver -nosplash"\fP into +the \fIBackground Program\fP field. That will cause gdm to run xscreensaver +while nobody is logged in, and kill it as soon as someone does log in. +(The user will then be responsible for starting xscreensaver on their +own, if they want.) + +In this situation, the \fIxscreensaver\fP process will probably be running +as user \fIgdm\fP instead of \fIroot\fP. You can configure the settings +for this nobody-logged-in state (timeouts, DPMS, etc.) by editing +the \fI~gdm/.xscreensaver\fP file. .SH USING CDE (COMMON DESKTOP ENVIRONMENT) The easiest way to use \fIxscreensaver\fP on a system with CDE is to simply switch off the built-in CDE screensaver, and use \fIxscreensaver\fP instead; @@ -839,6 +841,21 @@ This associates the VUE front panel ``Lock'' icon with the xscreensaver lock command. .RE .PP +.SH USING KDE (K DESKTOP ENVIRONMENT) +I understand that KDE has invented their own wrapper around xscreensaver, +that is inferior to +.BR xscreensaver-demo (1) +in any number of ways. I've never actually seen it. Presumably, there is +some way to turn off KDE's screensaver framework, and make it so that the +usual +.BR xscreensaver-demo (1) +and +.BR xscreensaver-command (1) +mechanisms are used, in a similar way to how one can reconfigure CDE and +VUE environments, above. + +But I don't know how. If you do, please let me know, and I'll document +it here. .SH ADDING TO MENUS The .BR xscreensaver-command (1) diff --git a/hacks/Makefile.in b/hacks/Makefile.in index 69d0fe43..008ec75d 100644 --- a/hacks/Makefile.in +++ b/hacks/Makefile.in @@ -51,6 +51,7 @@ HACK_PRE = $(LIBS) $(X_LIBS) HACK_POST = $(X_PRE_LIBS) -lXt -lX11 $(XMU_LIBS) -lXext $(X_EXTRA_LIBS) -lm HACK_LIBS = $(HACK_PRE) @HACK_LIBS@ $(HACK_POST) XPM_LIBS = $(HACK_PRE) @XPM_LIBS@ @HACK_LIBS@ $(HACK_POST) +JPEG_LIBS = @JPEG_LIBS@ XLOCK_LIBS = $(HACK_LIBS) UTILS_SRC = $(srcdir)/../utils @@ -91,7 +92,9 @@ SRCS = attraction.c blitspin.c bouboule.c braid.c bubbles.c \ phosphor.c xmatrix.c petri.c shadebobs.c xsublim.c ccurve.c \ blaster.c bumps.c ripples.c xteevee.c xspirograph.c \ nerverot.c xrayswarm.c hyperball.c zoom.c whirlwindwarp.c \ - rotzoomer.c whirlygig.c speedmine.c vermiculate.c + rotzoomer.c whirlygig.c speedmine.c vermiculate.c \ + xpm-pixmap.c webcollage-helper.c twang.c apollonian.c \ + euler2d.c juggle.c polyominoes.c thornbird.c SCRIPTS = vidwhacker webcollage OBJS = attraction.o blitspin.o bouboule.o braid.o bubbles.o \ @@ -112,7 +115,9 @@ OBJS = attraction.o blitspin.o bouboule.o braid.o bubbles.o \ phosphor.o xmatrix.o petri.o shadebobs.o xsublim.o ccurve.o \ blaster.o bumps.o ripples.o xteevee.o xspirograph.o \ nerverot.o xrayswarm.o hyperball.o zoom.o whirlwindwarp.o \ - rotzoomer.o whirlygig.o speedmine.o vermiculate.o + rotzoomer.o whirlygig.o speedmine.o vermiculate.o \ + xpm-pixmap.o webcollage-helper.o twang.o apollonian.o \ + euler2d.o juggle.o polyominoes.o thornbird.o NEXES = attraction blitspin bouboule braid bubbles decayscreen deco \ drift flag flame forest vines galaxy grav greynetic halo \ @@ -127,8 +132,11 @@ NEXES = attraction blitspin bouboule braid bubbles decayscreen deco \ wander spotlight critical phosphor xmatrix petri shadebobs \ xsublim ccurve blaster bumps ripples xteevee xspirograph \ nerverot xrayswarm hyperball zoom whirlwindwarp rotzoomer \ - whirlygig speedmine vermiculate + whirlygig speedmine vermiculate twang apollonian euler2d \ + juggle polyominoes thornbird \ + @JPEG_EXES@ SEXES = sonar +JPEG_EXES = webcollage-helper EXES = $(NEXES) $(SEXES) HACK_OBJS_1 = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \ @@ -141,7 +149,7 @@ XSHM_OBJS = $(UTILS_BIN)/xshm.o XDBE_OBJS = $(UTILS_BIN)/xdbe.o HDRS = bubbles.h screenhack.h xlockmore.h xlockmoreI.h automata.h \ - bumps.h + bumps.h xpm-pixmap.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 \ @@ -157,7 +165,8 @@ MEN = attraction.man blitspin.man bouboule.man braid.man \ vidwhacker.man webcollage.man xsublim.man distort.man \ phosphor.man xmatrix.man xteevee.man xflame.man petri.man \ nerverot.man zoom.man whirlwindwarp.man hyperball.man \ - rotzoomer.man whirlygig.man speedmine.man penetrate.man + rotzoomer.man whirlygig.man speedmine.man penetrate.man \ + xspirograph.man twang.man STAR = * EXTRAS = README Makefile.in xlock_23.h .gdbinit \ config/README \ @@ -269,11 +278,11 @@ install-xml: @if [ ! -d $(install_prefix)$(HACK_CONF_DIR) ]; then \ $(INSTALL_DIRS) $(install_prefix)$(HACK_CONF_DIR) ; \ fi ; \ - cd $(srcdir)/config/ ; \ - for file in README $(STAR).xml ; do \ - echo $(INSTALL_DATA) $$file \ + files=`cd $(srcdir)/config/ ; echo README $(STAR).xml` ; \ + for file in $$files ; do \ + echo $(INSTALL_DATA) config/$$file \ $(install_prefix)$(HACK_CONF_DIR)/$$file ; \ - $(INSTALL_DATA) $$file \ + $(INSTALL_DATA) config/$$file \ $(install_prefix)$(HACK_CONF_DIR)/$$file ; \ done @@ -427,6 +436,7 @@ screenhack-xlock.o: screenhack.c -DXLOCKMORE $(srcdir)/screenhack.c # Some abbreviations to keep the lines short... +XPM = xpm-pixmap.o ALP = $(UTILS_BIN)/alpha.o HSV = $(UTILS_BIN)/hsv.o SPL = $(UTILS_BIN)/spline.o @@ -454,11 +464,11 @@ xscreensaver-sgigl: xscreensaver-sgigl.c attraction: attraction.o $(HACK_OBJS) $(COL) $(SPL) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(SPL) $(HACK_LIBS) -blitspin: blitspin.o $(HACK_OBJS) $(GRAB) - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(XPM_LIBS) +blitspin: blitspin.o $(HACK_OBJS) $(GRAB) $(XPM) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(XPM) $(XPM_LIBS) -bubbles: bubbles.o $(HACK_OBJS) bubbles-default.o - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) bubbles-default.o $(XPM_LIBS) +bubbles: bubbles.o $(HACK_OBJS) bubbles-default.o $(XPM) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) bubbles-default.o $(XPM) $(XPM_LIBS) decayscreen: decayscreen.o $(HACK_OBJS) $(GRAB) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(HACK_LIBS) @@ -499,8 +509,8 @@ moire: moire.o $(HACK_OBJS) $(COL) $(SHM) moire2: moire2.o $(HACK_OBJS) $(COL) $(DBE) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(DBE) $(HACK_LIBS) -noseguy: noseguy.o $(HACK_OBJS) - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(XPM_LIBS) +noseguy: noseguy.o $(HACK_OBJS) $(XPM) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(XPM) $(XPM_LIBS) pedal: pedal.o $(HACK_OBJS) $(HSV) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(HSV) $(HACK_LIBS) @@ -556,8 +566,8 @@ interference: interference.o $(HACK_OBJS) $(COL) $(SHM) $(DBE) truchet: truchet.o $(HACK_OBJS) $(COL) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(HACK_LIBS) -bsod: bsod.o $(HACK_OBJS) $(GRAB) - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(HACK_LIBS) $(XPM_LIBS) +bsod: bsod.o $(HACK_OBJS) $(GRAB) $(XPM) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(XPM) $(XPM_LIBS) distort: distort.o $(HACK_OBJS) $(GRAB) $(SHM) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(SHM) $(HACK_LIBS) @@ -583,8 +593,8 @@ compass: compass.o $(HACK_OBJS) $(DBE) squiral: squiral.o $(HACK_OBJS) $(COL) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(HACK_LIBS) -xflame: xflame.o $(HACK_OBJS) $(SHM) - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(SHM) $(HACK_LIBS) $(XPM_LIBS) +xflame: xflame.o $(HACK_OBJS) $(SHM) $(XPM) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(SHM) $(XPM) $(XPM_LIBS) wander: wander.o $(HACK_OBJS) $(COL) $(ERASE) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS) @@ -598,8 +608,8 @@ critical: critical.o $(HACK_OBJS) $(COL) $(ERASE) phosphor: phosphor.o $(HACK_OBJS) $(COL) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(HACK_LIBS) -xmatrix: xmatrix.o $(HACK_OBJS) - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(HACK_LIBS) $(XPM_LIBS) +xmatrix: xmatrix.o $(HACK_OBJS) $(XPM) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(XPM) $(XPM_LIBS) petri: petri.o $(HACK_OBJS) $(COL) $(SPL) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(SPL) $(HACK_LIBS) @@ -652,6 +662,9 @@ speedmine: speedmine.o $(HACK_OBJS) $(COL) vermiculate: vermiculate.o $(HACK_OBJS) $(COL) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(HACK_LIBS) +twang: twang.o $(HACK_OBJS) $(GRAB) $(SHM) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(SHM) $(HACK_LIBS) + # The rules for those hacks which follow the `xlockmore' API. # @@ -665,8 +678,8 @@ braid: braid.o $(XLOCK_OBJS) $(ERASE) drift: drift.o $(XLOCK_OBJS) $(ERASE) $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(ERASE) $(HACK_LIBS) -flag: flag.o $(XLOCK_OBJS) - $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(XPM_LIBS) +flag: flag.o $(XLOCK_OBJS) $(XPM) + $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(XPM) $(XPM_LIBS) forest: forest.o $(XLOCK_OBJS) $(ERASE) $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(ERASE) $(HACK_LIBS) @@ -749,19 +762,36 @@ loop: loop.o $(XLOCK_OBJS) flow: flow.o $(XLOCK_OBJS) $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(HACK_LIBS) -discrete: discrete.o $(XLOCK_OBJS) $(ERASE) +discrete: discrete.o $(XLOCK_OBJS) $(ERASE) $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(ERASE) $(HACK_LIBS) -crystal: crystal.o $(XLOCK_OBJS) +crystal: crystal.o $(XLOCK_OBJS) $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(HACK_LIBS) +apollonian: apollonian.o $(XLOCK_OBJS) $(ERASE) + $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(ERASE) $(HACK_LIBS) + +euler2d: euler2d.o $(XLOCK_OBJS) + $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(HACK_LIBS) +juggle: juggle.o $(XLOCK_OBJS) + $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(HACK_LIBS) -# This one is not like the others. +polyominoes: polyominoes.o $(XLOCK_OBJS) $(ERASE) + $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(ERASE) $(HACK_LIBS) + +thornbird: thornbird.o $(XLOCK_OBJS) + $(CC_HACK) -o $@ $@.o $(XLOCK_OBJS) $(HACK_LIBS) + + +# These are not like the others. # xsublim: xsublim.o $(HACK_OBJS_1) $(CC_HACK) -o $@ $@.o $(HACK_OBJS_1) $(HACK_LIBS) +webcollage-helper: webcollage-helper.o + $(CC_HACK) -o $@ $@.o $(XPM_LIBS) $(JPEG_LIBS) + ############################################################################## # @@ -772,6 +802,7 @@ attraction.o: $(srcdir)/screenhack.h attraction.o: ../config.h blitspin.o: $(srcdir)/screenhack.h blitspin.o: ../config.h +blitspin.o: $(srcdir)/xpm-pixmap.h blitspin.o: $(srcdir)/images/som.xbm bouboule.o: $(srcdir)/xlockmore.h bouboule.o: ../config.h @@ -784,6 +815,7 @@ braid.o: $(srcdir)/screenhack.h bubbles.o: $(srcdir)/screenhack.h bubbles.o: ../config.h bubbles.o: $(srcdir)/bubbles.h +bubbles.o: $(srcdir)/xpm-pixmap.h bubbles-default.o: ../config.h bubbles-default.o: $(srcdir)/bubbles.h bubbles-default.o: $(srcdir)/images/bubbles/blood1.xpm @@ -842,11 +874,12 @@ flag.o: $(srcdir)/xlockmore.h flag.o: ../config.h flag.o: $(srcdir)/xlockmoreI.h flag.o: $(srcdir)/screenhack.h +flag.o: $(srcdir)/xpm-pixmap.h flag.o: $(srcdir)/images/bob.xbm flame.o: $(srcdir)/screenhack.h flame.o: ../config.h -forest.o: ../config.h forest.o: $(srcdir)/xlockmore.h +forest.o: ../config.h forest.o: $(srcdir)/xlockmoreI.h forest.o: $(srcdir)/screenhack.h vines.o: $(srcdir)/xlockmore.h @@ -905,6 +938,7 @@ moire.o: $(srcdir)/screenhack.h moire.o: ../config.h noseguy.o: $(srcdir)/screenhack.h noseguy.o: ../config.h +noseguy.o: $(srcdir)/xpm-pixmap.h noseguy.o: $(srcdir)/images/noseguy/nose-f1.xpm noseguy.o: $(srcdir)/images/noseguy/nose-f2.xpm noseguy.o: $(srcdir)/images/noseguy/nose-f3.xpm @@ -1055,6 +1089,7 @@ truchet.o: $(srcdir)/screenhack.h truchet.o: ../config.h bsod.o: $(srcdir)/screenhack.h bsod.o: ../config.h +bsod.o: $(srcdir)/xpm-pixmap.h bsod.o: $(srcdir)/images/amiga.xpm bsod.o: $(srcdir)/images/atari.xbm bsod.o: $(srcdir)/images/mac.xbm @@ -1094,6 +1129,7 @@ squiral.o: $(srcdir)/screenhack.h squiral.o: ../config.h xflame.o: $(srcdir)/screenhack.h xflame.o: ../config.h +xflame.o: $(srcdir)/xpm-pixmap.h xflame.o: $(srcdir)/images/bob.xbm wander.o: $(srcdir)/screenhack.h wander.o: ../config.h @@ -1105,6 +1141,7 @@ phosphor.o: $(srcdir)/screenhack.h phosphor.o: ../config.h xmatrix.o: $(srcdir)/screenhack.h xmatrix.o: ../config.h +xmatrix.o: $(srcdir)/xpm-pixmap.h xmatrix.o: $(srcdir)/images/matrix0.xpm xmatrix.o: $(srcdir)/images/matrix1.xpm xmatrix.o: $(srcdir)/images/matrix2.xpm @@ -1152,4 +1189,28 @@ speedmine.o: $(srcdir)/screenhack.h speedmine.o: ../config.h vermiculate.o: $(srcdir)/screenhack.h vermiculate.o: ../config.h +xpm-pixmap.o: ../config.h +webcollage-helper.o: ../config.h +twang.o: $(srcdir)/screenhack.h +twang.o: ../config.h +apollonian.o: $(srcdir)/xlockmore.h +apollonian.o: ../config.h +apollonian.o: $(srcdir)/xlockmoreI.h +apollonian.o: $(srcdir)/screenhack.h +euler2d.o: $(srcdir)/xlockmore.h +euler2d.o: ../config.h +euler2d.o: $(srcdir)/xlockmoreI.h +euler2d.o: $(srcdir)/screenhack.h +juggle.o: $(srcdir)/xlockmore.h +juggle.o: ../config.h +juggle.o: $(srcdir)/xlockmoreI.h +juggle.o: $(srcdir)/screenhack.h +polyominoes.o: $(srcdir)/xlockmore.h +polyominoes.o: ../config.h +polyominoes.o: $(srcdir)/xlockmoreI.h +polyominoes.o: $(srcdir)/screenhack.h +thornbird.o: $(srcdir)/xlockmore.h +thornbird.o: ../config.h +thornbird.o: $(srcdir)/xlockmoreI.h +thornbird.o: $(srcdir)/screenhack.h diff --git a/hacks/ant.c b/hacks/ant.c index db76bfd3..f41f19de 100644 --- a/hacks/ant.c +++ b/hacks/ant.c @@ -5,7 +5,7 @@ */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)ant.c 4.11 98/06/18 xlockmore"; +static const char sccsid[] = "@(#)ant.c 5.00 2000/11/01 xlockmore"; #endif @@ -25,25 +25,26 @@ static const char sccsid[] = "@(#)ant.c 4.11 98/06/18 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: Compatible with xscreensaver - * 16-Apr-97: -neighbors 3 and 8 added - * 01-Jan-97: Updated ant.c to handle more kinds of ants. Thanks to - * J Austin David . Check it out in - * java at http://havoc.gtf.gatech.edu/austin He thought up the - * new Ladder ant. - * 04-Apr-96: -neighbors 6 runtime-time option added for hexagonal ants - * (bees), coded from an idea of Jim Propp's in Science News, - * Oct 28, 1995 VOL. 148 page 287 - * 20-Sep-95: Memory leak in ant fixed. Now random colors. - * 05-Sep-95: Coded from A.K. Dewdney's "Computer Recreations", Scientific - * American Magazine" Sep 1989 pp 180-183, Mar 1990 p 121 - * Also used Ian Stewart's Mathematical Recreations, Scientific - * American Jul 1994 pp 104-107 - * also used demon.c and life.c as a guide. + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 16-Apr-1997: -neighbors 3 and 8 added + * 01-Jan-1997: Updated ant.c to handle more kinds of ants. Thanks to + * J Austin David . Check it out in + * java at http://havoc.gtf.gatech.edu/austin He thought up the + * new Ladder ant. + * 04-Apr-1996: -neighbors 6 runtime-time option added for hexagonal ants + * (bees), coded from an idea of Jim Propp's in Science News, + * Oct 28, 1995 VOL. 148 page 287 + * 20-Sep-1995: Memory leak in ant fixed. Now random colors. + * 05-Sep-1995: Coded from A.K. Dewdney's "Computer Recreations", Scientific + * American Magazine" Sep 1989 pp 180-183, Mar 1990 p 121 + * Also used Ian Stewart's Mathematical Recreations, Scientific + * American Jul 1994 pp 104-107 + * also used demon.c and life.c as a guide. */ /*- - Species Grid Number of Neigbors + Species Grid Number of Neighbors ------- ---- ------------------ Ants Square 4 (or 8) Bees Hexagon 6 @@ -53,85 +54,86 @@ static const char sccsid[] = "@(#)ant.c 4.11 98/06/18 xlockmore"; */ #ifdef STANDALONE -# define PROGCLASS "Ant" -# define HACK_INIT init_ant -# define HACK_DRAW draw_ant -# define ant_opts xlockmore_opts -# define DEFAULTS "*delay: 1000 \n" \ - "*count: -3 \n" \ - "*cycles: 40000 \n" \ - "*size: -12 \n" \ - "*ncolors: 64 \n" \ - "*neighbors: 0 \n" \ - "*sharpturn: False \n" -# include "xlockmore.h" /* in xscreensaver distribution */ -# include "erase.h" +#define MODE_ant +#define PROGCLASS "Ant" +#define HACK_INIT init_ant +#define HACK_DRAW draw_ant +#define ant_opts xlockmore_opts +#define DEFAULTS "*delay: 1000 \n" \ + "*count: -3 \n" \ + "*cycles: 40000 \n" \ + "*size: -12 \n" \ + "*ncolors: 64 \n" \ + "*neighbors: 0 \n" \ + "*sharpturn: False \n" +#include "xlockmore.h" /* in xscreensaver distribution */ +#include "erase.h" #else /* STANDALONE */ -# include "xlock.h" /* in xlockmore distribution */ +#include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ - #include "automata.h" +#ifdef MODE_ant + /*- - * neighbors of 0 randomizes it between 3, 4 and 6. - * 8, 9 12 are available also but not recommended. + * neighbors of 0 randomizes it for 3, 4, 6, 8, 12 (last 2 are less likely) */ -#ifdef STANDALONE -static int neighbors; -#else -extern int neighbors; -#endif /* !STANDALONE */ - +#define DEF_NEIGHBORS "0" /* choose random value */ #define DEF_TRUCHET "False" +#define DEF_EYES "False" #define DEF_SHARPTURN "False" -#define DEF_NEIGHBORS "0" +static int neighbors; static Bool truchet; +static Bool eyes; static Bool sharpturn; static XrmOptionDescRec opts[] = { - {"-truchet", ".ant.truchet", XrmoptionNoArg, (caddr_t) "on"}, - {"+truchet", ".ant.truchet", XrmoptionNoArg, (caddr_t) "off"}, - {"-sharpturn", ".ant.sharpturn", XrmoptionNoArg, (caddr_t) "on"}, - {"+sharpturn", ".ant.sharpturn", XrmoptionNoArg, (caddr_t) "off"}, - -#ifdef STANDALONE + {(char *) "-neighbors", (char *) ".ant.neighbors", XrmoptionSepArg, (caddr_t) NULL}, + {(char *) "-truchet", (char *) ".ant.truchet", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+truchet", (char *) ".ant.truchet", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-eyes", (char *) ".ant.eyes", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+eyes", (char *) ".ant.eyes", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-sharpturn", (char *) ".ant.sharpturn", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+sharpturn", (char *) ".ant.sharpturn", XrmoptionNoArg, (caddr_t) "off"}, {"-neighbors", ".ant.neighbors", XrmoptionSepArg, (caddr_t) 0}, {"+neighbors", ".ant.neighbors", XrmoptionSepArg, (caddr_t) 0} -#endif /* STANDALONE */ - }; static argtype vars[] = { - {(caddr_t *) & truchet, "truchet", "Truchet", DEF_TRUCHET, t_Bool}, - {(caddr_t *) & sharpturn, "sharpturn", "SharpTurn", DEF_SHARPTURN, t_Bool}, -#ifdef STANDALONE + {(caddr_t *) & neighbors, (char *) "neighbors", (char *) "Neighbors", (char *) DEF_NEIGHBORS, t_Int}, + {(caddr_t *) & truchet, (char *) "truchet", (char *) "Truchet", (char *) DEF_TRUCHET, t_Bool}, + {(caddr_t *) & eyes, (char *) "eyes", (char *) "Eyes", (char *) DEF_EYES, t_Bool}, + {(caddr_t *) & sharpturn, (char *) "sharpturn", (char *) "SharpTurn", (char *) DEF_SHARPTURN, t_Bool}, {(caddr_t *) & neighbors, "neighbors", "Neighbors", DEF_NEIGHBORS, t_Int} -#endif /* STANDALONE */ }; static OptionStruct desc[] = { - {"-/+truchet", "turn on/off Truchet lines"}, - {"-/+sharpturn", "turn on/off sharp turns (6 or 12 neighbors only)"} + {(char *) "-neighbors num", (char *) "squares 4 or 8, hexagons 6, triangles 3 or 12"}, + {(char *) "-/+truchet", (char *) "turn on/off Truchet lines"}, + {(char *) "-/+eyes", (char *) "turn on/off eyes"}, + {(char *) "-/+sharpturn", (char *) "turn on/off sharp turns (6, 8 or 12 neighbors only)"} }; ModeSpecOpt ant_opts = {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; #ifdef USE_MODULES -ModStruct ant_description = -{"ant", "init_ant", "draw_ant", "release_ant", - "refresh_ant", "init_ant", NULL, &ant_opts, +const ModStruct ant_description = +{"ant", + "init_ant", "draw_ant", "release_ant", + "refresh_ant", "init_ant", (char *) NULL, &ant_opts, 1000, -3, 40000, -12, 64, 1.0, "", "Shows Langton's and Turk's generalized ants", 0, NULL}; #endif #define ANTBITS(n,w,h)\ - ap->pixmaps[ap->init_bits++]=\ - XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1) + if ((ap->pixmaps[ap->init_bits]=\ + XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1))==None){\ + free_ant(display,ap); return;} else {ap->init_bits++;} /* If you change the table you may have to change the following 2 constants */ #define STATES 2 @@ -142,7 +144,6 @@ ModStruct ant_description = #define MINRANDOMSIZE 5 #define ANGLES 360 - typedef struct { unsigned char color; short direction; @@ -161,13 +162,15 @@ typedef struct { int generation; int xs, ys; int xb, yb; + int init_dir; int nrows, ncols; int width, height; unsigned char ncolors, nstates; int n; int redrawing, redrawpos; int truchet; /* Only for Turk modes */ - int sharpturn; /* Only for even neighbors > 4 (i.e. 6 and 12) */ + int eyes; + int sharpturn; statestruct machine[NUMSTIPPLES * STATES]; unsigned char *tape; unsigned char *truchet_state; @@ -183,13 +186,14 @@ typedef struct { } antfarmstruct; static char plots[] = -{3, -#if 1 /* Without this... this mode is misnamed... */ - 4, +{3, 4, 6, 8, +#ifdef NUMBER_9 + 9, #endif - 6}; /* Neighborhoods, 8 just makes a mess */ + 12}; -#define NEIGHBORKINDS (long) (sizeof plots / sizeof *plots) +#define NEIGHBORKINDS ((long) (sizeof plots / sizeof *plots)) +#define GOODNEIGHBORKINDS 3 /* Relative ant moves */ #define FS 0 /* Step */ @@ -205,7 +209,7 @@ static char plots[] = #define STHL 10 /* Step then turn hard left */ #define STL 11 /* Step then turn left */ -static antfarmstruct *antfarms = NULL; +static antfarmstruct *antfarms = (antfarmstruct *) NULL; /* LANGTON'S ANT (10) Chaotic after 500, Builder after 10,000 (104p) */ /* TURK'S 100 ANT Always chaotic?, tested past 150,000,000 */ @@ -484,8 +488,8 @@ fillcell(ModeInfo * mi, GC gc, int col, int row) ap->shape.hexagon[0].x = ap->xb + ccol * ap->xs; ap->shape.hexagon[0].y = ap->yb + crow * ap->ys; if (ap->xs == 1 && ap->ys == 1) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc, - ap->shape.hexagon[0].x, ap->shape.hexagon[0].y, 1, 1); + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc, + ap->shape.hexagon[0].x, ap->shape.hexagon[0].y); else XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, ap->shape.hexagon, 6, Convex, CoordModePrevious); @@ -499,9 +503,9 @@ fillcell(ModeInfo * mi, GC gc, int col, int row) ap->shape.triangle[orient][0].x = ap->xb + col * ap->xs; ap->shape.triangle[orient][0].y = ap->yb + row * ap->ys; if (ap->xs <= 3 || ap->ys <= 3) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc, + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc, ((orient) ? -1 : 1) + ap->shape.triangle[orient][0].x, - ap->shape.triangle[orient][0].y, 1, 1); + ap->shape.triangle[orient][0].y); else { if (orient) ap->shape.triangle[orient][0].x += (ap->xs / 2 - 1); @@ -529,7 +533,7 @@ truchetcell(ModeInfo * mi, int col, int row, int truchetstate) hex.x = ap->xb + ccol * ap->xs - (int) ((double) ap->xs / 2.0) - 1; hex.y = ap->yb + crow * ap->ys - (int) ((double) ap->ys / 2.0) - 1; for (side = 0; side < 6; side++) { - if (side > 0) { + if (side) { hex.x += ap->shape.hexagon[side].x; hex.y += ap->shape.hexagon[side].y; } @@ -539,17 +543,29 @@ truchetcell(ModeInfo * mi, int col, int row, int truchetstate) ((570 - (side * 60) + fudge) % 360) * 64, (120 - 2 * fudge) * 64); } } else { - /* Very crude approx of Sqrt 3, so it will not cause drawing errors. */ - hex.x = ap->xb + ccol * ap->xs - (int) ((double) ap->xs * 1.6 / 2.0); - hex.y = ap->yb + crow * ap->ys - (int) ((double) ap->ys * 1.6 / 2.0); + hex.x = ap->xb + ccol * ap->xs - (int) ((double) ap->xs * 1.6 / 2.0) - 1; + hex.y = ap->yb + crow * ap->ys - (int) ((double) ap->ys * 1.6 / 2.0) - 1; for (side = 0; side < 6; side++) { - if (side > 0) { + if (side) { hex.x += ap->shape.hexagon[side].x; hex.y += ap->shape.hexagon[side].y; } hex2.x = hex.x + ap->shape.hexagon[side + 1].x / 2; - hex2.y = hex.y + ap->shape.hexagon[side + 1].y / 2; + hex2.y = hex.y + ap->shape.hexagon[side + 1].y / 2 + 1; + /* Lots of fudging here */ + if (side == 1) { + hex2.x += (short) (ap->xs * 0.1 + 1); + hex2.y += (short) (ap->ys * 0.1 - ((ap->ys > 5) ? 1 : 0)); + } else if (side == 2) { + hex2.x += (short) (ap->xs * 0.1); + } else if (side == 4) { + hex2.x += (short) (ap->xs * 0.1); + hex2.y += (short) (ap->ys * 0.1 - 1); + } else if (side == 5) { + hex2.x += (short) (ap->xs * 0.5); + hex2.y += (short) (-ap->ys * 0.3 + 1); + } if (truchetstate == side % 3) /* Crude approx of 120 deg, so it will not cause drawing errors. */ XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), @@ -561,7 +577,7 @@ truchetcell(ModeInfo * mi, int col, int row, int truchetstate) } else if (ap->neighbors == 4) { if (truchetstate) { XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), - ap->xb + ap->xs * col - ap->xs / 2+ 1, + ap->xb + ap->xs * col - ap->xs / 2 + 1, ap->yb + ap->ys * row + ap->ys / 2 - 1, ap->xs - 2, ap->ys - 2, 0 * 64, 90 * 64); @@ -586,6 +602,7 @@ truchetcell(ModeInfo * mi, int col, int row, int truchetstate) int orient = (col + row) % 2; /* O left 1 right */ int side, ang; int fudge = 7; /* fudge because the triangles are not exact */ + double fudge2 = 1.18; XPoint tri; tri.x = ap->xb + col * ap->xs; @@ -600,14 +617,16 @@ truchetcell(ModeInfo * mi, int col, int row, int truchetstate) tri.x += ap->shape.triangle[orient][side].x; tri.y += ap->shape.triangle[orient][side].y; } - if (truchetstate == side % 3) { + if (truchetstate == side) { if (orient) ang = (510 - side * 120) % 360; /* Right */ else ang = (690 - side * 120) % 360; /* Left */ XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), - tri.x - ap->xs / 2, tri.y - 3 * ap->ys / 4, - ap->xs, 3 * ap->ys / 2, + (int) (tri.x - ap->xs * fudge2 / 2), + (int) (tri.y - 3 * ap->ys * fudge2 / 4), + (unsigned int) (ap->xs * fudge2), + (unsigned int) (3 * ap->ys * fudge2 / 2), (ang + fudge) * 64, (60 - 2 * fudge) * 64); } } @@ -656,48 +675,152 @@ drawtruchet(ModeInfo * mi, int col, int row, } static void -draw_anant(ModeInfo * mi, int col, int row) +draw_anant(ModeInfo * mi, int direction, int col, int row) { - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); - fillcell(mi, MI_GC(mi), col, row); -#if 0 /* Can not see eyes */ - { - antfarmstruct *ap = &antfarms[MI_SCREEN(mi)]; - Display *display = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - - if (ap->xs > 2 && ap->ys > 2) { /* Draw Eyes */ + antfarmstruct *ap = &antfarms[MI_SCREEN(mi)]; + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); - XSetForeground(display, MI_GC(mi), MI_BLACK_PIXEL(mi)); + XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi)); + fillcell(mi, MI_GC(mi), col, row); + if (ap->eyes) { /* Draw Eyes */ + XSetForeground(display, MI_GC(mi), MI_BLACK_PIXEL(mi)); + if (ap->neighbors == 6) { + int ccol = 2 * col + !(row & 1), crow = 2 * row; + int side, ang; + XPoint hex; + + if (!(ap->xs > 3 && ap->ys > 3)) + return; + hex.x = ap->xb + ccol * ap->xs; + hex.y = ap->yb + crow * ap->ys + ap->ys / 2; + ang = direction * ap->neighbors / ANGLES; + for (side = 0; side < ap->neighbors; side++) { + if (side) { + hex.x -= ap->shape.hexagon[side].x / 2; + hex.y += ap->shape.hexagon[side].y / 2; + } + if (side == (ap->neighbors + ang - 2) % ap->neighbors) + XDrawPoint(display, window, MI_GC(mi), hex.x, hex.y); + if (side == (ap->neighbors + ang - 1) % ap->neighbors) + XDrawPoint(display, window, MI_GC(mi), hex.x, hex.y); + } + } else if (ap->neighbors == 4 || ap->neighbors == 8) { + if (!(ap->xs > 3 && ap->ys > 3)) + return; switch (direction) { case 0: XDrawPoint(display, window, MI_GC(mi), - ap->xb + ap->xs - 1, ap->yb + 1); + ap->xb + ap->xs * (col + 1) - 3, + ap->yb + ap->ys * row + ap->ys / 2 - 2); XDrawPoint(display, window, MI_GC(mi), - ap->xb + ap->xs - 1, ap->yb + ap->ys - 2); + ap->xb + ap->xs * (col + 1) - 3, + ap->yb + ap->ys * row + ap->ys / 2); break; - case 180: - XDrawPoint(display, window, MI_GC(mi), ap->xb, ap->yb + 1); - XDrawPoint(display, window, MI_GC(mi), ap->xb, ap->yb + ap->ys - 2); + case 45: + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * (col + 1) - 4, + ap->yb + ap->ys * row + 1); + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * (col + 1) - 3, + ap->yb + ap->ys * row + 2); break; - if (neighbors == 4) { case 90: - XDrawPoint(display, window, MI_GC(mi), ap->xb + 1, ap->yb); - XDrawPoint(display, window, MI_GC(mi), - ap->xb + ap->xs - 2, ap->yb); - break; + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + ap->xs / 2 - 2, + ap->yb + ap->ys * row + 1); + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + ap->xs / 2, + ap->yb + ap->ys * row + 1); + break; + case 135: + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + 2, + ap->yb + ap->ys * row + 1); + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + 1, + ap->yb + ap->ys * row + 2); + break; + case 180: + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + 1, + ap->yb + ap->ys * row + ap->ys / 2 - 2); + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + 1, + ap->yb + ap->ys * row + ap->ys / 2); + break; + case 225: + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + 2, + ap->yb + ap->ys * (row + 1) - 3); + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + 1, + ap->yb + ap->ys * (row + 1) - 4); + break; case 270: - XDrawPoint(display, window, MI_GC(mi), - ap->xb + 1, ap->yb + ap->ys - 1); - XDrawPoint(display, window, MI_GC(mi), - ap->xb + ap->xs - 2, ap->yb + ap->ys - 1); - break; - } /* else BEE */ + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + ap->xs / 2 - 2, + ap->yb + ap->ys * (row + 1) - 3); + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * col + ap->xs / 2, + ap->yb + ap->ys * (row + 1) - 3); + break; + case 315: + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * (col + 1) - 4, + ap->yb + ap->ys * (row + 1) - 3); + XDrawPoint(display, window, MI_GC(mi), + ap->xb + ap->xs * (col + 1) - 3, + ap->yb + ap->ys * (row + 1) - 4); + break; default: + (void) fprintf(stderr, "wrong eyes direction %d for ant eyes\n", direction); + } + } else { /* TRI */ + int orient = (col + row) % 2; /* O left 1 right */ + int side, ang; + XPoint tri; + + if (!(ap->xs > 6 && ap->ys > 6)) + return; + tri.x = ap->xb + col * ap->xs; + tri.y = ap->yb + row * ap->ys; + if (orient) + tri.x += (ap->xs / 6 - 1); + else + tri.x -= (ap->xs / 6 - 1); + ang = direction * ap->neighbors / ANGLES; + /* approx... does not work that well for even numbers */ + if ( +#ifdef NUMBER_9 + ap->neighbors == 9 || +#endif + ap->neighbors == 12) { +#ifdef UNDER_CONSTRUCTION + /* Not sure why this does not work */ + ang = ((ang + ap->neighbors / 6) / (ap->neighbors / 3)) % 3; +#else + return; +#endif + } + for (side = 0; side < 3; side++) { + if (side) { + tri.x += ap->shape.triangle[orient][side].x / 3; + tri.y += ap->shape.triangle[orient][side].y / 3; + } + /* Either you have the eyes in back or one eye in front */ +#if 0 + if (side == ang) + XDrawPoint(display, window, MI_GC(mi), tri.x, tri.y); +#else + if (side == (ang + 2) % 3) + XDrawPoint(display, window, MI_GC(mi), tri.x, tri.y); + if (side == (ang + 1) % 3) + XDrawPoint(display, window, MI_GC(mi), tri.x, tri.y); +#endif } } } -#endif } #if 0 @@ -720,35 +843,36 @@ RandomSoup(mi) #endif static short -fromTableDirection(unsigned char dir, int neighbors) +fromTableDirection(unsigned char dir, int local_neighbors) { + /* Crafted to work for odd number of neighbors */ switch (dir) { case FS: return 0; - case TRS: - return (ANGLES / neighbors); - case THRS: - return (ANGLES / 2 - ANGLES / neighbors); - case TBS: - return (ANGLES / 2); - case THLS: - return (ANGLES / 2 + ANGLES / neighbors); case TLS: - return (ANGLES - ANGLES / neighbors); + return (ANGLES / local_neighbors); + case THLS: + return (2 * ANGLES / local_neighbors); + case TBS: + return ((local_neighbors / 2) * ANGLES / local_neighbors); + case THRS: + return (ANGLES - 2 * ANGLES / local_neighbors); + case TRS: + return (ANGLES - ANGLES / local_neighbors); case SF: return ANGLES; - case STR: - return (ANGLES + ANGLES / neighbors); - case STHR: - return (3 * ANGLES / 2 - ANGLES / neighbors); - case STB: - return (3 * ANGLES / 2); - case STHL: - return (3 * ANGLES / 2 + ANGLES / neighbors); case STL: - return (2 * ANGLES - ANGLES / neighbors); + return (ANGLES + ANGLES / local_neighbors); + case STHL: + return (ANGLES + 2 * ANGLES / local_neighbors); + case STB: + return (ANGLES + (local_neighbors / 2) * ANGLES / local_neighbors); + case STHR: + return (2 * ANGLES - 2 * ANGLES / local_neighbors); + case STR: + return (2 * ANGLES - ANGLES / local_neighbors); default: - (void) fprintf(stderr, "wrong direction %d\n", dir); + (void) fprintf(stderr, "wrong direction %d from table\n", dir); } return -1; } @@ -770,7 +894,7 @@ getTable(ModeInfo * mi, int i) ap->n, ap->neighbors, i, ap->ncolors, ap->nstates); for (j = 0; j < total; j++) { ap->machine[j].color = *patptr++; - if (ap->sharpturn && ap->neighbors > 4 && !(ap->neighbors % 2)) { + if (ap->sharpturn && ap->neighbors > 4) { int k = *patptr++; switch (k) { @@ -816,9 +940,9 @@ getTurk(ModeInfo * mi, int i) antfarmstruct *ap = &antfarms[MI_SCREEN(mi)]; int power2, j, number, total; - /* To force a number, say has i + 2 (or 4) digits in binary */ + /* To force a number, say has i + 2 (or 4) binary digits */ power2 = 1 << (i + 1); - /* Dont want numbers which in binary are all 1's. */ + /* Do not want numbers which in binary are all 1's. */ number = NRAND(power2 - 1) + power2; /* To force a particular number, say */ @@ -827,7 +951,7 @@ getTurk(ModeInfo * mi, int i) total = ap->ncolors * ap->nstates; for (j = 0; j < total; j++) { ap->machine[j].color = (j + 1) % total; - if (ap->sharpturn && ap->neighbors > 4 && !(ap->neighbors % 2)) { + if (ap->sharpturn && ap->neighbors > 4) { ap->machine[j].direction = (power2 & number) ? fromTableDirection(THRS, ap->neighbors) : fromTableDirection(THLS, ap->neighbors); @@ -847,6 +971,33 @@ getTurk(ModeInfo * mi, int i) ap->n, ap->neighbors, number, ap->ncolors); } +static void +free_ant(Display *display, antfarmstruct *ap) +{ + int shade; + + if (ap->stippledGC != None) { + XFreeGC(display, ap->stippledGC); + ap->stippledGC = None; + } + for (shade = 0; shade < ap->init_bits; shade++) { + XFreePixmap(display, ap->pixmaps[shade]); + } + ap->init_bits = 0; + if (ap->tape != NULL) { + (void) free((void *) ap->tape); + ap->tape = (unsigned char *) NULL; + } + if (ap->ants != NULL) { + (void) free((void *) ap->ants); + ap->ants = (antstruct *) NULL; + } + if (ap->truchet_state != NULL) { + (void) free((void *) ap->truchet_state); + ap->truchet_state = (unsigned char *) NULL; + } +} + void init_ant(ModeInfo * mi) { @@ -855,13 +1006,7 @@ init_ant(ModeInfo * mi) int size = MI_SIZE(mi); antfarmstruct *ap; int col, row, dir; - long i; - - /* jwz sez: small sizes look like crap */ - if (size < 0) - size = NRAND(-size)+1; - if (size < 5) - size += 5; + int i; if (antfarms == NULL) { if ((antfarms = (antfarmstruct *) calloc(MI_NUM_SCREENS(mi), @@ -869,17 +1014,23 @@ init_ant(ModeInfo * mi) return; } ap = &antfarms[MI_SCREEN(mi)]; + ap->redrawing = 0; if (MI_NPIXELS(mi) <= 2) { if (ap->stippledGC == None) { XGCValues gcv; gcv.fill_style = FillOpaqueStippled; - ap->stippledGC = XCreateGC(display, window, GCFillStyle, &gcv); + if ((ap->stippledGC = XCreateGC(display, window, GCFillStyle, + &gcv)) == None) { + free_ant(display, ap); + return; + } } if (ap->init_bits == 0) { - for (i = 1; i < NUMSTIPPLES; i++) + for (i = 1; i < NUMSTIPPLES; i++) { ANTBITS(stipples[i], STIPPLESIZE, STIPPLESIZE); + } } } ap->generation = 0; @@ -888,7 +1039,7 @@ init_ant(ModeInfo * mi) /* if ap->n is random ... the size can change */ if (ap->ants != NULL) { (void) free((void *) ap->ants); - ap->ants = NULL; + ap->ants = (antstruct *) NULL; } ap->n = NRAND(-ap->n - MINANTS + 1) + MINANTS; } else if (ap->n < MINANTS) @@ -897,27 +1048,29 @@ init_ant(ModeInfo * mi) ap->width = MI_WIDTH(mi); ap->height = MI_HEIGHT(mi); - if (neighbors == 8 || neighbors == 9 || neighbors == 12) - ap->neighbors = neighbors; /* Discourage but not deny use... */ - else - for (i = 0; i < NEIGHBORKINDS; i++) { - if (neighbors == plots[i]) { - ap->neighbors = plots[i]; - break; - } - if (i == NEIGHBORKINDS - 1) { + for (i = 0; i < NEIGHBORKINDS; i++) { + if (neighbors == plots[i]) { + ap->neighbors = plots[i]; + break; + } + if (i == NEIGHBORKINDS - 1) { + if (!NRAND(10)) { + /* Make above 6 rare */ ap->neighbors = plots[NRAND(NEIGHBORKINDS)]; - break; + } else { + ap->neighbors = plots[NRAND(GOODNEIGHBORKINDS)]; } + break; } + } if (ap->neighbors == 6) { int nccols, ncrows; - if (ap->width < 2) - ap->width = 2; - if (ap->height < 4) - ap->height = 4; + if (ap->width < 8) + ap->width = 8; + if (ap->height < 8) + ap->height = 8; if (size < -MINSIZE) { ap->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(ap->width, ap->height) / MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE; @@ -934,11 +1087,11 @@ init_ant(ModeInfo * mi) MINGRIDSIZE)); ap->xs = ap->ys; nccols = MAX(ap->width / ap->xs - 2, 2); - ncrows = MAX(ap->height / ap->ys - 1, 2); + ncrows = MAX(ap->height / ap->ys - 1, 4); ap->ncols = nccols / 2; ap->nrows = 2 * (ncrows / 4); ap->xb = (ap->width - ap->xs * nccols) / 2 + ap->xs / 2; - ap->yb = (ap->height - ap->ys * (ncrows / 2) * 2) / 2 + ap->ys; + ap->yb = (ap->height - ap->ys * (ncrows / 2) * 2) / 2 + ap->ys - 2; for (i = 0; i < 6; i++) { ap->shape.hexagon[i].x = (ap->xs - 1) * hexagonUnit[i].x; ap->shape.hexagon[i].y = ((ap->ys - 1) * hexagonUnit[i].y / 2) * 4 / 3; @@ -1011,13 +1164,14 @@ init_ant(ModeInfo * mi) if (MI_IS_FULLRANDOM(mi)) { ap->truchet = (Bool) (LRAND() & 1); + ap->eyes = (Bool) (LRAND() & 1); ap->sharpturn = (Bool) (LRAND() & 1); } else { ap->truchet = truchet; + ap->eyes = eyes; ap->sharpturn = sharpturn; } - /* Exclude odd # of neighbors, stepping forward not defined */ - if (!NRAND(NUMSTIPPLES) && ((ap->neighbors + 1) % 2)) { + if (!NRAND(NUMSTIPPLES)) { getTable(mi, (int) (NRAND(NTABLES))); } else getTurk(mi, (int) (NRAND(NUMSTIPPLES - 1))); @@ -1025,21 +1179,38 @@ init_ant(ModeInfo * mi) for (i = 0; i < (int) ap->ncolors - 1; i++) ap->colors[i] = (unsigned char) (NRAND(MI_NPIXELS(mi)) + i * MI_NPIXELS(mi)) / ((int) (ap->ncolors - 1)); - if (ap->ants == NULL) - ap->ants = (antstruct *) malloc(ap->n * sizeof (antstruct)); - if (ap->tape != NULL) + if (ap->ants == NULL) { + if ((ap->ants = (antstruct *) malloc(ap->n * sizeof (antstruct))) == + NULL) { + free_ant(display, ap); + return; + } + } + if (ap->tape != NULL) (void) free((void *) ap->tape); - ap->tape = (unsigned char *) - calloc(ap->ncols * ap->nrows, sizeof (unsigned char)); - + if ((ap->tape = (unsigned char *) calloc(ap->ncols * ap->nrows, + sizeof (unsigned char))) == NULL) { + free_ant(display, ap); + return; + } if (ap->truchet_state != NULL) (void) free((void *) ap->truchet_state); - ap->truchet_state = (unsigned char *) - calloc(ap->ncols * ap->nrows, sizeof (unsigned char)); + if ((ap->truchet_state = (unsigned char *) calloc(ap->ncols * ap->nrows, + sizeof (unsigned char))) == NULL) { + free_ant(display, ap); + return; + } - col = ap->ncols / 2; row = ap->nrows / 2; + col = ap->ncols / 2; + if (col > 0 && ((ap->neighbors % 2) || ap->neighbors == 12) && (LRAND() & 1)) + col--; dir = NRAND(ap->neighbors) * ANGLES / ap->neighbors; + ap->init_dir = dir; +#ifdef NUMBER_9 + if (ap->neighbors == 9 && !((col + row) & 1)) + dir = (dir + ANGLES - ANGLES / (ap->neighbors * 2)) % ANGLES; +#endif /* Have them all start in the same spot, why not? */ for (i = 0; i < ap->n; i++) { ap->ants[i].col = col; @@ -1047,21 +1218,26 @@ init_ant(ModeInfo * mi) ap->ants[i].direction = dir; ap->ants[i].state = 0; } - draw_anant(mi, col, row); + draw_anant(mi, dir, col, row); } void draw_ant(ModeInfo * mi) { - antfarmstruct *ap = &antfarms[MI_SCREEN(mi)]; antstruct *anant; statestruct *status; int i, state_pos, tape_pos; unsigned char color; short chg_dir, old_dir; + antfarmstruct *ap; - MI_IS_DRAWN(mi) = True; + if (antfarms == NULL) + return; + ap = &antfarms[MI_SCREEN(mi)]; + if (ap->ants == NULL) + return; + MI_IS_DRAWN(mi) = True; ap->painted = True; for (i = 0; i < ap->n; i++) { anant = &ap->ants[i]; @@ -1082,7 +1258,10 @@ draw_ant(ModeInfo * mi) if (ap->neighbors == 6) { if (ap->sharpturn) { - a = (chg_dir / 120 == 2); + a = (((ANGLES + anant->direction - old_dir) % ANGLES) == 240); + /* should be some way of getting rid of the init_dir dependency... */ + b = !(ap->init_dir % 120); + a = ((a && !b) || (b && !a)); drawtruchet(mi, anant->col, anant->row, status->color, a); } else { a = (old_dir / 60) % 3; @@ -1106,10 +1285,16 @@ draw_ant(ModeInfo * mi) } anant->state = status->next; - /* If edge than wrap it */ + /* Allow step first and turn */ old_dir = ((status->direction < ANGLES) ? anant->direction : old_dir); +#if DEBUG + (void) printf("old_dir %d, col %d, row %d", old_dir, anant->col, anant->row); +#endif position_of_neighbor(ap, old_dir, &(anant->col), &(anant->row)); - draw_anant(mi, anant->col, anant->row); +#if DEBUG + (void) printf(", ncol %d, nrow %d\n", anant->col, anant->row); +#endif + draw_anant(mi, anant->direction, anant->col, anant->row); } if (++ap->generation > MI_CYCLES(mi)) { #ifdef STANDALONE @@ -1142,31 +1327,21 @@ release_ant(ModeInfo * mi) if (antfarms != NULL) { int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - antfarmstruct *ap = &antfarms[screen]; - int shade; - - if (ap->stippledGC != None) { - XFreeGC(MI_DISPLAY(mi), ap->stippledGC); - } - for (shade = 0; shade < ap->init_bits; shade++) - XFreePixmap(MI_DISPLAY(mi), ap->pixmaps[shade]); - if (ap->tape != NULL) - (void) free((void *) ap->tape); - if (ap->ants != NULL) - (void) free((void *) ap->ants); - if (ap->truchet_state != NULL) - (void) free((void *) ap->truchet_state); - } + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_ant(MI_DISPLAY(mi), &antfarms[screen]); (void) free((void *) antfarms); - antfarms = NULL; + antfarms = (antfarmstruct *) NULL; } } void refresh_ant(ModeInfo * mi) { - antfarmstruct *ap = &antfarms[MI_SCREEN(mi)]; + antfarmstruct *ap; + + if (antfarms == NULL) + return; + ap = &antfarms[MI_SCREEN(mi)]; if (ap->painted) { MI_CLEARWINDOW(mi); @@ -1174,3 +1349,5 @@ refresh_ant(ModeInfo * mi) ap->redrawpos = 0; } } + +#endif /* MODE_ant */ diff --git a/hacks/apollonian.c b/hacks/apollonian.c new file mode 100644 index 00000000..4befef4e --- /dev/null +++ b/hacks/apollonian.c @@ -0,0 +1,820 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* apollonian --- Apollonian Circles */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)apollonian.c 5.02 2001/07/01 xlockmore"; +#endif + +/*- + * Copyright (c) 2000, 2001 by Allan R. Wilks . + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * radius r = 1 / c (curvature) + * + * Descartes Circle Theorem: (a, b, c, d are curvatures of tangential circles) + * Let a, b, c, d be the curvatures of for mutually (externally) tangent + * circles in the plane. Then + * a^2 + b^2 + c^2 + d^2 = (a + b + c + d)^2 / 2 + * + * Complex Descartes Theorem: If the oriented curvatues and (complex) centers + * of an oriented Descrates configuration in the plane are a, b, c, d and + * w, x, y, z respectively, then + * a^2*w^2 + b^2*x^2 + c^2*y^2 + d^2*z^2 = (aw + bx + cy + dz)^2 / 2 + * In addition these quantities satisfy + * a^2*w + b^2*x + c^2*y + d^2*z = (aw + bx + cy + dz)(a + b + c + d) / 2 + * + * Enumerate root integer Descartes quadruples (a,b,c,d) satisfying the + * Descartes condition: + * 2(a^2+b^2+c^2+d^2) = (a+b+c+d)^2 + * i.e., quadruples for which no application of the "pollinate" operator + * z <- 2(a+b+c+d) - 3*z, + * where z is in {a,b,c,d}, gives a quad of strictly smaller sum. This + * is equivalent to the condition: + * sum(a,b,c,d) >= 2*max(a,b,c,d) + * which, because of the Descartes condition, is equivalent to + * sum(a^2,b^2,c^2,d^2) >= 2*max(a,b,c,d)^2 + * + * + * Todo: + * Add a small font + * + * Revision History: + * 25-Jun-2001: Converted from C and Postscript code by David Bagley + * Original code by Allan R. Wilks . + * + * From Circle Math Science News April 21, 2001 VOL. 254-255 + * http://www.sciencenews.org/20010421/toc.asp + * Apollonian Circle Packings Assorted papers from Ronald L Graham, + * Jeffrey Lagarias, Colin Mallows, Allan Wilks, Catherine Yan + * http://front.math.ucdavis.edu/math.NT/0009113 + * http://front.math.ucdavis.edu/math.MG/0101066 + * http://front.math.ucdavis.edu/math.MG/0010298 + * http://front.math.ucdavis.edu/math.MG/0010302 + * http://front.math.ucdavis.edu/math.MG/0010324 + */ + +#ifdef STANDALONE +#define MODE_apollonian +#define PROGCLASS "Apollonian" +#define HACK_INIT init_apollonian +#define HACK_DRAW draw_apollonian +#define apollonian_opts xlockmore_opts +#define DEFAULTS "*delay: 1000000 \n" \ + "*count: 64 \n" \ + "*cycles: 20 \n" \ + "*ncolors: 64 \n" +#include "xlockmore.h" /* in xscreensaver distribution */ +#include "erase.h" +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_apollonian + +#define DEF_ALTGEOM "True" +#define DEF_LABEL "True" + +static Bool altgeom; +static Bool label; + +static XrmOptionDescRec opts[] = +{ + {(char *) "-altgeom", (char *) ".apollonian.altgeom", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+altgeom", (char *) ".apollonian.altgeom", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-label", (char *) ".apollonian.label", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+label", (char *) ".apollonian.label", XrmoptionNoArg, (caddr_t) "off"}, +}; +static argtype vars[] = +{ + {(caddr_t *) & altgeom, (char *) "altgeom", (char *) "AltGeom", (char *) DEF_ALTGEOM, t_Bool}, + {(caddr_t *) & label, (char *) "label", (char *) "Label", (char *) DEF_LABEL, t_Bool}, +}; +static OptionStruct desc[] = +{ + {(char *) "-/+altgeom", (char *) "turn on/off alternate geometries (off euclidean space, on includes spherical and hyperbolic)"}, + {(char *) "-/+label", (char *) "turn on/off alternate space and number labeling"}, +}; + +ModeSpecOpt apollonian_opts = +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef DOFONT +extern XFontStruct *getFont(Display * display); +#endif + +#ifdef USE_MODULES +ModStruct apollonian_description = +{"apollonian", "init_apollonian", "draw_apollonian", "release_apollonian", + "init_apollonian", "init_apollonian", (char *) NULL, &apollonian_opts, + 1000000, 64, 20, 1, 64, 1.0, "", + "Shows Apollonian Circles", 0, NULL}; + +#endif + +typedef struct { + int a, b, c, d; +} apollonian_quadruple; + +typedef struct { + double e; /* euclidean bend */ + double s; /* spherical bend */ + double h; /* hyperbolic bend */ + double x, y; /* euclidean bend times euclidean position */ +} circle; +enum space { + euclidean = 0, spherical, hyperbolic +}; + +const char * space_string[] = { + "euclidean", + "spherical", + "hyperbolic" +}; + +/* +Generate Apollonian packing starting with a quadruple of circles. +The four input lines each contain the 5-tuple (e,s,h,x,y) representing +the circle with radius 1/e and center (x/e,y/e). The s and h is propagated +like e, x and y, but can differ from e so as to represent different +geometries, spherical and hyperbolic, respectively. The "standard" picture, +for example (-1, 2, 2, 3), can be labeled for the three geometries. +Origins of circles z1, z2, z3, z4 +a * z1 = 0 +b * z2 = (a+b)/a +c * z3 = (q123 + a * i)^2/(a*(a+b)) where q123 = sqrt(a*b+a*c+b*c) +d * z4 = (q124 + a * i)^2/(a*(a+b)) where q124 = q123 - a - b +If (e,x,y) represents the Euclidean circle (1/e,x/e,y/e) (so that e is +the label in the standard picture) then the "spherical label" is +(e^2+x^2+y^2-1)/(2*e) (an integer!) and the "hyperbolic label", is +calulated by h + s = e. +*/ +circle examples[][4] = { +{ /* double semi-bounded */ + { 0, 0, 0, 0, 1}, + { 0, 0, 0, 0, -1}, + { 1, 1, 1, -1, 0}, + { 1, 1, 1, 1, 0} +}, +#if 0 +{ /* standard */ + {-1, 0, -1, 0, 0}, + { 2, 1, 1, 1, 0}, + { 2, 1, 1, -1, 0}, + { 3, 2, 1, 0, 2} +}, +{ /* next simplest */ + {-2, -1, -1, 0.0, 0}, + { 3, 2, 1, 0.5, 0}, + { 6, 3, 3, -2.0, 0}, + { 7, 4, 3, -1.5, 2} +}, +{ /* */ + {-3, -2, -1, 0.0, 0}, + { 4, 3, 1, 1.0 / 3.0, 0}, + {12, 7, 5, -3.0, 0}, + {13, 8, 5, -8.0 / 3.0, 2} +}, +{ /* Mickey */ + {-3, -2, -1, 0.0, 0}, + { 5, 4, 1, 2.0 / 3.0, 0}, + { 8, 5, 3, -4.0 / 3.0, -1}, + { 8, 5, 3, -4.0 / 3.0, 1} +}, +{ /* */ + {-4, -3, -1, 0.00, 0}, + { 5, 4, 1, 0.25, 0}, + {20, 13, 7, -4.00, 0}, + {21, 14, 7, -3.75, 2} +}, +{ /* Mickey2 */ + {-4, -2, -2, 0.0, 0}, + { 8, 4, 4, 1.0, 0}, + { 9, 5, 4, -0.75, -1}, + { 9, 5, 4, -0.75, 1} +}, +{ /* Mickey3 */ + {-5, -4, -1, 0.0, 0}, + { 7, 6, 1, 0.4, 0}, + {18, 13, 5, -2.4, -1}, + {18, 13, 5, -2.4, 1} +}, +{ /* */ + {-6, -5, -1, 0.0, 0}, + { 7, 6, 1, 1.0 / 6.0, 0}, + {42, 31, 11, -6.0, 0}, + {43, 32, 11, -35.0 / 6.0, 2} +}, +{ /* */ + {-6, -3, -3, 0.0, 0}, + {10, 5, 5, 2.0 / 3.0, 0}, + {15, 8, 7, -1.5, 0}, + {19, 10, 9, -5.0 / 6.0, 2} +}, +{ /* asymmetric */ + {-6, -5, -1, 0.0, 0.0}, + {11, 10, 1, 5.0 / 6.0, 0.0}, + {14, 11, 3, -16.0 / 15.0, -0.8}, + {15, 12, 3, -0.9, 1.2} +}, +#endif +/* Non integer stuff */ +#define DELTA 2.154700538 /* ((3+2*sqrt(3))/3) */ +{ /* 3 fold symmetric bounded (x, y calculated later) */ + { -1, -1, -1, 0.0, 0.0}, + {DELTA, DELTA, DELTA, 1.0, 0.0}, + {DELTA, DELTA, DELTA, 1.0, -1.0}, + {DELTA, DELTA, DELTA, -1.0, 1.0} +}, +{ /* semi-bounded (x, y calculated later) */ +#define ALPHA 2.618033989 /* ((3+sqrt(5))/2) */ + { 1.0, 1.0, 1.0, 0, 0}, + { 0.0, 0.0, 0.0, 0, -1}, + {1.0/(ALPHA*ALPHA), 1.0/(ALPHA*ALPHA), 1.0/(ALPHA*ALPHA), -1, 0}, + { 1.0/ALPHA, 1.0/ALPHA, 1.0/ALPHA, -1, 0} +}, +{ /* unbounded (x, y calculated later) */ +/* #define PHI 1.618033989 *//* ((1+sqrt(5))/2) */ +#define BETA 2.890053638 /* (PHI+sqrt(PHI)) */ + { 1.0, 1.0, 1.0, 0, 0}, + {1.0/(BETA*BETA*BETA), 1.0/(BETA*BETA*BETA), 1.0/(BETA*BETA*BETA), 1, 0}, + { 1.0/(BETA*BETA), 1.0/(BETA*BETA), 1.0/(BETA*BETA), 1, 0}, + { 1.0/BETA, 1.0/BETA, 1.0/BETA, 1, 0} +} +}; + +#define PREDEF_CIRCLE_GAMES (sizeof (examples) / (4 * sizeof (circle))) + +#if 0 +Euclidean +0, 0, 1, 1 +-1, 2, 2, 3 +-2, 3, 6, 7 +-3, 5, 8, 8 +-4, 8, 9, 9 +-3, 4, 12, 13 +-6, 11, 14, 15 + -5, 7, 18, 18 + -6, 10, 15, 19 + -7, 12, 17, 20 + -4, 5, 20, 21 + -9, 18, 19, 22 + -8, 13, 21, 24 +Spherical +0, 1, 1, 2 + -1, 2, 3, 4 + -2, 4, 5, 5 + -2, 3, 7, 8 +Hyperbolic +-1, 1, 1, 1 + 0, 0, 1, 3 + -2, 3, 5, 6 + -3, 6, 6, 7 +#endif + +typedef struct { + int size; + XPoint offset; + int geometry; + circle c1, c2, c3, c4; + int color_offset; + int count; + Bool label, altgeom; + apollonian_quadruple *quad; +#ifdef DOFONT + XFontStruct *font; +#endif + int time; + int game; +} apollonianstruct; + +static apollonianstruct *apollonians = (apollonianstruct *) NULL; + +#define FONT_HEIGHT 19 +#define FONT_WIDTH 15 +#define FONT_LENGTH 20 +#define MAX_CHAR 10 +#define K 2.15470053837925152902 /* 1+2/sqrt(3) */ +#define MAXBEND 100 /* Do not want configurable by user since it will take too + much time if increased. */ + +static int +gcd(int a, int b) +{ + int r; + + while (b) { + r = a % b; + a = b; + b = r; + } + return a; +} + +static int +isqrt(int n) +{ + int y; + + if (n < 0) + return -1; + y = (int) (sqrt((double) n) + 0.5); + return ((n == y*y) ? y : -1); +} + +static void +dquad(int n, apollonian_quadruple *quad) +{ + int a, b, c, d; + int counter = 0, B, C; + + for (a = 0; a < MAXBEND; a++) { + B = (int) (K * a); + for (b = a + 1; b <= B; b++) { + C = (int) (((a + b) * (a + b)) / (4.0 * (b - a))); + for (c = b; c <= C; c++) { + d = isqrt(b*c-a*(b+c)); + if (d >= 0 && (gcd(a,gcd(b,c)) <= 1)) { + quad[counter].a = -a; + quad[counter].b = b; + quad[counter].c = c; + quad[counter].d = -a+b+c-2*d; + if (++counter >= n) { + return; + } + } + } + } + } + (void) printf("found only %d below maximum bend of %d\n", + counter, MAXBEND); + for (; counter < n; counter++) { + quad[counter].a = -1; + quad[counter].b = 2; + quad[counter].c = 2; + quad[counter].d = 3; + } + return; +} + +/* + * Given a Descartes quadruple of bends (a,b,c,d), with a<0, find a + * quadruple of circles, represented by (bend,bend*x,bend*y), such + * that the circles have the given bends and the bends times the + * centers are integers. + * + * This just performs an exaustive search, assuming that the outer + * circle has center in the unit square. + * + * It is always sufficient to look in {(x,y):0<=y<=x<=1/2} for the + * center of the outer circle, but this may not lead to a packing + * that can be labelled with integer spherical and hyperbolic labels. + * To effect the smaller search, replace FOR(a) with + * + * for (pa = ea/2; pa <= 0; pa++) for (qa = pa; qa <= 0; qa++) + */ + +#define For(v,l,h) for (v = l; v <= h; v++) +#define FOR(z) For(p##z,lop##z,hip##z) For(q##z,loq##z,hiq##z) +#define H(z) ((e##z*e##z+p##z*p##z+q##z*q##z)%2) +#define UNIT(z) ((abs(e##z)-1)*(abs(e##z)-1) >= p##z*p##z+q##z*q##z) +#define T(z,w) is_tangent(e##z,p##z,q##z,e##w,p##w,q##w) +#define LO(r,z) lo##r##z = iceil(e##z*(r##a+1),ea)-1 +#define HI(r,z) hi##r##z = iflor(e##z*(r##a-1),ea)-1 +#define B(z) LO(p,z); HI(p,z); LO(q,z); HI(q,z) + +static int +is_quad(int a, int b, int c, int d) +{ + int s; + + s = a+b+c+d; + return 2*(a*a+b*b+c*c+d*d) == s*s; +} + +static Bool +is_tangent(int e1, int p1, int q1, int e2, int p2, int q2) +{ + int dx, dy, s; + + dx = p1*e2 - p2*e1; + dy = q1*e2 - q2*e1; + s = e1 + e2; + return dx*dx + dy*dy == s*s; +} + +static int +iflor(int a, int b) +{ + int q; + + if (b == 0) { + (void) printf("iflor: b = 0\n"); + return 0; + } + if (a%b == 0) + return a/b; + q = abs(a)/abs(b); + return ((a<0)^(b<0)) ? -q-1 : q; +} + +static int +iceil(int a, int b) +{ + int q; + + if (b == 0) { + (void) printf("iceil: b = 0\n"); + return 0; + } + if (a%b == 0) + return a/b; + q = abs(a)/abs(b); + return ((a<0)^(b<0)) ? -q : 1+q; +} + +static double +geom(int geometry, int e, int p, int q) +{ + int g = (geometry == spherical) ? -1 : + (geometry == hyperbolic) ? 1 : 0; + + if (g) + return (e*e + (1.0 - p*p - q*q) * g) / (2.0*e); + (void) printf("geom: g = 0\n"); + return e; +} + +static void +cquad(circle *c1, circle *c2, circle *c3, circle *c4) +{ + int ea, eb, ec, ed; + int pa, pb, pc, pd; + int qa, qb, qc, qd; + int lopa, lopb, lopc, lopd; + int hipa, hipb, hipc, hipd; + int loqa, loqb, loqc, loqd; + int hiqa, hiqb, hiqc, hiqd; + + ea = (int) c1->e; + eb = (int) c2->e; + ec = (int) c3->e; + ed = (int) c4->e; + if (ea >= 0) + (void) printf("ea = %d\n", ea); + if (!is_quad(ea,eb,ec,ed)) + (void) printf("Error not quad %d %d %d %d\n", ea, eb, ec, ed); + lopa = loqa = ea; + hipa = hiqa = 0; + FOR(a) { + B(b); B(c); B(d); + if (H(a) && UNIT(a)) FOR(b) { + if (H(b) && T(a,b)) FOR(c) { + if (H(c) && T(a,c) && T(b,c)) FOR(d) { + if (H(d) && T(a,d) && T(b,d) && T(c,d)) { + c1->s = geom(spherical, ea, pa, qa); + c1->h = geom(hyperbolic, ea, pa, qa); + c2->s = geom(spherical, eb, pb, qb); + c2->h = geom(hyperbolic, eb, pb, qb); + c3->s = geom(spherical, ec, pc, qc); + c3->h = geom(hyperbolic, ec, pc, qc); + c4->s = geom(spherical, ed, pd, qd); + c4->h = geom(hyperbolic, ed, pd, qd); + } + } + } + } + } +} + +static void +p(ModeInfo *mi, circle c) +{ + apollonianstruct *cp = &apollonians[MI_SCREEN(mi)]; + char string[10]; + double g, e; + int g_width; + +#ifdef DEBUG + (void) printf("c.e=%g c.s=%g c.h=%g c.x=%g c.y=%g\n", + c.e, c.s, c.h, c.x, c.y); +#endif + g = (cp->geometry == spherical) ? c.s : (cp->geometry == hyperbolic) ? + c.h : c.e; + if (c.e < 0.0) { + if (g < 0.0) + g = -g; + if (MI_NPIXELS(mi) <= 2) + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), + MI_WHITE_PIXEL(mi)); + else + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), + MI_PIXEL(mi, ((int) ((g + cp->color_offset) * + g)) % MI_NPIXELS(mi))); + XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + ((int) (cp->size * (-cp->c1.e) * (c.x - 1.0) / + (-2.0 * c.e) + cp->size / 2.0 + cp->offset.x)), + ((int) (cp->size * (-cp->c1.e) * (c.y - 1.0) / + (-2.0 * c.e) + cp->size / 2.0 + cp->offset.y)), + (int) (cp->c1.e * cp->size / c.e), + (int) (cp->c1.e * cp->size / c.e), 0, 23040); + if (!cp->label) { +#ifdef DEBUG + (void) printf("%g\n", -g); +#endif + return; + } + (void) sprintf(string, "%g", (g == 0.0) ? 0 : -g); + if (cp->size >= 10 * FONT_WIDTH) { + /* hard code these to corners */ + XDrawString(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + ((int) (cp->size * c.x / (2.0 * c.e))) + cp->offset.x, + ((int) (cp->size * c.y / (2.0 * c.e))) + FONT_HEIGHT, + string, (g == 0.0) ? 1 : ((g < 10.0) ? 2 : + ((g < 100.0) ? 3 : 4))); + } + if (cp->altgeom && MI_HEIGHT(mi) >= 30 * FONT_WIDTH) { + XDrawString(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + ((int) (cp->size * c.x / (2.0 * c.e) + cp->offset.x)), + ((int) (cp->size * c.y / (2.0 * c.e) + MI_HEIGHT(mi) - + FONT_HEIGHT / 2)), space_string[cp->geometry], + strlen(space_string[cp->geometry])); + } + return; + } + if (MI_NPIXELS(mi) <= 2) + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); + else + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), + MI_PIXEL(mi, ((int) ((g + cp->color_offset) * g)) % + MI_NPIXELS(mi))); + if (c.e == 0.0) { + if (c.x == 0.0 && c.y != 0.0) { + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + 0, (int) ((c.y + 1.0) * cp->size / 2.0 + cp->offset.y), + MI_WIDTH(mi), + (int) ((c.y + 1.0) * cp->size / 2.0 + cp->offset.y)); + } else if (c.y == 0.0 && c.x != 0.0) { + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + (int) ((c.x + 1.0) * cp->size / 2.0 + cp->offset.x), 0, + (int) ((c.x + 1.0) * cp->size / 2.0 + cp->offset.x), + MI_HEIGHT(mi)); + } + return; + } + e = (cp->c1.e >= 0.0) ? 1.0 : -cp->c1.e; + XFillArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + ((int) (cp->size * e * (c.x - 1.0) / (2.0 * c.e) + + cp->size / 2.0 + cp->offset.x)), + ((int) (cp->size * e * (c.y - 1.0) / (2.0 * c.e) + + cp->size / 2.0 + cp->offset.y)), + (int) (e * cp->size / c.e), (int) (e * cp->size / c.e), + 0, 23040); + if (!cp->label) { +#ifdef DEBUG + (void) printf("%g\n", g); +#endif + return; + } + if (MI_NPIXELS(mi) <= 2) + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); + else + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), + MI_PIXEL(mi, ((int) ((g + cp->color_offset) * g) + + MI_NPIXELS(mi) / 2) % MI_NPIXELS(mi))); + g_width = (g < 10.0) ? 1: ((g < 100.0) ? 2 : 3); + if (c.e < e * cp->size / (FONT_LENGTH + 5 * g_width) && g < 1000.0) { + (void) sprintf(string, "%g", g); + XDrawString(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + ((int) (cp->size * e * c.x / (2.0 * c.e) + + cp->size / 2.0 + cp->offset.x)) - + g_width * FONT_WIDTH / 2, + ((int) (cp->size * e * c.y / (2.0 * c.e) + + cp->size / 2.0 + cp->offset.y)) + + FONT_HEIGHT / 2, + string, g_width); + } +} + +#define BIG 7 +static void +f(ModeInfo *mi, circle c1, circle c2, circle c3, circle c4) +{ + apollonianstruct *cp = &apollonians[MI_SCREEN(mi)]; + int e = (int) ((cp->c1.e >= 0.0) ? 1.0 : -cp->c1.e); + circle c; + + c.e = 2*(c1.e+c2.e+c3.e) - c4.e; + c.s = 2*(c1.s+c2.s+c3.s) - c4.s; + c.h = 2*(c1.h+c2.h+c3.h) - c4.h; + c.x = 2*(c1.x+c2.x+c3.x) - c4.x; + c.y = 2*(c1.y+c2.y+c3.y) - c4.y; + if (c.e > cp->size * e || c.x / c.e > BIG || c.y / c.e > BIG || + c.x / c.e < -BIG || c.y / c.e < -BIG) + return; + p(mi, c); + f(mi, c2, c3, c, c1); + f(mi, c1, c3, c, c2); + f(mi, c1, c2, c, c3); +} + +static void +free_apollonian(Display *display, apollonianstruct *cp) +{ + if (cp->quad != NULL) { + (void) free((void *) cp->quad); + cp->quad = (apollonian_quadruple *) NULL; + } +#ifdef DOFONT + if (cp->gc != None) { + XFreeGC(display, cp->gc); + cp->gc = None; + } + if (cp->font != None) { + XFreeFont(display, cp->font); + cp->font = None; + } +#endif +} + +#ifndef DEBUG +void +randomize_c(int randomize, circle * c) +{ + if (randomize / 2) { + double temp; + + temp = c->x; + c->x = c->y; + c->y = temp; + } + if (randomize % 2) { + c->x = -c->x; + c->y = -c->y; + } +} +#endif + +void +init_apollonian(ModeInfo * mi) +{ + apollonianstruct *cp; + int i; + + if (apollonians == NULL) { + if ((apollonians = (apollonianstruct *) calloc(MI_NUM_SCREENS(mi), + sizeof (apollonianstruct))) == NULL) + return; + } + cp = &apollonians[MI_SCREEN(mi)]; + + cp->size = MAX(MIN(MI_WIDTH(mi), MI_HEIGHT(mi)) - 1, 1); + cp->offset.x = (MI_WIDTH(mi) - cp->size) / 2; + cp->offset.y = (MI_HEIGHT(mi) - cp->size) / 2; + cp->color_offset = NRAND(MI_NPIXELS(mi)); + +#ifdef DOFONT + if (cp->font == None) { + if ((cp->font = getFont(MI_DISPLAY(mi))) == None) + return False; + } +#endif + cp->label = label; + cp->altgeom = cp->label && altgeom; + + if (cp->quad == NULL) { + cp->count = ABS(MI_COUNT(mi)); + if ((cp->quad = (apollonian_quadruple *) malloc(cp->count * + sizeof (apollonian_quadruple))) == NULL) { + return; + } + dquad(cp->count, cp->quad); + } + cp->game = NRAND(PREDEF_CIRCLE_GAMES + cp->count); + cp->geometry = (cp->game && cp->altgeom) ? NRAND(3) : 0; + + if (cp->game < PREDEF_CIRCLE_GAMES) { + cp->c1 = examples[cp->game][0]; + cp->c2 = examples[cp->game][1]; + cp->c3 = examples[cp->game][2]; + cp->c4 = examples[cp->game][3]; + /* do not label non int */ + cp->label = cp->label && (cp->c4.e == (int) cp->c4.e); + } else { /* uses results of dquad, all int */ + i = cp->game - PREDEF_CIRCLE_GAMES; + cp->c1.e = cp->quad[i].a; + cp->c2.e = cp->quad[i].b; + cp->c3.e = cp->quad[i].c; + cp->c4.e = cp->quad[i].d; + if (cp->geometry) + cquad(&(cp->c1), &(cp->c2), &(cp->c3), &(cp->c4)); + } + cp->time = 0; + MI_CLEARWINDOW(mi); + if (cp->game != 0) { + double q123; + + if (cp->c1.e == 0.0 || cp->c1.e == -cp->c2.e) + return; + cp->c1.x = 0.0; + cp->c1.y = 0.0; + cp->c2.x = -(cp->c1.e + cp->c2.e) / cp->c1.e; + cp->c2.y = 0; + q123 = sqrt(cp->c1.e * cp->c2.e + cp->c1.e * cp->c3.e + + cp->c2.e * cp->c3.e); +#ifdef DEBUG + (void) printf("q123 = %g, ", q123); +#endif + cp->c3.x = (cp->c1.e * cp->c1.e - q123 * q123) / (cp->c1.e * + (cp->c1.e + cp->c2.e)); + cp->c3.y = -2.0 * q123 / (cp->c1.e + cp->c2.e); + q123 = -cp->c1.e - cp->c2.e + q123; + cp->c4.x = (cp->c1.e * cp->c1.e - q123 * q123) / (cp->c1.e * + (cp->c1.e + cp->c2.e)); + cp->c4.y = -2.0 * q123 / (cp->c1.e + cp->c2.e); +#ifdef DEBUG + (void) printf("q124 = %g\n", q123); + (void) printf("%g %g %g %g %g %g %g %g\n", + cp->c1.x, cp->c1.y, cp->c2.x, cp->c2.y, + cp->c3.x, cp->c3.y, cp->c4.x, cp->c4.y); +#endif + } +#ifndef DEBUG + if (LRAND() & 1) { + cp->c3.y = -cp->c3.y; + cp->c4.y = -cp->c4.y; + } + i = NRAND(4); + randomize_c(i, &(cp->c1)); + randomize_c(i, &(cp->c2)); + randomize_c(i, &(cp->c3)); + randomize_c(i, &(cp->c4)); +#endif +} + +void +draw_apollonian(ModeInfo * mi) +{ + apollonianstruct *cp; + + if (apollonians == NULL) + return; + cp = &apollonians[MI_SCREEN(mi)]; + + + MI_IS_DRAWN(mi) = True; + + if (cp->time < 5) { + switch (cp->time) { + case 0: + p(mi, cp->c1); + p(mi, cp->c2); + p(mi, cp->c3); + p(mi, cp->c4); + break; + case 1: + f(mi, cp->c1, cp->c2, cp->c3, cp->c4); + break; + case 2: + f(mi, cp->c1, cp->c2, cp->c4, cp->c3); + break; + case 3: + f(mi, cp->c1, cp->c3, cp->c4, cp->c2); + break; + case 4: + f(mi, cp->c2, cp->c3, cp->c4, cp->c1); + } + } + if (++cp->time > MI_CYCLES(mi)) + { +#ifdef STANDALONE + erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi)); +#endif /* STANDALONE */ + init_apollonian(mi); + } +} + +void +release_apollonian(ModeInfo * mi) +{ + if (apollonians != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_apollonian(MI_DISPLAY(mi), &apollonians[screen]); + (void) free((void *) apollonians); + apollonians = (apollonianstruct *) NULL; + } +} + +#endif /* MODE_apollonian */ diff --git a/hacks/blitspin.c b/hacks/blitspin.c index 1c527253..ec31aa09 100644 --- a/hacks/blitspin.c +++ b/hacks/blitspin.c @@ -25,23 +25,9 @@ */ #include "screenhack.h" +#include "xpm-pixmap.h" #include -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif - -#ifdef HAVE_XMU -# ifndef VMS -# include -#else /* VMS */ -# include -# endif /* VMS */ -#endif - #include "images/som.xbm" static Display *dpy; @@ -93,93 +79,6 @@ rotate (void) } } -static void -read_bitmap (char *bitmap_name, int *widthP, int *heightP) -{ -#ifdef HAVE_XPM - XWindowAttributes xgwa; - XpmAttributes xpmattrs; - int result; - xpmattrs.valuemask = 0; - bitmap = 0; - - XGetWindowAttributes (dpy, window, &xgwa); - -# ifdef XpmCloseness - xpmattrs.valuemask |= XpmCloseness; - xpmattrs.closeness = 40000; -# endif -# ifdef XpmVisual - xpmattrs.valuemask |= XpmVisual; - xpmattrs.visual = xgwa.visual; -# endif -# ifdef XpmDepth - xpmattrs.valuemask |= XpmDepth; - xpmattrs.depth = xgwa.depth; -# endif -# ifdef XpmColormap - xpmattrs.valuemask |= XpmColormap; - xpmattrs.colormap = xgwa.colormap; -# endif - - result = XpmReadFileToPixmap (dpy, window, bitmap_name, &bitmap, 0, - &xpmattrs); - switch (result) - { - case XpmColorError: - fprintf (stderr, "%s: warning: xpm color substitution performed\n", - progname); - /* fall through */ - case XpmSuccess: - *widthP = xpmattrs.width; - *heightP = xpmattrs.height; - break; - case XpmFileInvalid: - case XpmOpenFailed: - bitmap = 0; - break; - case XpmColorFailed: - fprintf (stderr, "%s: xpm: color allocation failed\n", progname); - exit (-1); - case XpmNoMemory: - fprintf (stderr, "%s: xpm: out of memory\n", progname); - exit (-1); - default: - fprintf (stderr, "%s: xpm: unknown error code %d\n", progname, result); - exit (-1); - } - if (! bitmap) -#endif - -#ifdef HAVE_XMU - { - int xh, yh; - Pixmap b2; - bitmap = XmuLocateBitmapFile (DefaultScreenOfDisplay (dpy), bitmap_name, - 0, 0, widthP, heightP, &xh, &yh); - if (! bitmap) - { - fprintf (stderr, "%s: couldn't find bitmap %s\n", progname, - bitmap_name); - exit (1); - } - b2 = XmuCreatePixmapFromBitmap (dpy, window, bitmap, *widthP, *heightP, - depth, fg, bg); - XFreePixmap (dpy, bitmap); - bitmap = b2; - } -#else /* !XMU */ - { - fprintf (stderr, - "%s: your vendor doesn't ship the standard Xmu library.\n", - progname); - fprintf (stderr, "\tWe can't load XBM files without it.\n"); - exit (1); - } -#endif /* !XMU */ -} - - static Pixmap read_screen (Display *dpy, Window window, int *widthP, int *heightP) { @@ -262,7 +161,8 @@ init (void) } else { - read_bitmap (bitmap_name, &width, &height); + bitmap = xpm_file_to_pixmap (dpy, window, bitmap_name, + &width, &height, 0); scale_up = True; /* probably? */ } @@ -314,12 +214,10 @@ display (Pixmap pixmap) last_w = xgwa.width; last_h = xgwa.height; } -#ifdef HAVE_XPM if (depth != 1) XCopyArea (dpy, pixmap, window, gc, 0, 0, size, size, (xgwa.width-size)>>1, (xgwa.height-size)>>1); else -#endif XCopyPlane (dpy, pixmap, window, gc, 0, 0, size, size, (xgwa.width-size)>>1, (xgwa.height-size)>>1, 1); /* diff --git a/hacks/braid.c b/hacks/braid.c index 9d9c4e5f..55e4fa7e 100644 --- a/hacks/braid.c +++ b/hacks/braid.c @@ -1,11 +1,15 @@ -/* -*- Mode: C; tab-width: 4 -*- - * braid --- draws random color-cyling rotating braids around a circle. +/* -*- Mode: C; tab-width: 4 -*- */ +/*- + * braid --- random braids around a circle and then changes the color in + * a rotational pattern */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)braid.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)braid.c 5.00 2000/11/01 xlockmore"; + #endif -/* +/*- * Copyright (c) 1995 by John Neil. * * Permission to use, copy, modify, and distribute this software and its @@ -21,31 +25,44 @@ static const char sccsid[] = "@(#)braid.c 4.00 97/01/01 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 01-Sep-95: color knotted components differently, J. Neil. - * 29-Aug-95: Written. John Neil + * 01-Nov-2000: Allocation checks + * 10-May-1997: Jamie Zawinski compatible with xscreensaver + * 01-Sep-1995: color knotted components differently, J. Neil. + * 29-Aug-1995: Written. John Neil */ #ifdef STANDALONE -# define PROGCLASS "Braid" -# define HACK_INIT init_braid -# define HACK_DRAW draw_braid -# define braid_opts xlockmore_opts -# define DEFAULTS "*count: 15 \n" \ - "*size: -7 \n" \ - "*cycles: 100 \n" \ - "*delay: 1000 \n" \ - "*ncolors: 64 \n" -# define UNIFORM_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -# include "erase.h" -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -ModeSpecOpt braid_opts = { - 0, NULL, 0, NULL, NULL }; +#define MODE_braid +#define PROGCLASS "Braid" +#define HACK_INIT init_braid +#define HACK_DRAW draw_braid +#define braid_opts xlockmore_opts +#define DEFAULTS "*delay: 1000 \n" \ + "*count: 15 \n" \ + "*cycles: 100 \n" \ + "*size: -7 \n" \ + "*ncolors: 64 \n" +#define UNIFORM_COLORS +#include "xlockmore.h" +#include "erase.h" +#else /* STANDALONE */ +#include "xlock.h" + +#endif /* STANDALONE */ + +#ifdef MODE_braid + +ModeSpecOpt braid_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct braid_description = +{"braid", "init_braid", "draw_braid", "release_braid", + "refresh_braid", "init_braid", (char *) NULL, &braid_opts, + 1000, 15, 100, 1, 64, 1.0, "", + "Shows random braids and knots", 0, NULL}; +#endif #if defined( COLORROUND ) && defined( COLORCOMP ) #undef COLORROUND @@ -72,6 +89,7 @@ ModeSpecOpt braid_opts = { #define FLOATRAND(min,max) ((min)+((double) LRAND()/((double) MAXRAND))*((max)-(min))) typedef struct { + int linewidth; int braidword[MAXLENGTH]; int components[MAXSTRANDS]; int startcomp[MAXLENGTH][MAXSTRANDS]; @@ -84,10 +102,10 @@ typedef struct { float max_radius; float top, bottom, left, right; int age; - int color_direction; + int color_direction; } braidtype; -static braidtype *braids = NULL; +static braidtype *braids = (braidtype *) NULL; static int applyword(braidtype * braid, int string, int position) @@ -147,7 +165,6 @@ applywordbackto(braidtype * braid, int string, int position) void init_braid(ModeInfo * mi) { - Display *display = MI_DISPLAY(mi); braidtype *braid; int used[MAXSTRANDS]; int i, count, comp, c; @@ -160,25 +177,26 @@ init_braid(ModeInfo * mi) } braid = &braids[MI_SCREEN(mi)]; - braid->center_x = MI_WIN_WIDTH(mi) / 2; - braid->center_y = MI_WIN_HEIGHT(mi) / 2; + braid->center_x = MI_WIDTH(mi) / 2; + braid->center_y = MI_HEIGHT(mi) / 2; braid->age = 0; /* jwz: go in the other direction sometimes. */ braid->color_direction = ((LRAND() & 1) ? 1 : -1); - XClearWindow(display, MI_WINDOW(mi)); + + MI_CLEARWINDOW(mi); min_length = (braid->center_x > braid->center_y) ? braid->center_y : braid->center_x; braid->min_radius = min_length * 0.30; braid->max_radius = min_length * 0.90; - if (MI_BATCHCOUNT(mi) < MINSTRANDS) + if (MI_COUNT(mi) < MINSTRANDS) braid->nstrands = MINSTRANDS; else braid->nstrands = INTRAND(MINSTRANDS, - MAX(MIN(MIN(MAXSTRANDS, MI_BATCHCOUNT(mi)), - (int) ((braid->max_radius - braid->min_radius) / 5.0)), MINSTRANDS)); + MAX(MIN(MIN(MAXSTRANDS, MI_COUNT(mi)), + (int) ((braid->max_radius - braid->min_radius) / 5.0)), MINSTRANDS)); braid->braidlength = INTRAND(MINLENGTH, MIN(MAXLENGTH, braid->nstrands * 6)); for (i = 0; i < braid->braidlength; i++) { @@ -214,7 +232,7 @@ init_braid(ModeInfo * mi) braid->startcolor = (MI_NPIXELS(mi) > 2) ? (float) NRAND(MI_NPIXELS(mi)) : 0.0; - /* XSetLineAttributes (display, MI_GC(mi), 2, LineSolid, CapRound, + /* XSetLineAttributes (display, MI_GC(mi), 2, LineSolid, CapRound, JoinRound); */ (void) memset((char *) braid->components, 0, sizeof (braid->components)); @@ -237,21 +255,12 @@ init_braid(ModeInfo * mi) } } while (count > 0); - { - int line_width = MI_SIZE(mi); - if (line_width == 0) - line_width = -8; - if (line_width < 0) - line_width = NRAND(-line_width)+1; - if (line_width == 1) - line_width = 0; - XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), line_width, - LineSolid, - (line_width <= 3 ? CapButt : CapRound), - JoinMiter); - } - + braid->linewidth = MI_SIZE(mi); + if (braid->linewidth < 0) + braid->linewidth = NRAND(-braid->linewidth) + 1; + if (braid->linewidth * braid->linewidth * 8 > MIN(MI_WIDTH(mi), MI_HEIGHT(mi))) + braid->linewidth = MIN(1, (int) sqrt((double) MIN(MI_WIDTH(mi), MI_HEIGHT(mi)) / 8)); for (i = 0; i < braid->nstrands; i++) if (!(braid->components[i] & 1)) braid->components[i] *= -1; @@ -262,22 +271,31 @@ draw_braid(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); - braidtype *braid = &braids[MI_SCREEN(mi)]; - float num_points, t_inc; + int num_points = 500; + float t_inc; float theta, psi; float t, r_diff; int i, s; float x_1, y_1, x_2, y_2, r1, r2; float color, color_use = 0.0, color_inc; + braidtype *braid; - num_points = 500.0; - theta = (2.0 * M_PI) / (float) (braid->braidlength); - t_inc = (2.0 * M_PI) / num_points; - color_inc = (float) MI_NPIXELS(mi) / num_points; - color_inc *= braid->color_direction; + if (braids == NULL) + return; + braid = &braids[MI_SCREEN(mi)]; + MI_IS_DRAWN(mi) = True; + XSetLineAttributes(display, MI_GC(mi), braid->linewidth, + LineSolid, + (braid->linewidth <= 3 ? CapButt : CapRound), + JoinMiter); + + theta = (2.0 * M_PI) / (float) (braid->braidlength); + t_inc = (2.0 * M_PI) / (float) num_points; + color_inc = (float) MI_NPIXELS(mi) * braid->color_direction / + (float) num_points; braid->startcolor += SPINRATE * color_inc; - if (braid->startcolor >= MI_NPIXELS(mi)) + if (((int) braid->startcolor) >= MI_NPIXELS(mi)) braid->startcolor = 0.0; r_diff = (braid->max_radius - braid->min_radius) / (float) (braid->nstrands); @@ -289,7 +307,7 @@ draw_braid(ModeInfo * mi) for (t = 0.0; t < theta; t += t_inc) { #ifdef COLORROUND color += color_inc; - if (color >= (float) (MI_NPIXELS(mi))) + if (((int) color) >= MI_NPIXELS(mi)) color = 0.0; color_use = color; #endif @@ -303,16 +321,16 @@ draw_braid(ModeInfo * mi) color_use = color + SPINRATE * braid->components[applywordbackto(braid, s, i)] + (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi); - while (color_use >= (float) MI_NPIXELS(mi)) + while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); - while (color_use < 0.0) + while (((int) color_use) < 0) color_use += (float) MI_NPIXELS(mi); } #endif #ifdef COLORROUND if (MI_NPIXELS(mi) > 2) { color_use += SPINRATE * color_inc; - while (color_use >= (float) (MI_NPIXELS(mi))) + while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); } #endif @@ -335,7 +353,7 @@ draw_braid(ModeInfo * mi) if (MI_NPIXELS(mi) > 2) XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use)); else - XSetForeground(display, MI_GC(mi), MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi)); XDrawLine(display, window, MI_GC(mi), (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2)); @@ -345,9 +363,9 @@ draw_braid(ModeInfo * mi) color_use = color + SPINRATE * braid->components[applywordbackto(braid, s + 1, i)] + (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi); - while (color_use >= (float) MI_NPIXELS(mi)) + while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); - while (color_use < 0.0) + while (((int) color_use) < 0) color_use += (float) MI_NPIXELS(mi); } #endif @@ -368,7 +386,7 @@ draw_braid(ModeInfo * mi) if (MI_NPIXELS(mi) > 2) XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use)); else - XSetForeground(display, MI_GC(mi), MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi)); XDrawLine(display, window, MI_GC(mi), (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2)); @@ -380,16 +398,16 @@ draw_braid(ModeInfo * mi) color_use = color + SPINRATE * braid->components[applywordbackto(braid, s, i)] + (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi); - while (color_use >= (float) MI_NPIXELS(mi)) + while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); - while (color_use < 0.0) + while (((int) color_use) < 0) color_use += (float) MI_NPIXELS(mi); } #endif #ifdef COLORROUND if (MI_NPIXELS(mi) > 2) { color_use += SPINRATE * color_inc; - while (color_use >= (float) MI_NPIXELS(mi)) + while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); } #endif @@ -401,7 +419,7 @@ draw_braid(ModeInfo * mi) if (MI_NPIXELS(mi) > 2) XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use)); else - XSetForeground(display, MI_GC(mi), MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi)); XDrawLine(display, window, MI_GC(mi), (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2)); @@ -409,12 +427,13 @@ draw_braid(ModeInfo * mi) } } } + XSetLineAttributes(display, MI_GC(mi), 1, LineSolid, CapNotLast, JoinRound); if (++braid->age > MI_CYCLES(mi)) { #ifdef STANDALONE erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi)); #endif - init_braid(mi); + init_braid(mi); } } @@ -423,12 +442,14 @@ release_braid(ModeInfo * mi) { if (braids != NULL) { (void) free((void *) braids); - braids = NULL; + braids = (braidtype *) NULL; } } void refresh_braid(ModeInfo * mi) { - /* Do nothing, it will refresh by itself */ + MI_CLEARWINDOW(mi); } + +#endif /* MODE_braid */ diff --git a/hacks/bsod.c b/hacks/bsod.c index e86efe26..8178dd46 100644 --- a/hacks/bsod.c +++ b/hacks/bsod.c @@ -19,19 +19,17 @@ */ #include "screenhack.h" +#include "xpm-pixmap.h" #include #include -#ifdef HAVE_XPM -# include -# include "images/amiga.xpm" -#endif +#include "images/amiga.xpm" #include "images/atari.xbm" #include "images/mac.xbm" -static void +static int draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv, XFontStruct *font, int xoff, int yoff, @@ -117,6 +115,8 @@ draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv, } s++; } + + return width * char_width; } @@ -665,6 +665,8 @@ amiga (Display *dpy, Window window, int delay) unsigned long fg, bg, bg2; Pixmap pixmap = 0; int pix_w = 0, pix_h = 0; + int string_width; + int margin; const char *string = ("_Software failure. Press left mouse button to continue.\n" @@ -703,37 +705,10 @@ amiga (Display *dpy, Window window, int delay) height = (font->ascent + font->descent) * 6; -#ifdef HAVE_XPM - { - XpmAttributes xpmattrs; - int result; - xpmattrs.valuemask = 0; - -# ifdef XpmCloseness - xpmattrs.valuemask |= XpmCloseness; - xpmattrs.closeness = 40000; -# endif -# ifdef XpmVisual - xpmattrs.valuemask |= XpmVisual; - xpmattrs.visual = xgwa.visual; -# endif -# ifdef XpmDepth - xpmattrs.valuemask |= XpmDepth; - xpmattrs.depth = xgwa.depth; -# endif -# ifdef XpmColormap - xpmattrs.valuemask |= XpmColormap; - xpmattrs.colormap = xgwa.colormap; -# endif - - result = XpmCreatePixmapFromData(dpy, window, amiga_hand, - &pixmap, 0 /* mask */, &xpmattrs); - if (!pixmap || (result != XpmSuccess && result != XpmColorError)) - pixmap = 0; - pix_w = xpmattrs.width; - pix_h = xpmattrs.height; - } -#endif /* HAVE_XPM */ +#if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM) + pixmap = xpm_data_to_pixmap (dpy, window, (char **) amiga_hand, + &pix_w, &pix_h, 0); +#endif /* HAVE_GDK_PIXBUF || HAVE_XPM */ if (pixmap && xgwa.height > 600) /* scale up the bitmap */ { @@ -758,18 +733,24 @@ amiga (Display *dpy, Window window, int delay) } XFillRectangle(dpy, window, gc2, 0, 0, xgwa.width, height); - draw_string(dpy, window, gc, &gcv, font, 0, 0, xgwa.width, height, string,0); - + margin = font->ascent; + string_width = draw_string(dpy, window, gc, &gcv, font, + margin, 0, + xgwa.width - (margin * 2), height, + string, 0); { GC gca = gc; while (delay > 0) { - XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, font->ascent); - XFillRectangle(dpy, window, gca, 0, 0, font->ascent, height); - XFillRectangle(dpy, window, gca, xgwa.width-font->ascent, 0, - font->ascent, height); - XFillRectangle(dpy, window, gca, 0, height-font->ascent, xgwa.width, - font->ascent); + int x2; + XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, margin); + XFillRectangle(dpy, window, gca, 0, 0, margin, height); + XFillRectangle(dpy, window, gca, + 0, height - margin, xgwa.width, margin); + x2 = margin + string_width; + if (x2 < xgwa.width - margin) x2 = xgwa.width - margin; + XFillRectangle(dpy, window, gca, x2, 0, margin, height); + gca = (gca == gc ? gc2 : gc); XSync(dpy, False); if (bsod_sleep(dpy, 1)) diff --git a/hacks/bubbles-default.c b/hacks/bubbles-default.c index f393f1fa..cdd47c91 100644 --- a/hacks/bubbles-default.c +++ b/hacks/bubbles-default.c @@ -14,6 +14,8 @@ # include "config.h" #endif +#include + #include #include #include "bubbles.h" diff --git a/hacks/bubbles.c b/hacks/bubbles.c index f92b4334..fe5ccef0 100644 --- a/hacks/bubbles.c +++ b/hacks/bubbles.c @@ -1,6 +1,6 @@ /* bubbles.c - frying pan / soft drink in a glass simulation */ -/*$Id: bubbles.c,v 1.17 2000/07/19 06:38:42 jwz Exp $*/ +/*$Id: bubbles.c,v 1.18 2002/01/17 02:16:04 jwz Exp $*/ /* * Copyright (C) 1995-1996 James Macnicol @@ -41,7 +41,6 @@ #include #include "screenhack.h" -#include "bubbles.h" #include @@ -60,9 +59,11 @@ # include #endif #include "yarandom.h" +#include "bubbles.h" +#include "xpm-pixmap.h" -#ifdef HAVE_XPM -# include +#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) +# define FANCY_BUBBLES #endif /* @@ -92,9 +93,9 @@ char *defaults [] = { XrmOptionDescRec options [] = { { "-simple", ".simple", XrmoptionNoArg, "true" }, -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES { "-broken", ".broken", XrmoptionNoArg, "true" }, -#endif /* HAVE_XPM */ +#endif { "-quiet", ".quiet", XrmoptionNoArg, "true" }, { "-nodelay", ".nodelay", XrmoptionNoArg, "true" }, { "-3D", ".3D", XrmoptionNoArg, "true" }, @@ -137,13 +138,13 @@ static long *bubble_areas; static int *bubble_droppages; static GC draw_gc, erase_gc; -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES static int num_bubble_pixmaps; static Bubble_Step **step_pixmaps; -#endif /* HAVE_XPM */ +#endif /* Options stuff */ -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES static Bool simple = False; #else static Bool simple = True; @@ -225,7 +226,7 @@ turned off if DEBUG isn't set. */ bb->radius, bb->x, bb->y, bb->magic, bb->cell_index); die_bad_bubble(bb); } -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES } else { if ((bb->x < 0) || (bb->x > screen_width) || (bb->y < 0) || (bb->y > screen_height) || @@ -236,7 +237,7 @@ turned off if DEBUG isn't set. */ bb->radius, bb->x, bb->y, bb->magic, bb->cell_index); die_bad_bubble(bb); } -#endif /* HAVE_XPM */ +#endif } #endif /* DEBUG */ return 0; @@ -438,20 +439,20 @@ adjust_areas (void) long factor; int i; -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES if (simple) maxarea = bubble_areas[bubble_max_radius+1]; else maxarea = step_pixmaps[num_bubble_pixmaps]->area; -#else +#else /* !FANCY_BUBBLES */ maxarea = bubble_areas[bubble_max_radius+1]; -#endif /* HAVE_XPM */ +#endif /* !FANCY_BUBBLES */ maxvalue = (double)screen_width * 2.0 * (double)maxarea; factor = (long)ceil(maxvalue / (double)LONG_MAX); if (factor > 1) { /* Overflow will occur in weighted_mean(). We must divide areas each by factor so it will never do so. */ -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES if (simple) { for (i = bubble_min_radius; i <= bubble_max_radius+1; i++) { bubble_areas[i] /= factor; @@ -471,13 +472,13 @@ adjust_areas (void) #endif /* DEBUG */ } } -#else +#else /* !FANCY_BUBBLES */ for (i = bubble_min_radius; i <= bubble_max_radius+1; i++) { bubble_areas[i] /= factor; if (bubble_areas[i] == 0) bubble_areas[i] = 1; } -#endif /* HAVE_XPM */ +#endif /* !FANCY_BUBBLES */ } #ifdef DEBUG printf("maxarea = %ld\n", maxarea); @@ -507,12 +508,12 @@ size. */ if (simple) { rv->radius = bubble_min_radius; rv->area = bubble_areas[bubble_min_radius]; -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES } else { rv->step = 0; rv->radius = step_pixmaps[0]->radius; rv->area = step_pixmaps[0]->area; -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } rv->visible = 0; rv->magic = BUBBLE_MAGIC; @@ -540,7 +541,7 @@ show_bubble(Bubble *bb) (bb->y - bb->radius), bb->radius*2, bb->radius*2, 0, 360*64); } else { -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES XSetClipOrigin(defdsp, step_pixmaps[bb->step]->draw_gc, (bb->x - bb->radius), (bb->y - bb->radius)); @@ -551,7 +552,7 @@ show_bubble(Bubble *bb) (bb->radius * 2), (bb->x - bb->radius), (bb->y - bb->radius)); -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } } } @@ -573,7 +574,7 @@ hide_bubble(Bubble *bb) (bb->y - bb->radius), bb->radius*2, bb->radius*2, 0, 360*64); } else { -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES if (! broken) { XSetClipOrigin(defdsp, step_pixmaps[bb->step]->erase_gc, (bb->x - bb->radius), (bb->y - bb->radius)); @@ -584,7 +585,7 @@ hide_bubble(Bubble *bb) (bb->radius * 2), (bb->radius * 2)); } -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } } } @@ -761,24 +762,24 @@ bubble_eat(Bubble *diner, Bubble *food) if ((simple) && (diner->area > bubble_areas[bubble_max_radius])) { diner->area = bubble_areas[bubble_max_radius]; } -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES if ((! simple) && (diner->area > step_pixmaps[num_bubble_pixmaps]->area)) { diner->area = step_pixmaps[num_bubble_pixmaps]->area; } -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } else { if ((simple) && (diner->area > bubble_areas[bubble_max_radius])) { delete_bubble_in_mesh(diner, DELETE_BUBBLE); return 0; } -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES if ((! simple) && (diner->area > step_pixmaps[num_bubble_pixmaps]->area)) { delete_bubble_in_mesh(diner, DELETE_BUBBLE); return 0; } -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } if (simple) { @@ -790,7 +791,7 @@ bubble_eat(Bubble *diner, Bubble *food) diner->radius = i; } show_bubble(diner); -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES } else { if (diner->area > step_pixmaps[diner->step+1]->area) { i = diner->step; @@ -800,7 +801,7 @@ bubble_eat(Bubble *diner, Bubble *food) diner->radius = step_pixmaps[diner->step]->radius; } show_bubble(diner); -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } /* Now adjust locations and cells if need be */ @@ -958,12 +959,12 @@ insert_new_bubble(Bubble *tmp) if ((nextbub->area >= bubble_areas[bubble_max_radius - 1]) && (random() % 2 == 0)) continue; } -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES else { if ((nextbub->step >= num_bubble_pixmaps - 1) && (random() % 2 == 0)) continue; } -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } break; } @@ -996,10 +997,10 @@ drop_bubble( Bubble *bb ) if (simple) (bb->y) += (bubble_droppages[bb->radius] * drop_dir); -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES else (bb->y) += (step_pixmaps[bb->step]->droppage * drop_dir); -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ if ((bb->y < 0) || (bb->y > screen_height)) { delete_bubble_in_mesh( bb, DELETE_BUBBLE ); return -1; @@ -1020,12 +1021,12 @@ drop_bubble( Bubble *bb ) if ((bb->area >= bubble_areas[bubble_max_radius - 1]) && (random() % 2 == 0)) leave_trail( bb ); } -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES else { if ((bb->step >= num_bubble_pixmaps - 1) && (random() % 2 == 0)) leave_trail( bb ); } -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } return 0; @@ -1053,7 +1054,7 @@ get_length_of_bubble_list(Bubble *bb) * still check for XPM, though! */ -#ifdef HAVE_XPM +#ifdef FANCY_BUBBLES /* * Pixmaps without file I/O (but do have XPM) @@ -1178,7 +1179,6 @@ make_pixmap_from_default(char **pixmap_data, Bubble_Step *bl) This is virtually copied verbatim from make_pixmap_from_file() above and changes made to either should be propagated onwards! */ { - int result; XGCValues gcv; #ifdef DEBUG @@ -1193,49 +1193,16 @@ changes made to either should be propagated onwards! */ exit(1); } - bl->xpmattrs.valuemask = 0; - -#ifdef XpmCloseness - bl->xpmattrs.valuemask |= XpmCloseness; - bl->xpmattrs.closeness = 40000; -#endif -#ifdef XpmVisual - bl->xpmattrs.valuemask |= XpmVisual; - bl->xpmattrs.visual = defvisual; -#endif -#ifdef XpmDepth - bl->xpmattrs.valuemask |= XpmDepth; - bl->xpmattrs.depth = screen_depth; -#endif -#ifdef XpmColormap - bl->xpmattrs.valuemask |= XpmColormap; - bl->xpmattrs.colormap = defcmap; -#endif - - - /* This is the only line which is different from make_pixmap_from_file() */ - result = XpmCreatePixmapFromData(defdsp, defwin, pixmap_data, &bl->ball, - &bl->shape_mask, &bl->xpmattrs); - - switch(result) { - case XpmColorError: - fprintf(stderr, "xpm: color substitution performed\n"); - /* fall through */ - case XpmSuccess: - bl->radius = MAX(bl->xpmattrs.width, bl->xpmattrs.height) / 2; +#ifdef FANCY_BUBBLES + { + int w, h; + bl->ball = xpm_data_to_pixmap (defdsp, defwin, (char **) pixmap_data, + &w, &h, &bl->shape_mask); + bl->radius = MAX(w, h) / 2; bl->area = calc_bubble_area(bl->radius); - break; - case XpmColorFailed: - fprintf(stderr, "xpm: color allocation failed\n"); - exit(1); - case XpmNoMemory: - fprintf(stderr, "xpm: out of memory\n"); - exit(1); - default: - fprintf(stderr, "xpm: unknown error code %d\n", result); - exit(1); } - +#endif /* FANCY_BUBBLES */ + gcv.plane_mask = AllPlanes; gcv.foreground = default_fg_pixel; gcv.function = GXcopy; @@ -1279,7 +1246,7 @@ default_to_pixmaps (void) make_pixmap_array(pixmap_list); } -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ /* @@ -1337,11 +1304,11 @@ get_resources(Display *dpy, Window window) if (! quiet) fprintf(stderr, "-broken not available in simple mode\n"); } else { -#ifndef HAVE_XPM +#ifndef FANCY_BUBBLES simple = 1; -#else +#else /* FANCY_BUBBLES */ broken = get_boolean_resource("broken", "Boolean"); -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ } } @@ -1401,18 +1368,18 @@ init_bubbles (Display *dpy, Window window) mesh_length = (2 * bubble_max_radius) + 3; } else { -#ifndef HAVE_XPM +#ifndef FANCY_BUBBLES fprintf(stderr, - "Bug: simple mode code not set but HAVE_XPM not defined\n"); + "Bug: simple mode code not set but FANCY_BUBBLES not defined\n"); exit(1); -#else +#else /* FANCY_BUBBLES */ /* Make sure all #ifdef sort of things have been taken care of in get_resources(). */ default_to_pixmaps(); /* Set mesh length */ mesh_length = (2 * step_pixmaps[num_bubble_pixmaps-1]->radius) + 3; -#endif /* HAVE_XPM */ +#endif /* FANCY_BUBBLES */ /* Am I missing something in here??? */ } diff --git a/hacks/bubbles.h b/hacks/bubbles.h index 6bca1c67..18d9f2b5 100644 --- a/hacks/bubbles.h +++ b/hacks/bubbles.h @@ -1,14 +1,10 @@ /* bubbles.h - definitions for bubbles screensaver */ -/* $Id: bubbles.h,v 1.3 2000/07/19 06:38:42 jwz Exp $ */ +/* $Id: bubbles.h,v 1.4 2002/01/17 02:16:04 jwz Exp $ */ #ifndef _BUBBLES_H_ #define _BUBBLES_H_ -#ifdef HAVE_XPM -#include -#endif - /*************************************************************************** * Options you might like to change to affect the program's behaviour * ***************************************************************************/ @@ -187,32 +183,31 @@ typedef struct bub Bubble; * better name...) */ -#ifdef HAVE_XPM +#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) struct bub_step { int radius; long area; int droppage; Pixmap ball, shape_mask; GC draw_gc, erase_gc; - XpmAttributes xpmattrs; struct bub_step *next; }; typedef struct bub_step Bubble_Step; -#endif /* HAVE_XPM */ +#endif /* HAVE_XPM || HAVE_GDK_PIXBUF */ /* Make sure default bubble isn't compiled when we don't have XPM Disable file I/O code too. */ -#ifndef HAVE_XPM +#if !defined(HAVE_XPM) && !defined(HAVE_GDK_PIXBUF) # define NO_DEFAULT_BUBBLE # undef BUBBLES_IO -#endif /* HAVE_XPM */ +#endif /* !HAVE_XPM && !HAVE_GDK_PIXBUF */ /* Make sure default bubble is compiled in when we have XPM and no file I/O */ -#ifdef HAVE_XPM +#if defined(HAVE_XPM) || defined(HAVE_GDK_PIXBUF) # ifndef BUBBLES_IO # undef NO_DEFAULT_BUBBLE # endif /* BUBBLES_IO */ -#endif /* HAVE_XPM */ +#endif /* HAVE_XPM || HAVE_GDK_PIXBUF */ #endif /* _BUBBLES_H_ */ diff --git a/hacks/bumps.h b/hacks/bumps.h index d5601ec7..f5e8c292 100644 --- a/hacks/bumps.h +++ b/hacks/bumps.h @@ -47,6 +47,8 @@ typedef unsigned char BOOL; char *progclass = "Bumps"; char *defaults [] = { + ".background: black", + ".foreground: white", "*degrees: 360", "*color: random", "*colorcount: 64", diff --git a/hacks/ccurve.c b/hacks/ccurve.c index 1555d88d..efe5915c 100644 --- a/hacks/ccurve.c +++ b/hacks/ccurve.c @@ -644,6 +644,8 @@ char *progclass = "Ccurve"; char *defaults [] = { + ".background: black", + ".foreground: white", ".delay: 1", ".pause: 3", ".limit: 200000", diff --git a/hacks/compile_axp.com b/hacks/compile_axp.com index bd83e4d3..27fc3d71 100644 --- a/hacks/compile_axp.com +++ b/hacks/compile_axp.com @@ -1,4 +1,5 @@ $ 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]) APOLLONIAN.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 @@ -22,6 +23,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DISTORT.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DRIFT.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) EPICYCLE.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) EULER2D.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FADEPLOT.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAG.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAME.C @@ -40,6 +42,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) IMSMAP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) INTERFERENCE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JIGSAW.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JUGGLE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JULIA.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) KALEIDESCOPE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) KUMPPA.C @@ -61,6 +64,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENROSE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PETRI.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PHOSPHOR.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) POLYOMINOES.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PYRO.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) QIX.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RD-BOMB.C @@ -84,11 +88,14 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STRANGE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SWIRL.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) T3D.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) THORNBIRD.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRIANGLE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRUCHET.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TWANG.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) VERMICULATE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) VINES.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WANDER.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WEBCOLLAGE-HELPER.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WHIRLWINDWARP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WHIRLYGIG.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WORM.C @@ -97,6 +104,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XLOCKMORE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XLYAP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XMATRIX.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XPM-PIXMAP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XRAYSWARM.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XSCREENSAVER-SGIGL.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XSPIROGRAPH.C diff --git a/hacks/compile_decc.com b/hacks/compile_decc.com index bd83e4d3..27fc3d71 100644 --- a/hacks/compile_decc.com +++ b/hacks/compile_decc.com @@ -1,4 +1,5 @@ $ 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]) APOLLONIAN.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 @@ -22,6 +23,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DISTORT.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DRIFT.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) EPICYCLE.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) EULER2D.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FADEPLOT.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAG.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) FLAME.C @@ -40,6 +42,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) IMSMAP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) INTERFERENCE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JIGSAW.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JUGGLE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) JULIA.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) KALEIDESCOPE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) KUMPPA.C @@ -61,6 +64,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENROSE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PETRI.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PHOSPHOR.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) POLYOMINOES.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PYRO.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) QIX.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) RD-BOMB.C @@ -84,11 +88,14 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STRANGE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SWIRL.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) T3D.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) THORNBIRD.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRIANGLE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRUCHET.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TWANG.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) VERMICULATE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) VINES.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WANDER.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WEBCOLLAGE-HELPER.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WHIRLWINDWARP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WHIRLYGIG.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) WORM.C @@ -97,6 +104,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XLOCKMORE.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XLYAP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XMATRIX.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XPM-PIXMAP.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XRAYSWARM.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XSCREENSAVER-SGIGL.C $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XSPIROGRAPH.C diff --git a/hacks/config/README b/hacks/config/README index b7528988..5f4ca9a4 100644 --- a/hacks/config/README +++ b/hacks/config/README @@ -4,8 +4,8 @@ a screen saver and locker for the X window system by Jamie Zawinski - version 4.00 - 02-Jan-2002 + version 4.01 + 24-Feb-2002 http://www.jwz.org/xscreensaver/ diff --git a/hacks/config/apollonian.xml b/hacks/config/apollonian.xml new file mode 100644 index 00000000..0f89877d --- /dev/null +++ b/hacks/config/apollonian.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + <_description> +Packs a large circle with smaller circles, demonstrating the +Descartes Circle Theorem. Written by Allan R. Wilks and David Bagley. + + diff --git a/hacks/config/boxed.xml b/hacks/config/boxed.xml new file mode 100644 index 00000000..5685f7f5 --- /dev/null +++ b/hacks/config/boxed.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + <_description> +Draws a box full of 3D bouncing balls that explode. +Written by Sander van Grieken. + + diff --git a/hacks/config/cosmos.xml b/hacks/config/cosmos.xml index e70dd326..63f713fb 100644 --- a/hacks/config/cosmos.xml +++ b/hacks/config/cosmos.xml @@ -5,6 +5,6 @@ <_description> Draws fireworks and zooming, fading flares. By Tom Campbell. -You can find it at <http://www.mindspring.com/~campbell/cosmos/> +You can find it at <http://cosmos.dnsalias.net/cosmos/> \ No newline at end of file diff --git a/hacks/config/critical.xml b/hacks/config/critical.xml index 0b4ef398..443d026b 100644 --- a/hacks/config/critical.xml +++ b/hacks/config/critical.xml @@ -6,7 +6,7 @@ + low="3" high="255" default="64"/> + + + + + + + + + + + + + + + + + + <_description> +Simulates two dimensional Incompressible Inviscid Fluid Flow. +Written by Stephen Montgomery-Smith. + + diff --git a/hacks/config/flame.xml b/hacks/config/flame.xml index 85c0e805..210a850e 100644 --- a/hacks/config/flame.xml +++ b/hacks/config/flame.xml @@ -18,7 +18,7 @@ low="1" high="250" default="25"/> + low="1" high="20" default="20"/> <_description> This draws fractal trees. Written by Peter Baumung. Everybody loves diff --git a/hacks/config/galaxy.xml b/hacks/config/galaxy.xml index 80b35644..e139f53d 100644 --- a/hacks/config/galaxy.xml +++ b/hacks/config/galaxy.xml @@ -18,7 +18,7 @@ + low="10" high="255" default="64"/> diff --git a/hacks/config/gears.xml b/hacks/config/gears.xml index 83b6a2a1..d0ef3c79 100644 --- a/hacks/config/gears.xml +++ b/hacks/config/gears.xml @@ -4,9 +4,6 @@ - - + + + + + + + + + + + + + + + + + + + + + <_description> +Draws an animation of sprinkling fire-like 3D triangles in a landscape +filled with trees. Requires OpenGL, and a machine with fast hardware +support for texture maps. + +Written by Eric Lassauge <lassauge@mail.dotcom.fr>. + + diff --git a/hacks/config/glsnake.xml b/hacks/config/glsnake.xml new file mode 100644 index 00000000..f897c482 --- /dev/null +++ b/hacks/config/glsnake.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + <_description> +Draws a simulation of the Rubik's Snake puzzle. +Written by Jamie Wilkinson, Andrew Bennetts, and Peter Aylett. + + diff --git a/hacks/config/juggle.xml b/hacks/config/juggle.xml new file mode 100644 index 00000000..6cc1f14f --- /dev/null +++ b/hacks/config/juggle.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + <_description> +Draws a juggling stick-man. Written by Tim Auckland. + + diff --git a/hacks/config/polyominoes.xml b/hacks/config/polyominoes.xml new file mode 100644 index 00000000..80ed2518 --- /dev/null +++ b/hacks/config/polyominoes.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + <_description> +Repeatedly attempts to completely fill a rectangle with +irregularly-shaped puzzle pieces. Written by Stephen Montgomery-Smith. + + diff --git a/hacks/config/pulsar.xml b/hacks/config/pulsar.xml index 0bb4777d..e4b6802d 100644 --- a/hacks/config/pulsar.xml +++ b/hacks/config/pulsar.xml @@ -32,7 +32,7 @@ - + diff --git a/hacks/config/sballs.xml b/hacks/config/sballs.xml new file mode 100644 index 00000000..eeae18de --- /dev/null +++ b/hacks/config/sballs.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + <_description> +Draws an animation of textured balls spinning like crazy in GL. +Requires OpenGL, and a machine with fast hardware support for texture +maps. + +Written by Eric Lassauge <lassauge@mail.dotcom.fr>. + + diff --git a/hacks/config/ssystem.xml b/hacks/config/ssystem.xml index f5c5caca..c9934477 100644 --- a/hacks/config/ssystem.xml +++ b/hacks/config/ssystem.xml @@ -8,12 +8,20 @@ SSystem is a GL Solar System simulator. It simulates flybys of Sun, the nine planets and a few major satellites, with four camera modes. Written by Raul Alonso. This is not included with the XScreenSaver -package, but if you don't have it already, you can find it at -<http://www1.las.es/~amil/ssystem/>. +package, but is packaged separately. -Note: this program doesn't work as a screen saver on all systems, -because it doesn't communicate with xscreensaver properly. It happens -to work with some window managers, but not with others, so your -mileage may vary. +Note: SSystem does not work as a screen saver on all systems, because +it doesn't communicate with xscreensaver properly. It happens to work +with some window managers, but not with others, so your mileage may +vary. + +SSystem was once available at <http://www1.las.es/~amil/ssystem/>, +but is now gone. You may still be able to find copies elsewhere. + +SSystem has since evolved into two different programs: OpenUniverse +(http://openuniverse.sourceforge.net/) and Celestia +(http://www.shatters.net/celestia/). Sadly, neither of these programs +work with xscreensaver at all. You are encouraged to nag their authors +into adding xscreensaver support! diff --git a/hacks/config/thornbird.xml b/hacks/config/thornbird.xml new file mode 100644 index 00000000..15d7fb0e --- /dev/null +++ b/hacks/config/thornbird.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + <_description> +Displays a view of the ``Bird in a Thornbush'' fractal. +Written by Tim Auckland. + + diff --git a/hacks/config/twang.xml b/hacks/config/twang.xml new file mode 100644 index 00000000..f963c16f --- /dev/null +++ b/hacks/config/twang.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + <_description> + Divides the screen into a grid, and plucks them. + Written by Dan Bornstein. + + diff --git a/hacks/coral.c b/hacks/coral.c index 7621d5ee..e17d4951 100644 --- a/hacks/coral.c +++ b/hacks/coral.c @@ -88,8 +88,8 @@ init_coral(Display *dpy, Window window) for( i = 0; i < seeds; i++ ) { int x, y; do { - x = random() % width; - y = random() % height; + x = 1 + random() % (width - 2); + y = 1 + random() % (height - 2); } while( getdot(x, y) ); setdot((x-1), (y-1)); setdot(x, (y-1)); setdot((x+1), (y-1)); diff --git a/hacks/critical.c b/hacks/critical.c index 1e8f3a1a..5a6fae2a 100644 --- a/hacks/critical.c +++ b/hacks/critical.c @@ -199,8 +199,8 @@ setup_colormap (Display *dpy, XWindowAttributes *wattr, /* Make a colormap */ *n_colors = get_integer_resource ("ncolors", "Integer"); - if (*n_colors < 2) - *n_colors = 2; + if (*n_colors < 3) + *n_colors = 3; *colors = (XColor *) calloc (sizeof(XColor), *n_colors); if (!*colors) @@ -384,11 +384,3 @@ screenhack (Display *dpy, Window window) i_restart = (i_restart + 1) % n_restart; } } - - -/* - * Local variables: - * c-indent-mode: gnu - * compile-command "make critical && ./critical" - * End: - */ diff --git a/hacks/deco.c b/hacks/deco.c index ae908051..628deb98 100644 --- a/hacks/deco.c +++ b/hacks/deco.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1997, 1998 Jamie Zawinski +/* xscreensaver, Copyright (c) 1997, 1998, 2002 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -14,6 +14,8 @@ #include "screenhack.h" #include +#include +#include static XColor colors[255]; static int ncolors = 0; diff --git a/hacks/demon.c b/hacks/demon.c index db0255ae..df7ea3e8 100644 --- a/hacks/demon.c +++ b/hacks/demon.c @@ -2,7 +2,7 @@ /* demon --- David Griffeath's cellular automata */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)demon.c 4.07 97/11/24 xlockmore"; +static const char sccsid[] = "@(#)demon.c 5.00 2000/11/01 xlockmore"; #endif @@ -22,16 +22,17 @@ static const char sccsid[] = "@(#)demon.c 4.07 97/11/24 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: Compatible with xscreensaver - * 16-Apr-97: -neighbors 3, 9 (not sound mathematically), 12, and 8 added - * 30-May-96: Ron Hitchens + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 16-Apr-1997: -neighbors 3, 9 (not sound mathematically), 12, and 8 added + * 30-May-1996: Ron Hitchens * Fixed memory management that caused leaks - * 14-Apr-96: -neighbors 6 runtime-time option added - * 21-Aug-95: Coded from A.K. Dewdney's "Computer Recreations", Scientific - * American Magazine" Aug 1989 pp 102-105. Also very similar to - * hodgepodge machine described in A.K. Dewdney's "Computer - * Recreations", Scientific American Magazine" Aug 1988 pp 104-107. - * also used life.c as a guide. + * 14-Apr-1996: -neighbors 6 runtime-time option added + * 21-Aug-1995: Coded from A.K. Dewdney's "Computer Recreations", Scientific + * American Magazine" Aug 1989 pp 102-105. Also very similar + * to hodgepodge machine described in A.K. Dewdney's "Computer + * Recreations", Scientific American Magazine" Aug 1988 + * pp 104-107. Also used life.c as a guide. */ /*- @@ -39,7 +40,7 @@ static const char sccsid[] = "@(#)demon.c 4.07 97/11/24 xlockmore"; */ /*- - Grid Number of Neigbors + Grid Number of Neighbors ---- ------------------ Square 4 or 8 Hexagon 6 @@ -47,47 +48,64 @@ static const char sccsid[] = "@(#)demon.c 4.07 97/11/24 xlockmore"; */ #ifdef STANDALONE +#define MODE_demon #define PROGCLASS "Demon" #define HACK_INIT init_demon #define HACK_DRAW draw_demon #define demon_opts xlockmore_opts -#define DEFAULTS "*delay: 50000 \n" \ - "*count: 0 \n" \ - "*cycles: 1000 \n" \ - "*size: -7 \n" \ - "*ncolors: 64 \n" \ - "*neighbors: 0 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* in xscreensaver distribution */ +#define DEFAULTS "*delay: 50000 \n" \ + "*count: 0 \n" \ + "*cycles: 1000 \n" \ + "*size: -7 \n" \ + "*ncolors: 64 \n" \ + "*neighbors: 0 \n" +#define UNIFORM_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ -# include "xlock.h" /* in xlockmore distribution */ +#include "xlock.h" /* in xlockmore distribution */ + #endif /* STANDALONE */ #include "automata.h" +#ifdef MODE_demon + /*- * neighbors of 0 randomizes it between 3, 4, 6, 8, 9, and 12. */ -#ifdef STANDALONE -static int neighbors; -#else -extern int neighbors; -#endif /* !STANDALONE */ +#define DEF_NEIGHBORS "0" /* choose random value */ + +static int neighbors; + +static XrmOptionDescRec opts[] = +{ + {(char *) "-neighbors", (char *) ".demon.neighbors", XrmoptionSepArg, (caddr_t) NULL} +}; + +static argtype vars[] = +{ + {(caddr_t *) & neighbors, (char *) "neighbors", (char *) "Neighbors", (char *) DEF_NEIGHBORS, t_Int} +}; +static OptionStruct desc[] = +{ + {(char *) "-neighbors num", (char *) "squares 4 or 8, hexagons 6, triangles 3, 9 or 12"} +}; ModeSpecOpt demon_opts = -{0, NULL, 0, NULL, NULL}; +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; #ifdef USE_MODULES ModStruct demon_description = {"demon", "init_demon", "draw_demon", "release_demon", - "refresh_demon", "init_demon", NULL, &demon_opts, + "refresh_demon", "init_demon", (char *) NULL, &demon_opts, 50000, 0, 1000, -7, 64, 1.0, "", "Shows Griffeath's cellular automata", 0, NULL}; #endif #define DEMONBITS(n,w,h)\ - dp->pixmaps[dp->init_bits++]=\ - XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1) + if ((dp->pixmaps[dp->init_bits]=\ + XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1))==None){\ + free_demon(display,dp); return;} else {dp->init_bits++;} #define REDRAWSTEP 2000 /* How many cells to draw per cycle */ #define MINSTATES 2 @@ -129,7 +147,7 @@ static char plots[2][NEIGHBORKINDS] = {12, 16, 18, 20, 22, 24} /* Number of states */ }; -static demonstruct *demons = NULL; +static demonstruct *demons = (demonstruct *) NULL; static void drawcell(ModeInfo * mi, int col, int row, unsigned char state) @@ -161,8 +179,8 @@ drawcell(ModeInfo * mi, int col, int row, unsigned char state) dp->shape.hexagon[0].x = dp->xb + ccol * dp->xs; dp->shape.hexagon[0].y = dp->yb + crow * dp->ys; if (dp->xs == 1 && dp->ys == 1) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), - gc, dp->shape.hexagon[0].x, dp->shape.hexagon[0].y, 1, 1); + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), + gc, dp->shape.hexagon[0].x, dp->shape.hexagon[0].y); else XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, dp->shape.hexagon, 6, Convex, CoordModePrevious); @@ -176,9 +194,9 @@ drawcell(ModeInfo * mi, int col, int row, unsigned char state) dp->shape.triangle[orient][0].x = dp->xb + col * dp->xs; dp->shape.triangle[orient][0].y = dp->yb + row * dp->ys; if (dp->xs <= 3 || dp->ys <= 3) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc, + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc, ((orient) ? -1 : 1) + dp->shape.triangle[orient][0].x, - dp->shape.triangle[orient][0].y, 1, 1); + dp->shape.triangle[orient][0].y); else { if (orient) dp->shape.triangle[orient][0].x += (dp->xs / 2 - 1); @@ -191,18 +209,22 @@ drawcell(ModeInfo * mi, int col, int row, unsigned char state) } } -static void +static Bool addtolist(ModeInfo * mi, int col, int row, unsigned char state) { demonstruct *dp = &demons[MI_SCREEN(mi)]; CellList *current; current = dp->cellList[state]; - dp->cellList[state] = (CellList *) malloc(sizeof (CellList)); + if ((dp->cellList[state] = (CellList *) + malloc(sizeof (CellList))) == NULL) { + return False; + } dp->cellList[state]->pt.x = col; dp->cellList[state]->pt.y = row; dp->cellList[state]->next = current; dp->ncells[state]++; + return True; } #ifdef DEBUG @@ -235,8 +257,8 @@ free_state(demonstruct * dp, int state) dp->cellList[state] = dp->cellList[state]->next; (void) free((void *) current); } - dp->cellList[state] = NULL; - if (dp->ncells) + dp->cellList[state] = (CellList *) NULL; + if (dp->ncells != NULL) dp->ncells[state] = 0; } @@ -249,7 +271,7 @@ free_list(demonstruct * dp) for (state = 0; state < dp->states; state++) free_state(dp, state); (void) free((void *) dp->cellList); - dp->cellList = NULL; + dp->cellList = (CellList **) NULL; } static void @@ -260,19 +282,35 @@ free_struct(demonstruct * dp) } if (dp->ncells != NULL) { (void) free((void *) dp->ncells); - dp->ncells = NULL; + dp->ncells = (int *) NULL; } if (dp->oldcell != NULL) { (void) free((void *) dp->oldcell); - dp->oldcell = NULL; + dp->oldcell = (unsigned char *) NULL; } if (dp->newcell != NULL) { (void) free((void *) dp->newcell); - dp->newcell = NULL; + dp->newcell = (unsigned char *) NULL; } } static void +free_demon(Display *display, demonstruct *dp) +{ + int shade; + + if (dp->stippledGC != None) { + XFreeGC(display, dp->stippledGC); + dp->stippledGC = None; + } + for (shade = 0; shade < dp->init_bits; shade++) { + XFreePixmap(display, dp->pixmaps[shade]); + } + dp->init_bits = 0; + free_struct(dp); +} + +static Bool draw_state(ModeInfo * mi, int state) { demonstruct *dp = &demons[MI_SCREEN(mi)]; @@ -309,8 +347,8 @@ draw_state(ModeInfo * mi, int state) dp->shape.hexagon[0].x = dp->xb + ccol * dp->xs; dp->shape.hexagon[0].y = dp->yb + crow * dp->ys; if (dp->xs == 1 && dp->ys == 1) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), - gc, dp->shape.hexagon[0].x, dp->shape.hexagon[0].y, 1, 1); + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), + gc, dp->shape.hexagon[0].x, dp->shape.hexagon[0].y); else XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, dp->shape.hexagon, 6, Convex, CoordModePrevious); @@ -321,7 +359,10 @@ draw_state(ModeInfo * mi, int state) int ncells = 0; /* Create Rectangle list from part of the cellList */ - rects = (XRectangle *) malloc(dp->ncells[state] * sizeof (XRectangle)); + if ((rects = (XRectangle *) malloc(dp->ncells[state] * + sizeof (XRectangle))) == NULL) { + return False; + } current = dp->cellList[state]; while (current) { rects[ncells].x = dp->xb + current->pt.x * dp->xs; @@ -346,9 +387,9 @@ draw_state(ModeInfo * mi, int state) dp->shape.triangle[orient][0].x = dp->xb + col * dp->xs; dp->shape.triangle[orient][0].y = dp->yb + row * dp->ys; if (dp->xs <= 3 || dp->ys <= 3) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc, + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc, ((orient) ? -1 : 1) + dp->shape.triangle[orient][0].x, - dp->shape.triangle[orient][0].y, 1, 1); + dp->shape.triangle[orient][0].y); else { if (orient) dp->shape.triangle[orient][0].x += (dp->xs / 2 - 1); @@ -362,6 +403,7 @@ draw_state(ModeInfo * mi, int state) } free_state(dp, state); XFlush(MI_DISPLAY(mi)); + return True; } static void @@ -374,7 +416,8 @@ RandomSoup(ModeInfo * mi) for (col = 0; col < dp->ncols; ++col) { dp->oldcell[col + mrow] = (unsigned char) LRAND() % ((unsigned char) dp->states); - addtolist(mi, col, row, dp->oldcell[col + mrow]); + if (!addtolist(mi, col, row, dp->oldcell[col + mrow])) + return; /* sparse soup */ } mrow += dp->ncols; } @@ -394,6 +437,7 @@ init_demon(ModeInfo * mi) return; } dp = &demons[MI_SCREEN(mi)]; + dp->generation = 0; dp->redrawing = 0; if (MI_NPIXELS(mi) < NUMSTIPPLES) { @@ -401,13 +445,18 @@ init_demon(ModeInfo * mi) XGCValues gcv; gcv.fill_style = FillOpaqueStippled; - dp->stippledGC = XCreateGC(display, window, GCFillStyle, &gcv); + if ((dp->stippledGC = XCreateGC(display, window, + GCFillStyle, &gcv)) == None) { + free_demon(display, dp); + return; + } } if (dp->init_bits == 0) { int i; - for (i = 1; i < NUMSTIPPLES; i++) + for (i = 1; i < NUMSTIPPLES; i++) { DEMONBITS(stipples[i], STIPPLESIZE, STIPPLESIZE); + } } } free_struct(dp); @@ -429,8 +478,15 @@ init_demon(ModeInfo * mi) dp->states = NRAND(-dp->states - MINSTATES + 1) + MINSTATES; else if (dp->states < MINSTATES) dp->states = plots[1][nk]; - dp->cellList = (CellList **) calloc(dp->states, sizeof (CellList *)); - dp->ncells = (int *) calloc(dp->states, sizeof (int)); + if ((dp->cellList = (CellList **) calloc(dp->states, + sizeof (CellList *))) == NULL) { + free_demon(display, dp); + return; + } + if ((dp->ncells = (int *) calloc(dp->states, sizeof (int))) == NULL) { + free_demon(display, dp); + return; + } dp->state = 0; @@ -440,10 +496,10 @@ init_demon(ModeInfo * mi) if (dp->neighbors == 6) { int nccols, ncrows, i; - if (dp->width < 2) - dp->width = 2; - if (dp->height < 4) - dp->height = 4; + if (dp->width < 8) + dp->width = 8; + if (dp->height < 8) + dp->height = 8; if (size < -MINSIZE) dp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(dp->width, dp->height) / MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE; @@ -457,11 +513,11 @@ init_demon(ModeInfo * mi) MINGRIDSIZE)); dp->xs = dp->ys; nccols = MAX(dp->width / dp->xs - 2, 2); - ncrows = MAX(dp->height / dp->ys - 1, 2); + ncrows = MAX(dp->height / dp->ys - 1, 4); dp->ncols = nccols / 2; dp->nrows = 2 * (ncrows / 4); dp->xb = (dp->width - dp->xs * nccols) / 2 + dp->xs / 2; - dp->yb = (dp->height - dp->ys * (ncrows / 2) * 2) / 2 + dp->ys; + dp->yb = (dp->height - dp->ys * (ncrows / 2) * 2) / 2 + dp->ys - 2; for (i = 0; i < 6; i++) { dp->shape.hexagon[i].x = (dp->xs - 1) * hexagonUnit[i].x; dp->shape.hexagon[i].y = ((dp->ys - 1) * hexagonUnit[i].y / 2) * 4 / 3; @@ -518,11 +574,17 @@ init_demon(ModeInfo * mi) MI_CLEARWINDOW(mi); - dp->oldcell = (unsigned char *) - malloc(dp->ncols * dp->nrows * sizeof (unsigned char)); + if ((dp->oldcell = (unsigned char *) + malloc(dp->ncols * dp->nrows * sizeof (unsigned char))) == NULL) { + free_demon(display, dp); + return; + } - dp->newcell = (unsigned char *) - malloc(dp->ncols * dp->nrows * sizeof (unsigned char)); + if ((dp->newcell = (unsigned char *) + malloc(dp->ncols * dp->nrows * sizeof (unsigned char))) == NULL) { + free_demon(display, dp); + return; + } RandomSoup(mi); } @@ -530,11 +592,16 @@ init_demon(ModeInfo * mi) void draw_demon(ModeInfo * mi) { - demonstruct *dp = &demons[MI_SCREEN(mi)]; int i, j, k, l, mj = 0, ml; + demonstruct *dp; - MI_IS_DRAWN(mi) = True; + if (demons == NULL) + return; + dp = &demons[MI_SCREEN(mi)]; + if (dp->cellList == NULL) + return; + MI_IS_DRAWN(mi) = True; if (dp->state >= dp->states) { (void) memcpy((char *) dp->newcell, (char *) dp->oldcell, dp->ncols * dp->nrows * sizeof (unsigned char)); @@ -554,7 +621,6 @@ draw_demon(ModeInfo * mi) dp->newcell[i + mj] = dp->oldcell[k + ml]; /* E */ k = (i + 1 == dp->ncols) ? 0 : i + 1; - l = j; ml = mj; if (dp->oldcell[k + ml] == (int) (dp->oldcell[i + mj] + 1) % dp->states) @@ -581,7 +647,6 @@ draw_demon(ModeInfo * mi) dp->newcell[i + mj] = dp->oldcell[k + ml]; /* W */ k = (!i) ? dp->ncols - 1 : i - 1; - l = j; ml = mj; if (dp->oldcell[k + ml] == (int) (dp->oldcell[i + mj] + 1) % dp->states) @@ -611,7 +676,6 @@ draw_demon(ModeInfo * mi) dp->newcell[i + mj] = dp->oldcell[k + ml]; /* E */ k = (i + 1 == dp->ncols) ? 0 : i + 1; - l = j; ml = mj; if (dp->oldcell[k + ml] == (int) (dp->oldcell[i + mj] + 1) % dp->states) @@ -676,7 +740,6 @@ draw_demon(ModeInfo * mi) if ((i + j) % 2) { /* right */ /* W */ k = (!i) ? dp->ncols - 1 : i - 1; - l = j; ml = mj; if (dp->oldcell[k + ml] == (int) (dp->oldcell[i + mj] + 1) % dp->states) @@ -684,7 +747,6 @@ draw_demon(ModeInfo * mi) } else { /* left */ /* E */ k = (i + 1 == dp->ncols) ? 0 : i + 1; - l = j; ml = mj; if (dp->oldcell[k + ml] == (int) (dp->oldcell[i + mj] + 1) % dp->states) @@ -846,7 +908,10 @@ draw_demon(ModeInfo * mi) for (i = 0; i < dp->ncols; i++) if (dp->oldcell[i + mj] != dp->newcell[i + mj]) { dp->oldcell[i + mj] = dp->newcell[i + mj]; - addtolist(mi, i, j, dp->oldcell[i + mj]); + if (!addtolist(mi, i, j, dp->oldcell[i + mj])) { + free_demon(MI_DISPLAY(mi), dp); + return; + } } mj += dp->ncols; } @@ -855,7 +920,10 @@ draw_demon(ModeInfo * mi) dp->state = 0; } else { if (dp->ncells[dp->state]) - draw_state(mi, dp->state); + if (!draw_state(mi, dp->state)) { + free_demon(MI_DISPLAY(mi), dp); + return; + } dp->state++; } if (dp->redrawing) { @@ -877,26 +945,24 @@ release_demon(ModeInfo * mi) if (demons != NULL) { int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - demonstruct *dp = &demons[screen]; - int shade; - - if (dp->stippledGC != None) { - XFreeGC(MI_DISPLAY(mi), dp->stippledGC); - } - for (shade = 0; shade < dp->init_bits; shade++) - XFreePixmap(MI_DISPLAY(mi), dp->pixmaps[shade]); - free_struct(dp); - } + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_demon(MI_DISPLAY(mi), &demons[screen]); (void) free((void *) demons); - demons = NULL; + demons = (demonstruct *) NULL; } -} void +} +void refresh_demon(ModeInfo * mi) { - demonstruct *dp = &demons[MI_SCREEN(mi)]; + demonstruct *dp; + + if (demons == NULL) + return; + dp = &demons[MI_SCREEN(mi)]; dp->redrawing = 1; dp->redrawpos = 0; } + +#endif /* MODE_demon */ diff --git a/hacks/discrete.c b/hacks/discrete.c index 7f336a65..bf251f57 100644 --- a/hacks/discrete.c +++ b/hacks/discrete.c @@ -2,12 +2,12 @@ /* discrete --- chaotic mappings */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)discrete.c 4.10 98/04/24 xlockmore"; +static const char sccsid[] = "@(#)discrete.c 5.00 2000/11/01 xlockmore"; #endif /*- - * Copyright (c) 1996 by Tim Auckland + * Copyright (c) 1996 by Tim Auckland * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -27,36 +27,37 @@ static const char sccsid[] = "@(#)discrete.c 4.10 98/04/24 xlockmore"; * Map" and the "Bird in a Thornbush" fractal. * * Revision History: - * 31-Jul-97: Ported to xlockmore-4 - * 08-Aug-96: Adapted from hop.c Copyright (c) 1991 by Patrick J. Naughton. + * 01-Nov-2000: Allocation checks + * 31-Jul-1997: Ported to xlockmore-4 + * 08-Aug-1996: Adapted from hop.c Copyright (c) 1991 by Patrick J. Naughton. */ #ifdef STANDALONE -# define PROGCLASS "Discrete" -# define HACK_INIT init_discrete -# define HACK_DRAW draw_discrete -# define discrete_opts xlockmore_opts -# define SMOOTH_COLORS -# define BRIGHT_COLORS -# define DEFAULTS "*delay: 1000 \n" \ - "*count: 4096 \n" \ - "*cycles: 2500 \n" \ - "*ncolors: 100 \n" - -# include "xlockmore.h" /* in xscreensaver distribution */ -# include "erase.h" - +#define MODE_discrete +#define PROGCLASS "Discrete" +#define HACK_INIT init_discrete +#define HACK_DRAW draw_discrete +#define discrete_opts xlockmore_opts +#define DEFAULTS "*delay: 1000 \n" \ + "*count: 4096 \n" \ + "*cycles: 2500 \n" \ + "*ncolors: 100 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#include "erase.h" #else /* STANDALONE */ -# include "xlock.h" /* in xlockmore distribution */ +#include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ +#ifdef MODE_discrete + ModeSpecOpt discrete_opts = -{0, NULL, 0, NULL, NULL}; +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; #ifdef USE_MODULES ModStruct discrete_description = {"discrete", "init_discrete", "draw_discrete", "release_discrete", - "refresh_discrete", "init_discrete", NULL, &discrete_opts, + "refresh_discrete", "init_discrete", (char *) NULL, &discrete_opts, 1000, 4096, 2500, 1, 64, 1.0, "", "Shows various discrete maps", 0, NULL}; @@ -69,7 +70,7 @@ enum ftypes { /*#define TEST STANDARD */ #define BIASES 18 -static int bias[BIASES] = +static enum ftypes bias[BIASES] = { STANDARD, STANDARD, STANDARD, STANDARD, SQRT, SQRT, SQRT, SQRT, @@ -101,7 +102,7 @@ typedef struct { XPoint *pointBuffer; /* pointer for XDrawPoints */ } discretestruct; -static discretestruct *discretes = NULL; +static discretestruct *discretes = (discretestruct *) NULL; void init_discrete(ModeInfo * mi) @@ -117,7 +118,6 @@ init_discrete(ModeInfo * mi) } hp = &discretes[MI_SCREEN(mi)]; - hp->maxx = MI_WIDTH(mi); hp->maxy = MI_HEIGHT(mi); #ifdef TEST @@ -239,12 +239,15 @@ init_discrete(ModeInfo * mi) hp->pix = 0; hp->inc = 0; - if (hp->pointBuffer == NULL) - hp->pointBuffer = (XPoint *) malloc(MI_COUNT(mi) * sizeof (XPoint)); + if (hp->pointBuffer == NULL) { + hp->pointBuffer = (XPoint *) malloc(sizeof (XPoint) * MI_COUNT(mi)); + /* if fails will check later */ + } /* Clear the background. */ MI_CLEARWINDOW(mi); + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); hp->count = 0; } @@ -255,18 +258,26 @@ draw_discrete(ModeInfo * mi) Display *dsp = MI_DISPLAY(mi); Window win = MI_WINDOW(mi); double oldj, oldi; - int batchcount = MI_COUNT(mi); + int count = MI_COUNT(mi); int cycles = MI_CYCLES(mi); int k; XPoint *xp; GC gc = MI_GC(mi); - discretestruct *hp = &discretes[MI_SCREEN(mi)]; + discretestruct *hp; - k = batchcount; + if (discretes == NULL) + return; + hp = &discretes[MI_SCREEN(mi)]; + if (hp->pointBuffer == NULL) + return; + + k = count; xp = hp->pointBuffer; hp->inc++; + MI_IS_DRAWN(mi) = True; + if (MI_NPIXELS(mi) > 2) { XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); if (++hp->pix >= MI_NPIXELS(mi)) @@ -289,18 +300,18 @@ draw_discrete(ModeInfo * mi) #endif #define HD #ifdef HD - if (k < batchcount / 4) { - hp->i = ((double) k / batchcount) * 8 - 1; + if (k < count / 4) { + hp->i = ((double) k / count) * 8 - 1; hp->j = 1; - } else if (k < batchcount / 2) { + } else if (k < count / 2) { hp->i = 1; - hp->j = 3 - ((double) k / batchcount) * 8; - } else if (k < 3 * batchcount / 4) { - hp->i = 5 - ((double) k / batchcount) * 8; + hp->j = 3 - ((double) k / count) * 8; + } else if (k < 3 * count / 4) { + hp->i = 5 - ((double) k / count) * 8; hp->j = -1; } else { hp->i = -1; - hp->j = ((double) k / batchcount) * 8 - 7; + hp->j = ((double) k / count) * 8 - 7; } for (i = 1; i < (hp->inc % 15); i++) { oldj = hp->j; @@ -370,6 +381,8 @@ draw_discrete(ModeInfo * mi) hp->i = ((LRAND() < MAXRAND / 2) ? -1 : 1) * sqrt(((oldi - hp->a) + sqrt((oldi - hp->a) * (oldi - hp->a) + (oldj - hp->b) * (oldj - hp->b))) / 2); + if (hp->i < 0.00000001 && hp->i > -0.00000001) + hp->i = (hp->i > 0.0) ? 0.00000001 : -0.00000001; hp->j = (oldj - hp->b) / (2 * hp->i); break; } @@ -377,7 +390,7 @@ draw_discrete(ModeInfo * mi) xp->y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js); xp++; } - XDrawPoints(dsp, win, gc, hp->pointBuffer, batchcount, CoordModeOrigin); + XDrawPoints(dsp, win, gc, hp->pointBuffer, count, CoordModeOrigin); if (++hp->count > cycles) { #ifdef STANDALONE erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi)); @@ -395,11 +408,13 @@ release_discrete(ModeInfo * mi) for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { discretestruct *hp = &discretes[screen]; - if (hp->pointBuffer != NULL) + if (hp->pointBuffer != NULL) { (void) free((void *) hp->pointBuffer); + /* hp->pointBuffer = NULL; */ + } } (void) free((void *) discretes); - discretes = NULL; + discretes = (discretestruct *) NULL; } } @@ -408,3 +423,5 @@ refresh_discrete(ModeInfo * mi) { MI_CLEARWINDOW(mi); } + +#endif /* MODE_discrete */ diff --git a/hacks/drift.c b/hacks/drift.c index 6e5399fe..8b4aa63c 100644 --- a/hacks/drift.c +++ b/hacks/drift.c @@ -1,11 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * drift --- drifting recursive fractal cosmic flames. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* drift --- drifting recursive fractal cosmic flames */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)drift.c 4.02 97/04/01 xlockmore"; +static const char sccsid[] = "@(#)drift.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1991 by Patrick J. Naughton. +/*- + * Copyright (c) 1991 by Patrick J. Naughton. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,35 +22,33 @@ static const char sccsid[] = "@(#)drift.c 4.02 97/04/01 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 01-Jan-97: Moved new flame to drift. Compile time options now run time. - * 01-Jun-95: Updated by Scott Draves. - * 27-Jun-91: vary number of functions used. - * 24-Jun-91: fixed portability problem with integer mod (%). - * 06-Jun-91: Written. (received from Scott Draves, spot@cs.cmu.edu). + * 01-Nov-2000: Allocation checks + * 10-May-1997: Jamie Zawinski compatible with xscreensaver + * 01-Jan-1997: Moved new flame to drift. Compile time options now run time. + * 01-Jun-1995: Updated by Scott Draves. + * 27-Jun-1991: vary number of functions used. + * 24-Jun-1991: fixed portability problem with integer mod (%). + * 06-Jun-1991: Written, received from Scott Draves */ #ifdef STANDALONE -# define PROGCLASS "Drift" -# define HACK_INIT init_drift -# define HACK_DRAW draw_drift -# define drift_opts xlockmore_opts -# define DEFAULTS "*count: 30 \n" \ - "*delay: 10000 \n" \ - "*ncolors: 200 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -# include "erase.h" -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ +#define MODE_drift +#define PROGCLASS "Drift" +#define HACK_INIT init_drift +#define HACK_DRAW draw_drift +#define drift_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 30 \n" \ + "*ncolors: 200 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#include "erase.h" +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ -#define MAXBATCH1 200 /* mono */ -#define MAXBATCH2 20 /* color */ -#define FUSE 10 /* discard this many initial iterations */ -#define NMAJORVARS 7 -#define MAXLEV 10 +#ifdef MODE_drift #define DEF_GROW "False" /* Grow fractals instead of animating one at a time, would then be like flame */ @@ -62,24 +62,39 @@ static Bool liss; static XrmOptionDescRec opts[] = { - {"-grow", ".drift.grow", XrmoptionNoArg, (caddr_t) "on"}, - {"+grow", ".drift.grow", XrmoptionNoArg, (caddr_t) "off"}, - {"-liss", ".drift.trail", XrmoptionNoArg, (caddr_t) "on"}, - {"+liss", ".drift.trail", XrmoptionNoArg, (caddr_t) "off"} + {(char *) "-grow", (char *) ".drift.grow", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+grow", (char *) ".drift.grow", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-liss", (char *) ".drift.trail", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+liss", (char *) ".drift.trail", XrmoptionNoArg, (caddr_t) "off"} }; static argtype vars[] = { - {(caddr_t *) & grow, "grow", "Grow", DEF_GROW, t_Bool}, - {(caddr_t *) & liss, "liss", "Liss", DEF_LISS, t_Bool} + {(caddr_t *) & grow, (char *) "grow", (char *) "Grow", (char *) DEF_GROW, t_Bool}, + {(caddr_t *) & liss, (char *) "liss", (char *) "Liss", (char *) DEF_LISS, t_Bool} }; static OptionStruct desc[] = { - {"-/+grow", "turn on/off growing fractals, else they are animated"}, - {"-/+liss", "turn on/off using lissojous figures to get points"} + {(char *) "-/+grow", (char *) "turn on/off growing fractals, else they are animated"}, + {(char *) "-/+liss", (char *) "turn on/off using lissojous figures to get points"} }; -ModeSpecOpt drift_opts = { 4, opts, 2, vars, desc }; +ModeSpecOpt drift_opts = +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct drift_description = +{"drift", "init_drift", "draw_drift", "release_drift", + "refresh_drift", "init_drift", (char *) NULL, &drift_opts, + 10000, 30, 1, 1, 64, 1.0, "", + "Shows cosmic drifting flame fractals", 0, NULL}; + +#endif +#define MAXBATCH1 200 /* mono */ +#define MAXBATCH2 20 /* color */ +#define FUSE 10 /* discard this many initial iterations */ +#define NMAJORVARS 7 +#define MAXLEV 10 typedef struct { /* shape of current flame */ @@ -109,81 +124,81 @@ typedef struct { XPoint pts[MAXBATCH1]; /* here they are */ unsigned long pixcol; /* when drawing in color, we have a buffer per color */ - int ncpoints[NUMCOLORS]; - XPoint cpts[NUMCOLORS][MAXBATCH2]; + int *ncpoints; + XPoint *cpts; double x, y, c; int liss_time; Bool grow, liss; + + short lasthalf; + long saved_random_bits; + int nbits; } driftstruct; -static driftstruct *drifts = NULL; +static driftstruct *drifts = (driftstruct *) NULL; static short -halfrandom(int mv) +halfrandom(driftstruct * dp, int mv) { - static short lasthalf = 0; unsigned long r; - if (lasthalf) { - r = lasthalf; - lasthalf = 0; + if (dp->lasthalf) { + r = dp->lasthalf; + dp->lasthalf = 0; } else { r = LRAND(); - lasthalf = r >> 16; + dp->lasthalf = (short) (r >> 16); } r = r % mv; return r; } static int -frandom(int n) +frandom(driftstruct * dp, int n) { - static long saved_random_bits = 0; - static int nbits = 0; int result; - if (3 > nbits) { - saved_random_bits = LRAND(); - nbits = 31; + if (3 > dp->nbits) { + dp->saved_random_bits = LRAND(); + dp->nbits = 31; } switch (n) { case 2: - result = saved_random_bits & 1; - saved_random_bits >>= 1; - nbits -= 1; + result = (int) (dp->saved_random_bits & 1); + dp->saved_random_bits >>= 1; + dp->nbits -= 1; return result; case 3: - result = saved_random_bits & 3; - saved_random_bits >>= 2; - nbits -= 2; + result = (int) (dp->saved_random_bits & 3); + dp->saved_random_bits >>= 2; + dp->nbits -= 2; if (3 == result) - return frandom(3); + return frandom(dp, 3); return result; case 4: - result = saved_random_bits & 3; - saved_random_bits >>= 2; - nbits -= 2; + result = (int) (dp->saved_random_bits & 3); + dp->saved_random_bits >>= 2; + dp->nbits -= 2; return result; case 5: - result = saved_random_bits & 7; - saved_random_bits >>= 3; - nbits -= 3; + result = (int) (dp->saved_random_bits & 7); + dp->saved_random_bits >>= 3; + dp->nbits -= 3; if (4 < result) - return frandom(5); + return frandom(dp, 5); return result; default: (void) fprintf(stderr, "bad arg to frandom\n"); - exit(1); } return 0; } -#define DISTRIB_A (halfrandom(7000) + 9000) -#define DISTRIB_B ((frandom(3) + 1) * (frandom(3) + 1) * 120000) +#define DISTRIB_A (halfrandom(dp, 7000) + 9000) +#define DISTRIB_B ((frandom(dp, 3) + 1) * (frandom(dp, 3) + 1) * 120000) #define LEN(x) (sizeof(x)/sizeof((x)[0])) static void @@ -195,7 +210,7 @@ initmode(ModeInfo * mi, int mode) dp->mode = mode; - dp->major_variation = halfrandom(VARIATION_LEN); + dp->major_variation = halfrandom(dp, VARIATION_LEN); /* 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 6 */ dp->major_variation = ((dp->major_variation >= VARIATION_LEN >> 1) && (dp->major_variation < VARIATION_LEN - 1)) ? @@ -204,11 +219,11 @@ initmode(ModeInfo * mi, int mode) if (dp->grow) { dp->rainbow = 0; if (mode) { - if (!dp->color || halfrandom(8)) { - dp->nfractals = halfrandom(30) + 5; + if (!dp->color || halfrandom(dp, 8)) { + dp->nfractals = halfrandom(dp, 30) + 5; dp->fractal_len = DISTRIB_A; } else { - dp->nfractals = halfrandom(5) + 5; + dp->nfractals = halfrandom(dp, 5) + 5; dp->fractal_len = DISTRIB_B; } } else { @@ -221,8 +236,9 @@ initmode(ModeInfo * mi, int mode) dp->rainbow = dp->color; dp->fractal_len = 2000000; } - dp->fractal_len = (dp->fractal_len * MI_BATCHCOUNT(mi)) / 20; - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + dp->fractal_len = (dp->fractal_len * MI_COUNT(mi)) / 20; + + MI_CLEARWINDOW(mi); } static void @@ -237,16 +253,29 @@ pick_df_coefs(ModeInfo * mi) r = 1e-6; for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) { - dp->df[j][k][i] = ((double) halfrandom(1000) / 500.0 - 1.0); + dp->df[j][k][i] = ((double) halfrandom(dp, 1000) / 500.0 - 1.0); r += dp->df[j][k][i] * dp->df[j][k][i]; } - r = (3 + halfrandom(5)) * 0.01 / sqrt(r); + r = (3 + halfrandom(dp, 5)) * 0.01 / sqrt(r); for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) dp->df[j][k][i] *= r; } } +static void +free_drift(driftstruct *dp) +{ + if (dp->ncpoints != NULL) { + (void) free((void *) dp->ncpoints); + dp->ncpoints = (int *) NULL; + } + if (dp->cpts != NULL) { + (void) free((void *) dp->cpts); + dp->cpts = (XPoint *) NULL; + } +} + static void initfractal(ModeInfo * mi) { @@ -257,24 +286,40 @@ initfractal(ModeInfo * mi) dp->fuse = FUSE; dp->total_points = 0; + + if (!dp->ncpoints) { + if ((dp->ncpoints = (int *) malloc(sizeof (int) * MI_NCOLORS(mi))) == + NULL) { + free_drift(dp); + return; + } + } + if (!dp->cpts) { + if ((dp->cpts = (XPoint *) malloc(MAXBATCH2 * sizeof (XPoint) * + MI_NCOLORS(mi))) == NULL) { + free_drift(dp); + return; + } + } + if (dp->rainbow) for (i = 0; i < MI_NPIXELS(mi); i++) dp->ncpoints[i] = 0; else dp->npoints = 0; - dp->nxforms = halfrandom(XFORM_LEN); + dp->nxforms = halfrandom(dp, XFORM_LEN); /* 2, 2, 2, 3, 3, 3, 4, 4, 5 */ dp->nxforms = (dp->nxforms >= XFORM_LEN - 1) + dp->nxforms / 3 + 2; dp->c = dp->x = dp->y = 0.0; - if (dp->liss && !halfrandom(10)) { + if (dp->liss && !halfrandom(dp, 10)) { dp->liss_time = 0; } if (!dp->grow) pick_df_coefs(mi); for (i = 0; i < dp->nxforms; i++) { if (NMAJORVARS == dp->major_variation) - dp->variation[i] = halfrandom(NMAJORVARS); + dp->variation[i] = halfrandom(dp, NMAJORVARS); else dp->variation[i] = dp->major_variation; for (j = 0; j < 2; j++) @@ -282,13 +327,13 @@ initfractal(ModeInfo * mi) if (dp->liss) dp->f[j][k][i] = sin(dp->liss_time * dp->df[j][k][i]); else - dp->f[j][k][i] = ((double) halfrandom(1000) / 500.0 - 1.0); + dp->f[j][k][i] = ((double) halfrandom(dp, 1000) / 500.0 - 1.0); } } if (dp->color) - dp->pixcol = MI_PIXEL(mi, halfrandom(MI_NPIXELS(mi))); + dp->pixcol = MI_PIXEL(mi, halfrandom(dp, MI_NPIXELS(mi))); else - dp->pixcol = MI_WIN_WHITE_PIXEL(mi); + dp->pixcol = MI_WHITE_PIXEL(mi); } @@ -305,26 +350,17 @@ init_drift(ModeInfo * mi) } dp = &drifts[MI_SCREEN(mi)]; - dp->width = MI_WIN_WIDTH(mi); - dp->height = MI_WIN_HEIGHT(mi); + dp->width = MI_WIDTH(mi); + dp->height = MI_HEIGHT(mi); dp->color = MI_NPIXELS(mi) > 2; - if (MI_WIN_IS_FULLRANDOM(mi)) { -#if 1 /* jwz: even up the odds */ - switch ((int) (LRAND() % 3)) { - case 0: dp->grow = True; dp->liss = False; break; - case 1: dp->grow = False; dp->liss = True; break; - default: dp->grow = False; dp->liss = False; break; - /* liss and grow don't work together. */ - } -#else /* 0 */ - if (LRAND() & 1) + if (MI_IS_FULLRANDOM(mi)) { + if (NRAND(3) == 0) dp->grow = True; else { dp->grow = False; dp->liss = (Bool) (LRAND() & 1); } -#endif } else { dp->grow = grow; if (dp->grow) @@ -339,7 +375,7 @@ init_drift(ModeInfo * mi) static void iter(driftstruct * dp) { - int i = frandom(dp->nxforms); + int i = frandom(dp, dp->nxforms); double nx, ny, nc; @@ -480,8 +516,8 @@ iter(driftstruct * dp) /* how to check nan too? some machines don't have finite(). don't need to check ny, it'll propogate */ if (nx > 1e4 || nx < -1e4) { - nx = halfrandom(1000) / 500.0 - 1.0; - ny = halfrandom(1000) / 500.0 - 1.0; + nx = halfrandom(dp, 1000) / 500.0 - 1.0; + ny = halfrandom(dp, 1000) / 500.0 - 1.0; dp->fuse = FUSE; } dp->x = nx; @@ -529,11 +565,11 @@ draw(ModeInfo * mi, driftstruct * dp, Drawable d) if (c >= npix) c = npix - 1; n = dp->ncpoints[c]; - dp->cpts[c][n].x = fixed_x; - dp->cpts[c][n].y = fixed_y; + dp->cpts[c * MAXBATCH2 + n].x = fixed_x; + dp->cpts[c * MAXBATCH2 + n].y = fixed_y; if (++dp->ncpoints[c] == MAXBATCH2) { XSetForeground(display, gc, MI_PIXEL(mi, c)); - XDrawPoints(display, d, gc, dp->cpts[c], + XDrawPoints(display, d, gc, &(dp->cpts[c * MAXBATCH2]), dp->ncpoints[c], CoordModeOrigin); dp->ncpoints[c] = 0; } @@ -553,7 +589,7 @@ draw_flush(ModeInfo * mi, driftstruct * dp, Drawable d) for (i = 0; i < npix; i++) { if (dp->ncpoints[i]) { XSetForeground(display, gc, MI_PIXEL(mi, i)); - XDrawPoints(display, d, gc, dp->cpts[i], + XDrawPoints(display, d, gc, &(dp->cpts[i * MAXBATCH2]), dp->ncpoints[i], CoordModeOrigin); dp->ncpoints[i] = 0; } @@ -572,10 +608,16 @@ void draw_drift(ModeInfo * mi) { Window window = MI_WINDOW(mi); - driftstruct *dp = &drifts[MI_SCREEN(mi)]; + driftstruct *dp; - dp->timer = 3000; + if (drifts == NULL) + return; + dp = &drifts[MI_SCREEN(mi)]; + if (dp->ncpoints == NULL) + return; + MI_IS_DRAWN(mi) = True; + dp->timer = 3000; while (dp->timer) { iter(dp); draw(mi, dp, window); @@ -587,7 +629,7 @@ draw_drift(ModeInfo * mi) sleep(4); /* #### make settable */ erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi)); #endif /* STANDALONE */ - initmode(mi, frandom(2)); + initmode(mi, frandom(dp, 2)); } initfractal(mi); } @@ -618,13 +660,19 @@ void release_drift(ModeInfo * mi) { if (drifts != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_drift(&drifts[screen]); (void) free((void *) drifts); - drifts = NULL; + drifts = (driftstruct *) NULL; } } void refresh_drift(ModeInfo * mi) { - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + MI_CLEARWINDOW(mi); } + +#endif /* MODE_drift */ diff --git a/hacks/euler2d.c b/hacks/euler2d.c new file mode 100644 index 00000000..c73b64ad --- /dev/null +++ b/hacks/euler2d.c @@ -0,0 +1,878 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* euler2d --- 2 Dimensional Incompressible Inviscid Fluid Flow */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)euler2d.c 5.00 2000/11/01 xlockmore"; + +#endif + +/* + * Copyright (c) 2000 by Stephen Montgomery-Smith + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * 04-Nov-2000: Added an option eulerpower. This allows for example the + * quasi-geostrophic equation by setting eulerpower to 2. + * 01-Nov-2000: Allocation checks. + * 10-Sep-2000: Added optimizations, and removed subtle_perturb, by stephen. + * 03-Sep-2000: Changed method of solving ode to Adams-Bashforth of order 2. + * Previously used a rather compilcated method of order 4. + * This doubles the speed of the program. Also it seems + * to have improved numerical stability. Done by stephen. + * 27-Aug-2000: Added rotation of region to maximize screen fill by stephen. + * 05-Jun-2000: Adapted from flow.c Copyright (c) 1996 by Tim Auckland + * 18-Jul-1996: Adapted from swarm.c Copyright (c) 1991 by Patrick J. Naughton. + * 31-Aug-1990: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org) + */ + +/* + * The mathematical aspects of this program are discussed in the file + * euler2d.tex. + */ + +#ifdef STANDALONE +#define MODE_euler2d +#define PROGCLASS "Euler2d" +#define HACK_INIT init_euler2d +#define HACK_DRAW draw_euler2d +#define euler2d_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ +"*count: 1024 \n" \ +"*cycles: 3000 \n" \ +"*ncolors: 64 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_euler2d + +#define DEF_EULERTAIL "10" + +#define DEBUG_POINTED_REGION 0 + +static int tail_len; +static int variable_boundary = 1; +static float power = 1; + +static XrmOptionDescRec opts[] = +{ + {(char* ) "-eulertail", (char *) ".euler2d.eulertail", + XrmoptionSepArg, (caddr_t) NULL}, + {(char* ) "-eulerpower", (char *) ".euler2d.eulerpower", + XrmoptionSepArg, (caddr_t) NULL}, +}; +static argtype vars[] = +{ + {(caddr_t *) &tail_len, (char *) "eulertail", + (char *) "EulerTail", (char *) DEF_EULERTAIL, t_Int}, + {(caddr_t *) &power, (char *) "eulerpower", + (char *) "EulerPower", (char *) "1", t_Float}, +}; +static OptionStruct desc[] = +{ + {(char *) "-eulertail len", (char *) "Length of Euler2d tails"}, + {(char *) "-eulerpower power", (char *) "power of interaction law for points for Euler2d"}, +}; + +ModeSpecOpt euler2d_opts = +{sizeof opts / sizeof opts[0], opts, + sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct euler2d_description = { + "euler2d", "init_euler2d", "draw_euler2d", "release_euler2d", + "refresh_euler2d", "init_euler2d", (char *) NULL, &euler2d_opts, + 1000, 1024, 3000, 1, 64, 1.0, "", + "Simulates 2D incompressible invisid fluid.", 0, NULL +}; + +#endif + +#define balance_rand(v) ((LRAND()/MAXRAND*(v))-((v)/2)) /* random around 0 */ +#define positive_rand(v) (LRAND()/MAXRAND*(v)) /* positive random */ + +#define number_of_vortex_points 20 + +#define n_bound_p 500 +#define deg_p 6 + +static double delta_t; + +typedef struct { + int width; + int height; + int count; + double xshift,yshift,scale; + double radius; + + int N; + int Nvortex; + +/* x[2i+0] = x coord for nth point + x[2i+1] = y coord for nth point + w[i] = vorticity at nth point +*/ + double *x; + double *w; + + double *diffx; + double *olddiffx; + double *tempx; + double *tempdiffx; +/* (xs[2i+0],xs[2i+1]) is reflection of (x[2i+0],x[2i+1]) about unit circle + xs[2i+0] = x[2i+0]/nx + xs[2i+1] = x[2i+1]/nx + where + nx = x[2i+0]*x[2i+0] + x[2i+1]*x[2i+1] + + x_is_zero[i] = (nx < 1e-10) +*/ + double *xs; + short *x_is_zero; + +/* (p[2i+0],p[2i+1]) is image of (x[2i+0],x[2i+1]) under polynomial p. + mod_dp2 is |p'(z)|^2 when z = (x[2i+0],x[2i+1]). +*/ + double *p; + double *mod_dp2; + +/* Sometimes in our calculations we get overflow or numbers that are too big. + If that happens with the point x[2*i+0], x[2*i+1], we set dead[i]. +*/ + short *dead; + + XSegment *csegs; + int cnsegs; + XSegment *old_segs; + int *nold_segs; + int c_old_seg; + int boundary_color; + int hide_vortex; + short *lastx; + + double p_coef[2*(deg_p-1)]; + XSegment *boundary; + +} euler2dstruct; + +static euler2dstruct *euler2ds = (euler2dstruct *) NULL; + +/* + If variable_boundary == 1, then we make a variable boundary. + The way this is done is to map the unit disk under a + polynomial p, where + p(z) = z + c_2 z^2 + ... + c_n z^n + where n = deg_p. sp->p_coef contains the complex numbers + c_2, c_3, ... c_n. +*/ + +#define add(a1,a2,b1,b2) (a1)+=(b1);(a2)+=(b2) +#define mult(a1,a2,b1,b2) temp=(a1)*(b1)-(a2)*(b2); \ + (a2)=(a1)*(b2)+(a2)*(b1);(a1)=temp + +static void +calc_p(double *p1, double *p2, double z1, double z2, double p_coef[]) +{ + int i; + double temp; + + *p1=0; + *p2=0; + for(i=deg_p;i>=2;i--) + { + add(*p1,*p2,p_coef[(i-2)*2],p_coef[(i-2)*2+1]); + mult(*p1,*p2,z1,z2); + } + add(*p1,*p2,1,0); + mult(*p1,*p2,z1,z2); +} + +/* Calculate |p'(z)|^2 */ +static double +calc_mod_dp2(double z1, double z2, double p_coef[]) +{ + int i; + double temp,mp1,mp2; + + mp1=0; + mp2=0; + for(i=deg_p;i>=2;i--) + { + add(mp1,mp2,i*p_coef[(i-2)*2],i*p_coef[(i-2)*2+1]); + mult(mp1,mp2,z1,z2); + } + add(mp1,mp2,1,0); + return mp1*mp1+mp2*mp2; +} + +static void +calc_all_p(euler2dstruct *sp) +{ + int i,j; + double temp,p1,p2,z1,z2; + for(j=(sp->hide_vortex?sp->Nvortex:0);jN;j++) if(!sp->dead[j]) + { + p1=0; + p2=0; + z1=sp->x[2*j+0]; + z2=sp->x[2*j+1]; + for(i=deg_p;i>=2;i--) + { + add(p1,p2,sp->p_coef[(i-2)*2],sp->p_coef[(i-2)*2+1]); + mult(p1,p2,z1,z2); + } + add(p1,p2,1,0); + mult(p1,p2,z1,z2); + sp->p[2*j+0] = p1; + sp->p[2*j+1] = p2; + } +} + +static void +calc_all_mod_dp2(double *x, euler2dstruct *sp) +{ + int i,j; + double temp,mp1,mp2,z1,z2; + for(j=0;jN;j++) if(!sp->dead[j]) + { + mp1=0; + mp2=0; + z1=x[2*j+0]; + z2=x[2*j+1]; + for(i=deg_p;i>=2;i--) + { + add(mp1,mp2,i*sp->p_coef[(i-2)*2],i*sp->p_coef[(i-2)*2+1]); + mult(mp1,mp2,z1,z2); + } + add(mp1,mp2,1,0); + sp->mod_dp2[j] = mp1*mp1+mp2*mp2; + } +} + +static void +derivs(double *x, euler2dstruct *sp) +{ + int i,j; + double u1,u2,x1,x2,xij1,xij2,nxij; + double nx; + + if (variable_boundary) + calc_all_mod_dp2(sp->x,sp); + + for (j=0;jNvortex;j++) if (!sp->dead[j]) + { + nx = x[2*j+0]*x[2*j+0] + x[2*j+1]*x[2*j+1]; + if (nx < 1e-10) + sp->x_is_zero[j] = 1; + else { + sp->x_is_zero[j] = 0; + sp->xs[2*j+0] = x[2*j+0]/nx; + sp->xs[2*j+1] = x[2*j+1]/nx; + } + } + + (void) memset(sp->diffx,0,sizeof(double)*2*sp->N); + + for (i=0;iN;i++) if (!sp->dead[i]) + { + x1 = x[2*i+0]; + x2 = x[2*i+1]; + for (j=0;jNvortex;j++) if (!sp->dead[j]) + { +/* + Calculate the Biot-Savart kernel, that is, effect of a + vortex point at a = (x[2*j+0],x[2*j+1]) at the point + x = (x1,x2), returning the vector field in (u1,u2). + + In the plane, this is given by the formula + + u = (x-a)/|x-a|^2 or zero if x=a. + + However, in the unit disk we have to subtract from the + above: + + (x-as)/|x-as|^2 + + where as = a/|a|^2 is the reflection of a about the unit circle. + + If however power != 1, then + + u = (x-a)/|x-a|^(power+1) - |a|^(1-power) (x-as)/|x-as|^(power+1) + +*/ + + xij1 = x1 - x[2*j+0]; + xij2 = x2 - x[2*j+1]; + nxij = (power==1.0) ? xij1*xij1+xij2*xij2 : pow(xij1*xij1+xij2*xij2,(power+1)/2.0); + + if(nxij >= 1e-4) { + u1 = xij2/nxij; + u2 = -xij1/nxij; + } + else + u1 = u2 = 0.0; + + if (!sp->x_is_zero[j]) + { + xij1 = x1 - sp->xs[2*j+0]; + xij2 = x2 - sp->xs[2*j+1]; + nxij = (power==1.0) ? xij1*xij1+xij2*xij2 : pow(xij1*xij1+xij2*xij2,(power+1)/2.0); + + if (nxij < 1e-5) + { + sp->dead[i] = 1; + u1 = u2 = 0.0; + } + else + { + u1 -= xij2/nxij; + u2 += xij1/nxij; + } + } + + if (!sp->dead[i]) + { + sp->diffx[2*i+0] += u1*sp->w[j]; + sp->diffx[2*i+1] += u2*sp->w[j]; + } + } + + if (!sp->dead[i] && variable_boundary) + { + if (sp->mod_dp2[i] < 1e-5) + sp->dead[i] = 1; + else + { + sp->diffx[2*i+0] /= sp->mod_dp2[i]; + sp->diffx[2*i+1] /= sp->mod_dp2[i]; + } + } + } +} + +/* + What perturb does is effectively + ret = x + k, + where k should be of order delta_t. + + We have the option to do this more subtly by mapping points x + in the unit disk to points y in the plane, where y = f(|x|) x, + with f(t) = -log(1-t)/t. + + This might reduce (but does not remove) problems where particles near + the edge of the boundary bounce around. + + But it seems to be not that effective, so for now switch it off. +*/ + +#define SUBTLE_PERTURB 0 + +static void +perturb(double ret[], double x[], double k[], euler2dstruct *sp) +{ + int i; + double x1,x2,k1,k2; + +#if SUBTLE_PERTURB + double d1,d2,t1,t2,mag,mag2,mlog1mmag,memmagdmag,xdotk; + for (i=0;iN;i++) if (!sp->dead[i]) + { + x1 = x[2*i+0]; + x2 = x[2*i+1]; + k1 = k[2*i+0]; + k2 = k[2*i+1]; + mag2 = x1*x1 + x2*x2; + if (mag2 < 1e-10) + { + ret[2*i+0] = x1+k1; + ret[2*i+1] = x2+k2; + } + else if (mag2 > 1-1e-5) + sp->dead[i] = 1; + else + { + mag = sqrt(mag2); + mlog1mmag = -log(1-mag); + xdotk = x1*k1 + x2*k2; + t1 = (x1 + k1)*mlog1mmag/mag + x1*xdotk*(1.0/(1-mag)-mlog1mmag/mag)/mag/mag; + t2 = (x2 + k2)*mlog1mmag/mag + x2*xdotk*(1.0/(1-mag)-mlog1mmag/mag)/mag/mag; + mag = sqrt(t1*t1+t2*t2); + if (mag > 11.5 /* log(1e5) */) + sp->dead[i] = 1; + else + { + memmagdmag = (mag>1e-5) ? ((1.0-exp(-mag))/mag) : (1-mag/2.0); + ret[2*i+0] = t1*memmagdmag; + ret[2*i+1] = t2*memmagdmag; + } + } + if (!sp->dead[i]) + { + d1 = ret[2*i+0]-x1; + d2 = ret[2*i+1]-x2; + if (d1*d1+d2*d2 > 0.1) + sp->dead[i] = 1; + } + } + +#else + + for (i=0;iN;i++) if (!sp->dead[i]) + { + x1 = x[2*i+0]; + x2 = x[2*i+1]; + k1 = k[2*i+0]; + k2 = k[2*i+1]; + if (k1*k1+k2*k2 > 0.1 || x1*x1+x2*x2 > 1-1e-5) + sp->dead[i] = 1; + else + { + ret[2*i+0] = x1+k1; + ret[2*i+1] = x2+k2; + } + } +#endif +} + +static void +ode_solve(euler2dstruct *sp) +{ + int i; + double *temp; + + if (sp->count < 1) { + /* midpoint method */ + derivs(sp->x,sp); + (void) memcpy(sp->olddiffx,sp->diffx,sizeof(double)*2*sp->N); + for (i=0;iN;i++) if (!sp->dead[i]) { + sp->tempdiffx[2*i+0] = 0.5*delta_t*sp->diffx[2*i+0]; + sp->tempdiffx[2*i+1] = 0.5*delta_t*sp->diffx[2*i+1]; + } + perturb(sp->tempx,sp->x,sp->tempdiffx,sp); + derivs(sp->tempx,sp); + for (i=0;iN;i++) if (!sp->dead[i]) { + sp->tempdiffx[2*i+0] = delta_t*sp->diffx[2*i+0]; + sp->tempdiffx[2*i+1] = delta_t*sp->diffx[2*i+1]; + } + perturb(sp->x,sp->x,sp->tempdiffx,sp); + } else { + /* Adams Basforth */ + derivs(sp->x,sp); + for (i=0;iN;i++) if (!sp->dead[i]) { + sp->tempdiffx[2*i+0] = delta_t*(1.5*sp->diffx[2*i+0] - 0.5*sp->olddiffx[2*i+0]); + sp->tempdiffx[2*i+1] = delta_t*(1.5*sp->diffx[2*i+1] - 0.5*sp->olddiffx[2*i+1]); + } + perturb(sp->x,sp->x,sp->tempdiffx,sp); + temp = sp->olddiffx; + sp->olddiffx = sp->diffx; + sp->diffx = temp; + } +} + +#define deallocate(p,t) if (p!=NULL) {(void) free((void *) p); p=(t*)NULL; } +#define allocate(p,t,s) if ((p=(t*)malloc(sizeof(t)*s))==NULL)\ +{free_euler2d(sp);return;} + +static void +free_euler2d(euler2dstruct *sp) +{ + deallocate(sp->csegs, XSegment); + deallocate(sp->old_segs, XSegment); + deallocate(sp->nold_segs, int); + deallocate(sp->lastx, short); + deallocate(sp->x, double); + deallocate(sp->diffx, double); + deallocate(sp->w, double); + deallocate(sp->olddiffx, double); + deallocate(sp->tempdiffx, double); + deallocate(sp->tempx, double); + deallocate(sp->dead, short); + deallocate(sp->boundary, XSegment); + deallocate(sp->xs, double); + deallocate(sp->x_is_zero, short); + deallocate(sp->p, double); + deallocate(sp->mod_dp2, double); +} + +void +init_euler2d(ModeInfo * mi) +{ +#define nr_rotates 18 /* how many rotations to try to fill as much of screen as possible - must be even number */ + euler2dstruct *sp; + int i,k,n,np; + double r,theta,x,y,w; + double mag,xscale,yscale,p1,p2; + double low[nr_rotates],high[nr_rotates],pp1,pp2,pn1,pn2,angle1,angle2,tempangle,dist,scale,bestscale,temp; + int besti = 0; + + if (power<0.5) power = 0.5; + if (power>3.0) power = 3.0; + variable_boundary &= power == 1.0; + delta_t = 0.001; + if (power>1.0) delta_t *= pow(0.1,power-1); + + if (euler2ds == NULL) { + if ((euler2ds = (euler2dstruct *) calloc(MI_NUM_SCREENS(mi), + sizeof (euler2dstruct))) == NULL) + return; + } + sp = &euler2ds[MI_SCREEN(mi)]; + + sp->boundary_color = NRAND(MI_NPIXELS(mi)); + sp->hide_vortex = NRAND(4) != 0; + + sp->count = 0; + + sp->width = MI_WIDTH(mi); + sp->height = MI_HEIGHT(mi); + + sp->N = MI_COUNT(mi)+number_of_vortex_points; + sp->Nvortex = number_of_vortex_points; + + if (tail_len < 1) { /* minimum tail */ + tail_len = 1; + } + if (tail_len > MI_CYCLES(mi)) { /* maximum tail */ + tail_len = MI_CYCLES(mi); + } + + /* Clear the background. */ + MI_CLEARWINDOW(mi); + + free_euler2d(sp); + + /* Allocate memory. */ + + if (sp->csegs == NULL) { + allocate(sp->csegs, XSegment, sp->N); + allocate(sp->old_segs, XSegment, sp->N * tail_len); + allocate(sp->nold_segs, int, tail_len); + allocate(sp->lastx, short, sp->N * 2); + allocate(sp->x, double, sp->N * 2); + allocate(sp->diffx, double, sp->N * 2); + allocate(sp->w, double, sp->Nvortex); + allocate(sp->olddiffx, double, sp->N * 2); + allocate(sp->tempdiffx, double, sp->N * 2); + allocate(sp->tempx, double, sp->N * 2); + allocate(sp->dead, short, sp->N); + allocate(sp->boundary, XSegment, n_bound_p); + allocate(sp->xs, double, sp->Nvortex * 2); + allocate(sp->x_is_zero, short, sp->Nvortex); + allocate(sp->p, double, sp->N * 2); + allocate(sp->mod_dp2, double, sp->N); + } + for (i=0;inold_segs[i] = 0; + } + sp->c_old_seg = 0; + (void) memset(sp->dead,0,sp->N*sizeof(short)); + + if (variable_boundary) + { + /* Initialize polynomial p */ +/* + The polynomial p(z) = z + c_2 z^2 + ... c_n z^n needs to be + a bijection of the unit disk onto its image. This is achieved + by insisting that sum_{k=2}^n k |c_k| <= 1. Actually we set + the inequality to be equality (to get more interesting shapes). +*/ + mag = 0; + for(k=2;k<=deg_p;k++) + { + r = positive_rand(1.0/k); + theta = balance_rand(2*M_PI); + sp->p_coef[2*(k-2)+0]=r*cos(theta); + sp->p_coef[2*(k-2)+1]=r*sin(theta); + mag += k*r; + } + if (mag > 0.0001) for(k=2;k<=deg_p;k++) + { + sp->p_coef[2*(k-2)+0] /= mag; + sp->p_coef[2*(k-2)+1] /= mag; + } + +#if DEBUG_POINTED_REGION + for(k=2;k<=deg_p;k++){ + sp->p_coef[2*(k-2)+0]=0; + sp->p_coef[2*(k-2)+1]=0; + } + sp->p_coef[2*(6-2)+0] = 1.0/6.0; +#endif + + +/* Here we figure out the best rotation of the domain so that it fills as + much of the screen as possible. The number of angles we look at is determined + by nr_rotates (we look every 180/nr_rotates degrees). + While we figure out the best angle to rotate, we also figure out the correct scaling factors. +*/ + + for(k=0;kp_coef); + calc_p(&pp1,&pp2,cos((double)(k-1)/(n_bound_p)*2*M_PI),sin((double)(k-1)/(n_bound_p)*2*M_PI),sp->p_coef); + calc_p(&pn1,&pn2,cos((double)(k+1)/(n_bound_p)*2*M_PI),sin((double)(k+1)/(n_bound_p)*2*M_PI),sp->p_coef); + angle1 = nr_rotates/M_PI*atan2(p2-pp2,p1-pp1)-nr_rotates/2; + angle2 = nr_rotates/M_PI*atan2(pn2-p2,pn1-p1)-nr_rotates/2; + while (angle1<0) angle1+=nr_rotates*2; + while (angle2<0) angle2+=nr_rotates*2; + if (angle1>nr_rotates*1.75 && angle2nr_rotates*1.75) angle1+=nr_rotates*2; + if (angle2high[i%nr_rotates]) high[i%nr_rotates] = dist; + if (disthigh[i%nr_rotates]) high[i%nr_rotates] = -dist; + if (-distwidth-5.0)/(high[i]-low[i]); + yscale = (sp->height-5.0)/(high[(i+nr_rotates/2)%nr_rotates]-low[(i+nr_rotates/2)%nr_rotates]); + scale = (xscale>yscale) ? yscale : xscale; + if (scale>bestscale) { + bestscale = scale; + besti = i; + } + } +/* Here we do the rotation. The way we do this is to replace the + polynomial p(z) by a^{-1} p(a z) where a = exp(i best_angle). +*/ + p1 = 1; + p2 = 0; + for(k=2;k<=deg_p;k++) + { + mult(p1,p2,cos((double)besti*M_PI/nr_rotates),sin((double)besti*M_PI/nr_rotates)); + mult(sp->p_coef[2*(k-2)+0],sp->p_coef[2*(k-2)+1],p1,p2); + } + + sp->scale = bestscale; + sp->xshift = -(low[besti]+high[besti])/2.0*sp->scale+sp->width/2; + if (bestiyshift = -(low[besti+nr_rotates/2]+high[besti+nr_rotates/2])/2.0*sp->scale+sp->height/2; + else + sp->yshift = (low[besti-nr_rotates/2]+high[besti-nr_rotates/2])/2.0*sp->scale+sp->height/2; + + +/* Initialize boundary */ + + for(k=0;kp_coef); + sp->boundary[k].x1 = (short)(p1*sp->scale+sp->xshift); + sp->boundary[k].y1 = (short)(p2*sp->scale+sp->yshift); + } + for(k=1;kboundary[k].x2 = sp->boundary[k-1].x1; + sp->boundary[k].y2 = sp->boundary[k-1].y1; + } + sp->boundary[0].x2 = sp->boundary[n_bound_p-1].x1; + sp->boundary[0].y2 = sp->boundary[n_bound_p-1].y1; + } + else + { + if (sp->width>sp->height) + sp->radius = sp->height/2.0-5.0; + else + sp->radius = sp->width/2.0-5.0; + } + + /* Initialize point positions */ + + for (i=sp->Nvortex;iN;i++) { + do { + r = sqrt(positive_rand(1.0)); + theta = balance_rand(2*M_PI); + sp->x[2*i+0]=r*cos(theta); + sp->x[2*i+1]=r*sin(theta); + /* This is to make sure the initial distribution of points is uniform */ + } while (variable_boundary && + calc_mod_dp2(sp->x[2*i+0],sp->x[2*i+1],sp->p_coef) + < positive_rand(4)); + } + + n = NRAND(4)+2; + /* number of vortex points with negative vorticity */ + if (n%2) { + np = NRAND(n+1); + } + else { + /* if n is even make sure that np==n/2 is twice as likely + as the other possibilities. */ + np = NRAND(n+2); + if (np==n+1) np=n/2; + } + for(k=0;kNvortex; + for (i=sp->Nvortex*k/n;iNvortex*(k+1)/n;i++) { + theta = balance_rand(2*M_PI); + sp->x[2*i+0]=x + r*cos(theta); + sp->x[2*i+1]=y + r*sin(theta); + sp->w[i]=w; + } + } +} + +void +draw_euler2d(ModeInfo * mi) +{ + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + int b, col, n_non_vortex_segs; + euler2dstruct *sp; + + MI_IS_DRAWN(mi) = True; + + if (euler2ds == NULL) + return; + sp = &euler2ds[MI_SCREEN(mi)]; + if (sp->csegs == NULL) + return; + + ode_solve(sp); + if (variable_boundary) + calc_all_p(sp); + + sp->cnsegs = 0; + for(b=sp->Nvortex;bN;b++) if(!sp->dead[b]) + { + sp->csegs[sp->cnsegs].x1 = sp->lastx[2*b+0]; + sp->csegs[sp->cnsegs].y1 = sp->lastx[2*b+1]; + if (variable_boundary) + { + sp->csegs[sp->cnsegs].x2 = (short)(sp->p[2*b+0]*sp->scale+sp->xshift); + sp->csegs[sp->cnsegs].y2 = (short)(sp->p[2*b+1]*sp->scale+sp->yshift); + } + else + { + sp->csegs[sp->cnsegs].x2 = (short)(sp->x[2*b+0]*sp->radius+sp->width/2); + sp->csegs[sp->cnsegs].y2 = (short)(sp->x[2*b+1]*sp->radius+sp->height/2); + } + sp->lastx[2*b+0] = sp->csegs[sp->cnsegs].x2; + sp->lastx[2*b+1] = sp->csegs[sp->cnsegs].y2; + sp->cnsegs++; + } + n_non_vortex_segs = sp->cnsegs; + + if (!sp->hide_vortex) for(b=0;bNvortex;b++) if(!sp->dead[b]) + { + sp->csegs[sp->cnsegs].x1 = sp->lastx[2*b+0]; + sp->csegs[sp->cnsegs].y1 = sp->lastx[2*b+1]; + if (variable_boundary) + { + sp->csegs[sp->cnsegs].x2 = (short)(sp->p[2*b+0]*sp->scale+sp->xshift); + sp->csegs[sp->cnsegs].y2 = (short)(sp->p[2*b+1]*sp->scale+sp->yshift); + } + else + { + sp->csegs[sp->cnsegs].x2 = (short)(sp->x[2*b+0]*sp->radius+sp->width/2); + sp->csegs[sp->cnsegs].y2 = (short)(sp->x[2*b+1]*sp->radius+sp->height/2); + } + sp->lastx[2*b+0] = sp->csegs[sp->cnsegs].x2; + sp->lastx[2*b+1] = sp->csegs[sp->cnsegs].y2; + sp->cnsegs++; + } + + if (sp->count) { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + + XDrawSegments(display, window, gc, sp->old_segs+sp->c_old_seg*sp->N, sp->nold_segs[sp->c_old_seg]); + + if (MI_NPIXELS(mi) > 2){ /* render colour */ + for (col = 0; col < MI_NPIXELS(mi); col++) { + int start = col*n_non_vortex_segs/MI_NPIXELS(mi); + int finish = (col+1)*n_non_vortex_segs/MI_NPIXELS(mi); + XSetForeground(display, gc, MI_PIXEL(mi, col)); + XDrawSegments(display, window, gc,sp->csegs+start, finish-start); + } + if (!sp->hide_vortex) { + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + XDrawSegments(display, window, gc,sp->csegs+n_non_vortex_segs, sp->cnsegs-n_non_vortex_segs); + } + + } else { /* render mono */ + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + XDrawSegments(display, window, gc, + sp->csegs, sp->cnsegs); + } + + if (MI_NPIXELS(mi) > 2) /* render colour */ + XSetForeground(display, gc, MI_PIXEL(mi, sp->boundary_color)); + else + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); + if (variable_boundary) + XDrawSegments(display, window, gc, + sp->boundary, n_bound_p); + else + XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + sp->width/2 - (int) sp->radius - 1, sp->height/2 - (int) sp->radius -1, + (int) (2*sp->radius) + 2, (int) (2* sp->radius) + 2, 0, 64*360); + + /* Copy to erase-list */ + (void) memcpy(sp->old_segs+sp->c_old_seg*sp->N, sp->csegs, sp->cnsegs*sizeof(XSegment)); + sp->nold_segs[sp->c_old_seg] = sp->cnsegs; + sp->c_old_seg++; + if (sp->c_old_seg >= tail_len) + sp->c_old_seg = 0; + } + + if (++sp->count > MI_CYCLES(mi)) /* pick a new flow */ + init_euler2d(mi); + +} + +void +release_euler2d(ModeInfo * mi) +{ + if (euler2ds != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_euler2d(&euler2ds[screen]); + (void) free((void *) euler2ds); + euler2ds = (euler2dstruct *) NULL; + } +} + +void +refresh_euler2d(ModeInfo * mi) +{ + MI_CLEARWINDOW(mi); +} + +#endif /* MODE_euler2d */ diff --git a/hacks/fadeplot.c b/hacks/fadeplot.c index 5b715522..ad48b710 100644 --- a/hacks/fadeplot.c +++ b/hacks/fadeplot.c @@ -1,12 +1,15 @@ -/* -*- Mode: C; tab-width: 4 -*- - * fadeplot.c --- some easy plotting stuff, by Bas van Gaalen, Holland, PD - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* fadeplot --- a fading plot of sine squared */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)fadeplot.c 4.04 97/07/26 xlockmore"; +static const char sccsid[] = "@(#)fadeplot.c 5.00 2000/11/01 xlockmore"; + #endif -/* Converted for xlock by Charles Vidal - * See xlock.c for copying information. +/*- + * Some easy plotting stuff, by Bas van Gaalen, Holland, PD + * + * Copyright (c) 1996 by Charles Vidal * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -19,34 +22,46 @@ static const char sccsid[] = "@(#)fadeplot.c 4.04 97/07/26 xlockmore"; * 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. - */ - -/*- - 1) Not random enough, i.e. always same starting position. - 2) Needs to be less flashy + * + * Revision History: + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with screensaver + * 1996: Written by Charles Vidal based on work by Bas van Gaalen */ #ifdef STANDALONE -# define PROGCLASS "Fadeplot" -# define HACK_INIT init_fadeplot -# define HACK_DRAW draw_fadeplot -# define fadeplot_opts xlockmore_opts -# define DEFAULTS "*count: 10 \n" \ - "*delay: 30000 \n" \ - "*cycles: 1500 \n" \ - "*ncolors: 64 \n" -# define BRIGHT_COLORS -# define UNIFORM_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ +#define MODE_fadeplot +#define PROGCLASS "Fadeplot" +#define HACK_INIT init_fadeplot +#define HACK_DRAW draw_fadeplot +#define fadeplot_opts xlockmore_opts +#define DEFAULTS "*delay: 30000 \n" \ + "*count: 10 \n" \ + "*cycles: 1500 \n" \ + "*ncolors: 64 \n" +#define BRIGHT_COLORS +#define UNIFORM_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ +#include "xlock.h" /* in xlockmore distribution */ + #endif /* STANDALONE */ -ModeSpecOpt fadeplot_opts = { - 0, NULL, 0, NULL, NULL }; +#ifdef MODE_fadeplot + +ModeSpecOpt fadeplot_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct fadeplot_description = +{"fadeplot", "init_fadeplot", "draw_fadeplot", "release_fadeplot", + "refresh_fadeplot", "init_fadeplot", (char *) NULL, &fadeplot_opts, + 30000, 10, 1500, 1, 64, 0.6, "", + "Shows a fading plot of sine squared", 0, NULL}; + +#endif #define MINSTEPS 1 -#define ANGLES 1000 typedef struct { XPoint speed, step, factor, st; @@ -54,23 +69,43 @@ typedef struct { int min; int width, height; int pix; - int stab[ANGLES]; + int angles; + int *stab; XPoint *pts; } fadeplotstruct; -static fadeplotstruct *fadeplots = NULL; +static fadeplotstruct *fadeplots = (fadeplotstruct *) NULL; static void +free_fadeplot(fadeplotstruct *fp) +{ + if (fp->pts != NULL) { + (void) free((void *) fp->pts); + fp->pts = (XPoint *) NULL; + } + if (fp->stab != NULL) { + (void) free((void *) fp->stab); + fp->stab = (int *) NULL; + } +} + +static Bool initSintab(ModeInfo * mi) { fadeplotstruct *fp = &fadeplots[MI_SCREEN(mi)]; int i; float x; - for (i = 0; i < ANGLES; i++) { - x = SINF(i * 2 * M_PI / ANGLES); + fp->angles = NRAND(950) + 250; + if ((fp->stab = (int *) malloc(fp->angles * sizeof (int))) == NULL) { + free_fadeplot(fp); + return False; + } + for (i = 0; i < fp->angles; i++) { + x = SINF(2.0 * M_PI * i / fp->angles); fp->stab[i] = (int) (x * ABS(x) * fp->min) + fp->min; } + return True; } void @@ -85,9 +120,9 @@ init_fadeplot(ModeInfo * mi) } fp = &fadeplots[MI_SCREEN(mi)]; - fp->width = MI_WIN_WIDTH(mi); - fp->height = MI_WIN_HEIGHT(mi); - fp->min = MAX(MIN(fp->width, fp->height) / 2, 1); + fp->width = MI_WIDTH(mi); + fp->height = MI_HEIGHT(mi); + fp->min = MAX(MIN(fp->width, fp->height) / 2, 1); fp->speed.x = 8; fp->speed.y = 10; @@ -97,37 +132,50 @@ init_fadeplot(ModeInfo * mi) fp->factor.x = MAX(fp->width / (2 * fp->min), 1); fp->factor.y = MAX(fp->height / (2 * fp->min), 1); - fp->nbstep = MI_BATCHCOUNT(mi); + fp->nbstep = MI_COUNT(mi); if (fp->nbstep < -MINSTEPS) { fp->nbstep = NRAND(-fp->nbstep - MINSTEPS + 1) + MINSTEPS; } else if (fp->nbstep < MINSTEPS) fp->nbstep = MINSTEPS; - fp->maxpts = MI_CYCLES(mi); - if (fp->maxpts < 1) - fp->maxpts = 1; + fp->maxpts = MI_CYCLES(mi); + if (fp->maxpts < 1) + fp->maxpts = 1; - if (fp->pts == NULL) - fp->pts = (XPoint *) calloc(fp->maxpts, sizeof (XPoint)); + if (fp->pts == NULL) { + if ((fp->pts = (XPoint *) calloc(fp->maxpts, sizeof (XPoint))) == + NULL) { + free_fadeplot(fp); + return; + } + } if (MI_NPIXELS(mi) > 2) fp->pix = NRAND(MI_NPIXELS(mi)); - initSintab(mi); - - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + if (fp->stab != NULL) + (void) free((void *) fp->stab); + if (!initSintab(mi)) + return; + MI_CLEARWINDOW(mi); } void draw_fadeplot(ModeInfo * mi) { - fadeplotstruct *fp = &fadeplots[MI_SCREEN(mi)]; Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); - int i, j; - long temp; + int i, j, temp; + fadeplotstruct *fp; - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + if (fadeplots == NULL) + return; + fp = &fadeplots[MI_SCREEN(mi)]; + if (fp->stab == NULL) + return; + + MI_IS_DRAWN(mi) = True; + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); XDrawPoints(display, window, gc, fp->pts, fp->maxpts, CoordModeOrigin); if (MI_NPIXELS(mi) > 2) { @@ -135,43 +183,54 @@ draw_fadeplot(ModeInfo * mi) if (++fp->pix >= MI_NPIXELS(mi)) fp->pix = 0; } else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); - - for (temp = fp->nbstep - 1; temp >= 0; temp--) { - j = temp; - for (i = 0; i < fp->maxpts / fp->nbstep; i++) { - fp->pts[temp * i + i].x = - fp->stab[(fp->st.x + fp->speed.x * j + i * fp->step.x) % ANGLES] * - fp->factor.x + fp->width / 2 - fp->min; - fp->pts[temp * i + i].y = - fp->stab[(fp->st.y + fp->speed.y * j + i * fp->step.y) % ANGLES] * - fp->factor.y + fp->height / 2 - fp->min; - } + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + + temp = 0; + for (j = 0; j < fp->nbstep; j++) { + for (i = 0; i < fp->maxpts / fp->nbstep; i++) { + fp->pts[temp].x = + fp->stab[(fp->st.x + fp->speed.x * j + i * fp->step.x) % fp->angles] * + fp->factor.x + fp->width / 2 - fp->min; + fp->pts[temp].y = + fp->stab[(fp->st.y + fp->speed.y * j + i * fp->step.y) % fp->angles] * + fp->factor.y + fp->height / 2 - fp->min; + temp++; } - XDrawPoints(display, window, gc, fp->pts, fp->maxpts, CoordModeOrigin); + } + XDrawPoints(display, window, gc, fp->pts, temp, CoordModeOrigin); XFlush(display); - fp->st.x = (fp->st.x + fp->speed.x) % ANGLES; - fp->st.y = (fp->st.y + fp->speed.y) % ANGLES; + fp->st.x = (fp->st.x + fp->speed.x) % fp->angles; + fp->st.y = (fp->st.y + fp->speed.y) % fp->angles; fp->temps++; - if ((fp->temps % (ANGLES / 2)) == 0) { - fp->temps = fp->temps % ANGLES * 5; - if ((fp->temps % (ANGLES)) == 0) + if ((fp->temps % (fp->angles / 2)) == 0) { + fp->temps = fp->temps % fp->angles * 5; + if ((fp->temps % (fp->angles)) == 0) fp->speed.y = (fp->speed.y++) % 30 + 1; - if ((fp->temps % (ANGLES * 2)) == 0) + if ((fp->temps % (fp->angles * 2)) == 0) fp->speed.x = (fp->speed.x) % 20; - if ((fp->temps % (ANGLES * 3)) == 0) + if ((fp->temps % (fp->angles * 3)) == 0) fp->step.y = (fp->step.y++) % 2 + 1; - XClearWindow(display, window); + + MI_CLEARWINDOW(mi); } } void refresh_fadeplot(ModeInfo * mi) { - + MI_CLEARWINDOW(mi); } void release_fadeplot(ModeInfo * mi) { - /* Do nothing, it will refresh by itself */ + if (fadeplots != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_fadeplot(&fadeplots[screen]); + (void) free((void *) fadeplots); + fadeplots = (fadeplotstruct *) NULL; + } } + +#endif /* MODE_fadeplot */ diff --git a/hacks/flag.c b/hacks/flag.c index 2ed9296e..41311f4a 100644 --- a/hacks/flag.c +++ b/hacks/flag.c @@ -48,20 +48,7 @@ static const char sccsid[] = "@(#)flag.c 4.02 97/04/01 xlockmore"; # define DEF_TEXT "" # include "xlockmore.h" /* from the xscreensaver distribution */ -# ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -# endif - -#ifdef HAVE_XMU -# ifndef VMS -# include -# else /* VMS */ -# include -# endif /* VMS */ -#endif /* HAVE_XMU */ +#include "xpm-pixmap.h" #include "images/bob.xbm" @@ -219,100 +206,18 @@ make_flag_bits(ModeInfo *mi) *bitmap_name && !!strcmp(bitmap_name, "(default)")) { -#ifdef HAVE_XPM - Window window = MI_WINDOW(mi); - XWindowAttributes xgwa; - XpmAttributes xpmattrs; - int result; Pixmap bitmap = 0; - int width = 0, height = 0; - xpmattrs.valuemask = 0; - - XGetWindowAttributes (dpy, window, &xgwa); - -# ifdef XpmCloseness - xpmattrs.valuemask |= XpmCloseness; - xpmattrs.closeness = 40000; -# endif -# ifdef XpmVisual - xpmattrs.valuemask |= XpmVisual; - xpmattrs.visual = xgwa.visual; -# endif -# ifdef XpmDepth - xpmattrs.valuemask |= XpmDepth; - xpmattrs.depth = xgwa.depth; -# endif -# ifdef XpmColormap - xpmattrs.valuemask |= XpmColormap; - xpmattrs.colormap = xgwa.colormap; -# endif - - /* Uh, we don't need these now. We use the colors from the xpm. - It kinda sucks that we already allocated them. */ - XFreeColors(dpy, xgwa.colormap, mi->pixels, mi->npixels, 0L); - - result = XpmReadFileToPixmap (dpy, window, bitmap_name, &bitmap, 0, - &xpmattrs); - switch (result) - { - case XpmColorError: - fprintf (stderr, "%s: warning: xpm color substitution performed\n", - progname); - /* fall through */ - case XpmSuccess: - width = xpmattrs.width; - height = xpmattrs.height; - break; - case XpmFileInvalid: - case XpmOpenFailed: - bitmap = 0; - break; - case XpmColorFailed: - fprintf (stderr, "%s: xpm: color allocation failed\n", progname); - exit (-1); - case XpmNoMemory: - fprintf (stderr, "%s: xpm: out of memory\n", progname); - exit (-1); - default: - fprintf (stderr, "%s: xpm: unknown error code %d\n", progname, - result); - exit (-1); - } + int width = 0; + int height = 0; + bitmap = xpm_file_to_pixmap (dpy, MI_WINDOW (mi), bitmap_name, + &width, &height, 0); if (bitmap) { fp->image = XGetImage(dpy, bitmap, 0, 0, width, height, ~0L, ZPixmap); XFreePixmap(dpy, bitmap); } - else -#endif /* HAVE_XPM */ - -#ifdef HAVE_XMU - { - int width, height, xh, yh; - Pixmap bitmap = - XmuLocateBitmapFile (DefaultScreenOfDisplay (dpy), - bitmap_name, 0, 0, &width, &height, &xh, &yh); - if (!bitmap) - { - fprintf(stderr, "%s: unable to load bitmap file %s\n", - progname, bitmap_name); - exit (1); - } - fp->image = XGetImage(dpy, bitmap, 0, 0, width, height, - 1L, XYPixmap); - XFreePixmap(dpy, bitmap); - } - -#else /* !XMU */ - fprintf (stderr, - "%s: your vendor doesn't ship the standard Xmu library.\n", - progname); - fprintf (stderr, "\tWe can't load XBM files without it.\n"); - exit (1); -#endif /* !XMU */ - } else if (text && *text) { diff --git a/hacks/forest.c b/hacks/forest.c index 0a64c060..ce57b7b9 100644 --- a/hacks/forest.c +++ b/hacks/forest.c @@ -1,233 +1,226 @@ -/* forest.c (aka xtree.c), Copyright (c) 1999 - * Peter Baumung +/* -*- Mode: C; tab-width: 4 -*- */ +/* forest --- binary trees in a fractal forest */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)forest.c 5.00 2000/11/01 xlockmore"; + +#endif + +/*- + * Copyright (c) 1995 Pascal Pensa + * + * Original idea : Guillaume Ramey + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. * - * Most code taken from - * xscreensaver, Copyright (c) 1992, 1995, 1997 - * Jamie Zawinski + * Revision History: + * 01-Nov-2000: Allocation checks + * 10-May-1997: 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" /*"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 trees_opts = {0, NULL, 0, NULL, NULL}; +#define MODE_forest +#define PROGCLASS "Forest" +#define HACK_INIT init_forest +#define HACK_DRAW draw_forest +#define forest_opts xlockmore_opts +#define DEFAULTS "*delay: 500000 \n" \ + "*count: 100 \n" \ + "*cycles: 200 \n" \ + "*ncolors: 20 \n" +#define UNIFORM_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ + +#endif /* STANDALONE */ + +#ifdef MODE_forest + +ModeSpecOpt forest_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct forest_description = +{"forest", "init_forest", "draw_forest", "release_forest", + "refresh_forest", "init_forest", (char *) NULL, &forest_opts, + 400000, 100, 200, 1, 64, 1.0, "", + "Shows binary trees of a fractal forest", 0, NULL}; + +#endif + +#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))) typedef struct { - 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; + int width; + int height; + int time; /* up time */ + int ntrees; +} foreststruct; + +static foreststruct *forests = (foreststruct *) 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_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); + } } -double rRand(double a, double b) { - return (a+(b-a)*NRAND(10001)/10000.0); +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_WIDTH(mi); + fp->height = MI_HEIGHT(mi); + fp->time = 0; + + fp->ntrees = MI_COUNT(mi); + if (fp->ntrees < -MINTREES) + fp->ntrees = NRAND(-fp->ntrees - MINTREES + 1) + MINTREES; + else if (fp->ntrees < MINTREES) + fp->ntrees = MINTREES; + + MI_CLEARWINDOW(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 +draw_forest(ModeInfo * mi) +{ + Display *display = MI_DISPLAY(mi); + GC gc = MI_GC(mi); + short x, y, x_2, y_2, len, c = 0; + float a, as; + foreststruct *fp; + + if (forests == NULL) + return; + fp = &forests[MI_SCREEN(mi)]; + + MI_IS_DRAWN(mi) = True; + 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_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)) { + init_forest(mi); + } } -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 +release_forest(ModeInfo * mi) +{ + if (forests != NULL) { + (void) free((void *) forests); + forests = (foreststruct *) NULL; + } } -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)); +void +refresh_forest(ModeInfo * mi) +{ + MI_CLEARWINDOW(mi); } -void release_trees(ModeInfo * mi) { - if (trees != NULL) { - (void) free((void *) trees); - trees = NULL; - } -} +#endif /* MODE_forest */ diff --git a/hacks/glx/Makefile.in b/hacks/glx/Makefile.in index a824037e..5b8f0280 100644 --- a/hacks/glx/Makefile.in +++ b/hacks/glx/Makefile.in @@ -78,7 +78,8 @@ SRCS = xscreensaver-gl-helper.c \ gflux.c stonerview.c stonerview-move.c stonerview-osc.c \ stonerview-view.c starwars.c glut_stroke.c glut_swidth.c \ gltext.c molecule.c dangerball.c sphere.c tube.c circuit.c \ - menger.c engine.c flipscreen3d.c font-ximage.c grab-ximage.c + menger.c engine.c flipscreen3d.c font-ximage.c \ + grab-ximage.c glsnake.c boxed.c glforestfire.c sballs.c OBJS = xscreensaver-gl-helper.o \ atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \ @@ -93,12 +94,14 @@ OBJS = xscreensaver-gl-helper.o \ gflux.o stonerview.o stonerview-move.o stonerview-osc.o \ stonerview-view.o starwars.o glut_stroke.o glut_swidth.o \ gltext.o molecule.o dangerball.o sphere.o tube.o circuit.o \ - menger.o engine.o flipscreen3d.o font-ximage.o grab-ximage.o + menger.o engine.o flipscreen3d.o font-ximage.o \ + grab-ximage.o glsnake.o boxed.o glforestfire.o sballs.o GL_EXES = cage gears moebius pipes sproingies stairs superquadrics \ morph3d rubik atlantis lament bubble3d glplanet pulsar \ sierpinski3d gflux stonerview starwars gltext molecule \ - dangerball circuit menger engine flipscreen3d + dangerball circuit menger engine flipscreen3d glsnake boxed \ + glforestfire sballs GLE_EXES = extrusion GL_UTIL_EXES = xscreensaver-gl-helper HACK_EXES = @GL_EXES@ @GLE_EXES@ @@ -112,10 +115,11 @@ HACK_OBJS = screenhack-gl.o xlock-gl.o fps.o $(HACK_BIN)/xlockmore.o \ $(UTILS_BIN)/colors.o HDRS = atlantis.h bubble3d.h buildlwo.h e_textures.h xpm-ximage.h \ - grab-ximage.h font-ximage.h tube.h sphere.h \ + grab-ximage.h font-ximage.h tube.h sphere.h boxed.h \ stonerview-move.h stonerview-osc.h glutstroke.h glut_roman.h GL_MEN = gflux.man lament.man starwars.man gltext.man \ - molecule.man xscreensaver-gl-helper.man + molecule.man xscreensaver-gl-helper.man glsnake.man \ + glforestfire.man sballs.man MEN = @GL_MEN@ EXTRAS = README Makefile.in @@ -369,6 +373,17 @@ engine: engine.o $(HACK_OBJS) flipscreen3d: flipscreen3d.o $(HACK_OBJS) $(GRAB_OBJS) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB_OBJS) $(HACK_LIBS) +glsnake: glsnake.o $(HACK_OBJS) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(HACK_LIBS) + +boxed: boxed.o $(HACK_OBJS) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(HACK_LIBS) + +glforestfire: glforestfire.o $(HACK_OBJS) xpm-ximage.o + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) xpm-ximage.o $(XPM_LIBS) + +sballs: sballs.o $(HACK_OBJS) xpm-ximage.o + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) xpm-ximage.o $(XPM_LIBS) # This one works differently (it's not xlock-like.) # @@ -503,4 +518,15 @@ flipscreen3d.o: ../../config.h flipscreen3d.o: $(srcdir)/grab-ximage.h font-ximage.o: ../../config.h grab-ximage.o: ../../config.h +glsnake.o: ../../config.h +boxed.o: $(srcdir)/boxed.h +boxed.o: ../../config.h +glforestfire.o: ../../config.h +glforestfire.o: $(srcdir)/xpm-ximage.h +glforestfire.o: $(HACK_SRC)/images/ground.xpm +glforestfire.o: $(HACK_SRC)/images/tree.xpm +sballs.o: ../../config.h +sballs.o: $(srcdir)/xpm-ximage.h +sballs.o: $(HACK_SRC)/images/sball.xpm +sballs.o: $(HACK_SRC)/images/sball-bg.xpm diff --git a/hacks/glx/atlantis.c b/hacks/glx/atlantis.c index 5c37d860..b62d50d3 100644 --- a/hacks/glx/atlantis.c +++ b/hacks/glx/atlantis.c @@ -174,8 +174,10 @@ ModStruct atlantis_description = static atlantisstruct *atlantis = NULL; #include "xpm-ximage.h" + #include "../images/sea-texture.xpm" + static void parse_image_data(ModeInfo *mi) { diff --git a/hacks/glx/boxed.c b/hacks/glx/boxed.c new file mode 100644 index 00000000..b973f083 --- /dev/null +++ b/hacks/glx/boxed.c @@ -0,0 +1,1179 @@ +/* thebox --- 3D bouncing balls that explode */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; + +#endif + +/*- + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * + * 2001: Written by Sander van Grieken + * as an OpenGL screensaver for the xscreensaver package. + * Lots of hardcoded values still in place. Also, there are some + * copy/paste leftovers from the gears hack. opts don't work. + */ + +#include +#include "boxed.h" + +/* +**---------------------------------------------------------------------------- +** Defines +**---------------------------------------------------------------------------- +*/ + +#ifdef STANDALONE +# define PROGCLASS "boxed" +# define HACK_INIT init_boxed +# define HACK_DRAW draw_boxed +# define HACK_RESHAPE reshape_boxed +# define boxed_opts xlockmore_opts +# define DEFAULTS "*delay: 20000 \n" \ + "*showFPS: False \n" \ + +# include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +# include "xlock.h" /* from the xlockmore distribution */ +#endif /* !STANDALONE */ + +#ifdef USE_GL +#include + +#undef countof +#define countof(x) (int)(sizeof((x))/sizeof((*x))) +#undef rnd +#define rnd() ( ((float)random()) / ((float)RAND_MAX * 2.0) ) + +/* #define DEF_PLANETARY "False" + +static int planetary; + +static XrmOptionDescRec opts[] = { + {"-planetary", ".gears.planetary", XrmoptionNoArg, (caddr_t) "true" }, + {"+planetary", ".gears.planetary", XrmoptionNoArg, (caddr_t) "false" }, +}; + +static argtype vars[] = { + {(caddr_t *) &planetary, "planetary", "Planetary", DEF_PLANETARY, t_Bool}, +}; +*/ + +/* ModeSpecOpts boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; */ + +ModeSpecOpt boxed_opts = {0, NULL, 0, NULL, NULL}; + +#ifdef USE_MODULES + +ModStruct boxed_description = { + "boxed", "init_boxed", "draw_boxed", "release_boxed", + "draw_boxed", "init_boxed", NULL, &boxed_opts, + 1000, 1, 2, 1, 4, 1.0, "", + "Shows GL's boxed balls", 0, NULL}; + +#endif + +#define BOOL int +#define TRUE 1 +#define FALSE 0 + +/* rendering defines */ + +/* box size */ +#define BOX_SIZE 20.0f + +/* camera */ +#define CAM_HEIGHT 100.0f +#define CAMDISTANCE_MIN 20.0 +#define CAMDISTANCE_MAX 150.0 +#define CAMDISTANCE_SPEED 1.5 + +/* rendering the sphere */ +#define MESH_SIZE 5 +#define SPHERE_VERTICES (2+MESH_SIZE*MESH_SIZE*2) +#define SPHERE_INDICES ((MESH_SIZE*4 + MESH_SIZE*4*(MESH_SIZE-1))*3) + +#define EXPLOSION 10.0f +#define MAXBALLS 50; +#define NUMBALLS 12; +#define BALLSIZE 3.0f; + +/* +**----------------------------------------------------------------------------- +** Typedefs +**----------------------------------------------------------------------------- +*/ + +typedef struct { + GLfloat x; + GLfloat y; + GLfloat z; +} vectorf; + +typedef struct { + vectorf loc; + vectorf dir; + vectorf color; + float radius; + BOOL bounced; + int offside; + BOOL justcreated; +} ball; + +typedef struct { + int num_balls; + float ballsize; + float explosion; + ball *balls; +} ballman; + +typedef struct { + vectorf loc; + vectorf dir; + BOOL far; +} tri; + +typedef struct { + int num_tri; + int lifetime; + float scalefac; + float explosion; + vectorf color; + tri *tris; + GLint *indices; + vectorf *normals; + vectorf *vertices; +} triman; + +typedef struct { + int numballs; + float ballsize; + float explosion; + BOOL textures; + BOOL transparent; + float camspeed; +} boxed_config; + + +typedef struct { + float cam_x_speed, cam_z_speed, cam_y_speed; + boxed_config config; + float tic; + vectorf spherev[SPHERE_VERTICES]; + GLint spherei[SPHERE_INDICES]; + ballman bman; + triman *tman; + GLXContext *glx_context; + GLint listobjects; + GLint gllists[3]; + Window window; + BOOL stop; + char *tex1; +} boxedstruct; + +#define GLL_PATTERN 1 +#define GLL_BALL 2 +#define GLL_BOX 3 + +/* +**---------------------------------------------------------------------------- +** Local Variables +**---------------------------------------------------------------------------- +*/ + +static boxedstruct *boxed = NULL; + + +/* +**---------------------------------------------------------------------------- +** Functions +**---------------------------------------------------------------------------- +*/ + +/* + * Add 2 vectors + */ +static inline void addvectors(vectorf *dest, vectorf *s1, vectorf *s2) +{ + dest->x = s1->x + s2->x; + dest->y = s1->y + s2->y; + dest->z = s1->z + s2->z; +} + +/* + * Sub 2 vectors + */ +static inline void subvectors(vectorf *dest, vectorf* s1, vectorf *s2) +{ + dest->x = s1->x - s2->x; + dest->y = s1->y - s2->y; + dest->z = s1->z - s2->z; +} + +/* + * Multiply vector with scalar (scale vector) + */ +static inline void scalevector(vectorf *dest, vectorf *source, GLfloat sc) +{ + dest->x = source->x * sc; + dest->y = source->y * sc; + dest->z = source->z * sc; +} + +/* + * Copy vector + */ +static inline void copyvector(vectorf *dest, vectorf* source) +{ + dest->x = source->x; + dest->y = source->y; + dest->z = source->z; +} + + +static inline GLfloat +dotproduct(vectorf * v1, vectorf * v2) +{ + return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z; +} + +static inline GLfloat +squaremagnitude(vectorf * v) +{ + return v->x * v->x + v->y * v->y + v->z * v->z; +} + + + +/* + * Generate the Sphere data + * + * Input: + */ + +static void generatesphere(void) +{ + float dj = M_PI/(MESH_SIZE+1.0f); + float di = M_PI/MESH_SIZE; + int v; /* vertex offset */ + int ind; /* indices offset */ + int i,j,si; + GLfloat r_y_plane, h_y_plane; + vectorf *spherev; + GLint *spherei; + + /* + * generate the sphere data + * vertices 0 and 1 are the north and south poles + */ + + spherei = boxed->spherei; + spherev = boxed->spherev; + + spherev[0].x = 0.0f; spherev[0].y =1.0f; spherev[0].z = 0.0f; + spherev[1].x = 0.0f; spherev[1].y =-1.0f; spherev[1].z = 0.0f; + + for (j=0; jloc.x = 5-10*rnd(); + newball->loc.y = 35+20*rnd(); + newball->loc.z = 5-10*rnd(); + newball->dir.x = 0.5f-rnd(); + newball->dir.y = 0.0; + newball->dir.z = 0.5-rnd(); + newball->offside = 0; + newball->bounced = FALSE; + newball->radius = BALLSIZE; + while (r+g+b < 1.7f ) { + newball->color.x = r=rnd(); + newball->color.y = g=rnd(); + newball->color.z = b=rnd(); + } + newball->justcreated = TRUE; +} + +/* Update position of each ball */ + +void updateballs(ballman *bman) { + register int b,j; + vectorf dvect,richting,relspeed,influence; + GLfloat squaredist; + + for (b=0;bnum_balls;b++) { + + /* apply gravity */ + bman->balls[b].dir.y -= 0.15f; + /* apply movement */ + addvectors(&bman->balls[b].loc,&bman->balls[b].loc,&bman->balls[b].dir); + /* boundary check */ + if (bman->balls[b].loc.y < bman->balls[b].radius) { /* ball onder bodem? (bodem @ y=0) */ + if ((bman->balls[b].loc.x < -100.0) || + (bman->balls[b].loc.x > 100.0) || + (bman->balls[b].loc.z < -100.0) || + (bman->balls[b].loc.z > 100.0)) { + if (bman->balls[b].loc.y < -1000.0) + createball(&bman->balls[b]); + } else { + bman->balls[b].loc.y = bman->balls[b].radius + (bman->balls[b].radius - bman->balls[b].loc.y); + bman->balls[b].dir.y = -bman->balls[b].dir.y; + if (bman->balls[b].offside) { + bman->balls[b].bounced = TRUE; /* temporary disable painting ball */ + scalevector(&bman->balls[b].dir,&bman->balls[b].dir,0.80f); + if (squaremagnitude(&bman->balls[b].dir) < 0.08f) { + createball(&bman->balls[b]); + } + } + } + + } + if (!bman->balls[b].offside) { + if (bman->balls[b].loc.x - bman->balls[b].radius < -20.0f) { /* x ondergrens */ + if (bman->balls[b].loc.y > 41+bman->balls[b].radius) bman->balls[b].offside=1; + else { + bman->balls[b].dir.x = -bman->balls[b].dir.x; + bman->balls[b].loc.x = -20.0f + bman->balls[b].radius; + } + } + if (bman->balls[b].loc.x + bman->balls[b].radius > 20.0f) { /* x bovengrens */ + if (bman->balls[b].loc.y > 41+bman->balls[b].radius) bman->balls[b].offside=1; + else { + bman->balls[b].dir.x = -bman->balls[b].dir.x; + bman->balls[b].loc.x = 20.0f - bman->balls[b].radius; + } + } + if (bman->balls[b].loc.z - bman->balls[b].radius < -20.0f) { /* z ondergrens */ + if (bman->balls[b].loc.y > 41+bman->balls[b].radius) bman->balls[b].offside=1; + else { + bman->balls[b].dir.z = -bman->balls[b].dir.z; + bman->balls[b].loc.z = -20.0f + bman->balls[b].radius; + } + } + if (bman->balls[b].loc.z + bman->balls[b].radius > 20.0f) { /* z bovengrens */ + if (bman->balls[b].loc.y > 41+bman->balls[b].radius) bman->balls[b].offside=1; + else { + bman->balls[b].dir.z = -bman->balls[b].dir.z; + bman->balls[b].loc.z = 20.0f - bman->balls[b].radius; + } + } + } /* end if !offside */ + + /* check voor stuiteren */ + for (j=b+1;jnum_balls;j++) { + squaredist = (bman->balls[b].radius * bman->balls[b].radius) + (bman->balls[j].radius * bman->balls[j].radius); + subvectors(&dvect,&bman->balls[b].loc,&bman->balls[j].loc); + if ( squaremagnitude(&dvect) < squaredist ) { /* balls b and j touch */ + subvectors(&richting,&bman->balls[j].loc,&bman->balls[b].loc); + subvectors(&relspeed,&bman->balls[b].dir,&bman->balls[j].dir); + /* calc mutual influence direction and magnitude */ + scalevector(&influence,&richting,(dotproduct(&richting,&relspeed)/squaremagnitude(&richting))); + + subvectors(&bman->balls[b].dir,&bman->balls[b].dir,&influence); + addvectors(&bman->balls[j].dir,&bman->balls[j].dir,&influence); + addvectors(&bman->balls[b].loc,&bman->balls[b].loc,&bman->balls[b].dir); + addvectors(&bman->balls[j].loc,&bman->balls[j].loc,&bman->balls[j].dir); + + subvectors(&dvect,&bman->balls[b].loc,&bman->balls[j].loc); + while (squaremagnitude(&dvect) < squaredist) { + addvectors(&bman->balls[b].loc,&bman->balls[b].loc,&bman->balls[b].dir); + addvectors(&bman->balls[j].loc,&bman->balls[j].loc,&bman->balls[j].dir); + subvectors(&dvect,&bman->balls[b].loc,&bman->balls[j].loc); + } + } + } /* end for j */ + } /* end for b */ +} + + +/* +* explode ball into triangles +*/ + +void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_num, ball *b) { + int pos; + float explosion; + float scale; + register int i; + vectorf avgdir,dvect; + + tman->scalefac = b->radius; + copyvector(&tman->color,&b->color); + explosion = 1.0f + tman->explosion * 2.0 * rnd(); + + tman->num_tri = ind_num/3; + + /* reserveer geheugen voor de poly's in een bal */ + + tman->tris = (tri *)malloc(tman->num_tri * sizeof(tri)); + tman->vertices = (vectorf *)malloc(ind_num * sizeof(vectorf)); + tman->normals = (vectorf *)malloc(ind_num/3 * sizeof(vectorf)); + + for (i=0; i<(tman->num_tri); i++) { + tman->tris[i].far = FALSE; + pos = i * 3; + /* kopieer elke poly apart naar een tri structure */ + copyvector(&tman->vertices[pos+0],&spherev[spherei[pos+0]]); + copyvector(&tman->vertices[pos+1],&spherev[spherei[pos+1]]); + copyvector(&tman->vertices[pos+2],&spherev[spherei[pos+2]]); + /* Calculate average direction of shrapnel */ + addvectors(&avgdir,&tman->vertices[pos+0],&tman->vertices[pos+1]); + addvectors(&avgdir,&avgdir,&tman->vertices[pos+2]); + scalevector(&avgdir,&avgdir,0.33333); + + /* should normalize first, NYI */ + copyvector(&tman->normals[i],&avgdir); + + /* copy de lokatie */ + addvectors(&tman->tris[i].loc,&b->loc,&avgdir); + /* en translate alle triangles terug naar hun eigen oorsprong */ + tman->vertices[pos+0].x -= avgdir.x; + tman->vertices[pos+0].y -= avgdir.y; + tman->vertices[pos+0].z -= avgdir.z; + tman->vertices[pos+1].x -= avgdir.x; + tman->vertices[pos+1].y -= avgdir.y; + tman->vertices[pos+1].z -= avgdir.z; + tman->vertices[pos+2].x -= avgdir.x; + tman->vertices[pos+2].y -= avgdir.y; + tman->vertices[pos+2].z -= avgdir.z; + /* alwaar opschaling plaatsvindt */ + scale = b->radius * 2; + scalevector(&tman->vertices[pos+0],&tman->vertices[pos+0],scale); + scalevector(&tman->vertices[pos+1],&tman->vertices[pos+1],scale); + scalevector(&tman->vertices[pos+2],&tman->vertices[pos+2],scale); + + /* bereken nieuwe richting */ + scalevector(&tman->tris[i].dir,&avgdir,explosion); + dvect.x = 0.1f - 0.2f*rnd(); + dvect.y = 0.15f - 0.3f*rnd(); + dvect.z = 0.1f - 0.2f*rnd(); + addvectors(&tman->tris[i].dir,&tman->tris[i].dir,&dvect); + } +} + + +/* +* update position of each tri +*/ + +void updatetris(triman *t) { + int b; + + for (b=0;bnum_tri;b++) { + /* apply gravity */ + t->tris[b].dir.y -= 0.1f; + /* apply movement */ + addvectors(&t->tris[b].loc,&t->tris[b].loc,&t->tris[b].dir); + /* boundary check */ + if (t->tris[b].far) continue; + if (t->tris[b].loc.y < 0) { /* onder bodem ? */ + if ((t->tris[b].loc.x > -100.0f) & + (t->tris[b].loc.x < 100.0f) & + (t->tris[b].loc.z > -100.0f) & + (t->tris[b].loc.z < 100.0f)) { /* in veld */ + t->tris[b].dir.y = -(t->tris[b].dir.y); + t->tris[b].loc.y = -t->tris[b].loc.y; + scalevector(&t->tris[b].dir,&t->tris[b].dir,0.75f); /* dampening */ + } + else { + t->tris[b].far = TRUE; + continue; + } + } + + /* this should be replaced with code that determines + * the correct wall the tri bounces in to. this code sucks. + */ + if ((t->tris[b].loc.x > -21.0f) & + (t->tris[b].loc.x < 21.0f) & + (t->tris[b].loc.z > -21.0f) & + (t->tris[b].loc.z < 21.0f)) { /* in box? */ + if ((t->tris[b].loc.x > -21.0f) & + (t->tris[b].loc.x < 0)) { + t->tris[b].loc.x = -21.0f; + t->tris[b].dir.x = -t->tris[b].dir.x; + } + if ((t->tris[b].loc.x < 21.0f) & + (t->tris[b].loc.x > 0)) { + t->tris[b].loc.x = 21.0f; + t->tris[b].dir.x = -t->tris[b].dir.x; + } + if ((t->tris[b].loc.z > -21.0f) & + (t->tris[b].loc.z < 0)) { + t->tris[b].loc.z = -21.0f; + t->tris[b].dir.z = -t->tris[b].dir.z; + } + if ((t->tris[b].loc.z < 21.0f) & + (t->tris[b].loc.z > 0)) { + t->tris[b].loc.z = 21.0f; + t->tris[b].dir.z = -t->tris[b].dir.z; + } + } + } /* end for b */ +} + + +/* + * free memory allocated by a tri manager + */ +void freetris(triman *t) { + if (!t) return; + if (t->tris) free(t->tris); + if (t->vertices) free(t->vertices); + if (t->normals) free(t->normals); + t->tris = NULL; + t->vertices = NULL; + t->normals = NULL; + t->num_tri = 0; + t->lifetime = 0; +} + + +/* + *load defaults in config structure + */ +void setdefaultconfig(boxed_config *config) { + config->numballs = NUMBALLS; + config->textures = TRUE; + config->transparent = FALSE; + config->explosion = 25.0f; + config->ballsize = BALLSIZE; + config->camspeed = 35.0f; +} + + +/* + * draw bottom + */ +static void drawfilledbox(boxedstruct *boxed) +{ + /* draws texture filled box, + top is drawn using the entire texture, + the sides are drawn using the edge of the texture + */ + + /* front */ + glBegin(GL_QUADS); + glTexCoord2f(0,1); + glVertex3f(-1.0,1.0,1.0); + glTexCoord2f(1,1); + glVertex3f(1.0,1.0,1.0); + glTexCoord2f(1,1); + glVertex3f(1.0,-1.0,1.0); + glTexCoord2f(0,1); + glVertex3f(-1.0,-1.0,1.0); + /* rear */ + glTexCoord2f(0,1); + glVertex3f(1.0,1.0,-1.0); + glTexCoord2f(1,1); + glVertex3f(-1.0,1.0,-1.0); + glTexCoord2f(1,1); + glVertex3f(-1.0,-1.0,-1.0); + glTexCoord2f(0,1); + glVertex3f(1.0,-1.0,-1.0); + /* left */ + glTexCoord2f(1,1); + glVertex3f(-1.0,1.0,1.0); + glTexCoord2f(1,1); + glVertex3f(-1.0,-1.0,1.0); + glTexCoord2f(0,1); + glVertex3f(-1.0,-1.0,-1.0); + glTexCoord2f(0,1); + glVertex3f(-1.0,1.0,-1.0); + /* right */ + glTexCoord2f(0,1); + glVertex3f(1.0,1.0,1.0); + glTexCoord2f(1,1); + glVertex3f(1.0,1.0,-1.0); + glTexCoord2f(1,1); + glVertex3f(1.0,-1.0,-1.0); + glTexCoord2f(0,1); + glVertex3f(1.0,-1.0,1.0); + /* top */ + glTexCoord2f(0.0,0.0); + glVertex3f(-1.0,1.0,1.0); + glTexCoord2f(0.0,1.0); + glVertex3f(-1.0,1.0,-1.0); + glTexCoord2f(1.0,1.0); + glVertex3f(1.0,1.0,-1.0); + glTexCoord2f(1.0,0.0); + glVertex3f(1.0,1.0,1.0); + /* bottom */ + glTexCoord2f(0,0); + glVertex3f(-1.0,-1.0,1.0); + glTexCoord2f(0,1); + glVertex3f(-1.0,-1.0,-1.0); + glTexCoord2f(1,1); + glVertex3f(1.0,-1.0,-1.0); + glTexCoord2f(1,0); + glVertex3f(1.0,-1.0,1.0); + glEnd(); +} + + +/* + * Draw a box made of lines + */ +static void drawbox(boxedstruct *boxed) +{ + /* top */ + glBegin(GL_LINE_STRIP); + glVertex3f(-1.0,1.0,1.0); + glVertex3f(-1.0,1.0,-1.0); + glVertex3f(1.0,1.0,-1.0); + glVertex3f(1.0,1.0,1.0); + glVertex3f(-1.0,1.0,1.0); + glEnd(); + /* bottom */ + glBegin(GL_LINE_STRIP); + glVertex3f(-1.0,-1.0,1.0); + glVertex3f(1.0,-1.0,1.0); + glVertex3f(1.0,-1.0,-1.0); + glVertex3f(-1.0,-1.0,-1.0); + glVertex3f(-1.0,-1.0,1.0); + glEnd(); + /* connect top & bottom */ + glBegin(GL_LINES); + glVertex3f(-1.0,1.0,1.0); + glVertex3f(-1.0,-1.0,1.0); + glVertex3f(1.0,1.0,1.0); + glVertex3f(1.0,-1.0,1.0); + glVertex3f(1.0,1.0,-1.0); + glVertex3f(1.0,-1.0,-1.0); + glVertex3f(-1.0,1.0,-1.0); + glVertex3f(-1.0,-1.0,-1.0); + glEnd(); +} + + + +/* + * Draw ball + */ +static void drawball(boxedstruct *gp, ball *b) +{ + int i,pos,cnt; + GLint *spherei = gp->spherei; + vectorf *spherev = gp->spherev; + GLfloat col[3]; + + glPushMatrix(); + + glTranslatef(b->loc.x,b->loc.y,b->loc.z); + glScalef(b->radius,b->radius,b->radius); + glColor3f(b->color.x,b->color.y,b->color.z); + col[0] = b->color.x; + col[1] = b->color.y; + col[2] = b->color.z; + glMaterialfv(GL_FRONT, GL_DIFFUSE, col); + col[0] *= 0.5; + col[1] *= 0.5; + col[2] *= 0.5; + glMaterialfv(GL_FRONT, GL_EMISSION,col); + + if (!gp->gllists[GLL_BALL]) { + glNewList(gp->listobjects + GLL_BALL,GL_COMPILE_AND_EXECUTE); + cnt = SPHERE_INDICES/3; + for (i=0; igllists[GLL_BALL] = 1; + } else { + glCallList(gp->listobjects + GLL_BALL); + } + + glPopMatrix(); +} + + +/* + * Draw all triangles in triman + */ +static void drawtriman(triman *t) +{ + int i,pos; + vectorf *spherev = t->vertices; + GLfloat col[3]; + + glPushMatrix(); + glColor3f(t->color.x,t->color.y,t->color.z); + col[0] = t->color.x; + col[1] = t->color.y; + col[2] = t->color.z; + glMaterialfv(GL_FRONT, GL_DIFFUSE, col); + col[0] *= 0.3; + col[1] *= 0.3; + col[2] *= 0.3; + glMaterialfv(GL_FRONT, GL_EMISSION,col); + + for (i=0; inum_tri; i++) { + pos = i*3; + glPushMatrix(); + glTranslatef(t->tris[i].loc.x,t->tris[i].loc.y,t->tris[i].loc.z); + glBegin(GL_TRIANGLES); + glNormal3f(t->normals[i].x,t->normals[i].y,t->normals[i].z); + glVertex3f(spherev[pos+0].x,spherev[pos+0].y,spherev[pos+0].z); + glVertex3f(spherev[pos+1].x,spherev[pos+1].y,spherev[pos+1].z); + glVertex3f(spherev[pos+2].x,spherev[pos+2].y,spherev[pos+2].z); + glEnd(); + glPopMatrix(); + } + glPopMatrix(); +} + +/* + * draw floor pattern + */ +static void drawpattern(boxedstruct *boxed) +{ + if (!boxed->gllists[GLL_PATTERN]) { + glNewList(boxed->listobjects + GLL_PATTERN,GL_COMPILE_AND_EXECUTE); + + glBegin(GL_LINE_STRIP); + glVertex3f(-25.0f, 0.0f, 35.0f); + glVertex3f(-15.0f, 0.0f, 35.0f); + glVertex3f(-5.0f, 0.0f, 25.0f); + glVertex3f(5.0f, 0.0f, 25.0f); + glVertex3f(15.0f, 0.0f, 35.0f); + glVertex3f(25.0f, 0.0f, 35.0f); + glVertex3f(35.0f, 0.0f, 25.0f); + glVertex3f(35.0f, 0.0f, 15.0f); + glVertex3f(25.0f, 0.0f, 5.0f); + glVertex3f(25.0f, 0.0f, -5.0f); + glVertex3f(35.0f, 0.0f, -15.0f); + glVertex3f(35.0f, 0.0f, -25.0f); + glVertex3f(25.0f, 0.0f, -35.0f); + glVertex3f(15.0f, 0.0f,-35.0f); + glVertex3f(5.0f, 0.0f, -25.0f); + glVertex3f(-5.0f, 0.0f, -25.0f); + glVertex3f(-15.0f, 0.0f,-35.0f); + glVertex3f(-25.0f, 0.0f,-35.0f); + glVertex3f(-35.0f, 0.0f, -25.0f); + glVertex3f(-35.0f, 0.0f, -15.0f); + glVertex3f(-25.0f, 0.0f, -5.0f); + glVertex3f(-25.0f, 0.0f, 5.0f); + glVertex3f(-35.0f, 0.0f, 15.0f); + glVertex3f(-35.0f, 0.0f, 25.0f); + glVertex3f(-25.0f, 0.0f, 35.0f); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3f(-5.0f, 0.0f, 15.0f); + glVertex3f(5.0f, 0.0f, 15.0f); + glVertex3f(15.0f, 0.0f, 5.0f); + glVertex3f(15.0f, 0.0f, -5.0f); + glVertex3f(5.0f, 0.0f, -15.0f); + glVertex3f(-5.0f, 0.0f, -15.0f); + glVertex3f(-15.0f, 0.0f, -5.0f); + glVertex3f(-15.0f, 0.0f, 5.0f); + glVertex3f(-5.0f, 0.0f, 15.0f); + glEnd(); + glEndList(); + boxed->gllists[GLL_PATTERN] = 1; + } else { + glCallList(boxed->listobjects + GLL_PATTERN); + } +} + + +/* + * main rendering loop + */ +static void draw(ModeInfo * mi) +{ + boxedstruct *gp = &boxed[MI_SCREEN(mi)]; + vectorf v1; + GLfloat dcam; + int dx, dz; + int i; + + GLfloat dgray[4] = {0.3f, 0.3f, 0.3f, 1.0f}; + GLfloat black[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + GLfloat lblue[4] = {0.4f,0.6f,1.0f }; + + GLfloat l0_ambient[] = {0.0, 0.0, 0.0, 1.0}; + GLfloat l0_specular[] = {1.0, 1.0, 1.0, 1.0}; + GLfloat l0_diffuse[] = {1.0, 1.0, 1.0, 1.0}; + GLfloat l0_position[] = {0.0, 0.0, 0.0, 1.0}; /* w != 0 -> positional light */ + GLfloat l1_ambient[] = {0.0, 0.0, 0.0, 1.0}; + GLfloat l1_specular[] = {1.0, 1.0, 1.0, 1.0}; + GLfloat l1_diffuse[] = {0.5, 0.5, 0.5, 1.0}; + GLfloat l1_position[] = {0.0, 1.0, 0.0, 0.0}; /* w = 0 -> directional light */ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + + gp->tic += 0.01f; + + /* rotate camera around (0,0,0), looking at (0,0,0), up is (0,1,0) */ + dcam = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos(gp->tic/CAMDISTANCE_SPEED); + v1.x = dcam * sin(gp->tic/gp->cam_x_speed); + v1.z = dcam * cos(gp->tic/gp->cam_z_speed); + v1.y = CAM_HEIGHT * sin(gp->tic/gp->cam_y_speed) + 1.02 * CAM_HEIGHT; + gluLookAt(v1.x,v1.y,v1.z,0.0,0.0,0.0,0.0,1.0,0.0); + + glLightfv(GL_LIGHT0, GL_AMBIENT, l0_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, l0_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, l0_specular); + glLightfv(GL_LIGHT0, GL_POSITION, l0_position); + glLightfv(GL_LIGHT1, GL_AMBIENT, l1_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, l1_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, l1_specular); + glLightfv(GL_LIGHT1, GL_POSITION, l1_position); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + glFrontFace(GL_CW); + + glMaterialfv(GL_FRONT, GL_SPECULAR, black); + glMaterialfv(GL_FRONT, GL_EMISSION, lblue); + glMaterialfv(GL_FRONT,GL_AMBIENT,black); + glMaterialf(GL_FRONT, GL_SHININESS, 5.0); + + + /* draw ground grid */ + /* glDisable(GL_DEPTH_TEST); */ + glDisable(GL_LIGHTING); + + glColor3f(0.1,0.1,0.6); + for (dx= -2; dx<3; dx++) { + for (dz= -2; dz<3; dz++) { + glPushMatrix(); + glTranslatef(dx*30.0f, 0.0f, dz*30.0f); + drawpattern(gp); + glPopMatrix(); + } + } + + /* Set drawing mode for the boxes */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glPushMatrix(); + glColor3f(1.0,1.0,1.0); + glScalef(20.0,0.25,20.0); + glTranslatef(0.0,2.0,0.0); + drawfilledbox(gp); + glPopMatrix(); + glDisable(GL_TEXTURE_2D); + + glPushMatrix(); + glColor3f(0.2,0.5,0.2); + glScalef(20.0,20.0,0.25); + glTranslatef(0.0,1.0,81.0); + drawbox(gp); + glPopMatrix(); + + glPushMatrix(); + glColor3f(0.2,0.5,0.2); + glScalef(20.0,20.0,0.25); + glTranslatef(0.0,1.0,-81.0); + drawbox(gp); + glPopMatrix(); + + glPushMatrix(); + glColor3f(0.2,0.5,0.2); + glScalef(.25,20.0,20.0); + glTranslatef(-81.0,1.0,0.0); + drawbox(gp); + glPopMatrix(); + + glPushMatrix(); + glColor3f(0.2,0.5,0.2); + glScalef(.25,20.0,20.0); + glTranslatef(81.0,1.0,0.0); + drawbox(gp); + glPopMatrix(); + + glEnable(GL_LIGHTING); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, dgray); + glMaterialfv(GL_FRONT, GL_EMISSION, black); /* turn it off before painting the balls */ + + /* move the balls and shrapnel */ + updateballs(&gp->bman); + + glFrontFace(GL_CCW); + for (i=0;ibman.num_balls;i++) { + if (gp->bman.balls[i].justcreated) { + gp->bman.balls[i].justcreated = FALSE; + freetris(&gp->tman[i]); + } + if ((gp->bman.balls[i].bounced) & (gp->tman[i].vertices == NULL)) { + createtrisfromball(&gp->tman[i],gp->spherev,gp->spherei,SPHERE_INDICES,&gp->bman.balls[i]); + } + if (gp->bman.balls[i].bounced) { + updatetris(&gp->tman[i]); + glDisable(GL_CULL_FACE); + drawtriman(&gp->tman[i]); + glEnable(GL_CULL_FACE); + } else { + drawball(gp, &gp->bman.balls[i]); + } + } + + glFlush(); +} + + + +/* + * new window size or exposure + */ +void reshape_boxed(ModeInfo *mi, int width, int height) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + + glViewport(0, 0, (GLint) width, (GLint) height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0,1/h,2.0,1000.0); + glMatrixMode (GL_MODELVIEW); + + glLineWidth(1); + glPointSize(1); +} + + +static void +pinit(ModeInfo * mi) +{ + boxedstruct *gp = &boxed[MI_SCREEN(mi)]; + ballman *bman; + int i,texpixels; + char *texpixeldata; + char *texpixeltarget; + + glShadeModel(GL_SMOOTH); + glClearDepth(1.0); + glClearColor(0.0,0.05,0.1,0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* Load configuration */ + setdefaultconfig(&gp->config); + + bman = &gp->bman; + + bman->balls = (ball *)malloc(gp->config.numballs * sizeof(ball)); + bman->num_balls = gp->config.numballs; + bman->ballsize = gp->config.ballsize; + bman->explosion = gp->config.explosion; + + gp->tman = (triman *)malloc(bman->num_balls * sizeof(triman)); + memset(gp->tman,0,bman->num_balls * sizeof(triman)); + + for(i=0;inum_balls;i++) { + gp->tman[i].explosion = (float) (((int)gp->config.explosion) / 15.0f ); + gp->tman[i].vertices = NULL; + gp->tman[i].normals = NULL; + gp->tman[i].tris = NULL; + createball(&bman->balls[i]); + bman->balls[i].loc.y *= rnd(); + } + + generatesphere(); + + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + + /* define cam path */ + gp->cam_x_speed = 1.0f/((float)gp->config.camspeed/50.0 + rnd()*((float)gp->config.camspeed/50.0)); + gp->cam_z_speed = 1.0f/((float)gp->config.camspeed/50.0 + rnd()*((float)gp->config.camspeed/50.0)); + gp->cam_y_speed = 1.0f/((float)gp->config.camspeed/250.0 + rnd()*((float)gp->config.camspeed/250.0)); + if (rnd() < 0.5f) gp->cam_x_speed = -gp->cam_x_speed; + if (rnd() < 0.5f) gp->cam_z_speed = -gp->cam_z_speed; + + + gp->tex1 = (char *)malloc(3*width*height*sizeof(GLuint)); + texpixels = 256*256; /*width*height;*/ + texpixeldata = header_data; + texpixeltarget = gp->tex1; + for (i=0; i < texpixels; i++) { + HEADER_PIXEL(texpixeldata,texpixeltarget); + texpixeltarget += 3; + } + + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 256, 256, + GL_RGB, GL_UNSIGNED_BYTE, gp->tex1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + +} + + + +void +init_boxed(ModeInfo * mi) +{ + int screen = MI_SCREEN(mi); + + /* Colormap cmap; */ + /* Boolean rgba, doublebuffer, cmap_installed; */ + boxedstruct *gp; + + if (boxed == NULL) { + if ((boxed = (boxedstruct *) calloc(MI_NUM_SCREENS(mi),sizeof (boxedstruct))) == NULL) return; + } + gp = &boxed[screen]; + gp->window = MI_WINDOW(mi); + + if ((gp->glx_context = init_GL(mi)) != NULL) { + reshape_boxed(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + glDrawBuffer(GL_BACK); + if (!glIsList(gp->listobjects)) { + gp->listobjects = glGenLists(3); + gp->gllists[0] = 0; + gp->gllists[1] = 0; + gp->gllists[2] = 0; + } + pinit(mi); + } else { + MI_CLEARWINDOW(mi); + } +} + + +void +draw_boxed(ModeInfo * mi) +{ + boxedstruct *gp = &boxed[MI_SCREEN(mi)]; + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + + if (!gp->glx_context) + return; + + glDrawBuffer(GL_BACK); + + glXMakeCurrent(display, window, *(gp->glx_context)); + draw(mi); + + if (mi->fps_p) do_fps (mi); + glFinish(); + glXSwapBuffers(display, window); +} + +void +release_boxed(ModeInfo * mi) +{ + if (boxed != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { + boxedstruct *gp = &boxed[screen]; + + if (gp->glx_context) { + /* Display lists MUST be freed while their glXContext is current. */ + glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context)); + + /*if (glIsList(gp->gear1)) + glDeleteLists(gp->gear1, 1); + if (glIsList(gp->gear2)) + glDeleteLists(gp->gear2, 1); + if (glIsList(gp->gear3)) + glDeleteLists(gp->gear3, 1); + if (glIsList(gp->gear_inner)) + glDeleteLists(gp->gear_inner, 1); + if (glIsList(gp->gear_outer)) + glDeleteLists(gp->gear_outer, 1); + */ + + /* TODO + * free all trimans + * free all balls + * free all sphere indices & vertices + */ + + } + } + (void) free((void *) boxed); + boxed = NULL; + } + FreeAllGL(mi); +} + + +/*********************************************************/ + +#endif diff --git a/hacks/glx/boxed.h b/hacks/glx/boxed.h new file mode 100644 index 00000000..cab42a2f --- /dev/null +++ b/hacks/glx/boxed.h @@ -0,0 +1,4111 @@ +/* GIMP header image file format (RGB-only): /home/shag/build/xscreensaver-3.33/hacks/glx/thebox.h */ + +static unsigned int width = 256; +static unsigned int height = 256; + +/* Call this macro repeatedly. After each use, the pixel data can be extracted */ + +#define HEADER_PIXEL(data,pixel) \ + pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \ + pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \ + pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \ + data += 4; + +static char *header_data = + "!FY'\"&Q#!&M!!VM-!6Y(!&M##6Q&\"69%\"FU'!FE!!VM$!VI$!&M!!FM#!VU&!'!!" + "\"&M%#&M!\"6Q$\"')#!FY#\"FY%\"6Y\"\"&Y#\"6]$\"&U!\"G%!\"7%&!G)!!'-!!')!\"'=!" + "!G!##G5\"\"75$\"W9#!G5#!G9!!WA$#'=\"!GE#\"'A%#GI$!GI!#'A!!'E##GQ&%7Q#" + "#WU%#W=%\"W]#\"GY\"%WQ)%7Y\"\"H-!\"W]&\"8!$%8%#$8-&\"8%!#81%$85)#H!##H-&" + "$H1(#H)#\"X5#$XA%\"X9##H9#\"89#\"89!\"HA\"\"8A!\"8A!\"X=#$8E&#(I!\"8I&$HM!" + "#8I%\"8M!!HM#!HM!!HU!$(M($8Q)!H])!XQ!\"8Y!$(]'$(Y'$8Q(\"XY%#XQ#\"I!$" + "\"XY\"#Y)##)%#%(]%$Y!!#I%\"\")!%#Y!$#9%!#8]!#I%\"$)%$%HY%#HU\"$91($9-(" + "$))$#95!%8]&!9-\"$X](\")!#!)%!%)-\"#9-$#)-&#I5\"$Y%!#)-)\"I-!#91!\"Y-\"" + "\"(]\"$I-'#IA\"\"I-!#Y-&#)-##Y-##)1#!I-##)-#\"H]!#)5#\"Y-\"!)-!\"Y!&$)-!" + "#)1#\"Y%##(]!$9-)\"I)!#)1#$Y%'\"XY\"\"91#!)1!#I)\"$)%%%(]&#HY\"#(]!#I)\"" + "&8]%!(]!\"Y!##H]%#X]!#)%##(Y&\"I)!$X]!#Y!#\"(Y\"\"HY!#Y%'\"8Y!%(]+#XQ&" + "\"8M#!XQ$\"Y%%\"8M!#XU!#HI\"$XQ$#XI&\"HI!#8A\"$8E\"#(5!#8A$$(A%\"8=#$(5(" + "#X='$89##H=\"#(=!\"XA#\"(-#\"H1\"\"81!\"8-!!(5!\"X-##8!#\"H1%$(!&%X1$" + "#(%$\"G]\"!8%\"\"7M!\"7U!#'Y$\"7M!#7Y##GI$#WI%!'M#\"7A!\"GI\"!G9!!GI&!GE!" + "\"GE%!W=\"!'E#\"W!\"!G%%!W5&!G9!!W)\"\"'-#!7-'\"V]&!W1\"\"'%\"\"'%#\"&]\"!'1%" + "\"&Y##FQ%!&U!\"FU!\"&Q#!&I!!FU#!&Y!!6M\"!FM%!FI!!&M!!VM\"!VM\"!FI%\"6Q$" + "!&E#!VQ&!&E!\"FM!\"FM#!&Q!\"&I%#&I%\"&M*\"VM(!6U\"!6A\"!&I'!FM#!FM!\"6M\"" + "!FE##FU%#V]$\"&Y#\"FY!\"F]%!F]!!V]\"!G1!\"7%\"#75(!G%!\"71$\"'-#\"'1!!G5&" + "!W5$!G=!\"7)\"\"G=%\"7M#\"GM'!WA\"!'A!#7A*\"7I!#7Q&#X!*$'I!#'I\"$'U(\"7U!" + "#7Y%!GY!#GY&\"7]!!H)!$H!+\"WY##X!'#X%'\"H1!\"()#\"H=\"\"X1(%X-(!H1!#X5!" + "\"H5\"$8-&%X5'\"8-!#X-'\"XE%#H= '#XA$\"XE#\"XE#\"H=!#HE%\"XI\"!HM##(I'" + "\"8A!#H=#\"H]!#(Q#\"8Q##(Y#!HE#\"HU!\"))%$(Y$#(Q#$H]&#X]!#X]#\"HU!!)%!" + "\"Y!\"#I!&$)%%$)%$#Y-#$XQ*#95!#9)!&9%($)1'!Y)!\"Y-\"#9)$%I%'#)-#\"I-!" + "$9)(!YA'&)-*!I%#!Y5!#Y)#%I-$$I5#\"Y1%#I)%#YA&$I1)#))#!Y5!#9-$#)1#" + "\"I1!\"I1!!)1$\"I-!#I1%\"Y!#\"H]!#I)%#9)!#))#$9) -$$)='#Y1##I9\"!Y1$" + "$)-'#Y)##I-%#99$!)-!#)-&!)-'$Y-+!9-\"%9)#\"X]\"$))'\"9=#$Y)!#Y%#$Y%(" + "!I%&#Y!##(]!$I!'#9!!%I)!!Y!\"$H]#\"9!##8I(#8]$$(Y'\"I-!$8U##(Q##8I$" + "$(U'!HU#$HU!#(Q!%(I)#H](#HU\"$(E(\"XM\"\"HI!\"XA#\"HE!\"(I%&(A(#HE%#XI!" + "#H9##8=!\"HA$$8=#!H1##(=!%(1&\"H1!#85%\"X1#\"8-!$(-#\"8-!\"X-\"\"X%#\"X%!" + "!H!#!H!!#8-%!'I!\"8%!\"GY%$7M)\"GM\"!'M!\"GU\"\"WU#\"WM!\"'I#\"8!!!75\"\"'I#" + "\"79+\"G5\"\"'5!!GA#\"'-\"#'=\"!G%!#')'\"'=,!W5$\"'-#\"G!#\"')#\"'%#\"6U#!W!\"" + "\"6]#\"G!%#'!$!VU\"!&Q!\"&Q#\"6]$!FM!!&]##&Q'!&Q!!6M$!6M&!&I!!69\"!G!#" + "\"6I$!&E!!6Y\"!FI#!6M&!&M!!F='!&Q&!&M!!VE$!VI$\"&I'!6M\"\"&I#!FE!\"6E&" + "#&Y%\"W)(!VU\"\"G!)!FU!#V]&!G9!!79&\"G-\"\"7)$!G1!\"G-$!W5\"\"71$\"'5#\"'5!" + "!71\"\"'1\"!G9!!7A%\"'A#!G1&\"GI$\"'A!#7I%\"'E'#H!&\"WY#\"WM&$GU%\"']\"!GY!" + "!WY!$H!+#W]'\"8!!\"X!#\"'Y#\"W]!!H)##X1'#H-##(5##89\"#H-!\"81!\"89##H1&" + "%HE%\"8=!$(9%\"X9\"!X9!\"XA#\"HI$\"XE(#(I#$(Y*$8I(\"8I!#85!#XM!!HM!$8M&" + "#(Y##(Q!#XQ!#XY##8Q$#(Q#$9%%#HY%\"X]\"$H]&!H]!\"8Y!!Y5!$I!)'I!'$)!!" + "#9%!\"9!$%95#\"9%&#I1(#9)$\"9-#!Y%!\"Y!#\"))\"!HQ!\"I)!$91\"\"I-!#9!!$9))" + "!)-'\"I-!$I5##)9#\"I5$#8]!#Y)##)1##)1#\"I9!$I-##9=!\"YA%$9-%\")5%\"I)!" + "\"I5!$)-'$)1!\"9=#$Y5!\"Y)\"#Y5&!)A!\"Y-\"#I=!#91$#I%\"#)-#%I5!#)5##9)$" + "#)1&!9-\"#91$\"I1!\"I1$\"Y9\"#I)%!I-#!I-##)-#\"I-!\"Y5\"#I)\"!))$\"))\"!)%!" + "!X]!$)!(\"Y%#$9%\"#I%\"#I)\"$Y-'#I%#\"I!!#Y-##I%)!Y%!\"8]!#I-%#)%#$(Y'" + "$)%%#XY#\"I!!\"8]!#(U#\"HA$#HU\"&HQ)&(Q*\"HU!#8M$\"8M!#8Q$#8Q$$(E(\"8E#" + "#(A#\"HA!%85'#(=!%(=#\"H5\"#H9\"\"89!\"85!\"H-'!H5#\"8=!$85$\"8-!!X)!#'U$" + "\"8%!\"8!!$H!$#(1!\"(%#!GU#!WY!\"WU#\"7U!$GU#\"7Q!#GI$\"7M!\"7M#\"GI%\"GI\"" + "#WE*\"'E#\"WA&#'A'\"'I\"!')!\"G9\"\"W5$#W-#\"'1#\"'-#!7-\"\"&Y%\"G5\"\"'!#!'%#" + "\"'%#\"F]'\"VY&!&Q!#&Y\"\"&U!\"&Q#!FQ!\"FQ%$VU*!&E!!FM%!VM&!VM$\"F9)\"&U)" + "!&M#!&Q!!&I!!&M!!6Q\"\"6]&!&A!!FQ#!VQ$!6=\"!6Y&!6M\"$6M&#FM)!FQ!\"&Q#" + "\"6M,\"6Y$#&]$\"V]*#FY)!F]!!G!!!&]!\"')\"!W)!\"7-&!G5!!'-!\"75#!G5!!G9!" + "\"'A#!G5!!GA#\"WA#\"GA)!'E!#'A\"#GU!#WM%#7M%\"7M!#WY'#7Y%\"7Y!\"GM\"#7]%" + "\"X)##']$\"8%!#8%$%(=&\"8%!\"8)$$X)#$()#$8%)\"8-!&X1(\"X=\"$H='$(=\"%H1&" + "!HE#\"X=#\"89!!X5'$8A##XI&\"8A&#(I!&(Y##HI(#(]#\"8M!#8Q$!HQ!\"HQ!$(Y'" + "\"XU\"#9!$$X](\"XM%#HU%\"XQ(#XU&\"8Y!#9-!#8Y$\"8Y!#I!\"\"9)#\"H]!\"8]!#8U!" + "$9%##X]!\"X]\"\"I%!$Y!*!I)##9-$$914\")1(#I-%#)-#!))$$)5$$Y1*#91$\"Y1%" + "$9=\"!Y9!\"9-#$9%)\"Y5\"&)-&$)5'\"Y%#\"I5!\"I='#)9##99$#)=##I9%\"YI!#)9#" + "#)9#%I9.\"II!#Y9#\")=\"\"I9!%)1($Y9$\")E\"#Y9#\"Y9\"!YA$$I9)\"I5!#95$\")5(" + "$)1'#Y=##Y9&$I5##Y9&\")9\"#Y5##)9##9=$#9-$!Y9!$)A'\"Y-\"&9-+!)-!\"Y-\"" + "\"I)!\"I-!#91'#))##9)$\"XY\"#9)$#9%!$H]#!I)#%I)!&I%&$9!%%I1!!X]!\"8]!" + "\"8]!\"I!\"$HU'!XY!\"XU\"#(Q##(U#%(U)$XE%#8I$!(U#\"8M#\"HU$#(Q!\"HM!#HU\"" + "!XE$\"8M!\"85!!H9!\"XA\"#(=$\"X=##HI%$89##X5&\"89#!H=&#(1&\"85!\"(5\"#H-%" + "$(!&#H)%#(5#\"()#\"8)$!G]#\"']\"#W]'#8!##WY'$X!)#7U#\"WQ#\"7Q!\"WM##'Q!" + "\"7I!\"WI#\"G=\"$7E$#W5*\"'=#!G=!$75,#W='\"'5\"!79\"#71(!W%\"\"G%#\"')#\"'%#" + "#G%$\"7)$!'!!\"'!#\"G%\"\"&Y#!VU\"!6M\"!FQ!\"6]&!6=\"!F]#!VM$!&U#\"FQ#\"&E#" + "!&M#!VI$!VU*\"VU&!6M(!6Q\"\"FQ%#6M$!FQ#!FI#!VMM(\"&M#\"&U#\"&M#!F]&" + "!FY(\"6Y$!7)\"#6U\"\"W)&!G!!\"G%##G)'!W)\"!'9!\"7-$#W5#\"'-#\"'9%!W-\"\"'=\"" + "!'=!\"G9%#7Q##'E$\"GI#%'I'!GE#\"WQ!\"'Q\"\"WM##GY$#WY)\"7Y##8!%#X%!\"X%#" + "#H)$\"H%\"%(5!#'Y!$8))#7]%#H-#$81$\"H5\"#89$#(=!#85!$(5($H-$#XMY\"" + "$(E%!(M!#89\"$HM'\"(E\"\"HM!!(I!\"8I!!(I$#8]$#(E#%(Q)$HQ)#XQ'$(U'#8A$" + "\"HI!#XY#\"8Y!#(]##9!!#8]$$)!(#Y%$$9%%$9%#%(]\"#9!!\"Y%##Y)##I-\"#8Y-" + "\"I1!$9-\"$)5'\"I1!#))#\"I1!!))!#9%$!I)#\"I1!%)5\"\"95##91!$)5$$I5)#95!" + "$9=%\"I1!\"YI\"\"I9!#99$\"I9!\"Y5\"#I=%$)9!$I=#$)='!YI!\"I9!%I='!)5!#Y9#" + "$I=#!)A$\"I=!#I=%#9=$\"YQ!#)=##)A#\"YA\"\"I5!#I=(#Y9&\"II!!IA#\"9=##Y5#" + "#)9#\"I1!\"IE!#Y9&\"YI\"#Y-&\"Y=\"\"I=!#I9%#)9##I9\"$Y1'&9A&#I1%\"I!'#)1#" + "\"91#\"Y1\"#Y1&$))$$I5#!I%(\"I!$\"I)!#))#$Y)!#I1\"#I%##8]$#(]!$8Y\"#Y-#" + "#HQ(\"XY\"\"I!!#(Y#\"Y1\"#8Y$$(Y(\"HU!\"XM\"#8U$%(I#\"XQ\"\"XY\"#(M!!HI&\"(I\"" + "#HE#!HI!#HM(#8=$\"X=\"#XE'!(9&\"XE#$X=&#(A'\"81!\"H1!#8=$\"81$$81&#(-$" + "#H-%\"8%!#H))$H)\"\"8%!\"X%!#8)%\"']%#(!!\"7U!\"'E#\"WU#!GM!\"GQ\"\"7Q!#WI%" + "!WM$\"GA$\"WA!\"WE#!'A!\"'A#!7A\"#GA$!G5!\"G5$\"W5#!G5!!'1!\"W)$\"G5\"#&Y#" + "\"'%#\"'%#\"F]##6M!!F]!#6](!G!!\"FU#\"6I$!VQ\"\"FM)!&Q!!&Y!!FM#!&=#\"FM%" + "!6U\"!6M$!6M\"!FQ##&E%\"&M*!VM$!6Q\"\"6U(\"6M$\"6Q$\"6E\"!VM\"!FY#!VU$\"&]\"" + "\"FI%!&U&\"'%#\"'!\"!W!\"!G!!\"W%#\"71$\"'-#\"7%$!G-!!F]!!G=!\"'-\"#GI#\"7A#" + "\"7=$!WI\"\"GU\"!GE#\"GU\"#'Q$\"7Y&!'Q#\"W=$#7Y%$GY#\"GY%!G]#\"H)\"\"H!\"\"(!\"" + "\"7Y!$(%%\"8)$$H-%\"X-\"\"X%#$(-(#H1##81%\"85!#(A#\"89!#(9##H=%#(=!!H=#" + "\"XA%\"HE$#H=%!HI!$XQ+#(I#\"8E!#(Q#\"8M#\"XQ\"\"HI$#I%%%9%*#8Y$#(U#%)%\"" + "\"X]%\"Y-\"\"8Y!\"I!!!Y!$#(U!\"I!!$))!!Y-!%I-+%9%&\"I)!\"I!!\"I-!$)-$#I1\"" + "\"Y!%#)1#!91\"\"I-!#HY%\"I1!$Y-+#95!$I5&#Y=&#IA%\"I9!#Y9&#I=%\"I9!\"I9!" + "#9E#$)M&\"I=!!9=\"$I=#\"Y9%#Y5)$)A!$)=$#I=\"%99\"%II&#Y9##YA#$IA##Y9&" + "!)E!\"I5!#9A$$Y=!$9A$\"YM!#IA\"$YI&$IA%#I9\"$YA'#Y=#$)9$#9E!$9=%\"IE!" + "\"Y5\"\"I9!\"IQ!#I=%%9I%\"I=!#)M#\"99&!)=!#YE%#99'$I9#$Y5'#)9##)9##)1#" + "$I=#\")-%\"Y)\"!I1)'))'\"I-!\"I)!$9-%$)-!#H]%#9)!$I)#\"Y)\"#I!#\"I-!$)!$" + "#I%\"#8Y$$8U##(Q#!X]!\"X]%%H]-\"(Y\"\"H]!\"XQ\"#XQ$#(Q&%(Q)#(Q#!HQ!\"8U#" + "\"HQ!#XY&\"8Y!!HI&\"X=##(M#!(=!#8E%\"H9\"!H9#$()##8I$%(5&#()!#H9&!(-!" + "#8-%#H-%#H9##']$\"8)!\"(%##X%!\"81!!(!$$H)(!(!$\"GY)#WQ'#7U#\"7Y#!GY#" + "!'Q!\"WM#!'Q!\"W9#\"'E#!WE!\"GA%\"G=%\"'=#\"G9$!G1!!W5\"!7-\"#71(!W1'\"'%#" + "\"F]%!7%'\"&]#!6Y$\"W-&#&]'!FY!\"&Q#\"&M#\"FI%$VY%!6M*\"VM&!&M!!&M#!FM#" + "!&Q!!&U%!FM#!6M\"\"6M$!&I!\"&M%!&M!#&U%#&M'!7%$!FQ!\"VY&#&U%\"6Y&!W!$" + "!6M$!FY!!&]#\"'%%\"'1\"!G1#\"V]\"\"W1&\"W5(!G9!!G9!!79\"!'5#!'=!\"GA\"!GA#" + "!GE!#79\"\"WI!\"'I!#WE#\"GQ\"$'Q##7U#!GQ!\"X)\"\"7Y!\"'Y\"$'Y%!H!!\"8)!#(%$" + "$H-%\"(%#%(!$#X-'\"X%#\"H%!#X1$#(5#\"89#\"X9\"#XQ&\"X=#\"89!#X=!#(E#\"HE$" + "#HA##(E&#(M#\"XM%$(M!\"HI!$XM(#HQ%#HY%$H]&#)!#$9!+#H]\"%Y!#$(]$%I!+" + "\"8]!#9!!#9%!!Y)$#9-!#9-!\")%\"\"I!\"#9-$\"I-!\"I-!\"Y9\"&)9##8]!$91%#)1#" + "#9=$\"Y1\"#I9%#Y5##Y5&\"I5!$)='!Y1!#I1($9=(#)9#\"Y9\"\")=\"!YI!!Y=!!Y=!" + "#Y%$$YA&#YA\"%9E%#9=!#95!#YA##99!$)5$%Y9%$YA&%9I)$)E$%9E)#)5##9E$" + "#YM\"$IE%$YI$#9A!%)E!#9E!#9=!#Y=#$95%&)M\"$I5##I=!$)I$$YA&$IA%$9M!" + "#Y5##YA\"$9=\"#YI#$)A$#)A#$)5$&9A.$IA($)1$#9E#\"I=!!I9##)A#!95\"\"II!" + "\"99##Y1&!)9!\"Y!##Y=#$Y5.#))#\"(]\"\"I1!\"I5!\"9)#!Y-!$Y%*$))$\"I)$\"I)!" + "$)%!$I)##9!!#9!\"$HE!$(]$#8]$\"8Y!#(]##HY%\"8U#!HY!#XU&\"XU\"\"HY!\"89!" + "\"8M!#HI##XM'#XAQ$\"XI\"!H5##(9#\"XA#!H5#$X=%\"H9%$X9#%(=#$X5&#(5&" + "$H1*%X%'#(-!$(-%#8)%#H-&\"8%!#()$$(!#\"8%!#X%!$']&\"WU#\"W]#\"7U!$'U#" + "\"WQ!!GU!#'I$!'I#\"GI\"!GM!\"'I#!'E#\"WM#!W)!#'9&!G9!#'5\"!G5#!')!!7%&" + "\"G-%\"W)&!79%\"')#\"7)$\"7-$#&]&\"&U!$6Y%!FQ!!W%!\"FY%!VM\"#6E\"!V]\"\"6M&" + "!FU#!&M#!&Q!\"6M(!6M\"!&=#!VM$\"VE(\"VM$!V]\"\"&Q#\"&U#!6U$!FM!!&Y##'%%" + "!G%!!W%!\"7%$!')#!')!\"G-%#'1&$'I!!G9#\"79+!75\"\"W9&\"71$\"W-&#'U\"\"7E#" + "!WM$!'E#!GU##7I#\"WM(!G]!\"7U!#'A\"\"X!#$7]*#X!'\"8!!\"WI##(!$#H%&!H!#" + "$8)$\"X)%#8-'#(5#!H5!!(=!%XE)\"89#!X9$\"H=!\"X=%#H5&\"HE!#(M#%8I'#HE#" + "$HY)%(E+\"8]!\"8M!#(Q#\"XY\"!HI&!8I\"$8Y&\"8I!\"HI'\"XU\"#HY%#(])#8Y$#I!#" + "#9!!#H]\"#I%\"\"Y-\"!))!$))!$9=%$9-)#I)\"#9-$\"I1'\"I1!%Y=(#))&$95\"#)5#" + "$I9)#)5)$I9)&91'\"I5!%Y=$!)='\"Y-\"$Y-!#95!%9=)$IA\"$9=%%)A(#9A!#91!" + "$)E#\"IA$#9E!#IE\"\"II!$9E$%)A%%)E$&IE.#)=#$)='$IA\"$)A!#9E!%IM&$)E$" + "$)Q#$9I\"$)=!$IA#&9I'#9I$$9I$#9I!$9M!%)A+#IE$\"IE!$IA%%9=\"$9=%$Y=$" + "$)I#!)E!#YQ##9E!#YE#&)A(!YA$%)A(#YA#&)A\"&9I&#IE\"$Y=!$9=(\"IA!\"Y1\"" + "$9)\"!YA!#I9%#)%$#Y%#%95\"\"I)!$)5'\"I1!\"9%$\"I1$#Y)&#)-#$91(\"Y-%%)-%" + "\"8]!#99'#)%#%Y%,\"I-!$)!!#9-!#9!\"!Y!!$HY##(U#\"I!$#(Y##(Y#%(]%#XU#" + "#(Q#!XQ!#(Q##8I$#HQ%#8Q!#HQ\"\"XE#\"8I!#XE&\"XQ%#X9$\"XA0\"X5#$8-)!H9!" + "#(=!\"XE#\"X=#$(1#\"7]#!X1!#8%\"#H)$!(%!#H%&\"H!\"\"X%#$8-'\"H%\"\"7Y!$(!(" + "\"GQ$\"7E!!H%!#WM'\"7M!#7M#!GI#!WY$\"GA#!WE!!GE!#7I(\"W=!\"G9%\"')(#71$" + "#G%\"!'%!\"'A'\"G1\"!G%#!'!!!G!#\"G1#!FU#!FY)#&U%!&U#!VY\"\"VQ$\"FQ%!FM*" + "!VM$\"FI'\"&Q#\"&M#$&M)\"6M$!VM$\"&M##&M!\"&U##VU,\"&U!\"&U#\"FU%\"&]#!FY&" + "#')%\"G)%!FY!$7-%\"')\"\"G1%!W1(!G5%\"G9$!'9!!G=!\"'=#!G1!!W=\"!GA!\"7I!" + "\"7M!$'M(\"7M!\"7I!#WQ%\"WY#$GY%$'U#!7Y\"#W]$\"X!#\"X%#$(%%\"8)!#()!!X-$" + "\"X-#&H9'\"H5'!H5!#H)&$8=##89$\"X9#\"X=#\"8A!%8A-#(9#\"HM!#XE##HA&\"(A\"" + "\"8M!\"HA!!HI!#HQ%#HM&!XQ$$8U##XI#\"8Y!#XY##9%!#Y)&#HY%#9%!!X]$$9!&" + "$I%'#)%$%)9%$I!*$Y%!!)-!#Y1#$8](#)9#$I5,\"Y1%#I5%#95!\"I1$$95(%II&" + "$)A!\"I9!!)=!\"I=!\"Y5\"$9=%$IA#%9E\"#Y9#$9=+$)=$$)A$!Y=!$YI&#YA\"$Y=#" + "$IQ%%IE$&)I,$)I#%9I%#YM#\"II!#YI\"#)Q\"#9I!#YM\"$)I#%IQ)&)I,$9Y!%II#" + "#9M!#9M!%IA*%YA$%YQ!$)I#\"YM!#)=#\"IM!#9A!#YM#$9U$#IM\"%)I(%)M!#9E!" + "#)I&#)M##Y9#'YI*#II\"#9E!#Y=\"$)E#&9E#%YE+%YE+#9I!#9A!%IQ#%9A\"$)=!" + "#99!#Y1#!9=%#)9#%9=\"$)5!\"Y=\"\"Y=\"#I=%\"Y-\"!I%##)1#\"I1!%)=$#))&!(]#" + "\"Y1%!I-##9)$#Y-&$91(#Y))#Y)##H]\"$I)#%I!!$X]*#9)!\"X]\"!8U%$8Y\"$(Y$" + "\"8U!%HI%!XM!$(Q(\"8M##Y!'#(M&#(I'#(E$\"(U\"!(E!\"HE!!HI!$HA'!H=!\"8-!" + "$89#\"HA!#89%#(9#\"81!\"(1\"\"(-\"#(5#$8).$()(\"8%!#7U%\"8!!\"GY$\"7]!#GY&" + "\"GY\"\"WU##GQ&!GM#!GI#\"GM\"\"GI\"#7I%\"GE$!WA!\"'A%%'9#\"7=#$'A&\"'9#!W5\"" + "\"79&!W-\"!G1!!W)!\"G)%!'%##G%\"\"&Y#!VY\"!&]!\"6Y$!FU!!VU\"\"&Q##6]#!FM%" + "!FQ!!6Q$!6M$!6Q\"!6E\"\"W!&\"VM$!&I!!VM\"\"VQ##FQ)\"6Y#!W%\"\"7!\"#7)##'!%" + "\"'%\"\"'1#\"G%##G-)\"71(\"W1!\"G-%\"79$!W9\"!G9!\"W=##7A#$'E(!'I!\"GU\"\"G=%" + "\"W=#\"7=$!GE(\"WU##'U$#'I!#8%%$W](%8)(#'Y&!(!!\"']#\"(-#%'Y$#H-##X-'" + "\"X9#\"(5\"#X=#\"8)(\"X=##X5'#X=!\"8=$\"8A!!HE!$XE%!HA!\"8I!$8I)$HE*#8M$" + "#8Q2#8Y$$XQ*$HU&\"HM!$(]'\"(U\"#(]#\"H]!\"8]!$Y!!#9%!\"I!!#)1#\"9%$$))%" + "#9-!#(]!#))#\"8Q!$9A(\"I5!$99($I-##)I##YE&!I1&$99(#IE$\"I9!$I9\"\"I5!" + "\"IQ!\"IE$#9=$#9A!%IE$!YA!$)-$$II%$IE&$YA&$IQ\"$)I!\"IM!#YI#\"II$#9A!" + "\"I9!#YM#%9M)#9I#\"II!#9I!#IM\"$I=##)Y#$9I!#IE\"#IM+#YU)#Y=##9Q!#9M!" + "#9M!#9I!\"9U#$)Q'%)U'%)Q*$)A!$YU#%9M)#9Q!%IE##9M!#9E$$IQ&$)M#%YE$" + "#)M%#IM!!YM$$II##YM#\"IU!$)E#%)A!$)Q$$)I'$II##9I!$IE#$9A!$II&$IE%" + "$9A%#YA##IE!$YE*#9=!!)A!#9A'#9=!\"I9!%99#\"95#\")1%\"I-!!Y5!#Y%'$I5)" + "$(Y'#91$#9)!$9-%!)!!\"95##9)!\"8Y&%9-#$)!%%)%&\"Y!\"#(]!#(]#\"9!#\"H]$" + "$(M%#8M$#(M#$(Q(!XQ!#(Q#\"8U!\"9!##8M$!(=!#8E%\"XI\"#(I##(='\"XA\"\"8=#" + "\"8A#!(=!$(9\"\"X=\"$(=\"$(1(\"X%#!8-(#H-&!H%%$8%$\"8-!\"W]#\"8%!#7Q&\"W]#" + "#7Y#\"WY!&'E$#7U##'Q$\"7M!\"WQ#\"'A!#7M%!WE\"!WQ\"\"79\"#G=$\"GA%\"G)!!W9\"" + "\"GM$%7)'#'-&!'-!\"7!$!W-!\"'%#!FU!\"&U#!F]!!W!\"\"&U#\"&Q#!FU#\"FU!\"&I)" + "!FM!!6M\"!&]!!&=!!&M!#6M\"\"6]$$&Q'#6Y(!&U!\"&M#!F]!\"6Y#\"6Y$#'!'\"'1#" + "!G)!!')$!'-#\"G-%#G5'!G5#!GE!\"'=##G9\"\"W=%!GA%\"7A!!'M#\"WM!\"GA#\"GU\"" + "$GY*\"7Y!\"WY!#7Q\"#8!%\"7]!#']!!WY&\"7U!\"7U!$(-%\"X!##H)#$(!*#H9&$X-\"" + "#X-!#85\"#H)&\"X9#\"H5!#(='\"8E!!H9!$8A##(Q#$8M##XI&\"8=!!)!$#HI#!XQ!" + "$HU$\"(Y%\"XU\"!X]!#(U!$I1##I!&#)!&$))$#8]!$9%#'I%'\"I)$!I-##9)!$I9#" + "!Y)!!Y-!\"I1!\"I1!#))#$I5&\"I5!!I5#%I9#\"Y9%#)=&#Y9&\"II!\"I=!$I1&$YE#" + "$9I%')5*#9E!!YE!$IE&$IE%&YQ($IE#$YM#%)I/$9M!$YA$$IE##YM##YU\"%)U'" + "\"IM$$IQ)#II!%YM.#9Q!$)Y##IM!$IQ&$IU\"$)U##9Q!$IQ&#YQ##9Q!$)U#$)Q#" + "\"IU!$YQ##YQ#$9Q!\"II!$)M$')Q*$9I!$)M#$II%#YQ#'9I(#IU!$YY&\"Z!\"#9U!" + "#YQ#!YE!$)U#\"IU##9I!$YI$$9M$#9M!%IQ'$IM\"#YI#%)5!#9M!#II\"#YI#%9E)" + "#YE#\"IE!%9M)%9=*$99%#YI#\"YA\"$Y1!#Y=##99!#9=$\"9I&$9=%$Y5*#)9#\"Y=\"" + "%9E)#)1#&)5##I1%$)5*%Y)\"$9-(#X]&!Y)!#(Y&#I!\"$I)'$))!$9!%#I%\"\"8]!" + "\"X]\"\"I%!$I!##(U&\"HU!#(U#!XY$#8U$#9!$\"8E!\"(Y.#XI'$(I!#(A!#(M!\"XE#" + "#(A##8=$%(=)\"X9##X9!$(1&#(5#\"89!#(1$$()%\"()%#8)%%8%#\"H!\"\"8!!$'Y%" + "#7]%$(-#\"7Y!#(%$#7U##WU\"#7M%#'E+\"GE\"\"GE\"!GE!\"'E#\"'9!$'=&\"'9\"#'9+" + "\"'E#\"W5#\"'1'\"71&!71$\"&U#\"'-!\"&Y#\"W%$\"G%!!F]!\"F]#!&]#!FU!\"&U#!6Q'" + "!VQ$!VM\"\"VQ*!&Q!\"6M$\"&U#\"&I!\"&U#!G!!\"&]'!V]\"\"W!&!G!!!71\"!')!!')!" + "\"'-\"\"'-!\"'-#!'!%\"W1##GI#!'5!!GI!!'E!\"G=%!WE)\"7=$#7I!!WM\"#'M$\"'M\"" + "$7Y$\"GE#!X%$\"GY\"\"7]!\"8!!\"89!\"(!%#(%'\"H)\"\"8)#$X1&#X%$\"X1#\"(-($(1#" + "#X5!\"89##89%#85%!8=\"\"H5\"$HA!#8=$%8]#\"XE\"\"XI\"\"(I\"#XE!#(Q##HI%!HU!" + "\"HQ!\"8Y)!HM#\"8]!\"8U!\"X]\"$9%%%Y9!\"Y!\"$)%%$Y!'\"Y=\"$))!#Y-#$I-)\"I-!" + "$Y1*\"Y1\"\"95#$)1'\"I5$#95$#95$\"I9!#)9#\"I=!%)=(\"I9$#IE\"!Y-$#9A!#9I!" + "#I9\"#IE%\"I5!#)I#\"IM$$II&$9U$#)A#$IQ&&IM(%)M!%9E Q!#YQ#$YQ'%)Q!" + "%9Q($YY#%9Y\"&)Q(&IM$%)Y'!YU$#YM#%)U($9U($9U$%9Q($9U!&YY%%)Y$$9U$" + "\"IU'\"9M#%YE!#)]#!YQ!$YM##I]!&Y]$#)Y&\"YU$$)Y##II\"#9Q!%IU&\"9Y##IY!" + "&9M-#YQ&$Y]&$YQ'$YQ##9Q!\"YQ!#9U!#9Q!\"YQ\"$IM&$)A-#YI\"#9Q!$II%#IM$" + "\")A%\"YM\"#9I!$Y=!$9E\"$)5$#YA#%)9%!YA!#9=!#9A!#99!#)A#%IY*\"I9!\"Y9\"" + "!Y-!\"I9!&)=&!)1!!91+\"I1!#91$#I5\"#I-%$H]##9)!#))#\"I1!\"Y-\"$9%&\"I)!" + "$8U\"#(]#!(]!\"I%!#8U$\"8Y!#XU&#HE#$HQ&#HQ%#(Q##(M#$HI'#(I##(U##(E$" + "\"X=#$XA(\"8=##(9#\"(9%\"X5\"!H5#\"X5\"#89%#85$$(!(#8-*!G]#!X!$\"X%\"#8)%" + "\"X!#\"GY'!'U!\"7U!\"7U!!']#\"WQ#!WQ!$'U##7I!\"7E!!GE!#WA%\"'A*\"'A#!79\"" + "\"75(\"W9#\"G5%!W5$!G=%\"7-$#')'!G)!#7)&!G-%$7!#\"&Q#\"7%$\"FY%#FU\"#FA#" + "!&M!!&M!!VI$#&M#\"FQ!!&M!!G%!!6U$!FU!\"&Y#\"&]#\"'!\"!F]!!G!!!W)\"#W!!" + "\"'-##'1&!'1!!G9!!G5!\"7A!!GI!\"7A$\"7Q#\"7A$\"W9!#7Q%\"7Q!#'U$$'Q&\"GQ\"" + "!'M!\"7Y!\"7Y!\"7]$\"7]!\"'Y##'Y$!X%!\"X)-%$(9(#8-%#H9#!(I$#85%#(E$" + "#89$#H=%!HA##(I#\"XA%#(A#$89!\"(I\"\"HI$!(I)\"Y!#$8Q(#HQ&&HM*#(Q#!HM!" + "$(Y!!Y!'#)!##X]&\"9)#$9)\"#XU#!Y%$!Y)!$)1'!X]'$91%\"I-!$Y1!\")-\"\"9%#" + "\")5\"$I1)#IE%#Y-&$I=)#)9#\"Y5%#Y9#\"IE$%)A%&91$#IA!#YE\"#9E!#)E##9M!" + "\"II!#)I#\"9E##IM\"$YE*\"9I#%YQ'#I]!$)U##9Q!#9I!#I]!#9U!%)Q$%IY)#Y=\"" + "%IQ*%9Q($)Y#%I=#%)U'$)U#\"IY!$)Y##9U$#9U!%I]#'J!'$)Y#$9Y$$*%&$IY&" + "!YY!$)Q#$Z!##Z%)$I]%$YY##YY\"\"YM\"$IY&%YI!#IU\"\"IY!$)M$$9Y$\":!#'9]+" + "%9Y(&YU$#YI#')Q%$IU%$IU%$)U##J)!\"9E##9U#$J%%!YQ!$9E\"$IY\"$)I#\"9M#" + "\")I\"#9I!$YE U!$9A$$I]\"#99!#YI##9E!#IE!#YA#\"IE!#9A!#Y9##I9\"!)5!" + "\")E%#)9##Y=&$)1'#)5##)5##))#\"I1!\"Y1\"%)I!\"I-$\"I-$$)%'#9)$\"Y%#$))$" + "$Y%%$I)##X]!'I%*&(]&%HY$#8Y$#(Q#\"HM$#8U$#(]&\"H]!\"(=\"#XQ##(I#\"8Y#" + "$(A(!(A!#8A$\"H%!#X='#H=##(9!#X=$#H5&\"X-#!(9!\"H)\"$H-*\"8!!\"8A!\"8%!" + "!H!#\"(!#!GY#\"W]!#WY$\"7U#\"7Q!\"WU#\"7Q!\"WM#\"G9\"\"WY##7]%\"'I#!7A$!'9!" + "\"'=##'I$\"75$!G5!!71\"\"'-#\"'-#!'!!\"7-$!G!!#'!%\"VU#\"&]#!FE!!F]!\"&U!" + "!&I!!FM#!VE&\"6Y&\"&Q#\"6=(\"'!#!F]!\"&]##'%'#6]$!W%$!7)%!G)!\"G-%\"W1#" + "\"'1##'5\"\"75$!'9!!G1%!G=!\"'1#$79%!GE!\"WQ#!7E\"%GU&!GE&\"'=!#X)'\"7U#" + "\"GQ\"#'Y$\"WQ#\"8!!\"W]#\"X1#\"(%*\"()*\"8%!#81%$X-+#H!!%(=)!85\"#H=%#(=!" + "#XI'#8A$!HA#\"X=\"\"8E!\"XQ\"$HM*\"XQ%\"8A!#H]\"\"8Q##XQ#\"XE#\"8U!\"8Y!\"Y-\"" + "$H]&\"I-!#(Y!\")!##9)!#9%$\"9)&\")1\"#I)&$9)(\"Y1(#)9##))##91!!Y5!#I5\"" + "\"I9!!Y9!\"I9!!Y=!\"II!#Y=##YA##Y9#$IA#&I=(&IE$%)E(#IA!'9E+%II##99!" + "!)Q!#9M!#9=!'9M'$)M$#YQ#%II#$)Q$#IM\"#J!!%YE!$)Y##IY!#IQ!$9Y$$I]&" + "&IY.$:)!%YM.%)M($Z!&\"Z!\"%9])$:!$$I]&$J%&%)]($:-#&)Y!$:!$#I]!$:)!" + "#I]!$9]$%IY*#J)!#J)!%YU!$IQ%#IY!&*!$%*-'!I]#$9U$#Y]\"#YU\"\")M%\"I]'" + "$)Y##Y]\"#IY!#9U!#9Y#\"YY!$9]$')Y\"$)Y#\"YQ!#9I!#9U!\"IE$%)M!#IY!$IQ&" + "#9Q!#)Y&#YQ#%)M($9Y$%9I%$9E%#YI#\"YM\"!9I\"#IA\"%9E\"#Y=\"$)A!\"9E[!" + "#9A!&9=&%Y=!\"I=!\"IE!#Y5##I9\"\"I9!#Y=\"#I-%\"Y-\"#91$#9%$!)5!!Y)!\"I)!" + "\"8U!$Y-(!Y%!$)!$\"I!!\"H]!!Y!!#XY!&HY)#)!##8U$#8Q$!(Q!#XI##HQ%#HY%" + "#8I$#8M(\"XI\"#XA!!8E\"#(A!#85%#X5'\"89&\"85#!(5#%(1$\"(1##H5&$8!)!(5!" + "#(%$#85\"\"8-!\"WQ#\"7Q!#GU$\"X%\"\"WU##WU%\"WY#$'M!#'Y$#WQ'\"WM#!G=!\"'A#" + "#'I'!W=\"#G1$\"79&!71\"!W%$!W1&!'-!#')\"!79\"!W%\"\"'5#!W)(#F]'\"&Y!!FU!" + "!7!%!FY#\"VI&!FU##&Q#!6U\"\"6Y#!F]!!F]!!6]\"\"&]\"!G%!\"'5\"#G-)!'9%\"'%#" + "\"G1#\"75,!W9\"!G1!!W5\"!W5\"!GQ!!GE!#7Q#\"'Q##8%*\"7U!\"WQ#\"WU#\"GY\"!WM)" + "\"W]#!G]!#()$\"'Q\"#(%&$(%(#H))\"(1\"\"H-!!X)!\"HA\"\"85!\"85!\"XA#\"X=##(E$" + "\"X=#!HA!\"8A!\"HE!\"(I%#HE%%8M'#HQM$#(U#!)!!$)%!#(I##XY&#(]#&)%*" + "#8]$#91!$Y%!$I!$$I%'$Y)(!Y%!#I-\"#I-%#)9##I%%#)-#%I9.#)9##)A&$I9#" + "\"I=!\"I9!!YE!!Y9!$YU'#9M!$IE##9=!!IA&#YM&$)I$%)E!%)A$$9A%$9M!%)Q$" + "%)M(%YQ$!YU!#YM)$YI*$)] Q!#IY!#IU!$Y]&$9U!$)]#%*%'#IY!$IY\"#:!#" + "#Z!\"#Y]\"#I]!$Z!\"%)]$$9Y$$*%##J%!$Y]'$:!$%J)*&*%!$J%&&*!($9U($I]%" + "$:%$%*-'#YY\"#J%!$*!#$9Q!#J%!\"YQ!\"J%!$:-$#IY!%*1##J!!!*!!\"J!!$J!%" + "%)](#9]$#I]!$9U$%)Q!!YQ!#J)$$YM#$)Y#$9U$$IY\"%)Y!#9M!&)](#9I!$)U#" + "$9M!&)U$#)U##9Q#$*%##J%!\")M,$IU%$)M##YM&$YI&\")E\"\"II$$YE##YE#%)-(" + "%)E$#IA!&9M&\"I1!\"YM\"\"I=!\"99#!)9*#9-!\"I1!#95!\"I9!#))##I)_$\"I)*" + "#(Y!!Y-!!)-!#I%##I%##I!#%)1(\"I)!$8]\"#8Q!#(U#!(U!!8U(!XQ!\"8Q!!HE#" + "\"8E!$HI$\"8I!\"XE(#XY#!XA!#H5&#(I##(5$!(9!#(5$$85&#H)#$X1#$8-&\"X-\"" + "#85'!WQ'\"8!!\"X!#\"WY!#GY!\"X!#\"(%%#']$#'U'\"WM##WA'\"WM!!GQ%#'I$!GE#" + "$'A&\"7A$\"'=!!W%\"!G=!!WA!#W=%!G1!\"7%$!'E%!G)!!FY!!F]!\"6Y$!F]!\"6Q$" + "!&M'!FM!!FY!\"&U#\"&U#\"&Y\"!FU!!V]$!'!!#&]'!'%##7-#\"75&!G-!#7)#!G1!" + "#'5&!G-!\"GE#!WA!#7A(!GM!\"7I##GM&$'Y(\"WA!\"WQ%!GQ!!WQ$#7Y%!W]!\"7]!" + "!'U!#W]%\"X-##85%#()$\"85!\"(%#\"8!!#(1!$(9(!H-!\"89!\"X)#$(E'\"(=\"#XA'" + "\"8A#\"X=#\"HE!#XY#\"XM\"\"H9!#(I#\"(I%\"8U!#9!!#8I\"$XU$\"(]\"\"Y%##XI!%)))" + "#9)!$)-$$Y-$\"I-!\"Y%##)1##Y5##9=!\"I5!\"Y1\"!Y-$\")5\"$I1&#Y)&$9I%\"I9$" + "#)5##YI##99!#)E##IE\"#IE%!YI!$9A$#9E!$9M!\"YM\"#9U!$)A$#YQ##9A!#9U!" + "$9I$#)U#$9]!#II\"$99%#9]##J!!%9Q)&9Y\"$Y]'$9]$\"I]#$:!$%YI!#9U!#Z)\"" + "\"9]\"$J!%$JA!#J!!#YY\"#Z!%$:!!\"Z%$\"YY$!Z-!$Z)##J-!$IY&#J!!%)]!%Y]'" + "$J!&$*%##J1!%*!#%J-%!*%!%)I%!*-$$I]\"#Y]\"#9U!$*-#\"J%!#J)!\"YY\"$*!#" + "$*!#$*%##J!!!YY!#J!!!YQ!$*%#$J!%$)]##J!$#J)!#)]#$)]#&:!&#IU!#YY\"" + "%Z%+%9U\"$9U$#IU\"#IM%\"J%$#9Q#&II($9]'$9Q!$YM#$YU#$II%#9Q!#YE\"#9I!" + "$)=$$)A!$II&#)A&$YA$$IA\"\"I=!$YE&\"I1!#))##)9#\"))\"\"I5!\"Y-\"\"XY\"!Y-!" + "\"91##)-##))#\"Y-\"#)5##Y)##(Y!#9!!&Y!.\"X]\"\"I!!\"HY!#8]'$(Y'#XI'!8U%" + "#XQ&\"8Q!!H]!\"8Q!&(M!#H5#!HE!!8M%\"HA!#H9&\"H=\"#81%#X5'#(5!\"X-\"#8-\"" + "$(-(\"8%!$(5&#H%&!H!#\"8!!$GY#$(!%#'U$\"WU#\"GA#\"GQ\"\"7M!#7M%\"7]!#7I%" + "!WU\"#'5'\"'E#!G=!\"'9\"#'9$\"'5#\"7-$#71%\"G5$\"'-!!G)!!G%!\"G%#\"FM#!FY!" + "\"'!##&Q$#&U'!FU!!&]!\"&Y\"!F]!!G!!\"'!#\"'-#!')#\"W)\"#7)#!G1#\"'1\"!G=!" + "!W9\"\"7M#\"'=#\"'Q#\"W=%#GM(\"GI#\"'E#\"WQ#!'Q!#'Q$!'E%\"7U!!'Y#\"W]#\"W]!" + "\"WU#!X%$\"8%!#X%'#81%%(-'#X1&\"81!$(5(%(=&#(=!\"H9!#(=##HA\"\"XQ\"%8=$" + "\"8E!!HM!\"8E!!89\"#(M#!XM!#(U##(Q#\"XU\"%8Y&%)!+!HY!#(E$$XU%%)!##Y1#" + "#)%#\"Y)\"\"X]\"!)1!#I5%$)9$\"Y1\"#Y9#!Y5!#YE%#Y5##I=%$9=%\"IM!#YQ)$)A#" + "#YE#%9Q)%9A\"!YA'#YI##YQ%$)U#$YA$#YM\"#YQ)%)=!'9M+$9Y!#9U!#IY!#)Y#" + "\"IM!!IY#%YU*#YY\"$*%'\"J!!#)]##I]!%9])#9Q!$*%#$Z!#$:!$'Z!%!J!##Z!\"" + "#Z%&#J%!#Z%\"#J%!!Z%!%IM&$J1%#J!$\"J%!$*)#%:1!$J)\"#J1!$Z!\"#Z!\"$Z!#" + "#:1##I]!%Z)##J)!#Z)\"\"J!!%J)\"%Z-#$J%!#Z-\"$:-$#*5\"$:%$#J-!#I]!$*!'" + "%*%##J5!$:%$$:%$$*1#\"Z-!#)]##Z!\"$)]#$*%#$9U!$*5#$Z%&$)]#$)Y#$)]#" + "$I]%$)]#\"YU\"$9Y!$I]&%9Q(%*!!\"IQ!$IE%$9Q!%9Q($Z%#$9Q%%IQ##9I!#9I#" + "%II*#9=!$)I!$95%$9U!#Y5#$IA%%99##Y=#%9A#!9I)\"Y1\"$Y5*\"9M#\"I5!\")5%" + "#I5\"$I-'#)5#\"Y-\"#Y)&\"I%%%9!&$I) !!#Y!#&(Q'\"I!!#HU%#8U$#(M##8M$" + "\"8Q!#8U$#XI'\"XM\"#(I#!HI!\"XA#\"XE\"!HE!#(A$#(I#\"XA#!(9'#X5Q\"\"(1#" + "\"X1#!8-\"#H)%#H)%%'U\"!GI!#7Y\"\"G]\"\"W]#\"'Y%\"WU##7Q&!WE$\"7U#\"7E!$'M&" + "$7M&\"'M#\"'9\"!7A$#'5&\"G9\"\"71&\"W5+\"'1!!'-!\"G-\"!G-#!G)'\"'%!\"7%$#VY$" + "!&Q!\"W%#\"&U%\"F])!VU\"\"F]%!V]&$FU)!G%%#7)%!W1\"!G)!\"71#!G%'!W5\"\"G=#" + "\"G-$\"'E!!G9!\"'A#!WA\"\"'A!#GM$$'M!\"8%!#7Q(#GU&!GY!#'Y$!WU$\"7Q&$H!\"" + "#(%$$X%#!X!!\"8)!!8-%#(5#\"89!!(5!\"X5##XI##(=#\"H=!#8A!$(=%\"XE#!(9#" + "\"XY%#(U##XM!\"X]\"$9!($(]!\"8M!\"HM!!HM#\")!##(]#\"I!!#Y%$$I!'!Y!!#I!%" + "\"I)!\"9-#$Y1!#I)\"\")=%$I1#\"Y5\"$)9!#95$%I-$#9A$#Y=#\"IE!$)I#\"I=!$9M$" + "\"Y=\"%)I%$9Q!#9Q!')I*\"YQ$\"9M&&)I\"#YQ\"\")Q\"$9I\"#I]!%)E$$YY#$)U#%)Y!" + "$)Y#%)I%#IY!$)]#%I]*$I]%$J%!$9]$#Z!\"#Y]\"#J)!$Z%&#Z%\"#Z)\"#YU\"%:)%" + "%*-#%:)($*-*#Z!\"#Z)\"$*)#!:)\"#J-!#Z-\"#Z-\"%*-'$:-!\"Z1!$:-!#Z1\"\"J-!" + "&*-'#*)\"%Z5-#J1!$:-#$:-!$*%##Z5\"$Z1&#J!!#J%!%Z-#!*-!\"*)%#Z1\"&:%%" + "%*)'!:-%#J)!&:5)!Z)!$Z%&#J)!#J!!%:%!#J%!#J=!#J%!$:!!#:5#$Z%&$:!$" + "$*%#$J!%#9U!#9]$$*!##IQ\"\"9I&$YU'%IY&#)A##IQ!$9]$%)U(#YM#&)]($)U#" + "#9U!%9=)\"I-!#YI#\"YQ\"$IE#!YE!#YI&\"9I#%YQ!#Y=#\")=\"\"Y=\"$)9!#)9#!)1!" + "#)-#$I9##I1%#)-##I-%#))#\"Y)\"\"I)!$9%%$I5&#I!%#(]##XQ'!Y%!!9-\"#X]&" + "\"XM\"#X]&$8I#%8M*#(M#\"HY!%(I#\"89#$8E&#(A#$(E$#H9#!H=+%HA##X1'$X5+" + "!H1#$(-%#GY#\"8)!#X-'\"8!!\"X!#\"7]!!G]!\"7Q!\"WU#\"GY\"\"7U$!'Q##7Q%%7I(" + "!GM#\"WA#\"'Q\"\"7A##'9$\"7=!!GA!\"'9!\"'-!\"79$\"GA%\"71$\"6]$#&]\"#7!&\"&Y#" + "!FE!\"&M#!6Y\"#&Y#!F]!!F]!\"7!$!VQ\"!G!!#7)'\"'-#\"G1\"!'5$!G5#!G9!!WQ$" + "\"'=#\"GA##'9'\"GU\"\"GU$\"'I!!'M&\"'A!!WQ!#7U%\"W]##8!%!7U\"\"WU#\"X)#\"H-\"" + "\"8!!!H-!\"(!##(5#\"X-##(5$#H5&\"HE!#(5&$HE*#8Q$#(I#\"8A!\"8E#!(A#$(U!" + "#HM&%(Q##(Q#\"8M##(U##(U#\"Y%#\"XE\"#XY&$))!#9%!#(U!!9)\"#XQ#$))$#9%$" + "\"I1!\"8]#$Y%'$)1$#95$#I5\"$I=&#Y9#\"IE!\"9A#%)M!$Y=#%)A(#9E!$9E%#9I!" + "!YE!#II!#9M!$YU M!$IQ\"$)U#$IQ%%*!$$IY%$IQ&$:!!%)Y'\"IY$#Y]\"!9]&" + "!9U\"$9U!#J!!%:!$$J!&#Z!\"%:%!\"IY$&J%&$J))%*5#$*%##Z1\"%Z)'$Z1&\"Z)\"" + "#Z%\"!:-)#J-!')]&$:%$#J%!!:1\"#Z)\"#J-!!Z-!'J1*$*)#$Z1&$:!!$Z-#&:1%" + "$J5!$:1##J5!\"*5\"%Z1&$:1!#J1!#J-$&:--$:1$#J!!&*-!\"J!!!Z-!%J-\"#Z)\"" + "%:%!#J9!%J-\"#Z-\"#Z!\"$:%$#Z)\"#YY\"$I]\"$:1##J)!$:)!#Z%\"!*!!#Z%\"$)U'" + "$YU#%)Q$#Z!\"#Z%&$J%%$)]##Y]\"$9Y$$)M##:!#$*!#%)Y+&)I\"#I]!%*)$#Y=\"" + "%)Q!$9Y$$)A#$*)#$)Q##YI##IQ%#YE#$)E$%9M%$YE'#YE\"#9-!\"IA!$95(#Y5#" + "$)9!!Y1!\"I9!\"Y1\"#)=#!Y=!#)-##)%$$))$%9%*$)!!#Y-##I!%#)%##(]#$8U\"" + "&)%*#XQ!\"8Y!\"(Q%#I)%!H]!#XE&\"I!!#XE&\"8E!#89!#(I$#89%#(A##(9!#XA!" + "#(5!\"X)#\"81!\"X-#!H1!#H%(\"X)#$X5%\"H%!$'U#\"8!!!GY!!X%'\"GY\"$'U#\"7U!" + "#WI%\"7I!\"GI#\"'9#\"GE%!G9!\"G=%\"'5\"\"W9(!G1!\"G1%\"7-$#'-%#'!'#W)##'!'" + "!G)!!&Q!\"F]#\"&U!\"7!\"\"6](\"'!#!W)\"!G1!\"'!!!'5#!71\"\"'5!!G9!\"G9\"#'-'" + "#G))!'=!\"GA$\"7Q&#WE%\"WM#\"WQ##7E(\"WU!\"7U!#G]!!WQ$\"(!#\"H!!#(!$#G]!" + "\"8!!\"8M!\"X1#\"85+!X=&\"X=#\"X5\"$H9$\"XE\"\"XI\"#(5$#(E##XM$\"HI!$(I%#8M$" + "#8E$#)!#\"(I\"\"8Q#$(Y(!HY#\"HY$#X]##)!'$XU!$8]\"!Y)!#I%\"#I)%#)-#$)1!" + "#Y1##I5%$)5'\"I5$!9E\"#)5#\"Y-($)5!$9=\"#)M#\"9=#$YE&&9A-%YE!!IE)#9A!" + "#IM\"$9E\"#YA##YQ\"#YE#%YM$$)U#$)U#$9U!#IY!#YM%$:%$%Y]-#I]!%Y]#%YU(" + "$)]#&*!!%:!!%:-(#J)!#I]!'*-!#Z9\"$:)$$J1%&J-'%J%&$9]!#J1!&*-+$*%#" + "#Z1%$:)$$:1##J1!$J1!\"Z1!$Z=&#:1##Z1\"%J1\"$J5%#J1!#J9!$:E##Z5\"%*5'" + "#J1!$*5\"%Z5&!:5\"#J5!#J5!#*9\"$:5#%*5##J-!!ZI!%:5(#J9!$Z1\"\"J1##Z-\"" + "#J1!$Z1\"#J%!%*1##Z5\"\"J1!#Z-\"$:-!#J-!$*-'#Z5\"#Z-\"$*-#%:)!#I]!$Z%\"" + "\"J)!#J-!$J5!&Z)+#:-#$J-\"\"J%!':-*$)]##YQ\"#J!!\"YY$$IY%$*!##9U!%IQ'" + "%9Q)#9Q!%I9!#YQ##IE(!YY$#9I!&)I,$9M!#YE\"!YI!#9E!%I1'&)E&#I=!#Y=#" + "!I9)#95$\")5\"%9-'#Y9#$9-%#)5#\"I-!#)-##))#!Y-$%)%)%I%!#I-\"\"I!!\"Y1%" + "\"XU\"\"HQ!$9!#\"HU!!8U\"#8U$#(U#\"XM\"!(E!#(I#$8E)#HE#\"HE!\"85!#H=\"\"X9#" + "!()!\"X5\"\"8)!!8-\"#H-#\"81!#8)%\"X%\"\"GY\"\"7]!\"8%##'Y$\"'Y#!W]!\"W]#\"WQ#" + "\"WQ##GQ!!GE#\"G=\"!7Y%\"GE%\"W=#\"'9\"#W1%!W9&\"G9%#'1&!W5\"\"7%\"#'!'\"G)%" + "!FI!!VY\"!G!!\"&Y!!W!$!G%!!G)!!'9#\"G-%\"G1#!W1\"!W5$!W9!\"'I!!G1!#79'" + "\"WA%\"'E##GI&#'A$\"7M!\"GQ\"#'Q$\"WU#\"WY##7],#(!$#X!!#8!\"#(!$\"8)!#(9!" + "\"8)!\"X-\"\"8-!\"(5%#X-$\"X-\"$HA$$H-$#8A%!8=\"\"(=(#HM)#8Q$\"X]\"#XU##(Q!" + "#(Q##(]##XY#\"8]!$XI%$(]'#H]%$X]$'9%/#I!#\"I)!\"I)!!95\"#9-!$)1'\"I5!" + "!Y9!#95$$9)%$99\"!Y1$\"YE\"$)I$$95\"$)A$$YA$$)E#&9E##9I$$9Q!#9M!%)E(" + "#YQ\"&)Y,%)Q$$YY&$IU%%)I($IY%!YY!$IY(%I]*$IY)$I]\"$I]\"\"9Q#$*!#&*)!" + "%J%\"$:%$%J)\"$J)%%*5'%:%!#Z%\"#J)!#J5!$:-#!*-!#Z-\"$*5\"%:1)#JA!\"J1!" + "'J-'%J9\"#JA!#J9!$J)%$J5!#)]#%:5!$*A#%Z=#$J5!\"Z5!%J9)$JE%#JA!#J9!" + "$*=##*9\"\"Z%\"#Z9\"\"*1\"#J9!\"Z9!%*=#\"*1\"#JA!%:E(&*9+\"Z5!$:)!\"J%!%:1!" + "!:-\"#J1!!9Y%#J)!#Z5!#Z9!!Z!!#Z%\"$J1($*5##Z!\"\"Z1!!*-%%:)!#J-%!:-\"" + "%Z5#%*)##J)!!Z)!#J-!#Z-\"#J%!$J%)#I]!#Z!\"':)&%J))$I]\"$Z!##9Y'$)Y#" + "#9M!#YM\"#9U!#I]!#IQ+$9M%#)Q\"%)Q!$)I##IE!$II##9Q!!IA)%IE$!)A!&)-#" + "#Y9#!)=!!)1$\"I-!!)1!#)-#\"Y5\"$Y5$\"Y1\"#)-#%)!\"#Y)&$Y%+$)9!\"I%!#9)!" + "\"I)!\"8Y!$(]$#8]!#(I$#8]$#HU%\"HQ!#(M!\"8M##HI%\"XE\"!HA!\"HE!#HE\"%8=%" + "\"85!!H=!!(5!#85\"$H1*#H-#$(-##81\"\"H!\"$H%(\"8)!#(!$\"7]!$H!*\"8!!\"7U!" + "#GM&#WU'#8%$!GI!\"GI\"\"'E!!7A\"\"GA.\"G-'\"'9\"\"G9\"$79$\"'=\"\"71$\"79#\"7!&" + "\"&Y!\"&Y#!&U!\"W!(\"&Y!\"'%#!'1!!W-!$'-(\"G)'\"G9$!79\"!W=\"\"7I$#'A%\"'A#" + "!GA!\"'9!#7I%\"7Q!\"GI#$GQ\"%'Y'$'Q!$7Y'\"GQ\"$7]$#W]%!H1!\"8%!#(%$\"(-\"" + "#8-%#(5!\"X5#\"85!\"8=!\"X=##(9!\"XA#\"XE\"\"89!\"(I\"\"8A!#(I##HM%!XU$$(U%" + "\"8Q!$I!'#HU%#(U#\"I!!$(U'&)5&\"H]!$)!!!Y)!\"9-##I-%$9-+#9-!\"I-!!Y9$" + "#)5##99$$99%#)1##)A##9A!$IA&\")E\"%IE*#9M!$IU\"#YM#$YM&$YU'$9Q%#99!" + "$)Q$#9Q!$IE&%9U%#)Y\"%)U!%IY'!YM!$9]!$*!#%:)($*1#$*1#$*%#%:%(#J1!" + "$Z%##J)!#Z)&%:-!%YY$#Z-\"%:-!%*='!Z5!%*5'\":5\"%:5+(*9!#J5!#J)!#J1!" + "$*A&#JA!#J9!#Z9\"$JA!#Z5\"':1\"\"JI$$Z9\"!*9$$*M\"#ZA%\":E\"#ZA\"$J%&$J=%" + "$:=$&*E(#J=!\"Z=!#J9%\"Z=!&:=,#J9%$ZA\"\"ZU!#Z9\"%JM)\":5*$J9!%:=!$JA!" + "$J9!%:5(\":5\"!*%!%ZM\"#J5!$J5!#:5##J5!$Z5\"#Z-\"#J1!\"J1!!Z9!!*5!\"Z%!" + "#Z-\"#J1%\"Z-!#J-!#Z)\"&Z%!$IU\"$J)\"$J-!%*)'#Z%\"$J!&#*!&$)U#%9Y%#I]!" + "$)]#\"IY!!)Y!#9Q!$9]$%)U!%IQ##YE#$)E#$IM\"\"IM!#9M$$)9!$)E#\"9E#$IA#" + "#IA!#YE#$I=c$#9)$#)9)#I-(\"Y5\"%91&\"Y=+\"I-!\"I!!#9%%\"Y!#$Y%$#))#" + "$I)&\"H]!\"8]!$)%!!HQ!\"8Q!#(]##(Q#\"HQ!#(A!\"X=#\"8I!#HI%#8E%$(A($8A)" + "\"8A!\"X1#$H5*#(1$\"81!#81%#81\"\"H)%#H)##8%%$H%'#H!&#H!$#X%'\"GM\"\"WU!" + "#WQ'\"GQ\"\"WQ%#7E%!'Q#\"GI\"#7A%!'A!#'E'!G%!\"WM&\"'-\"\"W5%\"'1#\"'1'!W-!" + "\"'!#\"V]&\"G%\"!W)\"\"7)$\"7%(\"W-(\"71#!V]\"!G-#\"75(#W9\"#7=&\"7=$\"7A$!G9!" + "!GI!#7M%#WM'\"WU#\"WQ#\"7Y$#7Y%\"7Y!#'Q\"$WU!%!H!!\"8)!#85%$8-!\"85!" + "\"81!\"X5\"\"85!!(9!#81\"\"XA#$H9%!HA&\"8E!$XI%#(I!#(M&!Y!$!HQ&\"(Q%!HE&" + "!HY!$8Y\"\"8]!\"Y%#$)1!#9%%#I!#\"I%!#))#\")-(#Y1##)1##)-#$I5#\"Y1\"\"Y%\"" + "%)9(\"Y=\"#9M$$)A$#I=!#9A!#YE##IE$$YI'%99)#IE!$9E$#9Q$%)Q!$)I!$YI#" + "%YU*#J!!$)Y##9]$$IY&!YM!%YU#\"Y]$%Z5\"\"Z!%\"J!!&J)*#Z)\"#J1!#Z)\"$*)#" + "$Z1&#J)!#J-!\"*-\"\"J)!%*1#$:!!#*9\"$*5#&:9($J5!$:E#$J5!#Z)\"$*9##ZA!" + "#*=\"#ZE\"$J9!#J=!#JA!#JA!$Z=%#ZI\"%*9'%:=$$:9#$J=!$*A#$ZA&&Z5#&:E!" + "%*A'!:A\"$JE$$JI$$*A#(:9.%ZQ%$JQ!&*=($JA$&Z=.\"Z9!#J9!#Z=\"#Z=\"#Z9\"" + "#Z=\"%ZE\"#JA!$J-\"$*=#%:=($*5\"#J=!#J1(#JE!#J=!#*9\"#Z5!$:5$#ZA!\"Z-!" + "$:9#\"J1!#:-##JE!#J1!#*-\"%J))%:)!$IQ&$J1\"%*1+%J!\"#J%$%:!\"$9Y$$IY%" + "\")Q\"$9]!$Z%\"#)Y-$)Y#$YM'$)]#$9Q$$IU\"#YQ#$)Q$\"J)!#9Q!#9A!$)I$$IA&" + "$I9#$9=%$I=#$)9$!I5#$9=%#9-$%)A\"\"I5!#Y5&%)1(#9)$\"I-!\"9-##H]\"\"I!!" + "#9)!#)-##I!\"#XY!%(M)#8Y!!8U\"#(]#\"9!#\"XQ\"%XE##8M$#(M##XM!!HI&$8=(" + "!HA!\"X=#\"8=##(5#!(9$#H5&$(%(\"WY!#X-$#(-$\"X)#!H%!!H!!$'Y!\"8!!\"7Y!" + "#'E$\"WU!#']$#7I##WM\"\"7Q!\"WI#\"'E#\"7I)!G=(\"W9!\"G5%\"79&\"WI#\"')\"!G1!" + "!6]\"\"6]&\"'%#!7!\"#'))\"W-%*\"'1!\"'5##W1*!W9!!W=!\"GA%\"'9\"\"GE\"!GM!" + "$'Y&\"WY#\"GI#$'M#\"7U!\"WY%$GM#\"'Y%#GY$\"WY#\"7]##X=$!(%!#()!\"81!#(1#" + "#H-##H5#!HA&\"8E!\"X=##(A##XE!%8E$!(E!\"XI\"!XI!#(I$\"HQ!#XU!#(I#%(Y\"" + "!HU!#H]\"\"Y!##9-!\")!#&)%'#9)'!Y)$#9-!#9-!$9-%$Y=*#91$%I9$$95\"\"I9!" + "#9=$#Y=#%I9.$9E$\"IM!#YQ\"#YI##9=!$9M!#YM#%IQ*$YU##YI#$YY'$)U#$YY'" + "$)Y##YY\"#I]!#YE#&:!*\"J!$$Z!'$*%##J%!%J-\"$J-\"\"Z)%#*%#$J-%#*-\"$J-\"" + "$*)#$:-#\"J1!#Z5\"$J9%#Z)\"%J5)#J5!#J9!&:9%#:5#\"*=\"%J1\"#J9!$JA!!:E\"" + "$Z1&#Z=\"!Z%!#Z5\"$JE!&JA-#JA!\"ZI!#JA!#JA!$ZA\"$*=)#Z=\"%*I#$*Q\"%JE(" + "!ZM$#ZI\"$ZI&\"ZE!#*A\"#ZQ!%ZE\"\"ZM!#ZI\"#*A\"#J=!$ZM!#ZA!#ZA!$JQ!$JQ%" + "#JA!#J=!$*A##ZA!#J5!&JE)#J=!$JA!#ZE\"#J1!#J9!$:!$%:E$#J9!\"Z9!#Z5!" + "#Z-\"!:%\"%:9!$J1\"\"Z1!$*!##Z-\"!:-%#Z-\"$:-!%Z-&&:))$:)$$:%$%*!($9]$" + "#)]\"&J!#%J!&$J-%$*)#$9Y!$9Y$%YM!$)U##YU\"\")Q\"!9M%#9M!$)]#%IA'#9M-" + "#YM\"\"9I#$YU#%)=(#9E!#Y=&\"9=##)A##9A!!9-\"#)5#\"I!!!91%\"I-!$9E%!Y)$" + "&)9\"#HQ\"#I!#$9!##)!##(M##9!*$(I'#I-%$(M%\"XU\"#(U&!(=!\"HQ!!8E%$(E%" + "!HM#!HI#\"X=\"\"X=\"\"(!##85%$8=##(=!#H-#!(9!\"H)\"\"X!!#(%$!X!$$H!%\"W]#" + "\"7U!\"WY!!GU!\"7Y!\"WU#!WE$\"'I!\"GE\"!GQ%\"G1$!GA!!'A$\"7M!!G)#\"W1(!G1!" + "\"'!%!6]%\"'%#!W)\"\"G5\"!G-#!W-!#75%#'5%\"G5%!W=$\"GA%\"'E#!'A$#'E$\"7]!" + "!GM#!W]\"#'E$\"WU##WY\"#W]'#7M#\"X%#$(%(#X1&!X)\"#H)#\"89!$H1'\"X)#!HA!" + "#(9$\"8=!$8=##8-%#H=%\"XE\"\"8E!#HI\"\"HI!$XM+$8Q)\"HI!#HU%#HU%$(Y'#I)%" + "\"I!!#I)\"#9)!\"I)!#9!!$9)+\"I1!#Y%$#Y)'#Y)#\"Y5\"#Y%'#Y5#\"I9!\")A%$9=!" + "$)E#$)I!\"9E#$)A#$)A!%IA*%YI!#9=!#IE\"#IY!!YU!$9M!$*!##YY\"#Z%\"#9Q!" + "\"IY!$YU#$:!$$*!##)U#\"Z%!%I]*$*)##J-!$J%!!J-#\"Z9!%JA%$9]!#Z!\"$J1!" + "#J1!#Z1\"&JE)%*9#%*I'#JA!$:9$!Z-!&J9\"#Z9\"#JI!#J=!$:E$#J5!\"ZA!#*A\"" + "#ZA\"#ZQ!#JA!$:)$\"J1!#ZI\"#JE!$JE!$ZE&#JE!#JE$\"ZE!$JI$':E%$*I\"%:U'" + "$ZI&%*I#\"*Q\"#*]\"%:I$%*Q'$J=!#ZI\"#JM!%JE)$ZE\"#JE!\"ZE!$:Q##JA!\"ZI!" + "#*M\"#JE!$ZE\"%*M\"#J=!%:A(#JE!#*=\"&:E!$*=\"$:=##JA!#Z=\"%*9&#JE!#*9\"" + "!Z9!!ZA!#J5!$Z-&\"ZE!&*)(\":1##J9!!:9\"%:1!#Z)\"$Z!\"#*-\"%:)!#J1!!YU!" + "#J%!#J%!\"J!!$Z!'$*%#%9U)$Y] ]##Y]\"#IY$\"IU#$IU%#IQ$#IU!#)Q#))U," + "$9I\"%YI+$9A$\"I5!\"IA!#II!#9A!#)=##)A#\"YA\"\"I9!$9)(\"I5!\"Y1\"%Y=,!9-\"" + "!Y9!#HQ%#91!#Y%##Y-&\"9%#$(U$#X]##X]&#(Q#!8Q\"$8Q\"\"HQ!\"XQ\"$XI+\"HM!" + "\"XE%\"89!!8E%\"X1#$8E&#H9&\"HI!\"(5\"#X1'#(=!!X-!\"8)!$85)\"H%!\"H!'!()!" + "$7M$\"W]##7U%#(%&\"WQ!$WQ+#GM&#'E$#GE&\"'A#!7A$\"GA#!GA!!75'\"G1)\"'E%" + "!G)!#G%\"#W%#\"71#!G-!\"71$\"W5#\"'5\"\"'I)\"'E#\"WA!!G5!!GM!\"'E!#7A!!GQ!" + "\"WU!\"GU\"\"7U#!7]$!GM%\"8!$\"GU\"\"X)%#X%$!H)#$89(#HE\"\"X5\"#85'\"X5#\"89!" + "\"(1##8I$\"XA\"\"(I%$8M#\"(A\"#HM##(M#!XM$#(A$\"8U!#95!#I%%!HY!\"X]\"#XY&" + "$HQ##I!\"'9%%#I%\"#9-!#91!!Y)!$)1'!I=##)5##95!%9A&#)5#$Y9'%9E\"\"I=!" + "\"YU$\"IE$#)9#$9U$#Y9##9Q'$IM&$IQ\"#9Q!#9U!%IY##9U!$)Y#\"IY!$Y]'#*!#" + "\"J%!$*!#%)]!$:!'(:%+\"Z)!#J)!#J)!$9Y!$J-%$J-!%J%\"$J5%#J1!$:5##J5!" + "\"Z9%\"ZE!&:9,$J5%$J=!!Z9!$*9\"\"ZE!$*9\"$:I$#ZA\"#ZI\"#ZA\"$ZE%$ZE&$*E\"" + "%:E!#J=!!:E&\"Z=!\"ZI!#JI!$ZI%$:I##ZM!#JE!\"Z]$&:Y,#:A#$ZI!$JI!#JA!" + "#JE!$Z9&!ZA!!*Q!!ZI!%*9&#ZU!#ZQ!#:A##ZE!&*E($*9##:U\"#ZM!%:I'&JI!" + "$JE!':E1#:U#$*E\"'*U#\"Z5%#JM!$J=!#JE!#J=!#J=!\"Z=!$ZI\"#JA!#:=&\"Z-!" + "\"ZE!$*I\"#JE!#J5!#Z9!#Z9\"$J5%#Z5\"#J!!$JI$#J1!\"*1%#J-!#J-!$*-#!:-\"" + "#J1!#J%!#J%!&:-)#J!!$*!##J!!$9Q!$I]&#Y]\"\"IY!%)Y!#)]#$)Y##9Q!$YQ#" + "$)U#$)I#$9A$#IU\"#YE\"$9I!#Y=#&)A,$)A$#)M#\"IE!\")=\"!Y)!%Y1+\"I)!\")9\"" + "\"I-!#Y5&$)-$\"8U!#9!!#(Q!%91)!)!!$(]$\"(M\"#I!)\"HU$$HM*#(E$\"8]!!8M\"" + "!XI!\"8Q!%8E'#8I$%XE#\"81!\"85!\"89$\"X)\"!(1!$X5%#85%!H9(\"H-\"#X%'!G]!" + "%']'#W]'!GU#$'Y(#7Q%\"7Q!\"'Q#\"7M!#'I%#7I%\"GA$\"GE%!W=$!G=#!'-#\"G5%" + "!W%\"!W%\"!7)\"!G)#\"W5%#'5$#G5&!'=!!G9!\"'=#!GI!\"'E##'A$\"'E!\"7U!#7A#" + "\"7Q!!GU!\"7Y!$GE#\"WY##GU&!G]!\"G]\"#(%$\"8)#$7])#(I$\"81!#8A\"#(A#$H9*" + "#X-'!H=!#8A%#85\"!HA!!8I\"$8Q(\"(M\"\"8Q!$HM)\"XU\"#XY#\"XY\"#(]#\"8]!$I)'" + "%Y! %!\")!##))#\"I-!\"Y5\"$I)#\"I5!$I-&#)=##Y9&#IQ$$Y9$!YA!#9E!#YQ#" + "$IE&$)E$#IE\"#9U!#9M!&)Q(&9M.$)U#$IQ&$9Y$%)]!&9Y&%)]!$I]%%:!$%Z%*" + "$*)#$:1!#J1!#J)!&J-'\"I]!%J5%'Z-('*9%#J1!$:1#%:=!#Z=!\"J5##J9!#Z-\"" + "\"*9\"#*5\"#ZE\"#*=\"%*9&%JA%&:A!#JI!#Z9!%:A!#JM!#ZE!%ZE*$ZE\"#ZE\"%*I#" + "#*I\"$:I#&:E$%JQ!':9\"#JM!$:E#%*M&#JM!#JA!%JI)#Z]!$J]$%*Q*$JM$#JA!" + "\"ZM!#ZM!(:M*#:M\"$:M$#:I#%JI!#ZY!#JM!#JM!'JI&#JM!$ZI&#ZE\"$JI$#JM!" + "#JM!#JI!$JI!#JE!%JY(%*E'$ZA\"%ZM*#JE!\"*A!\"*I\"%*A+#J=!&*9+$:A##ZA!" + "#:A##JE!':Q(#J1!%:E!#Z-\"$Z9&&*1!#Z9\"\"Z5!%J1-#J1!\"J)!#I]!#J%!$J-%" + "!Z5!#*!##J)!%Z9*\"9]&$*!'#Z%%$*!#%IY'$)Q$$IY%&IY$$IY%!Z!!#YQ##YQ#" + "\"II$$9M!$9M(#9Q!$IM%#YE\"!9Q\"%9E%#9A!&IE($)1!#9I#\"IE!#)9#$)='#)5#" + "$I9)\"Y1\"&9-*#Y%$#9%%\"I%!$9%##(Y!!)%$#(Y##XU'#Y!&\"8Y!\"8M!#8U$!HM!" + "$(M'\"XA#\"XU\"\"8I#\"8A!\"(5\"\"XI\"\"H9\"\"X=\"\"H)\"\"(1\"!X%'\"8-!$()(\"7]!#7Y\"" + "#H)%$(%##H%##()$#G]!\"7Y!\"G]\"\"7Q!\"'Q#\"WI!#7Q'\"'E#\"G=%\"'A#\"G9\"!'1%" + "\"G-%\"'%#\"G-$!G-!\"G1$\"WM&!GE!!7A\"#'5$!WE!!WM!!7I\"\"7I!#GY!$'I)\"GA\"" + "\"H%\"\"G]%\"W]#\"G]\"#GY##H!&%8%#\"8%!\"(-#$(9%\"81!\"X%\"#(9##X='\"8)!\"8=!" + "!8A\"$8A(\"81!#(I#\"(M\"#HM\"\"XU\"%8U*#8]!$8U%\"8Y#%I%+\"8]#\"HY$#9-!\"8]!" + "$)%%$Y)+#99$#Y)'#91!#)9#!Y5!#99$#9Q#$)M&\"I5$#9E!&)A%$Y=!#9A!$YM#" + "%)9(#9M!\"YI!$IU%#YQ#%*!#!YU$$)Y##IY!#IU\"#YQ#%)]'$*%#%9U)&*%!&J%#" + "#J%!$:%$$Z9\"$:%$(Z-&$:-##J1!#*1\"$J5!#Z9\"$J9!#ZE\"#J5!#Z9!$*=&!*=!" + "#J9!&*-+#JA!%:1(%JU!$JA!#Z=\"#JE!#JE!$*5##JI!#JE!#ZI!$JM%$*U\"#JM!" + "$:E$$JM!\"ZM!\"ZM!#J=!#ZQ!%JQ(#ZQ!#ZQ!$JQ!#ZQ!$ZI%#JM!$:U##ZY!!ZQ!" + "#JM!&:Q($JE%\"ZQ!&JU%\"*Q\"\":Q\"%*I#&*Q#!Z]!$:Q#%JQ)$+)\"$*Q)#ZU!\"*Q\"" + "$:Q#%JM)$JM!$*U\"$[!&':M!%JQ!&ZM+%ZM&&:I%#ZE\"$J5!#ZY!%:E!\"Z=!\"ZE!" + "$*M\"$ZA%\"*A!%:A($*9\"#J9!!:=%#J-!#JE!%:9%#Z-\"$J5!$J=!#Z)\"#J=!\"Z)\"" + "%*1''*9)#Z9!$:-$\"Z!\"\"Z)!$*%#!Z)!%:)($*!#%Z!'#J!!$IU%$YU'!Z%!#9U!" + "\"IU!%)Q'\"9Q##YQ##9I!#9M!$IA##IQ!$)E&!)E!#Y9##Y=#\"IM!\"I-!!I5&$Y5$" + "#9A!#9=*%I1$#)-##91!#91!$9!%#9!!#9!!!Y!!#8]!\"(U\"\"I!!#(Y#\"8I#\"XQ\"" + "!(9$\"HI!\"XM\"#(I#\"HE$#(M##(=$!HE!#X1%#89%#(=!!()!$HA*#()'\"81!$(%&" + "\"X%!#']&\"8!!#8!$#GY$#'Y$!GU#\"GQ%\"7Q!#7M#$7I'\"'E\"!'Q#!7A%\"75#\"'E#" + "#')%!'-!#'5'\"W5&!G5&\"75$\"7=$\"'=#!GM!\"WE%\"'E#\"WE##7Y%\"GI#\"GQ\"#7Y#" + "\"X%##GY!\"7]!\"H%$$8%%\"\"WY#\"H)!!X-!#H1&\"H1\"\"89!%89%\"85!\"HQ$#H=\"" + "\"8E!!HE&$HI'\"XE#!(A!\"XE#\"HQ'\"8U!#XUY$#HI#\")!(%9%,$8]%#9%!!)-!" + "#))&!Y9!\"I-!$Y)(\"I!!$I5#\")5\"\"I9!!9I%$Y=!#I9\"$)I$#YE%&)E)$9I%#9I!" + "$IM%$*)##J!!%YQ'#*!&$IU%%9Y(%IY\"\"I]!#I]!#J%!$I]\"#J)!%:1($Z!&%:%!" + "%)]!#J-%%J-\"%:1(%*=+#J1!#Z)\"#Z5!$J9!#JA!#J5!#J5!#*5\"&*A+#ZA%%*A&" + "$Z-\"$Z9&#JA!$JI(%:E!#JE!#Z9!#ZI\"$JM!\"ZI!!*M!#JI!\"ZM!#ZU!\"*M\"%Z])" + "&:I!$JM!%JM!$*Q\"#JA!%*U\"#ZQ!!ZM!#Z]!#ZU!#ZU!\"ZU!**U)$*]&#ZY!\"[!!" + "%JQ!$[!!#ZU!#JI!%ZU)#JI!$J]!$ZQ%#ZU!#[)!'*U#$JI!$*]\"$Z]%%+)\"\"[!!" + "$JU!#JM!%*M\"%:Q$!*Q$%JQ!#ZU!#Z]!#:M##JM!#JM$&ZU\"$ZM\"!:Q\"#ZE!#JI!" + "%*I\"&:A,$J9!#JI!$Z=\"$*=#$JQ!\"ZA!#J5!#*=\"%Z1&#J9!$J9!#Z9%!*5!#J5!" + "#J%!#J=!#*9\"#JA!#J-!%*1'%Z)+#Z-\"\"J!!%:%(#:%##Y]\"$*!#!)]!%:%!%9Y," + "#IU!#IU\"$)]#%9U%#9U!&IM$\"YM\"$9I$$YI&&Y9/#IE(#9A!$IA%%9=%\"I=!!I=#" + "\"I1!\"(]%$9-(#9A$#9)!\"I-!$))%#))#%I%$%)!%\"8]#$X]$\"Y%##)%##))##8Y$" + "$(]$%(M##8M$\"H-*!HQ!\"XI\"#(A##8A%%H=&#(E!\"8M#\"8=!\"X1\"\"X9#\"8)!\"8)!" + "\"X=%$()(\"X!#$8%)#']$\"H!!\"WQ#!'M!\"7Q!\"GM\"\"GY\"#7I%#7I%!W1\"!GE%!WA&" + "!G-!\"7=#\"G1$#'9'#'5\"\"'5#!W9&\"79#\"W1&$7E$\"GM\"#']$#WA#!GU##7Y#$8)&" + "$'Y#\"G]!\"W]##(!$\"(!#\"8)!\"H)!\"X-#\"X-#$(9%#(9!#H1!#X5&&(=%%(E##(A$" + "!HE#!XI$#(M!#8M!\"XE#$(Q!#(U#%8Q$#(Y!#(]##HU\"#XU&#(]!#I5\"\"I1!\"I5!" + "\"I)!#))##9-$$Y1'!)1$#I=%\"I9!#9A!%Y=(%)E!#)A#\"IE!$)E#\"IA!$9U!#YM\"" + "%YM$#YM#$IU\"!9Q\"$)U#$*!#$:!!&)]$#Z!\"\"J%!\"Z%\"%Z%'%*%'$J-\"#Z!\"#J-!" + "!Z-!#*9\"'*1%#J1!#J5!$J5!!Z1!$Z9\"$:9##J=!$Z5\"#Z=!#J=!%:E!#JA!#Z=\"" + "&:I,\"JM#\"ZE!$JM$!ZY!%*I\"$:Y#%ZQ&$ZM\"$*U\"#:Q##;%&#ZQ!#ZQ!$J]!$*Y\"" + "%*I\"#:U#$JU$#*]\"%:U$$J]!#ZU!\"ZU%#[)!#[%!$*U\"$ZY%$*Y\"$*Y\"#[)!$JU$" + "$;%\"\"Z]!&[%\"\"JY#\"[!!$ZU%(J].#ZU!#*]\"%JY)\"*Y\"\"ZM!$ZY)\"ZQ!$ZY%$:Q#" + "#ZU!$JQ!#ZI!$+!\"$*U\"#JM!$*U\"\":]\"#*Q\"$*M\"!ZM!#ZQ!#:]\"%ZE*$JA%%ZU)" + "$:I#$*I\"$J9%(JI#\"*E!#ZA\"#JE!$JM!$*A\"\"JM#%JA)#ZA%#ZQ!\"*9!#:5##Z=\"" + "\"Z5!&:5!#J9!$*%##J)!%J-\"%J5\"\"J%!%:-!$:1!$:)!#*%#%J!*$:!!#J%!&9Y&" + "%YY$$)Y#$)Y##IU!#YU\"#YQ#%9U%#9U!#9A!#YI##)M#$IU%$YI'$)A!$)=$#)5#" + "#I=!#9=$\"Y=\"!Y5$%Y5%\"9-##9!*\"H]!#Y9##)%##Y-#%Y1($)%%$(]'!HY!#(E!" + "#XU##8Q$\"8Q+#8M$#HQ\"#(I#\"HU$%(E#\"XA\"!(I!\"85!\"8=#\"H=!\"8=#\"8-!\"X%#" + "!H)!\"(!%#8%$#(!$\"8)!\"(%%#WY$!7U\"!GQ#$7M'\"7Q$\"GM%#7M&!GE!\"'9##GI$" + "\"7=$#'-'!W1!!79\"\"G1'\"7=#!WA$#7A##'A'#'E$\"WQ##'E'\"WQ&\"GU\"#GU!\"W]#" + "#']$!GU!#H!&$(%(#H)!$8%)\"X)##(A$#(1 $\"(9\"$(=!$XA&#(I##(A$#XI!" + "!XI$#HI#\"8Y!\"8M##XQ&#(U##(U!\"XY\"#H]%$I)##9!!!8Y\"%I!(\"I)!\"I)!$Y1$" + "$H]#$)5'\"I1$#I1%$I9 I##I1%#IA%#)A##IA\"#9E!$)Y##)U\"\"IU!#YQ#$9Q!" + "#YE%$)U#$IQ\"$J! Q!#9]'%:!\"\"IU!#J)!$J%)$*%#%9])$J)%&*-($Z-&\"J-!" + "#Z-\"'Z1)$J5!$J9!%*A#$J9!$J9!#J)!#J5$#J=!%:5(#JA!%J9\"%JE(#JM!#ZA!" + "#J9!&ZM\"\"ZI!%*Q\"#JE!#JM!&ZI\"$JQ$!K!#'+!#![!$$JU$#ZQ!#[%!#[)!#JI!" + "%:M(#[)!$[%%#[-!#ZY!#[!!$*Y\"$[)!$ZU%$J]$#Z]!\"*]!$:]*$[%!#[-!#ZQ!" + "\"ZM!$:M$%J]%&;!#$[%!#;!#&ZY.#JM!#*]\"';!,$*]\"#Z]$#Z]!\"+!\"#ZY!%Z]\"" + "%ZU\"$*U\"'*Q+#*Q\"#JE!%K)(#*Y\"$J]!%*U'$JE$$JM!&J]!#ZQ!#J9!!ZY!$JQ$" + "%ZM\"$:M$\"JM$%ZE\"$:I$$:I$#J=!#J=!\"*E%$:E##JM!$JM!$*I\"#*A&#J1!$:=$" + "#*9\"#J9!\"J9#%:5!$JA$$J!\"%J1\"#Z-\"%J5)$:-!#J)!#J-!#Z%\"#J!!'*!0&J-\"" + "#IU\"#J)%#IY+$IY%#YQ##J)!$9Y!#9Q!#9M!#)M#%YI(%I5!#YA#$9E(#9I!$)A#" + "#)A#!Y9!&99*%)5%!Y5$$Y-'\"I5!#)%#!Y1!\"I1!$9%&$(]$\"8Y!\"Y)\"\"8U##(I'" + "!8M($(U$#(=$\"HQ!$(E(\"8I#\"8I!#HE##(=$\"HE$\"8E!$X5,#8=%$H5\"\"8-!$(-#" + "#8-%!(-!\"(5'#X%'\"8!!\"8-!\"H!!\"WY!$'Y)#7]%\"7Q!\"7M!\"7M!\"7I##'E+!G=!" + "\"7)$\"G-$\"'1\"!'1$\"'5%#79!\"'I##'E'!7U\"$7E*\"WM##7Q#\"GY\"!7Q\"!GM!\"X!#" + "$H!'$X!)#(%!\"8-!\"8%!#85\"\"H1!\"81$\"(9\"$81!#(1!#8=$!HI!$8I&\"(E\"\"8I!" + "!HE!$8M&\"(Q\"\"XE\"#)!$\"X]\"$(Y!#H]%$(]*#H]\"#Y)#$))$#I-\"\"9-##I)&$)!(" + "!)1$#)5#$95%!Y=!!Y=!\"I=!$YA&#IA\"$IA A!#YI\"#YY\"%IQ'%)Q$#IU\"%)Y$" + "$YU'#IM\"#J!!\"I]$$Y]&$*!#$9]$!J%#$)Y#$:)!&*!(#Z-\"\"J!!\"Z9!$:%$$:5$" + "#J1!#J9!%J-\"#J=!#J9!\"J=##JE!#J5!%ZE)&:M(\"ZM!$ZM%#ZE\"$JQ(#ZI!#ZU!" + "%JM!&:A$&*=+%*M&&*I'$ZQ%#ZY!#[!!$JU!$+%\"$:U$#ZU!$ZM\"$:Y'#Z]!&*Y*" + "$Z]%$K%(\"ZY!!Z]!#;%#%K!)#*]!#Z]!%;)+#[!!#[%!$Z]%#[%!$*U\"$ZY%%;!'" + "&K%!!+!$$K!$#*Y%\"[!!\"[1!#[!!#+)&$:Y*$+-\"$+!\"#ZY!#[9!$;!##[!!#[)!" + "%K)$$ZU%\"*]!$JY!#ZU!%J],$:Y#![!!\"JQ$$*U\"':I%#ZU!\"ZU!%*I'%:]#%K!)" + "$ZQ%!ZU!$*Q\"&JY!%JQ$$*M\"#*M\"$JI!#JE!%*E'\"*Q!#JE!$*E\"$Z=\"\"*I\"\"ZA%" + "#J=$#J5!$:9##Z9\"$*1&#J1!$J5!\"J1!$*-##J=!\":-\"$:)!#*1\"$:!$$J5%$:)$" + "\"J!!#Z!&\"IU!$:%!#)M%&)Y%!IQ##YQ&$)Q$#)Q#$YU#\"IM$$YI&%Y1%#9E!%)5\"" + "&)I\"!95\"#9=$#I5%#99$#)9##I9\"#Y9#!Y-!\"Y-\"$I-)#9%!#Y%$$9!&\"I1$\"8]!" + "\"(Y\"\"8Y!\"(]%\"HQ$#(]#!XU!#XI!#(I#\"8A!$XE\"\"8A!\"X=#%(1'\"X9\"#()!\"85!" + "\"89&!()#\"X!#\"G]\"\"X%#$WY!\"(%#!']!#X!\"#7Q#$'M##GQ&\"GM\"$'E!\"'E\"!W=\"" + "!71'\"'%#!'=#!W5!\"G=\"!WQ\"!WE\"$'U($GI&\"GM'\"7M!#7M&\"GQ\"\"WY##7Q%!WY$" + "!(!#$8%$\"X%##(!$&(-+\"8-!$(A\"\"(%#\"HE$#85$\"X-#!HA!#8A$\"(5%#89$#8]$" + "\"8I!\"8A!!HQ!#(Q#\"XY\"$8M#\"X]\"\"I!!%Y!#%XY\"!Y!!#Y%&$))$#Y-&!Y1!\"91#" + "#9I$$I9&#)5&#Y5 =!#)=#!YE!\"II!#)A##9I!!YM!#9Q!%9Y%$9U$#)]##IM\"" + "#)Y#&)Y!#Y]\"$YY&$)Q$%:%+!Z)!$J!%&*-!&J-\"$:-#&*-+$:1!$Z1&$Z5\"#*5%" + "%:1%#J9!#J=!#J=!#Z=\"#JA!$*A\"%*M&%*E\"&:Q,&*E$!*I$#JE!%*M*#JM!$:E#" + "!ZM!#Z]!$*M\"\"*Q!#ZU!$*M\"$:]##[!!$*I\"'JY*\"ZU$$*Y&#[%!&+)\"&:M!%:U$" + "$[!!#[!!$;%\"%[!)#;!\"$+!\"%[!&%[%)$[!&$[%!%+%&$K%$#[%!\"ZU!$+!\"$*U\"" + "#[%)#[%!$;%\"$+)\"#[%!!ZY!$K%$$[%!$[1!%+%&#[%!$+%\"#ZU!$K1$#*]!$K%$" + "\";5&%;%'%JY!#[!!![!!&:]+#[!!#:]\"%;!$%ZY\"$[!&%*Y*%:Y#$*M\"%JY($K!$" + "&;)'&JU)&JQ%$*U\"$:M$$*M\"$:Q$$*M\"%*M&%JM!%*I'$:M'%JI!\"ZM!#ZA\"#JA!" + "#JA!#JA!$:=$$*9)%*='$J%&$Z-&$JI!#J9!#J1$$:1!#Z-\"%:-%!Z%!$Z)\"#J=!" + "%9]!#J%!#YQ##Z!(#9Q!#J1!$)]#$)]#$)U#$)Q$$IQ&\"IQ!#IQ\"#YE%#Y]\"&9=$" + "#9A!#9E!#I5\"%Y=,#YA\"\"Y9\"\"I5!\"I=!\")9%$)5'#Y%'$I% %!$I%'#XU##(Q!" + "\"X]\"\"XI\"\"8Y##9!!#(E!\"HM!#XA#\"8I!\"8E#\"X=#!X=!\"8A!\"81!\"89!\"H9!#HM&" + "#']$#85%$X1#\"X)##(!'#8-%\"G]\"\"WY#&(%)#'Q$!GU!#7]%\"GE\"\"7Y!#7=%#'I\"" + "$'5&#G1$!G=%!G=!!W1&\"'E#!WE\"\"GA\"\"WM#\"7=!\"'Q#\"8%!$GY*!G]%#W]'\"7]!" + "\"X)##8!\"!(%!$H1%#(1!\"81!\"X5%\"W]##8=$%(5#\"XE#\"H-$#8E%#(I#\"XU\"\"8Q!" + "\"HU!\"I!\"\"XU\"\"XE\"!X]$!XY$\"I!!$Y!'%I-!\"XY\"\"8Y!$)5!\"I)!$Y1*\"IA!#)1#" + "#)-#!YA!\"IE!$)-$$)I$$YE$#IE!\"9I##9Q'#)]##9I!#99!\"YU!#IY!#YU\"$)Y#" + "#Z!\"$)Y#%*%'\":!\"!Z!!$9Y!%Y]'#Z%\"$Z1&&*%(#J-!$:1!#J5!#JI!\":A#%*9'" + "#JE!%:=(%:=$$ZE&%*=&$J5!&:I,$:Q#%:M$#JI!#*E\"$JY!$*M\"#ZI!#Z]!$:I#" + "#ZQ!\"*Q\"%:Q$%*Q##[!!%ZY\"%*Y\"#ZQ!$+!\"$;!#$[!!$*]\"&:],%K!)%;!#\"[)!" + "&;)#![%!#[%!\"K!$#JY$$[)!\"+!\"&+%\"$[%!\"ZQ!$[)%\"K)#'[)\"$+1\"#[1!#[)!" + "\"Z]$#+)\"%;)+$+)!$+!\"$+)\"%+).#+!\"#;)\"$[)!#[%!#[)!%+-&$[%!![1!\"[%!" + "$+!\"$;)\"#Z]!#[%!#[%!#[1!$;)'#ZY!%K!!'K%,%Z])!*]!#JI!#Z]!#Z]!%:M'" + "$:]##+%!$JU!$:Q#&:Q$$ZU\"#ZE\"$JQ!$JQ($ZE%$ZM%#ZY!$JQ!#JI!#Z5\"&:E%" + "\"ZM!#JE!%*=*$*A#$Z=\"#Z=!#JE!#ZA\"#Z5!#*5\"&*1!!*5$%Z1#$Z9&#J-!\"J)!" + "#J1!#J-!#I]!$:!$#IU\"$Y]#$)U##IY!#IU!$:!!#9]$#)Y#\"I]!#9I$$)U##)9#" + "!YE!#YE\"#9A!#II\"!I1#\"I9!#)-#\"Y5\"\"IE!#Y!'#9-$!Y5!\"(Y($HY$#I%\"#I%\"" + "!Y1!\"XM\"\"HY!#HM%\"8Y!!I%##XA$#(M!#8M$$8M\"#XE&\"XA\"#(A$#(A!!H9##H9#" + "$81)!H=!#(-!#(!$\"85!\"H)!\"W]#%8%%!7]\"\"7]#\"X!#!WQ$#WQ'\"WU#\"7]!#7I\"" + "\"'=##79!#7=(\"'=%\"W=%\"75&\"7I!\"7M!#'Q$#WQ'\"7U!\"7U!#']$#7Y%!']!!X)$" + "!H)!#H)#$H-*!XA!#X-'!H5!#X!(!H9!!X1!#(I!\"HI'\"8=!\"HA!#8Q!\"8M!$(Q(" + "%(U,#I!%#XY&#XU&#(]##9%!$9!&$X](#9%!\"I)!!)9!\"9%#!Y=!#)=&#Y-#\"I=!" + "#I9%\"I=$$9=%$Y9'$9E%$)E#$9I\"#9M!%)I!$IQ&&)]($)]##YY\"$IY&%9Y!$9U$" + "$Z!##9U$#I]!&*!!#Z1\"&J)*#Z1\"#J-$$*9\"#J1!$Z5\"#Z5\"#ZE\"#J9!#J5!%:=!" + "%*=##Z9\"$*A##ZE\"!ZI!!ZQ!#ZQ!#JI!#J=!\"ZU!!ZI$!ZQ!%*Q'':Q!\"ZU!':U%" + "!:U\"\"ZU!#ZY!#ZY!&*Y#%ZY\"(*](\";%\"%ZU)%K%!\"[!!\"[!!#[!!#[!!!:Q\"#*M\"" + "$[)!$+-\"#K)$$K9#$[)!$;!#%+)\"$+-\"$+)\"&[-.\";-&\"+1%$+-\"%+!\"$K5$$;1#" + "$[-$&;-+$;-\"%[)!$+5\"%+9&$+-!$+1\"$+)\"$*Y\"$[)!#[I!%;-'$+)\"%+)&\"[1$" + "\"[!!$+1\"#K)#%[)%\"[5!#[!!#[!$#:]\"$*]\"$+)\"#JM!%[-&$JU!%K%!#JM!$+-&" + "\":]&$Z]!$J]!%:Y$\"ZY!#Z]!&ZU*%ZU\"#;%'$:I$#ZQ!$*M\"%:M$#ZY!$J]!#JM!" + "#ZU!#JM!$ZA%%ZA&$ZE)#:=##J9!%:=(%:=($J=!$J5!$JE%$J!%$Z1&#Z9\"$J%&" + "\":)#%JA)\":%#$*%#$:-#&*!!#Y]&%*%+$9Y!'YQ*#IU!$)U##)Q##IY!\"9Q##IQ!" + "#9Q!#YE%$IE#$YA!#)9##)A#\"IA!\"95##95$\"I5!#)5##)9##I5\"#I)&#Y-##Y!$" + "#9%$\"Y!#\"X]\"#8Y$#XY!!XU'#(Q#$XQ*$(Q!\"8I!#XM#$X=+\"(E\"$8A&$H=!\"85!" + "#85!\"X5##(1&!H%#\"(-#&()(#(%&\"X%\"\"']#\"8!!#'Y$#'Y$#7U\"\"WM#\"WQ&\"WE!" + "!79%\"'9!\"'E\"\"7I!#GM!\"W=(\"WM#$'Q!\"7Q!!GU!\"7Y!\"7Y!\"G]\"#7Q##W]'#GU#" + "#(!$#H)&\"(9\"\"X5##X5&#(5)%(=##8I%$8A '\"HE!\"8Q!!(=!\"8M#\"XM\"\"XM\"" + "#HQ&\"Y%#\"I!$#(]##9-$#Y!$$I!&$))!#)1#$)A!#)1##Y1&!Y=!#)5##Y-##9=$" + "\"I=!#IA%')I\"$)E#!)U!$)I$$9M!$YM#!IQ#$YU&$IQ&$)U##II\"#Y]\"#9Q!%YU(" + "#Z!\"!*%!$J)\"!Z1!\"J1!#J-!\"*1\"#J!$#J5!#J5!$*5#$J=!'*5(#J1!%Z9##JA!" + "%Z1#\"*A\"%JE(!:E\"#*I\"$JI%$*Y\"$*M\"!ZM!#JA!#Z]!#Z]!#ZQ!&*U*#ZU!$;!\"" + "$*Y\"'JQ%$JY!#[%!#[)$#ZQ!%[!&#;!#%+!\"%Z]*#JY(&+%*%;!'#[=!&;)'#[-!" + "%JY%#[%!#[)!%+-&%K-$$+)!#[-!#ZY!#[-!$+-!#[-!$[-!%;E\"%+5!#[=!#+1!" + "#[1!\"K)#$+M!#[5!$+1\"#+1\"#[-!%K1($+1\"#[-!!;=\"$J]!'[1-%+1&%+-\"$;-&" + "$[5$#[%!$[)%\"[1!$K)$%;-\"&K)!&+)\"$+)!$[)%%[%&\"ZU!%:Y$#;%*$[!!%ZY\"" + "\"Z]!%Z])'*]+$:Q#$:]#$:Q$#ZY!%;%'#*U\"$*Q\"#*Y\"#ZQ!$*Q\"$*Y\"\"ZM!!ZY!" + "%:I'!:I%#JI!'JA\"#JE$%:M$$*A\"!*9!#J9!#Z%&#Z5\"$J1%\"Z5+#J5$#Z-\"$:9#" + "#Z%\"%:1!#J9!#Z5\"\"J%!$J!\"$YY#&J!#$)]&$*%#$Y]&$9M!#IU$$9M%%YI!$)A#" + "$9M!#YE\"#YI\"$9E\"$)A#$)=!!YA!#9Q#$)=!\"I5$$91(#I1%\"Y1\"\"I-$\"I-!\"Y)\"" + "\"Y)%#I-\"#)%#\"I-!#(Y##(A$$8Y%\"HU!\"8Q!!HM!#(9##(Y!\"8M!\"X=#\"81!\"8-!" + "#89%#X5$\"81!#()$$(9(\"7]!$X)&$8%)\"8%!\"WY%\"WI#\"WY#\"X-##WU!\"WU%\"WQ!" + "!W5\"\"W=*#'9$\"'A\"#'E$#G9$!GM!\"WQ##'I$#7U%#7Y%#H!$$(!+\"7]!\"W]#\"8!$" + "#()$$(-(#(5##(=!#H-%%H9,#85$\"H=\"#(A#\"H=!$(Q'\"8M!\"(M\"!(Q!!HQ#\"8Q!" + "#(Y#$(Q%!H]!\"8]!#9!!%I%'\"Y)\"$)%!#I)%\"I%!\"I-!\"99&\"I9$#99$#)I##Y=#" + "$)=$$)A#%)9($9Q!#YQ\"$9U$$)M##YQ#\"IU!#J%!%)E%#IY!$*!#$9]$&:)-!Z%!" + "$Z)#$*)&#*1\"%J-\"&*5,$:A#$ZI!$:5##J=!#J9!#JI!#Z5\"&:9!$J5!%JA)&:A!" + "#ZE!&JE)':I!!*A$$*M\"!*U!#JM!$*Q\"$:M#\":A\"$ZU\"#ZU!%[!&$*Y\"\"ZE!$J]!" + "#ZY!#Z]!#[%!$J]!\"K!'#[)!$+%\"#[%!%K%)#[)!#[-!$[5!$;-\"$+!\"#+-\"$;-\"" + "!+)!&+1\"#;)\"&[1&#[1!\"[1!#[1!$;1\"%+9\"#K1$$[9!#[1!$+9\"#[1!&K5$\"[%!" + "$;A\"\";5&$;5\"$;5\"#[5!$K9#\";5\"%+5!$;-\"%+9&$[5!\"[1!#[1!$[-!$+1\"$+1\"" + "#[1!$[%!$;9\"#[)!#[%!#[-!$[!!$;)\"'K-!#[5!$+)\"#[9!&K5,#[)!$+)&#+)\"" + "$K9'\"ZQ$#ZY!![%!$JU!#Z]!#Z]!#[!!%*M'$*]\"#[%!$ZU%%*U&$JY!%*U'$:Q$" + "$*M\"\"ZM!#ZM!#JM!%ZI'%:I$&:E!%:A(%ZA\"$JE$!Z5!#JA!$*9#\"Z=!&*=+#J9!" + "$Z1\"$*-'#Z-\"$:-!#:)'$J)%#J%!$*%#$J%%&J%&$)]##9U!\"J%!#I]!#9U!#YQ%" + "$9I$%)A'%)I!#YI&$YA&#IA\"\"IA!\"9A&$91\"$)5'#Y5&\"I=!$Y1*!)-$#I!##))#" + "$9)%#8]'#H]\"%)!)\"I!!\"I!!%(U##(U#!(Y!#8M$\"XM\"#(I##(E#\"8=!\"H9\"\"8A#" + "!81\"#X=)$85)#HA+\"(5#\"8)$\"(%\"#(9!\"()\"\"8!!!X!!\"']#\"WU##WY\"\"(!%\"7Q#" + "#'A$!G9#\"'I!%WM+#GI'#'I%#'I&\"7E#\"'E!\"7Q$\"GQ\"#']$\"X%#\"X!#\"(%\"$()#" + "\"89##(1#$H9'#H1&#(9!!H=##HA='\"8M!#81\"#8I%$XU+\"HQ!$HM!\"XU\"%(M#" + "#8U!\"9!$%9!*$))!$9!&\"I)!\"Y-($I-)#)1##I9+#I1\"#Y=\"%)Q*$)9'#YE#$)A!" + "#9M!#YE##9A!%)=$%)Q!#IQ!#9Q!$)Y##YI\"$)Y##9Q!%*!!$:!!#IY!&Z%$%:%!" + "$J)%$I]&#*)\"\"J)!$J5!#J1!#Z=!'*5%%J9)%:5!\":=\"&*=+#JA!#:A'#*A\"#JM!" + "\"ZE!$JQ$$:M$$JM(#ZM!#ZQ!#JQ$$*U\"\"Z]!$JU!'[-)%*Y&#Z]!#;5\"%*]&$[%%" + "$;-##ZU!$:U#$[)!#[)!$J]!#[)!$+5!%:]+%[))\"[1!#K5$$;)#$[-$%JY)&;)+" + "%[-)%+)&$+!\"$+1\"\"[%!$+9\"%;1+$+%&$[5!&[5!![1!$;)\"$+-\"#[=!%+=!%+)\"" + "%[A%%+=%%;9\"%[9!#K5'$[-!%+9\"&;9\"%K9$$[9!'+1+'[1!&[1)%;5\"&[9!$[=$" + "#[5!\"[5!#[-!$[5$\";1\"#[-!#[-!$;1\"#+1\"\";-\"$K-(![-$#+-\"$[)!%K)(%Z]%" + "$[1$$[%!$*]\"#[%!%K!$%;-\"%K!)%K!$#Z]!$*]\"$*]\"#ZY!$ZY%$ZU%%*U\"$*U\"" + "&:Q$#JM$&JE-$*M\"#ZI!\"ZM!#JI!%:E!#Z9\"%ZE\"#J=!\"JE$%J5)#J9!#Z5!#J1!" + "#*9\"%J5%#J1!#J-!\"J-!\"Z)%#J)!$:%!$*!##I]!%IQ)$)]&%I]&$:!!\")Y\"$)Q$" + "\"J!!#IY!#YM#\"YI\"!Y=!$Y9'#95!#)E##95!#95$\"I9!!IA#\"I9!\"91#!8]%#9%!" + "$I%)#I%#$HY&#(Q!!I%&#(U##XY##(Y##XU!\"HU!#XQ!!HQ!!HI!#HI&&H9*\"HA%" + "\"81$$(A(#(9##89%\"XE(!H=!\"X)##H!&#H))\"8%!\"X!#\"7]!!W]!\"WY#\"7U!#H!$" + "\"'E#%WI(!GM##'I$#GM$\"WQ&\"GQ\"#'I$!(!#%H1&\"7]!\"()##8%$#8)%\"85!$H9!" + "$X1(#XE!#(5$#X=!#H=#\"89!#8A!$(M'$HQ'\"8I!%HIA%%HQ!!HU!%)!($HE!" + "\"H]!#Y)'!H]!\"Y%##))#$)-'#Y-##I)%\"9A#\"I=!\"I9!\"IA!\"I='%YE!$)M'\")E\"" + "#YE#$IA%&9A M!\"IU$#YQ\"%)U'$YY&#J5$$I]&$Z)&\")]\"\"J!!#*%#%J)\"$*)#" + "$*-##J)!%*%'\"J1!#*5\"#Z9\"$9]$%*='#ZI\"#Z5\"!:=\"$Z=)#JE!#*E\"#JI!#JI!" + "#ZE\"$K!$%*M'$:Q$$*Q\"!ZQ!$ZU\"\"Z]!!*U(#ZY!$;!#\";-\"$JY$#[!!%+!\"#[)!" + "$*Y\"#[!!\"+)%#[-!$+)\"#[-!#+)\"\"[-!#[!!$[)!$+1\"#[)!#[%!\";1\"%K=##+5\"" + "$+9\"%;9''+5\"#[5!%+=\"#[9!$[9!%K9$%;=\"\"[9!$[9!$[9!%;-\"&;I&$[9!&[5*" + "%+=!'[E!'+1&$[A!%+5\"%+=%$[I!%+M!#[5!%;5#&[=!#[9!%;9\"$[1%$[9!%+1\"" + "$[A!%+1!$[E!&[=)#[9!'[5&\"[5!&K1$%;%#%+9!$+-!\"[5!#[%!\";)\"$+9!&+-&" + "!;5)$+5\"$K-$$K!$%;%'#[!!$+-\"$[!!%J](%;!#$*Y\"#Z]!#[%!%JY!':U)#Z]!" + "\"ZU!#ZQ!#ZU!$*I\"#JM!#JM!$*M\"#JM!$ZI%%JI(\"ZE!$ZI\"$ZA&\"Z)!$J-)#J9!" + "#*9\"#J1!#:1'\"Z9!%ZE)#Z)\"&*)!#Z-\"%:5(%Z5#$9]$%9Y(%)U+$YM'$)Y##Z!&" + "#9Q!#)Y&#YQ)$IM%')M)#YQ##I9\"#YE\"'Y=#$Y=$\"I=!#)9##YE#\"I5!!)1!$Y1'" + "#)-##Y%'$I)##9%!\"Y%\"\"9%##8]$#(]##(I$#8U!#(Y!#8M!#(E$#8=%\"X=#!8E\"" + "#(A#\"85#$(=(\"X=##85%\"X1##X-$!H1##X-'!8%\"!W]\"#8%(\"W]##7Y%\"WQ#!GU#" + "!7M%!WE\"\"7M!#WM'$WQ)$X%&\"7U!#'Q!\"G]$\"'I!\"GU\"\"8%&!(!$!H)!\"X-#\"8!!" + "!(%!!H9!#(1$\"H-\"\"H9!!HM!\"8M!\"8I!!8M\"$(E(#(Y!!HM!\"8U#\"HU!#(U#\"8]!" + "!Y%!#9-!$9-%$I%'#HY%\"I1!%)1(%91&#I5%\"I9!!99\"#I=%#9=!#9=!#YE#$YI'" + "$YY##9U!$)U#&IE+\")M\"$IU(#J%!$)U#%Z!+\"YY!#Z%\"$:%!%Z%'#Z%\"$J%%\":)\"" + "$J5%\"*1\"!Z5!%Z9&$J9!$:-#$ZE\"$J=!%JA%#Z9\"$ZE%!ZI!!:E\"#JM!$:M##JM$" + "\"*M!#ZU!$:]##ZY!#ZU!$*Y\"#[!!#ZY!#:]\"%J]!&ZQ*#[!$%+!\"%[!\"#K%$#[1!" + "#[1!'+)+#ZY!#[)!$+-&$+-\"&;A&\"[1!%+9&$KE##[1!$+1\"#[=!$K=$#[5!%+M!" + "$[E!$[=!%[=!#[9!%[9%%[E!$[=!%[5%'KI$%[9%%;9\"![=!%;E\"%[=!\"[=!$[5!" + "%;5#%K1$&KA$$[A!#+1\"$[=!!+E!\"[9!&KA(&[=!%;I\"%+=\"![I!&K9((+1\"%[-%" + "$[A!$[=!'+9\"'+9&%KE$%+=\"&[5!#[9!%+5\"$[1!$+E!#[5!#+1%$K1(%[1!$;%#" + "#;!'%+)&#[-!\"K!#$+)\"\"[)!!*]!#ZQ!\"[%!$+)\"&+!+$JU!$J]$\";)&#ZY!(ZY+" + "\"ZY!%ZY\"&:Q$#ZY!&:M+$:Y##ZU!!ZM!#*=%#JE$$JI!$JA$\"Z=!\"*A\"&:A%%*='" + "$J-%&:5%$:9##J5!$*5\"$:=$%J-\"#J%$$Z)#$J!)$Z%#\"YY\"\"YY!#J!!\"IY!#9M!" + "$YQ##YU\"&)Y)$)M$%IM##YM##9I!$9M!#9I!#Y=\"#9A!#)1##99!\"I5!\"I5!\"Y1\"" + "!)1!#I)\"#I!#\"Y%\"$9%#!(U!\"(Y%$(]'$8M#\"8M!$HU-#XQ#$(9'#HA\"\"HI!\"89!" + "#HM%\"HA\"\"8=!$(9'\"(9\"!H5!#H1U$$X-%\"X-##H-&#H-&\"7U!$W](!GQ!\"7Y!" + "#G1'#'E\"\"WQ#\"'M\"#7M%\"7U!#7E#$'Y(#(!$#8!$#(!M#!X)\"#X)\"#H-!\"85!" + "%HE\"#(=$\"(5%$(A%$8A(%HA\"$(E'#(I!\"(M\"#(I#\"(M\"$)%'\"8U#$8Y)#(]#$(]'" + "#I!#$)%$!Y)!%9))\"9%#\"9-##)%$\"9A#\"I9!\"I-!$)5$$)E$#IA!$)E!#9Q!\")E\"" + "#9M!#YM#$)U##IU\"$YY&$J%%#IY!#YY&#YY\"%J!##J%!#9U!!ZA!$J)\"&*-+#J1!" + "\"*5\"%J1)%:9($*9\"\":9#%J=\"$Z9\"#J1!%JA\"\"ZE!!ZA!$ZI&%J=%%JM!$ZM\"$*Q\"" + "&ZQ*#ZQ!$ZA&#JI!#ZY!%:U(%*]&%Z]!$*Q\"(;!-$K!$$J]'$;%#\"Z]$\";)\"$+)-" + "%[5!$+-\"![-!$;-\"$+1!$K=#\";1\"\";1\"$[-%&;5'\"[5!%+9\"#+9!$[=!$[9!%[1!" + "$[=!)[=*&;A\"'[A!$[-!(+=\"%+M!%[=!$[=!'KE,#;A\"(+A&$;M\"%KA$\"[A!$[A!" + "%+A!&[A)%+E!%[A%$[=!%+9\"%KA$%+U!';1,&[=$#;E\"%K-$&+A!$[A!%K=$'+A*" + "\";5\"$+E!';=\"&[9!\"[A!&[=!%+I!#[9!%[=%&;E\"%+=\"&K1$&+=\"$;=\"'K-!%[5!" + "#K1#$[1$%;1'&K=,#+-\"$K-$\"[-!#[%!$*]\"$;%\"#[%!&+-&%+%\"$*U\"&J]!#+!\"" + "$*U\"$JM!#*Y\"$;!\"$[%%$[!!%*Q'%JM%%JI((ZU/#JI!%*9&&JY%#:E#%:A!#JA!" + "!*5!%ZI*#J9!$J9!\"*5\"#J5!#J5!$:1$#J5!#J)!#Z%\"$*1\"$*-#&*!$#:)#\"J!!" + "')])$IQ\"')I\"\"YU%#9Q!$)9*$YM##II\"$Y=!#YA#&)=-#I5%\"Y=\"\"Y%#\"YE\"\"Y-\"" + "\"Y5\"#)-#!91+!))'%9) %!#9%!!)-$$I!&\"Y%%%)!)#(U!\"XQ%$(Q!#(U#$HI$" + "#89%\"XA##8A%#XE!$(5%\"H5\"\"(5#$H1$\"X1#\"H-'$8)!$8%)\"H!!\"8!!\"G]\"\"WY!" + "#GE)\"7M!\"8!!!H!!\"GE\"\"7]!\"WU#&'Y&\"G]!&(!,#X%\"#8%$#H%&#(-!!(9!!(9#" + "\"(%%\"89!\"85!$HE$\"HE$#HI&\"XM\"#(I$\"XY\"#(Q##XU&\"8A!&8Y(#(Y!\"Y%\"%I%'" + "&I%)#HU\"\"I)!$Y-!#I5%!Y5!#)5##))##)A#&91'$IE)#9=!$9E%#YE\"#9M!$IQ%" + "#YA#&)Q(#IQ\"#9U!$J!&$)Y#$YU*$Z%*%IU)$IY%$*%#\"Z)!\"J-!%J-\"#Z-\"%*1'" + "%Z)'%*5'%:A!#J5$!ZA!#JA!#JA!%:9$#ZM!'ZI'\"ZA!'*M'!*Y$'*Y,%:M$#ZU!" + "%JY!#ZU!#ZY!$+)!!ZQ!&JU%#Z]!$*Y\"#+%&$[%!\"[%!$JY!#[)!#ZQ!%+)\"#[9!" + "%[-&&;9+%+1\"$[9$#[1!&;5#%;5#&+5\"#;9\"%+)\"$[9!#K=#)K11%+M!![I!$[E!" + "%+9\"%KA$&;=&%[9!%;=\"%;A&%;M\"&;E'&[9)$[I!(+5\"$+U!'[A!&+E!';M/&;I\"" + "![E!%+M!%;A\"$[A!%;A\"$[I!$[E!&[E%$[I!$[E$%KE#%;M\"$[I!![A!$;I&%+9\"" + "$;E\"%;A\"#+A)'+E*&+9*$[A!&+A\"%;=\"&;A'$+=!%;='%+U!#[9!'+9\"%;I\"%[9!" + "!+1!#[1!$;=\"#[%!'+-\"%[-)&;-$$[1!#[-!#[%!%[1)%;-\"#[)!\"[)!$+)\"';-," + "%[!\"#ZQ!&+)&$:Q$%*U'#ZQ!#ZY!#ZY!#ZQ!&JQ-$JI!$JM!#ZE\"#JI!!ZE!#Z=\"" + "#ZQ!%:=(#:=#\"Z=%\"Z9!\"Z)\"#J5!$J1($Z5&&Z!$$*1#%:)!#J-$!*)!%:!(#YI&" + "$IM%#IY!\"I]!$IQ&#IU\"#9I!#IY!#J!!%)I$#IQ!\"9M##9A!!YM!!)9!#)1#$I5&" + "!95\"\"Y1\"#91!#)-#!))!!I!##9)!%)%&\"8M##8]$\"8I##HU\"#(M#\"Y%\"#XI#$(I$" + "#8=\"#8I$$HE*!(I!#(=$#X=$\"X%#\"H5\"\"X1#\"8-!!H%##H)!#7U%\"W]#\"7Q!\"(%%" + "%7A$$WM$\"7U!#H-!\"WI%#7Y#!()!#8!\"#7]##H!&$H-$!H1!#X-!\"8=!\"H1\"%H-$" + "#8=$\"8=!$X=+\"XI\"\"8I!\"8A!#(M#$HM#%HI%#(Y##HQ%\"8U!%XQ&#Y% )!#I)\"" + "#9%!#I-%#I%)#)1#\"I1!#)5##)9#\"9=#!)9!$)E!$9I%\"I9$%)I!#)I&%Y=+&99'" + "#I]!#YU\"#9M!$Z-&!YY!#J)!#J!!%Y]$#J%!#J)!$Z)&$:A#\":%##Z5\"\"Z%\"#Z=\"" + "$*9\"\":1#$J=!%J9!#ZE\"#ZI!%*E'#J1!$JQ%$ZI\"#:M\"$*M\"$JI!$*I\"$*Q\"#ZU!" + "&JY,#ZI\"%K!$#Z]!$ZY\"%+%\"#[%!%[9$';%$#[-!$;)#%+)\"%[-&#K-$$+9\"$;1+" + "%K1('[9&$[5$%+5\"\";=\"$[=!%[)&\";5\"'+=*%KI#%[=!$[A!&KA(%;A\"&;U\"'+A\"" + "%;5\"'KE($[E!%;A\"%;E\"%;E\"&;I&&[M)%+Y!$[E$%;E\"%+Y!);E($;I\"$[I!%;I\"" + "$[I!$[E!#[E!%[I$&+I%%;M\"%;1\"$+U!%;E\"%KI#%[=$$+Q!$[9!%+I%$[E!%[I!" + "%[I$$[E!&KE(&KA(%+I&$;E\"%[A$$;A\"%+U!#[A!$[=!%;A\"&[=!&[=$%+1\"%[9%" + "&[9!$+9\"#+1\"%[5!#+-\"\"[9!$[=)$;1#\"[1!%;1'$ZU!%+!\"$;-\"#[%!%[%)\"[%!" + "#[-!$[-$$+%&$;%#!JU##*]\"&:Y$$*]\"#JY$\"*E\"$*Q\"\"Z=!\"JU$%J9\"$JM$$JA!" + "#ZQ!$*M\"!ZA!&:9!%J5\"#*!#$:=$%J1&!Z1!%Z%*%*='\"ZE!$J)%#J1!$J%%#*%#" + "':!\"%9]\"\"I]!$IU%#YM&#Y]\"$Y]##9Q!$)Q$\"9Q##IE\"#9E#$)E##IA!$)9*$9=%" + "#Y=##I1%#95$&Y1-\"Y1\"#9!\"#I!#$Y%!#Y!$#(]##(]#\"XY\"#8U$$8Q(\"I!!\"XM\"" + "$(E(!(I$\"HE!!(E!\"X=(#8E%#85\"\"H1\"\"HA%\"X!!\"X%#!(-!#8)'#X!!#7Y%!']!" + "#GM$\"7E!!'U!!'U!#X%'\"7U!#H!$\"8%!#X%'#(-!\"X!##(-$!H1#\"8=#\"(-#%(9&" + "#8I$#X='\"XA!%HI%\"8I##8M$\"XQ\"$HM#!HU#%(M#%)!\"!H]!!)!$%9)&%9%*" + "\"8]!#)-#$)-'\")A%%I1$!YA$$)5!\"I5!%IA*$9U!$)=$%)E$#YI##YQ#$)I$$YY#" + "&)U!!)Q!#9U$&I]*$IY&$:!!$YY&$*%#%*!!\"Z)\"#Z-\"\"J--#J1!\"Z5!$J5!#Z=\"" + "#J1!#J=!#J=!%:Q$#ZQ!$:I#&:=%$:E$$JM%%JQ$#ZQ!$JA%&JY,$*U\"$*Y\"&*]&" + "&JY!\"ZY!$K!$#[!!%*Y&(;5($;%\"%JY(%;1#$[-%#;-\"%K-(\";=\"#+1\"%+1!$;I\"" + "&[5!\";9&$[5!%+1\"\"[5!&+=&%+A!%KE$$+E!&+A\"&;Q'&+9\"'[E!%;I\"$;E\"%;A\"" + "'KE,&[M$%;I\"';A+$[I!&+Q%%KM#$+Q!$[U%%+M%$KQ#%[5)&[]$#[M$$+M!%+M!" + "$;M\"$[M$$+M!!+Y)#+Q!$+M!&;A/#[A!%+M%#+Q!\";]\"#[E!$+U%#[I!%+M!(,!)" + "%;I\"%[E!$[A!%;M\"%;Q&$[E!%+E)'[E)&;E'$[=!$+Q!%+M!%[A$$[A!$[9!%+=!" + "$KI#$;5&%[9$%+5\"$[9!&*Y'$[1!$;-#%+1!$+1\"%+1!$;-#$;%\"%+=&#ZU!%K1$" + "\"ZM!&;!,#ZY!';5#$:U#\"+%!$J]!&J]!&*U+$:U#!ZQ!':A%$*M\"\"*A\"#JE$$ZM%" + "#*I\"%ZI\"$ZI&!ZQ!#Z=!)*%'#Z9!#ZA!%Z5\"$*5\"#JE!#Z-\"%J-%!:-&#J!!$J%\"" + "%*%'%*!$\"*!%!YU!#I]!$9U!#9U!%IQ&$9M%&9M#$)E!#9E!#9E!\")E\"\"Y=%!Y5!" + "$Y1*!)9!%95,$)1'#I-%%9-)#))&#Y%#$)!!#)5#%8]#!H]##XY#\"HU!\"HQ$#(U#" + "%X])!H1#\"8I#$8E#\"81!!(=!$(E(#X9'\"(A\"$81&#H1&$8-)\"X)#\"X%!\"X)##'Q$" + "#7M#\"'I!\"7U!#GY#\"GU\"\"WM#\"GU\"\"G]!\"H%\"\"H%'#7]%#8=%\"H5\"#(5#\"(1##89$" + "#8Q$\"8M!\"XE#!HM&!HI!!XQ!\"XM\"%HQ(!XU$#8Y$\"8Y!#Y%*#X]&$Y%!#I%#\"Y%%" + "#I-%\"I)!\"I1!!Y-$#)5#!Y9!\"IA$%)E'#Y=#$)A##9Q!#9E!#9I!%IY\"$IM\"%YY(" + "\"YU\"\"J%!$9]'&I]#$*!#\")Q\"\"J)##I]!$*!1\"Z-%\"J1!$:1!#J-!#J1!%*9&#ZA\"" + "%*9'$JE%$*A\"\"*Q\"#ZQ!\"ZE!%:I'$*E\"%:E$%JQ!$JI%#ZQ!&JY,#ZU!\"ZY!#ZU!" + "$J]!#[)%$JY!%+5\"$+%\"%+)\"$;5\"%;-#!+1$#[!!#[1!%+1&&;E\"%;5#\"[)!#[5!" + "&[)\"&K9$'+=*$[5!#[=!$[I!&;I\"%[A!%[=$&;I&&;E\"%[E$$;=&%+I%&+A&$+A%" + "%;M\"$[E$#;Q\"%+E!$;Q\"%;M&$KY#$+Q!\"+U!$+I!$+Q!$;M##[=!&[M%$+U!#;Q\"" + "&;Y\"%+M%%;U'$<%\"$+Q!$+U!$+U%$+M!%;U&&+Q%$;I\"&[],$+]!&+=!$[U$$;U\"" + "%+M%&+M!$KE#%[M1$;Q\"$KE##+I!'+=\"$KY'&[I$![A!&;A&#[A!#+I!%[E!$[A!" + "%KA$$;M\"%[9$%;A&%[E$$[9!%[=!$[A!%;=\"#[5!&K)($Z]%$[E$$[)!$;1#&+%'" + "';!$#Z]!!+%!$[)!#[-%&;!#$*Y&\"*U\"$:Y#&*Y\"#[!!$+!\"#ZE\"#*]\"$JE!\"ZM!" + "%:I'#ZA\"%*E'#JE$#JA!#Z=\"$J=!#*9\"%*9&#JE!$:5$%:-!%:-($*)#$J%\"$*)#" + "$:1!#J%$#IY!\"IY#$9Y!!9Y\"\"IE!$IY%#)M\"#II$$IM&!YU!'9E+#)A#$IA%#9A!" + "!I=&!Y9!\"Y5(#Y=&!)=$!Y)!#I9\"\"I)!$I%'$I1##I!#\"Y!##XYc$$HQ'\"XU\"" + "\"8Q##(I##8M$#(A$#(E#\"H=!!H=!!X-)\"81!\"(9\"#(9!$!8-\"\"H%'\"7U#\"7]!" + "#7Q#$7M%!'Q!\"8!!#']!#H)&#()$\"81!!(5!\"X)\"#G]!\"X-\"#(5$!H5%#85$$85&" + "#HA%\"8A!!(M!\"8I!$8M(#(M##8Q$!(U!#HY%!XY*#9)!\"8Y!#9!!$)%$#9)$\"IA!" + "$)-$#91$\"91#$IA)$Y1'!Y=!\"I=!\")=\"#)E#$9I\"!IE##IY!$YM##IY!#9Q!#Z!," + "\"IE!$9Y!$J%\"$Z!#$:1!#Y]\"%:-(':%#\"J-!%*1#%Z1#\"J1!#J5!!Z9!#ZA!!ZM!" + "%:-!\":A\"#ZI\"\"ZI!#JA!$+)\"\"*Y!%ZQ\"!ZU!\":U\"#JM!$[!!#[%!#[!!#ZU!$+%\"" + "%+!\"#;)\"(K%*%ZU\"#[!!$[-!$K-($[-!#+%\"#K9$!+5$#[%!'KI#%;I\"%[=(%+1\"" + "%[I!$[A!$[A!\"[5!$[A!%+A!$+Q!$+M!$[E!$+M!&[I!#;I\"$KI#%+M!#+M!$+M!" + "$;M\"\"+U!$;M\"$KI'$+U!$;Y\"%+Q!$;E\"&[])%[U%%+U!\"[I$'+M!$KY#%+Q!&;I\"" + "$;Y\"%[Y$*;I'%KQ#$[U%$+M!'+Q*%;U\"%KY#&[U%&;E\"([I!#K]#%K]#&KU#$[Q$" + "&[Q$$;M'$+Q!&;I+%;Q+\"[Q%%+M%\"[E!%+=&%+Q!%KM#%[I!#KE#![I!&[E)%[E!" + "#;E\"#;=&%;A\"&+9\"&;A\"'[=!%+I%$[9!$[9!&;9#%;1#![5!#[1!$[5(#*]\"$[%!" + "$J]$#[-!%+)&%[5%!+)$$ZY\"#ZU!$:]##[%!!:]*#ZY!#Z]!#ZU!\"ZY!\"ZQ!$*Q\"" + "(JM.#JM!$JM!$ZA%#ZQ!&:I!$ZA&#J9!#Z9\"$:1!\"J-!#:1#$Z1\"#Z1\"%:-%!*-!" + "#J%!#J%!#J%!$)M$()]*!)U$$II##9U!$9U$%)Q$#YE#&IQ(\")I\"$IE%$9E$#Y=\"" + "$9A$#9M$&9-.\"Y)\"#)-#\"I1!$)%!&9%.\"Y-%$)9$#H]%\"Y!#$))!\"8Y!#(Y#$(Q'" + "#HU%$8E##(Q#\"HM$$(E$\"H9\"\"XA\"!(=!\"X=#\"X5#$(!#\"8)!$8-#\"H%\"\"GU%\"7Y$" + "\"WU!!GQ%#8-%\"7Y$\"GI\"#G])#()!#8%$\"8!!!H-&#(1##85$!H9!$XM%\"X=#\"H9\"" + "#XM!$HE*\"H5\"#(M)#XM!$8E&#(U##HU\"!(Y!#HU-#(]!\"9-##X]!$Y5*\"9A#\"9)#" + "$)1$#Y5##95$$IA&#)-#\"I9!#)I##9I!%YU#$)U#%II##9U!#9E!\")U%#I]!&*%$" + "#YU\"#9]##Z!&$*!##IY!%J1&#JA!&:-)%:1!$Z1\"\":5\"%:5!\"*5\"$J-%!Z5!#ZE!" + "$Z5&$JE$#*M\"#JI!$JI$$JM%#:Q\"$JQ%$ZU\"$JY$$*Y\"#[%!\"*]\"%[!&$;)\"\"K!#" + "!Z]!%+1&$[)%%K%!$+-\"%+-&$[1!%K)$&[5!$+9\"%[5!$[9!\"[9!$;=\"$[=!#;=\"" + "%;M\"![9!$[A!%K5$%+M!'KI,$[I!%;E\"%[Q(#[M%$[I!\"KM'%;M&$KQ#&+M&(+Q%" + "\"+Q!$;I\"&KM#%+U!%+Y%&KU,%+U!%KU#%+Q!&[E%#+Q!%KY#\"+M!%+U!%+Y!%;]!" + "%;Y\"%[Y$\"KU#$;Y&%KY#%\\)($+Y!'KY+(+Y!%+]!%+Y!$+Y!%+Y!'%#&]A&$]Y!%]Y!'=U(&-U!$MY!" + "%]Y!'MY#%^!!%^%%%]]!%]Y!(-Y+%N)%%^!!&-Y!$MU!%]U!$>%%(-Q+%]U!$MU!" + "%]M!#MY!%]M!&]M!#=E!%]Q!(=I,%M=!&N!$%]Q!&]E!&]E!&=A$#MA!&-A\"'-=\"" + "(=1(&M9%$=9!&]1!%]=!%M1!&=1$']-!'M)%%]9!&M)!'M%$%]%\"$=!!%!!%^%!%]]!" + "'-]!&]Q!&N!$&MU$&=]#%]M!%]]!(-]%$N%!%]]!(-Y+%]Y!%^%!)]Y(\"-Y!(-Q!" + "%]U+%]Y!%]]!&=Q#&-Q\"'-U!)-U%%]Q!&]M!*=M+&M=$'=A($ME!%]Q!&]E!#]E#" + "'-E!$MA!'==(*=5+(]=$$]5\"&-=#)-E+&]I!']-*%]5!\"M1\"&M1%(])/%M1!&-!#" + "%<]!%%(%^-!(=Y!" + "&-]!$^!!'-M''>)''.!%$N!!'.!!'.!+&>%#&-Y\"&-]!%]]!#]]\"$N%!%^!!%^%!" + "%=Y$'-Y!%]M!%]Q!$M]!'-U&(>%!&]A!\"-Q!%=E$%]I!%ME!%M=!%=I$)=I!'-1'" + "%M9!%MA!%]-\"#=9!(M=$&]9&%]9!'-5'&]A!%]1\"%M%*(M-$'\\]&%])\"$=)!%<]!" + "%M5!')!!^!)%^)!&.!!'-]!&-U\"'N-\"%^!!" + "&.!!%^-!'.%!%]Y!$N)!'-Y!$N!!$N!!)]U)%]]!&]]%#>!!%^-!%^!!'^-$$MY!" + "%]Y!#=Y!%]Y!%^!!%]M!'.!!%]Y!%]Y!$M]!*MY!%]Q!%]Q!$=9!$MQ!&]E!&]I!" + "%]Y!&-=#'=E\"#]9#%M5!&=9$#=A!&=9)\"=9!)--!\"-)!#=)!#M%\"(M%$#=5!\"-)!" + "%=!$&M!%&M!!&\\Y'&LY&%,U#$,M)%!-%^!!(M]'%^!!%^%!!.-&%^)!%^%!#>%!&^%%" + "&.9!%^!!$N-%%^%!$N%!%.9\"$M]!%^!!'.%!%]]!%^%!%^%!'N%('.%&%]Y!$>1$" + "*^!!%]]!']])%.!(&-U!(=]!%^%!)>!*)-U*%]Q!%]M!&=U#%]Q!%^!!%]M!$MM!" + "%]I!%ME!'-=!']E$\"-E!'=A(&-E\")=9!%M-!&])&%M5!%M%!%]1\"(-1+%]!\"&=)$" + "'1!'-]!%^!+%]Y!%]Q!!.5!&>!#(>%!*^!!&.=!%^!!'.)!%^)!%^)!&>)\"%^!!" + "&.5!%^5&$^5!%^-!#>%!%^)!%^-!%^)!,N)**.%)'.%&%^!!#^)\"&.)&*.%#%]U&" + "&N!$\"-]!&>1\"%^)!%]Y!%]]!&.5!%]]!#MY+%MY%*-Y)%^%!&=Q(%]U!%]Q!%]I!" + "&-9\"%]M!&]A!&]E!\"-A!(-=!(]A)%]I!&-=\"*-I4&M5$%M5!&-E\"%\\]&']-!$]!'" + "'-)\"%]%\"$=!!&=!$)-!\"(\\Y!%!%&=]#'-Y!#=]!&M]$$N%!" + "%^!!%]]!'-Y!(>)!'^!)'.-!%^-!&N1#%]]!&>1\"%^)!)>-%'.!!%^1!&.9!$N-!" + "&.=!'>)'%^-!%^)!&.-!'-]!'>5&(=]!%^!!'>-!'>9!%^1!&N1$&N)#%^%!'>5!" + "$N)!(>%!%^%!'-Y!$N!!%^%!'.-!%]Y!'-]!%]]!'-Y!%]]!%]Q!&-U\"%^!!#]1#" + "(]I$%]M!\"-U!%MM%(-I!&]E!&]A!%MA!$MQ!&]=!%-5#%]=+&M5$(MA$&M-!\"M5\"" + "'=%)$]5\"'M%*%M!!#\\](%LU!%]!\"&LM!$!!$N!!%^!!" + "%.%\"'^)$'-U!%^)!&.%!'.)!'.)!%^-!%]]!%^)!'.1!&^5%'^1)'>1!#>-!%^1!" + "&>1($N-!(.9*'.1!).1#)^9,&>%#(.1%(^--'>1'&^5*&.5!#>!!#N-!(^)#$N1!" + "(^-#'.)!\".!!#N)&&^)%'>9!'.!!'.)%%]]!(>%+%^!!&]]%'.!!'N%#&-U!$ME!" + "&=Q#$MQ!$MQ!&]Q%%]I!%]Q!&-=\"$MI!#=I!(-A!$]-\"&M9$$-1$&]1!)=-\"$]1#" + ")--&%M-!&=)$'M)$(\\Y!'-!,&=)$%\\Y#&=%$*%!$]Y!&N%$" + "%^%!(>)!'.)!%^-!%^-!%^%!&.9!$N1!%^)!'.%!&N1$$^5!&>)\"'>5!%^-!&.5!" + "'^E#%]]!)^5&&.5!(N9!&.9!$^A!,^1*%^1!'.)&&>5\"&>1\"$^5!&>=\"&N)$%^1!" + "'>1!%^-!%^-%&.9!%^)!'.)!%>)$'^1$&^!%&>!#$N!!$N!!%]Y!#=]!$MY!&>!#" + "&]M%&-Y\"'-U&'=E((-Q%%]M!&-I\"&]E+'ME(%MA!%]5\"&MA$&=1)(=9#%]%'&-1#" + "%MA!&M-!%M%!&=5((M!%$<]!&M!!'L]!%-#'.)%" + "%^-!%^)!(>-!&.9!%^1!&.9!%^!!&.5!&N-#\">5!&>5-&.=!&.9!).9)&.9!&.9!" + "$^E!&.A!%.=\"&.9!%^1!&N9#&NA#'>9!&N-##N9!%^1!'^9)%^)!&.9!*NI$'.-!" + "'>5!%^-!(>)&&^-%%^-!%^-!(N9!&>%#%^1!(^)\"%]]!)=M,%^)!)=Y%%]]!&N!$" + "\"^!#%]M!%^%!%]M!'-U!%MA!(-M!(=I!%]M!(=U!%MA!\"-=*'M5$%==$%ME!%]5'" + "%M1!%M1!%M-!%=%$%M)!%=-$$-!)&M%%(,Y,%\\Y\"&LU!%!!&^-%)N%!%^-!)N%&&^-%$.!$(>-%" + "(^)($^!!%^1!'.%!\".-!&.5!$^5!&.I!(>-!&.5!&.9!&.5!&.=!%^)!&.=!&.=!" + "$^E!&.M!'.1!&.=!'.1%&.5!#N=!&.=!&.9!&.=!%N9$&.9!'>M&#NA!$^5&*.9\"" + "&.9!(.9%(^-(%^-!%^1!&N-#$^5!'.-!+.A,&>)\"%^%!%^%!%]M!%^-!'N)('-U!" + "(=]!'MY-%^!!(MY\"%]Y!%]I!+-M#(-M+(=U&(-=!&]M!(MQ,&MA$'ME(']=/%M1!" + "'M5*(-1'']5&'--\"&M=$$=1!%M)!%])\"$<]!%!!%]Q!#=Q!%]Y!%]]!#>-!%^)!!>-\"$N)%#>)!(=Y!(>-!'>1&%^-!&N%$" + "'N9(&.9!%^1!&.=!&.5!&.9!)^Q&&>5\"(NA,)>=/&.=!&.5!$^=!$^A!&.A!(NA!" + "&.A!&.A!'N=\"\">A!&.=!&^A$&.U!&.=!(N5!'NI'&^A$%N=$&.A!(N=!%>-$$^9!" + "&.9!$^5!&.I!+N9*&.5!&>5\"&.5!$>1$%^)!%^-!%^-!(N!!$N%!%^%!%^%!&.!!" + "!.!%'=]\")M]!'-Y!%]U!$MU!&MQ$(-M!%]M!%]M!%]I!(]E.$MA!'M=$#=5!%MA!" + "&M=)#=5!%M1!%]5\"'M-*(-)\"&M%%$=1!(\\]!%\\]\"&,]#&L]!%!!#M]!(-Q!" + "(-U*&-Y\"%^)!(=]!$M]!%^!!)=U0&>!\"%^%!%^-!%^)!'M](%^-!(N1!(.-*%^1!" + ").9)'>9!'^9#'>5&(>%!(N=!'NM'&N9#*.A''NA''>A!'>9!(NM!&.E!&>E\"(^='" + "'>E&#^M'&.9!).E#*.M!&.Q!'>A!&.E!\">M!&.E!&.]!&>A!&.=!#^A\"&.A!&.E!" + "&.=!#>=%&>=\"&.9!(>1!&.=!&.5!'>9!&.5!(>1%&>-')N10%^%!&N)$&.)!#>1!" + ")>)%%>%#(-U!(=Y&$MQ!(=U'%^%!%]Q!$MM!&MQ$%M1&)=M!*-=$&]E!%M9*$]E\"" + "%=9$#=A!%M9!$<]!%]-\"(=5-#=1!$=%!(M%$%LU!'--\"&]!!%LM\"%\\U\"%!&%^!&%^%!%^)!'.)!%^1!$N%!*^!!'.1!%^1!$^=!%^1!" + "$^E!&.E&&.=!&.5!#NA!'>9!'>E!&.5!%>U\")NQ0%^A*&NQ\"'.I%(^M'(NI!'.=%" + "(>I+&.I&&.A!&.M!&^I)&.E!)^E!&.A!'>I,'>A!&.=!$^E!&.E!&>I!%.Q'(NI&" + "'>A!&.A!&.=!&.=!$^E&&.9!#^5\"'N9'#>-!%^)!$N1!%^-!&>!\"%^)!)N)&'.%!" + "$N!!'.)!%ME!$]M!$MY!)-Y)$M]!(=Y!%]Q!']Y))-A+$MQ!&]=!'ME)$ME!(-=!" + "$MA!*=9!%M9%#M9\"&M%!%]-\"%M)!%]=!&-%$']%!%-%$'=!)%\\]\"%1'$^I!&.5!&.A!$>)$" + "(.5*&.=!&>E'&.A!&NA#'>E!'NA''>=!'^I\"(^A\"'.I%#NI!&.I!+^M#'NM'$^M!" + "%^M%*.A'&.M!'>M!&.I!&.M!&.M!&^I$\">M!'>E!'>I!&.M!&NI()^I,$^E!(^E'" + "&>E!#NI!\">E!)^A!'>E!%^1!&.=!&>5\"#N5!'>5!%N5$&.9!(.A*'^5)#^1'&.)!" + "'>-'%^1!$N%!'N!)'.!!$M]!&-Y'*MY&&]M%#ME\"%]I!%]I!%]I!%M=!'-Y&$MI!" + "&-=#'-5\"%M9!%M5!\"M=#']-*%]9&$=)!'-%#&M-%&\\Y&&L]&$\\]#$=!!&\\U&%!0&]Y%%^%!%>%#(>1!'>1,%^)!*N-%&.5!%^)!'.1!+.5'#^9\"&^9%$.A#'.=%" + "'>Q!&^A$&>=\"'.A&(>A+&.M!%.9\"&.=&&.M!#NM!&.I!&.Q!&.I&&.Q!$_)!\"^Q#" + ").Q-&?!!(NM!'>Q!&^I$'^U\"'>M!&.]!#^Q!'>U!).I.(N=!&.M!'>I&)^I!'>I!" + "&^I$(NA!)^A!&.M&&^9$'^9#&.A!&.I!$^=!'>5!'>5!'>9!%N-%&.5!&.5!&>1\"" + "'>-&'-Y&#^)\"$^!&'.!!'.!&&-]\"&]=!'=Y'&-Y\"%]Q!&=M#%]Q!%ME!$MA!%ME!" + "%]M!%]E!&M9$%M9!(-E!'-1'&=1$%M-&'])!%M%!&M)!%])\"&L]!$=!!),]!%\\U\"" + "%LM!%%!%]Q!'M])" + "%^!!%]U!\"^!#$N1!'-]+$>)$'.-!'.1!&>1\"&.%!&^9%)^=!(.5$$^=!&.A!&.Q!" + "$^E!&.E!$^Q!&.Q!(^Q!'^I#&.A!(>M*$^M!'^E#+NY.\">U!'NM''>Q!(N]&(>U$" + "(>U%&.U&&.Y!'.]$(/)().I#(>Y*(^U'&.U!'>I!&.Q!(>U/&.Q!&.I!)^I!&.M!" + "&>I!$^A!*.M!#>=%&>I!&NM#$.A#*^E%'>9!(NA!'.=%&.9!(NA!&.=&&>-\"&N1$" + "(.1*#^-\"&.-!%]]!)>)*'^!)%^1!#>1!%]Q!%]Y!(-M!&]I!'-A!#=M!$MM!%M=!" + ",]E!']9+$MM!#M5\")-9!%M5!(]5$)--!'=-$&]-'%M)!%-9#%M)!&]!'%]%\"(LU%" + "'LU!&,U#$LM\"(%/%]]!*^%!" + "!-M!&.%!$N1!$^9&(>)!'>)'%^1!&.1!\"N1'(N9+$^9!(^1-(>5+&.A!'NE''.I%" + "&NE#&NI\"&^=$&.Q!&>Y!&>Y!&NQ\"*.Q'&^U)$^Y!'^]\"&^Y#'NM!'>=!&.U!'NY'" + "'NY!(^U!*.Y'&.U!&.Q!'^Y\"&.Y!%/!!+>U'!.U!'>E&&>Q!).U''.Q%&.E!$^M!" + "'>M!(^Q!&NI#(>M%'.Q%&.A!#^E\"&.A!$^5!)^Q&$^=!'>-&$^A!$N)!'>5!&^5%" + "&.5!%^1!).-$'.)%%^)!%^-!'N5(%^!!%-]#$MQ!'-Y!'-U!'-M&'-M!%ME!'-M'" + "%]A!%]I!&-M\"%MA!%M=!%M5&\"-1%&-=#%M-!'\\M'$=)!&<]$%M!!(,U#%!%" + "%^%!).1$'>)'%^-!&>!##N=!$^5!'>1&(.9*#NI!%N=$&.9!$^A!#N9!&>E!*NM4" + "&.A!&.Q!&.M!#^=\"$^Q!#NE!(^Q!)O%#$^Q!&^U#&.Y!'NY!'^Y\"&.Y!&.Y!*>]-" + "'_)(*.]!&.]!&.]!&?%!*?!(&.U!&?!!$^U!\"^Y#&.Y!*?!!&.U!&.]!&N]\"&.I&" + "&.]!&.Q!'>U!&.M!&.M!'>I&%.Q!'>A!&.I!&NI\"&>A!&.A!(NA!%^)!&.A!'N-\"" + "#>-!$N%!%>-$&N-#%^%!&.5!%]]!%^!!$N!!']])%]Y!%]M!)-]%#=Q!%]]!&MY$" + "%-=($MI!$M9!&-A\"%]5\"&-A\"&-A#%M-!%]1\"'--#$]%\"%M%!'\\M\"%M)!$,Y$'L]%" + "%LU!&\\Q&%!!%]]!%^-!%]]!" + "(>!!$>)%%N5%'^-)'>1&!.9!$N1!'>9&(.=$&.I!&.=!%^A&&.I!&.E!&.E!&.E!" + "(NM,'>=&&NQ\"(>A+&?!!)^U,&.U!&?1!*^Y$$.Q#-_-+$^]!&?!!&.]!&.]!&.]!" + "&?!!$_!!'O-!&^Y#&?-!(_%!'O-!&?!!'^]'%^]%$_!!%N]$*.]!&.Y!&?!!&.Y!" + "(^U!$^U!(^Y!'NQ'*NQ##.Q)*.M!&.I&(.E)*NA0&.I!&.=!$^9!(^-\"%^1!&^9%" + "&.=!&.9!#N9!$N1!%.9\"+^)+%^)!&.%!%^!!&N-)'.!%&=]#$MQ!&-]!(-U!&=E$" + "'-A'%]I!(]A$%MA!&-=\"#=-!&-E\"$]9'']1*#=A!%]-\"%-1$#M%\"%!$'.1!&N-$" + "%^%!#^!\"&.5!$N1!)>5*&>E\"&.A!&.=!%^1!'.=%$^M!&NA#).I\"&.M!&.U!)^M1" + "'>Q+'>Q&(.U)&.M!&.Q!$_%!&>]!&.Y!&N]\"&.Y!'O!!&_!)&?!!(_!!&?-!#O1!" + "'_)(&O!\"'N]!'?%%&_9\"&O%\"&?!!&.]!&_!#%O!#$.Y#'/!*%_%$&.Q!'N]!&.]!" + ").]-+NU'*.U!&.Y&&.Y!%>Q#$^Y!&_!#'NI!'>I!&NI\")NA%&.E!'^)*(.A$(.=$" + "&.9!&N-#'>9!&^1%%^)!#>-!&>)\"\">!!%^)!%]]!%]]!%.!\"%]Y!(-U%(=Y!%]]!" + "%ME!%]I!+M5'%M9!#M9!(==\"&-5#%M5!&-9\"%]I!&]=!%M%!,M=&'LM!(]!!&\\]&" + "&9!'^=(+NE4$.I#&.E&'^M\"'^=(!>I''>M&#^Q\"'NY!" + "&.Y!&.]!$_!!&.Y!&.]!'^U(&^Y#&NU\"'O!'!/!!&.]!&?!!%/-!(_)!&?%!*>Y3" + "&?%!&?%!$_)!'O)!*_%#%_%%&?)!'/)$&/9%&?)!'O1!'O)!&?!!&O!\"&?!!&^]#" + "%/-!&.]!'>Q!&.Q!'NY!*.U!*^M**.M2)?!('NE!#NE!&.I!$^A!'^E\"#NA!&N=#" + ")>=/'.=&$^9!'.!!#>1!%>-$'>-!&N%$$N)!%^-!$^%!%^!!%]Y!%]M!%]Q!%]Q!" + "'MM.%]M!&-I\"#=E!&]A%%M9!&-=\"$]9\"&-A\"(=1#\"M-#(])&&=9$%M%!'\\Y!%M%!" + "%\\]\"$L]\"%LQ!&LM&%,]#%!!'=U''^%)'.%!%^%!" + "%^-!'>)'%^-!(^)(&.)'&.=!&.5!\"N5\"\">I!$^A!$^I!$^E!&>A')NY$&.Q!+NU!" + "\">U!)>Y)%^A&).U-(_%!&.]!'/5$&.Q!$_%!&?)!&?%!&O-!&?!!#O-!&?)!$_)!" + "(_%!&_)#&?-!#O!!&?)!&?)!&?%!(/A!*?)!'O),(_)!(>Y*'_%((^U!#O%!+>Q!" + "(O!%(_%!%?%\"&.]!&.]!&?!!'.M%&>U!$^U!'NM'\">M!*NM)'>I!(^Q!&.E!-NA&" + "%>=(&.A!&.9!%N5%&>5\"%^1!$>-$%^)!%^-!'.!!#>)!,>!)&=]#$]Y!&=E#$MM!" + "(=Y&&=U#\"MU\"#=I!'-I&&]=!&-A\"(]A$%]5!%M5!%]5\"(--'&=)$\"-%!(LQ!%]!\"" + "&LY!&5&&.Q!&.Y!&.M!&.Q!+>A'$^Q!&.U!" + "(^Y!)^U,'>U!&?)!'N]'#N]!(_%!$_)!&NU\"&.]!'O)'&?%!&?5!&?1!'/9$%/5!" + "&_-#$^]!%/5!'_A''O-!&?1!'/1$'/5$*_1)+O-!&?-!%/-!'O)!&?)!)?5\")?%(" + "$O!%*O!/&?%!&.]!'O!!%/!!$^Y!'>U!'.Y$'NY!(^Q!&.M!$^M!&>1\"&.E!+>M!" + "&>A\"&.9!&.9!&>=\"&.5!&.-!&.9!&N-)(.1*'.-!&>%\"&]]%%]Y!%]]!'>!')^!(" + "(-M!%]Q!$]M!%]I!\"-E!#MA!'-1'%M=!%M9!%=-$&=1$(=1('=!)%]%\"%M%!'=%(" + "']!!%LU!%M!!*1#" + "&.5!&N5#&.9!'.I/&.A!&.=!%.I!&.E!%NI$#^M!&.E!'NU!&.Y!&^A$&.Y!#>Y%" + "'N]''^]!&.M!%O%#&?%!$O5$%/-!&?)!(_!!%/-!)/5-%/-!&?1!'O)!#O1!&?1!" + "$?1#*_-)&?-!&_1#(?))'_1!&O-\"*?1'&?!!*?5''O1!&?9!(O9$&?%!'?)%&?)!" + "'/)$#NY!&?5!&?!!&.U!,/)/'O%!'/!$&.Y!&.Q!&.M!(NQ&&.M!'O!!(.E)&^E)" + "&.=!&.A!&N=#&.=!'^5#&.5!(^1-%^1!$.-#$N)!&MU$&]]%%.!\")M]!%]]!(=]," + "#=Q!%MQ$%]Q!\"-Q!%ME!%MA!%ME!$M=!%M9!&-=\"%]=!$]=\"%]5!#=)!'])+#]%#" + "&M!%(]%!)\\Y!&LQ!%LM\"%\\Q\"$%\"'.%&'N-('>1''.1!" + "%^)!)^9&&>9\"\">=!'>=!'>E!&.E!#^5\"&^Q#\">Y!'.Y%#NM!->Y*'^Y\"#NY!&.U!" + "$_%!&?!!%/5!&?1!#O)!&?)!&.Y!&/)&'_-(&?-!)/1!(?1$&_5\")/1!(/=\"(O5*" + "&O%\"&?A+%/1'%/5!&?9!&?5!)?5(&O)\"&?5!&?A!&?5!&?9!&?9!#O)!&?)!)/-!" + "&?)!)/)''/!$&?-!'NY!(_%!&?!!)/!-'>Q!$^Y&&.M!&?!!&.U!).A#'NM'(NI!" + "&.A!&.I!%N=$+>9((N5!'.A%&.5!%.-\"'.1%%^-!&>%#&=Y#%^%!*^!''-]!%]I!" + "%]Q!'>%'&-Q\"$MM!%]M!&M5%$=9!%]I!&-9\"&-E\"'=5(&-)#&-A\"%M5!&]5!%]-\"" + "&-%#']%&%%&$^1!$N%!%^1!\">5!" + "\"N)\"&.5!&>9\"&.A!&.I!$^E!&.Q!&.Q!&.I!'NY!$^U!&^U$(^U!(^Y!(_)!&.]!" + "#NU!&N]\"&.]!&O1!%/5!&?-!*/!!&?=!%?1\"%/1!'O9&%_9*&?1!*?9!&?9!%/-!" + "&O1!%/=!)O9\"'/-$&O5!'_5'&_9\"&?E!&_M\"#OA!&_5#&?-!,_5&&?!!'O1!)_A*" + "&?5!(_-+'O)!&?)!%O)#'?-%&?!!%_!$\">]!&?)!&.Y!#NU!'>U!&.M!'>I&&.M!" + "&.I!'.E+&.A!&.A!&.9!&.A!$N1!#N=!'.1!%^-!'^))'.)!\"-Q!&>%#%]]!&.!!" + "$MU!\".%!'-A\"%]Q!%-M#']=%'-E''=A(%M=!&-9\"$]1\"%M5!(])/+M%3%M%!%]!\"" + ")=='%]!\"\",M!%\\E##\\U#$\\E#%U!#NU!(>]$$_%!'?!%'.]/#O%!" + "&?-!&?)!&O)!#O1!\"?9!&?=!&O1(&?1!'?=%&_5\"&O=')/E!&?5!&?5!(/M!&?=!" + "%/=!&?A!'?=%&O=!'O=&&?=!&?9!)/A,&?=!)?=(%/9!&?9!&_9)(OA+'/1$&?)!" + "&?1!&?=!)/-!#O-!(?))%/-!$/%-&?%!&.U!#O)!#O!!(^]!&.I!'.Q*(.Q$&.U!" + "&.I!&.I!&>E!'.-%&.=!&.9!(N9!%^-!'NA!$>5)*N)%%]Y!'.-!(>%!)M]!%^!!" + "'MY#$]]&%]U!&=Q#%]M!$=E$\"-I!#=A!%]A!%M=!+M=!%]I!(-1+'-)\"'])+'--'" + "%]-!%M!&\"<]\"',Q#$\\I#'<=!$\\I#%LQ!\",I!%LI\"%\\A#%L=\"$,=!&<1!%L5'&LA\"" + "%,!!%\\)##<1\"#+Y!&+]!'+Y!&L!'%[E!$[E!%+]%%;E\"%[E$'KE($[=!$[5!&[M-" + "#[1!%;5\"%+%\"$;5\"%[%%%;!$#[%!#[!!$:Q$#JI!\"JM##ZA\"%ZI*\"ZE!%*=&$JE(" + "\"Z9!$J9!$J5!#J%!$*!##J1!%I]\"#J!!%:%(#)M#%9]%#9Q!$9M%#YM##IE\"#I=!" + "%I)(\"Y1\"%I5*%)-%&9A*$Y=#\"II!%IA##9A!#II!#YI#%9U%$)Y##IY!$:-#$IU\"" + "$:5$#J-!$J1%#Z)\"#J-!#J%!\"Z9!#Z=\"\"ZA!%ZQ&%*Q'$ZM\"$:I$'ZU\"!:A\"#[!!" + "\"Z]!#[!!#[%!#[%!![9!$+=!$+5!%[9!&+M%%+A%&;A&![I!$[I!'+M!$K]#';U+" + "%KM#&+]!&\\%#$,%!%<9!$<)\"',5-%\\9#%LM\"'<5*&LA\"%\\A##,5!$LA\"$LA\"&\\Q&" + "%)'%^%!%^!!%^1!\">-!(>%!\".1!" + "&^9$&.I!&NE#%^I%'>E&&.M!&>M!$^Q!%>]\"%>U((.Y)'O!!&.U!&.]!&?)!&?-!" + "&?-!#O)!&?)!$_!!)/%!)/E!&?5!%/9!#O=!&?9!&?E!&?=!&_E\"&?=!%/E!&_M(" + "&_A\"&OE!'_A!'/U#&?5!'?E$(O9$)_A#&?9!&?A!&_A\"&?=!)?-.&?9!&?=!&?5!" + "&_%#'?5%&?1!(/1)&?1!'O)!&?)!&O%\"$.Y##/1$&.]!'>E!$^Y!&.U!)NU/\">]!" + "*.M!&.Q!&.I!&^I$&.M!(.A*(^-.&.A!'N5'&.=!&>%(&.-!\".%!%^!!&-]\")]](" + "$MY!']Y%&-U\"'-U!']M*%]I!&-I\"%ME!%ME!$]-\"%M=!#=5!%]5\"'M-.%]1\"&M%!" + "%]!\"'-!'%L]!%M%!'M!*$A!'.)&&.5!$^9!&.9!" + "&.9!(^A!)^E!&.I!&.U!&.A!&^U#'.Y$#^I\"&?!!'NY!'.]%%/-!&?)!'O%''O)!" + "'O-!(_)!&?-!)?1))?5!'_9!&?E!)?I!&?=!#O1!&/E%'/A##OA!)?E'*OA!*_U(" + "&OI')_A*'_E!)/9!#OA!(/A!+_E!'_I!)/A!*O=!'_A!&_=\"%/=!&?=!&?-!'/9$" + "#O9!'?5*%?5\",_1&&_1)'>Y&'/-$&O-!&.Y!&?)!$_%!'>]&$^M!$^]!&.U!+.Q," + "&.U!(NI!)^I&&.Y!&.E!(.A)&.9!&.9!'>1&'N%\"%^1!$N)!%N-%'.%!\".1!'.!!" + "&=M$%^-!&]Q%'-]!%]U!#=E!(-M%&=E#$ME!)MA-(=I,%M9!'=9('=1-$=-!']5!" + "%-=#%M)!'-!(%<]!&LY&$-$&N=#'N5').5/*^A%(>5+" + "(^A-(^E-$>1*&.=!&^M$#^E\"&.Q!(NU&(N]+&NY'\"NU!*_!#&.]!&?-!&_)#&?-!" + "(_1,&O1!&?-!&?=!&?=!&O9!&?=+%?A!%/=!&?E!'_A!*_Y!'_A!*O=!*_E(&OI!" + "&_I\"+_=!'?I$&?E!%/]!&OI!'_I!&OU!)/E!&?A!*OE!'_E!-?I!#O=!'_A!'_A!" + "#O=!&O-\"&OQ!&/Q$)/5!&?=!&?)!&?E!%/)!%/%!$_!!&.]!&.]!&?%!(/)('>U!" + "(^Q!'_!(*>U\"&.M!&>E!)^E!(>A&'.5&'>=&'.I*(N5,&.5!%^%!$>)*%^)!'^%)" + "\".!!'.!!%^!!\"-U!&]M!%]Q!&=Q(#=I!$=9!%MA!$M=!$]9\"'-9\"%]M!$]1\"']-!" + "%M%!'M)$*-!!$L]\"&,Y(%-%$%\\U\"%\\Y\"%LM\"&!!&N5#%^-!%^)!#N=!$^E!&.A!&.I&" + "(NE&'^A('NM''^Y('^U(&.Q!(NA,'N]!&?-!'O!!&?1!&?-!&?1!&N]\"&_%#)/=!" + "&?5!!O9#$_%!&?9!%/9!)/5!&?=!%/Q!*OA!*/E%*/E+*OM!,_E+#OE!&OI!%O=#" + "&OM!'_Q!&OM!'_M'(_E+(/Q!&_=\"'OM%\"?E!'/M#&?E!'_I!)/9!)/E!'_I!'_I&" + "&_I\")/=,(?9)&_9\"\"OE!'_5'&O)!(/=(&?-!'_!!)O%#$_%!$_!&&N]\"&>]!&.U!" + "'NY!&.Q!&.M!$>Q$&.M!(NM!%^1!%^-!%^%!&N9#&>-\"'N1('^-#%^5&).-$%^!!" + "'-U!&]]%$MY!'=Y((=Y!%]U!!-I!%]I!!-E!'=U\"&]=!!]A$']5!%M5!'-%#\"--!" + "(])&&-%$%M!!&\\]&&-!($!%$MQ!&MY$%]U!$MU!&-Q'-N%.&M]$'.-!$N1!&>5\")^9'&.9!)>5%&.M!" + "&.E!(.M)&.M!&.Q!&.U!&.U!$^M!(NI!'N]'(?!)&?%!&?%!'?)%&?-!'/-$+O1'" + "(?5#&?5!&?A!'O5!&?=!'/E#+OI%+_E!&_E(%/I!&OM!&OQ!&OI!&O]!)?M!&OQ!" + "&OI!%/E!&OU!!/Q!*OM''_U!&OU!&OQ!&OM!)OM\")OM((_I+&OI!'_E!'_A!\"?5!" + "*?E&&?9!&OM!&?=!'?9%!/5!&?%!&?)!&?-!&?E!#O)!'?-%'_-'&.]!(/)(&.Y!" + "'^U(&.Q!&.Q!'>M!(NE!&.I!&>-\"+NQ-\">I!(^='(.=$$^A!+>E!(>-&#>)!)>%+" + "#^!\"&-]!&>!\"'MQ#%]Q!&]M!%]M!%ME!)=I!$=9!%ME!&-9#$M=!&M)!%<])&M-!" + "%M)!&]5!',Q#%=%$%\\]\"%\\]\"(-!-'LI+&%!%^)!$^9!$N-!'^9#&.9!$^9!&.=!$^A!&.E!" + "&.M!&.U!$^M!&^Q#&.M!&?1&&.M!&N]\"&?!!&?!!&?)'&?)!'O%!'O-&&?%!,O9%" + "'O)!#O9!(_=%'OA&#OA!'_=!&OM!&?E!%/E!&OI!&OM!'?]$'_M!%_U#&_U\"&OI!" + "#_M!-/Y,&OM!&OY!'/U)&_U\"(OM$%_M#(?Q)&/U$'_Q!&OY!&OI!#_Q!%/=!*_A\"" + "'_E!(/A\"$/Q\"&?=!&OE!&?9!&?9!'?-%%/1!&?5!,?A\"'O)&'O%!$_)!._!1&.Y!" + "#.U)&.Q!$^Q!&.Q!%^M%&.Q!&.A!&^=$&NM\"(N=!%^1!(>5&'.-*$]U''.-!&=]#" + "$N-!%]U!'-Y!%]Y!'-U!%^!!&-U\"%]M!%]I!']E$%]A!&M=$&M9%(]%*$M5!%M-!" + "(M1)%]-!&=-$&\\]!%5!&N)$%^-!%^1!&>1\"&.9!'>9&'>A!&^Q#'>I!" + "%.I!&.M!&.E!+>U!&.E!&.U!(_!&&.U!'_!\"\"N]!$^]!#O%!'O1!&?1!'O1!)/5!" + "&?5!'_E!'_=!)?M!'_E!'_A!)_I*'_Q!&OI!%/E!'/9#+_Q&&?E!\"OM!&OU!)_Q#" + "!/]!&P-!&OY!&P)!(/]!)?I!'_Y!)/M,(/]!&OU!&OU!(_Q$&OY!(_U+'_M!(?=)" + "%/=!-/M&)/=!&OA!%?=!'O=&&OI!'O1!'O%!'/5$(O9*&?1!(/-)&?!!&?%!&.Q!" + "&.Q!'^Y'(NE!$^Q!&.M!%.Q!+^M)&NI#'NA'&.=!'>9!&^9$&^5%(>A+%^-!%^)!" + "$^%!%^!!%]]!&]U*&N)#&-U'%=I$'-U!%M9!*=A&#=A!&]A&(=9,'M5)&M5%'M5)" + "%]%\"%]!\")-1&'-%\"$!!'>9!'>5!'^-#'N1\"'>5+&NE#$^I!&.A!'>A&'^E#" + "&.I!#^E!%>M\"*NY\"(NA,&.U!'O!!$^]!&?%!&?%!'O)!&?9!&?1&'_A''O5!)?9!" + ")/=!'?=$)/A!*OM!&?5!#/I#(OI$)/E!)?M!&OI!$/U(&_U!&OU!'_Y!%_Y#'_U!" + "&OI!+?]*&P!!%/]!%0!!(/]!&O]!&_Y!'/]\"(OY*(/Q')?U!$/U\"#_M!\"_I\")OQ\"" + "'_U!(?E)%/I!'_E!&OM!&?=!+OA7$_Q%*O=!'?-+(?1#&?1!$/1\"&?=!&?%!'O)!" + "(^M-&?!!#NU!&.U!&.]!(>I+'>U!(NI!&>I!&>E\"%^)!&.!!&.I!%^-!%^!!'.)!" + "(>!!'.%!$N1!%]Y!)-]*%]Y!']Q$%]Q!&]M!%]U!%ME!'-=\"%M=!&-5#%-5#&=12" + "(M)$%M)!$M-!(]%!%-!$&-%$%L]!'LQ!%1&'^1)(N5!'>A!&>A\"%.I\"&.I!&.]!" + "(NI!%>I()NQ*(>I%$^Y!(_!,&/!&&.]!)/-(&?)!$_%!'/1$'^]!%/5!'O1!'O9&" + ")_A/)/A!-?1)+/E#&OI!&OM!$/Y!'OU%&_Q\"&P!!\"?U!#_]!'?Y$&OU!(/]!#_]!" + ")/],(_Y$'@!#%`1\"&P)!%0!!&P%!&O]!&OU!'/]/'/Y#&OU!&OY!&OU!'P!%(/]'" + "#_M!%/]!'_E!(/I!'_=!&?=!%/A!&?A!'O1!&?5!&?1!&?A!%/-!&?)!&?%!'>Q&" + "%NM$+N]'(NM!'>A!'>Q!'>M!&.E!&>Q!'>E&+^=+&.=!%N1$%N9$(>-!&N-#$^9!" + "&^)%'>!\"%^!!%]U!$MY!%]U!$MY!%]Q!%]Q!%]I!%ME!%]I!#]E#%M1*%M5!']-*" + "'-9'']-!'])+%M1!'=))'%!%]U!#MM!%]]!&-U!%^%!)N)1(>)!'.%!&.=!&.9!&.=!'>E!&>A!&.Q!$^I!" + "&NA##NY!,.]$&.M!&.U!&.U!&?)!$_%!'O)!&_1\"&?1!'O1!(/9(%?9\")/=!&?=!" + "&OI!'_E!*_E\"%/M!'OI%(_Q$'OM%&_U\")/U,&OU!&OY!&_]!&O]!&OY!)P-!(@!\"" + ",@%!&OQ!(0!!'`!,-`1!(?]\"'_U!'0-\")@!!(O]))OU.&`%'&_Y!'@!$&_U!&/Q%" + "'_Q!&_M\"#_E!%/M!,/E!'_9!&?1!\"?1!%/9!&?9!&_5#)/1!&O)!&?-!$_)!&?%!" + "&O!\"&.Y!*?%!&.Q!&^U$\">Y!$^M!'^Q\"&>M!$^=!&>A!&.9!(NI!$^5!*.-.&.)'" + "%]Y!&^-%%^!!$M]!\".%!%]A!%]U!$MQ!%]M!&]I%%M5!%]I!'==#&-A\"%-=$(-A!" + "'-1'#M-\"$=%!$]%#&,]#%<]!%LQ!%\\Q\"&)!%]Y!'N-(#>)!'>5!$N1!'^-#'N9'&.9!%^1!&.E!#NU!&.M!" + "&NI#%>Q\"#NY!*.U!(^]1!/%!(?!$&?5!&_1\"&?1!&_1\"'_5'&?=!&?-!+_=!(?9)" + "'O-!'_A!*/M$%OE#(OM$(?M\"'_Y!)?Y!(@!\"&OU!-0-#%O]\")@-&(0)!*`)!,@-'" + ")`%)&P%!(0!!'_U!(@%!)P-!(/]!(0%!(OQ#,@!!)@!!&O]!&P1!&O]!%/Y!&OU'" + "%/]!&/Q%&OM!)?M'&OI!,?E/'_E!\"?Q!'_=!&?A!&O1!*O=-%?1\"%?!($_)!(/1)" + "&O!\"&.]!&.]!$^Y!&NU\",NQ!&.]!'N]!'>M!&.E!\">A!&.5!%^-!%^)!&.-!%^)!" + "%>1#$N)!&.%!&.)!'-Y!%]U!)=Y&%^!!&]A!$MI!']9%'-U!$MA!%M=%%M9!&M5%" + "'-9,&-A\"%]-!#=%!&,M#%M!!%<]!&,Y#',Y##LI\"%-!%^)!(>1+*^1%&>5\").93#NA!'^A(&.Y!$^I!)^E!" + "'NQ'%NY$*.Q!$^Y!&.]!(NQ&%?%\",O),'/-$&?!!&_5\"'_E!(?%*)/5!'_5'&?=!" + "&?E!(/9(&OI!)/Q&&OM!&_Y!(/Q-)_Y.)?]!&P!!(0!!,?Y4(09!'_I!(@!\"(09!" + "(0-!(0)!+0-!(@)!-`)!)@!!(0)!(P9\"(0-!)0%%)P)!(@!\"%0!!&OY!&O]!&OY!" + "(_Q+-OY!&OI!$?M#$OE$(/E!*OI!'?=%'_I&%OM\"&O9!#OA!&?1!(/=((/%#'_)!" + "$^Y!&.Q!&?%!$^U!'>U!&.Q!&NQ\"'>M!&.9!&^Q$$^A!&>=\"%.9\"&.5!&>5\"%^1!" + ",.%-&N1##>!!\".!!&-]'&-]!&]U%'-]!&-M\"&=I#'=I('=E\"&]A!%M=!&M9$%M-!" + "&]1!&]1+%M%!%M%!*-%&%M)!)-!,%)!%^%!'N5(%^-!%^-!(>)!&.=!&^9%'^=#&.5!&NM\"&.=!&.U!" + "&.I!+>U!&^Q#&.]!#^]!&_)(&?)!$O1$'O)!&?1!'/=#'O5!(/5((?=#*OA!'_I!" + "(?I#%?I!)?I!'_Q!%/]!'_Q!%@%!(?M\"'P%$(/]!(0)!$0)!(0)!\"@!!)@!!(09!" + "(0-!/?Y)(@A!(0-!(0%!+@-),@-!)01%)@!!)P)!+@-/#`%!*?Y,'_Y!'?U$(_]+" + "&O]!)O].)?Y'\"?Q!&OI!&OI!'_Q!)?Q!&?A!&?=!&?-!&?-!%_5$&?1!&O-\"'_)!" + "&?5&&?!!&.]!&.I!\">]!$^Q!&.Q!&.M!'.=%'>U&&.=!$^=!\"N=\"&.9!%^-!&>5\"" + "&.5!%>-$%^!!$N%!&]]%%]Q!$MY!(=U!!-Q!&]M!%ME!)-=!&]A!&]A&&-E\"$=A$" + "%M1!%M-!%]5\"$<]!$=%!%\\]\"%\\Q\"%LY!&\\]&'LI*%!$%^%!%^-!$N%!'.)!%^-!&.9!$^I!'NE!(>E%'>A&)^I!&.I!" + "&.U!&>I!'^Y'*.Y!&?!!'O!!$_)!&O)!(O5%'/-)*?5,&?9!'_=!*OI!!/A!)/A'" + "(?E#&OI!&OQ!(_9%!/U!%OY('`!&&P!!(0!!(`!$(0!!(@!!(05!(0-!-0)1&01$" + "#`1!\"@1!'01\"(01!(01!(/]!(P)\"*`%!&`-!*0-**P-,'0)\"(_U%(@%!+/]!)@!!" + "&O]!*/U+(/Y'%/U!&OQ!'_]&&?=!'_M!%/I!#_I!&_A\"&?9!&?5!&?1!&?1!#O-!" + "+_)(\"?%&$_!!'N]!&^U#'NU'&>I!&>M!#NI!&.E!$^E!&.A!'.A&)^9!)N1!#N9!" + "%^)!'.-!%^%!&.%!$N!!$M]!$]M\"%]U!'MI)(-E&%M5!%]M!&MA$&-=\"$=9!%]5\"" + ")MA(']1/%M1!%M5!#M%\"&,]#%-!$&L]&$\\Q#$LA\"')\"(^)(%^%%'^-#$^5!%^-!(>1!&.=!)^9''>A!&.I!&.M!%.Q!" + "*^U5'.Y$(^Y!#NY!%/%!)?!#(?-#&?-!%/1!&_1##/5$&?9!&?=!)/A!&?9!&OQ!" + "&?E!&OM!&?9!'/Y\"&OM!&OQ!+0!!*0)0#?]$&P%!'@1#&P-!(09!&`9!(01!)`-(" + "&P1!)@A%'`-%#`5!%`5#&`5!%@%!)@A%+01!(0-!)P-!,@9&+0!!%@1!%@%!(0!!" + "%?]!(0!!*OY&&_U!&P!!&?A!)_I*&?E!'_=!)OA.(_5&&?5!&?%!&O1('_A!&N]\"" + "*/!2\"?=!*>]''O%!&.Y!(/%('^Y\"#NQ!$N=%-.E0#NA!&>=\"(.%*&.A!&.9!'>5!" + "&^!%&N)#%^)!&.5!%]Y!$]Y!&]Y*&-U!(-Q%%]M!%]Q!&=A($MA!(]A/%]='(-9'" + "'-5'$]1\"%M-!%M1!(M%$&-%#&M!%'LY!&,U#%LQ!$5&&N5#&.9&!.=!(NA&)>A$&.E!&.Q!(NM!" + "'>Q!'.U%'^]\"&.U!'O!!(_%&&O-!'_-!&?9!#_9!\"?=!#_-!*_9))?I!)?E')?M'" + "&?E!'/U#&P!!-?E'(/]!\"_]((/]!+@)/)0%%(@)!(09!)@1&+`11&01$)P1!'P5$" + "+P90(05!&`9!'@A)(09!&`5!&`9!%P5!'05\"#`5!,P5!)01%&P-!(0%!)P)!(0%!" + "(0!!(0-&&OU!&OU!&OU!'_I!&_I\"\"?Q!%/U!'_A!#OA!&O=!&O9!%/5!'/1$)_)*" + ")/5!'^]\"#O!!'N]!'.]%'?%&*>E)&.Y!&.I!&NI\"&.=!\"^A#(N=!&.A!&.5!&^9$" + "&.5!&N1#(>)+).-)%^!!%^!!(-M+'=I(#]U#%]M!%=A$)-9+)=M!&-A\"(MI-!==\"" + ")\\]%#=1!%M)!%LY!\"=!\"%,Y,',U#$L]\"%]&'O!'$^]!$_)!&?-!&?5!(/A('?E$&?=!'_=!(?I#&/E%&OI'" + "&OM!+/Y)\"OU''OY%)/Y&&O]!(0%!'P)$(0!!.@A/&P%!*0-#&P-!$`A$&`9!'01\"" + "%@9!&`9!\"P-'&`5!(05!&`5!!0=!(`9#&`9!&`9!&`5!)`5((0-!&P!!(0)!'_U!" + ",/]!&O]!&_]!)?]'%/U!&OQ!'?I$&OI!'_E!'_E!%/9!&?=!&?9!(_)!&?-!&?%!" + "$^]!'/%$%/5!(^]!#NU!(NY&&.]!'O!!\">Q!&.]!&.A!&NA#&N=#&>=')^9!&.5!" + "(.5*%>-(&>-\"&.!!\"-]!(>!,$MY!&MU$%]U!&=M#&-Q\"'MA$$MI!'M=$&-E\"&-9\"" + "%M-!*=1,$]1\"%=)%%]%''=%$$<]!()!%^-!%^)!)>-%&.9!'.M%*.U!%^1!$^E!&.I!&.U!%.Q!" + "'>U!&>A!$?!#$^]&&?%!'?!&%NY#&?-!&?)'&?5!&?5!&?9!&?E!)/E!#`!!!/M!" + "(/Q('?M$&OU!'/Y#(/]!&OU!(0!!(`!$)0%%)_]))P5!(0)!'P1$'01\")P=!&`A!" + "(@=!(@A!+0A')`A!*@A*(PI!&`-!&`=')0=*'@1#(P5\"(@1!&P1!(0)!)@!!(P)\"" + ")`%\"(_Y$%/U!(0!!'_U!&OM!$/U\"&OQ!&?A!'_=!&?A!&?9!'O5!(O5$&?-!&?1!" + "&O-!&?!!&.Y!%>]($_%!&?%!%NQ))>Q#(NM!&.M!$^9!'>I!$^A&(.=$(.9*%^%!" + "%^1!&>%#(^92&>1\"%^%!(>!!(-M0+-U#(>!!%M=!%]M!&=I#%-=#$]=\"$M=!%MA!" + "&-=\"'-A\"&-=#)M!.*-%!'-%\"'-!'\"5\"&.5!&.9!&.I!&.Q!&NI().U\"&>E!(N=!&.Y!" + ")O!*(N]+&^]#&.Y!\"?)!$_!!'O1&&?5!&O)!&?9!'_9!&O=!(OE$)?Q!%/M&&OM!" + "*OQ!&OU!(/Q!%/]!'?]#)/]%(0!!(09!-`9'*@1+(`5#'P1$)P1-%@=!(@=!(@=!" + "&`A!'`I%(@Q!(@E!*PM*)@E%&`A!)`Q!(@A!&`Y!&`=!'PA*(01!)`%)(01!(`=#" + "(0)!'_Y!#_Q!)/Y&#_I!(?]('_Y&&OM!#_M!(?M\"&?A!(_=&#/9)&?9!&?5!&?1&" + "'O-!%/-!&?%!'NY'&NY\"*?!!*>U\"'.U%$^E!&.I!(.E)'>A!&.A!$N1!(>9+(^-#" + "#N!!$N-!'.)!(>!!&^!%$M]!&=I#%]Y!%^!!$=U%%]M!%]I!*]Q!'=E(\"])$$=5!" + "&-9\"%]1!&LY!$M9!'M%%%=%%&=!$%M%!&M!%%]'&?5!(_)!'O)'&?!!%O-#&?9!(?9*%/E&)OE\"'_E!(?I\"'_=!" + "%/U!(`%*%/]!+`)%&P)!(0)!+P96,@)!+0-!(0--'P5$)`9.'05\",P=!(@=!(`I\"" + "+@E')`A!&`Q!+@A!)0I$#0U#&`9!(@E!(@I!+01!&`9!&`A!#`5!+`%2(0-!(/]!" + "(0)!)P%!&P%!(/]!#_]!#`%!$?Q#&OI!&?A!'_E!*?9&(_I%&OA!'O5&*?5!'/1$" + "&?-!).U\"&?%!'/!$#N]!%NY.&.]&$^Q!'>Q&#NI!&.A!'>E!&>A!&^1%&.5!'>9!" + "%^%!%^-!$>)%%.)\").!%'^%*)M]!%]I!%-U#&]M!&]M%']I$&MQ$&]A&*-=%$]9\"" + "%M9+(-%,$]1\"']%!&]-&#\\]#&\\Q\"$\\E#'\\Y+',U#&A!&.E!'>A!&.M&'^U($^A!" + "$^U!&.]!$>]$&.Y!&?=!&?)!&O-!'O9&)/A&'O1!&?E!&?A!+?=+&_I\"&OM!#OE!" + "&P!!%_U)'O]%)P)'#`%!(0%!&P%!+@-\"&P1!#`1!,P5!(`1#(@=!(@A!+@]!(`A#" + "(@E!*PM$)`M!&`E!%@M&(@I!'P9*'0E((@E!*PE+&`9!*@9#%@A!,@-!(P-)(0-!" + "+P)1,@)!(0!!'_]&(/E!&OM!%_U)&_M\"&?A!'_Q&'_E!&_A\"&O=!'O=&#O5!%/5!" + "\"?9!#O!!)_%%*O-!(^U!$_!!&.Q!%>Q($^=!&.E!$^Y!(NE!&N-$&.A!&.I!'.5&" + "$N%!%^)!)>-*)>%0(-U+&N!$%^%!%^!!'=Q\"#]Q##=M!%]I!'=A#&M=%'-5'$=5!" + "%M5+%M1!&=-$$=-!%])\"$=5!'<])&])&%M!!$1\"*^-!$^5!&.I!&.=!&.9!*.I-#^I\"&.M!'>Q!).U\"" + "&.]!'O!')/!-&.Q!'/9##O-!'O-!'O1&&.]!'_9!&?A!&?E!(?M\"&OM!$/Y\"%OQ\"" + "&P-!%/9!%/Y&&_]!*@!$(0-!(0%!)P9!(01!&`9!(09&)`9(+P5*(09!)`I!(@I!" + "&`M!)`E!*0]!'@Y\",@M%(@I!%@M!(@A!#`9!(@Q!+@=/&`M!(`A#&`9!(@1!(0-!" + "*0)))@%&%/]!'_Q!+?Y#)OU!&OU!&OQ!&_M\"&OE!&OE!&?A!)/='$OE$*/1+)/9!" + "&?5!$O1%'/%$)/%!&?!!$^]!&?)!#O!!%.U!&.Q!$^E!).I.$^A!&N1#&N1$%N1$" + "&.%!$^I!&.)!&.9!'.%!'.!%%]Q!$MU!&-U!%]U!'=M\"'-Y!)-9&(-A!'=5##M9\"" + "%])\"&M1%#=-!&]-!%M)!%]%\"%]!\"%M!!&\\Y!#)+(>A%&.5!%.A!'>5!'>9&#NA!*>I\"&.M!$^I!(^U!" + "(_%!&?!!)/!($_%+'O%'&?9!&_1\")/5!'?-%&?1!\"?=!&?9!'_E!'OM%&OM!&OQ!" + ")_Y\"&OY!&_]!&P)!(0!!*_Y!%@)!\"@-!(0-!%@5!&`9!&`I!,0E$)PI&&`A!(@E!" + "(@M!)0I$+0Q,(@]!&`Q!+`Q\"(@]!*@I)(@M!&09#&`M!+PM/(05!(P1)(01!(@-!" + ".P)$'_Y!(/]!&OQ!&OY!(?]/&OQ!&OQ!'_M!)_E/+_E,&?A!&?=!&?5!'O!!&_5#" + ")/-!'/)$(/%((_!!&O%\"&?!!'>Q!&.I!&^M)&.U!'>E&'>M!&.A!&.I!'NA'&>5\"" + "(N1,'.-*(>-!*>%*,.%-%]Q!%^!!'=U\"'-U!(-U*(=Y!'=I()=E1$MA!'-=!&M9$" + "'M5$$]A\"&]1&&M-!&]-!'M%%\"-%!'-%''LY%),Q'#,M!&,I#%\\A#$LA\"&,I$&\\9(" + "%L=\"%\\=#%<5!%,1!$,5!%+Q!%,)!%9!%^)!'-]!%^!!&>1\"&.5!&N9#&>-\"#N=!&.=!%>=#(NQ,'^Q(#NU!" + "$.Y#$^]!&?!!&O)\")O!)(/)(&?-!%/9!&?=!&?9!&?5!$_5*+?5+&OI!*_M(*@!%" + "\"?U!&OY!&P)!&`-!/0!!)P%!(0%!&P-!(/]!(`=#(`9#%@=!(@I!(@E!,@U+&`U!" + "*0U!*`Q+(@Q!)0Y#)`Q!+@I!/`Q!(`E\"(@I!)@E%*PY*(P-\"&`9!%@9!(01!(`-$" + ")?]&(@)!(O]#&P-!&P%!&P%!&O]!&?U%&/E%'_M!'_E!&/A%#O9!*OA!)?=('O1!" + ")_-%%/1!'_1''?!&+O!!(/%\"%^I%\">Q!$^U!'>E!$^I!%.E\"'NA'$^=!&.=!#>1!" + "$^-!&^-%%^-!%^%!#>%!$N!!%]]!(>-!%]U!'-Q&(-M!%=I$'ME$(-=!'-5'$=-%" + "%M-!&=5$%M1!%])\"&M-!&=)$',U##,U!*\\Y*$!*'.-!&^5$(>)!$^1&(.1*'.-!&^5%'>A!&.A!'^E\"&.A!&.Q!'>U!'NU," + "&.Y!&?!!(?!)&?)!%/1'#O)!#_1!\"?-!'/!$&?9!%/=!&?E!%/A!&OI!'OM%)OI)" + "#_U!'O]%)?]!$P%#(/]!(0-!(0)!(05!+01!&`5!,P9!%@5!&`A!(PI!*0I\"(@M!" + ")PQ&(@U!+@Y!+P]!(@]!)PY%-@]\")`M!)`E')`I!&`=!%@A!%@9!#`9!)01$(01!" + "(P)\")P%!(0!!(/]!+@!0&OY!&OU!*OM!#OE!)_Q)&OM!'_=!'/=#'_9!+O1!\"?1!" + "(>]*)?)()_-1'/9$&?%!&_!)&.Y!'?)%&NY\"&.M!)^E!$^I!'^=)(N5!'>=!&.=!" + "%N5%&.5!%^!!%N5%'.%!%^!!%]]!#-Y$)-=!'-M&#]M(&=E$&]E&&M=%'-E'%M9!" + "&M%&&M5*%M%!']-!%M)!%1\"&>!\"%^-!(^M'(.9$'>A!'N='*N5+&.I!'NM''>Q!%^U%" + "+>Y-'O!!&O-\"%_!$(/%#(_!!'/1$(/1\"&?9!$?1#&OI!)_A#'_M!(_I%&OM!&P!!" + "(OY*&P-!%?]'*_]!(0)!%0!!,@)!)@5&%@-!(05!%@=!&`E!(09!(@E!'@I\")`A!" + "(@I!)`U!&`U!*@E)(@M!.@]!*`]+(@M!/P=!&`M!,`A!(@=!)P=!&`5!+05!)P-'" + "(P)\"*P%,*`!-&P!!&O]!&OY!%OU\"&?E!&OM!*OM!(_Q$./A%&OA!&?9!&?9!&?1!" + "&?1!&O)!*O)($_!!)?%.&>]!'NY!&>U'&.Q!&^Q$&.I!(.U##N=!$^=!&.A!(N1'" + "#NA!%^1!%^-!$MY!(=Y!%^!!%]]!%-Y\")=Q!(=M'%ME!)=I!&M=$%MA!&-=#(=9," + "&]5&%]5!+])4*-1%%]-\")=%\"$=!!&\\Y!%!#(=Y!" + "&MU%%]M!\">5!'>)!&^-%%^)!&.9!'.)!&.9!'^=#$^=!'>E&'>I!&.A!'.U*&N]\"" + "%O!)&.]!%O-#+O%!&.Q!'O%!&_5\"&?-!(O5*%/-!&?=!&?9!#OE!&OM!&OM!)?Q'" + ")?Y!&OY!*@)+'?Y$&OY!&OQ!(/]!(P-\"&`5!&`5!%`)#&`A!(@A!(@I!&`E!(@I!" + "(@A!(@Q!*0U!)0M#(@E!)`M!&`Q!%@Q!(@E!)P5')0E$&`=!,@1-&`5!#`!!(@)(" + "(0!!(0%!&OY!(P))%@)!&P!!&OM!&O]!\"_U\"%/A!(/M!&OA!%/=!'_9'*O5-%/1!" + "&?)!(_-&$_%!&?%!&.Y!&>Y!&?%!&?!!$^Q!)>M.#^M\"&.M!&.=!$^=!%N=$&.5!" + "&.9!'^%)(.-%%>1#%^!!)M]!%]Y!$M]!&]]%%]U!%]Y!'-A\"%ME!$ME!#=9!$=1!" + "%,]#&M5*']5!#,]!%M1!&-!$&=%$&,]#$!\"$^)!*>!%%^)!&.=!'.-!'.-!'>E!'>=!%^1!&.=!'^I-'.I%'.Q%#NU!&.U!" + "&^Y#*.]1$_!!&O1!&.Y!(_%'&O-\")/-!&?5!!/5!&?A!'?9*'_E!%/I!&OM!)?Q-" + "'?M*&?E!&/M%%/Q!(0)!(`)$,@-!)P)!'P1$%`1\"&`9!&`I!(@=!(PA!+0I-(@E!" + ")`M!(@M!+@Q'(@Q!(PQ!(@Q!(@M!&`=!)PQ&#`9!$@9\"&`=!(09!%@5!&P1!\"`-\"" + "(0%!(0%!(`%$&OY!&OM!&OU!*/U+&OQ!&O]!&?=!)?E(&?A!&?E!#/9#%O5#&?)!" + "'_-'%/-!&.Y!\"NY!$_!!,/%#%NY#&.U!#^Q!&.I!).A($^E!%.Q!(NA,&N9#'>=!" + "(^!)$N!!%^)!%^1!&-U!%]Y!%^!!%]U!'-Q'(MQ\"%]I!&]Q!%ME!%M=%&]A!*-=/" + "&=5$(M1.%]5\"&=-$%M)!%]%\"%-!$^5!%^%!'>-&$N-!'^5)%^=&'>9!$^E!#^I\"#NM!(NE!+^U4" + "*NI$(.Q#$>Y$&^Q##O!!(_-,&?-!#O-!%/-'&?A!&?=!#OE!'_I!'/I#'OU%%/A!" + "(/M(&OU!&OY!'_U!(0%!(P)\"(@)!-0)2)P9&(01!'`5%(@1'&`9!)P9!(@M!(@=!" + "(@U!)`I!*0M((`M\"*@I#(@E!&`E!)`E'#`M!,0A2+@1)'@5#&`A!)@!!)P1'(0-!" + "'`)&+/U\"&P!!'P-$)?]!*_M4'_M!&OM!'OE&)?M-(_9%&OA!'_9!%/1!&?)!)/A!" + "&?5!&?)!\"?)!#O%!#N]!&?!!&.Y!&^M$&.Q!'>M+&^E$'.E%&.9!'>=!&^9$$^5!" + "%^-!*^)!'>)!\"-]!&^5$'.!!(=]!'-Q&%]M!$MI!&]=!#=I!)-E+#]I\"'=E\"%M=!" + "$=9!(=9\"%]!\"%M%!']-!&M)!&]!\"%M!!'<]$(,Y#$A&&NM\"&NI\"$^Y!$^Q!&.U!" + "$NU%(^Y!'O%'&?!!#O%!&?)!'O5!*O-(+_9!%/1!%/I!#?A%)OA\"&/=%'?M$&_M\"" + "&OU!&_Y!&P1!&`%!(/]!)@)&)P%!)0)%(0)!)P1!&`5!%@I!)`A!)`=')@5%(@E!" + "(@E!(PI!(@U!(@I!(@A'*0=)(01!(@E!'P5$(09!%@A!'09!&P1!(@1((P-\")01$" + "(0-!,@%!)P!'&O]!%OI\"&OU!,OQ*&OM!%/I!)?I'&?=&'_I!*O=3&O=!)/5!&_1#" + "$_)!(/)#%/1!'/!$&.Q!'NY!$^U!'>U!%^Q%&.M!(>M+'.A%&.I!'.9&'>9!$^=!" + "%^-!#N=!%]]!(>)!'-Y!(N!-%]]!%]Y!(=Y,*MQ,&MY$&-I\"$-A$&]I!&]5&%M9!" + "'M5*#]-#&M5$)\\Y!(=5''-)\"&=1.%<]!&\\Y+&LU!(,U(*-!!$\\I#)!\"%^%!%^)!%>-#'>5!&.5!%^-!(NA!'>9!'>I!%.I!&.M!'^U'&.Q!" + "'_!('.]*(^],$^U!(O-*&_=\"&O-\"&?1!#OA!(_1+)/A!&?9!#OA!'_I!&OU!&OY!" + "'_Q!&OM!#_Y!&P%!&OQ!)/Y%(0!!(01!'@1#(01!(P%\"%@-!'0=!%@=!(09!$@E\"" + "&`5!(@E!(@E!*PE+(@A!)`M!(@=!(@A'\"@A!&`=!'@=#+05!)P-!(05!(0-!)@%&" + "&OU!/0!!)0%%%/]!&OU!&OU!(_U%#_]!)?I!)/A!*_5)&_Q\"'_9!&O5!'?5%&/-%" + "'O5!'?)%'O1!&?%!&.M!&.A!&.Q!#^Q!$^M!$^M!#NI!&>M!'>E!&.=!&>=\"(>Q%" + "&.)!%^)!%^%!'.-!%^!!'N%()M]!%]Y!%]Q!&-U!%MA!&]E!']5!%MA!'M-*)==!" + "%]1\"%M-!$]1\"%M%!#,Y!&-%#']-*(,Y,%M!!%\\U#%LM!#1\"'N1()^91&.E!)>E$&.E!&.I!'>9!&.M!&.U!" + "$^E!&.Y!&.]!&?5!(?-)&?-!$_)!%/1!$?1#&?=!$_)!&?E!%_E$+OA%%/Q!'/Q#" + "(_Q%&OQ!'_U&&O]!(/]!(0!!&`)!(@%!)P)!)0-%)P5!&`5!(P5)'/Y\")PA&&`9!" + "&`=!(`A#(@9'#`A!(@=!(@A!(P=\"&`=!(09!#`9!)@9%(05!&`=!(05!(0%!+01!" + "(0%!)@!&&OY!&P-!&OU!(OQ*)?Q!*OM!)/I,'_5!%/9!(/=\"*?9!(/5(%/1!&?1!" + "&?A!#NQ!&.U!'O!'&.U!(.Y)$_!!$^I!%>A#$^I!'>E&&>E!&.A!$^5!&.1!$>-$" + "#>1!'.1!%N)*%^-!#=Y!%]]!$MU!'-U!\"MU''=U'&N-$#=I!)=5\"&-A(%]I!$]A\"" + "&M)!%MA!%MA!%=)$%M)!%]!\"#=)!%<]!%)!'N-\"%^1!$N1!&.9!'>=!&>=\"$^E!&>E\"&.]!&.M!$_!!" + "'>M!$.Y\"&.]!'NY!&?!!&?!!%?5\"#O-!&?=!&?5!$?=#)/=!&?A!'_A!)OI('_I'" + "*OM!%/Q!&?E!&_Y!(/]!%?]!(@!!'_Y!)P)!)0-%+P5*)@1&&P)!*P)2(P9\"*050" + "&`9!(P=\"%@9!&`9!&`A!(`9#&`E!(`5#&`9!!0A!(@-!&P1!)P%!)P-!%@%!(0%!" + "&P!!&O]!&OM!)_Y\")?U!&OU!%/M!#_M!)/E!*OI!'OE&'_=!(O9*%/5!$_)!#_-!" + "%/1!&_%(#O-!#O%!(/!(&^Q#$^Y!+NY'&^U$+NQ(&.=!#NI!&.9!&.=!&^E$&.-!" + "'>1!%^!!'.=&&-]!&.!!$N)!%]Q!'=I(%]Q!%]M!%]M&&]M+$MA!&-E\"$=1!&M9$" + "(-)'%])\"%M-!%M1!$])#&M!&&,]#%])\"'\\Y!%A!#NA!&N5#$^9!&.=!&.E!&>I!$^Q!&^M$\">Q!" + "'_%!'O%!(O!%#^E\"&?!!*?)!&?)!)/%((O)*&?9!&/1%%?1\"&OI!'_E!)/E!(OE$" + "&OM!#_Q!#_Y!&P!!%?U!&O]!)@!!'_Y!)P).&P1!&P1!(0-!)01$(05!'@-#%@=!" + "(09!#`9!&0E#&P1!&`9!(09!)P5!(`5#*`)!(P1\"+01!,`-)*P%%)P)!-`%!+0)(" + "(0%!&P%!(OY*(O]#&OU!'_I'&O5(&?E!'_E!\"?9!'/E)&?=!(?A)&?9!)?5.$_-&" + "#O-!&?!!$_%!&.Y!\"NY\"$.Y\"*>M((.Q)&.I!&NI#&.M!'>E&#NI!)^A!%^1!#>-!" + "\".1!%^)!%N-%'N)#&^%%!]]$%]U!%]Y!&MQ$&=M#)]]\"#=E!%MA!%=A$']=%&-A\"" + "&M-!%M=!%=!*'])!&M%&%M!!&E!&.Q!" + "'>Q&'>U!&?!!&.U!\"?!!)?!\"&?)!&?1!&?1!&?9!&?-!$O)$'_=!'_E!%?A!$/U(" + "&_U!&O]!'_M!&OU!'/Y#'_Q!&O]!'0!\"(/]!(0!!(`-$(01!)/Y&&P%!,@1!(0-!" + "&`9!&`5!(0-'#0-#&P1!(P5)&@1%+P=0(01!)PE&(`-$*`)!*`)!&P%!(@1'*_Y!" + "%/]!&OU!'/]\"&OI!&OQ!\"?U!&?9!)?I!'?I$)/A!'_=!&_A\"\"?5!&^]#&?-!&.Y!" + "(/=.#O%!'O%!&_-#(.Y)&NU\"&.Q!$^M!&>Q!%NI$'>E!&.A!'>9!'^9#)>5%&.9!" + "$^A!$M]!#N)!\".%!'>!\"(M]'%^-!&MU$%^!!']M*%ME!#=E!%MA!&]=!%-=#%M9!" + "&]5!%]1\"%M1!(--+*M%$']!!*-%!(\\Y&%\\Y#'\\Q+%%!%]Y!#=]!$N%!&N1#%^-!&.1!$.9#)N%!&.=!%^=%'>E!$^I!$.U\"$^M!" + "'NU'$^U!'.Y%$^]!'O!!&O%\")/-!&O)\"'O-&#O5!'/!$(O9*$/9\"(O=**O=!)/E!" + "'?I$#_Y!&P!!%/Q!\"_U\"(/U'&`!!(/]!+05!(0%!'@)#)P)!*`%!)P1!(@-!&P1!" + ",@-!(P)#*@1++01!%@1!%`1)(0-!(01!(`-#(P5\"&OY!(01!(`%$(P-\")?U!&OQ!" + "&O]!&O]!&_U!&OQ!%/Q!&OM!)OA)*_M-(OA$&?E!%/9'&O-\"'O5!(O9$#O-!&?)!" + "$_%!&.Y!&?!!)?%('NE!'>A!$^U!&.M!&.E!(.I$'>E!&.Q!&.=!(>A+(>1!&.9!" + "*N-%%^-!&.%!\".-!%^!&%]Y!$MY!(]U#&>!#']E*&-I0%MA!%M-!'M5$&=9$%-9$" + ")]93%M-!%M%!$=%!&,]#%M!!%!!'>%'&.)!'.-!'>)''-]&&.5!&N=#&.=!&.A!%^=&'NI''>M!" + "&.Q!&.I!&?!!&>Y!&?%!)O!$&?%!$_)!%?-\"%/1!&?9!&?5!'_M&(/=(&?A!)/E!" + ",?E\")_U\"*_Y!'OI%&_U!)?U!&?E!'?]#&OY!(0%!&OY!+01!,`)#)`-\"$`-%,@-!" + "&`5!)P)!&`=!+@5('`1,.@-6(@-!,0-&'@)#(0)!*P)%'_U!+O]$(0!!\"?Q!(P!)" + "!/E!'0!\"&OQ!&OU!%/M!%O]\"\"_E\"'OE&'?I$'?=$&?9!%/5!%O5#&O1!'O)&&.]!" + "&?%!(?!$(^]!&_!#%.Y!&.Y!'NQ'&.Y!#NE!&^A$&.A!$^=!(>A+&.9!&.9!#NA!" + "'.)!'.%&$N)!(=],&-Y!'-Y&&-]\"'=U(%]Q!%^!!%]I!&=I$\"]A#'-='%M9!%M-!" + "'=%(&-)#'=5$*-)!%M%!&=!$%,U)&<]$%LM&%\\Q#',M#$LI\"&,I#\"<1\"\"L=#'<=%" + "%<9!&<5!%\\1#%,%!%K]#%,%%%<)!%;]&#,!!%;U\"$+U!\"[I(\";=\"%[A%%[E!\";A\"" + "%KA#$K=$%+1\"&+1*'+-/%[))$[-$#ZY!#J]$&JY!$*U\"#ZU!$*I&$ZA\"$K!$#J9!" + "\"ZA!%Z=#%Z9\"$J5%&:1!%:-(\"J!!#J%!%J-&#J!!%*%$%YY#$)M##YU\"#9A!&9I*" + "#Y-#\"I5!$)='\")%\"#9=!!IA##Y=#\"II$$9I$\"IQ!#)]&#IM%$9]$%:!$$Z-&#J%!" + "#*%\"#J-!%J5\"#J9!#JE!$*=\"#JI!#:M#$JM%\"ZQ!#[!!%:]'#*Y\"$[!)\"Z]!\"ZU!" + "![1!#K5#%K1$&+%'%K9($[=!%;A\"%K=#&[I!';I\"\"KQ#$+M!$+Q!'L!#$;Y\"%+U!" + "'[Q-%<%\"&,%)&L1&&\\1(&<5%#<1!%\\%,&<=!%\\A#%LI\"&,Q#&\\M\"%%%%^%!$N%!%^)!'^-$&N1#&.)!&^5%&^%%&.=!'NM'(>E+'>I!&NI(" + "(^Q!(>I%&.Y!&.Y!(^Y!'_!!&?!!'/))%^Y%'_A!#O1!&?=!&?=&&O=!(?=**/5+" + "(/E!#_M!&OE'&OQ!)?I!&OQ!'OM%&OU!&O]!%?]!)@%&*_Y!%@%!*`%!)P-!(0)!" + "*@1$(/]!\"@9!&P-!*`1&,@)!(0-!&P!!)P%!*`%!&/]$(/]!*@!%&_I\"(/]!#_Y'" + "\"?]!%/U!&OQ!*_Q(&_I\"%/I!'/E*(_A%&?A!&?=!&?9!'O5!&?1!)/-!(?-)\"?)!" + "'/%$*/!!&.U!&>]!&.Q!'NY'&>Q!'.M%&>Y!&.E!#NI!&.9!'>9!&.%!&.=!'>-!" + "%^-!'.%%'.%%$N!!%]Y!%]E!&MU$$MM!(-U*+-I)$MI!%ME!%ME!#=5!%-5$&-1#" + "&-=\"&M5%%=)%#=%!(-)\"%M!!'-!(%\\Q\"#LE\"&LQ&$!!%N%%\".%!&-U!'.!!&^1%&NE#&.9!'.=&&.A!&.E!)^E&(.Q$" + "+>M!'NQ!&.M!&NY\"&?!!#N]!&?!!'/-$(_)!'O-&%O1#+/%%&?5!#O=!$/E\"*OA!" + "'_A!(?U\"&?E!'_E!&OU!&OQ!%/U!#_M!$@!\"'_Y!&O]!\"@%&&`-!&P)&#_]!(0!!" + "(0%!(0%!(0!!&/U$&P1!*0%*(0!!)P%!(01!+/]((0%!&`!!(/]!&OY&%?]!!/]!" + "&OY!$OU$&_M\"&OQ!%/E!)/A!+/A#%O9#&_9)&?5!&?-!&?5!&/-&$_%!&O)(&?%!" + "(/!.&.Q!&.]!&>Y!&.]!&.Q!&.M!).I\"'>I!&.I!&.A!#N=!).=#$N1!#>)!&.=!" + "'>9!%^%!%^%!&]]%%]Q!%]U!#]]\"$MQ!$]E,#=U!&]A!$MQ!%ME!%M5!#-9$%M)!" + "%M1!$]9')M)2&=)$#=)!&<]$%<]!&,I#&!#&N-$%^-%\".%!&.=!&.5!%N=$&^=$&.E!" + "&.Q!&.Q!).]-'^U().Y!(^]!$^]!&?!!&?%!&?-!&_-#&O1!'O%!'_5''O-!%O-#" + "&_A\"*/U+&?E!&OI!'OE&&OQ!(/]!%/]!&_U!&OU!&OY!&OQ!&OY!*0!#)?]!&OY!" + ")`!))@!!)?]!(/]!)P%!%`%#)?]')@!!(_Y$&O]!,P!0*?Y1&_Y!&OY!&_Q!(/Y'" + "&OU!&OI!\"?I!&OQ!'_9''_9!&?E!%/=!&_1\"&_5#+?1%&^]#&?-!&?)!*?1!&?%!" + "'.]%'O%!'NY!*N]\"'.Y%&.M!(^Q!$.M##NE!&.A!'>A!#NE!&.5!&>E\"'^-#%^)!" + "%^1!%.1')M],%]]!#^!\"(=Y!&]M!%]I!%]M!$MI!&]E!)-Q*%M1!%M5!)-5&%]5!" + "#=1!$=-!'-1''])!'-!(%<]!%\\]\"&LU!%%#)^)!%.)\"$^9!%^1!%N5%&>E\"(NA!&.A!&.E!\"^E#" + "'>M!$^M!&.Q!'>M!*NU.\"_)\"*.]!(^U!,/%/'?)%'_-(%/=!&?5!'/9#&?9!&?9!" + "*OA!&?A!%/E!&?A!&OM!)OU.'OE%'?M$#_I!,?Q\"'_U!&P!!\"?Y!\"?Y!*/]#&O]!" + "(O]*(?](&P!!(0%!(0!!'@!#*OM!)P!!&O]!'P%$*OU2&OY!&OY!&OU!'@!##_Q!" + "*OQ&&OI!%OM\")/A!(/E!&_Q!#OA!'O5!'/A#*?)!&?-!&O-\"&>Y!&?%!&_1\"(/!(" + "(_%!%.Q!'NY!&^M$(NQ+(>I*(NM!&NI#)^E!%^1!)N%!%^)!&.5!(>%!&>5''>-'" + ")=Y!'.)!%^!!&.%!'MU#$]M!%]U!%]U!&-I\"%]I!&-E\"'-A!$M=!%MA!&=5$'M=$" + "%]5\"&=-)$<]!%M9!%)!$N-!(>)%%^1!'>5!'>-'&.A!'>I!)^A!$^=!" + "&.Q!&.M!&.M!&?!!&.Q!&?%!&?!!#O!!&?!!'?1*#O-!&?)!#/5$)/5!'?1*&O9'" + "(_M0(/=\"&?A!)?E!)_9*'/I#&OI!&_M\"#_Q!(/]!*_U!'_Y!)?U-&P!!(0-'(/]!" + "'?Q$$?]\"&O]!'P)$(/]!'@!$+OU+&OY!&O]!'OQ%&O]!&OY!'_U!)?I!&OQ!(OM*" + "+/I)+OA+&?=!)?E('_E!%/=!&_=\"%_=$*/5%&?1!'?)%&?-!(O)0'O!!&?)!'.]$" + "&>]!&N]\"&^U#$^M!$^Q!&NE#'O!!*.E2&.Y!'>A!'N=,%^-!&.5!%^1!'.1!).)*" + "%.!\"(^-#']Y$%]]!%^%!'-U!%]Q!&=Q#&]A!'MI))-A+%=A$(==\"$=5!%]-\"%]1\"" + "$=1!&-5#%-)(\"])$&M!%$L]\"%%!(N!()N%!%^)!'N%.(.1*%^1!'>9!(NA!$^I!'>E&%>E#" + "$^I&(.M)&^Y#(NU&(NQ+#>I%*?1!&^]#&?!!&.]!&?1!&N]\"%/=!'?)%&?5!'O)'" + "&?5!*?9')/=!&?A!'_A!'_E!*O],&?=!'_Q!'_I!)/Q,&OI!%?Q!(0-!&OY!'/M#" + "!0!!)?U!,OY*&OU!'_Y!(_Q+(?Q\"$/U!%/U!&OY!&_I\"&OQ!&OQ!$OE$'_I&#_9!" + "%/=!'_I!'_M!-/A'&OA'(/A!&?9!&_5\"&?9!&?1!&?-!&?-!&.]!$_!!&O!\"$^Y!" + "$^]!'?%&&>Q'&^U$'.M%$^M!)>M#(NI!)^E&&.A!&.=!(N9&&.5!&.9!%^)!&N%$" + "&N1#%^!!&-]!&M])%]Y!(>!!+=U*%]I!#]I#%]I!%MA!'-A!&-=#$]9\"$M1!%M)!" + "&M)%$=1!&-%$%-!&N-$'.)!'>9!(^=!$^5!'^A(" + "'>A!&.E!$^Q!%>Y\"(^Q!'>U!&>Y!&.]!'O!!#_!!$_)!#O9!&O)!&?)!)O9#&?1!" + "&?9!&?5!%OM\"'/=#&?E!)/=!'_E!'_A!(O=$*OI!%?M!'?M$%/=!'?Y$&OQ!(/Q(" + "(_U+&OU!&_U\"#OY%&OI'&?A!&_U!#`!&(_Q%&OQ!&OQ!&OM!&OI!'_I!%_I*)/E!" + "&?E!%OA#)?9!&?=!\"?Q!+/5*&?5!#O5!&?1!&?-!(?-/'O)&&?)!&?!!&?!!&.]!" + "'.]$(.U#&.Q!(^Q'&.M!&.I!&NI#&^U)&NI#&.=!$^9!'N9'&.5!%^-!&>-\"$N!!" + "+.)(&>!\"$N%!%]]!%]U!%]U!(-Q%&-Y\"%ME!\"]E#$MA!%]1\"(=9\"'M=$&=5$%]A!" + "'--#%M!!&-%$'<]$$\\U((LY*',Y#%\\Q\"*,U&%LM\"%!!*.!$'.%!&N1$\"^)#)>9/&.9!$^=!&.A!" + "&^=$&^I$%N]#&N=#(^U!$^Y!'>M!&.Y!$^]!$_)!&_)#&O!\"&?)!$/!\"%/-!'_A!" + "(/5)#OA&'_9!'_=!'?=$#OA!(O9$&?=!'_E!*_E)&?9!&OQ!)?M!&?E!*/M+&OM'" + "%/I!'_Q!%/U!'OQ%'0%)&OQ!&_U\"(/E(&OU!&OY!&OM!\"_I\"(?I#'/E#'_E!'_E!" + ")/A&&?A!'?E$&?=!&?9!&?E!&?9!&/A%&?1!%/=!&?)!%/1!&>Q!$_!!&.]!'>M&" + "&^Y#&.U!&.Q!'O)!&.E!&.I!'NE!$^M!'^9)'^1#&.9!%.5\"%^1!(N-!%^)!%]]!" + ")=Q,%^!!&=]#&]Q!%]Q!\"=Q!%]M!(]I$(M9)$MA!%M=!&]=!%M9!%M)!&=1$%M)!" + "(-)\"'=-)\"M-\"),]\"%L]&#,Q!$I/%^9&&.A!" + "&.A!&.E!*^Q+&.U!&.Q!&.M!$^=!&.Y!'.U%&.]!&_!#$_%!(?%*'O-!&?-''?%&" + "+?5+(O5*&?A!&?5!(/%(&?A!&?=!'?E$'_A!&/E%(/I!'_E'&OQ!)OE\"&_9.&OM!" + "&OM!&OI!&OM!%/U!&OQ!%OM)&_U\"%/M!'_I!$?I#&OU!&?E!%?E!&?A!'_E!)OM\"" + "%/=!'_A!%/A&&?1!&?5!'O5!%/-!$_)!&?1!%_-$#O!!'/!$&?!!&?%!&.M!$_%!" + "\"_%#(.M)&.Q!'>M!'^E#'.Q%'>A!&>A\"&NA#&^=$&.A!&.5!(>-&&>)\"'>5!'.A&" + "%^!!%>%#&-Y!&]Y%(=I'%]I!%]I!*MI!%]I!&]E%%]5!%M=!'M5$&-1#%M1!&]5!" + "(=9'%M%&%M1!']!&%L]!%\\U\"%-%&.9!%^-!(N=!" + "&.A!&.Q!&^=$)^Y+&.M!%.E\"&.M!%>A#'.Y%'NY!'N]!'?!%&?%!)?%(&O)!'O-!" + "-_),*/1+&_=\"&?5!$?9#'_=!'_=!'_=!&?=!'OA&%OA#)?E'\"_E\",?E6)?I!)?U!" + "&/I0'_9!&OI!&OM!(/]!&OM!'_M&)/I,'_M!*O=!&OQ!*OE!#O1!&?A!&?A!&?1!" + "'_=!(_5&*?=&&?1!&?-!$/-\"&?-!'?9%&.]!&?%!)O%$#O!!(.U)&.]!&.U!$^U!" + "&.U!#NU!&.Q!&.E!'>9!$^M!(>A+&.=!(>A+&.9!'.E%%^1!$N!!'.)!(>)!%^%!" + "'.!!#-])#>-!&MU%$MQ!&=E$%-]#%]M!']E*(-A!'-='&]9!&=1$&]1!%]5\"$=-!" + "%]%\"(M9.!=5\"%9!%^)!" + "$^5!%.E\"&.A!'>A!(.Q#&^Q$&^U#'.Y%&^U#%NY#&.M!&.]!(>U*'O)&(.])&/)&" + ")O-#'O!!%O1#&?)!'O5!'?1%'_=!)/9!&_5#&?9!&?E!#O-!'_9!'_E!-/A&)/E!" + "'_E!(_U$'_I!'_E!&OM!*OE!(OE$'_=!'O1!+/A0&OI!&O9!&?=!%/-!(_9%&?9!" + "%/1!)_5$+/5$'O)!(?1$)/1-*_1\"'O%'&?!!$_)!*.]2'N]!'>Q&&.Q!(_)!&.Q!" + "&.M!&NQ\"(NI!'NE''>E&&NA#$^=!\"^=#&.9!\"NA\"'.1!'.)!%^1!'-]!$N%!%^%!" + "%]Y!%]U!\">!!%]Q!%]Q!%]Q!$MA!&]E!(-=!&]A%)-5!']9*&=5$%M)!%M!!$])\"" + "%]1\"%\\]\")\\]!',Y#'!\"%^)!%]U!'.)!&^-*'N)\"'.-!&.=!'N5(" + "&.=!'.1%(NA!'N='&>A\"$^M!&.A!&.Q!&.Y!'^U(#NQ!&.]!#^]!'_1('O%!)_)0" + "$_)!&/1%&?-!'O1!&?5!\"?=!&/5*'?=$)?A!&?9!&?=!%/A!&O5!&?=!&?E!'OA&" + "%/M!&_A\"'?Q$&?A!#OA!&?=!%/A!)/A!'?=$\"?=!&?=!(?=)'/E#&O9!&?9!&?5!" + "&?5!%/A!&_1\"&?1!(O-*'?)%'?%%'O%!'_)!(O!+&?!!*N])'.]$$^U!&^U$&.]!" + "'>A!$^Q!&.=!&.E!'>I!'.I%&.9!&.I!$N1!&.1!'N1('>9!$M]!$N%!&>!\"(N!-" + "\"]Y#%]U!&>%#\"-Q!%]M!&-9#&]]%)-A&%MA!%]=!&-9\"&=9$%]5!(-E!&\\Y\"%5!%^)!'.1!&N5(&.9!" + "'>9!(^=!'>=!&.E!&^A$&.E!(NE!&.M!&.U!&.U!$_%!'>M!&?!!(?!$&?!!(_%!" + "&?%!'/)$-/5!%/-!&?-!+?-+'_9!'?-%&?1!&?-!&_9\"'_A!&?5!&?-!!/)!+_=!" + "&_5#'_)((?=*&?=!(OA0'?A%(_=+*_=\"*/A1)/5!&?9!(?9*&?=!&_9\"#O1!'O5!" + "'?)%&?9!'/%$\"?-!&?%!\"?)!(?%)'O%!)?!(&.Y!(_!!&.]!'>A!$^Y!(>U%&.Y!" + "&^U#&.I!&.I!$>M)&.A!(>=&&>9\"'.-!&^1%'.1!'-]&$N1!%N5$(N5!%^!!%^!!" + "$N!!%]]!%]I!%]Y!%]M!'MQ$&=E#&]A!)-A+&MQ$%M9!#MA&&-9\"%M-!\"M!'%])\"" + "%\\Y#$]1\"#=!!&,U#%!\"&>)\"%^!!(>!!&.=!$N-!'>5!%^1!" + "&.M!'>9+&.=!'>=+$^E!%.Q!(^A2&NM\"(NM!&.Q!&.M!%/!!(^]!&.M!(>]*&.Y!" + "&.U!&?9!%/1!)/1!$_)!&?-!#^U!$_)!&_9\"'O1!&?5!)?5.&?-!&?A!#O9!'_E!" + "%/-!#O9!(?9#&?1!'_9!#O9!&_5\"(?A#%O9)'_1''_=!'?%&'_1'%/I!&?1!'/5$" + "&?-!)?-\"(?))'O)!&_%#'?-%)_!0&O%\"'N]!#O!!$_!!&>U!*^U*&?!!&NM#'^M(" + "$^M!'^E(!.E!&.A!$^9!%N5%%^)%$N%!#>!!(>-!$N-!%^%!(.-*(N!!%^%!'-]!" + "%^!!%-U#%]Q!'-Q&&]M!&-I\"%ME!$MA!&-A\"%M9!'-9'#M5\"%M1!'])+%]-\"(--!" + ")=%\"'=!)%<]!$%!%^%!$N%!%^-!(>)!&>1\"" + "'>9!$^5!'^=((^=\"(N=!\">E!&.M!&.I!&.9!&.M!&.M!&>Q!#NU!+.Y1%NY)$^]!" + "$_!!'O)&#O)!\">]!'O1&&?-!#O)!&.Y!)/-!&?=!&?%!'_I!'O1!%/5!(O5$'O1!" + "&?1!'_5!*O5-%/A!&?5!%/5!'O5&%/5!'_9!'O5&%/-!&?1!$_5&&?1!%/9!&?%!" + ")/%(&?1!$_)!&?)!#N]!'/!$&.M!&?!!&.Q!'>]&$^Q!).Y!'>U!(.E$&.A!'>Q!" + "+>=\"&.A!&.=!&.A!'NI'&.9!&^9%&>)('.)!&N9#&.-!%^%!$N%!'>)!\"-]!'MM(" + "'=U\"%]U!%]Q!\"-I!'MM(%]U!%ME!']=*$M=!%]5!$=-!&]9&'-1''M-$%M9!%M!!" + "%M-!']!+%L]!'%%)M]!$M]!&M]$!-]*%^%!&>-\"%.-\"&^5$" + "&N1#&.E!)>9*(>-!&.9!&.I!!>E\"&.=!&>I!'>I!(^Y!&.I!'NY'$^Y!(_!'&.Q!" + "$NU%$_!!&>U!$_!!$_)!%O)#'O-&#O)!&?-!&?-!&?-!&?9!'_1('/-)(_!!&?-!" + "'O1!%/5!'O-&&?-'%/-!'O5&\"O9!'_1!&_1#&?)!)/%(&?1!&O)\"'NY!'_-'&?%!" + "'_1(&?!!&?%!&?)!&O1!'N]!&.]!&.U!(?!)&>U!).Y!(>U*)^I!&NM\"'^U'+NI(" + "$^E!(NA!(N=!&.9!$^9!&.9!&.5!&>1\"%^-!'>)'%]Q!%^1!'M])%^!!%.9\"#>!!" + "'-U!%ME!#]I\"&]M!)M9#'ME.&]A!%M1!\"-1!%M9!%]5\"'-1'%]5!&=)$#=)!&M%!" + "%M%!'-)'(,Y,&,Y#(,Q1#,I%%%\"&.5!#N5!$^E!&.=!!.9!&^A$'>I!&.=!&.M!&.U&&NM\"&.]!&?!!&.Q!&.]!" + "&.U!'>U!\"O%!$_!!$/%\"'O%!&O-\"&?-!\"?)!'_!('O!!'O)!&?1!+?!1&?-!$O5)" + "$_)!)/1!&?A!(?5/'O-!#O5!%/5!*?)!'O)!'>Q!*_-))/5!&?)!'?)%'O)''O%!" + "&?5!(^Q!&.Y!'^Y''>U!&?!!'>Q!,.Y5&.U!%^M**>Q\"&.M!#^M\"&.M!'N='&.I!" + "'.1!&NE##NE!&.9!&.5!$^9!%^1!$N!!$N-!(>!&'.%%$N)!%^!!*>!)'=Y\"%]U!" + "%]M!&-U!&-I\"\"MI+%]Q!%M1%(]9.$-Q$%M9!&]5&\"-)!%]1\"&]-'%9+!.9!&.9!&.E!&NE#+.E,&.E!&.M!&.Q!&>Q!&.Y!" + "&^U$$_!!&?)!&?)!&?-!&.U!$_!!&?!!&.Q!&.M!&^])'O-!&O)!'O9&'O)!'O)!" + "'O)!#NU&&?5!(_)!(?))&?!!&?1!&O1!&?=!&?%!(?-#&?%!&?%!'.]*)?)\"'?!&" + "'.Y$#O%!$_!!&?!!'.U%&.Y!$NI%&.Y!&.Y!$^Y!'>M!'>M!'^I#&>E'(NE&&.E!" + "$^A!'>=!&.E!&>E\"%^%!(>1%'>-&'.-!'>)'(>)&%]U!$.)#%^!!%]Y!'MM$'-]!" + "&-A\"'-I'%]Q!%]I!&=A$(-A!$]='&-9#(-A+)]E#&M%!&=)$%M)!%M%!',],%<]!" + "&M-!(1\"" + "'.-!%^=%&.5!#N5!#>)!%^)!'N1(&.A!&.9!&.M!#NE!&>E\"(^M!&.I!'>U!'.Q%" + "&>I!&.U!).U'(_%!'NY!\">Y!).Y'&?%!&?)!&N]\"&.Y!&O%\"\"?)!+/%+&?%!*O%." + "'O)''O)!\"_1\"+O!!&?)!%/-!&?%!)/-!'O1!&?-!)/%-%?%\"'^Y(%/-!&O)\"(_!!" + "(?!)\"O%!&.Y!'NY!'_!!&.Q!*.Q!&.U!'.E%&>M''NY!'^=('>E!$^E!&.I!%^)!" + "\">=!$^9!'>9!&.5!%^1!&^!%&>-\"(.9%#>!!'.!!+-]\"%]]!%]Y!(=]!'-Y!%ME!" + "%]M!%]Q!(]I)%M=!&]M!']5%&]=!$]9\"']9%%M1!%]1\"&M-%%]!\"%M%!%M!!%<]!" + ")-)0%\\Q\"$A!" + "&.U!&.E!(?!)'>U&\">Q!&.U!'NY!&?%!%.M!*>]'&>Y!&.]!#O!!&?)!%O)#'.]$" + "&?!!'O)''O%!'O!!&_%#)^U,'^]!&?!!&/)&$.Y##NY!&O%\"%O%#\">Q!,.]*\"N]!" + "&?!!'/1$&.]!(_)!$.U\"$^Q!'>U&$^M!&.U!&.E!&^M$#NI!&.9!&.A!&.=!$^=!" + "#N9!$^9!&.5!'.-!*.))%^1!'>9!%^%!$>5$%.!\"$MY!$M]!$M]!%]U!(-Q!&]Q!" + "'-U!%M9!$ME!&=I(%MA!%]1!%]-\"%]1\"#\\](&M%*'--\"%]%\"']%*%]%\"&L]&%M!!" + "%M!!&Y!&.Y!*.Y,&.]!&?!!'O!').].#NU!&.]!" + "#_!!'_!(&?1!(^Y''O%!(_!&&?!!&_!#&N]\"*.],'N]!&.Y!#N]!'.Q%&>Y!'.Y%" + "'>U!'>U!'NQ!&.Q!)>Y)&>A\"&.M!&.I!$^I!&.E!(^E-&.A!&>E!&N5#(>=%'.=%" + "'.%!&.5!$^E!$N1!%^-!%^)!%^%!$N%!$^!!$M]!%]]!']Y)'-U!&]]%%]U!%M5!" + "&-A#%]I!%ME!)]Q-$-=$%M=!'-9'%M5!&-1'&M5%&=9$&=-$(=%(&]!\"%M%&(,Y(" + "(!\"" + "(N),%^%!$N%!$^9!'N-\"$^5!*.=('>5!'.-!&>)\"&.=!&.A!)^Q,(NM!#N=!&.I!" + "#NA!'>=!&.U!&.A!(>M+'>E!(NU+'^U\"&>Q!'>U!(?!$&.Y!'O%!)>Y##NY!\"?-!" + "'O)&&>U!&.Y!$^]!&?%!&?!!#N]!'>]&(^Y!'^Y'&.U!(>U%&.U!'NY-+>M3'>I!" + "%>Y\"&.I&&^Q#\">I!&.Q!&.]!&.I!&.U!'NM!&.M!&.5!&.5!(>M+&.5!'>9!\">5!" + "&.5!&.=!%^-!$^9!'.)!'.)!$N%!%^%!(-Y*'-]!$ME!'-U&&]Y*%]]!']M$%M=!" + "(=I!#]E#'-A!&]I%&MA$&=-$%M5!$=%%%M9!\"--!%!!&.5!$N1!'.9&$^9!&.=!$N)!&.I!&.E!&.=!" + "&.M!&>1\"&>I!&.Q!!.M!'/!$(N=!'>U!&.]!'>Q&'>Q!&>]!#NM!&.Q!&NM#'^Y'" + "&.]!&.]!(^Y!(>Q*(NQ+(^Y!&O)!*NY#'>M!&>M!&.Q!&.M!&^U#*^Y*'>Q&&.A!" + "&.Q!&.Q!\">U!&.I!&^-%'.I%#^E!&.I!'>5!%^1!'.9&'>5!\">E!(>)&&N5#$^5!" + "&N)$&.=!&^-%'>9!&.5!#>%!).)*#>%!%^!!&^%%%]Y!'-U!&-Q\"$MQ!%]Q!%-=$" + "$ME!$M-!)-A&&-=\"%]9!&=A$%M!!)=A0&=-$%!!%^%!#^5\"%^%!\".)!%^%!&^-%'>1'$N1!%N5%&N=#%^-!%^1!(NA!#NA!$^=!" + "&.5!&.A!'>E!&>E!'>I!&.M!&>I!&.M!'>M!(_)!)NQ%&.U!&^Q##NQ!&.U!&.Y!" + "'.Y%'.]$&.I!&.I!&.U!#O%!&.U!&_%#,>I&&.I!&.Q!&.Q!(.Q$&>Q!&.Q!)^Q&" + "#NM!(NI&&.=!(.M)#NI!&^Q#&NA#!N9#)^A!#N9!&>9\"%.9\")^=!'N)('N5(&.1!" + "&N-)&^-%%^)!%^%!%^!!$N!!+>%)&>!#*-Y$&-]\"'.!!\"-Q!%=M$%]M!%ME!']A*" + "&-9#%MA!&-A#%]5\"&]9!(=9'$=1!%]!'$])\"#=%!$<]!$M!\"()!(^-.'>1&%^-!&.9!)^=!&.5!&.5!" + "$^I!$^A!'>A!#^E!&.Q!&.Q!)NU%'>I&$^I!&.M!%NM$%.M'&.M!'>Q!&.E!&.M!" + "'>Q!&^=$&^M)&.E!&>Q!&NQ\"$^Q!#NQ!&.Y!(NI!'>M+*.M!&.M!'NQ'%.Q!$^M!" + "\">E!'>I!(^E-(^I'&.I!'^=)&.A!$^=!&^=*%^-!&.9!&.5!'>5!*^5&$N)!%^-!" + "(.9*&MY$%^1!'N!#(MY(%]U!%]]!$MQ!%]Y!&MY$$MU!&-]!%]M!'-Y!%ME!$ME!" + "%MA!%M=!$M1*)=I!%]5!&])&&=9$']1!%M)!%]-!'=%)%\\U\"%M-!%<=!',I(&LU!" + "&\\Q\"%!!$N%!'.-!&-]!&>!\"%>-#%>)$)>9%%^1!%.5\"#N9!&.=!&>A\"" + "&.9!&.A,&NA#&>A\"'NI'&.9!&>Q!#NE!&NI\"'>I!'>I!#NE!)>I$&.Q!&.M!&>I'" + "&.]!)^I!(.M$(.I)&.M!)>M$&.A!'^Q\"&>Q!&.M!&NI\"&N5#&.I!(.I$&NI\"'.A%" + ").M3&.E!#>A%#NA!&>=\"%^-!*^A&)>9%&.9!'.-!#N1&$N1!&^5$%^)!%^-!\">)!" + "(N)'&.%!%^%!$N!!#=]!%^!!$MU!%]U!)=]%%]Q!%]E!$=9!&-A\"&]I%%MA!%M=!" + "&M9%']I$(-50&]5!'=5($-1$%M-!'-)#$M)!'M%%&M%&%]!\"%<]!%])\"&]5!$LQ\"" + "$L=\"%LQ!&LE&%LE\"%!!$N%!%^%!%^-!(>%!#>!!%^)!&.5!%^)!'>A!%^%!'>A&" + "%.5\"&.=!&.A!(>I+&.=!&.=!'NA\"(NA!#NI!&^I)$^E!&^E$%.E!*>I\"&.Q!&>E\"" + "&.U!&.I!&.I!&.Y!(^U!#>I%&.I!#.M)*NA*&.I!%^1!&.E!&.A!%NE$$^E!'NA\"" + "&>E!*N9+&.=!(>E+%^=&'N='&.5!&>1\"&.=!&.5!$^9!'N1((>-!&.-!(>!,\".)!" + "%N%*&.%!#>-!$M]!%]]!%]]!%]Y!'-U!$MM!%]Q!&]M+$MI!%ME!%]I!%MA!%MA!" + "(=E\"%M9%&M1%'-5'%M-!&]1!%M!!%])''-%''=!$%M%!%!%(N!\"%^)!%^1!(]]-%^!!(>%!%]]!'.1!%^-!&.)!&.5!" + "(.E)&N9#'>9!&.9!&.A!'>A!)N10'.=%&.U!&>E!'^E\"&.I!&>E\"&.M!'^5#&.I!" + "$^=!&.E!&NI#(NE!&.E!(.E*(NM!'N=!&.E!&.M!(^M-'>A!'>E,#NA!(.A$&N=#" + "(N=,(N=!(>=&&.=!(>1!&.5!'>A!&.5!%.1\"&.5!&.-!&.9!%]Y!%^-!%.-\"'.%!" + "(=]!&>!\"'-Y!%]Q!)=Q0(N-'(-M!'=Q\"'-E!&=I$%]E!'MI(%M=!'-9\"\"ME\"$]9\"" + "&-9\"$=5!&M5%$=1!&-%#$M=!'=)(%]!'\"=)!'=!$\"]-$%M%!\"L]#&,]#'LQ&*,U!" + "%A!(^).(N9!&.A!%>%#&.5!'>E&&.9!)>=$%N5%$^5!&.M!" + "%^A*&.A!&.=!&.=!&.A!\">=!&.=!'NA\"'>A!+>A(&^A$$^=!'^=($^E!&.=!%^9+" + "*>=#'.1!(>5+$^5!*.=('.-!%^-!%^1!%.1\"$>!%'>-&\".1!%^%!%^!!%.%\"$M]!" + "(.%%&=]#'.%!'=Y(%]M!&]Q!'-U!%]I!'MI)%]I!&=M$#=M!&-A#%]5!$==%#=A!" + "%M9!&-%$)]1*%]-\"%M5&%M%!(-)\"(=-('-%#&M!&%)!(>%!%^-!(.-*&.-!" + "&.=!*.E'\">5!%^1!&N1#'.1!&.1!%^-!&>9\"&.A!&^=$'>E!&.9!(>A+$^M!(NA!" + "$^5!&.A!'>9!'>9!&.9!%^%!$N9&$^=!'>5!$^=!&.=!&.A!'.=%&.9!&.9!&^I$" + "#N5!&.5!%N1*%^1!$N-!'>)'\".-!&N-#&.E!(>)+&^)%%^%!&N%$%^!!&^!%%]]!" + "'-]&%]Y!&-Y!&-Y!'-U!(-Q!$MM!%]I!#=I!&]M!&M9%&ME$&M9%&]I%'-9'%]=!" + "%]5!$M=!)-1&%M-!&=!$#=!!%M%!%=!%%L]!'<]#$)#$=U%).%$'.-!&>)(" + "%^)!%^)!&.9!$^9!)>9%'.-%'.)%$N5%#>1!(N9!(N5!&.E!&^9$&.=!'NI''>9!" + "'N5()>1*$^=!&>9\"#N5!%N9$&.5!(N9!,>A,'>5!&.9!&.A!(N5!#N5!\"^1#\".1!" + "&>5\"&.A!%^%!%N1$(NA!(^-#$^%!'^)*)N%&#M]!)>%*&.-!\"N!\"(MU-%]]!%]Q!" + "&-Y!%]U!%]U!%]Q!%]Q!$MI!&MU$\"-I!(MQ($MI!$MQ!&]Q%%=A$%]5\"'-9'&M=$" + "$-1$&M-!%]5\"&-%$(])!%M)!&-!(&LU!%<]!%%\"&>%\"%^%!%.%\"" + "\".!!%^1!$^9!(N9!'>1'#>)!&N1#'.9&'.1!&N1#*.93%^)!$N1!%^1!'.1*'>5!" + "%^1!&N-$&.5!&>I!#N1!&.5!&^9$&.A!&.5!&.5!(N-'&.5!'>1''.1!).1)'.1!" + "%^-!%^)!%.1\"(N5,&N5))N!!&.5!$N%!%^%!&>%#(]]-'M])%]]!%]]!&-Y!(]Q(" + "&^%%%ME!(]I)$MY!'=]!'MA$%M1!%ME!(-A!%MA!&-9\"&-9\"'M1*%M9!%ME*$M5!" + "%M=!&]-&%<]!%M-!'=%)\"\\E$+-!+'LQ!#=!!%\\]\"&LU!#LQ#'%#&>)\"&^5%%^-!&>-\"%^-!&N-#'^!$(>1!'^-#'.)!\".1!" + "%^1!'NA''^)*'>5!&.5!%^1!&N)#'.1!$N1%%^)!$^5!&.9!\">E!$N-!-N-(&.5!" + "%^1!#^)\"'.)&&N-$'.-%%^)!%^1!(N!'\"-]!!.%!%]Q!&-]!$MY!)MI,$MY!%^!!" + "&-]\"#MA!$MM!%]M!%]M!&-I\"%]M!&=I$$MU!'-A\"'M=)&-9\"%]E!&-1,'=)($=-!" + "'M-$&M!&%M)!%]5\"#=%!%<]!(=%$%M!!%<]!%\\U#&LU!&LM*'<9!%!\"%^!!%.)\"$>-$)>!%%^-!(>!!'.)!#^%\"'.%!%^1!'>=!(^%(%^)!%^-!$^%!" + "(N%,%^%!&>1\"%^1!&N)$&.9!(>-!%^)!$N1!&N)#*^1!).1$%^-!#>-!&.)!(>)%" + "%^%!,>9'(^%#'-Y!).%$$.%#%^!!(>!!&-Y!%]]!(=U!%]Y!&MY$$]U&%^)!'.!&" + "&=I($MI!%]M!$ME!#=U!&]E!%M=!$MA!$-=$']5!%M9!'=Q\"%]5\"%M-!%M1!$]9\"" + "$])\"#=%!%<]!%!!%^)!(^%#'.%!$N)!%^-!%^)!'>-'%^-!&^)%$N-!&.5!" + "#>)!&.)'&.5!%^%!$N!!$N)!%^%!'^-$%^-!$N-!%^-!$N)!&N5(%]]!%]U!%^1!" + "%^)!'.%!'.!&*^!!'>!''.)!%]U!$]Q!&-Y!%M]%*.!)&]Y%'.%&%]Q!'-Q'%]I!" + "\"-I!#=E!%]A!$M=!$ME!%M9!%-A('M1)$-A$']9!*-5&%M5!#=)%\"-1!%--$%]%\"" + "'=)$%]%\"$=-!',]'&LQ&&\\Q&%M-!%\\U#$,M)%LM\"&LQ!%LQ!%,A$%)!$N%!'.%!&>-\"%^%!%^%!%^%!" + "%^1!%^-!&^!%'N='%^%!#^)\"(^))$N%!&N)#'.!!(>)!+>%)'.)%(N5!%-]\"%^-!" + "(N!(&>!#'-]!%]Q!)M]2'.!%%]Q!&MY$(=Y!%=Y)$]M!'=I((-Q!+-M('=M#(-M!" + "%]U!\"MQ\"(]E/%ME!%MA!%MA!%M=!(MA.%M1!&]5!$--$&--#%M)!'=%$%]-''--#" + "%\\Y\"%-5#%M!!%M!!'!'" + "%^1!%]Q!%^%!&MY)%^%!$N%!%^%!%^)!(^!#(.!%%]U!)MU'&.)!(.%%%]Y!%]Y!" + "&=]#(=]!%]]!%]Y!$M]!%]U!$]]!&=U#&]Q!%]Q!%]U!&=M$$MU!%]M!'=A#$MI!" + "\"-Y!$MI!&]M!&]E!$ME!&MA$$=9!&-E\"%M1!'=1#&-5#&=)$*M1'%M)!%]!\"%--$" + "$M!\"'L]!'<]$$,]$%<]!&)!%]U!%]U!%]U!&-Y!&.!'%]]!%]U!$MU!'-Y!(=]!%^!!%]]!$M]!'N)#%>)$" + "'N!)#>!!'^-#'-]!&>!#%^!!%^)!'>!\"&^!%'>!''.!!%]]!%]M!%=]$)-]%#=]!" + "%^!!)]]-%]]!'-Y&(-Q!!-]%&=I#%]Q!%]Q!'=Q(&=I#(-Q!#=I!&=M#']M)&]E!" + "%MA!(-E!&]9!&-9#&]9!%]E!%]1\"&-9#$]1\"%]-!'M-*$MI!%M%!(-)!&M-!%M%!" + "%\\]\"(L]%$-!$$)!%^!!$]]!#=Q!%]]!'-Q!%]Y!$MY!&]Y%'.!!&=Y#" + "'-U!%]M!%]U!%=Y$%]Q!$]Q'%]M!'=Y'&-M,&-M\"%ME!%-I#']A%#=I!$MI/&ME$" + "&MA$#=A!(=5,&=E#'-9'&]E!'-5''-=!!=1\"(M1$&])&%M)!'M%%$=%!%M!!'--#" + "#,]!%!\"']Q$%]I!(-Q!#=Q%" + "$MM!%]Q!$MQ!&MU%&]Q!'-]!#=E!%]M!&]Q!(-Q%$MY!&MI$(=M!%]I!#=]!&]E%" + "%]Q!\"-U!*>!4'=I(&]Q!$MA!%]M!)=A+%]5\"(-E!&=M$&-1#(=9-%-5(%]9!'==(" + "'=5#%]5\"%]1!*-1*%]%\"(]5$$=)!%]-\"#M%\"%M!!%M-!&L]!&LQ&(,],'-)'&LY!" + "'M%$%LE\"&\\Q'& -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif - #ifdef HAVE_XMU # ifndef VMS # include @@ -70,7 +63,7 @@ # endif /* VMS */ #endif -#include +#include #include #include #include diff --git a/hacks/glx/flipscreen3d.c b/hacks/glx/flipscreen3d.c index c2bca276..2134fbcf 100644 --- a/hacks/glx/flipscreen3d.c +++ b/hacks/glx/flipscreen3d.c @@ -28,6 +28,7 @@ #define DEFAULTS "*delay: 20000 \n" \ "*showFPS: False \n" \ "*rotate: True \n" \ + "*wireframe: False \n" \ # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ @@ -108,7 +109,7 @@ int fadetime = 0; /* fade before regrab */ /* draw the texture mapped quad (actually two back to back)*/ -void showscreen(int frozen) +void showscreen(int frozen, int wire) { static GLfloat r = 1, g = 1, b = 1, a = 1; GLfloat qxw, qyh; @@ -159,12 +160,15 @@ void showscreen(int frozen) glColor4f(r, g, b, a); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthMask(GL_FALSE); + if (!wire) + { + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(GL_FALSE); + } - glBegin(GL_QUADS); + glBegin(wire ? GL_LINE_LOOP : GL_QUADS); glNormal3f(0, 0, 1); @@ -275,7 +279,7 @@ void drawgrid(void) glEnd(); } -void display(void) +void display(int wire) { static GLfloat rx=1, ry=1, rz=0; static GLfloat rot = 0; @@ -335,7 +339,7 @@ void display(void) odrot = drot; if (rot > 360 || rot < -360) /* dont overflow rotation! */ rot -= rot; - showscreen(frozen); + showscreen(frozen, wire); glPopMatrix(); glFlush(); } @@ -354,6 +358,10 @@ void reshape_screenflip(ModeInfo *mi, int width, int height) void getSnapshot (ModeInfo *modeinfo) { XImage *ximage; + int status; + + if (MI_IS_WIREFRAME(modeinfo)) + return; ximage = screen_to_ximage (modeinfo->xgwa.screen, modeinfo->window); @@ -361,8 +369,10 @@ void getSnapshot (ModeInfo *modeinfo) tw = modeinfo->xgwa.width; th = modeinfo->xgwa.height; +#if 0 /* jwz: this makes the image start off the bottom right of the screen */ qx += (qw*tw/winw); qy -= (qh*th/winh); +#endif qw *= (GLfloat)tw/winw; qh *= (GLfloat)th/winh; @@ -374,12 +384,24 @@ void getSnapshot (ModeInfo *modeinfo) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - if (gluBuild2DMipmaps(GL_TEXTURE_2D, 3, - ximage->width, ximage->height, - GL_RGBA, GL_UNSIGNED_BYTE, ximage->data)) { - printf("Error!\n"); - exit(1); - } + + clear_gl_error(); + status = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, + ximage->width, ximage->height, + GL_RGBA, GL_UNSIGNED_BYTE, ximage->data); + if (status) + { + const char *s = gluErrorString (status); + fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n", + progname, ximage->width, ximage->height, + (s ? s : "(unknown)")); + fprintf (stderr, "%s: turning on -wireframe.\n", progname); + MI_IS_WIREFRAME(modeinfo) = 1; + clear_gl_error(); + } + check_gl_error("mipmapping"); /* should get a return code instead of a + GL error, but just in case... */ + free(ximage->data); ximage->data = 0; XDestroyImage (ximage); @@ -406,12 +428,16 @@ void init_screenflip(ModeInfo *mi) winh = MI_WIN_HEIGHT(mi); winw = MI_WIN_WIDTH(mi); glClearColor(0.0,0.0,0.0,0.0); - glShadeModel(GL_SMOOTH); - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - glDisable(GL_LIGHTING); + + if (! MI_IS_WIREFRAME(mi)) + { + glShadeModel(GL_SMOOTH); + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glDisable(GL_LIGHTING); + } getSnapshot(mi); } @@ -430,7 +456,7 @@ void draw_screenflip(ModeInfo *mi) if (regrab) getSnapshot(mi); - display(); + display(MI_IS_WIREFRAME(mi)); if(mi->fps_p) do_fps(mi); glFinish(); diff --git a/hacks/glx/gflux.c b/hacks/glx/gflux.c index 2e9f0670..172f4061 100644 --- a/hacks/glx/gflux.c +++ b/hacks/glx/gflux.c @@ -76,13 +76,6 @@ #ifdef USE_GL /* whole file */ -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif - #ifdef HAVE_XMU # ifndef VMS # include @@ -428,9 +421,11 @@ void initTexture(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + clear_gl_error(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, gflux->imageWidth, gflux->imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, *(gflux->image)); - + check_gl_error("texture"); } #else /* HAVE_PPM FALSE */ diff --git a/hacks/glx/glforestfire.c b/hacks/glx/glforestfire.c new file mode 100644 index 00000000..dee6a566 --- /dev/null +++ b/hacks/glx/glforestfire.c @@ -0,0 +1,1124 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* fire --- 3D fire or rain landscape */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)fire.c 5.02 2001/09/26 xlockmore"; +#endif + +/* Copyright (c) E. Lassauge, 2001. */ + +/* + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * The original code for this mode was written by David Bucciarelli + * (tech.hmw@plus.it) and could be found in the demo package + * of Mesa (Mesa-3.2/3Dfx/demos/). This mode is the result of the merge of + * two of the David's demos (fire and rain). + * + * Eric Lassauge (October-10-2000) + * http://lassauge.free.fr/linux.html + * + * REVISION HISTORY: + * + * E.Lassauge - 26-Sep-2001: + * - add wander option and code + * - cleanups for xscreensaver + * + * E.Lassauge - 09-Mar-2001: + * - get rid of my framerate options to use showfps + * + * E.Lassauge - 12-Jan-2001: + * - add rain particules, selected if count=0 (no fire means rain !) + * + * E.Lassauge - 28-Nov-2000: + * - modified release part to add freeing of GL objects + * + * E.Lassauge - 14-Nov-2000: + * - use new common xpm_to_ximage function + * + * E.Lassauge - 25-Oct-2000: + * - add the trees (with a new resource '-trees') + * - corrected handling of color (textured vs untextured) + * - corrected handling of endiannes for the xpm files + * - inverted ground pixmap file + * - use malloc-ed tree array + * + * TSchmidt - 23-Oct-2000: + * - added size option like used in sproingies mode + * + * E.Lassauge - 13-Oct-2000: + * - when trackmouse and window is iconified (login screen): stop tracking + * - add pure GLX handling of framerate display (erased GLUT stuff) + * - made count a per screen variable and update it only if framemode + * - changes for no_texture an wireframe modes + * - change no_texture color for the ground + * - add freeing of texture image + * - misc comments and little tweakings + * + * TODO: + * - perhaps use a user supplied xpm for ground image (or a whatever image + * file using ImageMagick ?) + * - random number of trees ? change trees at change_fire ? + * - fix wireframe mode: it's too CPU intensive. + * - look how we can get the Wheel events (Button4&5). + */ + + +#ifdef STANDALONE /* xscreensaver mode */ +#define PROGCLASS "Fire" +#define HACK_INIT init_fire +#define HACK_DRAW draw_fire +#define HACK_RESHAPE reshape_fire +#define fire_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 800 \n" \ + "*size: 0 \n" \ + "*trees: 5 \n" \ + "*showFPS: False \n" \ + "*trackmouse: False \n" \ + "*wander: True \n" \ + "*wireframe: False \n" \ + "*fog: False \n" \ + "*shadows: True \n" \ + "*texture: True \n" + +#define MODE_fire +#include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ +#include "visgl.h" +#endif /* !STANDALONE */ + +#ifdef MODE_fire + +#define MINSIZE 32 + +#include +#include +#include + +#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined( HAVE_XPM ) +/* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */ +#include "xpm-ximage.h" +#define I_HAVE_XPM + +#ifdef STANDALONE +#include "../images/ground.xpm" +#include "../images/tree.xpm" +#else /* !STANDALONE */ +#include "pixmaps/ground.xpm" +#include "pixmaps/tree.xpm" +#endif /* !STANDALONE */ +#endif /* HAVE_XPM */ + +/* vector utility macros */ +#define vinit(a,i,j,k) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ +} + +#define vinit4(a,i,j,k,w) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ + (a)[3]=w;\ +} + +#define vadds(a,dt,b) {\ + (a)[0]+=(dt)*(b)[0];\ + (a)[1]+=(dt)*(b)[1];\ + (a)[2]+=(dt)*(b)[2];\ +} + +#define vequ(a,b) {\ + (a)[0]=(b)[0];\ + (a)[1]=(b)[1];\ + (a)[2]=(b)[2];\ +} + +#define vinter(a,dt,b,c) {\ + (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\ + (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\ + (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\ +} + +#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) + +#define vclamp(v) {\ + (v)[0]=clamp((v)[0]);\ + (v)[1]=clamp((v)[1]);\ + (v)[2]=clamp((v)[2]);\ +} + +/* Manage option vars */ +#define DEF_TEXTURE "True" +#define DEF_FOG "False" +#define DEF_SHADOWS "True" +#define DEF_FRAMERATE "False" +#define DEF_TRACKMOUSE "False" +#define DEF_WANDER "True" +#define DEF_TREES "5" +#define MAX_TREES 20 +static Bool do_texture; +static Bool do_fog; +static Bool do_shadows; +static Bool do_trackmouse; +static Bool do_wander; +static int num_trees; +static int frame = 0; +static XFontStruct *mode_font = None; + +static XrmOptionDescRec opts[] = { + {(char *) "-texture", (char *) ".fire.texture", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+texture", (char *) ".fire.texture", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-fog", (char *) ".fire.fog", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+fog", (char *) ".fire.fog", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-shadows", (char *) ".fire.shadows", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+shadows", (char *) ".fire.shadows", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-trackmouse", (char *) ".fire.trackmouse", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+trackmouse", (char *) ".fire.trackmouse", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-wander", (char *) ".fire.wander", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+wander", (char *) ".fire.wander", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-trees", (char *) ".fire.trees", XrmoptionSepArg, (caddr_t) NULL}, + +}; + +static argtype vars[] = { + {(caddr_t *) & do_texture, (char *) "texture", (char *) "Texture", (char *) DEF_TEXTURE, t_Bool}, + {(caddr_t *) & do_fog, (char *) "fog", (char *) "Fog", (char *) DEF_FOG, t_Bool}, + {(caddr_t *) & do_shadows, (char *) "shadows", (char *) "Shadows", (char *) DEF_SHADOWS, t_Bool}, + {(caddr_t *) & do_trackmouse, (char *) "trackmouse", (char *) "TrackMouse", (char *) DEF_TRACKMOUSE, t_Bool}, + {(caddr_t *) & do_wander, (char *) "wander", (char *) "Wander", (char *) DEF_WANDER, t_Bool}, + {(caddr_t *) & num_trees, (char *) "trees", (char *) "Trees", (char *) DEF_TREES, t_Int}, +}; + +static OptionStruct desc[] = { + {(char *) "-/+texture", (char *) "turn on/off texturing"}, + {(char *) "-/+fog", (char *) "turn on/off fog"}, + {(char *) "-/+shadows", (char *) "turn on/off shadows"}, + {(char *) "-/+trackmouse", (char *) "turn on/off the tracking of the mouse"}, + {(char *) "-/+wander", (char *) "turn on/off wandering"}, + {(char *) "-trees num", (char *) "number of trees (0 disables)"}, +}; + +ModeSpecOpt fire_opts = + { sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc }; + +#ifdef USE_MODULES +ModStruct fire_description = + { "fire", "init_fire", "draw_fire", "release_fire", + "draw_fire", "change_fire", (char *) NULL, &fire_opts, + 10000, 800, 1, 400, 64, 1.0, "", + "Shows a 3D fire-like image", 0, NULL +}; +#endif /* USE_MODULES */ + +/* misc defines */ +#define TREEINR 2.5 /* tree min distance */ +#define TREEOUTR 8.0 /* tree max distance */ +#define FRAME 50 /* frame count interval */ +#define DIMP 20.0 /* dimension of ground */ +#define DIMTP 16.0 /* dimension of ground texture */ + +#define RIDCOL 0.4 /* factor for color blending */ + +#define AGRAV -9.8 /* gravity */ + +#define NUMPART 7500 /* rain particles */ + +/* fire particle struct */ +typedef struct { + int age; + float p[3][3]; + float v[3]; + float c[3][4]; +} part; + +/* rain particle struct */ +typedef struct { + float age; + float acc[3]; + float vel[3]; + float pos[3]; + float partLength; + float oldpos[3]; +} rain; + +/* colors */ +static float black[3] = { 0.0, 0.0, 0.0 }; /* shadow color */ +static float partcol1[3] = { 1.0, 0.2, 0.0 }; /* initial color: red-ish */ +static float partcol2[3] = { 1.0, 1.0, 0.0 }; /* blending color: yellow-ish */ +static float fogcolor[4] = { 0.9, 0.9, 1.0, 1.0 }; + +/* ground */ +static float q[4][3] = { + {-DIMP, 0.0, -DIMP}, + {DIMP, 0.0, -DIMP}, + {DIMP, 0.0, DIMP}, + {-DIMP, 0.0, DIMP} +}; + +/* ground texture */ +static float qt[4][2] = { + {-DIMTP, -DIMTP}, + {DIMTP, -DIMTP}, + {DIMTP, DIMTP}, + {-DIMTP, DIMTP} +}; + +/* default values for observer */ +static const float DEF_OBS[3] = { 2.0f, 1.0f, 0.0f }; +#define DEV_V 0.0 +#define DEF_ALPHA -90.0 +#define DEF_BETA 90.0 + +/* tree struct */ +typedef struct { + float x,y,z; +} treestruct; + +/* the mode struct, contains all per screen variables */ +typedef struct { + GLint WIDTH, HEIGHT; /* display dimensions */ + GLXContext *glx_context; + + int np; /* number of fire particles : set it through 'count' resource */ + float eject_r; /* emission radius */ + float dt, maxage, eject_vy, eject_vl; + float ridtri; /* fire particle size */ + Bool shadows; /* misc booleans: set them through specific resources */ + Bool fog; + + part *p; /* fire particles array */ + rain *r; /* rain particles array */ + + XImage *gtexture; /* ground texture image bits */ + XImage *ttexture; /* tree texture image bits */ + GLuint groundid; /* ground texture id: GL world */ + GLuint treeid; /* tree texture id: GL world */ + GLuint fontbase; /* fontbase id: GL world */ + + int num_trees; /* number of trees: set it through 'trees' resource */ + treestruct *treepos; /* trees positions: float treepos[num_trees][3] */ + + float min[3]; /* raining area */ + float max[3]; + + float obs[3]; /* observer coordinates */ + float dir[3]; /* view direction */ + float v; /* observer velocity */ + float alpha; /* observer angles */ + float beta; +} firestruct; + +/* array of firestruct indexed by screen number */ +static firestruct *fire = (firestruct *) NULL; + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * Misc funcs. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +/* utility function for the rain particles */ +static float gettimerain(void) +{ +#if 0 + /* Oh yeah, *that's* portable! WTF. */ + + static clock_t told=0; + clock_t tnew,ris; + + tnew=clock(); + + ris=tnew-told; + + told=tnew; + + return (ris/(float)CLOCKS_PER_SEC); +#else + return 0; +#endif +} + +/* my RAND */ +static float vrnd(void) +{ + return ((float) LRAND() / (float) MAXRAND); +} + +/* initialise new fire particle */ +static void setnewpart(firestruct * fs, part * p) +{ + float a, vi[3], *c; + + p->age = 0; + + a = vrnd() * M_PI * 2.0; + + vinit(vi, sin(a) * fs->eject_r * vrnd(), 0.15, cos(a) * fs->eject_r * vrnd()); + vinit(p->p[0], vi[0] + vrnd() * fs->ridtri, vi[1] + vrnd() * fs->ridtri, vi[2] + vrnd() * fs->ridtri); + vinit(p->p[1], vi[0] + vrnd() * fs->ridtri, vi[1] + vrnd() * fs->ridtri, vi[2] + vrnd() * fs->ridtri); + vinit(p->p[2], vi[0] + vrnd() * fs->ridtri, vi[1] + vrnd() * fs->ridtri, vi[2] + vrnd() * fs->ridtri); + + vinit(p->v, vi[0] * fs->eject_vl / (fs->eject_r / 2), + vrnd() * fs->eject_vy + fs->eject_vy / 2, + vi[2] * fs->eject_vl / (fs->eject_r / 2)); + + c = partcol1; + + vinit4(p->c[0], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); + vinit4(p->c[1], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); + vinit4(p->c[2], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); +} + +/* initialise new rain particle */ +static void setnewrain(firestruct * fs, rain * r) +{ + r->age=0.0f; + + vinit(r->acc,0.0f,-0.98f,0.0f); + vinit(r->vel,0.0f,0.0f,0.0f); + + r->partLength=0.2f; + + vinit(r->oldpos,fs->min[0]+(fs->max[0]-fs->min[0])*vrnd(), + fs->max[1]+0.2f*fs->max[1]*vrnd(), + fs->min[2]+(fs->max[2]-fs->min[2])*vrnd()); + vequ(r->pos,r->oldpos); + vadds(r->oldpos,-(r->partLength),r->vel); + + r->pos[1]=(fs->max[1]-fs->min[1])*vrnd()+fs->min[1]; + r->oldpos[1]=r->pos[1]-r->partLength*r->vel[1]; +} + +/* set fire particle values */ +static void setpart(firestruct * fs, part * p) +{ + float fact; + + if (p->p[0][1] < 0.1) { + setnewpart(fs, p); + return; + } + + p->v[1] += AGRAV * fs->dt; + + vadds(p->p[0], fs->dt, p->v); + vadds(p->p[1], fs->dt, p->v); + vadds(p->p[2], fs->dt, p->v); + + p->age++; + + if ((p->age) > fs->maxage) { + vequ(p->c[0], partcol2); + vequ(p->c[1], partcol2); + vequ(p->c[2], partcol2); + } else { + fact = 1.0 / fs->maxage; + vadds(p->c[0], fact, partcol2); + vclamp(p->c[0]); + p->c[0][3] = fact * (fs->maxage - p->age); + + vadds(p->c[1], fact, partcol2); + vclamp(p->c[1]); + p->c[1][3] = fact * (fs->maxage - p->age); + + vadds(p->c[2], fact, partcol2); + vclamp(p->c[2]); + p->c[2][3] = fact * (fs->maxage - p->age); + } +} + +/* set rain particle values */ +static void setpartrain(firestruct * fs, rain * r, float dt) +{ + r->age += dt; + + vadds(r->vel,dt,r->acc); + vadds(r->pos,dt,r->vel); + + if(r->pos[0]min[0]) + r->pos[0]=fs->max[0]-(fs->min[0]-r->pos[0]); + if(r->pos[2]min[2]) + r->pos[2]=fs->max[2]-(fs->min[2]-r->pos[2]); + + if(r->pos[0]>fs->max[0]) + r->pos[0]=fs->min[0]+(r->pos[0]-fs->max[0]); + if(r->pos[2]>fs->max[2]) + r->pos[2]=fs->min[2]+(r->pos[2]-fs->max[2]); + + vequ(r->oldpos,r->pos); + vadds(r->oldpos,-(r->partLength),r->vel); + if(r->pos[1]min[1]) + setnewrain(fs, r); +} + +/* draw a tree */ +static void drawtree(float x, float y, float z) +{ + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); + glVertex3f(x-1.5,y+0.0,z); + + glTexCoord2f(1.0,0.0); + glVertex3f(x+1.5,y+0.0,z); + + glTexCoord2f(1.0,1.0); + glVertex3f(x+1.5,y+3.0,z); + + glTexCoord2f(0.0,1.0); + glVertex3f(x-1.5,y+3.0,z); + + + glTexCoord2f(0.0,0.0); + glVertex3f(x,y+0.0,z-1.5); + + glTexCoord2f(1.0,0.0); + glVertex3f(x,y+0.0,z+1.5); + + glTexCoord2f(1.0,1.0); + glVertex3f(x,y+3.0,z+1.5); + + glTexCoord2f(0.0,1.0); + glVertex3f(x,y+3.0,z-1.5); + + glEnd(); + +} + +/* calculate observer position : modified only if trackmouse is used */ +static void calcposobs(firestruct * fs) +{ + fs->dir[0] = sin(fs->alpha * M_PI / 180.0); + fs->dir[2] = + cos(fs->alpha * M_PI / 180.0) * sin(fs->beta * M_PI / 180.0); + fs->dir[1] = cos(fs->beta * M_PI / 180.0); + + fs->obs[0] += fs->v * fs->dir[0]; + fs->obs[1] += fs->v * fs->dir[1]; + fs->obs[2] += fs->v * fs->dir[2]; + + if (!fs->np) + { + vinit(fs->min,fs->obs[0]-7.0f,-0.2f,fs->obs[2]-7.0f); + vinit(fs->max,fs->obs[0]+7.0f,8.0f,fs->obs[2]+7.0f); + } +} + +/* track the mouse in a joystick manner : not perfect but it works */ +static void trackmouse(ModeInfo * mi) +{ + firestruct *fs = &fire[MI_SCREEN(mi)]; + /* we keep static values (not per screen) for the mouse stuff: in general you have only one mouse :-> */ + static int max[2] = { 0, 0 }; + static int min[2] = { 0x7fffffff, 0x7fffffff }, center[2]; + Window r, c; + int rx, ry, cx, cy; + unsigned int m; + + (void) XQueryPointer(MI_DISPLAY(mi), MI_WINDOW(mi), + &r, &c, &rx, &ry, &cx, &cy, &m); + + if (max[0] < cx) + max[0] = cx; + if (min[0] > cx) + min[0] = cx; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < cy) + max[1] = cy; + if (min[1] > cy) + min[1] = cy; + center[1] = (max[1] + min[1]) / 2; + + if (fabs(center[0] - (float) cx) > 0.1 * (max[0] - min[0])) + fs->alpha += 2.5 * (center[0] - (float) cx) / (max[0] - min[0]); + if (fabs(center[1] - (float) cy) > 0.1 * (max[1] - min[1])) + fs->beta += 2.5 * (center[1] - (float) cy) / (max[1] - min[1]); + + /* oops: can't get those buttons */ + if (m & Button4Mask) + fs->v += 0.01; + if (m & Button5Mask) + fs->v -= 0.01; + +} + +/* initialise textures */ +static void inittextures(ModeInfo * mi) +{ + firestruct *fs = &fire[MI_SCREEN(mi)]; + +#if defined( I_HAVE_XPM ) + if (do_texture) { + + glGenTextures(1, &fs->groundid); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, fs->groundid); +#endif /* HAVE_GLBINDTEXTURE */ + + if ((fs->gtexture = xpm_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), + MI_COLORMAP(mi), ground)) == None) { + (void) fprintf(stderr, "Error reading the ground texture.\n"); + glDeleteTextures(1, &fs->groundid); + do_texture = False; + fs->groundid = 0; + fs->treeid = 0; + return; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + fs->gtexture->width, fs->gtexture->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, fs->gtexture->data); + check_gl_error("texture"); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + if (fs->num_trees) + { + glGenTextures(1, &fs->treeid); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D,fs->treeid); +#endif /* HAVE_GLBINDTEXTURE */ + if ((fs->ttexture = xpm_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), + MI_COLORMAP(mi), tree)) == None) { + (void)fprintf(stderr,"Error reading tree texture.\n"); + glDeleteTextures(1, &fs->treeid); + fs->treeid = 0; + fs->num_trees = 0; + return; + } + + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + fs->ttexture->width, fs->ttexture->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, fs->ttexture->data); + check_gl_error("texture"); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + } + } + else + { + fs->groundid = 0; /* default textures */ + fs->treeid = 0; + } +#else /* !I_HAVE_XPM */ + do_texture = False; + fs->groundid = 0; /* default textures */ + fs->treeid = 0; +#endif /* !I_HAVE_XPM */ +} + +/* init tree array and positions */ +static Bool inittree(ModeInfo * mi) +{ + firestruct *fs = &fire[MI_SCREEN(mi)]; + int i; + float dist; + + /* allocate treepos array */ + if ((fs->treepos = (treestruct *) malloc(fs->num_trees * + sizeof(treestruct))) == NULL) { + return False; + } + /* initialise positions */ + for(i=0;inum_trees;i++) + do { + fs->treepos[i].x =vrnd()*TREEOUTR*2.0-TREEOUTR; + fs->treepos[i].y =0.0; + fs->treepos[i].z =vrnd()*TREEOUTR*2.0-TREEOUTR; + dist=sqrt(fs->treepos[i].x *fs->treepos[i].x +fs->treepos[i].z *fs->treepos[i].z ); + } while((distTREEOUTR)); + return True; +} + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * GL funcs. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +#ifndef STANDALONE +static void Reshape(ModeInfo * mi) +#else +void reshape_fire(ModeInfo * mi, int width, int height) +#endif +{ + + firestruct *fs = &fire[MI_SCREEN(mi)]; + int size = MI_SIZE(mi); + + /* Viewport is specified size if size >= MINSIZE && size < screensize */ + if (size <= 1) { + fs->WIDTH = MI_WIDTH(mi); + fs->HEIGHT = MI_HEIGHT(mi); + } else if (size < MINSIZE) { + fs->WIDTH = MINSIZE; + fs->HEIGHT = MINSIZE; + } else { + fs->WIDTH = (size > MI_WIDTH(mi)) ? MI_WIDTH(mi) : size; + fs->HEIGHT = (size > MI_HEIGHT(mi)) ? MI_HEIGHT(mi) : size; + } + glViewport((MI_WIDTH(mi) - fs->WIDTH) / 2, (MI_HEIGHT(mi) - fs->HEIGHT) / 2, fs->WIDTH, fs->HEIGHT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(70.0, fs->WIDTH / (float) fs->HEIGHT, 0.1, 30.0); + + glMatrixMode(GL_MODELVIEW); + +} + +static void DrawFire(ModeInfo * mi) +{ + int j; + firestruct *fs = &fire[MI_SCREEN(mi)]; + Bool wire = MI_IS_WIREFRAME(mi); + + if (do_trackmouse && !MI_IS_ICONIC(mi)) + trackmouse(mi); + + if (do_wander) + { + GLfloat x, y, z; + +# define SINOID(SCALE,SIZE) \ + ((((1 + sin((frame * (SCALE)) / 2 * M_PI)) / 2.0) * (SIZE)) - (SIZE)/2) + + x = SINOID(0.031, 0.85); + y = SINOID(0.017, 0.25); + z = SINOID(0.023, 0.85); + frame++; + fs->obs[0] = x + DEF_OBS[0]; + fs->obs[1] = y + DEF_OBS[1]; + fs->obs[2] = z + DEF_OBS[2]; + fs->dir[1] = y; + fs->dir[2] = z; + } + + glEnable(GL_DEPTH_TEST); + + if (fs->fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glDepthMask(GL_TRUE); + glClearColor(0.5, 0.5, 0.8, 1.0); /* sky in the distance */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + calcposobs(fs); + gluLookAt(fs->obs[0], fs->obs[1], fs->obs[2], + fs->obs[0] + fs->dir[0], fs->obs[1] + fs->dir[1], + fs->obs[2] + fs->dir[2], 0.0, 1.0, 0.0); + + + glEnable(GL_TEXTURE_2D); + + /* draw ground using the computed texture */ + if (do_texture) { + glColor4f(1.0,1.0,1.0,1.0); /* white to get texture in it's true color */ +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, fs->groundid); +#endif /* HAVE_GLBINDTEXTURE */ + } + else + glColor4f(0.54, 0.27, 0.07, 1.0); /* untextured ground color */ + glBegin(GL_QUADS); + glTexCoord2fv(qt[0]); + glVertex3fv(q[0]); + glTexCoord2fv(qt[1]); + glVertex3fv(q[1]); + glTexCoord2fv(qt[2]); + glVertex3fv(q[2]); + glTexCoord2fv(qt[3]); + glVertex3fv(q[3]); + glEnd(); + + glAlphaFunc(GL_GEQUAL, 0.9); + if (fs->num_trees) + { + /* here do_texture IS True - and color used is white */ + glEnable(GL_ALPHA_TEST); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D,fs->treeid); +#endif /* HAVE_GLBINDTEXTURE */ + for(j=0;jnum_trees;j++) + drawtree(fs->treepos[j].x ,fs->treepos[j].y ,fs->treepos[j].z ); + glDisable(GL_ALPHA_TEST); + } + glDisable(GL_TEXTURE_2D); + glDepthMask(GL_FALSE); + + if (fs->shadows) { + /* draw shadows with black color */ + glBegin(wire ? GL_LINE_STRIP : GL_TRIANGLES); + for (j = 0; j < fs->np; j++) { + glColor4f(black[0], black[1], black[2], fs->p[j].c[0][3]); + glVertex3f(fs->p[j].p[0][0], 0.1, fs->p[j].p[0][2]); + + glColor4f(black[0], black[1], black[2], fs->p[j].c[1][3]); + glVertex3f(fs->p[j].p[1][0], 0.1, fs->p[j].p[1][2]); + + glColor4f(black[0], black[1], black[2], fs->p[j].c[2][3]); + glVertex3f(fs->p[j].p[2][0], 0.1, fs->p[j].p[2][2]); + } + glEnd(); + } + + glBegin(wire ? GL_LINE_STRIP : GL_TRIANGLES); + for (j = 0; j < fs->np; j++) { + /* draw particles: colors are computed in setpart */ + glColor4fv(fs->p[j].c[0]); + glVertex3fv(fs->p[j].p[0]); + + glColor4fv(fs->p[j].c[1]); + glVertex3fv(fs->p[j].p[1]); + + glColor4fv(fs->p[j].c[2]); + glVertex3fv(fs->p[j].p[2]); + + setpart(fs, &fs->p[j]); + } + glEnd(); + + /* draw rain particles if no fire particles */ + if (!fs->np) + { + float timeused = gettimerain(); + glDisable(GL_TEXTURE_2D); + glShadeModel(GL_SMOOTH); + glBegin(GL_LINES); + for (j = 0; j < NUMPART; j++) { + glColor4f(0.7f,0.95f,1.0f,0.0f); + glVertex3fv(fs->r[j].oldpos); + glColor4f(0.3f,0.7f,1.0f,1.0f); + glVertex3fv(fs->r[j].pos); + setpartrain(fs, &fs->r[j],timeused); + } + glEnd(); + glShadeModel(GL_FLAT); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + + /* manage framerate display */ + if (MI_IS_FPS(mi)) do_fps (mi); + glPopMatrix(); +} + + +static Bool Init(ModeInfo * mi) +{ + int i; + firestruct *fs = &fire[MI_SCREEN(mi)]; + + /* default settings */ + fs->eject_r = 0.1 + NRAND(10) * 0.03; + fs->dt = 0.015; + fs->eject_vy = 4; + fs->eject_vl = 1; + fs->ridtri = 0.1 + NRAND(10) * 0.005; + fs->maxage = 1.0 / fs->dt; + vinit(fs->obs, DEF_OBS[0], DEF_OBS[1], DEF_OBS[2]); + fs->v = 0.0; + fs->alpha = DEF_ALPHA; + fs->beta = DEF_BETA; + + /* initialise texture stuff */ + if (do_texture) + inittextures(mi); + else + { + fs->ttexture = (XImage*) NULL; + fs->gtexture = (XImage*) NULL; + } + + if (MI_IS_DEBUG(mi)) { + (void) fprintf(stderr, + "%s:\n\tnum_part=%d\n\ttrees=%d\n\tfog=%s\n\tshadows=%s\n\teject_r=%.3f\n\tridtri=%.3f\n", + MI_NAME(mi), + fs->np, + fs->num_trees, + fs->fog ? "on" : "off", + fs->shadows ? "on" : "off", + fs->eject_r, fs->ridtri); + } + + glShadeModel(GL_FLAT); + glEnable(GL_DEPTH_TEST); + + /* makes particles blend with background */ + if (!MI_IS_WIREFRAME(mi)||(!fs->np)) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + /* fog stuff */ + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP); + glFogfv(GL_FOG_COLOR, fogcolor); + glFogf(GL_FOG_DENSITY, 0.03); + glHint(GL_FOG_HINT, GL_NICEST); + + /* initialise particles and trees */ + for (i = 0; i < fs->np; i++) { + setnewpart(fs, &(fs->p[i])); + } + + if (fs->num_trees) + if (!inittree(mi)) { + return False; + } + + /* if no fire particles then initialise rain particles */ + if (!fs->np) + { + vinit(fs->min,-7.0f,-0.2f,-7.0f); + vinit(fs->max,7.0f,8.0f,7.0f); + for (i = 0; i < NUMPART; i++) { + setnewrain(fs, &(fs->r[i])); + } + } + + return True; +} + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * Xlock hooks. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + + +static void +free_fire(firestruct *fs) +{ + if (mode_font != None && fs->fontbase != None) { + glDeleteLists(fs->fontbase, mode_font->max_char_or_byte2 - + mode_font->min_char_or_byte2 + 1); + fs->fontbase = None; + } + + if (fs->p != NULL) { + (void) free((void *) fs->p); + fs->p = (part *) NULL; + } + if (fs->r != NULL) { + (void) free((void *) fs->r); + fs->r = (rain *) NULL; + } + if (fs->treepos != NULL) { + (void) free((void *) fs->treepos); + fs->treepos = (treestruct *) NULL; + } + if (fs->ttexture != None) { + glDeleteTextures(1, &fs->treeid); + XDestroyImage(fs->ttexture); + fs->ttexture = None; + } + if (fs->gtexture != None) { + glDeleteTextures(1, &fs->groundid); + XDestroyImage(fs->gtexture); + fs->gtexture = None; + } +} + +/* + *----------------------------------------------------------------------------- + * Initialize fire. Called each time the window changes. + *----------------------------------------------------------------------------- + */ + +void +init_fire(ModeInfo * mi) +{ + firestruct *fs; + + /* allocate the main fire table if needed */ + if (fire == NULL) { + if ((fire = (firestruct *) calloc(MI_NUM_SCREENS(mi), + sizeof(firestruct))) == NULL) + return; + } + + /* initialise the per screen fire structure */ + fs = &fire[MI_SCREEN(mi)]; + fs->np = MI_COUNT(mi); + fs->fog = do_fog; + fs->shadows = do_shadows; + /* initialise fire particles if any */ + if ((fs->np)&&(fs->p == NULL)) { + if ((fs->p = (part *) calloc(fs->np, sizeof(part))) == NULL) { + free_fire(fs); + return; + } + } + else if (fs->r == NULL) { + /* initialise rain particles if no fire particles */ + if ((fs->r = (rain *) calloc(NUMPART, sizeof(part))) == NULL) { + free_fire(fs); + return; + } + } + + /* check tree number */ + if (do_texture) + fs->num_trees = (num_treesnum_trees = 0; + + /* check wander/trackmouse */ + if (do_trackmouse && do_wander) do_wander = 0; + + /* xlock GL stuff */ + if ((fs->glx_context = init_GL(mi)) != NULL) { + +#ifndef STANDALONE + Reshape(mi); /* xlock mode */ +#else + reshape_fire(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ +#endif + glDrawBuffer(GL_BACK); + if (!Init(mi)) { + free_fire(fs); + return; + } + } else { + MI_CLEARWINDOW(mi); + } +} + +/* + *----------------------------------------------------------------------------- + * Called by the mainline code periodically to update the display. + *----------------------------------------------------------------------------- + */ +void draw_fire(ModeInfo * mi) +{ + firestruct *fs = &fire[MI_SCREEN(mi)]; + + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + + MI_IS_DRAWN(mi) = True; + + if (!fs->glx_context) + return; + + glXMakeCurrent(display, window, *(fs->glx_context)); + DrawFire(mi); +#ifndef STANDALONE + Reshape(mi); /* xlock mode */ +#else + reshape_fire(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ +#endif + + glFinish(); + glXSwapBuffers(display, window); +} + + +/* + *----------------------------------------------------------------------------- + * The display is being taken away from us. Free up malloc'ed + * memory and X resources that we've alloc'ed. Only called + * once, we must zap everything for every screen. + *----------------------------------------------------------------------------- + */ + +void release_fire(ModeInfo * mi) +{ + if (fire != NULL) { + int screen; + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_fire(&fire[screen]); + (void) free((void *) fire); + fire = (firestruct *) NULL; + } + if (mode_font != None) + { + /* only free-ed when there are no more screens used */ + XFreeFont(MI_DISPLAY(mi), mode_font); + mode_font = None; + } + FreeAllGL(mi); +} + +void change_fire(ModeInfo * mi) +{ + firestruct *fs = &fire[MI_SCREEN(mi)]; + + if (!fs->glx_context) + return; + + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(fs->glx_context)); + + /* if available, randomly change some values */ + if (do_fog) + fs->fog = LRAND() & 1; + if (do_shadows) + fs->shadows = LRAND() & 1; + /* reset observer position */ + frame = 0; + vinit(fs->obs, DEF_OBS[0], DEF_OBS[1], DEF_OBS[2]); + fs->v = 0.0; + /* particle randomisation */ + fs->eject_r = 0.1 + NRAND(10) * 0.03; + fs->ridtri = 0.1 + NRAND(10) * 0.005; + + if (MI_IS_DEBUG(mi)) { + (void) fprintf(stderr, + "%s:\n\tnum_part=%d\n\ttrees=%d\n\tfog=%s\n\tshadows=%s\n\teject_r=%.3f\n\tridtri=%.3f\n", + MI_NAME(mi), + fs->np, + fs->num_trees, + fs->fog ? "on" : "off", + fs->shadows ? "on" : "off", + fs->eject_r, fs->ridtri); + } +} +#endif /* MODE_fire */ diff --git a/hacks/glx/glforestfire.man b/hacks/glx/glforestfire.man new file mode 100644 index 00000000..82620f9b --- /dev/null +++ b/hacks/glx/glforestfire.man @@ -0,0 +1,132 @@ +.de EX \"Begin example +.ne 5 +.if n .sp 1 +.if t .sp .5 +.nf +.in +.5i +.. +.de EE +.fi +.in -.5i +.if n .sp 1 +.if t .sp .5 +.. +.TH XScreenSaver 1 "03-Oct-01" "X Version 11" +.SH NAME +glforestfire - draws a GL animation of sprinkling fire-like 3D triangles +.SH SYNOPSIS +.B glforestfire +[\-display \fIhost:display.screen\fP] [\-window] [\-root] +[\-visual \fIvisual\fP] [\-delay \fImicroseconds\fP] +[\-count \fInumber_of_particles\fP] +[\-trees \fInumber_of_trees\fP] +[\-size \fIviewport_size\fP] +[\-texture] [\-no-texture] +[\-shadows] [\-no-shadows] +[\-fog] [\-no-fog] +[\-wireframe] [\-no-wireframe] +[\-wander] [\-no-wander] +[\-trackmouse] [\-no-trackmouse] +[\-fps] [\-no-fps] +.SH DESCRIPTION +The \fIglforestfire\fP program draws an animation of sprinkling fire-like 3D triangles in +a landscape filled with trees. +.SH OPTIONS +.I glforestfire +accepts the following options: +.TP 8 +.B \-window +Draw on a newly-created window. This is the default. +.TP 8 +.B \-root +Draw on the root window. +.TP 8 +.B \-install +Install a private colormap for the window. +.TP 8 +.B \-visual \fIvisual\fP\fP +Specify which visual to use. Legal values are the name of a visual class, +or the id number (decimal or hex) of a specific visual. +.TP 8 +.B \-fps +Display a running tally of how many frames per second are being rendered. +In conjunction with \fB\-delay 0\fP, this can be a useful benchmark of +your GL performance. +.TP 8 +.B \-trees \fInumber_of_trees\fP\fP +Specify how much trees are drawn in the landscape. +.TP 8 +.B \-count \fInumber_of_particles\fP\fP +Specify how much fire particles are drawn. A very special case is 0 +wich means that you get +.B rain +! +.TP 8 +.B \-size \fIviewport_size\fP\fP +Viewport of GL scene is specified size if greater than 32 and less than screensize. Default value is 0, meaning full screensize. +.TP 8 +.B \-texture +Show a textured ground and the trees. This is the default. +.TP 8 +.B \-no\-texture +Disables texturing the landscape. This implies that no trees are drawn. +.TP 8 +.B \-shadows +Show a shadow for each particle on the ground. This is the default. +.TP 8 +.B \-no\-shadows +Disables the drawing of the shadows. +.TP 8 +.B \-fog +Show a fog in the distance. +.TP 8 +.B \-no\-fog +Disables the fog. This is the default. +.TP 8 +.B \-wander +Move the observer around the landscape. This is the default. +.TP 8 +.B \-no\-wander +Keep the fire centered on the screen. +.TP 8 +.B \-trackmouse +Let the mouse be a joystick to change the view of the landscape. +This implies +.I \-no\-wander. +.TP 8 +.B \-no\-trackmouse +Disables mouse tracking. This is the default. +.TP 8 +.B \-wire +Draw a wireframe rendition of the fire: this will consist only of +single-pixel lines for the triangles. +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH SEE ALSO +.BR X (1), +.BR xscreensaver (1) +.SH COPYRIGHT +Copyright \(co 2001 by Eric Lassauge. +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. No representations are made about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +The original code for this hack was written by David Bucciarelli +(tech.hmw@plus.it) and could be found in the demo package +of Mesa (Mesa-3.2/3Dfx/demos/). This hack is the result of the merge of +two of the David's demos (fire and rain). + +.SH AUTHOR +David Bucciarelli +Eric Lassauge diff --git a/hacks/glx/glplanet.c b/hacks/glx/glplanet.c index 047abbf6..0685386f 100644 --- a/hacks/glx/glplanet.c +++ b/hacks/glx/glplanet.c @@ -14,6 +14,8 @@ * other special, indirect and consequential damages. * * Revision History: + * + * 16-Jan-02: jwz@jwz.org gdk_pixbuf support. * 21-Mar-01: jwz@jwz.org Broke sphere routine out into its own file. * * 9-Oct-98: dek@cgl.ucsf.edu Added stars. @@ -28,18 +30,8 @@ * BUGS: * -bounce is broken * - * For even more spectacular results, grab the images from the "SSysten" - * package (http://www.msu.edu/user/kamelkev/) and do this: - * - * cd ssystem-1.4/hires/ - * foreach f ( *.jpg ) - * djpeg $f | ppmquant 254 | ppmtoxpm > /tmp/$f:r.xpm - * end - * - * cd /tmp - * foreach f ( *.xpm ) - * glplanet -image $f - * end + * For even more spectacular results, grab the images from the "SSystem" + * package (http://www.msu.edu/user/kamelkev/) and use its JPEGs! */ @@ -78,13 +70,6 @@ #include "sphere.h" -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif - #ifdef HAVE_XMU # ifndef VMS # include @@ -257,88 +242,25 @@ setup_file_texture (ModeInfo *mi, char *filename) { Display *dpy = mi->dpy; Visual *visual = mi->xgwa.visual; + Colormap cmap = mi->xgwa.colormap; + XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename); -#ifdef HAVE_XPM - { - char **xpm_data = 0; - int result = XpmReadFileToData (filename, &xpm_data); - switch (result) { - case XpmSuccess: - { - XImage *image = xpm_to_ximage (dpy, visual, cmap, xpm_data); - - clear_gl_error(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - image->width, image->height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image->data); - check_gl_error("texture"); - - /* setup parameters for texturing */ - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - return; - } - break; - - case XpmOpenFailed: - fprintf (stderr, "%s: file %s doesn't exist.\n", progname, filename); - exit (-1); - break; - - case XpmFileInvalid: - /* Fall through and try it as an XBM. */ - break; - - case XpmNoMemory: - fprintf (stderr, "%s: XPM: out of memory\n", progname); - exit (-1); - break; - - default: - fprintf (stderr, "%s: XPM: unknown error code %d\n", progname, result); - exit (-1); - break; - } - } -#endif /* HAVE_XPM */ + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + image->width, image->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image->data); + check_gl_error("texture"); -#ifdef HAVE_XMU - { - planetstruct *gp = &planets[MI_SCREEN(mi)]; - unsigned int width = 0; - unsigned int height = 0; - unsigned char *data = 0; - int xhot, yhot; - int status = XmuReadBitmapDataFromFile (filename, &width, &height, &data, - &xhot, &yhot); - if (status != Success) - { -# ifdef HAVE_XPM - fprintf (stderr, "%s: not an XPM file: %s\n", progname, filename); -# endif - fprintf (stderr, "%s: not an XBM file: %s\n", progname, filename); - exit (1); - } + /* setup parameters for texturing */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width); - setup_xbm_texture ((char *) data, width, height, &gp->fg, &gp->bg); - } -#else /* !XMU */ - -# ifdef HAVE_XPM - fprintf (stderr, "%s: not an XPM file: %s\n", progname, filename); -# endif - fprintf (stderr, "%s: your vendor doesn't ship the standard Xmu library.\n", - progname); - fprintf (stderr, "%s: we can't load XBM files without it.\n",progname); - exit (1); -#endif /* !XMU */ + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } diff --git a/hacks/glx/glsnake.c b/hacks/glx/glsnake.c new file mode 100644 index 00000000..d54082b1 --- /dev/null +++ b/hacks/glx/glsnake.c @@ -0,0 +1,1051 @@ +/* glsnake, Copyright (c) 2001,2002 + * Jamie Wilkinson, Andrew Bennetts, Peter Aylett + * jaq@spacepants.org, andrew@puzzling.org, peter@ylett.com + * + * ported to xscreensaver 15th Jan 2002 by Jamie Wilkinson + * http://spacepants.org/src/glsnake/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +extern XtAppContext app; + +#define PROGCLASS "glsnake" +#define HACK_INIT glsnake_init +#define HACK_DRAW glsnake_draw +#define HACK_RESHAPE glsnake_reshape +#define sws_opts xlockmore_opts + +#define DEF_SPEED "0.05" +#define DEF_EXPLODE "0.03" +#define DEF_VELOCITY "1.0" +#define DEF_ACCEL "0.1" +#define DEF_STATICTIME "5000" +#define DEF_YSPIN "0.10" +#define DEF_ZSPIN "0.14" +#define DEF_SCARYCOLOUR "False" +#define DEF_LABELS "True" + +#define DEFAULTS "*delay: 30000 \n" \ + "*count: 30 \n" \ + "*showFPS: False \n" \ + "*wireframe: False \n" \ + "*speed: " DEF_SPEED " \n" \ + "*explode: " DEF_EXPLODE " \n" \ + "*velocity: " DEF_VELOCITY " \n" \ +/* "*accel: " DEF_ACCEL " \n" */ \ + "*statictime: " DEF_STATICTIME " \n" \ + "*yspin: " DEF_YSPIN " \n" \ + "*zspin: " DEF_ZSPIN " \n" \ + "*scarycolour:" DEF_SCARYCOLOUR " \n" \ + "*labels: " DEF_LABELS " \n" \ + "*labelfont: -*-helvetica-medium-r-*-*-*-120-*\n" \ + + + +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + +#include "xlockmore.h" + +#ifdef USE_GL /* whole file */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ZERO 0 +#define LEFT 1 +#define PIN 2 +#define RIGHT 3 + +typedef struct model_s { + char * name; + float node[24]; +} model_t; + +typedef struct nodeang_s { + float cur_angle; + float dest_angle; +} nodeang_t; + +typedef struct { + GLXContext * glx_context; + + int node_list; /* name of the display list */ + int is_cyclic; + int is_legal; + int last_turn; + int selected; + struct timeb last_iteration; + struct timeb last_morph; + int morphing; + nodeang_t node[24]; + GLfloat roty; + GLfloat rotz; + int paused; + int dragging; + int m_count; + int m; + int cur_model; + int interactive; + GLfloat colour_t[3]; + GLfloat colour_i[3]; + GLfloat colour[3]; + model_t * models; + + XFontStruct * font; + GLuint font_list; +} glsnake_configuration; + +static glsnake_configuration *glc = NULL; + +static GLfloat speed; +static GLfloat explode; +static GLfloat velocity; +/* static GLfloat accel; */ +static long statictime; +static GLfloat yspin; +static GLfloat zspin; +static Bool scarycolour; +static Bool labels; + +static XrmOptionDescRec opts[] = { + { "-speed", ".speed", XrmoptionSepArg, 0 }, + { "-explode", ".explode", XrmoptionSepArg, 0 }, + { "-velocity", ".velocity", XrmoptionSepArg, 0 }, +/* { "-accel", ".accel", XrmoptionSepArg, 0 }, */ + { "-statictime", ".statictime", XrmoptionSepArg, 0 }, + { "-yspin", ".yspin", XrmoptionSepArg, 0 }, + { "-zspin", ".zspin", XrmoptionSepArg, 0 }, + { "-scarycolour", ".scarycolour", XrmoptionNoArg, "True" }, + { "+scarycolour", ".scarycolour", XrmoptionNoArg, "False" }, + { "-labels", ".labels", XrmoptionNoArg, "True" }, + { "+labels", ".labels", XrmoptionNoArg, "False" }, +}; + +static argtype vars[] = { + {(caddr_t *) &speed, "speed", "Speed", DEF_SPEED, t_Float}, + {(caddr_t *) &explode, "explode", "Explode", DEF_EXPLODE, t_Float}, + {(caddr_t *) &velocity, "velocity", "Velocity", DEF_VELOCITY, t_Float}, +/* {(caddr_t *) &accel, "accel", "Acceleration", DEF_ACCEL, t_Float}, */ + {(caddr_t *) &statictime, "statictime", "Static Time", DEF_STATICTIME, t_Int}, + {(caddr_t *) &yspin, "yspin", "Y Spin", DEF_YSPIN, t_Float}, + {(caddr_t *) &zspin, "zspin", "Z Spin", DEF_ZSPIN, t_Float}, +/* {(caddr_t *) &interactive, "interactive", "Interactive", DEF_INTERACTIVE, t_Bool}, */ + {(caddr_t *) &scarycolour, "scarycolour", "Scary Colour", DEF_SCARYCOLOUR, t_Bool}, + {(caddr_t *) &labels, "labels", "Labels", DEF_LABELS, t_Bool}, +}; + +ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL}; + +/* prism models */ +#define VOFFSET 0.045 +float solid_prism_v[][3] = { + /* first corner, bottom left front */ + { VOFFSET, VOFFSET, 1.0 }, + { VOFFSET, 0.0, 1.0 - VOFFSET }, + { 0.0, VOFFSET, 1.0 - VOFFSET }, + /* second corner, rear */ + { VOFFSET, VOFFSET, 0.00 }, + { VOFFSET, 0.0, VOFFSET }, + { 0.0, VOFFSET, VOFFSET }, + /* third, right front */ + { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 1.0 }, + { 1.0 - VOFFSET / M_SQRT1_2, 0.0, 1.0 - VOFFSET }, + { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, 1.0 - VOFFSET }, + /* fourth, right rear */ + { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 0.0 }, + { 1.0 - VOFFSET / M_SQRT1_2, 0.0, VOFFSET }, + { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, VOFFSET }, + /* fifth, upper front */ + { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 1.0 }, + { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, 1.0 - VOFFSET }, + { 0.0, 1.0 - VOFFSET / M_SQRT1_2, 1.0 - VOFFSET}, + /* sixth, upper rear */ + { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 0.0 }, + { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, VOFFSET }, + { 0.0, 1.0 - VOFFSET / M_SQRT1_2, VOFFSET } +}; + +/* normals */ +float solid_prism_n[][3] = { + /* corners */ + { -VOFFSET, -VOFFSET, VOFFSET }, + { VOFFSET, -VOFFSET, VOFFSET }, + { -VOFFSET, VOFFSET, VOFFSET }, + { -VOFFSET, -VOFFSET, -VOFFSET }, + { VOFFSET, -VOFFSET, -VOFFSET }, + { -VOFFSET, VOFFSET, -VOFFSET }, + /* edges */ + { -VOFFSET, 0.0, VOFFSET }, + { 0.0, -VOFFSET, VOFFSET }, + { VOFFSET, VOFFSET, VOFFSET }, + { -VOFFSET, 0.0, -VOFFSET }, + { 0.0, -VOFFSET, -VOFFSET }, + { VOFFSET, VOFFSET, -VOFFSET }, + { -VOFFSET, -VOFFSET, 0.0 }, + { VOFFSET, -VOFFSET, 0.0 }, + { -VOFFSET, VOFFSET, 0.0 }, + /* faces */ + { 0.0, 0.0, 1.0 }, + { 0.0, -1.0, 0.0 }, + { M_SQRT1_2, M_SQRT1_2, 0.0 }, + { -1.0, 0.0, 0.0 }, + { 0.0, 0.0, -1.0 } +}; + +/* vertices */ +float wire_prism_v[][3] = { + { 0.0, 0.0, 1.0 }, + { 1.0, 0.0, 1.0 }, + { 0.0, 1.0, 1.0 }, + { 0.0, 0.0, 0.0 }, + { 1.0, 0.0, 0.0 }, + { 0.0, 1.0, 0.0 } +}; + +/* normals */ +float wire_prism_n[][3] = { + { 0.0, 0.0, 1.0}, + { 0.0,-1.0, 0.0}, + { M_SQRT1_2, M_SQRT1_2, 0.0}, + {-1.0, 0.0, 0.0}, + { 0.0, 0.0,-1.0} +}; + +/* default models */ +#define Z 0.0 +#define L 90.0 +#define P 180.0 +#define R 270.0 + +static model_t default_models[] = { + { "Ball", + { R, R, L, L, R, L, R, R, L, R, L, L, R, R, L, L, R, L, R, R, L, R, L } + }, + { "Snow", + { R, R, R, R, L, L, L, L, R, R, R, R, L, L, L, L, R, R, R, R, L, L, L } + }, + { "Propellor", + { Z, Z, Z, R, L, R, Z, L, Z, Z, Z, R, L, R, Z, L, Z, Z, Z, R, L, R, Z } + }, + { "Flamingo", + { Z, P, Z, Z, Z, Z, Z, P, R, R, P, R, L, P, L, R, P, R, R, Z, Z, Z, P } + }, + { "Cat", + { Z, P, P, Z, P, P, Z, L, Z, P, P, Z, P, P, Z, P, P, Z, Z, Z, Z, Z, Z } + }, + { "Rooster", + { Z, Z, P, P, Z, L, Z, L, R, P, R, Z, P, P, Z, R, P, R, L, Z, L, Z, P } + } +}; + +/* add a model to the model list */ +model_t * add_model(model_t * models, char * name, int * rotations, int * count) { + int i; + + (*count)++; + models = realloc(models, sizeof(model_t) * (*count)); + models[(*count)-1].name = strdup(name); +#ifdef DEBUG + fprintf(stderr, "resized models to %d bytes for model %s\n", sizeof(model_t) * (*count), models[(*count)-1].name); +#endif + for (i = 0; i < 24; i++) { + models[(*count)-1].node[i] = rotations[i] * 90.0; + } + return models; +} + +/* filename is the name of the file to load + * models is the pointer to where the models will be kept + * returns a new pointer to models + * count is number of models read + */ +model_t * load_modelfile(char * filename, model_t * models, int * count) { + int c; + FILE * f; + char buffy[256]; + int rotations[24]; + int name = 1; + int rots = 0; + + f = fopen(filename, "r"); + if (f == NULL) { + int error_msg_len = strlen(filename) + 33 + 1; + char * error_msg = (char *) malloc(sizeof(char) * error_msg_len); + sprintf(error_msg, "Unable to open model data file \"%s\"", filename); + perror(error_msg); + free(error_msg); + return models; + } + + while ((c = getc(f)) != EOF) { + switch (c) { + /* ignore comments */ + case '#': + while (c != '\n') + c = getc(f); + break; + case ':': + buffy[name-1] = '\0'; + name = 0; + break; + case '\n': + if (rots > 0) { +#ifdef DEBUG + /* print out the model we just read in */ + int i; + printf("%s: ", buffy); + for (i = 0; i < rots; i++) { + switch (rotations[i]) { + case LEFT: + printf("L"); + break; + case RIGHT: + printf("R"); + break; + case PIN: + printf("P"); + break; + case ZERO: + printf("Z"); + break; + } + } + printf("\n"); +#endif + models = add_model(models, buffy, rotations, count); + } + name = 1; + rots = 0; + break; + default: + if (name) { + buffy[name-1] = c; + name++; + if (name > 255) + fprintf(stderr, "buffy overflow warning\n"); + } else { + switch (c) { + case '0': + case 'Z': + rotations[rots] = ZERO; + rots++; + break; + case '1': + case 'L': + rotations[rots] = LEFT; + rots++; + break; + case '2': + case 'P': + rotations[rots] = PIN; + rots++; + break; + case '3': + case 'R': + rotations[rots] = RIGHT; + rots++; + break; + default: + break; + } + } + break; + } + } + return models; +} + +model_t * load_models(char * dirpath, model_t * models, int * count) { + char name[1024]; + struct dirent * dp; + DIR * dfd; + + if ((dfd = opendir(dirpath)) == NULL) { + if (strstr(dirpath, "data") == NULL) +/* fprintf(stderr, "load_models: can't read %s/\n", dirpath); */ + return models; + } + while ((dp = readdir(dfd)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) + continue; + if (strlen(dirpath) + strlen(dp->d_name) + 2 > sizeof(name)) + fprintf(stderr, "load_models: name %s/%s too long\n", dirpath, dp->d_name); + else { + sprintf(name, "%s/%s", dirpath, dp->d_name); + if (strcmp(&name[(int) strlen(name) - 7], "glsnake") == 0) { +#ifdef DEBUG + fprintf(stderr, "load_models: opening %s\n", name); +#endif + models = load_modelfile(name, models, count); + } + } + } + closedir(dfd); + return models; +} + +/* snake metrics */ +#define X_MASK 1 +#define Y_MASK 2 +#define Z_MASK 4 +#define GETSCALAR(vec,mask) ((vec)==(mask) ? 1 : ((vec)==-(mask) ? -1 : 0 )) + +int cross_product(int src_dir, int dest_dir) { + return X_MASK * (GETSCALAR(src_dir, Y_MASK) * GETSCALAR(dest_dir, Z_MASK) - + GETSCALAR(src_dir, Z_MASK) * GETSCALAR(dest_dir, Y_MASK)) + + Y_MASK * (GETSCALAR(src_dir, Z_MASK) * GETSCALAR(dest_dir, X_MASK) - + GETSCALAR(src_dir, X_MASK) * GETSCALAR(dest_dir, Z_MASK)) + + Z_MASK * (GETSCALAR(src_dir, X_MASK) * GETSCALAR(dest_dir, Y_MASK) - + GETSCALAR(src_dir, Y_MASK) * GETSCALAR(dest_dir, X_MASK)); +} + +void calc_snake_metrics(glsnake_configuration * bp) { + int src_dir, dest_dir; + int i, x, y, z; + int prev_src_dir = -Y_MASK; + int prev_dest_dir = Z_MASK; + int grid[25][25][25]; + + /* zero the grid */ + memset(&grid, 0, sizeof(int) * 25*25*25); + + bp->is_legal = 1; + x = y = z = 12; + + /* trace path of snake and keep record for is_legal */ + for (i = 0; i < 23; i++) { + /* establish new state variables */ + src_dir = -prev_dest_dir; + x += GETSCALAR(prev_dest_dir, X_MASK); + y += GETSCALAR(prev_dest_dir, Y_MASK); + z += GETSCALAR(prev_dest_dir, Z_MASK); + + switch ((int) bp->node[i].dest_angle) { + case (int) (ZERO * 90.0): + dest_dir = -prev_src_dir; + break; + case (int) (PIN * 90.0): + dest_dir = prev_src_dir; + break; + case (int) (RIGHT * 90.): + case (int) (LEFT * 90.0): + dest_dir = cross_product(prev_src_dir, prev_dest_dir); + if (bp->node[i].dest_angle == (int) (RIGHT * 90.0)) + dest_dir = -dest_dir; + break; + default: + /* prevent spurious "might be used uninitialised" warnings */ + dest_dir = 0; + break; + } + + if (grid[x][y][z] == 0) + grid[x][y][z] = src_dir + dest_dir; + else if (grid[x][y][z] + src_dir + dest_dir == 0) + grid[x][y][z] = 8; + else + bp->is_legal = 0; + + prev_src_dir = src_dir; + prev_dest_dir = dest_dir; + } + + /* determine if the snake is cyclic */ + bp->is_cyclic = (dest_dir == Y_MASK && x == 12 && y == 11 && x == 12); + + /* determine last turn */ + bp->last_turn = -1; + if (bp->is_cyclic) { + switch (src_dir) { + case -Z_MASK: + bp->last_turn = ZERO * 90.0; + break; + case Z_MASK: + bp->last_turn = PIN * 90.0; + break; + case X_MASK: + bp->last_turn = LEFT * 90.0; + break; + case -X_MASK: + bp->last_turn = RIGHT * 90.0; + break; + } + } +} + +void set_colours(glsnake_configuration * bp, int immediate) { + /* set target colour */ + if (!bp->is_legal) { + bp->colour_t[0] = 0.5; + bp->colour_t[1] = 0.5; + bp->colour_t[2] = 0.5; + } else if (bp->is_cyclic) { + bp->colour_t[0] = 0.4; + bp->colour_t[1] = 0.8; + bp->colour_t[2] = 0.2; + } else { + bp->colour_t[0] = 0.3; + bp->colour_t[1] = 0.1; + bp->colour_t[2] = 0.9; + } + if (immediate) { + bp->colour_i[0] = bp->colour_t[0] - bp->colour[0]; + bp->colour_i[1] = bp->colour_t[1] - bp->colour[1]; + bp->colour_i[2] = bp->colour_t[2] - bp->colour[2]; + } else { + /* instead of 50.0, I should actually work out how many times this gets + * called during a morph */ + bp->colour_i[0] = (bp->colour_t[0] - bp->colour[0]) / 50.0; + bp->colour_i[1] = (bp->colour_t[1] - bp->colour[1]) / 50.0; + bp->colour_i[2] = (bp->colour_t[2] - bp->colour[2]) / 50.0; + } +} + +void start_morph(int model_index, int immediate, glsnake_configuration * bp) { + int i; + + for (i = 0; i < 23; i++) { + bp->node[i].dest_angle = bp->models[model_index].node[i]; + if (immediate) + bp->node[i].cur_angle = bp->models[model_index].node[i]; + } + + calc_snake_metrics(bp); + set_colours(bp, 0); + bp->cur_model = model_index; + bp->morphing = 1; +} + +/* convex hull */ + +/* model labels */ +void draw_label(ModeInfo * mi) { + glsnake_configuration *bp = &glc[MI_SCREEN(mi)]; + + glPushAttrib(GL_TRANSFORM_BIT | GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, mi->xgwa.width, 0, mi->xgwa.height); + glColor3f(1.0, 1.0, 0.0); + { + char * s; + int i, /* w, */ l; + + if (bp->interactive) + s = "interactive"; + else + s = bp->models[bp->cur_model].name; + + l = strlen(s); + /* + w = 0; + for (i = 0; i < l; i++) { + w += (bp->font->per_char + ? bp->font->per_char[((int)s[i]) - bp->font->min_char_or_byte2].rbearing + : bp->font->min_bounds.rbearing); + } + */ + + glRasterPos2f(10, mi->xgwa.height - 10 - (bp->font->ascent + bp->font->descent)); + /* mi->xgwa.width - w, bp->font->descent + bp->font->ascent); */ + + /* fprintf(stderr, "afaf.width = %d, w = %d\n", mi->xgwa.width, w); */ + + for (i = 0; i < l; i++) + glCallList(bp->font_list + (int)s[i]); + } + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); +} + +/* load the fonts -- this function borrowed from molecule.c */ +static void load_font(ModeInfo * mi, char * res, XFontStruct ** fontp, GLuint * dlistp) { + const char * font = get_string_resource(res, "Font"); + XFontStruct * f; + Font id; + int first, last; + + if (!font) + font = "-*-helvetica-medium-r-*-*-*-120-*"; + + f = XLoadQueryFont(mi->dpy, font); + if (!f) + f = XLoadQueryFont(mi->dpy, "fixed"); + + id = f->fid; + first = f->min_char_or_byte2; + last = f->max_char_or_byte2; + + clear_gl_error(); + *dlistp = glGenLists((GLuint) last + 1); + check_gl_error("glGenLists"); + glXUseXFont(id, first, last - first + 1, *dlistp + first); + check_gl_error("glXUseXFont"); + + *fontp = f; +} + + + +/* window management */ +void glsnake_reshape(ModeInfo *mi, int w, int h) { + glViewport (0, 0, (GLint) w, (GLint) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(25.0, w/(GLfloat)h, 1.0, 100.0 ); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +static void gl_init(ModeInfo *mi) { + /* glsnake_configuration *bp = &glc[MI_SCREEN(mi)]; */ + int wire = MI_IS_WIREFRAME(mi); + float light_pos[][3] = {{0.0,0.0,20.0},{0.0,20.0,0.0}}; + float light_dir[][3] = {{0.0,0.0,-20.0},{0.0,-20.0,0.0}}; + + glClearColor(0.0, 0.0, 0.0, 0.0); + glEnable(GL_DEPTH_TEST); + glShadeModel(GL_SMOOTH); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + glEnable(GL_NORMALIZE); + + if (!wire) { + glColor3f(1.0, 1.0, 1.0); + glLightfv(GL_LIGHT0, GL_POSITION, light_pos[0]); + glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir[0]); + glLightfv(GL_LIGHT1, GL_POSITION, light_pos[1]); + glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, light_dir[1]); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + glEnable(GL_COLOR_MATERIAL); + } +} + +/* lifted from lament.c */ +#define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n)))) +#define RANDSIGN() ((random() & 1) ? 1 : -1) + +void glsnake_init(ModeInfo *mi) { + glsnake_configuration * bp; + int wire = MI_IS_WIREFRAME(mi); + + if (!glc) { + glc = (glsnake_configuration *) calloc(MI_NUM_SCREENS(mi), sizeof(glsnake_configuration)); + if (!glc) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + bp = &glc[MI_SCREEN(mi)]; + } + + bp = &glc[MI_SCREEN(mi)]; + + if ((bp->glx_context = init_GL(mi)) != NULL) { + gl_init(mi); + glsnake_reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + } + + /* initialise config variables */ + memset(&bp->node, 0, sizeof(nodeang_t) * 24); + bp->m_count = sizeof(default_models) / sizeof(model_t); /* overwrite this in a bit */ + bp->selected = 11; + bp->is_cyclic = 0; + bp->is_legal = 1; + bp->last_turn = -1; + bp->roty = 0.0; + bp->rotz = 0.0; + bp->morphing = 0; + bp->paused = 0; + bp->dragging = 0; + bp->interactive = 0; + + ftime(&(bp->last_iteration)); + memcpy(&(bp->last_morph), &(bp->last_iteration), sizeof(struct timeb)); + /* srand((unsigned int) bp->last_iteration.time); */ + + /* load the model files */ + /* first copy the defaults to bp->m_count */ + bp->models = (model_t *) malloc(sizeof(model_t) * bp->m_count); + memcpy(bp->models, default_models, bp->m_count * sizeof(model_t)); + /* then add on models from the Debian model file location */ + bp->models = load_models("/usr/share/glsnake", bp->models, &(bp->m_count)); + + bp->m = bp->cur_model = RAND(bp->m_count); + start_morph(bp->cur_model, 1, bp); + + calc_snake_metrics(bp); + set_colours(bp, 1); + + /* set up a font for the labels */ + if (labels) + load_font(mi, "labelfont", &bp->font, &bp->font_list); + + bp->node_list = glGenLists(1); + glNewList(bp->node_list, GL_COMPILE); + if (!wire) { + /* corners */ + glBegin(GL_TRIANGLES); + glNormal3fv(solid_prism_n[0]); + glVertex3fv(solid_prism_v[0]); + glVertex3fv(solid_prism_v[2]); + glVertex3fv(solid_prism_v[1]); + + glNormal3fv(solid_prism_n[1]); + glVertex3fv(solid_prism_v[6]); + glVertex3fv(solid_prism_v[7]); + glVertex3fv(solid_prism_v[8]); + + glNormal3fv(solid_prism_n[2]); + glVertex3fv(solid_prism_v[12]); + glVertex3fv(solid_prism_v[13]); + glVertex3fv(solid_prism_v[14]); + + glNormal3fv(solid_prism_n[3]); + glVertex3fv(solid_prism_v[3]); + glVertex3fv(solid_prism_v[4]); + glVertex3fv(solid_prism_v[5]); + + glNormal3fv(solid_prism_n[4]); + glVertex3fv(solid_prism_v[9]); + glVertex3fv(solid_prism_v[11]); + glVertex3fv(solid_prism_v[10]); + + glNormal3fv(solid_prism_n[5]); + glVertex3fv(solid_prism_v[16]); + glVertex3fv(solid_prism_v[15]); + glVertex3fv(solid_prism_v[17]); + glEnd(); + + /* edges */ + glBegin(GL_QUADS); + glNormal3fv(solid_prism_n[6]); + glVertex3fv(solid_prism_v[0]); + glVertex3fv(solid_prism_v[12]); + glVertex3fv(solid_prism_v[14]); + glVertex3fv(solid_prism_v[2]); + + glNormal3fv(solid_prism_n[7]); + glVertex3fv(solid_prism_v[0]); + glVertex3fv(solid_prism_v[1]); + glVertex3fv(solid_prism_v[7]); + glVertex3fv(solid_prism_v[6]); + + glNormal3fv(solid_prism_n[8]); + glVertex3fv(solid_prism_v[6]); + glVertex3fv(solid_prism_v[8]); + glVertex3fv(solid_prism_v[13]); + glVertex3fv(solid_prism_v[12]); + + glNormal3fv(solid_prism_n[9]); + glVertex3fv(solid_prism_v[3]); + glVertex3fv(solid_prism_v[5]); + glVertex3fv(solid_prism_v[17]); + glVertex3fv(solid_prism_v[15]); + + glNormal3fv(solid_prism_n[10]); + glVertex3fv(solid_prism_v[3]); + glVertex3fv(solid_prism_v[9]); + glVertex3fv(solid_prism_v[10]); + glVertex3fv(solid_prism_v[4]); + + glNormal3fv(solid_prism_n[11]); + glVertex3fv(solid_prism_v[15]); + glVertex3fv(solid_prism_v[16]); + glVertex3fv(solid_prism_v[11]); + glVertex3fv(solid_prism_v[9]); + + glNormal3fv(solid_prism_n[12]); + glVertex3fv(solid_prism_v[1]); + glVertex3fv(solid_prism_v[2]); + glVertex3fv(solid_prism_v[5]); + glVertex3fv(solid_prism_v[4]); + + glNormal3fv(solid_prism_n[13]); + glVertex3fv(solid_prism_v[8]); + glVertex3fv(solid_prism_v[7]); + glVertex3fv(solid_prism_v[10]); + glVertex3fv(solid_prism_v[11]); + + glNormal3fv(solid_prism_n[14]); + glVertex3fv(solid_prism_v[13]); + glVertex3fv(solid_prism_v[16]); + glVertex3fv(solid_prism_v[17]); + glVertex3fv(solid_prism_v[14]); + glEnd(); + + /* faces */ + glBegin(GL_TRIANGLES); + glNormal3fv(solid_prism_n[15]); + glVertex3fv(solid_prism_v[0]); + glVertex3fv(solid_prism_v[6]); + glVertex3fv(solid_prism_v[12]); + + glNormal3fv(solid_prism_n[19]); + glVertex3fv(solid_prism_v[3]); + glVertex3fv(solid_prism_v[15]); + glVertex3fv(solid_prism_v[9]); + glEnd(); + + glBegin(GL_QUADS); + glNormal3fv(solid_prism_n[16]); + glVertex3fv(solid_prism_v[1]); + glVertex3fv(solid_prism_v[4]); + glVertex3fv(solid_prism_v[10]); + glVertex3fv(solid_prism_v[7]); + + glNormal3fv(solid_prism_n[17]); + glVertex3fv(solid_prism_v[8]); + glVertex3fv(solid_prism_v[11]); + glVertex3fv(solid_prism_v[16]); + glVertex3fv(solid_prism_v[13]); + + glNormal3fv(solid_prism_n[18]); + glVertex3fv(solid_prism_v[2]); + glVertex3fv(solid_prism_v[14]); + glVertex3fv(solid_prism_v[17]); + glVertex3fv(solid_prism_v[5]); + glEnd(); + } else { + /* build wire display list */ + glBegin(GL_LINE_STRIP); + glVertex3fv(wire_prism_v[0]); + glVertex3fv(wire_prism_v[1]); + glVertex3fv(wire_prism_v[2]); + glVertex3fv(wire_prism_v[0]); + glVertex3fv(wire_prism_v[3]); + glVertex3fv(wire_prism_v[4]); + glVertex3fv(wire_prism_v[5]); + glVertex3fv(wire_prism_v[3]); + glEnd(); + + glBegin(GL_LINES); + glVertex3fv(wire_prism_v[1]); + glVertex3fv(wire_prism_v[4]); + glVertex3fv(wire_prism_v[2]); + glVertex3fv(wire_prism_v[5]); + glEnd(); + } + glEndList(); +} + +/* "jwz? no way man, he's my idle" -- Jaq, 2001. + * I forget the context :( */ +void glsnake_idol(glsnake_configuration * bp) { + /* time since last iteration */ + long iter_msec; + /* time since the beginning of last morph */ + long morf_msec; + float iter_angle_max; + int i; + struct timeb current_time; + int still_morphing; + + /* Do nothing to the model if we are paused */ + if (bp->paused) { + /* Avoid busy waiting when nothing is changing */ + usleep(1); + return; + } + /* ftime is winDOS compatible */ + ftime(¤t_time); + + /* Well, ftime gives time with millisecond resolution. + * if current time is exactly equal to last iteration, + * then don't do this block + * (or worse, perhaps... who knows what the OS will do) + * So if no discernable amount of time has passed: + * a) There's no point updating the screen, because + * it would be the same + * b) The code will divide by zero + */ + iter_msec = (long) current_time.millitm - bp->last_iteration.millitm + + ((long) current_time.time - bp->last_iteration.time) * 1000L; + if (iter_msec) { + /* save the current time */ + memcpy(&(bp->last_iteration), ¤t_time, sizeof(struct timeb)); + + /* work out if we have to switch models */ + morf_msec = bp->last_iteration.millitm - bp->last_morph.millitm + + ((long) (bp->last_iteration.time - bp->last_morph.time) * 1000L); + + if ((morf_msec > statictime) && !bp->interactive) { + memcpy(&(bp->last_morph), &(bp->last_iteration), sizeof(struct timeb)); + start_morph(RAND(bp->m_count), 0, bp); + } + + if (bp->interactive && !bp->morphing) { + usleep(1); + return; + } + + if (!bp->dragging && !bp->interactive) { + bp->roty += 360/((1000/yspin)/iter_msec); + bp->rotz += 360/((1000/zspin)/iter_msec); + } + + /* work out the maximum angle for this iteration */ + iter_angle_max = 90.0 * (velocity/1000.0) * iter_msec; + + still_morphing = 0; + for (i = 0; i < 24; i++) { + float cur_angle = bp->node[i].cur_angle; + float dest_angle = bp->node[i].dest_angle; + if (cur_angle != dest_angle) { + still_morphing = 1; + if (fabs(cur_angle - dest_angle) <= iter_angle_max) + bp->node[i].cur_angle = dest_angle; + else if (fmod(cur_angle - dest_angle + 360, 360) > 180) + bp->node[i].cur_angle = fmod(cur_angle + iter_angle_max, 360); + else + bp->node[i].cur_angle = fmod(cur_angle + 360 - iter_angle_max, 360); + } + } + + if (!still_morphing) + bp->morphing = 0; + + /* colour cycling */ + if (fabs(bp->colour[0] - bp->colour_t[0]) <= fabs(bp->colour_i[0])) + bp->colour[0] = bp->colour_t[0]; + else + bp->colour[0] += bp->colour_i[0]; + if (fabs(bp->colour[1] - bp->colour_t[1]) <= fabs(bp->colour_i[1])) + bp->colour[1] = bp->colour_t[1]; + else + bp->colour[1] += bp->colour_i[1]; + if (fabs(bp->colour[2] - bp->colour_t[2]) <= fabs(bp->colour_i[2])) + bp->colour[2] = bp->colour_t[2]; + else + bp->colour[2] += bp->colour_i[2]; + } else { + /* We are going too fast, so we may as well let the + * cpu relax a little by sleeping for a millisecond. */ + usleep(1); + } +} + +void glsnake_draw(ModeInfo *mi) { + glsnake_configuration *bp = &glc[MI_SCREEN(mi)]; + Display *dpy = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + + int i; + float ang; + + if (!bp->glx_context) + return; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); + + /* rotate and translate into snake space */ + glRotatef(45.0, -5.0, 0.0, 1.0); + glTranslatef(-0.5, 0.0, 0.5); + + /* rotate the 0th junction */ + glTranslatef(0.5, 0.0, 0.5); + /* glMultMatrix(rotation); -- quaternion rotation */ + glRotatef(bp->roty, 0.0, 1.0, 0.0); + glRotatef(bp->rotz, 0.0, 0.0, 1.0); + glTranslated(-0.5, 0.0, -0.5); + + /* translate middle node to centre */ + for (i = 11; i >= 0; i--) { + ang = bp->node[i].cur_angle; + glTranslatef(0.5, 0.5, 0.5); + glRotatef(180+ang, -1.0, 0.0, 0.0); + glTranslatef(-1.0 - explode, 0.0, 0.0); + glRotatef(90, 0.0, 0.0, 1.0); + glTranslatef(-0.5, -0.5, -0.5); + } + + /* now draw each node along the snake */ + for (i = 0; i < 24; i++) { + glPushMatrix(); + + /* choose a colour for this node */ + if (bp->interactive && (i == bp->selected || i == bp->selected+1)) + glColor3f(1.0, 1.0, 0.0); + else { + if (i % 2) { + if (scarycolour) + glColor3f(0.6, 0.0, 0.9); + else + glColor3fv(bp->colour); + } else { + if (scarycolour) + glColor3f(0.2, 0.9, 1.0); + else + glColor3f(1.0, 1.0, 1.0); + } + } + + /* draw the node */ + glCallList(bp->node_list); + + /* now work out where to draw the next one */ + + /* interpolate between models */ + ang = bp->node[i].cur_angle; + + glTranslatef(0.5, 0.5, 0.5); + glRotatef(90, 0.0, 0.0, -1.0); + glTranslatef(1.0 + explode, 0.0, 0.0); + glRotatef(180 + ang, 1.0, 0.0, 0.0); + glTranslatef(-0.5, -0.5, -0.5); + } + + /* clear up the matrix stack */ + for (i = 0; i < 24; i++) + glPopMatrix(); + + if (labels) + draw_label(mi); + + if (mi->fps_p) + do_fps (mi); + + glsnake_idol(bp); + + glFlush(); + glXSwapBuffers(dpy, window); +} + +#endif /* USE_GL */ diff --git a/hacks/glx/glsnake.man b/hacks/glx/glsnake.man new file mode 100644 index 00000000..e6b55278 --- /dev/null +++ b/hacks/glx/glsnake.man @@ -0,0 +1,100 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH XScreenSaver 1 "January 15, 2001" "X Version 11" +.SH NAME +glsnake \- OpenGL enhanced Rubik's Snake cyclewaster. +.SH SYNOPSIS +.B glsnake +[\-display \fIhost:display.screen\fP] [\-window] [\-root] +[\-visual \fIvisual\fP] [\-delay \fImicroseconds\fP] [\-fps] +[\-wireframe] [\-scarycolour] +[\-velocity \fIangular\fP] +[\-explode \fIdistance\fP] +[\-statictime \fImilliseconds\fP] +[\-yspin \fIangle\fP] +[\-zspin \fIangle\fP] +.SH DESCRIPTION +.PP +.B glsnake +is an imitation of Rubiks\' Snake, using OpenGL. +.SH OPTIONS +.I glsnake +accepts the following options: +.TP 8 +.B \-window +Draw on a newly-created window. This is the default. +.TP 8 +.B \-root +Draw on the root window. +.TP 8 +.B \-install +Install a private colormap for the window. +.TP 8 +.B \-visual \fIvisual\fP\fP +Specify which visual to use. Legal values are the name of a visual class, +or the id number (decimal or hex) of a specific visual. +.TP 8 +.B \-fps +Display a running tally of how many frames per second are being rendered. +In conjunction with \fB\-delay 0\fP, this can be a useful benchmark of +your GL performance. +.TP 8 +.B \-wireframe +Display the snake in wireframe mode, rather than the default solid mode. +.TP 8 +.B \-scarycolour +Use the alternate colour scheme for the snake. Shape identification using +colour will be disabled. +.TP 8 +.B -velocity \fIangular\fP +Change the speed at which the snake morphs to a new shape. +.TP 8 +.B -explode \fIdistance\fP +Change the distance between the nodes of a snake. +.TP 8 +.B \-statictime \fImilliseconds\fP +Change the time between morphs. +.TP 8 +.B \-yspin \fIangle\fP +Change the angle of rotation around the Y axis per frame. +.TP 8 +.B \-zspin \fIangle\fP +Change the angle of rotation around the Z axis per frame. +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH FILES +.TP +\fB/usr/share/glsnake/*.glsnake\fP +This XScreenSaver will attempt to read model files installed with the interactive \fBglsnake\fP. +.SH SEE ALSO +.BR X (1), +.BR xscreensaver (1), +.BR glsnake (6) +.PP +.EX +http://spacepants.org/src/glsnake/ +.EE +.SH BUGS +The snake will happily intersect itself while morphing (this is not a bug). +.PP +The rotation/camera position sucks. +.SH COPYRIGHT +Copyright \(co 2001,2002 by Jamie Wilkinson, Andrew Bennetts, and Peter Aylett. +.PP +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. +.PP +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +.SH AUTHOR +Jamie Wilkinson , Andrew Bennetts , +and Peter Aylett . Ported to XScreenSaver by Jamie Wilkinson. diff --git a/hacks/glx/grab-ximage.c b/hacks/glx/grab-ximage.c index 3ca543fd..6a5b1fa2 100644 --- a/hacks/glx/grab-ximage.c +++ b/hacks/glx/grab-ximage.c @@ -21,6 +21,7 @@ #include /* only for GLfloat */ #include "grabscreen.h" +#include "visual.h" extern char *progname; @@ -32,14 +33,6 @@ extern char *progname; #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) -static Bool -bigendian (void) -{ - union { int i; char c[sizeof(int)]; } u; - u.i = 1; - return !u.c[0]; -} - /* return the next larger power of 2. */ static int to_pow2 (int i) @@ -53,6 +46,45 @@ to_pow2 (int i) } +/* Given a bitmask, returns the position and width of the field. + */ +static void +decode_mask (unsigned int mask, unsigned int *pos_ret, unsigned int *size_ret) +{ + int i; + for (i = 0; i < 32; i++) + if (mask & (1L << i)) + { + int j = 0; + *pos_ret = i; + for (; i < 32; i++, j++) + if (! (mask & (1L << i))) + break; + *size_ret = j; + return; + } +} + + +/* Given a value and a field-width, expands the field to fill out 8 bits. + */ +static unsigned char +spread_bits (unsigned char value, unsigned char width) +{ + switch (width) + { + case 8: return value; + case 7: return (value << 1) | (value >> 6); + case 6: return (value << 2) | (value >> 4); + case 5: return (value << 3) | (value >> 2); + case 4: return (value << 4) | (value); + case 3: return (value << 5) | (value << 2) | (value >> 2); + case 2: return (value << 6) | (value << 4) | (value); + default: abort(); break; + } +} + + /* Returns an XImage structure containing an image of the desktop. (As a side-effect, that image will be painted onto the given Window.) This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the @@ -80,6 +112,7 @@ screen_to_ximage (Screen *screen, Window window) */ { XImage *ximage1, *ximage2; + XColor *colors = 0; ximage1 = XGetImage (dpy, window, 0, 0, win_width, win_height, ~0L, ZPixmap); @@ -88,6 +121,22 @@ screen_to_ximage (Screen *screen, Window window) ximage2->data = (char *) calloc (tex_height, ximage2->bytes_per_line); + { + Screen *dscreen = DefaultScreenOfDisplay (dpy); + Visual *dvisual = DefaultVisualOfScreen (dscreen); + if (visual_class (dscreen, dvisual) == PseudoColor || + visual_class (dscreen, dvisual) == GrayScale) + { + Colormap cmap = DefaultColormapOfScreen(dscreen); + int ncolors = visual_cells (dscreen, dvisual); + int i; + colors = (XColor *) calloc (sizeof (*colors), ncolors+1); + for (i = 0; i < ncolors; i++) + colors[i].pixel = i; + XQueryColors (dpy, cmap, colors, ncolors); + } + } + /* Translate the server-ordered image to a client-ordered image. */ { @@ -95,25 +144,33 @@ screen_to_ximage (Screen *screen, Window window) int crpos, cgpos, cbpos, capos; /* bitfield positions */ int srpos, sgpos, sbpos; int srmsk, sgmsk, sbmsk; - int sdepth = ximage1->depth; + int srsiz, sgsiz, sbsiz; + int i; + + unsigned char spread_map[3][256]; srmsk = ximage1->red_mask; sgmsk = ximage1->green_mask; sbmsk = ximage1->blue_mask; - if (sdepth == 32 || sdepth == 24) - srpos = 16, sgpos = 8, sbpos = 0; - else /* 15 or 16 */ - srpos = 10, sgpos = 5, sbpos = 0; + + decode_mask (srmsk, &srpos, &srsiz); + decode_mask (sgmsk, &sgpos, &sgsiz); + decode_mask (sbmsk, &sbpos, &sbsiz); /* Note that unlike X, which is endianness-agnostic (since any XImage can have its own specific bit ordering, with the server reversing things as necessary) OpenGL pretends everything is client-side, so - we need to pack things in the right order for the client machine. + we need to pack things in "RGBA" order on the client machine, + regardless of its endianness. */ - if (bigendian()) - crpos = 24, cgpos = 16, cbpos = 8, capos = 0; - else - crpos = 0, cgpos = 8, cbpos = 16, capos = 24; + crpos = 0, cgpos = 8, cbpos = 16, capos = 24; + + for (i = 0; i < 256; i++) + { + spread_map[0][i] = spread_bits (i, srsiz); + spread_map[1][i] = spread_bits (i, sgsiz); + spread_map[2][i] = spread_bits (i, sbsiz); + } for (y = 0; y < win_height; y++) { @@ -121,26 +178,37 @@ screen_to_ximage (Screen *screen, Window window) for (x = 0; x < win_width; x++) { unsigned long sp = XGetPixel (ximage1, x, y2); - unsigned char sr = (sp & srmsk) >> srpos; - unsigned char sg = (sp & sgmsk) >> sgpos; - unsigned char sb = (sp & sbmsk) >> sbpos; + unsigned char sr, sg, sb; unsigned long cp; - if (sdepth < 24) /* spread 5 bits to 8 */ + if (colors) { - sr = (sr << 3) | (sr >> 2); - sg = (sg << 3) | (sg >> 2); - sb = (sb << 3) | (sb >> 2); + sr = colors[sp].red & 0xFF; + sg = colors[sp].green & 0xFF; + sb = colors[sp].blue & 0xFF; } + else + { + sr = (sp & srmsk) >> srpos; + sg = (sp & sgmsk) >> sgpos; + sb = (sp & sbmsk) >> sbpos; + + sr = spread_map[0][sr]; + sg = spread_map[1][sg]; + sb = spread_map[2][sb]; + } + cp = ((sr << crpos) | (sg << cgpos) | (sb << cbpos) | (0xFF << capos)); + XPutPixel (ximage2, x, y, cp); } } } + if (colors) free (colors); free (ximage1->data); ximage1->data = 0; XDestroyImage (ximage1); diff --git a/hacks/glx/lament.c b/hacks/glx/lament.c index 3f5080c0..aedc57d4 100644 --- a/hacks/glx/lament.c +++ b/hacks/glx/lament.c @@ -109,6 +109,7 @@ static argtype vars[] = { ModeSpecOpt lament_opts = {countof(opts), opts, countof(vars), vars, NULL}; #include "xpm-ximage.h" + #include "../images/lament.xpm" #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n)))) diff --git a/hacks/glx/molecule.c b/hacks/glx/molecule.c index cb2932eb..02b83624 100644 --- a/hacks/glx/molecule.c +++ b/hacks/glx/molecule.c @@ -112,6 +112,7 @@ #ifdef USE_GL /* whole file */ +#include #include #include @@ -1034,13 +1035,34 @@ parse_pdb_file (molecule *m, const char *name) } +typedef struct { char *atom; int count; } atom_and_count; + +/* When listing the components of a molecule, the convention is to put the + carbon atoms first, the hydrogen atoms second, and the other atom types + sorted alphabetically after that (although for some molecules, the usual + order is different, like for NH(3), but we don't special-case those.) + */ +static int +cmp_atoms (const void *aa, const void *bb) +{ + const atom_and_count *a = (atom_and_count *) aa; + const atom_and_count *b = (atom_and_count *) bb; + if (!a->atom) return 1; + if (!b->atom) return -1; + if (!strcmp(a->atom, "C")) return -1; + if (!strcmp(b->atom, "C")) return 1; + if (!strcmp(a->atom, "H")) return -1; + if (!strcmp(b->atom, "H")) return 1; + return strcmp (a->atom, b->atom); +} + static void generate_molecule_formula (molecule *m) { char *buf = (char *) malloc (m->natoms * 10); char *s = buf; int i; - struct { char *atom; int count; } counts[200]; + atom_and_count counts[200]; memset (counts, 0, sizeof(counts)); *s = 0; for (i = 0; i < m->natoms; i++) @@ -1061,6 +1083,10 @@ generate_molecule_formula (molecule *m) counts[j].count++; } + i = 0; + while (counts[i].atom) i++; + qsort (counts, i, sizeof(*counts), cmp_atoms); + i = 0; while (counts[i].atom) { diff --git a/hacks/glx/pulsar.c b/hacks/glx/pulsar.c index a7695027..9d894f40 100644 --- a/hacks/glx/pulsar.c +++ b/hacks/glx/pulsar.c @@ -74,13 +74,6 @@ #ifdef USE_GL /* whole file */ -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif - #ifdef HAVE_XMU # ifndef VMS # include @@ -93,9 +86,9 @@ #include #include -#include -#include +#include #include +#include /* Functions for loading and storing textures */ diff --git a/hacks/glx/sballs.c b/hacks/glx/sballs.c new file mode 100644 index 00000000..b8c3e74d --- /dev/null +++ b/hacks/glx/sballs.c @@ -0,0 +1,865 @@ +/* sballs --- balls spinning like crazy in GL */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)sballs.c 5.02 2001/03/10 xlockmore"; +#endif + +/* Copyright (c) E. Lassauge, 2001. */ + +/* + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * The original code for this mode was written by + * Mustata Bogdan (LoneRunner) + * and can be found at http://www.cfxweb.net/lonerunner/ + * + * Eric Lassauge (November-07-2000) + * http://lassauge.free.fr/linux.html + * + * REVISION HISTORY: + * + * E.Lassauge - 03-Oct-2001: + * - minor bugfixes - get ready for xscreensaver + * E.Lassauge - 09-Mar-2001: + * - get rid of my framerate options to use showfps + * E.Lassauge - 28-Nov-2000: + * - add handling of polyhedrons (like in ico) + * - modified release part to add freeing of GL objects + * E.Lassauge - 14-Nov-2000: + * - use new common xpm_to_ximage function + * + */ + +#ifdef STANDALONE /* xscreensaver mode */ +#define PROGCLASS "Sballs" +#define HACK_INIT init_sballs +#define HACK_DRAW draw_sballs +#define HACK_RESHAPE reshape_sballs +#define sballs_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*size: 0 \n" \ + "*cycles: 10 \n" \ + "*object: 0 \n" \ + "*trackmouse: False \n" \ + "*showFPS: False \n" \ + "*wireframe: False \n" \ + "*texture: True \n" + +#define MODE_sballs +#include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ +#include "visgl.h" +#endif /* !STANDALONE */ + +#ifdef MODE_sballs + +#define MINSIZE 32 /* minimal viewport size */ +#define FRAME 50 /* frame count interval */ +#define MAX_OBJ 8 /* number of 3D objects */ + +#include +#include +#include + +#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined( HAVE_XPM ) +/* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */ +#include "xpm-ximage.h" +#define I_HAVE_XPM + +#ifdef STANDALONE +#include "../images/sball.xpm" +#include "../images/sball-bg.xpm" +#else /* !STANDALONE */ +#include "pixmaps/sball.xpm" +#include "pixmaps/sball-bg.xpm" +#endif /* !STANDALONE */ +#endif /* HAVE_XPM */ + +/* Manage option vars */ +#define DEF_TEXTURE "True" +#define DEF_TRACKMOUSE "False" +#define DEF_OBJECT "2" +#define DEF_OBJECT_INDX 2 +static Bool do_texture; +static Bool do_trackmouse; +static int object; +static int spheres; + +static XrmOptionDescRec opts[] = { + {(char *) "-texture", (char *) ".sballs.texture", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+texture", (char *) ".sballs.texture", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-trackmouse", (char *) ".sballs.trackmouse", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+trackmouse", (char *) ".sballs.trackmouse", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-object", (char *) ".sballs.object", XrmoptionSepArg, (caddr_t) NULL}, + +}; + +static argtype vars[] = { + {(caddr_t *) & do_texture, (char *) "texture", (char *) "Texture", (char *) DEF_TEXTURE, t_Bool}, + {(caddr_t *) & do_trackmouse, (char *) "trackmouse", (char *) "TrackMouse", (char *) DEF_TRACKMOUSE, t_Bool}, + {(caddr_t *) & object, (char *) "object", (char *) "Object", (char *) DEF_OBJECT, t_Int}, + +}; + +static OptionStruct desc[] = { + /*{(char *) "-count spheres", (char *) "set number of spheres"},*/ + /*{(char *) "-cycles speed", (char *) "set ball speed value"},*/ + {(char *) "-/+texture", (char *) "turn on/off texturing"}, + {(char *) "-/+trackmouse", (char *) "turn on/off the tracking of the mouse"}, + {(char *) "-object num", (char *) "number of the 3D object (0 means random)"}, +}; + +ModeSpecOpt sballs_opts = + { sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc }; + +#ifdef USE_MODULES +ModStruct sballs_description = + { "sballs", "init_sballs", "draw_sballs", "release_sballs", + "draw_sballs", "change_sballs", (char *) NULL, &sballs_opts, + /* + delay,count,cycles,size,ncolors,sat + */ + 10000, 0, 10, 400, 64, 1.0, "", + "balls spinning like crazy in GL", 0, NULL +}; +#endif /* USE_MODULES */ + +/* misc types and defines */ +#define vinit(a,i,j,k) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ +} +typedef float vec_t; +typedef vec_t vec3_t[3]; + +#define MAX_BALLS 20 + +/* the mode struct, contains all per screen variables */ +typedef struct { + GLint WIDTH, HEIGHT; /* display dimensions */ + GLXContext *glx_context; + + + XImage *btexture; /* back texture image bits */ + XImage *ftexture; /* face texture image bits */ + GLuint backid; /* back texture id: GL world */ + GLuint faceid; /* face texture id: GL world */ + + vec3_t eye; + vec3_t rot; + vec3_t rotm; + int speed; + float radius[MAX_BALLS]; + +} sballsstruct; + +/* array of sballsstruct indexed by screen number */ +static sballsstruct *sballs = (sballsstruct *) NULL; + +/* lights */ +static float LightAmbient[]= { 1.0f, 1.0f, 1.0f, 1.0f }; +static float LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; +static float LightPosition[]= { 0.0f, 0.0f, 4.0f, 1.0f }; + +/* structure of the polyhedras */ +typedef struct { + const char *longname; /* long name of object */ + const char *shortname; /* short name of object */ + int numverts; /* number of vertices */ + float radius; /* radius */ + vec3_t v[MAX_BALLS];/* the vertices */ +} Polyinfo; + +static Polyinfo polygons[] = +{ + +/* 0: objtetra - structure values for tetrahedron */ + { + "tetrahedron", "tetra", /* long and short names */ + 4, /* number of vertices */ + 0.8, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.0 + {T, T, T}, + {T, -T, -T}, + {-T, T, -T}, + {-T, -T, T}, +#undef T + } + }, + +/* 1: objcube - structure values for cube */ + + { + "hexahedron", "cube", /* long and short names */ + 8, /* number of vertices, edges, and faces */ + 0.6, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.0 + {T, T, T}, + {T, T, -T}, + {T, -T, -T}, + {T, -T, T}, + {-T, T, T}, + {-T, T, -T}, + {-T, -T, -T}, + {-T, -T, T}, +#undef T + } + }, + +/* 2: objocta - structure values for octahedron */ + + { + "octahedron", "octa", /* long and short names */ + 6, /* number of vertices */ + 0.6, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.5 + {T, 0, 0}, + {-T, 0, 0}, + {0, T, 0}, + {0, -T, 0}, + {0, 0, T}, + {0, 0, -T}, +#undef T + } + }, +/* 3: objdodec - structure values for dodecahedron */ + + { + "dodecahedron", "dodeca", /* long and short names */ + 20, /* number of vertices */ + 0.35, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ + {0.000000, 0.500000, 1.000000}, + {0.000000, -0.500000, 1.000000}, + {0.000000, -0.500000, -1.000000}, + {0.000000, 0.500000, -1.000000}, + {1.000000, 0.000000, 0.500000}, + {-1.000000, 0.000000, 0.500000}, + {-1.000000, 0.000000, -0.500000}, + {1.000000, 0.000000, -0.500000}, + {0.500000, 1.000000, 0.000000}, + {-0.500000, 1.000000, 0.000000}, + {-0.500000, -1.000000, 0.000000}, + {0.500000, -1.000000, 0.000000}, + {0.750000, 0.750000, 0.750000}, + {-0.750000, 0.750000, 0.750000}, + {-0.750000, -0.750000, 0.750000}, + {0.750000, -0.750000, 0.750000}, + {0.750000, -0.750000, -0.750000}, + {0.750000, 0.750000, -0.750000}, + {-0.750000, 0.750000, -0.750000}, + {-0.750000, -0.750000, -0.750000}, + } + }, + +/* 4: objicosa - structure values for icosahedron */ + + { + "icosahedron", "icosa", /* long and short names */ + 12, /* number of vertices */ + 0.4, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ + {0.00000000, 0.00000000, -0.95105650}, + {0.00000000, 0.85065080, -0.42532537}, + {0.80901698, 0.26286556, -0.42532537}, + {0.50000000, -0.68819095, -0.42532537}, + {-0.50000000, -0.68819095, -0.42532537}, + {-0.80901698, 0.26286556, -0.42532537}, + {0.50000000, 0.68819095, 0.42532537}, + {0.80901698, -0.26286556, 0.42532537}, + {0.00000000, -0.85065080, 0.42532537}, + {-0.80901698, -0.26286556, 0.42532537}, + {-0.50000000, 0.68819095, 0.42532537}, + {0.00000000, 0.00000000, 0.95105650} + } + }, + +/* 5: objplane - structure values for plane */ + + { + "plane", "plane", /* long and short names */ + 4, /* number of vertices */ + 0.7, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.1 + {T, 0, 0}, + {-T, 0, 0}, + {0, T, 0}, + {0, -T, 0}, +#undef T + } + }, + +/* 6: objpyr - structure values for pyramid */ + + { + "pyramid", "pyramid", /* long and short names */ + 5, /* number of vertices */ + 0.5, + { /* vertices (x,y,z) */ + /* all points must be within radius 1 of the origin */ +#define T 1.0 + {T, 0, 0}, + {-T, 0, 0}, + {0, T, 0}, + {0, -T, 0}, + {0, 0, T}, +#undef T + } + }, + +/* 7: objstar - structure values for octahedron star (stellated octahedron?) */ + { + "star", "star", /* long and short names */ + 8, /* number of vertices */ + 0.7, + { /* vertices (x,y,z) */ + /* all points must be within radius 1 of the origin */ +#define T 0.9 + {T, T, T}, + {T, -T, -T}, + {-T, T, -T}, + {-T, -T, T}, + {-T, -T, -T}, + {-T, T, T}, + {T, -T, T}, + {T, T, -T}, +#undef T + } + }, + +}; + + + + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * Misc funcs. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +static void clamp(vec3_t v) +{ + int i; + + for (i = 0; i < 3; i ++) + if (v[i] > 360 || v[i] < -360) + v[i] = 0; +} + +/* track the mouse in a joystick manner : not perfect but it works */ +static void trackmouse(ModeInfo * mi) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + /* we keep static values (not per screen) for the mouse stuff: in general you have only one mouse :-> */ + static int max[2] = { 0, 0 }; + static int min[2] = { 0x7fffffff, 0x7fffffff }, center[2]; + Window r, c; + int rx, ry, cx, cy; + unsigned int m; + + (void) XQueryPointer(MI_DISPLAY(mi), MI_WINDOW(mi), + &r, &c, &rx, &ry, &cx, &cy, &m); + + if (max[0] < cx) + max[0] = cx; + if (min[0] > cx) + min[0] = cx; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < cy) + max[1] = cy; + if (min[1] > cy) + min[1] = cy; + center[1] = (max[1] + min[1]) / 2; + + if (fabs(center[0] - (float) cx) > 0.1 * (max[0] - min[0])) + sb->rot[0] -= ((center[0] - (float) cx) / (max[0] - min[0]) * 180.0f) / 200.0f; + if (fabs(center[1] - (float) cy) > 0.1 * (max[1] - min[1])) + sb->rot[1] -= ((center[1] - (float) cy) / (max[1] - min[1]) * 180.0f) / 200.0f;; + clamp(sb->rot); + + /* oops: can't get those buttons */ + if (m & Button4Mask) + sb->speed++; + if (m & Button5Mask) + sb->speed--; + +} + +/* initialise textures */ +static void inittextures(ModeInfo * mi) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + +#if defined( I_HAVE_XPM ) + if (do_texture) { + + glGenTextures(1, &sb->backid); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->backid); +#endif /* HAVE_GLBINDTEXTURE */ + + sb->btexture = xpm_to_ximage(MI_DISPLAY(mi), + MI_VISUAL(mi), + MI_COLORMAP(mi), + sball_bg); + if (!(sb->btexture)) { + (void) fprintf(stderr, "Error reading the background texture.\n"); + glDeleteTextures(1, &sb->backid); + do_texture = False; + sb->faceid = 0; /* default textures */ + sb->backid = 0; + return; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + sb->btexture->width, sb->btexture->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, sb->btexture->data); + check_gl_error("texture"); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glGenTextures(1, &sb->faceid); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->faceid); +#endif /* HAVE_GLBINDTEXTURE */ + + sb->ftexture = xpm_to_ximage(MI_DISPLAY(mi), + MI_VISUAL(mi), + MI_COLORMAP(mi), + sball); + if (!(sb->ftexture)) { + (void) fprintf(stderr, "Error reading the face texture.\n"); + glDeleteTextures(1, &sb->faceid); + sb->faceid = 0; + return; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + sb->ftexture->width, sb->ftexture->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, sb->ftexture->data); + check_gl_error("texture"); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else + { + sb->faceid = 0; /* default textures */ + sb->backid = 0; + } +#else /* !I_HAVE_XPM */ + do_texture = False; + sb->faceid = 0; /* default textures */ + sb->backid = 0; +#endif /* !I_HAVE_XPM */ +} + +static void drawSphere(ModeInfo * mi,int sphere_num) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + float x = polygons[object].v[sphere_num][0]; + float y = polygons[object].v[sphere_num][1]; + float z = polygons[object].v[sphere_num][2]; + int numMajor = 10; + int numMinor = 10; + float radius = sb->radius[sphere_num]; + double majorStep = (M_PI / numMajor); + double minorStep = (2.0 * M_PI / numMinor); + int i, j; + + glPushMatrix(); + glTranslatef(x, y, z); + + glColor4f(1, 1, 1, 1); + for (i = 0; i < numMajor; ++i) + { + double a = i * majorStep; + double b = a + majorStep; + double r0 = radius * sin(a); + double r1 = radius * sin(b); + GLfloat z0 = radius * cos(a); + GLfloat z1 = radius * cos(b); + + glBegin(MI_IS_WIREFRAME(mi) ? GL_LINE_STRIP: GL_TRIANGLE_STRIP); + for (j = 0; j <= numMinor; ++j) + { + double c = j * minorStep; + GLfloat x = cos(c); + GLfloat y = sin(c); + + glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius); + glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); + glVertex3f(x * r0, y * r0, z0); + + glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius); + glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); + glVertex3f(x * r1, y * r1, z1); + } + glEnd(); + } + + glPopMatrix(); +} + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * GL funcs. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +#ifndef STANDALONE +static void Reshape(ModeInfo * mi) +#else +void reshape_sballs(ModeInfo * mi, int width, int height) +#endif +{ + + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + int size = MI_SIZE(mi); + + /* Viewport is specified size if size >= MINSIZE && size < screensize */ + if (size <= 1) { + sb->WIDTH = MI_WIDTH(mi); + sb->HEIGHT = MI_HEIGHT(mi); + } else if (size < MINSIZE) { + sb->WIDTH = MINSIZE; + sb->HEIGHT = MINSIZE; + } else { + sb->WIDTH = (size > MI_WIDTH(mi)) ? MI_WIDTH(mi) : size; + sb->HEIGHT = (size > MI_HEIGHT(mi)) ? MI_HEIGHT(mi) : size; + } + glViewport((MI_WIDTH(mi) - sb->WIDTH) / 2, (MI_HEIGHT(mi) - sb->HEIGHT) / 2, sb->WIDTH, sb->HEIGHT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(55.0, (float)sb->WIDTH / (float) sb->HEIGHT, 1.0, 300.0); + + glMatrixMode(GL_MODELVIEW); + +} + +static void Draw(ModeInfo * mi) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + int sphere; + + if (do_trackmouse && !MI_IS_ICONIC(mi)) + trackmouse(mi); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glEnable(GL_DEPTH_TEST); + + /* move eyes */ + glTranslatef (-sb->eye[0], -sb->eye[1], -sb->eye[2]); + + /* draw background */ + if (do_texture) + { + glEnable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glColor3f(1, 1, 1); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->backid); +#endif /* HAVE_GLBINDTEXTURE */ + } + else + { + glColor3f(0, 0, 0); + } + glBegin(GL_QUAD_STRIP); + glNormal3f(0, 0, 1); glTexCoord2f(0,0); glVertex3f(8, 4.1, -4); + glNormal3f(0, 0, 1); glTexCoord2f(0,1); glVertex3f(8, -4.1, -4); + glNormal3f(0, 0, 1); glTexCoord2f(1,0); glVertex3f(-8, 4.1, -4); + glNormal3f(0, 0, 1); glTexCoord2f(1,1); glVertex3f(-8, -4.1, -4); + glEnd(); + + /* rotate the mouse */ + glRotatef(sb->rot[0], 1.0f, 0.0f, 0.0f); + glRotatef(sb->rot[1], 0.0f, 1.0f, 0.0f); + glRotatef(sb->rot[2], 0.0f, 0.0f, 1.0f); + + /* rotate the balls */ + glRotatef(sb->rotm[0], 1.0f, 0.0f, 0.0f); + glRotatef(sb->rotm[1], 0.0f, 1.0f, 0.0f); + glRotatef(sb->rotm[2], 0.0f, 0.0f, 1.0f); + + sb->rotm[0] += sb->speed; + sb->rotm[1] += -(sb->speed); + sb->rotm[2] += 0; + + /* draw the balls */ + if (do_texture) +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->faceid); +#endif /* HAVE_GLBINDTEXTURE */ + else + glEnable(GL_LIGHTING); + for (sphere=0;spherebtexture = (XImage*) NULL; + sb->ftexture = (XImage*) NULL; + } + + vinit(sb->eye ,0.0f, 0.0f, 6.0f); + vinit(sb->rot ,0.0f, 0.0f, 0.0f); + vinit(sb->rotm ,0.0f, 0.0f, 0.0f); + sb->speed = MI_CYCLES(mi); + + /* initialise object number */ + if (object == 0) + object = NRAND(MAX_OBJ); + if ((object == 0) || (object > MAX_OBJ)) + object = DEF_OBJECT_INDX; + object--; + + /* initialise sphere number */ + spheres = MI_COUNT(mi); + if (MI_COUNT(mi) > polygons[object].numverts) + spheres = polygons[object].numverts; + if (MI_COUNT(mi) < 1) + spheres = polygons[object].numverts; + /* initialise sphere radius */ + for(i=0; i < spheres;i++) + { +#if RANDOM_RADIUS + sb->radius[i] = ((float) LRAND() / (float) MAXRAND); + if (sb->radius[i] < 0.3) + sb->radius[i] = 0.3; + if (sb->radius[i] > 0.7) + sb->radius[i] = 0.7; +#else + sb->radius[i] = polygons[object].radius; +#endif + } + + if (MI_IS_DEBUG(mi)) { + (void) fprintf(stderr, + "%s:\n\tobject=%s\n\tspheres=%d\n\tspeed=%d\n\ttexture=%s\n", + MI_NAME(mi), + polygons[object].shortname, + spheres, + MI_CYCLES(mi), + do_texture ? "on" : "off" + ); + } + + glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); + glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); + glEnable(GL_LIGHT1); + + glClearColor(0, 0, 0, 0); +} + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * Xlock hooks. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +/* + *----------------------------------------------------------------------------- + * Initialize sballs. Called each time the window changes. + *----------------------------------------------------------------------------- + */ + +void init_sballs(ModeInfo * mi) +{ + sballsstruct *sb; + + if (sballs == NULL) { + if ((sballs = (sballsstruct *) calloc(MI_NUM_SCREENS(mi), + sizeof(sballsstruct))) == NULL) + return; + } + sb = &sballs[MI_SCREEN(mi)]; + + if ((sb->glx_context = init_GL(mi)) != NULL) { + +#ifndef STANDALONE + Reshape(mi); /* xlock mode */ +#else + reshape_sballs(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ +#endif + glDrawBuffer(GL_BACK); + Init(mi); + + } else { + MI_CLEARWINDOW(mi); + } +} + +/* + *----------------------------------------------------------------------------- + * Called by the mainline code periodically to update the display. + *----------------------------------------------------------------------------- + */ +void draw_sballs(ModeInfo * mi) +{ + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + sballsstruct *sb; + + if (sballs == NULL) + return; + sb = &sballs[MI_SCREEN(mi)]; + + MI_IS_DRAWN(mi) = True; + if (!sb->glx_context) + return; + + glXMakeCurrent(display, window, *(sb->glx_context)); + Draw(mi); +#ifndef STANDALONE + Reshape(mi); /* xlock mode */ +#else + reshape_sballs(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ +#endif + + glFinish(); + glXSwapBuffers(display, window); +} + + +/* + *----------------------------------------------------------------------------- + * The display is being taken away from us. Free up malloc'ed + * memory and X resources that we've alloc'ed. Only called + * once, we must zap everything for every screen. + *----------------------------------------------------------------------------- + */ + +void release_sballs(ModeInfo * mi) +{ + int screen; + + if (sballs != NULL) { + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { + sballsstruct *sb = &sballs[screen]; + if (sb->btexture) + { + glDeleteTextures(1,&sb->backid); + XDestroyImage(sb->btexture); + } + if (sb->ftexture) + { + glDeleteTextures(1,&sb->faceid); + XDestroyImage(sb->ftexture); + } + } + (void) free((void *) sballs); + sballs = (sballsstruct *) NULL; + } + FreeAllGL(mi); +} + +void change_sballs(ModeInfo * mi) +{ + sballsstruct *sb; + + if (sballs == NULL) + return; + sb = &sballs[MI_SCREEN(mi)]; + + if (!sb->glx_context) + return; + + /* initialise object number */ + if (object == 0) + object = NRAND(MAX_OBJ); + if ((object == 0) || (object > MAX_OBJ)) + object = DEF_OBJECT_INDX; + object--; + + /* correct sphere number */ + spheres = MI_COUNT(mi); + if (MI_COUNT(mi) > polygons[object].numverts) + spheres = polygons[object].numverts; + if (MI_COUNT(mi) < 1) + spheres = polygons[object].numverts; + + if (MI_IS_DEBUG(mi)) { + (void) fprintf(stderr, + "%s:\n\tobject=%s\n\tspheres=%d\n\tspeed=%d\n\ttexture=%s\n", + MI_NAME(mi), + polygons[object].shortname, + spheres, + MI_CYCLES(mi), + do_texture ? "on" : "off" + ); + } + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sb->glx_context)); + +} +#endif /* MODE_sballs */ diff --git a/hacks/glx/sballs.man b/hacks/glx/sballs.man new file mode 100644 index 00000000..d8de9918 --- /dev/null +++ b/hacks/glx/sballs.man @@ -0,0 +1,137 @@ +.de EX \"Begin example +.ne 5 +.if n .sp 1 +.if t .sp .5 +.nf +.in +.5i +.. +.de EE +.fi +.in -.5i +.if n .sp 1 +.if t .sp .5 +.. +.TH XScreenSaver 1 "03-Oct-01" "X Version 11" +.SH NAME +sballs - draws balls spinning like crazy in GL +.SH SYNOPSIS +.B sballs +[\-display \fIhost:display.screen\fP] [\-window] [\-root] +[\-visual \fIvisual\fP] [\-delay \fImicroseconds\fP] +[\-object \fIobject_number\fP] +[\-count \fInumber_of_spheres\fP] +[\-cycles \fIsphere_speed\fP] +[\-size \fIviewport_size\fP] +[\-texture] [\-no-texture] +[\-wireframe] [\-no-wireframe] +[\-trackmouse] [\-no-trackmouse] +[\-fps] [\-no-fps] +.SH DESCRIPTION +The \fIsballs\fP program draws an animation of balls spinning like crazy in GL. +.SH OPTIONS +.I sballs +accepts the following options: +.TP 8 +.B \-window +Draw on a newly-created window. This is the default. +.TP 8 +.B \-root +Draw on the root window. +.TP 8 +.B \-install +Install a private colormap for the window. +.TP 8 +.B \-visual \fIvisual\fP +Specify which visual to use. Legal values are the name of a visual class, +or the id number (decimal or hex) of a specific visual. +.TP 8 +.B \-fps +Display a running tally of how many frames per second are being rendered. +In conjunction with \fB\-delay 0\fP, this can be a useful benchmark of +your GL performance. +.TP 8 +.B \-object \fIobject_number\fP\fP +Specify how the spheres are grouped (forming an object). +Objects are: +.TP 10 +.B 1 +tetrahedron +.TP 10 +.B 2 +cube. This is the default. +.TP 10 +.B 3 +octahedron +.TP 10 +.B 4 +dodecahedron +.TP 10 +.B 5 +icosahedron +.TP 10 +.B 6 +plane +.TP 10 +.B 7 +pyramid +.TP 10 +.B 8 +star +.TP 8 +.B \-count \fInumber_of_spheres\fP\fP +Specify how much spheres are drawn in the selected object. +.TP 8 +.B \-size \fIviewport_size\fP\fP +Viewport of GL scene is specified size if greater than 32 and less than screensize. Default value is 0, meaning full screensize. +.TP 8 +.B \-count \fInumber_of_particles\fP\fP +Specify how much fire particles are drawn. A very special case is 0 +wich means that you get +.B rain +! +.TP 8 +.B \-texture +Show a textured background and spheres. This is the default. +.TP 8 +.B \-no\-texture +Disables texturing the animation. +.TP 8 +.B \-trackmouse +Let the mouse be a joystick to change the view of the animation. +This implies +.I \-no\-wander. +.TP 8 +.B \-no\-trackmouse +Disables mouse tracking. This is the default. +.TP 8 +.B \-wire +Draw a wireframe rendition of the spheres. +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH SEE ALSO +.BR X (1), +.BR xscreensaver (1) +.SH COPYRIGHT +Copyright \(co 2001 by Eric Lassauge. +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. No representations are made about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +The original code for this mode was written by +Mustata Bogdan (LoneRunner) +and can be found at http://www.cfxweb.net/lonerunner/ + +.SH AUTHOR +Mustata Bogdan (LoneRunner) +Eric Lassauge diff --git a/hacks/glx/starwars.c b/hacks/glx/starwars.c index 96c77753..5772d1eb 100644 --- a/hacks/glx/starwars.c +++ b/hacks/glx/starwars.c @@ -87,12 +87,17 @@ extern XtAppContext app; #ifdef USE_GL /* whole file */ +#include #include #include #include "glutstroke.h" #include "glut_roman.h" #define GLUT_FONT (&glutStrokeRoman) +#ifdef HAVE_UNAME +# include +#endif /* HAVE_UNAME */ + typedef struct { GLXContext *glx_context; @@ -258,15 +263,32 @@ launch_text_generator (sws_configuration *sc) if (!strcasecmp(oprogram, "(default)")) { + oprogram = FORTUNE_PROGRAM; + #ifdef __linux__ - static int done_once = 0; - struct stat st; - char *cmd = "cat /usr/src/linux/README"; - if (!(done_once++) && !stat (cmd+4, &st)) - oprogram = cmd; - else -#endif - oprogram = FORTUNE_PROGRAM; + { + static int done_once = 0; + if (!done_once) + { + struct utsname uts; + struct stat st; + done_once = 1; + if (uname (&uts) == 0) + { + static char cmd[200]; + char *s; + /* strip version at the first non-digit-dash-dot, to + lose any "SMP" crap at the end. */ + for (s = uts.release; *s; s++) + if (!isdigit(*s) && *s != '.' && *s != '-') + *s = 0; + sprintf (cmd, "cat /usr/src/linux-%s/README", uts.release); + if (!stat (cmd+4, &st)) + oprogram = cmd; + } + } + } +#endif /* __linux__ */ } program = (char *) malloc (strlen (oprogram) + 10); diff --git a/hacks/glx/tube.c b/hacks/glx/tube.c index 6632c29d..c11d5b30 100644 --- a/hacks/glx/tube.c +++ b/hacks/glx/tube.c @@ -151,28 +151,25 @@ tube_1 (GLfloat x1, GLfloat y1, GLfloat z1, int faces, Bool smooth, Bool wire, Bool cone_p) { - GLfloat length, angle, a, b, c; + GLfloat length, X, Y, Z; if (diameter <= 0) abort(); - a = (x2 - x1); - b = (y2 - y1); - c = (z2 - z1); + X = (x2 - x1); + Y = (y2 - y1); + Z = (z2 - z1); - length = sqrt (a*a + b*b + c*c); - angle = acos (a / length); + if (X == 0 && Y == 0 && Z == 0) + return; - glPushMatrix(); - glTranslatef(x1, y1, z1); - glScalef (length, length, length); + length = sqrt (X*X + Y*Y + Z*Z); - if (c == 0 && b == 0) - glRotatef (angle / (M_PI / 180), 0, 1, 0); - else - glRotatef (angle / (M_PI / 180), 0, -c, b); + glPushMatrix(); - glRotatef (-90, 0, 0, 1); - glScalef (diameter/length, 1, diameter/length); + glTranslatef(x1, y1, z1); + glRotatef (-atan2 (X, Y) * (180 / M_PI), 0, 0, 1); + glRotatef ( atan2 (Z, sqrt(X*X + Y*Y)) * (180 / M_PI), 1, 0, 0); + glScalef (diameter, length, diameter); /* extend the endpoints of the tube by the cap size in both directions */ if (cap_size != 0) @@ -186,6 +183,7 @@ tube_1 (GLfloat x1, GLfloat y1, GLfloat z1, unit_cone (faces, smooth, wire); else unit_tube (faces, smooth, wire); + glPopMatrix(); } diff --git a/hacks/glx/xpm-ximage.c b/hacks/glx/xpm-ximage.c index 615e0cd1..77210eca 100644 --- a/hacks/glx/xpm-ximage.c +++ b/hacks/glx/xpm-ximage.c @@ -1,5 +1,5 @@ /* xpm-ximage.c --- converts XPM data to an XImage for use with OpenGL. - * xscreensaver, Copyright (c) 1998, 2001 Jamie Zawinski + * xscreensaver, Copyright (c) 1998, 2001, 2002 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -18,11 +18,125 @@ #include #include -#include extern char *progname; -#ifdef HAVE_XPM /* whole file */ + +#if defined(HAVE_GDK_PIXBUF) + +# include +# include + + +/* Returns an XImage structure containing the bits of the given XPM image. + This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the + extra byte set to either 0xFF or 0x00 (based on the XPM file's mask.) + + The Display and Visual arguments are used only for creating the XImage; + no bits are pushed to the server. + + The Colormap argument is used just for parsing color names; no colors + are allocated. + + This is the gdk_pixbuf version of this function. + */ +static XImage * +xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap, + const char *filename, + char **xpm_data) +{ + GdkPixbuf *pb; + static int initted = 0; + + if (!initted) + { + gdk_pixbuf_xlib_init (dpy, DefaultScreen (dpy)); + xlib_rgb_init (dpy, DefaultScreenOfDisplay (dpy)); + initted = 1; + } + + pb = (filename + ? gdk_pixbuf_new_from_file (filename) + : gdk_pixbuf_new_from_xpm_data ((const char **) xpm_data)); + if (pb) + { + XImage *image; + int w = gdk_pixbuf_get_width (pb); + int h = gdk_pixbuf_get_height (pb); + guchar *row = gdk_pixbuf_get_pixels (pb); + int stride = gdk_pixbuf_get_rowstride (pb); + int chan = gdk_pixbuf_get_n_channels (pb); + int x, y; + + image = XCreateImage (dpy, visual, 32, ZPixmap, 0, 0, w, h, 32, 0); + image->data = (char *) malloc(h * image->bytes_per_line); + if (!image->data) + { + fprintf (stderr, "%s: out of memory (%d x %d)\n", progname, w, h); + exit (1); + } + + for (y = 0; y < h; y++) + { + int y2 = (h-1-y); /* Texture maps are upside down. */ + + guchar *i = row; + for (x = 0; x < w; x++) + { + unsigned long rgba = 0; + switch (chan) { + case 1: + rgba = ((0xFF << 24) | + (*i << 16) | + (*i << 8) | + *i); + i++; + break; + case 3: + rgba = ((0xFF << 24) | + (i[2] << 16) | + (i[1] << 8) | + i[0]); + i += 3; + break; + case 4: + rgba = ((i[3] << 24) | + (i[2] << 16) | + (i[1] << 8) | + i[0]); + i += 4; + break; + default: + abort(); + break; + } + XPutPixel (image, x, y2, rgba); + } + row += stride; + } + /* gdk_pixbuf_unref (pb); -- #### does doing this free colors? */ + + return image; + } + else if (filename) + { + fprintf (stderr, "%s: unable to load %s\n", progname, filename); + exit (1); + } + else + { + fprintf (stderr, "%s: unable to initialize builtin texture\n", progname); + exit (1); + } +} + + +#elif defined(HAVE_XPM) + + +#include +#include +#include #include #include @@ -39,18 +153,11 @@ bigendian (void) } -/* Returns an XImage structure containing the bits of the given XPM image. - This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the - extra byte set to either 0xFF or 0x00 (based on the XPM file's mask.) - - The Display and Visual arguments are used only for creating the XImage; - no bits are pushed to the server. - - The Colormap argument is used just for parsing color names; no colors - are allocated. +/* The libxpm version of this function... */ -XImage * -xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) +static XImage * +xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap, + const char *filename, char **xpm_data) { /* All we want to do is get RGB data out of the XPM file built in to this program. This is a pain, because there is no way (as of XPM version @@ -72,6 +179,18 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) memset (&xpm_image, 0, sizeof(xpm_image)); memset (&xpm_info, 0, sizeof(xpm_info)); + + if (filename) + { + xpm_data = 0; + if (! XpmReadFileToData ((char *) filename, &xpm_data)) + { + fprintf (stderr, "%s: unable to read XPM file %f\n", + progname, filename); + exit (1); + } + } + result = XpmCreateXpmImageFromData (xpm_data, &xpm_image, &xpm_info); if (result != XpmSuccess) { @@ -161,13 +280,39 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) } -#else /* !HAVE_XPM */ +#else /* !HAVE_XPM && !HAVE_GDK_PIXBUF */ -XImage * -xpm_to_ximage (char **xpm_data) +static XImage * +xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap, + const char *filename, char **xpm_data) { - fprintf(stderr, "%s: not compiled with XPM support.\n", progname); + fprintf(stderr, "%s: not compiled with XPM or Pixbuf support.\n", progname); exit (1); } #endif /* !HAVE_XPM */ + + +/* Returns an XImage structure containing the bits of the given XPM image. + This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the + extra byte set to either 0xFF or 0x00 (based on the XPM file's mask.) + + The Display and Visual arguments are used only for creating the XImage; + no bits are pushed to the server. + + The Colormap argument is used just for parsing color names; no colors + are allocated. + */ +XImage * +xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) +{ + return xpm_to_ximage_1 (dpy, visual, cmap, 0, xpm_data); +} + + +XImage * +xpm_file_to_ximage (Display *dpy, Visual *visual, Colormap cmap, + const char *filename) +{ + return xpm_to_ximage_1 (dpy, visual, cmap, filename, 0); +} diff --git a/hacks/glx/xpm-ximage.h b/hacks/glx/xpm-ximage.h index cfe6e0da..9877ba9d 100644 --- a/hacks/glx/xpm-ximage.h +++ b/hacks/glx/xpm-ximage.h @@ -1,5 +1,5 @@ /* xpm-ximage.h --- converts XPM data to an XImage for use with OpenGL. - * xscreensaver, Copyright (c) 1998 Jamie Zawinski + * xscreensaver, Copyright (c) 1998, 2002 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -24,5 +24,7 @@ are allocated. */ extern XImage *xpm_to_ximage (Display *, Visual *, Colormap, char **xpm_data); +extern XImage *xpm_file_to_ximage (Display *, Visual *, Colormap, + const char *filename); #endif /* _XPM_TEXTURE_H_ */ diff --git a/hacks/grav.c b/hacks/grav.c index eb243006..ccadc2a6 100644 --- a/hacks/grav.c +++ b/hacks/grav.c @@ -1,11 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * grav --- simulation of a planetary system. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* grav --- planets spinning around a pulsar */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)grav.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)grav.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1993 Greg Bowering +/*- + * Copyright (c) 1993 by Greg Boewring * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -19,25 +21,66 @@ static const char sccsid[] = "@(#)grav.c 4.00 97/01/01 xlockmore"; * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * - * Revision history: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 11-Jul-94: color version - * 06-Oct-93: by Greg Bowering + * Revision History: + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 11-Jul-1994: color version + * 06-Oct-1993: Written by Greg Bowering */ #ifdef STANDALONE -# define PROGCLASS "Grav" -# define HACK_INIT init_grav -# define HACK_DRAW draw_grav -# define grav_opts xlockmore_opts -# define DEFAULTS "*count: 12 \n" \ - "*delay: 10000 \n" \ - "*ncolors: 64 \n" -# define BRIGHT_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ +#define MODE_grav +#define PROGCLASS "Grav" +#define HACK_INIT init_grav +#define HACK_DRAW draw_grav +#define grav_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 12 \n" \ + "*ncolors: 64 \n" +#define BRIGHT_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ + +#endif /* STANDALONE */ + +#ifdef MODE_grav + +#define DEF_DECAY "False" /* Damping for decaying orbits */ +#define DEF_TRAIL "False" /* For trails (works good in mono only) */ + +static Bool decay; +static Bool trail; + +static XrmOptionDescRec opts[] = +{ + {(char *) "-decay", (char *) ".grav.decay", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+decay", (char *) ".grav.decay", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-trail", (char *) ".grav.trail", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+trail", (char *) ".grav.trail", XrmoptionNoArg, (caddr_t) "off"} +}; +static argtype vars[] = +{ + {(caddr_t *) & decay, (char *) "decay", (char *) "Decay", (char *) DEF_DECAY, t_Bool}, + {(caddr_t *) & trail, (char *) "trail", (char *) "Trail", (char *) DEF_TRAIL, t_Bool} +}; +static OptionStruct desc[] = +{ + {(char *) "-/+decay", (char *) "turn on/off decaying orbits"}, + {(char *) "-/+trail", (char *) "turn on/off trail dots"} +}; + +ModeSpecOpt grav_opts = +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct grav_description = +{"grav", "init_grav", "draw_grav", "release_grav", + "refresh_grav", "init_grav", (char *) NULL, &grav_opts, + 10000, -12, 1, 1, 64, 1.0, "", + "Shows orbiting planets", 0, NULL}; + +#endif #define GRAV -0.02 /* Gravitational constant */ #define DIST 16.0 @@ -80,35 +123,9 @@ static const char sccsid[] = "@(#)grav.c 4.00 97/01/01 xlockmore"; #define FLOATRAND(min,max) ((min)+(LRAND()/MAXRAND)*((max)-(min))) -#define DEF_DECAY "False" /* Damping for decaying orbits */ -#define DEF_TRAIL "False" /* For trails (works good in mono only) */ - -static Bool decay; -static Bool trail; - -static XrmOptionDescRec opts[] = -{ - {"-decay", ".grav.decay", XrmoptionNoArg, (caddr_t) "on"}, - {"+decay", ".grav.decay", XrmoptionNoArg, (caddr_t) "off"}, - {"-trail", ".grav.trail", XrmoptionNoArg, (caddr_t) "on"}, - {"+trail", ".grav.trail", XrmoptionNoArg, (caddr_t) "off"} -}; -static argtype vars[] = -{ - {(caddr_t *) & decay, "decay", "Decay", DEF_DECAY, t_Bool}, - {(caddr_t *) & trail, "trail", "Trail", DEF_TRAIL, t_Bool} -}; -static OptionStruct desc[] = -{ - {"-/+decay", "turn on/off decaying orbits"}, - {"-/+trail", "turn on/off trail dots"} -}; - -ModeSpecOpt grav_opts = { 4, opts, 2, vars, desc }; - typedef struct { - double P[DIMENSIONS], V[DIMENSIONS], A[DIMENSIONS]; - int xi, yi, ri; + double P[DIMENSIONS], V[DIMENSIONS], A[DIMENSIONS]; + int xi, yi, ri; unsigned long colors; } planetstruct; @@ -119,7 +136,7 @@ typedef struct { planetstruct *planets; } gravstruct; -static gravstruct *gravs = NULL; +static gravstruct *gravs = (gravstruct *) NULL; static void init_planet(ModeInfo * mi, planetstruct * planet) @@ -132,7 +149,7 @@ init_planet(ModeInfo * mi, planetstruct * planet) if (MI_NPIXELS(mi) > 2) planet->colors = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi))); else - planet->colors = MI_WIN_WHITE_PIXEL(mi); + planet->colors = MI_WHITE_PIXEL(mi); /* Initialize positions */ POS(X) = FLOATRAND(-XR, XR); POS(Y) = FLOATRAND(-YR, YR); @@ -200,7 +217,7 @@ draw_planet(ModeInfo * mi, planetstruct * planet) planet->xi = planet->yi = -1; /* Mask */ - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); Planet(gp->x, gp->y); if (trail) { XSetForeground(display, gc, planet->colors); @@ -221,8 +238,8 @@ init_grav(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - gravstruct *gp; unsigned char ball; + gravstruct *gp; if (gravs == NULL) { if ((gravs = (gravstruct *) calloc(MI_NUM_SCREENS(mi), @@ -231,28 +248,31 @@ init_grav(ModeInfo * mi) } gp = &gravs[MI_SCREEN(mi)]; - gp->width = MI_WIN_WIDTH(mi); - gp->height = MI_WIN_HEIGHT(mi); + gp->width = MI_WIDTH(mi); + gp->height = MI_HEIGHT(mi); gp->sr = STARRADIUS; - gp->nplanets = MI_BATCHCOUNT(mi); + gp->nplanets = MI_COUNT(mi); if (gp->nplanets < 0) { if (gp->planets) { (void) free((void *) gp->planets); - gp->planets = NULL; + gp->planets = (planetstruct *) NULL; } gp->nplanets = NRAND(-gp->nplanets) + 1; /* Add 1 so its not too boring */ } - if (!gp->planets) - gp->planets = (planetstruct *) calloc(gp->nplanets, sizeof (planetstruct)); + if (gp->planets == NULL) { + if ((gp->planets = (planetstruct *) calloc(gp->nplanets, + sizeof (planetstruct))) == NULL) + return; + } - XClearWindow(display, MI_WINDOW(mi)); + MI_CLEARWINDOW(mi); if (MI_NPIXELS(mi) > 2) gp->starcolor = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi))); else - gp->starcolor = MI_WIN_WHITE_PIXEL(mi); + gp->starcolor = MI_WHITE_PIXEL(mi); for (ball = 0; ball < (unsigned char) gp->nplanets; ball++) init_planet(mi, &gp->planets[ball]); @@ -268,11 +288,18 @@ draw_grav(ModeInfo * mi) Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); - gravstruct *gp = &gravs[MI_SCREEN(mi)]; register unsigned char ball; + gravstruct *gp; + + if (gravs == NULL) + return; + gp = &gravs[MI_SCREEN(mi)]; + if (gp->planets == NULL) + return; + MI_IS_DRAWN(mi) = True; /* Mask centrepoint */ - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); XDrawArc(display, window, gc, gp->width / 2 - gp->sr / 2, gp->height / 2 - gp->sr / 2, gp->sr, gp->sr, 0, 23040); @@ -311,12 +338,14 @@ release_grav(ModeInfo * mi) (void) free((void *) gp->planets); } (void) free((void *) gravs); - gravs = NULL; + gravs = (gravstruct *) NULL; } } void refresh_grav(ModeInfo * mi) { - /* Do nothing, it will refresh by itself */ + MI_CLEARWINDOW(mi); } + +#endif /* MODE_grav */ diff --git a/hacks/hopalong.c b/hacks/hopalong.c index 7b252e87..949c5b9f 100644 --- a/hacks/hopalong.c +++ b/hacks/hopalong.c @@ -1,11 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * hop --- real plane fractals. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* hop --- real plane fractals */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)hop.c 4.02 97/04/01 xlockmore"; +static const char sccsid[] = "@(#)hop.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1988-91 by Patrick J. Naughton. +/*- + * Copyright (c) 1991 by Patrick J. Naughton. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,54 +22,54 @@ static const char sccsid[] = "@(#)hop.c 4.02 97/04/01 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * Changes of David Bagley - * 24-Jun-97: EJK and RR functions stolen from xmartin2.2 - * Ed Kubaitis ejk functions and xmartin - * Renaldo Recuerdo rr function, generalized exponent version + * Changes in xlockmore distribution + * 01-Nov-2000: Allocation checks + * 24-Jun-1997: EJK and RR functions stolen from xmartin2.2 + * Ed Kubaitis ejk functions and xmartin + * Renaldo Recuerdo rr function, generalized exponent version * of the Barry Martin's square root function - * 10-May-97: jwz@jwz.org: ported from xlockmore 4.03a10 to be a - * standalone program and thus usable with xscreensaver - * (I threw away my 1992 port and started over.) - * 27-Jul-95: added Peter de Jong's hop from Scientific American - * July 87 p. 111. Sometimes they are amazing but there are a - * few duds (I did not see a pattern in the parameters). - * 29-Mar-95: changed name from hopalong to hop - * 09-Dec-94: added Barry Martin's sine hop - * - * (12-Aug-92: jwz@lucid.com: made xlock version run standalone.) - * - * Changes of Patrick J. Naughton - * 29-Oct-90: fix bad (int) cast. - * 29-Jul-90: support for multiple screens. - * 08-Jul-90: new timing and colors and new algorithm for fractals. - * 15-Dec-89: Fix for proper skipping of {White,Black}Pixel() in colors. - * 08-Oct-89: Fixed long standing typo bug in RandomInitHop(); - * Fixed bug in memory allocation in init_hop(); - * Moved seconds() to an extern. - * Got rid of the % mod since .mod is slow on a sparc. - * 20-Sep-89: Lint. - * 31-Aug-88: Forked from xlock.c for modularity. - * 23-Mar-88: Coded HOPALONG routines from Scientific American Sept. 86 p. 14. - * Hopalong was attributed to Barry Martin of Aston University - * (Birmingham, England) + * 10-May-1997: Compatible with xscreensaver + * 27-Jul-1995: added Peter de Jong's hop from Scientific American + * July 87 p. 111. Sometimes they are amazing but there are a + * few duds (I did not see a pattern in the parameters). + * 29-Mar-1995: changed name from hopalong to hop + * 09-Dec-1994: added Barry Martin's sine hop + * Changes in original xlock + * 29-Oct-1990: fix bad (int) cast. + * 29-Jul-1990: support for multiple screens. + * 08-Jul-1990: new timing and colors and new algorithm for fractals. + * 15-Dec-1989: Fix for proper skipping of {White,Black}Pixel() in colors. + * 08-Oct-1989: Fixed long standing typo bug in RandomInitHop(); + * Fixed bug in memory allocation in init_hop(); + * Moved seconds() to an extern. + * Got rid of the % mod since .mod is slow on a sparc. + * 20-Sep-1989: Lint. + * 31-Aug-1988: Forked from xlock.c for modularity. + * 23-Mar-1988: Coded HOPALONG routines from Scientific American Sept. 86 p. 14. + * Hopalong was attributed to Barry Martin of Aston University + * (Birmingham, England) */ + #ifdef STANDALONE -# define PROGCLASS "Hopalong" -# define HACK_INIT init_hop -# define HACK_DRAW draw_hop -# define HACK_FREE release_hop -# define hop_opts xlockmore_opts -# define DEFAULTS "*delay: 10000 \n" \ - "*count: 1000 \n" \ - "*cycles: 2500 \n" \ - "*ncolors: 200 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -# include "erase.h" -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ +#define MODE_hop +#define PROGCLASS "Hop" +#define HACK_INIT init_hop +#define HACK_DRAW draw_hop +#define hop_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 1000 \n" \ + "*cycles: 2500 \n" \ + "*ncolors: 200 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#include "erase.h" +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ + +#endif /* STANDALONE */ + +#ifdef MODE_hop #define DEF_MARTIN "False" #define DEF_POPCORN "False" @@ -95,56 +97,56 @@ static Bool sine; static XrmOptionDescRec opts[] = { - {"-martin", ".hop.martin", XrmoptionNoArg, (caddr_t) "on"}, - {"+martin", ".hop.martin", XrmoptionNoArg, (caddr_t) "off"}, - {"-popcorn", ".hop.popcorn", XrmoptionNoArg, (caddr_t) "on"}, - {"+popcorn", ".hop.popcorn", XrmoptionNoArg, (caddr_t) "off"}, - {"-ejk1", ".hop.ejk1", XrmoptionNoArg, (caddr_t) "on"}, - {"+ejk1", ".hop.ejk1", XrmoptionNoArg, (caddr_t) "off"}, - {"-ejk2", ".hop.ejk2", XrmoptionNoArg, (caddr_t) "on"}, - {"+ejk2", ".hop.ejk2", XrmoptionNoArg, (caddr_t) "off"}, - {"-ejk3", ".hop.ejk3", XrmoptionNoArg, (caddr_t) "on"}, - {"+ejk3", ".hop.ejk3", XrmoptionNoArg, (caddr_t) "off"}, - {"-ejk4", ".hop.ejk4", XrmoptionNoArg, (caddr_t) "on"}, - {"+ejk4", ".hop.ejk4", XrmoptionNoArg, (caddr_t) "off"}, - {"-ejk5", ".hop.ejk5", XrmoptionNoArg, (caddr_t) "on"}, - {"+ejk5", ".hop.ejk5", XrmoptionNoArg, (caddr_t) "off"}, - {"-ejk6", ".hop.ejk6", XrmoptionNoArg, (caddr_t) "on"}, - {"+ejk6", ".hop.ejk6", XrmoptionNoArg, (caddr_t) "off"}, - {"-rr", ".hop.rr", XrmoptionNoArg, (caddr_t) "on"}, - {"+rr", ".hop.rr", XrmoptionNoArg, (caddr_t) "off"}, - {"-jong", ".hop.jong", XrmoptionNoArg, (caddr_t) "on"}, - {"+jong", ".hop.jong", XrmoptionNoArg, (caddr_t) "off"}, - {"-sine", ".hop.sine", XrmoptionNoArg, (caddr_t) "on"}, - {"+sine", ".hop.sine", XrmoptionNoArg, (caddr_t) "off"} + {(char *) "-martin", (char *) ".hop.martin", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+martin", (char *) ".hop.martin", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-popcorn", (char *) ".hop.popcorn", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+popcorn", (char *) ".hop.popcorn", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-ejk1", (char *) ".hop.ejk1", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+ejk1", (char *) ".hop.ejk1", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-ejk2", (char *) ".hop.ejk2", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+ejk2", (char *) ".hop.ejk2", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-ejk3", (char *) ".hop.ejk3", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+ejk3", (char *) ".hop.ejk3", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-ejk4", (char *) ".hop.ejk4", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+ejk4", (char *) ".hop.ejk4", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-ejk5", (char *) ".hop.ejk5", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+ejk5", (char *) ".hop.ejk5", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-ejk6", (char *) ".hop.ejk6", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+ejk6", (char *) ".hop.ejk6", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-rr", (char *) ".hop.rr", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+rr", (char *) ".hop.rr", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-jong", (char *) ".hop.jong", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+jong", (char *) ".hop.jong", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-sine", (char *) ".hop.sine", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+sine", (char *) ".hop.sine", XrmoptionNoArg, (caddr_t) "off"} }; static argtype vars[] = { - {(caddr_t *) & martin, "martin", "Martin", DEF_MARTIN, t_Bool}, - {(caddr_t *) & popcorn, "popcorn", "Popcorn", DEF_POPCORN, t_Bool}, - {(caddr_t *) & ejk1, "ejk1", "EJK1", DEF_EJK1, t_Bool}, - {(caddr_t *) & ejk2, "ejk2", "EJK2", DEF_EJK2, t_Bool}, - {(caddr_t *) & ejk3, "ejk3", "EJK3", DEF_EJK3, t_Bool}, - {(caddr_t *) & ejk4, "ejk4", "EJK4", DEF_EJK4, t_Bool}, - {(caddr_t *) & ejk5, "ejk5", "EJK5", DEF_EJK5, t_Bool}, - {(caddr_t *) & ejk6, "ejk6", "EJK6", DEF_EJK6, t_Bool}, - {(caddr_t *) & rr, "rr", "RR", DEF_RR, t_Bool}, - {(caddr_t *) & jong, "jong", "Jong", DEF_JONG, t_Bool}, - {(caddr_t *) & sine, "sine", "Sine", DEF_SINE, t_Bool} + {(caddr_t *) & martin, (char *) "martin", (char *) "Martin", (char *) DEF_MARTIN, t_Bool}, + {(caddr_t *) & popcorn, (char *) "popcorn", (char *) "Popcorn", (char *) DEF_POPCORN, t_Bool}, + {(caddr_t *) & ejk1, (char *) "ejk1", (char *) "EJK1", (char *) DEF_EJK1, t_Bool}, + {(caddr_t *) & ejk2, (char *) "ejk2", (char *) "EJK2", (char *) DEF_EJK2, t_Bool}, + {(caddr_t *) & ejk3, (char *) "ejk3", (char *) "EJK3", (char *) DEF_EJK3, t_Bool}, + {(caddr_t *) & ejk4, (char *) "ejk4", (char *) "EJK4", (char *) DEF_EJK4, t_Bool}, + {(caddr_t *) & ejk5, (char *) "ejk5", (char *) "EJK5", (char *) DEF_EJK5, t_Bool}, + {(caddr_t *) & ejk6, (char *) "ejk6", (char *) "EJK6", (char *) DEF_EJK6, t_Bool}, + {(caddr_t *) & rr, (char *) "rr", (char *) "RR", (char *) DEF_RR, t_Bool}, + {(caddr_t *) & jong, (char *) "jong", (char *) "Jong", (char *) DEF_JONG, t_Bool}, + {(caddr_t *) & sine, (char *) "sine", (char *) "Sine", (char *) DEF_SINE, t_Bool} }; static OptionStruct desc[] = { - {"-/+martin", "turn on/off sqrt format"}, - {"-/+popcorn", "turn on/off Clifford A. Pickover's popcorn format"}, - {"-/+ejk1", "turn on/off ejk1 format"}, - {"-/+ejk2", "turn on/off ejk2 format"}, - {"-/+ejk3", "turn on/off ejk3 format"}, - {"-/+ejk4", "turn on/off ejk4 format"}, - {"-/+ejk5", "turn on/off ejk5 format"}, - {"-/+ejk6", "turn on/off ejk6 format"}, - {"-/+rr", "turn on/off rr format"}, - {"-/+jong", "turn on/off jong format"}, - {"-/+sine", "turn on/off sine format"} + {(char *) "-/+martin", (char *) "turn on/off sqrt format"}, + {(char *) "-/+popcorn", (char *) "turn on/off Clifford A. Pickover's popcorn format"}, + {(char *) "-/+ejk1", (char *) "turn on/off ejk1 format"}, + {(char *) "-/+ejk2", (char *) "turn on/off ejk2 format"}, + {(char *) "-/+ejk3", (char *) "turn on/off ejk3 format"}, + {(char *) "-/+ejk4", (char *) "turn on/off ejk4 format"}, + {(char *) "-/+ejk5", (char *) "turn on/off ejk5 format"}, + {(char *) "-/+ejk6", (char *) "turn on/off ejk6 format"}, + {(char *) "-/+rr", (char *) "turn on/off rr format"}, + {(char *) "-/+jong", (char *) "turn on/off jong format"}, + {(char *) "-/+sine", (char *) "turn on/off sine format"} }; ModeSpecOpt hop_opts = @@ -153,7 +155,7 @@ ModeSpecOpt hop_opts = #ifdef USE_MODULES ModStruct hop_description = {"hop", "init_hop", "draw_hop", "release_hop", - "refresh_hop", "init_hop", NULL, &hop_opts, + "refresh_hop", "init_hop", (char *) NULL, &hop_opts, 10000, 1000, 2500, 1, 64, 1.0, "", "Shows real plane iterated fractals", 0, NULL}; @@ -188,15 +190,15 @@ typedef struct { XPoint *pointBuffer; /* pointer for XDrawPoints */ } hopstruct; -static hopstruct *hops = NULL; +static hopstruct *hops = (hopstruct *) NULL; void init_hop(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - hopstruct *hp; double range; + hopstruct *hp; if (hops == NULL) { if ((hops = (hopstruct *) calloc(MI_NUM_SCREENS(mi), @@ -379,8 +381,11 @@ init_hop(ModeInfo * mi) hp->pix = NRAND(MI_NPIXELS(mi)); hp->bufsize = MI_COUNT(mi); - if (!hp->pointBuffer) - hp->pointBuffer = (XPoint *) malloc(hp->bufsize * sizeof (XPoint)); + if (hp->pointBuffer == NULL) { + if ((hp->pointBuffer = (XPoint *) malloc(hp->bufsize * + sizeof (XPoint))) == NULL) + return; + } MI_CLEARWINDOW(mi); @@ -392,13 +397,20 @@ init_hop(ModeInfo * mi) void draw_hop(ModeInfo * mi) { - hopstruct *hp = &hops[MI_SCREEN(mi)]; double oldj, oldi; - XPoint *xp = hp->pointBuffer; - int k = hp->bufsize; + XPoint *xp; + int k; + hopstruct *hp; - MI_IS_DRAWN(mi) = True; + if (hops == NULL) + return; + hp = &hops[MI_SCREEN(mi)]; + if (hp->pointBuffer == NULL) + return; + xp = hp->pointBuffer; + k = hp->bufsize; + MI_IS_DRAWN(mi) = True; hp->inc++; if (MI_NPIXELS(mi) > 2) { XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_PIXEL(mi, hp->pix)); @@ -536,12 +548,11 @@ release_hop(ModeInfo * mi) for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { hopstruct *hp = &hops[screen]; - if (hp->pointBuffer) + if (hp->pointBuffer != NULL) (void) free((void *) hp->pointBuffer); } - (void) free((void *) hops); - hops = NULL; + hops = (hopstruct *) NULL; } } @@ -550,3 +561,5 @@ refresh_hop(ModeInfo * mi) { MI_CLEARWINDOW(mi); } + +#endif /* MODE_hop */ diff --git a/hacks/hopalong.man b/hacks/hopalong.man index d36a360b..822f4e53 100644 --- a/hacks/hopalong.man +++ b/hacks/hopalong.man @@ -6,7 +6,7 @@ hopalong - draw real plane fractals [\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-install] [\-visual \fIvisual\fP] [\-ncolors \fIinteger\fP] [\-delay \fImicroseconds\fP] [\-cycles \fIinteger\fP] [\-count \fIinteger\fP] [\-jong] [\-no\-jong] [\-jong] [\-no\-sine] .SH DESCRIPTION -The \fIhopalong\fP program generates real plane fractals as described in +The \fIhop\fP program generates real plane fractals as described in the September 1986 issue of Scientific American. .SH OPTIONS .I hopalong diff --git a/hacks/ifs.c b/hacks/ifs.c index 3bccf872..111e5217 100644 --- a/hacks/ifs.c +++ b/hacks/ifs.c @@ -1,12 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * ifs --- Modified iterated functions system. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* ifs --- modified iterated functions system */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)ifs.c 4.02 97/04/01 xlockmore"; +static const char sccsid[] = "@(#)ifs.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1997 by Massimino Pascal (Pascal.Massimon@ens.fr) - * +/*- + * Copyright (c) 1997 by Massimino Pascal * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,33 +21,50 @@ static const char sccsid[] = "@(#)ifs.c 4.02 97/04/01 xlockmore"; * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * + * If this mode is weird and you have an old MetroX server, it is buggy. + * There is a free SuSE-enhanced MetroX X server that is fine. + * + * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing." + * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * Made it render into an offscreen bitmap and then copy - * that onto the screen, to reduce flicker. + * 01-Nov-2000: Allocation checks + * 10-May-1997: jwz@jwz.org: turned into a standalone program. + * Made it render into an offscreen bitmap and then copy + * that onto the screen, to reduce flicker. */ #ifdef STANDALONE -# define PROGCLASS "IFS" -# define HACK_INIT init_ifs -# define HACK_DRAW draw_ifs -# define ifs_opts xlockmore_opts -# define DEFAULTS "*delay: 20000 \n" \ - "*ncolors: 100 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -ModeSpecOpt ifs_opts = { - 0, NULL, 0, NULL, NULL }; +#define MODE_ifs +#define PROGCLASS "IFS" +#define HACK_INIT init_ifs +#define HACK_DRAW draw_ifs +#define ifs_opts xlockmore_opts +#define DEFAULTS "*delay: 20000 \n" \ + "*ncolors: 100 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_ifs + +ModeSpecOpt ifs_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct ifs_description = +{"ifs", "init_ifs", "draw_ifs", "release_ifs", + "init_ifs", "init_ifs", (char *) NULL, &ifs_opts, + 1000, 1, 1, 1, 64, 1.0, "", + "Shows a modified iterated function system", 0, NULL}; + +#endif -/*****************************************************/ /*****************************************************/ typedef float DBL; -typedef short int F_PT; +typedef int F_PT; /* typedef float F_PT; */ @@ -64,18 +82,6 @@ typedef short int F_PT; #define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) ) -/*****************************************************/ - -static int Max_Colors; -static ModeInfo *The_MI; -static F_PT Lx, Ly; -static int D; -static Display *display; -static GC gc; -static Window window; - -/*****************************************************/ - typedef struct Similitude_Struct SIMI; typedef struct Fractal_Struct FRACTAL; @@ -98,16 +104,15 @@ struct Fractal_Struct { DBL r_mean, dr_mean, dr2_mean; int Cur_Pt, Max_Pt; XPoint *Buffer1, *Buffer2; - Pixmap dbuf; /* jwz */ - GC dbuf_gc; + Pixmap dbuf; + GC dbuf_gc; }; -static FRACTAL *Root = NULL, *Cur_F; +static FRACTAL *Root = (FRACTAL *) NULL, *Cur_F; static XPoint *Buf; static int Cur_Pt; -/*****************************************************/ /*****************************************************/ static DBL @@ -146,11 +151,42 @@ Random_Simis(FRACTAL * F, SIMI * Cur, int i) } } +static void +free_ifs_buffers(FRACTAL *Fractal) +{ + if (Fractal->Buffer1 != NULL) { + (void) free((void *) Fractal->Buffer1); + Fractal->Buffer1 = (XPoint *) NULL; + } + if (Fractal->Buffer2 != NULL) { + (void) free((void *) Fractal->Buffer2); + Fractal->Buffer2 = (XPoint *) NULL; + } +} + + +static void +free_ifs(Display *display, FRACTAL *Fractal) +{ + free_ifs_buffers(Fractal); + if (Fractal->dbuf != None) { + XFreePixmap(display, Fractal->dbuf); + Fractal->dbuf = None; + } + if (Fractal->dbuf_gc != None) { + XFreeGC(display, Fractal->dbuf_gc); + Fractal->dbuf_gc = None; + } +} + /***************************************************************/ void init_ifs(ModeInfo * mi) { + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); int i; FRACTAL *Fractal; @@ -162,10 +198,7 @@ init_ifs(ModeInfo * mi) } Fractal = &Root[MI_SCREEN(mi)]; - if (Fractal->Max_Pt) { - free(Fractal->Buffer1); - free(Fractal->Buffer2); - } + free_ifs_buffers(Fractal); i = (NRAND(4)) + 2; /* Number of centers */ switch (i) { case 3: @@ -203,16 +236,19 @@ init_ifs(ModeInfo * mi) for (i = 0; i <= Fractal->Depth + 2; ++i) Fractal->Max_Pt *= Fractal->Nb_Simi; - Fractal->Buffer1 = (XPoint *) calloc(Fractal->Max_Pt, sizeof (XPoint)); - if (Fractal->Buffer1 == NULL) - goto Abort; - Fractal->Buffer2 = (XPoint *) calloc(Fractal->Max_Pt, sizeof (XPoint)); - if (Fractal->Buffer2 == NULL) - goto Abort; - + if ((Fractal->Buffer1 = (XPoint *) calloc(Fractal->Max_Pt, + sizeof (XPoint))) == NULL) { + free_ifs(display, Fractal); + return; + } + if ((Fractal->Buffer2 = (XPoint *) calloc(Fractal->Max_Pt, + sizeof (XPoint))) == NULL) { + free_ifs(display, Fractal); + return; + } Fractal->Speed = 6; - Fractal->Width = MI_WIN_WIDTH(mi); - Fractal->Height = MI_WIN_HEIGHT(mi); + Fractal->Width = MI_WIDTH(mi); + Fractal->Height = MI_HEIGHT(mi); Fractal->Cur_Pt = 0; Fractal->Count = 0; Fractal->Lx = (Fractal->Width - 1) / 2; @@ -221,46 +257,50 @@ init_ifs(ModeInfo * mi) Random_Simis(Fractal, Fractal->Components, 5 * MAX_SIMI); - Fractal->dbuf = XCreatePixmap(MI_DISPLAY(mi), MI_WINDOW(mi), - Fractal->Width, Fractal->Height, 1); - if (Fractal->dbuf) - { - XGCValues gcv; +#ifndef NO_DBUF + if (Fractal->dbuf != None) + XFreePixmap(display, Fractal->dbuf); + Fractal->dbuf = XCreatePixmap(display, window, + Fractal->Width, Fractal->Height, 1); + /* Allocation checked */ + if (Fractal->dbuf != None) { + XGCValues gcv; + gcv.foreground = 0; gcv.background = 0; + gcv.graphics_exposures = False; gcv.function = GXcopy; - Fractal->dbuf_gc = XCreateGC(MI_DISPLAY(mi), Fractal->dbuf, - GCForeground|GCBackground|GCFunction, - &gcv); - XFillRectangle(MI_DISPLAY(mi), Fractal->dbuf, - Fractal->dbuf_gc, 0,0, Fractal->Width, Fractal->Height); - - XSetBackground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi)); - XSetFunction(MI_DISPLAY(mi), MI_GC(mi), GXcopy); - } - - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); - return; - - Abort: - if (Fractal->Buffer1 != NULL) - free(Fractal->Buffer1); - if (Fractal->Buffer2 != NULL) - free(Fractal->Buffer2); - Fractal->Buffer1 = NULL; - Fractal->Buffer2 = NULL; - Fractal->Max_Pt = 0; - return; + + if (Fractal->dbuf_gc != None) + XFreeGC(display, Fractal->dbuf_gc); + if ((Fractal->dbuf_gc = XCreateGC(display, Fractal->dbuf, + GCForeground | GCBackground | GCGraphicsExposures | GCFunction, + &gcv)) == None) { + XFreePixmap(display, Fractal->dbuf); + Fractal->dbuf = None; + } else { + XFillRectangle(display, Fractal->dbuf, + Fractal->dbuf_gc, 0, 0, Fractal->Width, Fractal->Height); + XSetBackground(display, gc, MI_BLACK_PIXEL(mi)); + XSetFunction(display, gc, GXcopy); + } + } +#endif + MI_CLEARWINDOW(mi); + + /* don't want any exposure events from XCopyPlane */ + XSetGraphicsExposures(display, gc, False); + } /***************************************************************/ -#ifndef __GNUC__ -# undef inline -# define inline /* */ +/* Should be taken care of already... but just in case */ +#if !defined( __GNUC__ ) && !defined(__cplusplus) && !defined(c_plusplus) +#undef inline +#define inline /* */ #endif - static inline void Transform(SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y) { @@ -283,7 +323,7 @@ Transform(SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y) /***************************************************************/ static void -Trace(F_PT xo, F_PT yo) +Trace(FRACTAL * F, F_PT xo, F_PT yo) { F_PT x, y, i; SIMI *Cur; @@ -291,22 +331,26 @@ Trace(F_PT xo, F_PT yo) Cur = Cur_F->Components; for (i = Cur_F->Nb_Simi; i; --i, Cur++) { Transform(Cur, xo, yo, &x, &y); - Buf->x = Lx + (x * Lx / (UNIT * 2)); - Buf->y = Ly - (y * Ly / (UNIT * 2)); + Buf->x = F->Lx + (x * F->Lx / (UNIT * 2)); + Buf->y = F->Ly - (y * F->Ly / (UNIT * 2)); Buf++; Cur_Pt++; - if (D && ((x - xo) >> 4) && ((y - yo) >> 4)) { - D--; - Trace(x, y); - D++; + if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) { + F->Depth--; + Trace(F, x, y); + F->Depth++; } } } static void -Draw_Fractal(FRACTAL * F) +Draw_Fractal(ModeInfo * mi) { + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + FRACTAL *F = &Root[MI_SCREEN(mi)]; int i, j; F_PT x, y, xo, yo; SIMI *Cur, *Simi; @@ -328,9 +372,6 @@ Draw_Fractal(FRACTAL * F) Cur_Pt = 0; Cur_F = F; Buf = F->Buffer2; - Lx = F->Lx; - Ly = F->Ly; - D = F->Depth; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { xo = Cur->Cx; yo = Cur->Cy; @@ -338,43 +379,36 @@ Draw_Fractal(FRACTAL * F) if (Simi == Cur) continue; Transform(Simi, xo, yo, &x, &y); - Trace(x, y); + Trace(F, x, y); } } /* Erase previous */ - if (F->Cur_Pt) { - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(The_MI)); - if (F->dbuf) /* jwz */ - { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + if (F->dbuf != None) { XSetForeground(display, F->dbuf_gc, 0); -/* XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer1, F->Cur_Pt, - CoordModeOrigin); */ - XFillRectangle(display, F->dbuf, F->dbuf_gc, 0, 0, - F->Width, F->Height); - } - else - XDrawPoints(display, window, gc, F->Buffer1, F->Cur_Pt, - CoordModeOrigin); + /* XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer1, F->Cur_Pt, + CoordModeOrigin); */ + XFillRectangle(display, F->dbuf, F->dbuf_gc, 0, 0, + F->Width, F->Height); + } else + XDrawPoints(display, window, gc, F->Buffer1, F->Cur_Pt, CoordModeOrigin); } - if (Max_Colors < 2) - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(The_MI)); + if (MI_NPIXELS(mi) < 2) + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); else - XSetForeground(display, gc, MI_PIXEL(The_MI, F->Col % Max_Colors)); + XSetForeground(display, gc, MI_PIXEL(mi, F->Col % MI_NPIXELS(mi))); if (Cur_Pt) { - if (F->dbuf) - { - XSetForeground(display, F->dbuf_gc, 1); - XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer2, Cur_Pt, - CoordModeOrigin); - } - else - XDrawPoints(display, window, gc, F->Buffer2, Cur_Pt, CoordModeOrigin); + if (F->dbuf != None) { + XSetForeground(display, F->dbuf_gc, 1); + XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer2, Cur_Pt, + CoordModeOrigin); + } else + XDrawPoints(display, window, gc, F->Buffer2, Cur_Pt, CoordModeOrigin); } - - if (F->dbuf) - XCopyPlane(display, F->dbuf, window, gc, 0,0,F->Width,F->Height,0,0, 1); + if (F->dbuf != None) + XCopyPlane(display, F->dbuf, window, gc, 0, 0, F->Width, F->Height, 0, 0, 1); F->Cur_Pt = Cur_Pt; Buf = F->Buffer1; @@ -387,17 +421,15 @@ void draw_ifs(ModeInfo * mi) { int i; - FRACTAL *F; DBL u, uu, v, vv, u0, u1, u2, u3; SIMI *S, *S1, *S2, *S3, *S4; + FRACTAL *F; - The_MI = mi; - display = MI_DISPLAY(mi); - window = MI_WINDOW(mi); - gc = MI_GC(mi); - Max_Colors = MI_NPIXELS(mi); - + if (Root == NULL) + return; F = &Root[MI_SCREEN(mi)]; + if (F->Buffer1 == NULL) + return; u = (DBL) (F->Count) * (DBL) (F->Speed) / 1000.0; uu = u * u; @@ -423,7 +455,9 @@ draw_ifs(ModeInfo * mi) S->A2 = u0 * S1->A2 + u1 * S2->A2 + u2 * S3->A2 + u3 * S4->A2; } - Draw_Fractal(F); + MI_IS_DRAWN(mi) = True; + + Draw_Fractal(mi); if (F->Count >= 1000 / F->Speed) { S = F->Components; @@ -459,21 +493,14 @@ draw_ifs(ModeInfo * mi) void release_ifs(ModeInfo * mi) { - int i; + if (Root != NULL) { + int screen; - if (Root == NULL) - return; - - for (i = 0; i < MI_NUM_SCREENS(mi); ++i) { - if (Root[i].Buffer1 != NULL) - free(Root[i].Buffer1); - if (Root[i].Buffer2 != NULL) - free(Root[i].Buffer2); - if (Root[i].dbuf) - XFreePixmap(MI_DISPLAY(mi), Root[i].dbuf); - if (Root[i].dbuf_gc) - XFreeGC(MI_DISPLAY(mi), Root[i].dbuf_gc); + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_ifs(MI_DISPLAY(mi), &Root[screen]); + (void) free((void *) Root); + Root = (FRACTAL *) NULL; } - free(Root); - Root = NULL; } + +#endif /* MODE_ifs */ diff --git a/hacks/images/ground.xpm b/hacks/images/ground.xpm new file mode 100644 index 00000000..6f654af1 --- /dev/null +++ b/hacks/images/ground.xpm @@ -0,0 +1,227 @@ +/* XPM */ +static char *ground[] = { +/* width height ncolors chars_per_pixel */ +"128 128 92 1", +/* colors */ +" c #B4A589", +". c #C4B19C", +"X c #C4AD9C", +"o c #AC896A", +"O c #BCA994", +"+ c #BCA594", +"@ c #8C7451", +"# c #A49579", +"$ c #604929", +"% c #9C8D71", +"& c #AC9D84", +"* c #AC9984", +"= c #CBB195", +"- c #553D21", +"; c #AC9973", +": c #AC9573", +"> c #AC9173", +", c #BC987C", +"< c #BCAE93", +"1 c #6C5434", +"2 c #8B7659", +"3 c #CCB59C", +"4 c #947D5B", +"5 c #C4B194", +"6 c #94795B", +"7 c #C4AD94", +"8 c #C4A994", +"9 c #BCA98C", +"0 c #C4A48A", +"q c #8C7153", +"w c #BCA58C", +"e c #AD917A", +"r c #BCA18C", +"t c #B4A184", +"y c #B49D84", +"u c #AC997C", +"i c #AC957C", +"p c #745D3B", +"a c #A48D74", +"s c #A48974", +"d c #CBBBA4", +"f c #796143", +"g c #947D64", +"h c #D7C2A9", +"j c #8C795C", +"k c #A48963", +"l c #7B694B", +"z c #7C654C", +"x c #C4A98C", +"c c #BCA584", +"v c #BCA184", +"b c #B49D7C", +"n c #B4997C", +"m c #A4916C", +"M c #8F7E5E", +"N c #A48D6C", +"B c #A4896C", +"V c #D3BDA4", +"C c #A18569", +"Z c #9C8164", +"A c #9C7D64", +"S c #826C51", +"D c #846749", +"F c #DFCDB6", +"G c #D4B89E", +"H c #9C8567", +"J c #665032", +"K c #846D4C", +"L c #CCAE96", +"P c #947455", +"I c #7C6544", +"U c #A3987E", +"Y c #C4A584", +"T c #A49175", +"R c #765F41", +"E c #948165", +"W c #B89E85", +"Q c #D4BEA7", +"! c #B4A98E", +"~ c #837154", +"^ c #9C7D5C", +"/ c #AC8D6F", +"( c #957955", +") c #CCB798", +"_ c #AC9E7F", +"` c #6F5839", +"' c #A49184", +"] c #C4AC8C", +"[ c #C2B397", +"{ c #9C896B", +"} c #B4967C", +"| c None", +/* pixels */ +"p`Rpq4n}v6PkgK4by3}v=Y>nj9ZJ=n42Zv~DHBqS~SZl`jBHxvL=HZ=337kn@H@nZK`DJ$$fgb9=dV7hFFHExcn:LAv5yT5d7=@utB:ir>:cynnv>k", +"``zfIZ}}n^^oqjZvnwi>LLvvgnHR#d9+3VcSJ$~Ey}v:BZHn@SZHSSSIE@1qBBLn0x:{c7.xk>{^KN4qRSpJJ16uc3V)8dFF*i7YnHvkbvyyv57x6NuNnyv:Tt }vvo^", +"pD(KSNk>6:ooHuy]8 hbTlf~l4,obvN6qP4~zRlf1RqKHnE}bby=vttyioB:@kBk}4HgHp$jv{]5btyFFFd=i:IH/Wty7wyLL>b9wbwxvNu]TbLN@", +"IDiNj^6qD]^(geVGGh9K1fbN>46S@Miel{9t22Kffk/>b>@Dz>zpD~lR$R:w H6>>vccnNBs>}}Zn/vn>n>bqKK:R@:4ga&XQd3bN@H/6G7=Gwiiinvxnay{jNytKb>@", +"J1Bn>{KqpHnKpl>9=3nBD$2x]nn{T{N4STch3 q2fP@pk6B@RDK2{4fR11Z:aEua>b>BEZTkBi=aki:>>>:}N>@S22ZEH6{ONZHgKK:PbN}}4BB:TnT:6>46D({xv:n]w_ay35Hl6RN{;#yvtwuy}9b tn#tNqH@", +"B:4BH>>6Hxt>qfDeB/DBR$HyaeBnxxBlp@$J@R>5*Tu:HZ4Z~KEj24Ma{Nz11RIRH/qKS6tkmxknv>5nntm4g(B>jHN>xy5wc}y .33Hc>@4>N{:59uuHae53{:4HZHa", +"HHAZm;>}(xhnv6ayv}I$R$67BNBHvntkI_41p`Rj577yBK@4t@lqSH>6qqbHR11$qNqD@:>kZbZ^3vnAbT>>f1pHyvHS>Zxx]x7V>NHv:gqp6x3LB073GcI$$RH:i}B>yVVu3G]ETE4%w5.5BRfnTff1p~K>q>^K:K1D^$$JKnkiv}Cv7nBg>xw`$-DBBqR6Kg=738Oxt33>v/:6442&5euwBeEEH~Zg6}H", +"Z>>6uTBK`DBwLy73=Gh:1-1KNNn>ivhF h5hTt yatx9=t6K(Hll1JJ`B^Z(KvHl@HJ$$f/BvvoBB>7>P6w]D1$pHHCD^^Dniy3 7ivw/cbcmB{Bw3tb7uy*jHgZ^4BZ", +"ZgbH`I46IKz1{n3V9bGFvPKki>nc87FF<5=33DqS~DflI4^/Bfk4HDPl@@pPpqNCKCk}HH6H/opSfZ^CB6^`(Rzt35bS4BNBB57n9yrt}xi6ib{BiB6K^", +"{N#vlIpIKZnjPz>dbn6:]b>:xw:wh3hFh373w+553x=xw>Ck6IDZJ-fS6K}(1KHZNBi4:PqI1Rv^^Z>Z]vHHnBZZHA`qR1J`~12it3Nc7}niTrHE3.nBvvtT37P:vB1I", +"KK4;9TiiSKbx:DIjb>1pbbb05=iEd3d333937w09>Hw3vnkAZz(DR`1{f$$1p$>oB:i^ZZHkq1CP^kCK>xvcv>ovuB6f1J1`jqaOwysqux9NKJ]3HjtyaH978T7d>6}H@RpPP/N6tnyvyq^aH4SpJJK4A{a{2bDKNv6H4jS-pg6Zlj12:>gy{z$", +"tBH6Ee4qaavN=/4`;x=]3.c#bn3V d..3FOZrcs]VcBv9LnbZg^R`1fBfRlD6qK^(KZ64>q1RDDp^ko0y{Nuyv>uE{:EK11f6Huyug@@ff4DR`j~~1`Jl~5NynauVV#E", +"VVX0 u BZB5yvnH@4Nw3<.d55nvFXdFFdhh HgTc5h]G.0>ZNH>}HNq}~DIjZoNb61KBNayKpJ`1Ko2nwwycBw*yeHttHKRI2EvOuyuyH4aT%giTi{%~6zT{*}%ET&hF", +" w3wu#HDR>wwxBEi9]7.&5&8bfHXFFFQ3Fd>:Tw=uHH3wYB(o}k{BRHkKRD/>64kf$l@6c7amNf-`1D%9n:>{MKEiwbEw96~ _T.wwVhQ&E6aeygH%TT&", +"Uaw.VOaHf`gvwcB:]5vNcuuaH2gEcnK{y%j O* rr3hVO#%HNeg2a_E{", +"3ii*8.X.TpzAyyyn3cZB4k@1jjRjgOhhy FFQycEn3xBn:H/}vfj~ZKK~Dl2H6T< 2JKfq2quBZN@{BE{awhaDTNTHzIiEkH4ENyynqREd.XO%T v>v5xiiHs4jgE9T&", +"<+%gTO3d5hV XwysTy>4Zc=tvSEZw9>@DIp1`Tuc96SEyr5:tj*O#w:*uOHST=76EgjquZii ", +"&a%Uy.Oh3*u w*#2Tub@@>vm^>;nHahh.*3XX5w V7Gn]7G3Byn=b>HKS2Z6:>D~a hFVX7 ytT643ZBpJR4n{$-1p--RKBNZj`Z6 %&gE{iHj~jBNqgyir#* ~4> 3&", +"u&&.U T&5BHty<7y7t9_NmHbZ(ba>>r.V3.9i{;gi6y=cEHaq~m>wHHIMDS66gHTwH%%yO%#*%%HE%MEiTau !..dgzb *%", +"&!.Q& .7x5H0w<..=5ut3T~B(~vvaws5 .ydd7TmBvx]3:1lKpZmcwZl#Df2jql~]>&7 &t73X.y--l^KH:9GVPffJ$-----$1Rs~z<%Eyh+.i&%@E2SETXd..U~2Tt*", +"%&OX.&nwyGv w 9<7iE{3={uvjK>f6{& X< FFtv4kb=d]@1{lJDjjzl&O~HHEqD4Zy!d+Ei.dVdj4{{IayL=x^P,P1-$$$----`61j*TayyTSRRHEiT%%9&& !%%7*u", +"j% .7Ow7sar5Oy**9y:j@9]Gn{qu:y3w.XFr]Y^>k@1R%2$---$R$`Z2zagi#S@l2T.%2%STXdyxwFddVh5Ua95Bv}4 5v~bkkkg{Sg*w igzqJPA~~zah.3&dVEahhdd7tn3=k:}>KI:@$---JSzSgl14q&iH#`Rz%HzRJEw%&jz% ", +"'%E OX3.3 y*%23..uabp`B@cacmyBn8%T3V33yvHH>6%iaT]]YB]wnn9v3V56DJIP6EMEdT+7w3a2h.hFFh*u3Gxv=x`B>2pRERZka~f2j~#B{cZH$$-$JRJ~jT*T>i", +"%E%*.XVV8 HTgetiy3i>fJHqut]Tjz{t*U33HZgpD/{E2E>u5 H:v{wyvy9Vv6$$q6Jf{#Q7&9L7VBdd..hhbjg)=uxVZB3]tgnj62kBlq6yyt(4wcl----`$JE%ua T", +".U&.U. .79HgH@Z6IttvBo4fZHO3%j.Vb=tcnnBv+0cDJ>wlS 33QiEwsc93V.X 3iHRq3yhh3=.359<]a9T]vB$$zNcnT>l$$-J~@g{eiatH", +"QhXX 7tO3Ow4qR^^pZ~Bnnbq%gH3!Z .da5x# w>H2~%dr>LK(pI>nHHBDnVXGLk4x39+V3w3<3yZu3 T!7.<=BpBn'OO<7.3V9Vt.~KxcR-$gSi7y={$f4aj~2THgj#", +"OdO hdddh3rH6qk^6nc/nvhcvyedOe yFhXtXd*itETyOB>v4D$J@}]9aR6wdVt=y0rOd38wyE>{JytZ--$R6r3FxDPyir TT*&aa", +"%TO*T.dd.d3vNMPKIlvnb=GtS6N&ywr>wwZq%tE27yT8uKvx3:@`>Hv3]BjN.5.3dy*8]hy%3V7na6H%#ruy3ek$--127nB{xaZB1$`zlZbZ@IN;uy 3_a9b wER_3t>", +"wegqS%i<7.7.i@@K2RzjeHc94i9{TB3O{g4R1JRB{iTN{k6KG]B@n}3VhVu", +"cBzzz2Tr 7wy:qRfNSgitq;xgZxeTZwxaZ@I1$JEZ:NEAHPK.=ukv}G.hh35jgSTgHZqn3F3t>HD`6pzpDD1:H53($RKn>Sp6BBZIJ-16z$g/k=:Ziy7wt.dy#*.H&>{", +"K1JJ$~O>{HyETmDf]t9aBZH=NDgHZgZO46^@@Ip6{v4DIDN}i3LvYwh3dhd7bB6ZHHN@DaV3ywY>pKJ`pB^Kn>Th=kK1`6KDvcNnDJ-1I6pJDfZq@qa%Hsyy *iyTZ3t", +"bmI$`qvHqfgkNu:4D(I1fDq>b{6R`HEtqJ(>av9Vct=m^v0tjTnHv>dFQhFc]:Yv80yCqKzq@{Y}K-$pJDfKn=]55VnI$$pRv,n^>(@Dp-1$---`@(Ei+T4ZHBzq@p y", +"=FvPDfqkKD>;>t=tf^Lvv]vxDn3.h+ 5{qKPqE=a21Jzq$p4o^KRRl@KIR@Zi7.=;tg:`JIkH4Z^P^K^41--J$ZHyXw6@RzD66I>j", +"w==Lk1$1Rq]xN{w].tG9@/`D^vvx(KNvat>KIjDD{vv(p>HB{cGYqyhQd7uN@f`q47yH1-pP--$K>:{lplIHz~t3@nxiFh7BffRpZ@>K:vo>zR2I``6}yu^S1zp6KP9=", +"Tw3Vx>4D4R6Nv7y73{t3^6fpDNmN^q^3>B3:jR1`@PNcB}NkNy7wZqMH7Vw3wg6Z2TVwuK--$$1Kvx64ERD9t5T>6@cn5XbwY^pKkfBKN=R4Bidv^1RqyeqDpRlKIR@>", +"_ acxiV=xgZ:tr95nE@vc@(plgB:k}6kn=xw:HH=LVc~<9c7x6:yGvBp$I:q^Z26{GLc9v@6bE:PZ$-`$fPDTh39V9{q4f$K@K@^HKfK4>K4(>6$z4Bf~Iu>jbMqf>cH4j1K={w", +"j{K@y_rTBb]vwbE6HfKkn,x]ynyykNv:FVhV% wwc04nyV5kD$$D`1@@6Rxx3x]Bq4Rq`A$-$JPkfghhnYTWx=;q]GVFFFhd39>H>vxwFvD$--pqH6B4vnQ.0>4S$$qT6J$pP^p14Awydh{5=ZNpK6@^>6Hkv>vv^^{Tg@IEjjbAB{n>Bu{H#:@R@f", +"`1q@~ZE2lEty4tntB4DK~>n}nHu5Z4=GwFhFdh.cyi93h5FG@p$$6v=AI4lSBTa>4Rl1Pn0}>ZP^4KpDy53G2K3nIPJpKD4iT:=v/vb^ZH{qDK2{xiHKEHayVd7F]U{N", +":@k1(@~g4: tKN@H6:Jp(H}oZii TZ4=#Fh.9 35rt5hdV)V5:Hnt{=>mm`p1$JREk4Ipwn0E}ooZEDqR{nM`lv=kkll@Kn99bib=vy4D$1-f1pJj/@~@DJD>*x9d3;V", +"nun:2DyiTdVy#VwtcFh9353Fhb>vK(Z6>@q~l$I@6k4DZoAp7^Cev>qJ`5cppH;nvxv>iNk4BiauO3x:{1-$@#SHwZDlK$$RK _3V@a", +"==@^pRHH:wT73cNk`Dn/NNnY>;4K&7::;B3VbNdrg@vF]V797c}^=H4@RKHb5tZHBBuv^DRDRH0Zfs]:Ipitlpp@//w}8]>>q63h ayVWBkPKE97tv7rbc2fI@gw_{lK", +":x}bn>Hbttvy3L]L@DvxH:YvkN1p>iau]]a99t37cq(vxn:>qn=,nL>;wOB>y7h9e:vBa4J$$S4PfD@b1JRKIpfDin}nNn5]CqhF.ui8c>IRJ$EFODu7eu9NT6JKx{16", +"qkB,xi=xbi:vV3hVnDkL=wvv>vP@it B:t:Nmvbq;N>Ax9icBnxV==t=t0T6EHtr]07w}9Z`l9THPIzbZf-$H$JlkbB4uawwNq7d.waE7=:6J$JOyf{vqB9w#{Sz9cD1", +"I6>>vix7vNEahVGhc^Dnwwbc>]N> 75N4Nng^H;@^4qq>0]vvxx3G3w=rt;:4~Bu7v8xwV]g6G3tkKZb:I-$H$pf2B^Z:Ttt}q&XV7~`uGtbf1-ESJ@a6ax7ni@l>:Dp", +"fD}v:nsy7vKKi3u3V7By9=B:}cxvwMEN46cZDI:Tl$--(Bvbv]dw)3iyv>nxt# tVwvt3hhY1uFx=BrnnP1$pPo@(ko>bnN7>42%8NBl`HZybR--J(H4k6>wa{qKIqlp", +"1Kk}CHnex5BqfT3wdhwnitKE@k/HE{TNv}v}a^Z>lJ--pfn=rc3573yyv4P47Vww88.73dht$zyV3>}3]Y{D@nB4:vx/kp1Abxzj*w3t$J1quy--`b56>6fk>{qDJpk$", +"AK@kZ:n:B0nnKfutr3.wkT{smj(Ei.bl^}}vc:@JDKH2(>>vL=0777VV3cNDP*5yv95dhdhG@```ZYwV73=>pN=btxnk:p$4(Tw.Bf$H3]ovvyeB:c9tV]t;xu6jju}awe9y*7.&:DDpkFhVhYKpcwrnvkL:K4ND{y3au5]c>nRJ--Htbu6qq6N(p1IpZ}", +"vuw]:>:HbvLb]]c:<= T>Ni 3bHan.tH1(DRk^LP-IxY^>Z5=}HZTZ=xG]yhy{z@>iA~Bvss 7V3NRJEV*VV9Evc3>:>vYt0P1$1yw@~Z61n4f`zj{yNn:KILbzzu:Bv", +".54a~.blKvH6(^opD>c`I4c:n>cN6b9xy2yd3uNR>fjDZ0.8v3hxNp1t3w3FX>e}~/K(KRBwH$-qbba{l$KNMzExu9Lt59i5.uty=^k", +"5 wur:yZNuvr==3V377tv.35t7*{EEnwKlN;tm(,k(^K--S6^k4nc{]5=cBq7V.3>eg``KH>9bc>Gv}KfTynQhvsZ64PIf11=7S$-@NtbszSjS``9uyw97.F.B", +" y7w9TiAuOrr=3.35VubT85. tyja{:g@mk9cnY^fD1--`K>kI67n=G37tgyOyyxybj`f64b>va3vc>zKiidF=vEkD@DD1$=7al-z>>wvSl%B~$6~:vO.ET>wZe 7i5HaBT#9*9hV 5vyNycuc9}YK-$I$fDpbv:{b}:c83x7yisarc9cBRsN>>n=n=Y3vHix.dxbN4I1f@p$]3VVq`i9nrwaau.q6KHNw5O3dF33nZ:9", +"tui<.dngES*eqBHcuy3.ut%5#y5*5wu8yev:c]^4NlJRfpDR^bL:L=q^>07<y9xnv]3cr..37ybYDp4B`KNTwVvNcHZV7S`j_Ht:6Tt{OyQd bHur", +"i T9<.8bvT80i%9w3ttiTv9tH +5tT79hO=n}:4Hc=vvkRpp@:x}YvK@K> VdhOT2ttg88x7irayyy0n.VV3b93V3Exvkyt4p4lJN{HH-Jj7yE`j6gyi6vZ3*3.OtT;T", +"t7U .570nyn=xwut=yyZHNit*w3F73)8wVVxcNm@hVFhmN4k(;k^,/^ID(`t# UyTHnB{yvrHeEw7w0333.wx9n93+cV]vgEIIRJ9:DAJ-J_yaa#{@u qi@HfiV5bm:@", +"*i&&w..5vZ2HyAl{x9it}/#i5d_yb_tw%wVLx=](n:GFND@4@K>qn3GbH>f4t3<9ylIHgfR6~l>H&#yZi7=t5ygN3]=V73dbn4HqVvDa]*S~up~%Oyzq`qmH`qddiHB>", +"7O3*%w3GV7262@l6Ncbxv0]tw39wwy%933hG=GhnJJIc]4^IfR&=YGGG:mnAt3~Bg30BcLxh 5h3NH:@nT-J%!FUnyEEHaRRR-~IKz7Vd3>x", +"5g{T#Tx]r]vw6~DR@@>;:>tyaT8hVQ.dF=3b]43cp$J^xx]:{_b3nt>/v}644Ed33Lp---$Du#vcawwr{wcVhFVnb>yO%a9h8N}AbnR$J`dFD23OaZ2E2`@uuM2a 57c", +"iE{TbmyvityGZIl1E@jNu>:naBy@DKE3=V=@---RHtex0uy=7*3OVdFVvv>vBE2dFF c=xiHv7F;K1^YY/YHG37iNvvPffRHTEu3Lcf-$4ruEvnBg8Gn%7G %avv}uh7Ba35x]>>nvvjJzHaaSqicvyEj%E8.tT#T{>", +"t794KNBBtybiFVwqfHvcv=bv}>TMiw3vb353rn:T]ckk^bNHK677wHv:v4KDEc~6H Vn$$1Sdt77B~MslIa=3:BaBbwhwYvF5t>n6N>3Vn2N@@SIE>u*lzwyEt9..b@6", +" 79ulB>u57iEuvvBARg>B/tv7vcN%s#ntv3t3tuNvth5bY]bq4n7.39icc;:@uy>*c3]Zp6Hi&v]9:NHHg6Zu]0nnnv6>99c/ZZ=tb>q6(4T@H6plfREi{uO73cZZ", +"H4]tHBw7.V5it33>4ZNa]vy=3ir9yNnHxvc>x3]w:T>=V7ni4B89y yyvvaBjKnBG7tbTqZTTH4>i:5u{{P4S~N>o4nTqHDEbx3>kHvB>>44BA>v&;64jjy<3tnrw93=0N:wtu4>6l6@jgi@Hu:cig>>97vvb4ZEva(Evn3d7wT}N4nvn6>YaeHs7h3nkPl_>]nB:HB95=tm>Twd.3.ya4H@", +"AHA{{{wr99itt3QFdVT>pKBBvv35ywx}cx9ycw99=w>yytZ{{DJ1>{:ZfPN>578n0x:x=bE6aNg>N .3hhZBBbtw7>inb}i(]4}BZ>cnwyuZq=w>7ddV<]#nn", +":n8r2MlK2:2gTa53uc0ayaNcxv]9aLuBBEI>NHtKp~6.btB}npHc9xwc:ntc wb{tcnc~tHk:>EnvxtnvN:LK>]d3VFF33", +"v>=GzlRfI{4^Eg3.TT=}M2@1v5it]yniT:cxT#T{nxbc]:xbN>n@ZmN:;ZlKTgBBvypDTbwvxw:vv9X5*n@~JRgNbv85>]yyuTmc{xl4NAn>TbYccbvZkn(Hv3.dFF.5", +"wnu3EH@lp25w{Hxx%E33tZllINg:tr0ycywyxytTq@^SGcvuNa>HKH3Nt=@~`1l6N>:g:>>i9VwcuTyx3w9bf4BBx>wLi}73wx@ib:>TtB:ycuvvbY}(46v4T]wtFFww", +"V5>uKKuHaHn7w0x7ni 3h3Mn~KB>TBu7Oc:Ni#wtRp4ZNH>b>N:NN4>v77mbEqEHq@5=0xn7=xFVxnZaG757B4~q:>ynw8wr38B:9nv99t>b]BcL:kK^k}b:44aR h75", +"37HN1fa/=vPbBx xyxG7iwaTc6P2ZHs :Tsq6gt9I@bn@EH>wcyB:^>9G3HSV99xb4}v5wny7ay3]y>BrG9tc}IqNBBGw3Vwn0}c]]:ntTEa0b^]:PDP/wv::itqNVV5", +"TbH@EHZ@N^RAD2G7=73]t=7>n>Z@4ZS{9ivrZag{N};4@>::uvv}:c]hhFdt.9cb>H]tV3:aTw5h=vnNqy=hO8a2@6piLuw7b::TycrNyyHuy5~B]>4k>n=3N>v~pT5x", +"q4@KN{jHon@^ZDiNbG7.{Tn>Y:v:Tu>y.9yr:vcaZ~ZEH6u9nnYbNxtxdhdhdV :at3=3FOuwh3Qx]BaT>b3cr>BzpffT4iuw9 v9twt< tv5aqbcncZ6axTKHNI~bx", +"BEMqj4@@H/nZo@NMzH59TDH:g^4:uT]xty}naZ9x>q9=b_y3NvY>k;>>3.37d5yy97hF3Fh.tOG5e:6D6p@jl6H>{6>P2B:TB>75ryeby73iu{H64bcv2fS46lZb>Znw", +"bt>_aa6jqjb/Z4Zu@~yTxH:y44qlE@6txyNu>{/yvBDNy573i63vK@>aLN4HiEHuEtbEuNE~fBEqT=x>>>Nmvc}SNn=d3bK=L@P>}x7cuw=i{7h59<9VF=T=]baBN>66lJ$D@>;ZnPq@ZAgyiHTj@ZTt6SZ@BRpy_fK2{iT:TBZiE", +"E%5]T9HEHTub~~_#u9&Tv5^{c9B:{a%eb]9;N:by]xt=n]FF5@(=ckb,yw7uEu@RE85t]v97v}t={TqpqZbv:b46Z6ydyn5Tnag{4N24@RTvqlfjBHTiynaE", +"2~wRJH=hMp^w07,}:c:KZ9sI4]i:TkZn]:twN>TBHut=G>aaN^nBb7vnc .ci5bBy{g>w46fpK(IfIDiZH:55%T", +"~~uuuv3xHH%T)U4}w=9wvbnyB6{i80]:bvT:>bw4a3ysa <~2", +"Sj_wyac7xt5hFUZ)#E.u=cNv>T{@$JKK^n]<3hhTRJcMJ---glSSTyvy=5tnjqR(:>:>>b}:tv G7nGc>inE2%73vy=Y9vjeN1iVwe>N9B9=jT5y:D$$(`@DgmajE.ES", +"E{#*5MuVw]mFFF#iFhFhE9^6pp@(1J`pKc)6qpKB>v3yGrTxbNo77ywO3O{:LG:>HH~-Ki:ER~12>m63]5NI1p^>^H>twa<9~", +"E~{T<75F.FHN:.3tVhFF*8bN$$pI11Rl@GFV&Tng>4Bb>41SHNwxyw3w5]6qZb3Oy.xTK@xZ>H@R`$1JKS9g>,uawn==iPK:}4uv995 #", +"U{fzHT4 FFRf$Rb379dF3GV=$-$$J1EKK;G=m=xb4lH>l`IP^I~abBwtb4yy7ybgE/39HBa:vvx7=VG7bnDKuw>yxy^pqc0a>j{~l`Kf >wy%eaEOVwnI6=<99bH;:B9", +"&u~lH:E{FFlM`l9FV&y3VV==p$1IJR4l`Ib9NTb;E{EH4RS^Nqjiwvvxx>3539b{@g]57ba>:uxx]d5c}x@2MHe}nvgppiLrcBtu#4EIEay9#*t%w3=vqzx]cncNBu{>", +"]<9T#x>km3dFd.FF55nTvn]h95])tbfpJJ(n4f4vN={Rb}/>bbj%bnBv=8uwGOgHZ@{i)79vt:T>n5x=vc3TlRA}g{K1`jivYv3VFhv{E#id.3 T&%d3vjvt7}bvvcN{", +"VcOZ{iKKKt9hFFVV 3b:Rp]F3FhhFFTl`l4N{@@:@guf^xn}kxUy9iS~ejI2=VTNaN~S{i7ywvbvHbv]aEd3*aqDZK2$Kv>aCevw.V0T:aavO.5%att7hH::aA", +"c:a~zj~6vbzE.Fhu{bB@llbhVhhFFFF N77nB/NHRRlz:N:k4H3.3G{g@~~fH:L=vw>N&y3rby5xb8]7}EH.V3cZNf1$pb>N>Z}kgvOw2a>TzE.5M iaddygH@Z^4(~f", +"6N5u~lE4v3yuT%y:4K>wh3V.FFFFFFhVvbx9vx/mSJ`$BT1ppDunBb:]ZRD14P{>}>95wtwwwrwxw707=={u8:t57y1-$K:{v>(@Rj8n6f1qJJHTa:>H.d3x^^p@@f$$", +"JpT]>Tj@HV5xHE{vc@:7FFhuhh33FF.ha4ccnt::ZzElf4$1@Ig>2HZu5T@IqaH:bkNv7yyvO.58vunv=w7ytiitw3n~pKB{n>n/>}ia#f-$J$j{S~Ti7.7iiBEp1p1J", +"E~: Gbbi%09c__@;==h5OV.E{ciwdhFVug>5t=kk4ktaM`-$B@gBHEi{Vh]Kpgb#(^642i>Hyayu}ZZHx=<3F.gExw=Y^B7w:cVxB6~ivE$-`l@4uTtyO7VG9>5HI@K1", +"Nu#y3c ]v7thFVMp5=FFV5.H2u5F3h5V3G:ucnNkkknZ;I$`Dgi=9va#;>b@l1HtKHT{Rq{>gSHyo^6qZa3..yaEBE>vnywOcjV=naawh7jIzpfaE57wyv>vHu@Jpz^TX57>{4MN^l$IHqHt&2jSeD2genB6qKD5_O**Bg6kvyw77cqwV=ctuMRK4t3hVdv{Bk(R$$p@2wd7wzHzRR6v7BZ61v h75t@Pvtv{y]L>2:xv:y&9.9vHjgJ2yi7tHi=]8G.5bi", +"KgTTTa<57_@K=VbnNwVwiiEH]53 t:Yh{SZBE#7<5V.iiN2Eca*.aHx7]h7.3c", +"6Euuy{4Mc5_ywhh.77{nx:Ti8%ywdh!UU~M_9tuT>rrwvBDeabvNkAH&37]nmrOQ3VxH=BN4KIKi<7G=vy53&*]zj5<9twdO.OaE Va~_mTj%58c>w7rD@y", +"iN_O5<;9=] VFhVdy7{jHE_y# jlcxx=vnp{GF5yFF7Ovk:V_BSK`Db& 5hFFVcn!hdhX*2 OZ97w7>mpppHE~_9yu{EM`2yz2tN:a twyhh&S]i$pt]ujHn}vTV5n>9", +"{HT#<3;N4aHqqti9dFFF.hTqtic&&Tst#{yv0{b{{j454aZ:vtnMJR~`zvATm9y#Hd5w~ycZ6@{wwmN>v7Vyu>3", +"t955.d {{b:B@{wdFFFh=BKEu5.9yj6TEDfggEwtcH7nv x4Hc2J1`SK4BbNNu7TTa~R{2K:TE47bT:>vy%>6{", +"tw< d. E~&w.FdU.hd<]3V.nHzZt.FFFF=kEi 3<&tA~4@`$DEanu T:bn7=NN92```qq(n::am5 2Ej`jIR{tulT;nkZbi6aSH", +"O. g TU 7ddXdFd.33]335dVHH@R@E*FFFFF99)5 h59cED$$`R%irwwO>i:5G5v53UD2N6Pnn{u:vtSatlRS~lt5%gu:/^TcB/Ha", +"&95TEE9:H@u5FV93dEzavH6@IP~:H4I1f{{9:nvy:x", +"yT 5 dUjlM{&9[QFh9nny.MgtVw>S4Kl@N9h]a9<9Hb]>{6q@@enH61`6gjg=FFF&!hhhFd3V*z`EtbHrnTaby>H5=bgj~5y=xEftttNHSR$lj~ljTH*t5tv]5yb0=ac", +"&yZv%dd{~%{9U9 .3=Y/7h*Pi.bTjfplKKa t*{{>HNvu:NH6qB7wrHzD4@@nhFFhhFddFd]Vj--it7G3uv87HKR`$$`HEREO.##crv93=>twv", +".56gTOdd#%E#&%9un}}b3d7w5FYnjjl@^B9{{Tu>4SNN42ZH1@3vVxvfzg@@^TFFFd!~Ud.atHH~6A#8753i#mgSII4@`-l9y+V.Bg/S61R---Eu@j%t*#>{9>yvyyw3", +"=3:u{#Xh.y{t3& bTTbcx3B>k9tubBjnNjuiiEEH~S:uH~Hn6DNqZIAp$1z@AZQFh!EJEdE^BM~zBBZTaBie5t_~zf@j2l`fai3hxnkaKI1$MfKi{E%j%&UjH>nty79v", +"n}bwttt..3.#3tj2>E>HyH4gqHt79uZic46EqZ~&lIEvw#uy:Bqp1IN4$-Rq^~#dhh%JlEzlNKElPZS6e6>ZE~Nt.d0v{4qK@K:{j;vT&#j#. :uP=7.Vx", +">a}u 9 .<tF.ctw4{6ii:Ty5.x:nTm@^Huy{Tc9 jEd<_:Iv5t57", +"trtw!9O.*EBjEw..jJ`9:kNHn4IBv=tN%st3)9vwbBat79w9OhVw#Gbi59t&N%{{ty#tv5nb7<>@Hb:x@qNnm>H@~Eg4S6N^I`wvvqnookBgT_<H@4La4#4j{TeB{4NN66ZPJ]>ABi{DEN!{K{y a{v{bv>33>v=79y>9t2KEkNk>4BbvaT{&t yuibviPpDREx4pHuj@Ti~au5y]t4H]LL...< MMH6.np4dd Onvkq@j", +"oBt.OwTH;4# <{n5ER}^vuxwyx3wTx]9N>{}HB^q98w:Ey*twtw7i}mI$-j(qKIzNfKNi9GG]]m6jZaZgHb6EEj~%iMy:ZaHO95hv>vxn3<..d>HN@>B$-j*d5BbbtN4", +">vtyyu4qEEi9QOG]{p>AvLwV5y0xyct3c]v=>HvyFVh3i{iaavu9yn5vKR.]>ZD@tN`ppEb]vbycr@l`p1Hq2jl2T9nt78u=OVQFVvn>& TTxd.u>Bv]@`$zyOK@{B59", +"~279T{Z~HEa75w==N@{q4LOw=7>>N:T]tnu=v^vGdFhd aZ%BA~gn>y9_KwFyvZ}:;1J``/Yx=:_=aE~R`6vuEH>yy>H.3wi5Vta:vv>&. % 339xN:}v:S`Mbajm>av", +"ZRu5a4BEg@:3 {w3NZ~Dz:iEy8vbauBy=:EtbZc)xFhd9*E6>24j>nu&nITF9xBBb:KplI4vn95txTHHDI479ub:vuZ6y.{6w3cg{:nn*3.v9VV=c:Zin=#KM:NE>ng>", +"aj`MH6iY{E>wvu:9=5KDqf{Hnutc:uHNhtK2uNB5>hh.7t gsjKl4Tiaa@l4]L:Z3ryng6^n>:V]>2~T>:>B]vt>uyn@2MSDNtGvn>:Y8dyybV9v>u6:n95ijH6Hn{>Z", +"jS`SjHPgj4Nvyutv33w6cZPANN{n&{n2:c4@TNlyyyV3wT3xuySRS6jMb:KR$Rnih733b6kv553tjK@H4nkDaB}cHN9utZ@ql2Bty>:>tuH>jH759ZB/9BN{~6BNv{BH", +"u4Hg{ippIRN>7c33yu=:uYD@2gHgtEE~KiHB#:E:Ts5VvT9tuyn_S6{HHN>a~D1pVh3VwB2nnuttKNakq6^p(^B]n6n{GuIzpjqIN}>Hni4ZjNy<=i^4/NTyNHNgNvyT", +"tuuyNB11f$^nv=<3vc35/vB/@66qwuMalP46>uE#v7b<]n9c7_bvA6{%H{BTc;f$2.*7G7a;anuuH6KK@knk^>{wwZTHfpnNycv^atn>:n5hVv>^lv{]:kiBTvtt", +"4HE4ZH`-p1Pk~uV=]nniyw Eu;~fHNau%inb>ivc@t9ByyB;u3=HEitN@J@V9.F9nbavn{@11`pfkDD4b]ng%e33=DIZ:LvGvi}cyi3&u=xxuB=E/NkNYyc&:", +"4jKSD^f$JpP(1Ja5wiqm>N{a9cHw73*b3mp45ynmZK`1`$pJ1l{vxv%24tvNZf6/nnv77n=&vu{}v>9KNH4:oBivvt7" +}; diff --git a/hacks/images/sball-bg.xpm b/hacks/images/sball-bg.xpm new file mode 100644 index 00000000..4c313100 --- /dev/null +++ b/hacks/images/sball-bg.xpm @@ -0,0 +1,357 @@ +/* XPM */ +static char *sball_bg[] = { +/* width height ncolors chars_per_pixel */ +"256 256 94 2", +/* colors */ +" c #1D6868", +" . c #284848", +" X c #DF0305", +" o c #4B4646", +" O c #165757", +" + c #80B4B5", +" @ c #0C7271", +" # c #092A29", +" $ c #3B595A", +" % c #4C3636", +" & c #7F393A", +" * c #7F3030", +" = c #A80406", +" - c #2F7F7F", +" ; c #B80405", +" : c #2F9596", +" > c #855D5D", +" , c #3B7777", +" < c #A01818", +" 1 c #409596", +" 2 c #177271", +" 3 c #1F3637", +" 4 c #A67E7D", +" 5 c #382828", +" 6 c #56A8A8", +" 7 c #350304", +" 8 c #548585", +" 9 c #176060", +" 0 c #480506", +" q c #5D5A59", +" w c #758181", +" e c #CB5F5F", +" r c #37393A", +" t c #386969", +" y c #E61110", +" u c #74999A", +" i c #B0CBCB", +" p c #3F8B8A", +" a c #CF3B3B", +" s c #980405", +" d c #055051", +" f c #790304", +" g c #874343", +" h c #86504F", +" j c #1D4444", +" k c #9D2827", +" l c #075859", +" z c #CC2727", +" x c #609696", +" c c #963637", +" v c #880305", +" b c #C71818", +" n c #290707", +" m c #6F1717", +" M c #73A5A5", +" N c #1E1313", +" B c #208988", +" V c #491919", +" C c #287272", +" Z c #419F9E", +" A c #137D7E", +" S c #0A6868", +" D c #073637", +" F c #B29D9D", +" G c #2E2222", +" H c #686868", +" J c #6E7271", +" K c #F70204", +" L c #734A4B", +" P c #680305", +" I c #716060", +" U c #175050", +" Y c #486969", +" T c #795454", +" R c #547778", +" E c #064949", +" W c #285050", +" Q c #074040", +" ! c #482727", +" ~ c #4F9697", +" ^ c #308A89", +" / c #7B2121", +" ( c #184040", +" ) c #A53D3D", +" _ c #1A2121", +" ` c #580405", +" ' c #09605F", +" ] c #571E1E", +" [ c #C70405", +" { c #81C4C4", +" } c #207E7F", +" | c #285C5C", +". c #608A89", +".. c None", +/* pixels */ +" 2 } 2 } - } - - - - p - p p p ^ p p p ^ p ^ ^ ^ ^ ^ - ^ ^ B ^ ^ B ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ p ^ ^ p ^ p ^ p p p p p p p p p 8 p 8 8 8 R R R J H I q T L g g c c k < = s v m m ] V 5 G ( ( E U l 2 2 } } B ^ ^ ^ ^ : ^ ^ : ^ ^ ^ ^ ^ - } } C 2 2 9 9 O U U j . . . 3 . r 3 r r r r r r r r r r r r r r W . . . W W W | | | | | | | t | t t t t t t t t t t t t t t t t Y , Y , Y R Y , R R R R. R. w w w w u F + i { i i i { u. 8 Y t | 9 9 S S 2 2 2 2 C C t t t t t t t C t C C C C C 2 } 2 2 } 2 2 } 2", +" 2 C } C C C - , - p , p p , p p p p p p p p p , ^ - ^ - ^ - - } ^ - B } ^ } ^ B - ^ ^ ^ ^ ^ ^ ^ ^ p ^ ^ ^ p ^ ^ p ^ p p p p p 8 p 8 R 8 R R H H H q I T L g g c k < < s s v f ] ] G G _ 3 3 E U l ' 2 2 } } - B ^ ^ ^ ^ ^ ^ ^ ^ ^ - } } } C 2 2 9 9 O U U U j . ( 3 j r r r r r r r % r % % % % r % r . o r r o . o W . W . | W | | | | t | t | t | t t t t t t t t t t t t , Y , Y , R Y R R R 8 J 8 J. w u u u + { i i i i { + u. R t C | 9 9 9 S S S 2 2 t C C , t C C t C C C C 2 } C 2 2 2 2 2 2 2 2", +" C 2 C - - , - p p , 1 8 8 ~ 8 8 8 p p p p p p ^ p ^ - ^ - B ^ - B - B - B ^ } ^ ^ } ^ - ^ ^ ^ ^ ^ ^ ^ p ^ ^ p ^ p ^ p p p , p p R - R 8 R R R H H I T L L g & c k < = s v v m m V G 5 G ( D E d O S 2 2 } } B - B ^ ^ ^ ^ ^ } - } } } C 2 2 9 9 O O U U j j ( . 3 r r r r r r ! % ! % ! % ! r % % % r % r r r . r . . . W W W W | | | | | | | | C t | t Y Y t t C t , t , t , t , Y , Y , 8 8 R 8 R. R w w w u u M + i { i i { { + u w Y Y | | O 9 ' S S @ S 2 2 C t C t C C C C C 2 2 2 2 2 2 2 2 2 2 2 2", +" C C C , - p , , ~ 8 8 ~ 8 ~ ~ x ~ ~ ~ 8 8 8 p p , p p ^ - ^ - } - } - B - } ^ } ^ } ^ B - ^ - ^ - ^ ^ ^ ^ p ^ ^ ^ p p - p p p , p 8 R 8 H Y H Y I q q T L g c k k < s s v f m ` V G G # 3 ( Q U l ' S 2 2 2 } } } B } B } B } } } } } 2 2 2 9 9 O O U U j ( ( 3 r 3 5 r 5 5 ! ! ! ! ! ] ! ] ! ] ] ! ! % % % % r r r r . . o . W W . | W | | | | | | t t C t t t t , t t , Y , C R , R , , R 8 R. . . u. u M F + i { i i i + M w R Y t | | 9 O ' ' S S S 2 2 C t C C t C 2 2 2 2 2 2 2 2 @ 2 @ 2 C", +" C , - t , 8 8 8 8 x x x x x x x x x x ~ x ~ 8 p p p , ^ , ^ - ^ } ^ } } } B } } B - B - B - B ^ ^ - ^ - ^ ^ - p - ^ p , p , p , 8 , 8 Y R R H H I q h T & g & c < < s s v f m V V V G G _ 3 E E l O S @ } A } } } } } } } } } } 2 2 2 S 9 l l U E j ( ( 3 r 3 r 5 5 5 ! ! ] ] ] ] % ] * ! * ! % ] % ] ! r % % r r r r r j . . . W W W | O | | | | | t | t t t , C t C , , t , t Y p Y p R 8 R 8 R. . w w u u M + { i i { { { { u w R Y $ | | O l 9 ' ' @ 2 2 2 C C C 2 2 2 2 2 S 2 S 2 @ C ", +" , t p , 8 8 p. x x x x 6 u M M M 6 x x x ~ x ~ 8 p p p p ^ - - - - } - - } } ^ } } } B } B - } ^ } ^ - ^ - ^ - ^ , ^ - ^ , p p , - R R R H Y q I q L L L g c k < < s v f f m ` V G G # ( 3 Q j l l ' S @ 2 2 2 } } } } } } } 2 2 2 ' 9 l U d j ( ( 3 3 r 3 5 5 5 ! ! ] % ] % * ] / * ] * ] / ] * ] * ! ] ! ! % % r r r r r . . . . U W W | | O | | | t t , | , t C , t , , , p , R 8 R 8 8. . . u u u + { { { { i i i + u w R Y $ | | O O l ' S ' S S S 2 2 S C S 2 2 2 2 S @ S S S C", +" , , 8 R. . x u u M u M M M u M M u M M M x x x ~ ~ 8 p p , - ^ - - - } } } - } } } ^ } - } B - B - B - - ^ - ^ - ^ - p , 8 , , 8 R Y Y R q Y I H q T g & & & k < v s v v f ] ` G 7 G _ _ D Q E d O ' ' @ 2 2 2 2 A 2 A 2 2 2 @ ' ' 9 l U E j ( D 3 3 G G 5 5 ! ! ! ] ] m m m m m m m m m / m / ] ] * ] % ] % ! ! % r r r . r . . . . . U W O | | O | | C | C | C t , C , C , t , - , , , p R - 8. . . . x u M M + + i i i { { { u w 8 H $ t W U O O l 9 ' ' S S S S 2 S 2 2 2 S 2 @ S S S S 9 S C ,", +" , R 8. x x M M u M M + M + + M + M + M M M M x x x 8 8 p p p , - - } - - } } } } } } } } } } } } } - B - B - - ^ - - - ^ - , p , Y 8 Y R R q q q L L L L c k / < s v v f P ] ` V G _ 5 # 3 Q j d d ' ' S S @ @ 2 @ 2 2 2 @ 2 S 9 ' ' O d E E ( ( 3 3 G 3 5 5 5 ! ! ] ] m m / m m m / m < m / m / / m / m m / * ] ] % ! ! r r r r . 3 . . . W U | | O | 9 | | | t C C C t C , - , , p , , ~ R ~ 8. . u u M M + i { { i { i + u w R Y Y $ | W U U l l ' ' ' S S S S 2 S 2 S S S S S S 9 ' 9 9 | t t t ,", +" 8 8 8 x u u u M + + + { + i + + + + + + M M M M u x x p 8 8 p p - - - - } - C } } } } } } } } ^ } B } } - } - - - - ^ , - p , 8 , , R R Y q R I q q T & & & / k < v s v f f ` ] 7 V G _ _ ( D Q E d l 9 ' S S @ 2 S @ S ' ' ' l l d j U ( 3 D 3 _ 3 G 5 G ! ] ] m m ] m m / m < f / v / < v / < / m m / m ] / % ] ] ! % ! 5 r r r j 3 j . j W U | O | 9 | 9 C t t C C , C C , - t , p , 8 8 8 8 p. x x x u M M + { { i { i { + u w J H $ W W W U O l l l ' ' S ' S S S S S S S S S S S S ' 9 ' ' 9 9 9 | t , Y", +". . u u M M + + + + i + i { i { i { i + { + + M M M x x 8 ~ R p , , - - C } } C } } 2 } } } } } } } - } } } ^ } - - - ^ , - - , , , Y Y R Y q q q L L L & & k * v s v v f m P 0 V n G N # D 3 Q j d l l ' ' ' S S S S S ' ' ' l l U E j Q ( D ( G G G 5 G ! V ] ] m m m m / v / s v < s < s s s s < v < / < m / m m / % ] ! ! ! r r r r . . . . U j U | O O | 9 | 9 C t C C C - , - - , p , , p p 8 8. x x M M + { { { { i { + + u w R Y $ $ W W U U U O l ' ' ' S ' S S S S S S S S S S ' ' ' ' 9 9 9 9 | | t t , Y 8", +". u u u + + + i { i { i i { i i { i { i { { + + + u M u x x 8 ~ , p - , - C - 2 } C } 2 } } } } } } } } } - } } - - - - - - , , R Y R Y H H q q q L L & & & * < < v v f f P ` ] 0 V N 5 _ # D Q E E d l l ' ' ' ' ' ' 9 ' l l U d E E ( D 3 # G 3 G 5 G V V ] ] P m m f v < s v s s s s s s s s s s < s s / < / m m m / ! ] ! ! 5 r 5 3 r 3 j r . j W U U | O O | 9 | t C C C C t - , - , , p 1 8 8 ~ ~ x x 6 M 6 + { { i { { i { u w w R q $ $ . . U j d d l l l ' ' ' ' ' S ' S ' S ' ' ' ' ' ' O ' O O O | $ t Y Y 8 R", +" u u u M + i { i i { i i i i i i i i i i i i i { + + 6 u M x p 8. , , - , - C } C 2 2 } 2 2 2 A 2 } } } } } } - } } } - , - , , , Y , Y Y Y Y q L q L L & / k / v v v f f P ` ` V N G N 3 _ 3 3 Q j d d l l l l l ' l l l d d E E ( D ( _ D G G G G V V ] ] m m / m v / v s s s s s = = = = = = = = s s s s m v < / m ] m * ] ! ! 5 5 r r r 3 j ( . j W U U | O 9 9 9 C C C C - - - p p , p 8 8 ~ x x 6 M M { { { { { i { + + w J H q $ o W . j U U U d l l l ' ' ' ' ' ' ' ' ' ' ' l ' O l O O O O | | t t Y Y 8 R. ", +" u M + i + { i i { i i i i { i i i i i { i { i { + + + + u u x x p 8 , p - t - C C } C 2 2 } 2 } 2 A 2 } } } } } } - C - - - , , , , Y Y Y q q H q L L & & & / s v s v f f P ` V 0 n V _ _ # # D Q Q E E d d l l l d d d d j E ( Q 3 3 D _ 5 3 G G V V V ] m P m f v v s s s s = = = = = = = = = = s = = s s s < v / m / m m ! ] ] ! % 5 r 3 r 3 . ( . j j U O O | O 9 9 2 C C C - - - - , - , 1 8 ~ ~ ~ x x x M 6 { { { i { { { + 4 x J J $ q . . . j U j d U l l l l ' l ' ' ' ' ' l ' l l l l O O O | | W $ $ Y R R R. u", +" + + + { i i i i i i i i i i i i i i i i i i i i i i + + M u M x. 8 8 , , - C C C C C 2 C 2 2 2 2 } 2 } 2 } 2 } C } } - C - , - , t R Y Y Y q q q L o & & / k / v v v f P P P 0 0 V N N _ _ # 3 D Q Q E E U E d E d d j E Q Q 3 D ( _ _ 3 _ V N V V V m m P m v v v s s s s = = s = < = = < = < = = = = = = s s s < s m / m m / ] ! ! 5 5 5 5 r 3 j ( j U . U U O O 9 | 9 t C 2 C C C - - p p p p 1 8 ~ ~ M 6 6 + { { { { { { i M u w J H q o $ o . . j j d U d d l l l l l l l l l l l l l O U O U U W | $ t Y Y R R u w M", +" + F { i i { i i { i i i i i i i i i i i i i i i { i i { + + u u x. ~ R , p t , C C 2 C 2 2 2 2 2 2 A 2 A 2 } } 2 } C } - C - t , Y , Y Y q q q q L L L * / * v v v v f f P ` ` 0 N V N G # _ # 3 Q Q Q E E E E j E Q Q Q 3 D D _ # _ G N V G V V ` m P P f v v v s s s = = s < < < < < < < < < < < = = = = = s s s s < m / m m ] ] ! ! ! r G r 3 r ( 3 j j j U U O O 9 9 S C C C C - - - - p , p 8 ~ ~ x 6 6 M { + { { i { { { u u w J H $ $ o . . ( U j U E U d d d l l l l l l l d U d U U U U W | W $ t $ Y R R. w M +", +" { { i i i i { i i i { i { i { i { i i { i i i i i i { i + + M M u x. 8 8 Y - , C C C C 2 C 2 2 2 2 2 2 } 2 } 2 } C } C - C - , C , Y Y Y Y Y q q o & L & / / < v v f f f P ` 0 0 7 7 G _ G _ # # D 3 Q D Q Q Q Q Q ( D 3 D _ _ # 5 N G 5 n V 0 ] ` m f m v v v s s = s = < < < < < b < k b < b < b < < < = = = = s s v v v m ] m m ] ! ! 5 5 G 3 3 r 3 ( j U j U O O O 9 9 2 2 } C - - - ^ p p p ~ ~ Z x M 6 6 { { { { { i + F u w J H q q . o . 3 j ( E j j d U d d d d d d d d U d U U j U U W W W $ Y Y R w w u u u +", +" { i { i { i i i { i i { i i i i { i i i i i i i i i i { i { + + u u. . 8 , p t , C 2 2 2 2 2 2 2 2 2 2 2 } 2 } 2 } C } , C t , , Y Y $ q q q L L % & / / v v v v f P P ` ` 0 n V n N N # _ _ D D 3 D D 3 Q D D D 3 # # # 3 N G N V n V ` ] P P f f v v s s s s < < < < < k k k k k k k k k < k < b < < = = = s s s / < m m / m ] ] V ! ! 5 G 3 3 3 3 ( ( j U U U O 9 9 9 C C C C } - - p p p 1 1 ~ ~ 6 6 M { 6 { { { { { { u w w J H q o o W r . . 3 j ( E U E U d U d d U d U E U j U U . . W $ $ Y $ H R w w u + F {", +" { i i i i i { i i { i i { i { i i { i { i { i i { i i i i i + + + u u. . R 8 Y t , C t 2 2 @ 2 @ 2 2 2 2 } C } C C - , t t t Y q Y o q o L & * / * v v v f f f P ` ` 0 0 n n _ N G # 3 _ # D 3 D D 3 D _ # _ # _ G N G V G 0 V ` ] P P m f v v s s s s s < < < k k k k k k k k k k k k k k < < < < < = = = s s s v s m m m ] ] ! ! 5 5 5 G 3 3 3 ( U ( U U U O O 9 9 S 2 2 2 - - - - ^ p p ~ ~ ~ 6 6 6 6 { { { { { i M + u w J H q $ o o r . 3 . ( j ( j E j E j E j E j U j j U j . W . $ $ q $ H R w w u M + + {", +" i { i { { { i { { i { { i i { i { i i i i { i i i i { i { i i + + + u u. 8 8 Y , , t t C S 2 2 2 2 2 2 A 2 2 2 C } C C , t , Y Y Y q q q L o & * / / / v v f v f P P ` 0 0 n V N G N _ _ # # _ # # # # _ 3 _ # G N _ V n G 7 V ` ` P P f f v v v s s < < k < k k k k k c c c c c c c k c k k k k k b < < = = s s s v v m / m m V ] ! ! 5 5 3 5 3 r 3 ( j j U d O O 9 9 S C C } } - ^ p ^ p 1 ~ 6 ~ M 6 { { { { { { { + u 4 w J H q q o o r r . . 3 j ( ( ( U E ( j U j U ( U ( . . . . $ $ o Y H J w. u u F { i {", +" i i { i i i { i { { i { { { { { i { i { { i i i { i i i i i { i + + M x u 8 8 R , t , t t S S @ @ 2 2 2 2 2 } C C C C , t t t $ $ q q o & o & / m v f v f f f P P ` 0 0 V n 7 N N _ N _ _ # _ 3 _ _ _ # _ N _ N V N V 0 0 ` ] P P f f v v v s s < < < k k * k c c & c & c & c c c c c c ) c k k k < < < = = = s s v v v m m m ] V V ! 5 5 3 G 3 3 D ( Q j U U O l 9 9 2 2 2 C } - - ^ p p 1 1 ~ 6 6 6 6 { { { { { + + M u w J H I q $ o . r r 3 r j ( ( ( ( ( ( E ( ( ( ( ( . j . o . o $ q Y H 8 w w u + + { { i", +" { { i { { { { { i { { { + { + { + { { { i { { i i { i i i i i { i + + u u w. 8 R Y , t t S S 2 @ @ 2 2 2 2 2 2 } C C C t t Y q Y $ o o L * & / / < f v f f f P P ` ` 0 0 n V N N N G _ _ _ _ # _ _ _ N _ N V N 7 n 0 V ` ` P P f f v v s s s / < / k / k & & & c g c g g g g g & g c c c c k k k k k < < < s s s s v / f m m m ] V V G 5 5 G 3 3 3 3 ( j E U d O O 9 9 2 2 C } } - ^ ^ 1 1 1 Z 6 6 6 { 6 { { { { { + F u w w H q q o o o r o 3 . 3 3 j ( ( ( ( ( ( ( j 3 . . r . . o $ q q Y J w w u + F { i { i", +" i { { i { { i { + { + M + + F + + + + { { { { i { i i { i { i i { i + + + u. . 8 , Y , t t | 9 9 S S S 2 @ 2 2 2 2 C C C C t t t Y $ q q o L % % * / v f v f f f P P ` ` 0 0 7 n n V _ N N N _ N N N N N N V G n 7 V 0 0 ` ` P P f f v v v v v < < / k * & c & c g g g g & g & g g c g g g c & c c c k k k < < = = s s s v v f m m m ] V ] G 5 3 G 5 3 3 D ( ( j U U l ' 9 9 2 2 } } - ^ ^ ^ 1 1 Z 6 6 6 6 6 { { { { { + M w w J H I q o o o r r r r 3 r 3 . 3 ( 3 3 . j r . r . . o o q $ q H J w w u u + + { { i {", +" { i { { { { { { M + + F M u M M F M + F + { { { { i { i i i i i i { i + u M u w 8 R R Y t t | C 9 9 S 9 S S S S 2 @ 2 2 2 2 C C , t t $ q $ q o L & & / m m v f v f f P P ` ` 0 0 0 7 n n 7 N G N G N _ N _ V N N 7 7 0 0 0 ` P P P f f v v v s s < / / k k * c & & L & L L L L L g L g L L & g g g c c c k k k < < < s = s s v v < P P m V ] V V V 5 G _ r 3 3 3 ( Q E U d O ' 9 S 2 2 } } - ^ ^ 1 1 1 Z 6 6 6 { 6 { { { + + u F w w J I T q o o o r r r r 3 r 3 r j r . 3 r j 3 r r o o $ o q Y J w w u u F + i { i i {", +" { { { { { { M + M M u M u M u M M u u u + + + i { { i { i { i { i i { i + M u u. R R Y t t t | | | 9 9 9 9 S S S 2 2 2 2 C C t t $ Y $ o L % o ] / * v f v f f f f P P ` ` 0 0 7 7 n 7 G 7 N N V N n V n 7 0 n 0 0 ` ` ` P P f f v v v v s / / k * c & & L & L g L g L L g T L L L L g L g L g g g & & c k k k < < < s s s v v f m P m ] ] V ! G G G 3 _ 3 D 3 ( ( j d O l 9 S 2 C } } } ^ ^ 1 1 Z Z 6 6 6 6 { { 6 { + M + u w J J H q o o % o o r r r . r 3 r 3 3 r 3 r r o . o o $ o q H J J w w u + + { i { { i {", +" { { { { { M + M u M u M M u M u u M M F u M + M { { { i { i i i { i i { + F M u w. 8 R Y t t | | 9 9 9 ' 9 S S S @ S 2 2 C 2 C t t t $ Y q q o o L & ] / m f v f v f P P P ` ` 0 0 0 7 7 V n N 7 n n 7 n n 7 7 V 0 0 ` ` ` P f f f v v v v s / s k / c * & g & L L L q L q L q T q T L L T L L g L & g g c & c k k k < < s s s s v v v m P m ] V V V G 5 G G # 3 3 ( Q E U d O l 9 S 2 2 2 } - B ^ ^ 1 Z Z 6 Z { 6 { 6 { { { + u u 4 w J I I I o L r o % o r 5 r r r r r r r r r o % o o q q q H J w w u F + + i { { i { {", +" { { { + + 6 M M u M M u u u u u u u u M u M F M + { { { i { { { i i { i i { + M u w R R Y Y t t | | | 9 9 9 9 ' 9 S S S 2 2 2 C t t $ $ o q L % % / / m v f v f f f P P ` ` ` 0 0 7 0 7 7 7 7 n 7 n V 7 7 0 0 ` ` ` P P P f f f v v v v / k * / & * L & L L L L L T L q I q q L I q q q T q L h L L & g c & & k * k < < s s s v v v f P m P ] V V V G G 3 G G D 3 ( ( E U d O ' ' 2 2 } } B ^ ^ : Z Z 6 Z 6 6 6 { { { + + + u u w J I H L q o o o r % r o r r r r r r r o r o o o o q q H H w w w u + + { { { i { { {", +" { { + 6 M M M M x x u x x x x u x u u x u M u M M + + { { { i i { i { i { { F + u u w. R Y Y t $ | | O 9 O 9 ' ' ' S S 2 S 2 2 C C t t $ $ $ o o L * ] * f f f v f f f P P P ` ` 0 0 0 0 7 0 7 7 7 0 7 0 0 0 0 ` ` ` P P P f f v v v v v / < / * & & & & L L q L q q q I q T q T q q T q T q q T L L g L L g g c & k k < < < s s s v v f m P m ` ] V V G G G G # _ ( 3 Q ( E E l O ' 9 2 2 2 } } ^ ^ : 1 : Z Z 6 { 6 { 6 { { + M u F w w J I q L o L o % o % % % r % r % r o o o o o o q q q H J w w + u F { { i { { { { {", +" { 6 M 6 M M x 6 M x x x x x x x x x x x u u u M u M + { { i { { { { i i { i + + u u. w R R Y $ t t | | | 9 O 9 9 ' 9 S S S @ 2 C t t t q o $ L o % / m m f v f f f f f P P P ` ` ` 0 0 0 0 0 0 0 0 0 0 0 0 ` ` ` P P f f f v f v v v / v * / & & & L L o L q L q I q q q I q Y q q H q I q T I q q L L g L & & c & / k * < s s s s v v f f P m ] ` V G V G G 3 G _ D 3 Q ( E U l ' ' S 2 } } B ^ ^ : Z Z 6 Z 6 6 6 { 6 { + + u u w 4 J I I T q L L o o r o r % o % o o o % o o o q I I H J w w F u + { { { { { { { { {", +" + 6 + M 6 6 x x x x x x x x. x. x x x x x u u u u + M + { { i { i { i i { { + + u u w R R R Y $ $ | W O O O O ' ' ' ' S S S 2 2 t $ $ t $ o o L % & / m f f v f f f f P P ` P ` 0 ` 0 0 0 0 0 0 0 0 0 ` ` ` P P P P f f f v v v v < / / * * & L L o T L q q q q q q q q Y q q Y q q Y I q q q I q L q L L L g & & c * k < < < s v v v v f m P P ] V V V n 5 G # 5 # 3 3 Q j E d O ' ' 2 2 2 } } B ^ : 1 Z Z 6 6 6 { { 6 { 6 + u u w w J > H q L o L % L % % o % % r o % o o o L q q I H J w w w u F + + { { { { { { { {", +" 6 M M 6 M x 6 x ~ x ~ x ~. ~. ~. x. x x x u x M u u M { { { i { i { i { i { F + M w w 8 H Y Y t $ | | | O O O O ' ' ' S S 2 2 C t $ $ q o o & ] ] / f f f v f f f f P P P ` ` ` 0 ` 0 0 0 0 0 ` ` ` ` P P P P f f v f v f v m / * / * & g o L L q q q q q q q Y H Y q H Y H R q H Y q H q q I q L q L L L & c & c / k m < s s s v v f f P m ` ] ` N V G G G G # _ D D Q j d l l ' ' @ 2 2 } B ^ : : Z Z Z 6 6 6 Z { { + + M F u 4 w w I I T q L o % L o % o o o % L o L o q q I I J J w w u + M + { { { { { { { { 6", +" M 6 M 6 x ~ x ~ x ~ 8 ~ 8 ~ 8 8 x 8 8 x. x x x x u 6 M M M { { { { { i { i { i { + u u w. R R $ Y $ $ W W O O O l ' 9 ' S S S S C t $ $ $ o o o % & * m m f f f v f f P f P P ` ` ` ` ` ` ` ` ` ` ` ` P P P P f f f f f v v v m < / / & & % L L L q q q q q Y q Y Y q Y Y Y Y Y Y H Y H Y q q q q H q T q L L L & & & * k k / s v s v v v f f P m ` V V V n V _ G 3 _ ( 3 Q Q E j l l 9 S 2 2 } } B ^ : : Z 6 Z { 6 6 { 6 6 { M u u w w J > I I q L L L o & o L % L % o o L L q T q J J w w 4 u + + { { { { { { { { { 6", +" M 6 6 ~ 6 ~ ~ ~ ~ ~ 8 ~ p 8 ~ p 8 ~ ~ p 8 ~. x x x x u M M 6 { { { i { { i i { { + F u w w J H Y $ $ $ W | W U O O O l ' ' ' S @ 2 2 | C | $ $ $ o L o ] ] m / f f v f f f f P P P P P ` ` ` ` ` ` ` ` P ` P P f P f f f v v f v / / m / & % L L L o q o q q Y q q Y Y Y Y Y Y R Y Y R Y Y t H Y Y R q q q I q L L L g & & c / k / < < v s v v v f P P P ` 0 V G n G _ G # _ # 3 Q ( E d l ' S @ 2 A } B B : : Z Z Z Z 6 { 6 6 { + M M u w 4 w w I I T q L q L o L o L o o L L q I q I J J 4 w u u F M + + { { { { { { 6 { M", +" 6 6 6 ~ x ~ ~ ~ 8 ~ p 8 p 8 1 8 p 8 8 ~ ~ 8 ~ 8 x x x M x M + M { { { { i { { i { i + + u w w J R Y Y $ $ . W U U O l l l ' ' S S S t | t $ q o o o % * m m f f f f v f f f f P P P P ` P ` ` P ` P P P P P f f f f v f f v f m m / & & & % L o q q q q $ Y Y Y Y Y Y Y , Y Y Y R Y Y , R Y Y H Y q Y q q q q L q L L & & & / k / < v s v v v f f P m ` ] 0 V V G V N G 3 _ 3 D Q E j l l ' S 2 2 A B B : : : Z Z Z { Z 6 { { 6 + u M u w w > J > I I L L q L L L L L L q L q L I I J J w w u u + + + { { { { { { 6 { 6 6", +" 6 ~ 6 ~ ~ ~ 1 8 1 p 8 p ~ p p p 8 p p 8 p 8 ~ 8 ~ ~ x x 6 M M 6 { { { { { { i { i { + + M w. w R q Y o $ | W W U U U O l ' ' ' S S 2 $ $ W $ o L % / ] m f f v f f f f f P f P P P P P P P P P P P P P f f f v f f v v f / / * / & % L L o q q q Y q Y $ Y Y Y Y Y R Y R , Y , , t Y Y Y Y Y Y Y H Y q q q q L L L L & & c * v < / s v v v f f f P P ` ` V 0 G n G _ G # _ D 3 Q E d l ' ' @ 2 2 A B B : : Z Z Z Z { 6 6 { 6 + + u u u 4 w J J I I T q T L o L q L q L q q I J > J w w w u F M + { { { { { 6 { { 6 6 6", +" ~ 6 ~ ~ 1 ~ 1 p p p p p p p p p p p p p p 8 p ~ 8 ~ x ~ x x 6 M 6 { { { { { { i { { i + u u w w J Y q Y W $ W W U U U d O l ' ' ' S S C | | t $ o o % % & ] m / f f f v f f f f P f P P P P P P P P P f f f f f f f v f f f m / / / % L L o o q q $ $ q Y Y Y Y t Y t , t , C , , t , Y , , , Y R Y Y Y q q q q q q L o g & & * * * / < v s v v v f f P P ] ` 0 V 7 G V N G # _ 3 D ( Q E d l ' S @ 2 A } B : : : Z Z Z Z 6 { Z { 6 M + 4 u w w 4 J > I > I T q T L T q T q > I > J J 4 w 4 M u + M + { { { { { { 6 6 6 6 6", +" 6 ~ ~ ~ 1 1 p 1 p p p p p p , p p p , p p p p p ~ 8 ~ ~ x x 6 M M 6 { { { { { { { i + { F u u w R J Y q $ $ $ W . U U U l l l ' ' S S 9 C | $ W $ o o % % / m P f f f f f f f f f P f P f P P P P f P f P f f f f f v f v / m * ] & & % L L o q o q Y $ Y Y Y t Y , , , t , t , t , - , , Y t , t Y Y Y Y Y Y q q q L q L L L & * k * < / v v v v v f f f P ` ` 0 0 V n G N _ _ # 3 D Q ( E l l ' S 2 A B B B : : Z Z 6 6 6 6 6 { 6 + M M u w w w J J J I I T I T T q T T I > J > J w w u w u u + + + { { 6 { Z { 6 { 6 6 6", +" ~ Z 1 1 1 p p p p ^ ^ - - ^ - - ^ , : , p p p 8 p 8 ~ ~ ~ x x 6 6 M 6 { { { { i { i { { + + u w w J Y q $ $ r . W j j U d O l ' ' ' S S | | $ q o o o % / ] m f f f v f f f f f f f f P f f f P f f f f f f v f v f f m m / / & % L % o q q $ q $ q Y t t t , , t , t , - , - t , t - , , , t , , Y Y Y Y Y q q q q L q L & & & * / / < v v v v f f f P P P ` ] 0 0 n V G N 5 # _ # 3 Q E d l ' S @ 2 A A B : : : Z Z Z 6 6 { Z { 6 M M u u 4 w w J > J > I > H I > I I I J I w J 4 w w u F + M + { 6 { { { { Z 6 6 6 6 6", +" Z ~ 1 1 1 1 p ^ p ^ p - p - ^ - - - - - - p p p p p p 8 ~ ~ ~ x M 6 { 6 { { { { { { { i + + F w w J H q $ o $ $ . . U j U d l l ' ' ' S 9 S t | $ W o o % % ] ] m f f f f f v f f f f f f f f P f f f f f f f v f f f f v m / ] / % L % L o q o q $ Y t Y t t t t , C C - C t C C C - , C - t - , t , , t Y Y Y Y Y q q q q o L o & & / k / / v v v v v f f f P ` ` 0 V 0 n V _ N _ _ # D Q Q E d l ' S @ @ A B B : : Z Z Z 6 Z 6 6 6 + M M u u u w 4 w J 4 w I J > I I I J > J J J w w w F u u + + 6 + { { 6 { Z { 6 6 6 6 Z", +" Z 1 1 1 ^ ^ ^ ^ ^ - - ^ - - - - - - - - p - - p p p p p ~ ~ ~ ~ 6 x M 6 { { { { { i { { + + M u w w J H q $ o . . . U j U d d l l ' S ' S | | | $ $ . o o & ! * m m f f f f f v f f f f f f f f f f f f f f f f v f f f m / / / & % & o o o $ $ Y Y t Y t t t , C t C C C C - C - C - C - C C , t , t , , Y t Y Y $ q Y o q L L L % & & / * < / v v v f f f P P P ` ` 0 0 G n V N _ _ 3 _ D Q Q d d l ' S 2 A B B B : : Z Z Z 6 6 { 6 6 + 6 + u u w u w w J > w I w > J > w J 4 J 4 w w u u u + M + + { 6 { 6 6 6 6 6 6 Z 6 Z", +" 1 1 1 1 ^ p ^ ^ - ^ - - } - - } - - - - - - - - - p p p p 1 ~ ~ ~ 6 6 6 6 { { { { { { { i + F u w w R q Y q o $ . . . j j U U l l l ' S ' | | $ $ o o % % ] ] m f f f v f f v f f f f f f f f f f f f f v f f f f / m m / % & o o o q q $ q $ $ $ t t t C t C C C C C C C C } C C C C - C - C - C , t , t Y Y Y $ Y q q q o L g % & / / / v v v v v v f f f P P ` 0 0 0 n n V N _ _ _ # 3 Q E d l ' S @ @ A B B : : Z Z Z 6 Z 6 6 6 + M u u u F w w 4 w w w > J 4 J J J 4 I w w u 4 u u u M M { 6 { 6 { 6 { 6 { 6 6 6 Z Z", +" 1 : 1 ^ ^ ^ ^ - B - } } - } } - C } } - - - - - ^ - p p p p ~ ~ ~ 6 M 6 6 { 6 { { { { { { + + M u w w J q q $ o . . . U j E d d l ' ' ' ' S | | $ $ o o % % ] m m P f f f f f f f v f f f f f f f f v f v f f f f m m m / ] % % o L o $ o q Y $ t t t C t C C C C C C } C 2 C 2 } C 2 C C C } C , C , t , t Y Y q Y q q q L o L L * & / * / v v v v f v f f P P ` ` ` 0 7 G n G N _ 3 # D D Q E d l ' S @ @ A B B : : Z Z Z 6 Z { Z 6 6 + M x u u w w w 4 J 4 J J > w > w w w w w u u u + M + + 6 { { 6 6 6 { Z Z 6 Z Z Z", +" : 1 : ^ ^ ^ ^ } - } - } } } C } C } C } C } } - - - - ^ p p p 1 ~ ~ ~ 6 6 6 { { { { { { { i + u F w J J H q $ o . o 3 j j U j d d l ' ' ' 9 | | W $ r o r & % ] m m P f f f v f v f f f f f f f f v f f f f f f f v / ] * % & L o o q o $ $ t $ t t t t C C C C C 2 C 2 C 2 } 2 C 2 } C } C } C C C t C , , t t t Y Y $ $ q q o L % L % * / k m v f v v f f f f P P ` ` 0 0 7 n V N _ N _ # 3 Q Q d d ' S @ @ A A : : : Z Z Z 6 Z Z { 6 6 6 M M u u u w w w w w w w 4 w w 4 w u 4 w u F u M M + 6 { { Z { { 6 6 6 Z 6 Z Z Z", +" 1 : ^ ^ ^ ^ } ^ } } } C 2 C } 2 2 } C 2 } C } - } - ^ - p ^ p 1 1 ~ 6 ~ 6 6 { 6 { { { { { { + + u u w J J q q o o W . r E j U d d l l ' ' S 9 9 9 | | $ . o o % ] ] m m f f f f f f f v f v f v f v f f v f f f f f m m ] * ] % o % o o o Y $ $ t $ t t C C C 2 C 2 C 2 2 2 C 2 2 C 2 2 2 2 C C } C C C C t t t t Y Y q Y o q q o L L * * / m / / v v f v f f f P P ` ` ` 0 0 7 n G N N 3 # # D Q E d l ' S @ A A B B : : Z Z Z Z 6 Z 6 6 + 6 M M u u u 4 w w w w w w w w w w w u u u u M M M { 6 { 6 6 6 6 6 6 Z 6 Z Z Z :", +" : ^ : ^ ^ } B } } } 2 } 2 } 2 2 C 2 2 C 2 C } C } - - - ^ ^ p p 1 1 ~ 6 6 6 Z { { { { { { { + F + w w w J q q $ o o r j . ( E j d d l l ' ' S | | W $ o o % % ] ] m P P f f f v f f f f v f f f v f f f f f f m m m ] / % & o L o q $ $ Y $ $ t t t C t C C 2 C 2 2 C 2 2 2 2 2 2 } 2 C 2 2 2 C C C C C C , t t t Y $ q $ q q o o & % & / m m v f v v f f f f P P ` ` 0 0 V 7 7 n _ N _ # 3 D Q E d l ' S @ A A B : : Z Z Z Z 6 6 6 6 6 6 M u u u u w u w 4 w 4 w w 4 w u 4 u u u M u + 6 6 { 6 6 { 6 6 { 6 Z 6 Z Z : Z", +" : ^ ^ B ^ } } } } } 2 } 2 2 2 2 2 2 2 2 2 2 2 } } } } - - ^ ^ p p 1 1 ~ Z 6 6 6 6 { { { { { { + + u 4. J H q o o W r . 3 ( ( j E d l l ' ' ' 9 9 | | | $ . o % % ] ] m m f P f f f f v f v f f v f f f f f f f P m m ] * ! % o % o $ o $ o $ t $ t C 2 C 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 C 2 C 2 C C C , C t t t $ Y $ q q o L L % & & / * < m v f v f v f f P P P ` ` 0 0 7 n G n _ _ _ # D D E E l ' S @ @ A B B : : : Z Z Z 6 6 6 6 M 6 M u u u u w u w. w w u w u w u u u u u M M + 6 { 6 { Z { Z Z 6 6 Z Z Z Z :", +" : : ^ ^ } B } } 2 } 2 2 2 2 2 2 2 2 2 2 2 2 2 C 2 C } } } - ^ ^ p 1 1 1 6 6 6 6 6 { { { { { { + F M w w J H I q $ o r r . ( ( U E d d l ' ' ' 9 9 | W $ . o o % % ] ] m P f P f f f f f f f f f f f f f f f f m m m ] / % % L o o o o $ t t $ t t t 2 C 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 C 2 C C C t C t t Y $ Y $ o q q o L % L ] / m / f v f v f f f f f P P ` 0 0 0 7 7 G N _ _ # _ D Q E d l ' @ @ A B B B : : Z Z Z 6 Z 6 6 6 6 6 M M u u u u u w u w w u w w u u u M M M 6 M 6 { 6 6 6 6 Z { Z Z Z Z Z : :", +" ^ ^ B B } } } } } 2 2 2 2 2 2 2 2 2 2 2 2 2 } C } - } ^ ^ ^ p 1 1 Z Z 6 6 { 6 { { { { { { M M u 4 J J q q o o . o 3 . ( ( E d d l l ' ' 9 9 9 | | $ o . % % % ] m m P P f f f f f f f f v f f f f f f P m m m ] % % % L % o $ o $ t W $ | C t 2 C 2 S 2 S 2 2 S 2 S 2 2 2 2 2 2 2 2 2 2 C 2 C C t t $ Y $ q $ o o o L * % * / / m v f v f f f f P P P ` ` 0 0 7 7 7 N N N 3 # D D Q E d ' S S @ A A B B : : : Z Z Z 6 6 6 6 M 6 u M x u u w u w u u 4 M u u u u u M M M { 6 6 6 { 6 6 Z Z Z Z Z : Z : :", +" : ^ B ^ B } } A } 2 2 2 2 2 S @ S 2 2 2 2 2 } } } } - ^ ^ p 1 Z Z 6 6 6 6 Z { { { { + + F u w w J H q o o o r . 3 ( ( ( E d l l ' ' ' 9 9 | W $ . o % L ] ! ] m f P P f f f f f f f f f f f f P f ] m m % / & % o o o o $ $ $ $ t | t t 2 S 2 2 2 S @ 2 S 2 S @ S @ @ 2 2 2 2 2 2 2 2 t C C t t t $ $ $ $ o q L o o & ] / / m f f v f v f f f P P P ` ` 0 0 7 n 7 N _ N # _ D Q E d l ' S @ A A B : : : Z : Z Z 6 Z 6 6 6 6 6 x u u u u u u u u u w u u u M M M + 6 6 6 { 6 Z { Z { 6 6 Z Z Z Z : :", +" ^ B B } } } } 2 2 2 2 2 2 S S S S S 2 2 2 2 } } - B ^ ^ : p 1 1 Z 6 6 { { 6 { { { { + M u u w J I I q o o r r r j ( Q j E d l l ' ' 9 9 | | | r o . % % ! ] m m m P f P f f f f f f f f P f P P m m m ] ] % % % % o o $ $ $ $ $ | | t S 2 S 2 @ S S S S @ S S 2 S 2 2 C C C t t t t $ Y q $ o o L L % & / m / m v f v f f f f f P P ` ` ` 0 0 7 7 V N N _ # # D Q E d l ' S @ A A A B : : : Z Z Z 6 Z 6 6 6 x 6 M x u u u u u w u u u u u u M x 6 6 6 6 6 6 { Z 6 Z Z 6 Z Z : : : :", +" : ^ B B } } A } A 2 2 @ 2 S S S S S S S S 2 2 C 2 2 } } } ^ ^ : 1 Z Z 6 Z 6 Z { 6 { { { + + M 4 w J H q q o o r r 3 3 3 ( E E d l l ' ' ' 9 9 W | 9 o . o % % ] ] V m P f P f P f f P f f P f f P m ] m ] / % ] % o o o o W $ $ $ | t | t 2 2 S 2 S S @ S S 2 S S S S @ S @ 2 S 2 2 C C C | C $ t $ $ o q o o % % L ] / f / f v f f v f f f P P P ` ` 0 0 7 7 n N N G # # D D Q E d ' S @ A A B B : : : Z : Z Z 6 6 6 M 6 x 6 M x u u u u u x u u u M u 6 M 6 6 { 6 { Z 6 6 Z 6 Z Z Z Z Z : : :", +" B B B } } A A 2 2 @ 2 S S S S S 9 ' 9 S 9 S S S 2 2 2 2 } } - B ^ ^ 1 1 : 6 Z 6 { 6 6 { 6 { + + u u u > w I q o o o r r j ( ( ( E E d l l ' ' 9 9 9 | W . o o % % % ] m m ] P P f P f P f f P f P P m P m m ! ] % % L % o o W $ $ W | t | | S 2 S S S S S S S S S S S S S S S @ S @ 2 2 C C t t t $ t $ $ o q o L % * % * m m / f f v f f f f f P P ` ` ` 0 0 7 7 n N N _ _ # D Q E d l ' S @ @ A A B : : : : Z Z Z Z 6 Z 6 M 6 x u 6 u x u M u u x 6 u 6 M 6 M 6 6 6 6 6 Z { Z 6 6 Z Z Z : : : :", +" ^ B } B A } 2 A @ 2 @ 2 S S S 9 S ' S ' ' ' ' S S 2 2 2 } } } ^ ^ ^ : Z Z 6 Z 6 6 { { { { + + u F w w J I q L % o r r r 3 3 ( Q E d l l ' ' 9 9 9 W | o . . % % ! ] ] ] P m P P f P f P P f P f P m m m ! * ] % % % o W o . o $ $ | | | 9 t 9 S S S S S S S S S S S S S S S S S S S S 2 S @ 2 t t $ t $ q $ o o o % & ] / / m f f f v f f f f f P P ` ` 0 0 0 7 7 n N N # _ D D Q E d l ' @ A A A B B : : Z : : Z 6 Z 6 6 6 6 6 x 6 x 6 u x M x M x M x 6 M 6 + 6 6 Z { Z Z 6 6 Z Z Z : Z : : ^", +" B B B } } A 2 2 2 @ S S S S S ' 9 ' ' 9 ' ' 9 S ' @ 2 2 } } } ^ ^ ^ : Z Z Z 6 6 6 6 { { { { + + u w w J I q q o o % r 3 3 ( ( Q E d d l ' ' ' 9 O | | W . o o % % ] ! ] m m P P P P P f P P P m m ` m ! m ! % & r % o o . $ $ W | | | t S S S S S S S S ' S ' ' S ' S S S S S S S @ S 2 2 t $ t $ $ $ $ o L o o % * ] m m f f f v f f f f P f P P ` ` 0 0 7 7 N N N _ _ # D D E d l ' ' @ @ A B B B : : Z Z Z Z Z 6 Z 6 6 x M 6 x u x x M x x M 6 x M 6 6 6 6 6 6 Z { Z 6 6 Z Z Z Z : : : B", +" B B B } A A A 2 @ 2 S 2 S S ' ' ' ' ' ' ' ' ' ' 9 ' S S S 2 2 2 2 } } B ^ B : Z Z Z 6 6 { Z { 6 + + + u u 4 J I I L o o % r r 3 3 3 ( E d d l l l ' 9 9 U | W o . r % % ! ] ] ] V P m P f P P P P m ` m m m ! ] ] ! % % o o o o $ $ | $ | | 9 9 S 9 S S S S S ' S ' S ' S ' S ' S ' ' ' S ' S S S S S S 2 t C | $ $ $ $ o o o & % L ] / m m f f f f v f f f f P P ` ` ` 0 0 7 7 7 N N _ _ # D Q E d l ' S @ A B B B : : : : : Z Z Z 6 ~ 6 6 6 x 6 x 6 M x 6 M x M x 6 6 6 6 6 6 6 Z Z 6 Z Z 6 Z Z : : : : B", +" B B B A } A 2 @ @ @ S S S ' ' ' ' ' ' l ' ' ' ' ' ' S S 2 2 A } } B ^ ^ : Z Z Z 6 6 6 { { { { + M u u w w J I q L % o r r 3 3 ( Q Q E d d ' ' l 9 9 9 | W . o . % % ! ] ] m m m P m P P m P m P m ] ] ] ] % ] % % o r o . . $ $ W | | | | 9 S S ' S 9 S S ' S ' ' ' ' ' ' ' S ' S ' ' S ' S S S S S 2 | t $ $ $ o $ o o % % / % m / f f f v f f f f P f P P ` ` 0 0 7 7 7 N N N # # D D Q E l ' S @ @ A A B B : : : : Z Z Z Z 6 Z ~ 6 x M 6 x x 6 x x 6 x 6 M 6 6 6 6 6 6 Z 6 Z 6 Z 6 Z Z Z : : : B", +" B B B A } A A 2 2 @ @ S ' S ' ' ' ' l 9 l ' O l ' ' 9 ' S 2 S 2 2 } } } B : : : Z Z Z 6 6 6 6 6 6 + + + u 4 w I H T o o % ! r r 3 3 3 Q E d d l l ' ' 9 O | | W o . r % % % ] ] ] V m 0 m m P m ` m ] m ] m % ] ] % % o r o o r $ W $ | t | 9 | 9 9 S ' S S ' S ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' S ' S ' S S S S t | C | t $ $ $ o o o L % % / m m f f f f f f f f f f P P P ` ` 0 0 7 7 n n N _ _ # D Q E d l ' S @ A A B B B : : Z : Z Z Z Z 6 6 6 Z 6 ~ 6 M x 6 x M 6 x 6 6 6 6 6 Z 6 6 6 Z 6 Z Z Z Z : : : : B", +" B B B } A A A @ @ @ S S ' S ' ' l l l ' l l ' l ' ' ' ' S S 2 @ 2 A } } ^ ^ : Z Z Z 6 6 { { { { { + u u u w J > q L o o % r r G 3 ( ( Q E d l l ' l 9 O O | W . r o % % ! ] ! ] ] m m P V P m m P V m ] ] ] % % % % o o . . $ $ W W | | 9 | 9 9 9 S 9 S ' S ' ' ' S ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' S ' S S S S S S 9 t | | $ $ $ o o o % % % / ] m m f f f v f v f f f P P P ` ` ` 0 0 7 7 n N N _ # # D Q E d ' ' S @ A A B B : B : Z : Z Z Z Z Z 6 ~ x 6 x Z x M 6 x 6 M ~ 6 6 6 6 6 Z 6 Z 6 Z Z 6 Z Z : : : : :", +" B B B A } A A 2 @ 2 S S S ' ' ' ' l ' l l l l l l l l ' ' ' S S @ 2 2 } } B : : : Z Z 6 Z 6 6 6 6 { M + M w 4 J J T q L % % ! 3 3 3 3 ( Q E d l l l ' 9 9 U | W W . r r % % ! ] ] ] ] V ] m m 0 m ] m ] ] % ] ] % % % o r o o $ r | | | | | 9 C 9 9 9 S ' ' ' S ' ' ' ' ' ' ' ' ' l ' l ' ' ' ' ' ' ' ' ' S ' S S S 9 | | $ $ $ $ o o o & % ] % / m P f f f f f f f f f P P P ` ` 0 0 7 7 7 N _ N # # D D E d l ' S @ A A A B B : : : : Z Z Z Z 6 Z 6 6 ~ 6 x x 6 x 6 ~ x 6 6 6 Z 6 6 6 Z 6 Z 6 Z Z Z : Z : : : B", +" B B B } A A 2 @ @ @ S S S ' ' ' l ' l l l l l l l ' l ' 9 ' S 2 @ A A } B B B : Z Z Z 6 6 { 6 { 6 { M u 4 u J > H L o o % r r G 3 3 D Q E d d l l ' l 9 O | W W o . o r % ! ! ] ] ] m ` m V m ] V ] ] ] ] % % % % r o r . . $ W | W | | 9 | 9 9 9 S 9 S ' ' S ' ' ' ' ' ' ' l ' l ' l ' l ' ' ' ' ' ' ' S ' ' S S 9 9 9 | | | $ W $ o o o r % % / ] m m f f f f v f f f f P P P ` ` 0 0 0 7 7 n N N _ _ # D E E d l S S @ A A A B : B : : : Z Z Z Z Z 6 ~ 6 Z M Z x 6 x 6 6 x ~ 6 6 Z 6 Z 6 Z Z 6 Z Z Z Z : : : B B", +" B B B } A A A @ 2 @ S S S ' ' ' ' l l l l l l l l l l l ' ' ' S S 2 2 A } } B : : : Z Z Z 6 6 6 { 6 + + M u w w J T q L % % % r 5 r D 3 ( E E d l l ' O 9 O O W W . r r % % ! % ] ] ` ] ] V m ] ] m V m % ] ! ! % % % r o . o . $ $ | 9 | | 9 9 9 9 9 9 S ' 9 ' ' ' ' ' ' ' ' l ' l l ' l l ' l l l l ' ' ' ' ' S ' ' S S S 9 | | | | $ $ W . o o & % ] % m m P f f f f f f f f f f P P ` ` 0 0 7 7 n n _ N # # D Q Q d l ' S @ A A A B B B : : : : Z Z Z Z Z Z 6 ~ ~ ~ 6 x ~ 6 x Z 6 6 Z 6 6 Z 6 6 Z Z Z Z Z Z : : : B :", +" B B A B A A 2 @ @ @ S S S ' ' ' l l l l l d l l l l l l ' ' ' S S S 2 2 A } B B : : Z Z 6 6 6 { { 6 { M M u 4 J J > L L o % % 5 r G 3 3 D Q E d d l ' ' l 9 | | W W . r r % % ! ] ] % ] ` ] ] ] P ] ] ] ] ] % % % r o r . o . . W W | W | 9 9 | 9 9 S S 9 ' ' ' ' ' ' ' l l ' l ' l l l l l l l ' l ' l ' ' ' ' ' ' S ' 9 S 9 9 9 C | | | $ . $ o o o r % ] * m m P f f f f v f f f f P P P P ` ` 0 0 7 7 n N N _ _ # D Q E d l ' S @ A A B B B B : : Z : Z Z Z Z 6 ~ 6 Z M ~ 6 ~ 6 ~ 6 x 6 Z 6 Z 6 Z Z 6 Z Z Z Z Z : : : B :", +" B B B A A A A 2 @ @ S S S S ' l ' l l l l l d l d l l l l l ' ' S S @ 2 A } A B : : Z Z Z Z 6 6 Z { 6 + u u w w J I q o L % % % 5 3 G D ( Q E d d l l l 9 O O O W . o r r % % ! ! ! ] ] ] m ` ] ] ] ] ! ] ! % ! % % r o . o . o | W | | O | 9 9 9 9 9 9 ' ' ' ' ' ' l ' l ' l ' l l l l l l l l l l l l l ' l ' ' ' ' S ' S 9 9 9 9 | W | $ $ W o o o % % ! ] ] m P f f f f f f f f f f P P ` ` ` 0 7 7 7 n N _ # # D D E d l ' S @ @ A A B B B : : : : Z Z Z Z ~ 1 6 ~ ~ ~ 6 ~ ~ 6 ~ 6 Z 6 Z 6 Z 6 Z Z 6 Z Z Z : : : : : B", +" B B B A B A A @ @ @ S S S ' ' ' l l l d d d d d l d l l l ' ' ' S @ @ 2 A B B B : : : Z 6 { 6 6 { 6 + + u 4 w J > > L % L % ! r G 3 3 3 Q Q E d l l ' l 9 O | W W . . r % r ! ! ] ! ] ] ] ] ] ] ] ] ] ] % ! % % % r r r W o W W | W | | O 9 9 9 ' 9 S ' 9 ' ' ' ' ' l ' l l l l l l l l l l l l l l ' l ' l ' ' ' ' ' 9 S ' 9 9 | | | | W $ o . o o o % ] % m m f P f f f v f f f f f P P ` ` ` 0 0 7 7 7 N N N # # D Q E d l ' S @ @ A A B B : : : : : Z : Z Z 6 ~ Z 6 ~ ~ x ~ 6 ~ 6 Z 6 Z 6 Z Z Z Z Z Z Z Z : : : : B :", +" B B B B A A A 2 @ @ @ S S S ' ' ' l l l l d l d d d d d l l l ' ' S S @ 2 A B B B : : Z Z Z Z 6 { 6 { 6 M u u w w I T q & % % % 5 5 3 _ D 3 Q E d l l l ' O O O W W . r r r r % ! ! ] ! ] ] ] ] ] ] ] ! ! ! ] % r % r o o . W . W W | | O | 9 9 9 9 9 ' 9 ' ' ' l ' l ' l ' l l l l l l l l l l l l l l l l l ' l ' ' ' ' ' 9 S 9 9 9 9 9 | | W $ W o . o ! L ] ] ] m m P f f f f v f f f f f P P ` ` 0 0 7 7 n n N N # # D Q E d l ' @ @ A A A B B B B : : : Z 1 Z ~ Z Z ~ ~ 6 ~ 6 6 ~ ~ ~ Z 6 Z Z 6 Z 6 Z Z Z Z Z : Z : : : B", +" B B B A A A A @ A @ S S S ' ' ' l l l l d d d d d d d d l l l ' ' ' S @ 2 A } A B B : Z Z Z 6 6 6 6 { 6 + M w 4 J J > L L % % ! r 5 3 r 3 D Q E E d l l l 9 O O O W . . o r % % ! ! ! ! ] ] ] ] ] ! ] ] % ! ! % % % r r . o . W W | . O | O 9 9 9 9 ' 9 ' ' ' ' ' l ' l ' l l l l l l l l l d l l l l l l l ' l ' l ' ' ' ' S 9 9 9 9 9 | | | | W $ . o r o % % ] m ] m P f f f f f v f f f P f P P ` ` 0 0 7 7 7 N N N # # D Q E d l ' S @ A A A B B : : : : : Z Z Z 1 Z 1 6 ~ ~ ~ ~ Z ~ 6 ~ 6 Z 6 Z Z Z Z Z Z Z Z : : : : B :", +" B B B B } A A A @ @ @ S S S ' l ' l l l l d l d d l d d d l l l ' ' S @ @ 2 A B B : : : Z 6 Z Z { 6 6 + M M u w w J T L L L % % ! 5 G G D 3 Q Q d d l l ' l 9 O W W . . r r r ! % ! ! ] V ] V ] ! ] ! ] ! ] ! r % r o o r . . o W W W | O | O 9 O 9 ' 9 ' ' ' ' l ' l ' l l l l l l l l d l l d l d l d l l l l l ' l ' ' ' ' ' S 9 9 9 9 9 | | W $ o . o o % % % ] ] m P P f f f f v f f f f P P P ` ` ` 0 7 7 n n N N # # D D E d l ' S @ A A A B B B B : : : : 1 Z 1 Z ~ 1 Z ~ 6 ~ ~ 6 ~ ~ Z 6 Z Z Z Z Z Z Z Z : Z : Z : : B", +" B B B A B A A @ 2 @ @ S S ' ' ' l l l l d d d d d d d d l d l l ' ' S S @ 2 A A B B : : Z Z Z 6 6 6 { 6 6 + u w 4 J > q L % % ] ! 5 r G ( 3 ( Q E d l l l ' O O O W W . r r r % ! ! ! ! ] ! ] V ] V ] ! ! ! % % % r r r . o . W W W | | O O | O 9 9 l 9 ' l ' l ' l ' l l l l l l d l d l d l d l d l l d l l l l l ' ' ' ' ' ' 9 ' 9 9 9 | O | W W $ . o r o % ] ! ] m m P f f f f f v f f f f P P P ` ` 0 0 7 7 7 N N _ _ D D Q E d ' ' S @ @ A A B B : B : : Z : Z Z 1 Z 6 ~ 1 ~ ~ ~ ~ ~ ~ Z Z 6 Z 6 Z Z Z Z Z Z : : : : : B", +" : B B B B A A A A @ S @ S S ' ' ' ' l d l d d d d d d d d d l l l ' ' S @ @ A A A B : : Z Z 6 Z Z { 6 6 + u u w w J I L L & % % % 5 5 G # 3 D Q E d d l l l 9 O O U . . . r r r r ! ! ! % ] V ] ] % ] ! ! ! ! ! r r % r r r . . W W W U | O O 9 9 O 9 ' 9 ' ' ' ' l l ' l l l l d l l d d l d d d l d d l d l l l l l l l ' ' ' ' 9 9 9 9 9 | | | W W o . r o % % ] ] V m P P f f f v f v f f f f P P ` ` ` 0 7 7 n n N N # # D Q E d l ' S @ A A A B B B : : : : : 1 1 Z ~ 1 Z ~ 6 ~ ~ ~ ~ 6 ~ Z Z Z Z Z Z Z Z : Z : Z : : B :", +" B B B B A A A A @ @ @ S S S ' ' l l l l d d d d d d d d l d l l l ' ' S S 2 2 A B B B : : Z Z 6 Z 6 6 { 6 M u w 4 J > T T L * ! ! ! 5 G 3 3 3 Q E E d l l ' l O O | W . . r r % % ! ! ! V ! ! ] ! ] ! ! ! ! % % r % r r . o . . W W | W O | O 9 O 9 ' l l ' l ' l ' l l l l l l l d d l d d d l d d l d d l d l l l ' ' l ' ' ' ' 9 ' 9 O 9 O | W W W . o . r % % ! ! ] m P P f f f f f v f f f f P P P ` ` 0 0 7 7 7 N N _ # D D E E l ' ' @ @ A A A B B B : : : : Z : 1 Z ~ ~ 1 ~ ~ 6 ~ ~ ~ 6 ~ 6 Z Z Z Z Z Z Z : Z : : : : B", +" : B B B B B A A A @ @ @ S S S ' ' ' l l l d d d E E d d d d d l l ' ' S S @ @ A A B : : : Z Z Z Z { 6 6 M M M w w J H T L % & % % ! 5 G 3 _ D Q E E d l l l 9 O O U W . W r r r r ! ! ! ! ] ] V ! ! ] ! ! ! ! ! % r r r r j o . W W W O | O O O O 9 O 9 ' 9 ' l ' l ' l l l l l d l d l d d d d l d d d d l d l l l l l ' l ' l ' ' ' 9 9 O 9 O | | $ W o . r o % % ] ] m m P P f f v f v f v f f f P P ` ` 0 0 7 7 7 N N N # # D Q E d l ' @ @ @ A A B B B B : : : : Z 1 1 Z Z ~ ~ 1 ~ ~ Z ~ ~ Z Z Z Z Z Z Z Z Z Z : : : : : :", +" B : B B A A B A @ @ @ @ S S ' ' ' l l l d d d d d d E d d d d l l l ' ' S @ @ @ A A B B : : Z 6 Z Z 6 6 6 + M w u > J > L L % % ] ! 5 G 3 _ 3 D Q E d d l l l O O O W . . r r r r % ! ! ! ! V ] V ] ! ! ] ! % ! r % r r . r . . . W W W O | O O 9 O ' O ' l ' l ' l l l l l d l l d l d d d d d d d l d l d d l d l l l l l l ' ' O ' O 9 9 O | U | . W . o r % r % ] ! ] P P P f f f f f v f f f f f P P ` ` 0 0 7 7 n N N _ # D Q Q d l ' S @ @ A A B B B : B : : : Z 1 Z 1 ~ Z ~ ~ ~ ~ ~ ~ ~ ~ ~ Z Z Z Z : Z : : : : Z : : B", +" : B B B B B A A A @ @ @ @ S S ' ' ' l l l d d d E d E d d d d d l l ' ' S S @ A A A B : : Z Z 6 Z 6 6 { 6 M u u w 4 > > L L & * % ! 5 5 3 G 3 Q Q E d d l ' l 9 O U U W . . r r r r ! ! ! ! ! ! ] ! ] ! ! ! ! ! r % r r o r o . . W U W W U | O O 9 l 9 l 9 l ' l ' l l l l l d l d l d d l d d d d d d d d d d l d l l l l ' l ' l ' ' 9 9 O 9 | O W W . W r . % % % ] ] ] P P P f f v f v f v f f f P P P ` 0 0 7 7 n n _ N # # D Q E l ' ' S @ A A A B B B : : : : : : 1 1 1 ~ 1 ~ 1 ~ ~ ~ ~ Z ~ Z Z Z Z Z Z Z Z Z : : : : :", +" B : B B B A A A A @ @ @ S @ S ' ' ' l l d l d d E d E E d E d d d l l ' ' S @ 2 A A B B : : : Z Z 6 6 6 6 + M w u J J > T L % % ] ! ! 5 G # 3 3 Q E d d l l l O O O W W . r . r r ! % ! ! ! V ] V ! V ! ! ! % ! r % r r r . . . . W W W O O O O 9 O 9 l 9 l ' l l l ' l l l l l d l d d d d d d d d d d d d d l d l d l l l l ' l ' O ' O 9 O O O | | W W o . r % % ! ! ] ] m P P f f f f v f v f f f P P ` ` ` 0 0 7 7 N N N # # D Q E d l ' S @ @ A A B B B B : : : 1 Z 1 1 1 1 ~ ~ ~ 1 ~ 1 ~ ~ ~ Z Z Z Z Z : Z : : : : : : :", +" B : B B B A B A A A @ @ @ S S ' ' ' l l l d d d d E E d E d d d d l l ' S S @ @ A A B B : : Z Z 6 Z 6 6 6 6 u u w w I I T L L & ] ! ! 5 G G # 3 Q E E d d l l ' O O U W . . r 5 r r 5 ! ! ! ! V ! V ] ! ! ! ! ! G % r r r r r . . . W U W W | O O O O l 9 l ' l ' l l l l l d l d l d d d d d d d E d d d d d d d l d l l l l l ' l ' l ' 9 9 9 O O O W W j o . r % ! ! ] V m P P P f f f v f v f f f f P P P ` 0 0 7 7 7 N N _ # D D Q d l ' S @ @ A A A B B : B : : : : 1 1 1 1 ~ 1 ~ ~ ~ ~ ~ 1 ~ ~ Z Z : Z Z Z Z Z : : : : :", +" : B B B B B A A A A @ @ @ S S S ' l ' l d d d d E d E E d d E d d l l ' ' ' S @ @ A A B : : : Z Z Z { Z { 6 6 u w 4 w > T L * % ] % ! 5 5 3 3 3 D Q E d l l ' l O O U W . . r r r % 5 ! ! ! ! ] ! ] ! V ! ! ! 5 % 5 r r r r r W . . W W U U O O O 9 O ' O ' l ' l ' l l l l l l d d d l d d d E d d d d d d d d d d d l l l l l l ' l 9 l O O O O | W W W . . r r r % ! ] ] ] P P f f f f v f v f v f f P P ` ` ` 0 7 7 7 N n N # # D E E d ' ' S @ A A B B B B : : : : 1 1 1 1 ~ 1 ~ ~ ~ ~ ~ ~ ~ ~ 1 ~ ~ Z Z : Z : Z : : : : :", +" B : : B B B B A A A @ @ @ @ S S ' ' l l l l d d d E d E E E d d d l l l ' ' S @ @ A B B : : : Z Z Z Z 6 6 M M u w w J I T g o & & ] ! G 5 G G D Q Q E d d l l l O O U U . . . r r r r ! ! ! V ! V ! V ! ! ! ! ! ! % % r r r . r . . . W W W | O O O O ' O ' O ' l l l l l l d l d l d d d d d d d E d d E d d d d d l d d l l l l l l ' l ' 9 9 O U | O W W . o r r % ! ! ] ] ` P P f f f f v f v f f f f P P ` ` 0 0 7 7 n N N _ # D Q E d l S S @ @ A A B B B B : : : : 1 1 1 1 1 ~ 1 8 ~ 8 ~ 8 ~ ~ ~ 1 Z Z Z Z : Z : Z : : :", +" : B : B B B A B A A A @ @ S S S ' ' ' l l d l d E E E E d E E d d d l l ' ' S @ @ A A B B B : Z Z Z 6 Z 6 6 M u w w 4 > I L & % ] % ] ! G G 3 3 3 Q E d d l l ' l O O W j . j r r r ! 5 ! ! ! V ] V ] V ! ! ! 5 % 5 r r r r r . . . W U W U O O O O O O ' O ' l ' l l l l l l d l d d d d d d d d d d E d d d d d d l d l l l l ' l ' l 9 l O O O O O W W . . . r r % r ! ! ] ] P P P f f v f v v f v f f f P ` ` ` 0 7 7 7 N N _ # D D E d l ' S @ @ A A A B B B : : ^ : 1 1 1 1 ~ p ~ 8 ~ p ~ ~ 8 ~ 1 ~ ~ 1 : Z Z : Z : : : :", +" : B : B B B B A A A A @ @ @ S S S ' ' l l d d d d d E E E E d E d d l l ' ' S S @ @ A A B : : Z Z Z 6 6 Z M 6 u u w w J T T L & & ] ! ! 5 G G _ D Q Q d d d l l O O U U . . r . 5 r r ! ! ! V ! V ! V ! V ! ! ! ! % 5 r r r r . . . . . W U W O O O O O l 9 l l l ' l l l l d l d d l d d d d d d E d d d E d d d d d l d l d l l l l l ' l ' 9 O O O O U W . r . r r % ! ] ` ] ] P P f f f f v f v f f f f P P ` ` 0 0 7 n n N _ _ # D Q E l l ' @ @ A A A B B : B B : : : 1 1 8 1 8 ~ ~ 1 8 ~ ~ ~ ~ 8 ~ 1 ~ Z Z : Z : : : : :", +" : : B : B B B A A A A @ @ @ S S S ' ' l l l d d d E E E E d E d d d d l ' ' S S @ @ A A B B : : : Z Z 6 6 6 6 u w w J 4 L T & % / ] % V G 5 G ( 3 Q Q E d l l ' l O O U W j . r r r 5 ! 5 ! ! V V ] ! V ! V ! ! 5 ! r r r r r r . . . . U W U U O O O O l O ' O ' l l l l l l l d l d d l d d d d E d E d d d d d d d d d l d l l l ' l l 9 l O 9 O O W W W W . r r r r ! ! V ] P P P f f f v f v v v f f f P P P ` 0 0 7 7 n N N # # D Q E d l S S @ @ A A B B B : : : : p 1 1 1 8 1 p ~ 8 ~ ~ 8 8 ~ ~ p ~ ~ 1 1 Z Z : : Z : :", +" : B : B B B B B A A A A @ @ @ S S ' ' ' l l d d d E d E E E E E d d d l l ' S S @ @ A A B B : : Z Z Z 6 6 6 6 u M w J J > L L * L ] ] ! 5 G G # 3 D E E d d l l l O O U j . . 3 r r r 5 ! ! V ! V ! V ] ! V ! ! ! 5 ! 5 5 r r r 3 . . . . W U W O O O O l 9 l l l l ' l l l l l d l d d d d d d d d E d d d E d d d d d l d l l l l l l l l 9 l O O O O U U . . . r r r % ! ! ] ] ` P P f f f f v v f v f f f P P ` ` 0 7 7 n N _ N # D D E d l ' S @ @ A A A B B B : ^ 1 : p 1 p Z 8 ~ 8 8 ~ 8 p ~ 8 p ~ 8 1 ~ 1 : Z : Z : : :", +" : : : B B B B B A A A @ @ @ @ S S ' ' ' l l d d d d E E E E E E d d d l l l ' S @ @ A A B B : : : Z Z Z 6 6 6 u u w w > > > g & % * ! ] ! G G G ( 3 Q E d l l l ' l U U W . . r r r 5 ! ! ! ! V ] V V ! V V ! ! ! ! r % r r r r . r . . U U W U U O O O O l ' l ' l l l l l l d l d d l d d d d E d d d E d d E d d d d d d l d l l l ' l ' l O ' O O O W W W . . r r r 5 ! ! ] ] P P P f f f v f v v f v f f P P ` ` 0 0 7 7 n N N # # D E d l ' ' @ @ A A B B B B B : : ^ 1 1 p ~ p 8 p ~ 8 ~ 8 ~ ~ 8 ~ ~ ~ 1 ~ 1 1 : : : : :", +" : : : B : B B B B A A A @ @ @ S S S ' ' l l l d d E d E E E E E E d d d l ' ' S @ @ A A A B : : : Z : 6 Z 6 6 x u w w w > T L g % / ] ] V 5 G G D D Q E E d d l l O O U U . . r 3 r r 5 5 ! V ! V ! ] V ] V ! V ! 5 ! 5 r r r 3 r 3 . . . j W U | U O O ' O O O l l ' l l l l l l d l d d d d d d d E d E d E d d d d d l d d l d l l l l l l ' l O O O O U U . . . r r r % ! 0 ] ] P P P f f v f v v v f f f f P P ` ` 0 7 7 n N _ _ # D Q E d ' ' @ @ A A A B B B : : ^ : 1 p 1 8 p ~ ~ 8 p 8 p 8 8 ~ 8 ~ p 8 1 1 1 1 Z : : :", +" : : B : B B B A B A A A @ @ @ @ S S ' ' l l d d d d E E d E E E d E d l l l ' ' S @ @ A A B B : : : Z Z 6 Z 6 M u w w J > T L & & ] % ] ! G G G # 3 Q Q d d ' l l l O U U . . j r 5 r ! ! ! V ! V ] V V V V V ! V ! ! 5 ! r r r . r . . . . U U U U O O O l ' l 9 l l l l l l d l l d d d d d d E d d d E d d d E d d d d d l d l l l l ' l O l O O O O U U W W . . r r r 5 ! ! V ` ` P P f f f v v f v v f f f P P ` 0 0 0 7 7 n N _ # D Q E d l ' S @ @ A A B B B B : ^ : p 1 p p 8 8 8 8 ~. 8. p 8 8 8 ~ p ~ p 1 1 1 : 1 :", +" : : : B : B B B B A A A A @ @ S S S ' ' ' l l l d E d E E E d E E d d d d l ' S S @ @ A A B B : : Z Z Z Z 6 6 x u w w 4 I > g L & * / ] V V G 3 _ 3 Q Q E d d d ' l O O U j . 3 r r 5 5 5 V ! V V V V ] V ] ! V ! ! 5 ! 5 r 5 r r j r j . j . W U U U O O O l O l l ' l ' l l l l d l d l d d d d d E d E d E d d E d d d l d d l d l l l l ' l ' l O O O O U U . j . r r r ! ! ! ] P P P f f f f v v v v v f f P P ` ` ` 7 7 7 n _ N # D D E d l ' S @ @ A A A B B : ^ : : ^ 1 8 1 p 8 ~ p 8. 8 ~ 8. p 8 ~ 8 ~ 8 1 1 1 1 1 :", +" : : : B : B B B A B A A @ A @ @ S S S ' l l d d d d d E E E E E E d d d l l ' ' S @ @ A A B B B : : : 6 Z 6 6 6 u. w J > T h & * ] ] % V ! G G G ( D Q E d l ' l l O U U . . . r r r 5 ! ! V V ] V ] V V V V V V ! ! 5 5 r r r r r j r . . j W U U O U O l O l 9 l l l l l l l l l d l d d d d d d d d d E d d E d d d d d d l d l l l l l l l O l O O O U W U . . r j r r r ! V ] ] ` P P f f v f v v v f v f f P P ` 0 0 7 7 n N N # # D E E l ' S @ @ A A B B B B : ^ ^ 1 p p p 8 ~ 8 8 ~ R. . 8. 8 ~ 8 p 8 Z p 1 1 : 1 :", +" : B : : : B B B B A A A A @ @ @ @ S ' ' ' l ' d d d d E E E E E E E d d l l ' ' S @ @ A A A B B : : : Z Z Z 6 x x w w w J > T L & ] * ] ] ! G G G D 3 Q E d d l l l O O U j . . 3 r 5 5 5 ! ! V V V V V ] V ] V V V ! ! ! 5 5 r r 3 r . j . . U W U U U O O O O l l ' l ' l l l l d l l d l d d d d d E d E d E d d d d d d d l d l l l l l l ' l 9 l l O U U W U . . . 5 r 5 ! ! V ` P P P f f f v v v v v f f f P P ` ` 0 0 7 n n _ _ # D Q E l ' ' @ @ A A A B B B B : ^ 1 p 1 ~ p 8 8 8 8. 8 8 8 8. 8 8 ~ 8 ~ 8 1 p p 1 :", +" : : : B : B B B B B A A A A @ @ S S S ' ' l l d l d E d E E E E d E E d d l l ' S S @ @ A A B B : : : Z Z Z 6 6 u u w w > > T L & & ] ] ] V G G G # 3 Q E d d l l l O O U W j j r r r 5 ! V V V ] V ] ` V ] V V V ! V 5 ! 5 r 5 r r r 3 . . . j j W U O U l O l O l l l l l l l l l d l d l d d d d d d E d E d d E d d d d d d l d l d ' l l l ' l O O O O U U j . . j r r r 5 ! V ] ` ` P f f f v f v v v v f f f P P ` 0 0 7 7 N N N # D Q E d l ' S @ @ A A B B B : ^ : p ^ p 8 p 8 p 8 8 R 8 8. R ~ R 8 p 8 ~ p ~ p 1 1 ^", +" : : : : : B : B B A B A A A @ @ @ S S ' ' ' l l d d d E E E E E E E d E l l l ' S S @ @ A A B B : : Z Z Z Z ~ 6 x w w J J > h L & & ] / ] V ! G G 3 3 Q Q d d d ' l l O U U . r 3 r r ! G ! V V V ] V V ` V ] V V V V ! 5 ! 5 5 r r 3 r r j . . . U U U O U O O O l O ' l ' l l l l l l l d d d d d d d d d d E d d E d d d d l d l d l l l l ' l O l l O O U U W j . j r r r 5 ! ! V ] ` P P f f f v v v v v v f f P P ` ` 0 7 7 n N N # D D E d l S S @ @ A A B B B B ^ ^ p 1 p p p 8 8 8. 8. R 8 R. R ~. p 8 8 p p 1 p 1", +" 1 ^ : B : B : B B B A A A A @ @ @ S S ' ' l l l d d d E E E E E E E d d d l l ' ' S @ @ A A B B B : : : Z 6 6 Z x x u w > J > g & & ] * V ! V G G # 3 D Q d d l l l O l O j . . j r 3 5 ! ! V V V V ` ] 0 ] ` V V V V ! ! 5 5 5 r r r r j . 3 U j . U U U O O l l O l l l l l l l l d l d l d l d d d d d d d d d d d d d d d d l d l l d l l l l ' l O O O U O U W . . . 3 r 5 ! ! V ] ` P P P f f v f v v v f f f f P ` ` 0 0 7 7 N _ # # D E d l ' S @ @ A A B B B : B : ^ p p 8 8 8 8 8 R 8 R 8 w. 8 R 8 8 8 8 ~ 8 1 p 1 1", +" : : : : : : B B B B B A A A @ @ S @ S S ' ' l ' d d d d E E E E E E E d d d l ' ' S S @ A A A B B : : Z Z Z Z 6 x u w w w > h L & & * ] ] ] V 5 G G 3 ( Q E d d l ' l O U U U 3 r 3 % 5 ! G V V ] V ` V ` V ` V ] V V V G ! ! 5 5 3 r r r 3 . . . . j U O U U O O l O l ' l ' l l l l l l l d l d d d d d d E d E d d d d d l d d l d l l l l ' l l O l l l O U U U j . j r r r 5 ! V ] ` ` P P f v f v v v v v v f P P P ` 0 0 7 7 N N _ # D Q E l l S @ @ A A A B B B ^ ^ p p p p 8 p R 8 R 8 J. R 8 R w 8 8 8 8 p p 8 p p 1", +" p : ^ : B : B B B B B A A A A @ @ @ S S ' ' l l d d d E E E E E E E E d d l l l ' S S @ @ A A B B : : : : Z 6 Z ~ x w w J > > T g * / ] ] ] V G G G # D Q E d l l l l O O U . . j r 5 5 5 ! V V V ` V ] ` ] ` V ` V ] V ! V 5 ! 5 r r 3 3 . 3 . j U W U U U O l O O l O l l l ' l l l l d l l d d l d d d d d d d d d d d d d d l d l l l l l l l ' l O O O O U U U . . . 3 r r r 5 V V ] ` P P f f f v v v v v f v f P P ` ` 0 7 7 n N N # D Q E l l S S @ A A A B B B : ^ ^ p p 8 p R 8 R 8 w R 8 R w R 8 R. 8 8 8 ~ 8 p 1 p", +" 1 p : : : B : B B B B B A A A @ @ @ S S ' l ' l l d d d E E E E E E E E d d l l ' S S @ A A A B B B : : Z Z Z 6 x x w w J J > h L & / * m ] V V G 3 3 3 Q E d d l l l l O U j j r 3 r 5 ! G V V V V ] ` V ` ] ` V ] V V V V ! 5 5 5 5 r r r . 3 . . U j U U U U O l O ' l ' l l l l ' d ' d l d l d d d d d d d d d d d d d d d d l d l d l l l l l l ' l O l O U U U j 3 . . 5 5 5 ! V ] ` P P P f f v v v v v v f f f P ` ` 0 7 7 7 N _ _ D D E d ' ' @ @ A A A B B B B ^ ^ p p p p 8 8 R 8 R 8 J R R. R. R R 8 8 8 p 8 p p", +" p : ^ : B : B B B B A B A A A @ @ @ S S ' ' ' l d d d d E E E E E E E d d d l l ' ' S @ @ A A B B B : : : Z Z Z ~ x u w w > > h L * & ] ] ] ] ! G G _ D Q Q d d l ' l O O U j . . 3 r 5 5 ! V V ` ] ` ` ` ` V ` ` V 0 ] V V G ! 5 5 r r 3 3 r . j j . j U U U O O l O l O l l ' l l l l l l l l d l d d d d d d d d d d d d d d l d l l l l l l ' l ' l l O O U O U U . . . 3 3 r 5 5 V V ] ` P P f f v f v v v v v f f P P ` 0 0 7 7 N N # # Q Q d l ' S @ @ A A B B B ^ : ^ p p 8 R 8 R 8 J. R R J. H R w R 8 8 R p 8 ~ p p", +" p p 1 ^ : : : : B B B B A A A @ @ @ @ S S ' ' l l l d E d E E E E E E E d d l l l S S S @ A A A B B : : : Z Z 6 ~ x. w J J J h g L / * / ] V V G G G 3 ( Q d d d l l l d O U j 3 r r 5 5 ! V V 0 ] 0 ] ` ` ` ] ` ] ` V V V ] G ! 5 5 G % r 3 3 . . j . U U U U U U l O l l ' l l l l l l l l d l l d l d d d d d d d d d d l d d l d l d l l l l l l l l l l l U U U U j 3 . r r r 5 V V ] ` P P f f f v v v v v v f f P P ` ` 0 7 7 N N _ # D Q E l ' S @ @ A B A B B B ^ ^ p , p 8 8 R. R R R J R J R J. R R. R 8 8 8 8 p", +" p p : ^ : B : B B B B A A A A A @ @ S S ' ' ' l l d d d E E E E E E E E d d d l ' ' S @ @ @ A A B B : : : Z Z Z ~ x. u w > > > g & & / ] ] ] V G 5 # _ D Q E d ' l ' l O U U . . 3 r 5 5 V V V V ` ` ` ` ` ` ` ` 0 ] 0 ] V V V ! 5 5 5 3 r r 3 r 3 . U j U U U O O l O l O l l ' l ' l l l l l l d l d l d d d d d d d d d d d d l d l l l l l ' l ' l 9 l O O O U U j . . . 3 5 5 5 ! V V ` ` P P f v v v v v v v v f f P P ` 0 0 7 7 N _ # D Q d d ' ' S @ A A A B B ^ ^ ^ p p 8 R 8 R R R w J J R J J R J R w R 8 8 R p p 8", +" p p p : ^ : B : B B B B B A A A @ @ @ @ S ' ' ' l l d d d E E E E E E E d d d l l ' ' S @ A A A B B B : : : Z 6 ~ ~. w w w > > L & & * m m ] V V G G 3 ( Q E d d l l l O O j j j 5 3 r 5 5 V V ] V ` ] ` ` ` ` ` ` ] ` ] 0 V V V ! 5 5 r 5 3 r j . ( . . j U U U U U O l O l ' l l l l l l l l l l d l l d l d d d d d d d d d l d l l d l l l l l l l l O l O d O U U U j j r 3 r r 5 ! V ` ` P P f f f v v v v v v f f P P ` ` 7 7 n N _ _ D Q E d ' ' @ @ @ A B B B B ^ ^ p , p p R. R R H R J J J J J J R J 8 R 8 8 8 8 p", +" p p p p : ^ : B B B B B A A A A @ @ @ S S ' ' l l d d d E E E E E E E E E d d l l ' S S S @ A A B B B : : : Z : 6 ~ x w w J > > h g * / * ] ] V ! G G 3 3 Q E d l l l l O O U j . 3 r 5 5 ! V V 0 ` ` ` ` ` ` ` ` ` ` 0 V ` V V V G ! 5 5 r r 5 3 r j j j . j U U l O l O l O l l ' l ' l l l l l l l l d l d d l d d d d l d l d d l d l l l l l ' l ' l ' l O O O U U U . . . 3 r G 5 ! V V ` P P P f f v v v s v v f f f P ` ` 0 7 7 n N # # D E d l ' S @ A A A B B B ^ ^ ^ p p R 8 R R J J R J R J J J J J R R w R 8 8 p 8", +" p p p p ^ ^ : B : B B B B A A A A @ @ S S S ' ' l ' d d d d E E E E E E d d d l l ' ' S @ @ A A A B B : : : Z Z ~ ~ x. w J J > T g & / * / ` ] V G G _ 3 Q Q d d d ' l l O U j . 3 r r 5 G V V V ` ] ` ` ` P ` ` ` ` ` ] ` V V V V ! V 5 5 5 3 r 3 j r j j U U U U U U O O l ' l l ' l ' l ' l l l l l l d l l d d l d l d d d l d l d l l l l l l l ' l ' O l l U O U U j j j r 3 r 5 5 V V ` ` P P f f v v v v v v v f f P ` ` 0 7 7 N _ _ _ D Q d l S S @ @ A A A B B ^ ^ p , p R 8 R R J R J J J J R J R J J H R 8 R R 8 8", +" 8 p p ^ : ^ ^ : B B B B A B A A @ @ @ @ S ' ' l l l d d d E E E E E E E E d d l l ' ' S S @ @ A A B B B : : : Z 1 ~ x. w w > > h h & & / ] m V ! V _ G ( 3 E E d ' l l O l U U . . 3 5 5 ! V 0 ] 0 ` ` P ` ` P ` P ` ` ` 0 ] 0 V V G ! G 5 r 5 3 r 3 . j j . j U U U l O l O l O ' l l l ' l l l l l l l l d l d l d d l d l d l d l l d l l l l ' l l ' l l ' O l U U U j . . . 3 r 5 5 ! V V ` P P f f v v v v v v v f f f P ` ` 0 7 7 N _ # D E E l ' S @ @ A A B B B B ^ p p , 8 R R R R H J H H H H H J J R J R J 8 8 R p", +" p 8 p p p : B : B B B B B A A A A @ @ @ S S ' ' l l l d d d E E E E E E E d d d l l ' S S @ A A A B B B : : Z 1 Z ~ x. w J J > > g & * * ] m ] V V G G # ( Q E d d l ' l O O j ( . 5 3 5 G V V 0 ] ` ` ` ` P ` P ` ` ` ` ` V ` V V V G ! 5 5 r r 3 r 3 . ( . U j U U U U O l O l l ' l ' l l ' l ' l l l l l l l d l d l d d l d l l d l l l l l l l l l ' l O l O O O U U U j r 3 r r 5 G V ] ` ` P P f f v v v s v v v f f P ` 0 0 7 7 N N _ D Q E d ' ' @ @ A A A B B ^ ^ ^ p p R 8 R R R J H J H J H J H H J J J R R 8 R 8", +" R p p p p ^ ^ ^ : B B B B A A A A @ @ @ S S ' ' l ' d d d d E E E E E E E d d d l ' ' S S @ @ A A A B B : : : Z 1 ~ ~. . w J > > g g & / * m V V V 5 G # 3 Q E d ' l l l O U U . 3 3 r ! 5 V V V ` ` ` P ` P ` P ` P P ` ` ` 0 ] V V V V ! 5 G r 3 r 3 r j ( j U U U U l U O l O ' l l ' l ' l l l ' l l l l d l l d l d l d l l d l d l l l l l ' l ' l l l ' l O l U U U j j j r 3 3 5 5 ! V 0 ` P P f f v v v v v v v f f P P ` 0 7 7 N N # _ Q E d ' ' @ @ @ A B B B B - p , , 8 R R R J J H H H H I H H H J H J R J R 8 R", +" p R 8 p p ^ ^ : B B B B A B A A A @ @ @ @ S ' ' ' l ' d d d E E E E E E E E d l l l ' ' S @ @ @ A B B B B : : 1 1 ~ ~ x w w J I > h g & * / m ] ] V G 3 G 3 ( E d d l ' ' l U U j . r 3 5 5 V V V ` ` ` ` P ` P ` P P ` ` ` ` ` ` 0 V V V G 5 5 5 5 r 3 3 r j j . j U U U O l O l O l ' l ' l ' l ' l ' l l l l l d l l d l d l d l d l l l l ' l l l l ' l ' O l O l O U U U j ( j 3 r 5 5 G V V ` P P P f f v s v s v v v f P P ` ` 7 7 7 N 3 # D E d l S S @ A A A B } ^ ^ - p , 8 R R H R H H H I H H J H I H R J H R R R 8", +" 8 p p , p p ^ ^ B : B B B B A A A A @ @ S S S ' l l d d d d d E E E E d E d E d l l ' ' S S @ A A A B B : : : : Z Z ~. . w J > T h g * / * ] m ] V V G G 3 Q Q d d l l l l O U j U 3 3 5 5 V V 0 ` ` ` P ` P P P ` P ` P ` ` ` ` V 0 V V V G 5 5 5 3 r 3 . 3 . j U j j U U O O l O ' l l ' l ' l ' l l ' l l ' l l l d l l l d l l l l d l l l l ' l ' l ' l ' l O l U O U U j . . r 3 r 5 5 V V ` ` P f f f v v v s v v v f f P ` ` 0 7 7 N _ _ D E d l ' S @ @ A A B B B ^ ^ p , 8 R R R J H H H H J I I H H H H H J J R R R", +" 8 R 8 p p ^ ^ ^ : B B B B A B A A @ @ @ @ S S ' ' ' l l d d d E E E E E E d d d l l ' ' S S @ @ A A B B B B : Z 1 1 ~ ~. . w > J h g & & / / P ] V V 5 G # ( Q E d l ' ' O l U j . 3 r r 5 G V 0 ] ` ` ` P ` P P P P P ` P ` ` ` ` ] 0 V V V G 5 5 5 r r 3 r j ( . U U U U d O l O l O ' l ' l ' ' l ' l ' l l l l l l l d l l l d l l l l l l l l ' l ' l ' O l l O l O U U U j j 3 r 3 5 5 V V V ` ` P f f v v s v v v v f f P ` ` 0 7 7 N N # D Q E l ' S @ @ A A B } B - ^ , p R R H R H H H H H I I I I J I H H J J R H 8", +" R 8 , p , p ^ ^ ^ B B B B B A A A A @ @ @ S S ' ' l l d d d E E E E E E d E d d l l l ' S S @ @ A A A B B : : : : 1 ~ 8. w w J > h g g / * m * V ] V G G 3 3 Q E d l l l ' l O j U . 3 5 5 ! V V ` ` ` P ` P P P P P P P P ` ` ` ` 0 ` V V V V 5 5 5 G r 3 3 ( j ( ( j U U U O O l O ' l ' l ' l ' ' l ' l ' l ' l l l l l l d l l l l l l l l l l l ' l ' l ' l ' l O U l j U j . j 3 r r 5 5 V V ` P P P f v v v v s v v v f f P ` 0 0 7 N N _ 3 D E d ' S @ @ A A A B B ^ - p , 8 Y R J H H H I I I > H I > H H H H J J R R", +" 8 R 8 8 p p p ^ ^ : B B B B B A A A @ @ @ S S ' ' ' l l d d d d E d E E E E d d d l l ' S S @ @ A A A B B B : : 1 1 ~ ~. . w J > > h g & * / m m ] V G 5 _ 3 ( E d l l ' l l U U ( r 3 r 5 G 0 V 0 ` ` P ` P P P P P P ` P P P ` ` ` ` 0 V V V V G 5 5 G r 3 r j r j U j U U U U l O l O l ' l ' ' l ' l ' l ' l l l l l l l l l l l l l l l l ' l ' l ' l ' l ' l O l O O U U U j j r 3 3 5 5 V V 0 ` P P f f v v v s v v v f f P ` ` 7 7 n G # # Q E d l ' @ @ @ A B } B - ^ p , , R R Y J H I H I > I I I I I I H H H R H R", +" R R 8 p , p ^ ^ ^ B B B B B A A A A @ @ @ @ S S ' l ' d l d E E E E E E E d E d l l l ' ' S S @ @ A A B B B : : : 1 1 ~. . w J I > h g c / * m m V V V 5 G ( Q Q d d ' l l O l j U j 3 G 5 5 V V ` ` ` ` P P P P P P P P P P ` P ` ` ` V 0 V V G ! G 5 5 _ r 3 3 ( . ( j U U U d O U l O ' l ' l ' ' ' l ' l ' l ' l ' l l l l l l l l l l ' l l l ' l ' l ' l ' l ' O l U O U U j ( j r r G 5 G V ] ` ` P f f v v v s v v v f f P P ` 0 7 7 N N _ D E d l ' S @ A A A B B ^ - p , 8 R H J H H I I I I I > I I I I J H H J J R", +" R R 8 R 1 , p p ^ : B B B B B A A A A @ @ @ S ' ' l ' l d d d d d E E E E E d d d l l ' ' S S @ A A A B B B B : : 1 1 ~ 8. . J > I h g g * / / m ] ] V G G 3 3 Q d d l l ' ' O O j j r 3 r G V V 0 ` P ` P P P P P P P P P P P P ` ` ` ` ` V 0 V V 5 5 5 5 5 r 3 r j ( j j j U U U O l O l O l ' ' l ' ' l ' ' l ' l l l ' l l l l l l l l l l ' l ' l ' l ' ' l 9 l l l O l U j U j . 3 3 3 r G V V ` ` P P f f v v s v s v v f P P ` 0 7 7 n # # 3 Q d l ' S @ @ A A B } B - , p R R R H I H I I I T I T > I > I I I H H H R", +" R R R , 8 p - ^ ^ ^ B B B B A B A A A @ @ @ S S ' ' l l l d d E E E E d E E d d d l l ' ' S S @ @ A A A B B : : : : 1 ~ 8. R w J > > g g * * m m m V V G G G D Q E d l ' l l l U U j j 3 ! 5 G V ` ` ` ` P P P P f P f P P P P P P ` P ` ` 0 V V V G G 5 5 G 3 3 3 r ( j j U j U U U O l O ' l l ' ' ' ' ' ' l ' ' l ' l l l l ' l l l l l ' l l ' l ' l ' l ' ' l ' O l O U U U U j ( . r 3 ! 5 G V 0 ` P P f f v v v s v v v f f P ` ` 0 7 n G _ D Q E l ' S @ @ A A B B } ^ - , R R H Y H I I I > I T I T T I I > I H H H J", +" J R R 8 , p , p - ^ : B B B B A A A A @ @ @ S S ' ' ' l l d d d E d E E d E E d d l l ' ' S S @ @ @ A A B B B B : 1 1 1 ~. . w J > > g g c / / ] m ] ] G 5 G 3 ( E d d l ' ' l O U j j r 3 G V V V ` ` P ` P P P P f P P f P P P P P ` ` ` ` 0 V 0 V V G 5 5 5 G r 3 3 ( j ( U j U d U U l O l O ' l ' l ' ' ' l ' ' l ' l ' l l l ' l ' l l l ' l ' l ' ' ' ' l ' l ' O l O d O j U . 3 3 r 3 G V V V ` ` P f f v v s v s v v v f P ` ` 0 7 N N _ ( 3 E d l S @ @ A A A } B - p , Y R R H H H > q T T > T T T T I I I I H H H", +" R R R R 8 , p p ^ ^ B B B B A B A A A @ @ @ S S S ' l l l d d d E E E E E E d d d l l l ' S S @ @ A A A B B B : : : 1 1 8 8. w J > T h g & k / m m ] ` V G G ( 3 E d d ' l ' l O U U ( 3 r 5 V V 0 0 ` ` P P P P f P f P f P P P P P P ` ` ` ` ` V V 7 V G 5 5 G 3 r 3 r ( j ( j U U U U l O l O ' l ' ' ' ' ' ' ' l ' l ' l ' l l l ' l l ' l l ' l ' l ' l ' ' ' l ' l O l O U U U j j r 3 G 5 5 V V 0 ` P P f f v v s s v v v f f P ` 0 7 7 N N D D E d ' ' @ @ A A B B } ^ - , 8 Y R I I q I > T T T T T > I T I > I I H H", +" H H R R 8 , p , - ^ ^ B B B B B A A A @ @ @ @ S S ' ' l l l d d E d E d E d E d d d l l ' ' S S @ @ A A A B B B : : : 1 ~ 8. R J J > > g g * / / m ] ] V G G 3 D j E d l l ' l l U j U r 3 5 G G V ` ` ` P P P f P P f P f P f P P P P P ` ` ` ` 0 0 V V V G G 5 5 _ r 3 3 r ( U j j E U U O l O l ' l ' ' l ' ' ' ' ' ' ' ' l ' ' l l ' l ' l ' l ' l ' ' ' ' ' l 9 ' ' l O O l U j U j ( r 3 r 5 G V 0 ` ` P f f v v v v s v v f f P ` 0 0 7 N N # 3 Q d l ' @ @ @ A A B } - - p Y R H Y q H > q > T T T h T T T T I I I H H", +" H R R R R 8 , ^ p ^ ^ B B B A B A A A A @ @ S S S ' ' ' l d d d d E E E E E d E d l l l ' ' S S @ @ A A A B B B : : : 1 8 ~ 8 w w J > > g g c * / m m ] V ! G G 3 ( E l l l ' l 9 d U j j 3 G 5 V V 0 ` ` P P P P f P f f P f P f P P P P P ` ` ` ` ` 0 V V G 5 G 5 G G 3 r D . ( ( U j U d U O l O l ' l ' ' ' ' ' ' ' l ' l ' l ' l ' l ' l l ' l ' ' ' l ' ' l ' ' l ' O l O U U U j U j 3 r G 5 5 V V ` ` P f f v v s s v s v f f P P 0 0 7 7 _ _ D Q d l ' S @ A A A } B - , , R Y J H I I T T I T h T h T h T T T > q I H", +" H H H R Y R p , - - ^ B B B B B A A A @ @ @ @ S S ' ' l ' l d d d d E d E E E d d d l l ' ' S S @ @ A A A B B : B : ^ 1 1 ~ 8. J J I > g g & k / m m m ] V G G 3 ( Q d d ' l ' l O U j ( r 3 5 G V V ` ` ` P P P P f f P f f f f P f P P P P P ` ` 0 ` 0 0 V V V G 5 5 G 3 3 r 3 j ( U j U U U l O l O ' ' l ' ' ' ' ' ' ' ' ' ' ' ' l ' l ' ' l ' ' l ' ' l ' ' ' ' ' l ' l l O l U E j ( r 3 3 G 5 G V ` ` ` P f v v v v s v v v f P P ` 0 7 N G # 3 ( E l ' S @ @ A A } } - - , , R Y H I I q T T T h T h g T h T T T > I H", +" H H H R R R , p p ^ ^ ^ B B B A B A A A @ @ @ S S S ' ' l d l d d E E d E d E d d d l l l ' S S S @ @ A A A B B B : : 1 1 8 p. R J > > h g & / * m m ] ] V V 5 _ 3 j E l l ' ' l O O U ( 3 r 5 V V 0 ` ` P P P f P f P f f f P f f P f P P P ` P ` ` ` ` 0 V n V G 5 G G G 3 3 3 ( . ( j U U E O O l O ' l ' ' ' l ' ' ' ' ' l ' l ' ' l ' l ' l ' l ' ' ' ' ' ' ' l ' O ' O l U U U U j U j . 3 r 5 G V V ` P P f f v v s s v s v f f P ` 0 0 7 n # _ D E d ' ' @ @ A A B } ^ - , R Y H q H I T T T g T g h h g T h T T I q >", +" I H R H R R 8 , , - ^ - B B A B A A A A @ @ @ @ S ' ' ' l ' d d d d d E d E E d d d l l l ' ' S @ @ @ A A A B B B ^ : : p 1 8. w J J I > g c & k / m m m V ! 3 G ( ( E d l l ' ' l l j j . 3 _ 5 G V 0 ` ` P P f P f f f f f f P f f P f P P P P P ` ` ` ` 0 0 V V V G 5 5 5 G 3 3 3 ( U j j U U d O l O ' l ' ' ' ' ' ' ' ' ' ' ' l ' l ' ' l ' ' ' ' l ' ' ' ' ' ' ' ' ' l O l O l U j j j 3 3 G G ! G 0 0 ` P P f v v s v s v v f f P ` ` 7 7 N G # 3 E d ' S S @ A A A } } - p Y R Y H I q > T h L h g L g T g h T T T I I", +" I q H R R R R p p - ^ ^ B B B A B A A A @ @ @ S S S ' ' l l d l d E d E d E d E d d l l l ' ' S S @ @ A A A B B B : : ^ 1 p 8 8 8 w J > > g g & * < m m V ] V G G 3 ( Q l d ' ' ' l O U U ( r 3 G V V 0 ` ` P P P f P f f f f f f f f f f f P P P P P ` ` ` ` 0 0 V N V G G 5 G G 3 r 3 ( ( U j U U l O l l 9 l ' ' ' ' ' ' ' ' ' ' ' ' ' l ' ' l ' l ' ' ' l ' ' ' ' ' l ' l O l O U U U U ( j r 3 5 5 G V ` ` ` P f f v v s s v s v f P P ` 0 7 n N # D j d l ' S @ @ A A B - - t R Y H H I T T T T g h g h g h g T h T T T I", +" I H H q R R Y , p , ^ - B B B B B A A A A @ @ @ S S ' ' l ' l d d d E d E d E d d d d l l ' ' S S @ @ @ A B A B B B ^ : 1 p ~ 8 R J J I > h g c * / m m m ] V ! G 3 3 j E d l l ' ' l O j j 3 3 5 G V 0 ` ` P P P P f f f f f f f f f f f f P f P P P P ` ` ` ` 0 0 ` V G V G 5 5 G 3 3 3 ( ( U j U d U l O l l ' ' ' ' ' ' ' ' ' ' ' l ' ' ' l ' ' ' ' ' ' ' ' ' ' l ' ' ' 9 l l l O E U j j ( 3 r 3 G V V V ` ` P f v v v v s s v v f f P ` 0 7 7 _ _ 3 Q E l ' S @ A A A } } - p Y R Y q I q T T h h g g g h g g h g h T T I", +" I I I H H R Y 8 , - ^ - ^ B } B A A A A @ @ @ @ S S S ' ' l d l d d d d E d d d d d l l l ' ' S S @ @ A A A A B B : B : : 1 p ~. . J I > h g c & k / m m m V V G G 3 ( E l l ' ' l 9 l U U . r 5 5 G V 0 ` P P P f f f f f f v f f f f f f f f P f P P P P ` ` ` ` 0 V 0 G G G G 3 G 3 r 3 ( ( ( j U U l O l ' l ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l ' ' ' ' ' ' ' ' ' ' l ' l ' O O l U U j U 3 ( 3 G 5 5 G 0 0 ` P P f v v s v s v v v f P ` 0 0 7 N _ # Q E l ' S @ @ A A } } - t Y R H I q T T L L g g g g g g h L g h T T T", +" T I H H Y R R Y p , - - ^ } B B A B A A A @ @ S @ S S ' l ' l l d d E d E d E d d d d l l ' ' ' S @ @ @ A A A B B B B : ^ p p 8 8 R J J I > h ) * * / m m ] ] V 5 G 3 D j d d l ' ' l l O ( ( ( G 5 G V 0 ` ` P P P P f f f f v f v v f f f f f f f P P P P P ` ` ` ` 0 V 0 V G V G 5 G 3 3 3 ( ( U j E U O l O l ' l ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l ' ' ' ' ' ' ' ' ' ' l l O l U U U j ( r 3 G 5 G V 0 ` P P f v v v s s s v v f P P ` 7 7 n 3 _ D j d ' ' @ @ A A } } - - , Y Y q I T T T g h g g g g g g g g g g T T", +" T q I H H H Y 8 , p p - ^ B B A B A A A A @ @ @ S S S ' ' l l l d d d d E d d d E d l d l l ' ' S S @ @ @ A A B B B : B : 1 p 8 ~ R w J I > h g & k / / v m ] V V 5 G ( j E l l ' ' ' O l U j j 3 G G V 0 ` ` P P f f f f f f f v f f v f f f f f f f f P P P P ` ` ` ` 0 0 0 V n G V _ 5 G 3 3 ( ( j U d U l O ' l ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' O ' O l O U d U j U j ( 3 G 5 5 V V ` ` P f f v v s v s v v f P P ` 0 7 N N _ ( E d l S S @ A A A } - , Y Y H H q T T L g g g g g g g g g h g h h T", +" T T I q H Y R R 8 , - - - } B B A B A A @ A @ @ @ S S ' ' ' l l l d d d d d E d d d d l l ' ' ' S S @ @ A A A A B B B ^ : ^ 1 p 8. J w I I > g c & k * m m m ] V 5 G 3 ( j d l l ' ' l O U j ( 3 G ! G V 0 ` ` P P P f f v f v f v v v f v v f f f f f P f P P P P ` ` ` ` 0 0 0 V G G G 3 G 3 3 3 ( j j U d U l O ' l ' ' ' ' S ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l ' O l l U U U j ( ( r 3 G 5 G 0 0 ` P P f v v s s s v v v f P ` 0 7 7 N # D ( d l ' S @ @ A } } } t R Y Y I q T T h g g g g g c g ) g g h g g T", +" T T I I H H R Y Y p , - ^ ^ } B B A A A A A @ @ @ S S ' ' l ' d d l d d d E d d d d d l l l ' ' S S @ @ @ A A A B B B : ^ : p p 8 8 8 J J > > g g c / < m m m ] V ! 5 3 3 Q d l ' ' ' l l O U j . 3 5 G V 0 ` ` P P f f f f f v v f v f v v f v f f f f f f f P P P P P ` ` ` 0 0 V 7 V G G G G 3 3 Q ( U j U d O l l 9 ' ' ' ' ' ' S ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l ' O O l U U j U 3 3 r _ 5 G V 0 ` ` f f f v s v s s v v f P P 0 0 7 _ _ _ Q E l ' S @ @ A A } - , t R q q q T L g g g g c c c & g c g g g h T", +" T T T I q H q R R , , - - B } B B A B A A @ @ @ @ S S S ' ' ' l l d d d d d d d d d d l l l ' ' ' S @ @ @ A A A A B B B ^ : ^ p ~ 8 R J J I > h g c * / k m m m ] V G G ( ( j d l l ' ' l l U j ( 3 G V G 0 ` ` P P P P f f v f v v v v v v v v v v f v f f f f f f P P P ` ` ` ` 0 V 0 7 G G 3 G 3 3 3 ( j E U d O l l l ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l O l U E j ( U 3 r 3 G G V V ` ` P f f v v s s s v v f f ` ` 7 7 7 3 # Q j l ' S @ A @ } 2 } t , Y q H L T T g g g g g c & ) c c g g g g g", +" g T T q I H Y R Y p , - - - B } B A A A A A @ @ @ S S ' ' ' l l d d d d d E d d d d d l l l ' ' S S S @ @ @ A A B B B B : ^ : p p 8 8 R J J > h g g c * / m m m V V G 5 3 ( j d l ' ' ' ' O d U ( ( 3 5 G V 0 ` ` P f f f f f v f v v v f v v v v v v f v f f f f f f P P P P ` ` ` 0 0 V V G G G G 3 3 ( ( U U E O l O ' l ' ' ' S ' S ' ' S ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' O ' l l U l U U j ( j 3 G 5 5 G 0 0 ` P P f v v s s s v v v P P ` 0 7 N N _ j E d ' S S @ A A } } , t , q H q g L g g g c c c c & c c & ) g g g", +" g L T T I q H H R R , p - ^ } B B A B A A A @ @ @ @ S S ' ' l ' l l d d d d d d d d d l l l ' ' ' S S @ @ A A A A A B B B ^ ^ p p p R. J J I > g ) & k / < m m ] ] ! 5 G 3 ( j l l l ' ' l l U j ( r 3 V G 0 ` ` P P P P f v f v v v v v v v v v v v v v v f v f f f f f P P P ` ` ` 0 0 0 V G G 3 G 3 3 ( ( j U E U l l l ' ' ' ' ' ' S ' ' ' ' S ' ' ' S ' ' S ' S ' ' ' ' ' ' ' l O l U d U U j ( 3 r 3 G G V 0 ` P P f v v v s s s v v f P ` 0 7 7 3 _ D ( d l ' @ @ @ A 2 } C Y Y q T q T h g g g & c & c c c & ) * g g g", +" g h T T q I q Y Y Y R - - - - B A B A A A A @ @ @ S S S ' ' ' l l d l d d d d d d d d d l l l ' ' S S @ @ @ A A A B B B B : ^ : p p 8 R J J I T h g & c * < m m m ] V G r 3 ( E E l ' ' ' ' O U U ( 3 3 5 G V 0 ` ` P f f f f v v v v v v v v v v v v v v v v v f v f f f f f P P P ` ` 0 0 7 V n G G G D 3 3 ( E U d U l O ' l ' ' ' ' ' ' S ' ' ' ' S ' ' ' S ' ' ' ' S ' ' ' ' l 9 l O l U U j U ( j 3 G 5 5 G V ` ` P f f v s s s s v v f f ` ` 7 7 N _ ( Q d l S S @ @ A } } , , Y Y q I L L g g c c c c c c c c c c & g g", +" g g L T T H q H R , Y , , - } B A B A A A A A @ @ @ S S S ' l ' l l d d d d d d d d d l l l l ' S ' S @ @ @ A A A B A B B B ^ ^ p p 8 8 8 J I > > h c c * / < m m ` ] V 5 G 3 ( U l l ' ' ' ' l U j ( 3 G V G 0 0 ` P P P f f f f v v v v v s v s v s v v v v v v v v v f f f f P P P ` ` ` 0 0 G V G 3 G 3 D ( U j E U l l l ' ' ' ' ' S ' ' ' ' S ' ' ' S ' ' ' ' S ' ' ' ' ' ' ' l ' l U l U E j ( ( 3 3 G G V 0 0 ` P f f v s v s s s v f P P ` 0 7 N # _ ( E l ' S @ @ A 2 } C , Y q q L T g g g & c c k & c c c c c c c g", +" g g L T T q I Y H Y R p , - - } B A B A A A @ @ @ @ S S ' ' ' l l l l d d d d d d l d d l l ' ' ' S S S @ @ @ A A A B B B : ^ ^ p p 8 8 R J J I > g g c / k / m / m ] V 5 5 3 ( j d l ' ' ' l l O U j 3 3 5 G V 0 ` ` P P f f f v v v v s v v s v v s v s v s v v v v v v f f f f f P P ` ` ` 0 0 n G V _ G 3 3 ( j E U d O l l l ' ' ' ' S ' S ' ' ' S ' ' ' S ' ' ' ' S ' ' ' 9 ' l 9 l O d U U j U ( 3 r G 3 G V 0 ` ` P f v v s s s v v v f P 0 0 7 G N 3 D E l ' S @ @ A 2 } t , Y q q T L L g c c c c c k k c k c c & ) &", +" g g g L T T I I Y R Y t - - - } } B A A A A A @ @ @ S S S ' ' ' ' d l l d d d d d d d l l l l l ' ' S S @ @ @ A A A B A B B : ^ ^ p p 8 R R J I I h g g c * / < m m ] ] ! 5 3 ( j U l l ' ' ' l O d j ( 3 _ V G 0 ` ` P P f f v f v v v v v s v s s v s v s s v s v v v v v v v f P f P P ` ` 0 0 0 7 G G 3 _ 3 D ( j E U d l ' l ' ' ' ' ' S ' ' S ' ' ' S ' ' ' ' S ' ' ' ' ' ' ' ' l l O l O E E j ( ( 3 3 _ V G 0 ` P P f v v v s s s v v f P ` 0 7 7 _ # D j d ' ' @ @ @ A C C , Y $ I q g g g & c c c k c k k k c k c c c", +" & g g h T L q I q H , , , , - } B } B A A A @ @ @ @ @ S S ' ' l l l l d l d l d d d l d l l ' ' ' ' S S @ @ @ A A A A B B B B ^ ^ p p 8 8 R J J > > g ) & k * / m m m ] V G 5 3 ( E U l ' ' ' ' l O U ( ( r _ G V 0 ` ` P P f f f v v v s v s v s v s s s s v s s s v s v v v v v f f f P P P ` ` 0 V n V G G # 3 3 ( U E U d O l ' ' ' ' ' ' ' S ' ' S ' ' ' S ' S ' ' S ' ' ' ' ' ' l O l l U l U j ( ( r G G 5 G V 0 ` P f f v s s s s s v f f ` ` 7 7 _ _ 3 E d l S S @ @ A 2 C t Y q q L L & g c c k k k k c k c k c c c &", +" c g g g L T q H q Y R Y , - - - } A B A A A A A @ @ S S S S ' ' ' l l l d l d d l d l d l l l l ' ' S S @ @ @ @ A A B A B B B ^ ^ ^ p p R 8 J H I T h g c / k v < m m ` ] ! ! 3 3 j U l ' ' ' ' ' O d j ( 3 G G V 0 0 ` P P f f f v v v v s v s s s s s s s s s s s s v s s v v v v v f f P P ` ` ` 0 0 n G 3 G 3 3 Q ( j d U l l l l ' ' ' ' S ' ' S ' ' ' S ' ' ' ' ' ' S ' ' ' ' ' 9 l l O d U E U j ( ( 3 G 5 n V 0 ` P P f v v s s s s v v P P ` 0 7 G # 3 ( d l ' S @ @ A C C t Y q q T L g g & c c k c k k k k k k k c c", +" c c g g g T T q q Y Y Y R - - - } } A B A A @ @ @ @ @ S S ' ' ' l ' l l d l d d d d l d l l l ' ' ' S S S @ @ @ A A A A B B B B : ^ p p 8 R 8 J J > h h g c k * / m m m ] V 5 5 3 ( j d l ' ' ' ' l O E j ( 3 G G G 0 ` ` P P f f v v v v s v s s v s s s s s s s s s s s s s v s v v v f f f P ` ` ` 0 7 V G G G ( D ( Q j d d O l ' ' ' ' ' ' ' S ' ' S ' ' ' S ' S ' S ' ' ' ' ' ' ' l O l O U d j U ( 3 3 3 5 G V 0 ` ` P f v v s s s s v v f P ` 7 7 G _ _ Q E l ' S @ @ 2 A C , t q q q g g c c k k k k k k k k k k k k c", +" c c * g g L T q I q H , Y , C - } B A A A A A A @ @ @ S S S ' ' ' l l l l d l d l d d d l l ' l ' ' S S S @ @ @ A A A B A B B B ^ ^ ^ p 8 8 R J J I h h g c / k / < m m m ] ! 5 r 3 U j O ' ' ' ' ' O d U ( 3 G 5 G 0 0 ` ` P f f f v v v v s v s s s s s s s s s s s s s s s s s v v v v f f f P ` ` ` 0 n 7 G 3 G 3 3 ( j E U d l l l ' ' ' ' ' ' ' ' ' S ' S ' ' ' S ' ' S ' ' ' ' l ' ' O d l U E j ( ( ( G G G G 0 ` ` P f v v s s s s v v f P ` 0 7 N N ( Q j l ' S @ @ 2 2 C t t q q L L g & & c k k k k k k k k k k c k", +" c c g c g g T L q q Y R Y , - - } } } A A A @ A @ @ @ S S S S ' ' l ' d l d l d d l d l d l l ' ' ' S S S @ @ @ @ A A A B A B B ^ ^ ^ p , p 8 J J I > h g ) & k / < m m m ] V G 5 3 ( j d l ' ' ' ' ' l U j ( 3 G G V 0 ` ` P P f f f v v s v s s s s s s s s = s = s s s s s s s s s v v v f f P P P ` 0 0 G 7 N G # 3 ( Q U E d O l l ' ' ' ' S ' S ' ' ' S ' ' S ' ' S ' ' ' ' ' ' 9 l l l O O E U U ( ( ( 3 G G G V 0 ` P P f v s s s s s v f P P 0 7 7 N _ Q E d ' S S @ @ 2 C Y $ L q & g c k k k k k k < k < k k k k k", +" k c c & g L L T q H q Y , t , - - } B A A A A @ @ @ @ @ S S ' ' ' ' l ' d l l l l d l d l l l ' l ' ' S S @ @ @ @ A A A A B B B B ^ ^ ^ p 8 R R J H I T g g & k k / / m m m ] ! 5 r 3 ( U O l ' S ' ' O d E E 3 3 G G V 0 ` ` P f f f v v v s s s s s s s = s = s s = s = = s s s s s s v v v f f P P ` ` 0 0 G V 3 G _ D 3 ( E U d l l l l ' ' ' ' ' ' S ' ' S ' ' S ' ' ' S ' ' ' ' ' ' 9 l l O d U E j ( 3 3 3 5 G n 0 ` P P v v v s s s s v f f ` ` 7 N G # ( j d l ' @ @ @ 2 C t t q q L g & & c k k k k < k < k < k k k k", +" k k c & g c L T L q q Y Y Y , - C } } } A A A A @ @ @ @ S S S ' ' l l l l d l d d l d l l l l l ' ' ' S S @ @ @ @ A A A A B A B B ^ ^ ^ , p 8 R R J I > h g c c / k < m m m V ] ! 5 3 ( j d O ' ' ' ' ' l U j ( 3 G _ V 0 0 ` P P f f v v v s v s s s s = s s = s = s = s = s = s s s s s v v v v f P P ` ` 0 0 n G G # 3 3 Q ( E U d l ' l ' ' ' ' ' S ' ' ' ' ' ' ' ' S ' ' ' ' ' ' l ' l l O d O E U U ( ( 3 G G G V 0 0 ` P f v s s s s s v v f P ` 0 7 N _ D Q d ' ' S @ @ 2 2 t t q q L & & c k k k k < k < k < k < k k k", +" k k k c & g & g q q H q Y t , C - } } A A A A A @ @ @ @ S S S ' ' ' ' l l l l d l l d l d l l l ' ' ' S S S @ @ @ @ A A A A B B B B ^ ^ p p , R R J H I > h ) & k k m < / m m ] V 5 r 3 U j l l ' ' ' ' O l E j ( 3 G G N 0 ` ` P P f f v v v s s s s s s = = s = = = = = = s = = s = s s s s v v v f P P ` 0 0 n V G 5 # 3 ( ( E j d l l l l ' ' ' ' ' ' ' S ' S ' S ' ' ' S ' ' ' ' ' l ' l l d O d j E ( ( 3 _ 3 G G G ` ` P f f v s s s s s v f P ` 0 7 N # 3 ( d l S S @ @ 2 C t q q L L c & k k k < k < < b < b k < < k", +" k k c k c g g L T L q q Y R C t - } } } A A A @ A @ @ @ S S S ' ' ' l l l l d l d l l l d l l ' ' ' ' S S S @ @ @ A @ A A B A B B B ^ ^ - p 8 8 R J H I h h g c & k / v m m m m V ! 5 r 3 j U l ' ' ' ' ' l U E j 3 G G G 7 0 ` ` P f f f v v s s s s = s = s = = s = s = = = = = = s = s s s v v v f f P P ` 0 0 n G N G 3 D Q ( E d U l l ' l ' ' ' ' ' ' ' ' ' ' ' S ' ' ' ' ' ' ' ' ' O l l O d U E U j ( 3 3 5 G G V 0 ` P P v v s s s s s v f P ` 0 7 V _ # Q E l ' S S @ 2 2 t $ $ L o g & k k k k < b k < < < < < k < k", +" k k k k c & g g L L q Y q Y , , C C } } A A A A @ @ @ @ @ S S S ' ' ' l l l l O d l d l l l l ' l ' ' ' S S S @ @ @ A A A A A B } B B ^ ^ - ^ 8 R R J H I T h ) & k k / < m m m ] ! G r 3 ( U U O ' ' ' ' ' l d U ( ( _ V G 0 0 ` P P f v v v v s s s s = s = = = = = = = = = = = = = = = = s s s v v f f P P ` 0 7 7 G G # 3 3 Q j E d d l l l ' ' ' ' S ' ' S ' S ' ' ' ' S ' ' ' ' l ' ' ' l l l O d j Q ( ( 3 3 G G 7 0 0 P P f v s s s s s v v P P 0 7 n _ _ ( E d ' S S @ @ C C $ q q g & c & k < k < < < < b < < < < b k", +" < k k k c c & & L T q q H t Y t - } } } A A A @ A @ @ @ S S S S ' ' l l l l l l d l l d l l l l ' ' ' S S S @ @ @ @ @ A A A B A B B B ^ ^ ^ , , 8 R J H I T h g c & k * < / m m m ] V 5 r 3 j d O ' ' ' ' ' O l U Q ( 3 _ G 7 0 ` ` P f f f v s s s s s = s = s = = = = = = = = = = = = s = s s s s v v f f P ` ` 0 7 G G _ _ ( 3 Q E E d l l ' l ' ' ' ' ' ' ' ' ' S ' S ' ' ' ' ' ' ' ' l 9 l l U d U E U j ( 3 G G G G V 0 ` P f v v s = s s v v f ` ` 7 7 _ _ D E l ' ' @ S 2 $ $ L L L * k k k < b < < b < < < b < < k", +" < < < k k c & g L L L q q Y Y , , C C } } A @ A A @ @ @ @ S S S ' ' ' ' l l l l l l l l d l l ' l ' ' ' S S S @ @ @ @ A A A A A B } B ^ - ^ ^ p , 8 R J > I h g g c * k v < f m m m V ! 5 3 j j d O ' ' S ' ' l d j ( ( G G 5 n 0 ` ` P f f v v v s = s s = = = = = = = = = = = = = = = = = = = s s s v v f P P ` 0 0 7 V _ G D D ( j E U d l l l l ' ' ' ' ' S ' S ' ' ' ' S ' S ' ' ' ' ' l O l d l E U E ( ( D 3 3 G G 0 0 ` P f v s s s s s s v f P ` 0 n G # 3 j d l S S @ 2 t t q o L c & k k < < < < < < = b < < < < <", +" < k k k k k & c & L L q q $ Y t t C } 2 } A A @ A @ @ @ @ S S S ' ' ' l l l l d O d l l l l l l ' ' ' ' S S S S @ @ @ A A A A B A B B B ^ ^ , p , 8 Y R H I T h ) c c k * / v / m m V ! 5 r r j U U ' ' ' ' ' l l d j ( ( G G V 0 0 ` P f f v v v s s s = = = = = = = = ; = = ; = = ; = = = = = = s s v v v f P P ` 0 0 n G _ _ ( 3 Q E E d l l l ' l ' ' ' ' ' ' ' ' S ' ' ' ' ' ' ' ' ' l ' l l O d U E j U ( 3 3 _ G G 7 0 ` P f f v s s = s s v f P ` 7 7 N _ ( Q d l ' S @ S 2 | $ $ L L * & k k < < b < ; b < ; = b = < b", +" < b < < k k c & g & q L q q Y t , C - 2 } A A @ A @ @ @ @ @ S S S ' ' ' ' l l l l l l l l l l l l ' ' S ' S S S @ @ A @ @ A A A B B } B } ^ ^ , 8 , R R J I > h g g c / k < < / m m m ] ! 5 3 j j U l 9 ' ' ' ' l O E Q ( # G G n 0 ` P ` f f v v s s s = s = = = = = ; = = ; = ; = ; = ; = = = = = s s v v f f P P 0 0 n V N 3 _ D ( Q j d d l l l l ' ' ' ' ' ' S ' ' ' S ' ' ' ' ' ' ' l ' l ' d U l E U Q ( ( 3 3 G V G 0 ` ` P f v s = s s s v f P ` 0 7 N _ 3 Q d l ' S S S C $ q o & c * k k b < < < < = = = b = < = <", +" < < < k k k k c & g L L q q Y Y t C C } 2 } A A @ @ @ @ @ S S S ' ' ' ' l l l l l l d O l l l ' l ' ' ' S S S @ S @ @ @ A A A A A B A B ^ ^ - ^ p , 8 H R H I T h g c c k * / v / m m ] ! ! r r ( U U l ' ' S ' ' l E j ( 3 _ G G 0 0 ` P P f v v s s s = = = = = ; = = ; ; = ; = ; = ; = ; = = = = = s s v v f P P ` 0 0 7 G _ _ ( 3 Q E E d d l l ' l ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l ' l ' l l l E U E j U ( 3 3 _ G G 0 0 P P f v s s = s s s f f ` ` 7 7 # _ Q E l ' S S @ $ $ L o c * k < < < [ = [ < ; b s ; < [ <", +" = < b < < k k c c g & q L q $ Y t , C C } 2 A @ A A @ @ @ @ S S S S ' l ' ' l O l l l l l l l l l ' ' ' ' S S S @ @ @ @ @ A A A A A B } B } ^ - p , R R R H I I h g ) & k k < / v m m m ] ! 5 r j ( U O 9 ' ' ' l ' O d E 3 ( _ V n 0 0 ` P f f v v s = s = = = = ; = ; = ; = ; ; = ; ; ; = ; ; = = = = = s v v f P ` ` 0 7 7 _ G # 3 D Q j d d l l l ' l ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l l O d l U E j Q ( D 3 3 G G 0 0 ` P f v s s s = s s f f P 0 7 V _ _ ( E d ' S S S | $ q o & & k k < < < b = b ; = ; = ; = b =", +" ; < = < < k < k & & & L L q q Y t t C C } 2 A A @ @ @ @ @ S @ S S ' ' ' ' l l l l l l l l l l ' l ' ' ' ' S S S S @ @ @ A @ A A A B B B } B ^ - - p , 8 Y R H I T h g c k / k < / v / m V ] ! 5 3 r U U l ' ' ' ' ' l d U Q 3 # G G 7 0 ` ` P f v v s s = = = = = ; = ; ; = ; ; ; ; ; = ; ; ; = ; = = = s s s v v f P ` ` 0 n V _ _ 3 D Q Q E d d l l l ' ' ' ' ' ' ' ' ' S ' ' ' ' ' ' l ' l ' l l l U d E j Q ( 3 3 G G N V ` ` P f f s s = s s s v f ` ` 7 n _ 3 D E l l S S S $ o L & * k < < < = ; = ; = ; ; ; = ; = b", +" < ; < b < < k k k & & L L q q $ Y t C C 2 } @ A A @ A @ @ @ S S S S ' ' ' l ' l l O l l l l l l ' l ' ' S ' S S S @ @ @ @ A A A A A A } B B } ^ ^ , , 8 H R H I I h g g c k k < < / f m m ] ! 5 r 3 j j O l 9 ' ' ' l l E E ( ( _ N G 0 0 P P f v v s s s = = ; = ; = ; = ; ; ; = ; ; ; ; ; ; ; ; ; ; = = = s v v f P P ` 0 7 G N _ # 3 Q ( E d d l l l l ' l ' ' ' ' ' ' ' ' ' ' ' l ' ' l ' l O l l l E U E j ( ( 3 # G 5 n 0 ` ` f v v s s = s s v f P ` 0 7 N # 3 E d l ' S S | $ q o & & k k < b < ; b ; ; ; ; = ; ; ; ;", +" ; = b = < < k k k & c & L q q $ q t , C C 2 A 2 @ A @ @ @ @ S S S ' ' ' ' l 9 l l l l l l l l l l ' ' ' ' S S S @ S @ @ @ @ A A A A B B A B ^ - - - p , Y R H H > T g g c c k / < / v / m m V ] 5 r j j U O ' ' ' ' ' l O E j 3 3 G G 7 0 ` P P f v v s s = = = ; = ; ; ; ; = ; ; ; ; ; ; ; ; = ; = ; = = = = s v v f P ` ` 7 7 G G _ # 3 Q E E d d l l l l ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' l ' l l l U d E U E ( D 3 3 G G V 0 0 P P f v s = s = s v f P ` 0 7 G _ D Q d ' ' S S | $ o L * & k < < = ; ; = ; ; ; ; ; ; = ; =", +" ; ; ; ; < b < < k k & & L L q q Y t t C C 2 2 A A @ @ @ @ S @ S S S S ' ' ' l ' l l l l O l l l ' l ' ' ' ' S S S @ @ @ @ A @ A A A A A } B } B - ^ - , 8 Y R H H T h g & c / k < / < m f m ] V ! r r j U U O ' ' ' ' ' l E E ( ( _ N G 0 0 ` P f v v s s = = = = ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; = = s s v f f P ` ` 7 7 N 3 _ D 3 D E d d l l l ' l ' l ' ' ' ' ' ' ' ' ' ' ' l ' ' l ' l l d U d E j Q ( j # _ G G 0 0 ` P f s s s = = s v v P ` 0 7 7 # 3 Q d l ' ' S 9 | $ o o & / k < = b ; ; ; ; ; ; = ; ; ; ; ;", +" ; = ; < ; < < < k k & & & L L o Y $ t C C 2 2 @ A @ @ @ @ @ S S S ' ' ' ' l ' l O l l l l l ' l ' l ' ' S ' S S S @ @ @ @ A @ A A A B A B } ^ } - , p , R R q H I T h g c k k < < / / m m m ] ! 5 r 3 j U l O ' ' ' ' l l E Q 3 D G V n 0 ` P f f s s s = = ; ; ; = ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; = ; = = s s v f P ` 0 0 n G N _ ( D Q E E d d l l l l ' ' ' l ' ' ' ' ' ' ' ' ' ' l ' l l l l l d d U Q j Q 3 3 G _ G 7 0 ` P f v s s = s s s v P P 0 7 N _ # E E l ' ' S 9 | $ o L * * k < < ; = ; ; ; ; ; ; ; ; ; ; ;", +" ; ; ; ; < ; b < < k k * L & L q $ Y t t C C A 2 A @ @ @ @ @ S S S S S ' ' ' l ' l ' l l l l ' l l ' ' ' ' ' S S S S @ @ @ @ @ A A A A A A B } B - ^ - - , Y R R I I T h g g c k k < < v s m m m ] ! 5 3 . j U O ' ' ' ' l l d E D 3 _ _ 7 0 ` ` f f v s s = = ; = ; ; ; ; ; ; ; ; ; ; ; ; ; ; [ ; [ ; ; ; ; = = = s v f f P ` 0 7 V _ _ # 3 3 Q E E d d l l l ' l l ' ' l ' ' ' ' ' ' ' l ' ' l ' l l d l d E E Q ( D ( G G G 7 0 ` P f v s s = = = v v f ` 0 7 n 5 _ Q d d ' ' S 9 | $ o L & / < < = ; ; ; ; ; ; ; ; ; ; ; ; ;", +" ; ; ; ; ; = < < < k k * * & o L q $ $ t 2 2 2 2 A @ @ @ @ @ S S S ' ' ' ' ' l l l ' O ' l l ' ' l ' ' ' ' S S S S @ @ @ @ A @ A A A A B A } B } - - - p , R H H q I T h g c c k < / < / m f m V ! ! r 3 . U U l ' ' ' l l l j E 3 # G G 7 0 ` P f v v s = = = ; ; ; ; ; ; ; ; ; [ ; [ ; [ ; ; [ ; ; [ ; ; ; = = s s v f P P 0 0 7 n _ _ D D Q Q E d d l l l l ' ' ' ' ' ' l ' l ' l ' ' l l ' l l l O d U d U Q j 3 3 # G G V 0 ` P f v v = s = s s v f P ` 7 n _ _ E E d ' ' ' ' | $ o % & * k < [ ; ; [ ; [ ; ; ; ; ; ; ; ;", +" ; ; ; ; ; ; ; b < < k c & & L o q q Y $ t C 2 2 A @ @ @ @ @ S @ S S S S ' ' ' ' O ' l l ' l O l ' l ' ' ' ' ' S S S S S @ @ @ A @ A A A A B } } B } ^ - , , R Y R I I T h g g k * k < < v < m m m ] ! ! 3 . j U O O ' ' ' l l E E D ( _ N n 0 ` P f f s s = = ; ; ; ; ; ; ; [ ; [ ; ; ; [ ; [ ; [ ; [ ; ; ; ; ; = = s v v f ` ` 0 7 V _ _ # 3 3 Q E d d d l l l l l l ' l ' ' ' ' ' ' ' l ' l ' l l l l l d E E E Q Q 3 3 _ G N 0 0 P P f s s = = = s v f P ` 7 7 _ 3 D E l l ' ' 9 | $ o L * / b < ; ; ; ; ; ; [ ; [ ; ; ; ; ;", +" ; ; ; ; ; ; ; = < < < k & * & L o q $ t t C 2 2 @ A @ @ @ @ S S S S ' ' ' ' l ' l ' l l l ' l ' l ' ' ' ' S ' S @ S @ @ @ @ @ A @ A A A A A B } } - - - p Y , R H q I g g g c c k < < m / v m m m ] ! r 3 . U U l ' l ' l l d E Q 3 # G G 7 ` ` f f v s = = ; ; ; ; [ ; [ ; ; [ ; [ ; ; [ ; [ ; [ ; [ [ ; ; ; ; = = s v f P ` 0 0 7 N _ _ D D Q E E d d l l l ' l ' ' l ' l ' l ' l ' ' l ' l l l l l d d U E j Q ( 3 D G _ V 0 0 ` f f s s = s = s s f P ` 0 7 N _ D E d l ' ' 9 | r o * * < < = ; ; [ ; [ ; [ b ; [ ; ; [ ;", +" ; [ ; ; ; ; ; b [ < < k k & & o L q $ t $ t 2 2 @ @ @ @ @ S @ S S ' S ' ' ' ' l ' l l l ' l ' l ' ' ' ' ' ' S S S S S @ @ A @ @ A A @ A B A } } B } - - - , Y R Y I H T h g g k k / < < / < f m m ] ! 5 r r j U O O ' ' ' l l E E Q _ _ 7 7 0 ` P v v s s = ; ; ; ; ; [ ; [ ; [ ; ; [ ; [ ; [ ; [ [ ; [ ; [ ; ; ; = s v v f P ` 7 7 V _ _ # 3 D Q E E d d l l l l l ' l ' ' ' ' ' ' l ' l ' l ' l l d l d E E E Q Q 3 ( _ G G n ` ` P f v s = = = s s v P ` 7 7 G # 3 Q d l ' ' 9 W $ o % / k < ; ; ; ; [ [ b ; b [ < b [ b ;", +" ; ; [ ; ; ; ; ; = < < < k * * & L o $ q | C | 2 2 2 @ @ @ S @ S S S S S ' ' ' l ' l O ' l O ' l l ' l ' ' ' ' S S S S S @ @ @ @ @ A @ A A A A B A } - } - , , R Y R q I T T g c c k k < < < f / f m m ] ! 5 3 . j U l l ' l ' l d E 3 D 3 N 7 0 ` P f v s = = ; ; ; [ [ ; [ ; [ ; [ ; [ ; [ ; [ [ ; [ [ [ [ ; [ ; ; = = s v f P P 0 7 n N _ _ D D Q Q E d d d l l l l l ' l ' l ' l l ' ' l ' l l l l l d l E U E j ( D 3 _ G G 7 0 ` P v v s = = = s s v P ` 0 7 N _ D E d l l ' l | $ % & * < < ; ; [ [ b ; b b ; b b ; < [ b", +" b [ b [ ; [ ; ; ; ; < < k k & & L o L $ $ C 2 2 @ @ @ @ @ S @ S S S ' ' ' ' ' l ' l l ' l l l ' ' l ' ' ' S ' S @ S S @ @ @ @ A @ A A A A A } B } } - - p , Y J Y q I T L g c c k k < < < s m m m ] ! ! r . ( U U O l ' l l E E Q D _ _ 7 7 ` P f v s = = ; ; [ ; [ ; [ [ [ ; [ ; [ ; [ ; [ ; [ [ [ [ [ [ [ ; ; ; = s v v f P ` 0 7 N N 3 _ D Q Q E E d d d l l ' l ' l l ' l ' ' l ' l ' l l l l l l d d E E Q Q D 3 3 _ G 7 0 ` P f v s s = = = v v f P 0 7 N # D Q E l l ' O | r o & / < < ; ; ; [ [ b b ; b b ; b b b ;", +" b ; b ; [ ; ; ; ; ; < < < k & * & L q o $ Y | 2 @ S @ S @ S S S S ' S ' ' ' l ' l l ' l ' l 9 l l ' ' ' ' ' S S S S @ S @ @ @ @ A @ A @ A A A } } } - - C , Y , H Y I T T g g c k * < < < m v f m m V ! 5 r 3 j U l ' l ' l l E E D _ G n 7 ` ` f v s s = ; ; ; [ [ [ ; [ ; [ ; [ ; [ ; [ [ [ [ ; [ [ [ [ [ ; ; ; = = s v f P ` 0 7 n N _ # # D Q E E d d l d l l l l l ' l ' l ' l ' l l ' l l d l d d U E E j Q ( 3 # G _ V 0 ` P f v s = = = = s v P P 0 7 V _ 3 Q d d l ' O W . o * * < = ; ; [ b b [ b b b < b b ; b b", +" b b ; b b ; [ [ ; ; [ < < < k & * L o q $ t | 2 2 @ @ @ @ @ S S S S S ' ' ' ' ' l ' O l l ' l l ' ' ' ' ' S ' S S S S S @ @ @ @ A @ A A A A A } } } } - - , , Y , H I q T g g c k k < / < s < / f m ] ! 5 r . . U U l ' l l d d E D 3 _ _ 7 0 ` P f s = = ; ; [ ; [ [ [ [ ; [ [ ; [ ; [ ; [ ; [ [ [ [ [ [ [ [ [ ; ; = s s f f ` ` 0 7 N _ _ _ D Q Q E E d d d l l l ' l ' l l ' l l ' l ' l l l l l l l d d E E Q D 3 3 # V N 7 ` ` f v s = = = = s v f ` ` 7 N # # Q E l l l O W r L / / < ; ; [ b [ b b b b b b b b b ; b", +" b b < [ b [ b ; [ ; ; = < < k / & % L o $ $ t | 2 S @ S S S @ S S ' S ' ' ' l ' l ' l l ' l l l ' l ' ' ' ' S S S S @ S @ @ @ @ @ @ A @ A A A A } } } } C - , Y Y Y q H T L g & c k k < < v / v m m m ] V 5 r 3 j U O l l l l d E D D _ N 7 0 ` f f s = = ; [ [ [ [ [ [ [ [ [ ; [ ; [ ; [ ; [ [ [ [ [ [ [ [ [ [ [ ; ; = s v f P ` 0 7 7 _ _ D D D Q E E d d l d l l l l l l ' l l ' l l l ' l l l d d d d E U Q j Q D _ G _ n 0 0 P f v s = = = = s s f P 0 7 n N 3 D E d l l O W o % / * = ; ; [ [ b b b b b b b < b < b b", +" b b b b b ; b [ ; ; ; ; < < k * & * L q o $ | t S @ S @ @ @ S S S S S ' ' ' ' l ' l l ' O l ' l ' l ' ' ' ' ' ' S S S S S @ @ @ @ @ @ A A A A A } } } } - - - , , H q q I T g g c k k < < < s < v f m ] ! 5 r 3 . U U l ' l l d E Q Q _ _ 7 0 ` P v v = ; ; ; ; [ [ [ [ [ [ [ [ ; [ ; [ ; [ [ [ [ [ [ [ [ [ [ [ [ ; ; = s s f f ` 0 7 7 N _ _ _ D Q Q E E d d d l l l l l l l l l l ' l ' l l l l d l d l E E E Q D 3 3 # G V 0 0 ` P v s = = = = s v f P ` 7 n _ # D E d l l U W o % / < < ; ; [ b b b b b b b b b b b b b", +" b b < b b b b [ b ; ; ; ; = < k / & % & $ o $ | | 2 S S S S S S S ' ' ' ' ' ' ' l ' l l l ' l l l ' l ' ' ' S S S S S @ S @ @ @ @ A @ @ A A A A A } } } C - , t R , H q q T L g c c k < < < v < f m P m ] ! 5 r 3 j U l l l l d E Q D _ _ 7 7 ` P v s s ; ; [ [ [ [ [ [ [ [ ; [ [ ; [ ; [ [ ; [ [ [ [ X [ X [ [ [ ; ; ; = s v f P ` 0 7 G N # # D D Q E E d d d l d l l l l ' l ' l l l l l ' d ' d l d d d E E ( Q 3 D _ _ N 7 0 P f f s s = ; = = s f P ` 7 7 _ _ Q E d d l U . o % * < = ; [ b b b b z b z z b k b z b <", +" k b b b b b b b [ [ [ ; ; < < < * & * L o o $ | S S @ S @ S S S S S S ' ' ' ' ' l l ' l l ' O ' l ' ' ' ' ' ' ' S S S S S @ @ @ @ @ @ A @ A A A A } } - C - t , Y t q I q g g & c k k < < s < v v m m ] ! ! r . j U U l l l d E E D # G n 7 ` P f s = ; ; [ [ [ [ [ [ [ [ [ [ ; [ [ ; [ ; [ [ [ [ [ [ ; X [ X [ [ ; ; = s v f P ` 0 7 7 N _ _ D D Q Q E E d d l d l l l l l l l l l l ' l l l l l d l d E E E Q Q Q _ 3 _ V 7 0 ` P v s = = = = = v v P ` 7 7 _ # D Q d d d U . o / / < = ; [ b y b b z b z b z z < z b z", +" b z b z b b b b b [ ; [ ; ; < < k / & o o L $ $ | | S S S @ S S S S S ' ' ' ' ' l l ' l l ' l l ' l ' l ' ' ' ' S S S S S @ S @ @ @ @ @ A @ A @ A 2 A } 2 } - C , t , Y q H q T h g c k k < < < s v / v m ] ] V 5 3 . j U l d d d d Q D _ # N 7 ` P v v = ; ; [ [ X [ X [ [ [ [ ; [ ; [ ; [ ; [ ; [ [ X [ X [ [ [ [ [ [ ; ; = s v P P 0 0 7 N N # # D Q Q E E d d d d l d l l l l l l ' l l l l d l d l d d d E E j Q 3 D _ G G n 0 ` P v v = = ; = = s f P ` 0 7 _ _ Q E E d l U . % ] * s ; ; b b b z z z z z z < z z b k b", +" z z k b z b b b [ b b [ ; ; = < < * * * L o o $ | | S S S S S S S ' S ' ' ' ' ' l ' l l l ' l l l ' l ' ' ' ' ' S S S S S S @ @ @ @ @ @ A @ A A 2 A } } C - C t R Y Y q T T L g c k k < < < s < v f f P ] ! 5 r j j U U l l d E E Q # N V 7 ` P f s = ; [ [ [ [ X [ [ [ [ [ [ [ ; [ ; [ ; [ [ [ [ [ [ [ X [ X X X [ ; ; = s v f P ` 0 7 G N _ # D D Q Q E E d d l d l l l l l l l l l l l l l l l d d d d d E Q Q D 3 # _ G 7 0 ` P v v = = ; = s s v f ` 7 7 N # D Q E d d j . o / / < ; [ b b z y z z z z z z z k z z z", +" z b z z b z b b b b [ [ [ ; ; < < k * * % o o $ $ | 9 S S S S S S S ' S ' ' ' ' l l ' l l l l l l ' l l ' ' l ' S ' S ' S S @ S @ @ @ @ @ @ @ A @ A A } 2 } } C - , t Y Y q q q g g g c k k < < = s s / f m ] ] ! 5 3 ( j d d d d d E D D _ N 7 ` P v s = ; ; [ X [ [ X [ [ [ [ ; [ ; [ ; [ ; [ ; [ [ [ X [ [ [ X ; [ [ [ ; = = s f f ` 0 7 7 N N _ # D Q Q E E E d d d l d l l l l l l l l d l d l d l d d d E E E Q ( D _ # N 7 0 ` P f s s = ; = = s v P ` 0 7 _ # D Q E d E U r % / / = ; [ b y z z z z z z z z z z k z k", +" k z k z z b z z b b b b [ [ ; = < < * / & L o o $ | | 9 S S S S S S S ' S ' ' ' ' ' l ' l ' l ' l l ' l ' l ' ' ' S ' S S S S S S S @ @ @ @ @ A @ A 2 A 2 } 2 } C C , t Y Y q I L L g k k k < < s < s v v P P ] ! r r j U j l l d E E D # _ n 7 ` P v s = ; [ [ X [ X ; X [ [ ; [ ; [ ; ; [ ; ; [ [ [ [ [ X [ X [ X X X [ [ ; = s v f P ` 7 7 N _ # # D D Q Q E E d d d d d d l d l l l l d ' d ' d l l d d E E E Q Q D 3 3 _ 5 n 7 ` P v v = ; = ; = s v f ` 0 7 N _ D Q E d E U o % ] < = ; b y z z z z z a z a k z z z z z", +" z z z z z z z z b z b b [ ; ; ; = < < / & % o o $ W | 9 9 S S S ' S ' ' ' ' ' ' l l ' l l l l l l l l ' l ' ' ' ' ' ' S ' S S S @ S @ @ @ @ @ @ @ @ A @ A 2 } C C C , t Y Y q q L L g c k k < < < s s v / f m ] V 5 5 . ( U d d d E E D D N N 7 ` P v s ; ; [ X [ X [ X [ [ [ [ [ ; ; [ ; ; [ ; [ ; [ [ [ [ X [ X X ; X [ [ ; ; s s f P ` 0 7 7 N _ # D D Q Q E E E d d l d l d l l d l l l d l d l d d l d d E E E Q Q 3 # _ _ 7 0 ` P f v = = ; = = s v f ` 0 7 _ _ # Q E E E . r % / < s [ b b z z z a a z a z a k z k z z", +" k z k z k z z z z b b b b b [ ; ; < < * / * o o o $ | | 9 9 ' ' S S S S ' S ' ' ' ' ' l l ' l l l l ' l l ' l l ' ' ' ' ' S S S S S S S @ @ @ @ @ @ A @ 2 A 2 A C } C t , Y Y q q q g g & k k < < < = s s v f P ] ] 5 r 3 ( j U d d d Q Q # _ N 7 ` P v = = [ [ X [ X [ X [ X [ [ ; [ ; ; [ ; ; ; ; [ [ [ [ [ [ X [ X X [ X [ ; ; = s v P P 0 7 n N _ _ # D D Q Q E E d d d d d d l d l l d l l d l l l d d d E E E E Q D D # G _ 7 7 ` P f s = = ; ; = s v f ` 0 7 N _ D Q E d E j % ! / s = b y z z z a a z a z a z a ) z a k", +" a z a z a z z z z z z b y [ b ; ; = < < * * & o o $ W | 9 9 S S ' S ' S ' ' ' ' ' l l l l l l ' l l l l l l ' ' l ' ' ' S ' S S S S S @ S @ @ @ @ @ @ @ A 2 A 2 2 C C C t t Y q q q g & & c k < < ; s = s v v m P ] V 5 r j j E d E E Q D # _ N 7 ` f v = ; [ [ X X X [ X ; [ [ [ [ ; [ ; ; ; [ ; [ ; [ [ [ [ X [ [ X X X [ X [ ; = s v f P ` 0 7 N N # # # Q Q Q E E E d d d d l d l d d d l d l d d d l d d d E E Q Q Q 3 3 # G G 0 0 P f s s ; ; = = = v f P 0 7 N _ D D E E j j r / m = ; [ b a y a a a a a a ) z ) z ) z )", +" ) z ) k a z a z z z z z z b [ [ ; ; < < * / * o o . $ | O 9 9 ' ' S ' ' S ' ' ' ' ' ' l ' l l l l l l l ' l l l ' l ' ' ' ' ' ' S S S S @ S @ @ @ @ @ @ @ @ 2 } 2 } C C t t Y $ q q L L g k k < < < < s s s v P m ] V 5 3 3 j U E d E E D # _ 7 7 ` f v = ; [ [ X [ X [ X X [ [ ; [ ; ; ; ; ; ; ; ; ; [ [ [ X [ X X X [ X [ X [ ; ; = s f P ` 0 7 N N _ # # D D Q E E E E d d d d d d l d l d l d l l d d d d d E E E Q Q D # _ N 7 7 ` P f s = = ; ; = = v f P 0 7 N # D D Q E Q . r / / = ; b a y a a a a z a z a ) a z ) a z", +" ) z a z ) z z a z z z z b z b [ ; ; = < / / ] & o o r W | 9 9 ' ' ' S ' ' ' ' ' l l l l l l l l l l l l l l ' l ' ' ' ' ' ' S ' S S S S S S @ @ @ @ @ @ A @ 2 2 2 2 C C C t t Y q q L L g c k k b = = = s s v f P ] V 5 r 3 j E E E E Q D # _ N 0 ` f v = [ [ X X X X X [ [ [ [ [ ; ; ; ; ; ; ; ; [ ; [ ; [ [ X ; X [ X X X [ [ [ ; = s v f ` 0 7 n n N # # D D Q Q E E E d d d d d d d d l d l d d l d d d d E d E Q Q Q D 3 _ _ V 7 0 P f s = = ; ; = = v f ` 0 7 N _ # Q Q E ( 3 ! ] v < [ z z z a a a a a a ) a z ) z ) z )", +" a z ) z ) a a z a a z z z z y b [ ; ; = < * * & % o . $ W | O 9 ' ' ' S ' ' ' ' ' ' ' l ' l l l l l l l l l l l ' l l ' ' ' ' ' ' S S S S @ S S @ @ @ @ @ @ 2 A 2 2 2 C C t t $ q q L L c & k < < < = = = s v v P m V ! r 3 ( j E E E Q D # N 7 7 ` f s = [ [ X [ X [ X [ X [ [ [ ; ; ; ; ; ; ; ; ; ; ; [ [ [ [ X X X X [ X X X [ ; ; = v f P ` 0 7 N N _ # D D Q Q Q E E E d E d d d d d d l d d l d d d d d d E E E Q Q D # # N n 0 0 P f v = ; ; ; ; s s f P 0 7 N _ # D Q Q ( r ! / s ; b z y a a a a a a a a z ) a z ) z )", +" ) z ) a a z a a z z a y a z y b b [ ; = = < / / % L o . W O 9 O ' ' ' ' ' ' ' ' l ' l l l l l l l l l l l l l l l ' l ' l ' ' S ' ' S S S S S @ S @ @ @ @ @ @ 2 2 2 C C C t Y q q q L & & k k < ; < = = s v v f ] ] G 5 3 ( U E E Q Q D # _ n 0 P f s ; [ X X X X X X [ [ [ [ ; ; ; ; ; ; ; ; ; ; ; [ ; [ [ [ [ X X X X X X [ X [ ; = s f P ` 0 7 n N # # # D D Q Q E E E d E d d d d d d d d l d d d d d d E E E Q Q Q D _ 3 N N 7 ` P f s = = ; ; ; s s f P 0 7 N N D D Q Q ( 3 ] / s ; b z a a a a a a a a a ) a ) ) a ) z", +" z ) a z ) ) z a a a a a a z z z b b ; ; < < / * * % o r $ W O 9 l ' ' ' ' ' ' l ' l ' l l l l l l l l l l l l l l l ' l ' ' ' ' S ' ' ' S S S S @ S @ S @ @ @ 2 2 2 2 2 t t t Y $ $ L L g c k < < < ; = = s s f f P ] ! 5 3 3 j Q E E D # # N 7 0 P v = ; [ [ X X X X [ X [ [ ; [ ; ; ; ; = ; = ; ; ; ; [ [ [ [ [ X [ X X X X X X [ ; = s v f ` 0 7 N n _ N # D D Q Q Q E E E d E d d d l d d d d d d d d d d d E E E Q D D 3 _ N G 7 0 P f s = ; ; ; ; = v f P ` 7 N # # D Q Q 3 5 ] m s [ z y a a a a e a e a a ) a ) z ) z )", +" ) a ) z a ) a a a z a a y a z y z b [ ; ; s < / / % % o o j | O O ' l ' ' ' ' ' l l l l l l l l d l l d l l l l l l l l l ' l ' ' ' S ' S S S S S S @ S @ @ @ @ 2 2 2 C C $ $ Y q o L & & k k < ; = = = = s v f P ] V 5 3 3 ( Q E Q D D N N 7 ` P v = [ X X X X X X X [ [ [ [ ; ; ; = ; = ; = ; ; ; ; ; [ [ [ X [ X X [ X X X [ [ [ ; s v f P ` 7 7 N N # # # D D Q Q E E E E E d d d d d d d d d d d d d E E E E Q Q Q D # # N V 7 ` P f s = ; ; ; ; s s f P 0 7 n N # D Q Q 3 r ] / s b y a a a a a a a a a e a ) a ) a ) a", +" a c a ) ) a a ) a a a a a a z a z y b [ ; s < / * / % o . . W U O 9 l l ' l ' l ' l ' l l l d l d l d l l l d l l l l l ' l ' l ' ' ' ' S ' S S S S S @ S @ S 2 @ 2 2 t C t $ $ q q L & & k < < b = ; = s s v f P ` V V 3 3 ( Q Q Q D # N N 7 ` f s ; [ X X X X X [ X [ [ [ ; ; ; ; ; ; = = ; = ; ; ; ; ; [ [ [ [ X [ K X X X X X [ ; = s f P ` 0 7 n N _ # # D D Q Q Q Q E E d E E E d d d d d d d d d d d E E E Q Q Q D # _ _ n 7 0 P f s = ; [ ; ; = s f P 0 7 N # # D Q D 3 5 m s = b z a a a e a e a e ) a ) ) a ) z ) )", +" ) z ) a ) a a ) a a a a a a a y z z b b ; ; = < m / & % o o W W O l l ' l ' l ' l l l l l l l d l d l l d l l l l l l l l l ' ' ' ' ' ' S ' S S S S @ S @ S @ S @ 2 2 S C t t $ q o L L c & k < = ; = = = s v f f ] V 5 5 3 ( Q Q Q D # # n 7 ` f = ; [ X X X X X X X [ [ ; ; ; ; = = = ; = = ; = ; ; ; [ [ [ [ X X X X X X X X [ [ [ = s v P ` 0 7 n N N # # # D D Q Q E E E E E d E d E d d d d d d d E E d E E Q Q D D 3 _ _ n 0 ` P v s = ; ; [ ; s s f P 0 7 N N # D D D 3 ! m s b b z a a a e e a e a e a ) a ) a ) ) )", +" ) ) ) ) a ) ) a a a a a a a a a a z y b [ ; = < / * ] % o r . W U O O l l l ' l l l l l l l d l l d l d l d d d d l l l l l l l l l ' ' ' ' ' S S S S S S @ S @ S 2 t $ q $ q L & * k < < < ; ; = = s v v P ` V 5 G 3 ( Q Q D D N N 7 0 P v = ; [ X X X X X [ [ [ [ [ ; ; = ; = = = = = = ; = ; ; ; ; [ X [ [ X X X K X X X X [ ; = v f ` ` 7 n N N _ # # D D Q Q Q Q Q E E E E E d E d E d E d E d E E E E Q Q D D # 3 N n 7 0 P f s = ; [ ; ; = s f ` ` 7 N _ # D D 3 G ! m v ; y a a a e a e a e a ) e a ) ) ) ) z )", +" ) a ) a ) a ) a ) a a a a a a a a y a y b [ ; = < / / % % o r . U U O l l l l l l l l l l d l d d l d d l d l l d l l l l l l ' l ' ' ' ' ' ' S ' S S S S S S @ S @ S 2 t | t | q o L L * k k < [ ; ; = = s s f f P V G G ( 3 Q D D # # N n 0 P v = [ X X X K X X X X [ ; ; ; ; = = = = = = = = = ; = ; ; [ [ [ [ X X [ X X X X X X [ ; = s v P ` 0 7 N N N # # D D D Q Q E E E E E E E E E d E d E d E d E E E Q Q Q D D # _ _ 7 7 ` P v s ; ; [ ; ; = v v P 0 7 n N # D D 3 5 ] f s b z a a e a e e a e e a ) e ) a ) ) ) a", +" ) ) ) ) ) a ) a a a e a e a a a a a z z b b ; = s v / / % % r . . U U d l l l l l l l d l d l d l d d d d l d d d d l d l l l l l l l ' ' ' ' ' S ' S S S S S S S S 2 $ W q o o & & k < < ; = ; ; = s s f f ` V 5 5 D 3 Q D D # _ n 7 0 f = ; X X X K X X X [ [ [ [ ; ; ; = ; = = = = = = = = ; ; ; ; [ [ [ [ X X X K X X X [ X ; ; s v P ` 0 7 n N N _ # # D D D Q Q Q E Q E E E E E E E E d E d E E E Q E Q Q D D # N G n 7 ` P v s ; ; [ ; ; = s f P 0 7 N _ # # D # 5 ] / = b a a e a e e e e a e ) e ) ) ) ) ) ) )", +" ) ) ) a ) ) a e e a a a a a a a a a a y z b [ ; = s * m & r % . . W U U l d l l l l l l d l d d d d l d d d d l d l d l l l l l l ' l ' l ' ' ' ' S ' S S S S @ S S | | | Y $ o L & & k < < ; ; ; = = = s v P P V G G 3 3 D D D # N N n P v = ; X X X X X X X [ [ [ ; ; = = = = = = = = = = = = = ; ; ; ; [ [ X X [ X X X K X X X [ ; s s f P 0 7 7 N N # # # D D Q Q Q Q Q E E E E E d E E E E E E E E E E Q Q Q D D # # N n 7 ` P v s ; ; [ [ ; = v f P 0 7 N N # D _ 3 G m v = z a a a e e e a e e e a ) a ) ) ) a ) )", +" ) ) ) ) ) a ) ) ) ) e a e a e a a a a z z z b ; = = / m / % % r . . j U d l d l l l l d d l d d l d d d d d d d d d l d d d l l l l l l ' ' ' ' ' ' S ' S S S S S S S S $ $ $ L o & * k < < ; ; ; ; = = v f f ` V V G 3 D D D # N N 7 0 P v ; [ [ K X K X X X [ [ ; ; = ; = = = s = s = s = = = = = ; ; [ [ [ ; X X X K X X K X X [ ; = s f P ` 7 n N N N # # # D D D Q Q Q Q E Q E E E E E E E d E E E E Q E Q D D D # _ G 7 7 ` f v = ; [ [ ; ; = s f P 0 n N _ # # # G ! P s z y a a e e e e e e a e ) e ) e ) ) ) ) )", +" ) ) ) ) ) ) e ) e a e a e e a e a a a a y a y b ; = s / m / % % r . U U U d d l d d d l d d d d d d d d d d d d d d d d l d l d l l l l l l ' ' ' ' ' S ' S ' S S S S 9 9 | | $ q o L & * k < ; ; ; ; ; = s s v P P V G G # 3 D D # # n n 0 f s ; X X X K X X X [ [ [ ; b = < = < = s = < = s = = = = b = ; ; [ [ X X [ X X K X X X X [ [ = s v P ` 0 7 n N N N # # D D D Q Q Q Q E Q E E E E E E E E E E Q Q E Q Q Q D # # N N 7 0 ` P v = ; [ [ [ ; = v f ` 0 7 n N # # _ G V f s b a a e e e e e e e e e e ) ) ) ) ) ) ) )", +" ) ) ) ) ) ) ) a ) a e a a e a a a e a a a z z b b = = < / ] ! % r j . j j U d d d l d d d l d d d d d d E d d d d d d d d d d l d l l l l l ' l ' ' ' ' ' ' S ' S S ' S 9 $ $ o o o * * k < = ; ; ; ; < = s f f ` 0 V 3 _ D D # N N n 7 P v = [ X X K X X X X [ b ; b ; < = < = s < s s s < s < = < = = b ; ; [ ; X X X X X K X X X X [ ; = v f P ` 7 n N N # # # # D D D Q Q Q Q E Q E Q E E E E E E E E Q Q Q Q D D D # N _ n 0 ` f s = ; [ [ ; ; = s f P 0 7 N # # # _ G ] m = z a e a e e e e e e e ) h a > ) ) ) ) ) c", +" ) c ) ) ) ) e ) e ) ) e e a e e e a a a a a y z b ; = s / m / % r r 3 U j d d d d d d d d d d d d d d d d E d E d d d d d d d d l d l l l l l l ' ' ' ' ' S ' ' S ' S 9 9 | | | $ o o L * / < < ; ; [ b ; < = v v P ` V G G _ # # # # N n 7 P s ; X X K K X K X [ [ [ b = < < ; < = < s < < s < s < = < = < ; b [ [ [ [ [ X X K X K X X X [ ; = s f P 0 7 7 n N N N # # D D D D Q Q Q Q E Q E E Q E Q E Q E Q Q Q Q D D D # # _ N 7 0 ` f s = ; [ [ [ ; = v f ` 0 7 n N # # # V ` v < z a a e e e e e e e e e e h ) ) ) g ) ) )", +" ) ) c ) ) ) ) ) ) ) e e a e a e a e e a a a a z y ; ; s < m * ] % r r j U j U E d d d d d d d d d d E d E E d E d E d d d d d d d d d d l l l l l l ' ' ' ' ' S ' ' S 9 9 9 | | W q o L * * < < ; ; ; b ; < = v v P ` 0 G 3 _ D # # N n 7 ` v s [ X X K X K [ X X b < b < < = < = < s < s s < s < s < ; < < = b = b [ [ X X X X X X K X X X [ = s v P ` 0 n n N N # # # # D D D Q Q Q Q Q Q Q Q E Q E Q E Q Q Q Q Q D D D # # N n 7 0 P f s = [ X [ [ ; = v f P 7 n N N _ _ G G m = b a a e e e e e e e e h e ) ) e h ) ) ) c c", +" c g ) ) g ) ) e ) e e a e e e e a e a e a a a y a b b = s v m ] ] % r r ( j U E d E d d d E d E E E d E d E E E d E E d d d d d d d l d l d l l l ' l ' l ' ' ' ' ' ' ' 9 9 | $ $ o % & & / < < [ ; b ; b < = v f P ` V V G # # _ N # n n P v ; [ X K K X X X X b b ; b < < < < < < v < < s < s < s < < ; < b < b ; b [ X X X K X K X X X X [ ; s v f ` 0 7 n N N N # # # D D D D Q Q Q Q Q E Q Q E Q E Q Q Q Q Q Q D D # # _ N n 7 0 P v s ; [ [ [ [ ; s s f ` 0 7 N N # # N V P s z a e e e e e e e e e e h e h ) ) ) h ) c g", +" c ) c ) ) ) ) h ) e ) ) e e a e e e e a e a a a z y b ; = s / m % ! r r j ( E j E E d E E E d E d E E E E E E E E E E E E d E d d d d d d l l l l l l l ' ' ' ' ' ' ' 9 9 O W $ W o L % / * b ; ; [ ; b b = < v v P ` 7 G _ _ # # N n n 0 f s [ X X K K X X X b b < b < < < s < < v < < v < < v < < = < < < = b ; b b [ ; X X X X K K K X X [ ; = s f P ` n n N N N N # # # D D D D D Q Q Q Q Q Q Q Q Q E Q Q Q Q D D D D # N _ n 7 ` P f = ; [ [ X ; ; = v f ` 0 n N N _ N G ` f k y a e e e e F e 4 e 4 e e ) h ) ) g ) c ) c", +" c c g c ) ) ) e ) ) e e ) e e e e e a e e a a a a z b b ; s v m / ] % r 3 . j U E E E E d E d E E E d E E E E E E E E E E E d E d d d d d d d l l l l l l ' l ' ' ' ' 9 O | | $ r o o * k < < ; ; b b b < < < v f P 0 V N _ # _ N # n n ` v = X X K X K X X b b b b < < b < < < < < / s / < f < < v < < < < < b < < [ b X X [ K X X X K X X X [ = s f P ` 0 7 n N N # # # # # D D D Q Q Q Q Q Q Q E Q Q Q Q Q Q D Q D D # # _ N 7 7 ` P v = ; [ X [ [ ; s v f ` 7 n N N # N V ` v b a a e e e F e e F e e > ) e h ) h ) g c g c", +" c ) c ) h ) h ) ) e > ) e e e e e e e e e e e a a a z b ; = s < ] m ! r r 3 ( ( j E E E E E E E E E E E E E E E E E E E E E E E E E d d d d d d d l l l l l ' l ' l ' l 9 O W W o o % & / < < ; [ [ b b b < s v f P 0 7 G N _ # N n n 0 f s [ X K K K X y X b b b k b k < < < < < f < < s / < / < < < < < b < < b b b b b X X X X K K K X X X [ ; s v f ` 0 n n N N N N N # # D D D D D Q D Q Q Q Q Q Q Q Q Q Q D D D # # # N N 7 0 ` f s = [ [ X [ [ = = v P ` 7 n N N N N V P s z a e e e e F e e e 4 e e e > ) h ) ) ) & ) c", +" c & ) c ) ) g ) ) > e e ) e e a e e e e e a e a a a y z b ; = v m m ! ! r r ( ( Q Q E E E E E E E E E E E E E E E E E E E E E E E d E d d d d l d l l l l l l l l ' l O O O | . o o & / * = = [ b b b b k b s v P ` 0 G N _ _ N # n n ` v = [ X K K X K y b b b k < < k < < / < m / v / < v s / < < / < < < < < b < b = b X [ X K X X K K X X [ ; = v f P 0 0 n n N N # # # # # D D D D D Q D Q Q Q Q Q Q D D D D D D # # _ # n n 7 P f s = [ X [ [ [ ; s v P ` 7 7 N N _ N 0 f < z a e e F e e F e F e > > h e ) h ) g & ) & &", +" c g c & ) g c e g e ) h e e e e e e e e e e e e a a a z b b = s v m m ! 5 r 3 3 ( j Q Q E Q E E E Q E Q E Q E Q Q E Q E Q E E E E E E E E d d d d d d l l l l l l l l O O W W . % L % / < < ; ; [ b b k b < < v f ` 0 7 _ N # N n n 0 P s ; X X K K K X b b k b k z < k < k < < < / < / < / / < m < < < < < < < < < b b b b b X X K K X K X [ X [ ; s f P ` 7 n n N N N N # # # # D D D D D Q D D Q D Q D Q Q Q D D # # # N N N 7 0 P f s ; [ [ X [ [ = s v P ` n n n # n G ` f b a e e e e F e F 4 e e e e ) h ) h ) & ) & c c", +" & c & ) & ) g g ) ) e h ) e e e e e e e e e e e e a a a z b ; = v / m ] ! 5 r 3 ( ( Q Q Q E Q E Q E Q E Q E Q E Q E Q E Q E Q E E E E E d E d d d d l d d l l l l l O O O W W o o % / * < = ; b b z b z < < v f P ` 0 G N N N N n n 0 v ; [ K K K X X y b z z z k k k < k / m / v < / v / < < m < / < < k < k z < z b < b [ X X X X K K K K X X [ ; s v f ` 0 7 n N N N # N # # # # D D D D D D Q D Q D Q D D D D D # # # _ N n 7 ` P v s ; [ X [ [ [ = s v P ` 7 7 N n N 7 ` < z a e e F F e F e e 4 4 > > > ) h ) g g & c & &", +" c & c & & ) ) h ) h h e > e > e e e e e e e e e e e a a z z b ; s v m m ] ! 5 3 3 3 ( Q Q Q Q Q Q E Q Q E Q Q E Q Q Q Q E Q E Q E Q E E E E d E d d d d l d l d l l l U U W o r r & / < < = [ [ b z z z k < < f P ` n n N # N n n 0 f s ; X K K K K y b z < z k k k k k < k < < / / < / v / v / < m < < < < k < k < k b b b b y X K X K X K X X [ ; = v f ` ` n n n n # N N _ # # # D # D D D D D D D D D D D D D # # # # N n 7 7 ` P v = [ X X X [ [ = s f P 0 n n N N n 0 P s z e e e e e F e F 4 e 4 e e ) > ) g g c & g c &", +" & c & c g g ) ) h ) e ) e h e e e e e e e e e e e a e a a y z b = s v m ] ! 5 r 3 3 ( ( Q Q Q Q Q Q Q Q Q Q Q Q Q E Q Q Q Q E Q E Q E E E E E E d d d d d d l d d l U U U . . o % / * / = ; b b y z z k b < f f ` 0 7 G N n N n n ` v = X X K K X X b b z z k k k k k < / / / / v < / < / < / < m < / < k k < k k z < z b b b X X X X K K K K X X ; = s f P ` 0 7 n n N N # # # # # # D # D D D D D D D D D D D # D # # N # N n 7 ` f s = [ [ X X [ ; = s f P 0 7 n N n n 0 f k a a e F F F e F F e 4 > 4 h > ) h g g c & c & c", +" & & c & c & g ) h ) h > e > e e 4 e e F e e e e e e e a a a z b = = v f m ] ! 5 G 3 3 D ( Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q E Q E E E E E d d d d d l d d U U . . r o % ] / < = ; b z z z z z k < v P ` 0 n n N N n n 0 P s [ X K K X y y z z k z ) k k k / k k / k / k / m / m < / v / k / k / k k z < k z < z b b b y X K K K K X X X [ ; s v f ` 0 n n N N N N N N # # # # # D # D D D D D D D # D # # # # N n n 7 0 ` v s ; [ X X [ X ; = v f ` 0 n n n N n ` v z a e e F e F F F e 4 4 e > e h ) h ) & g c & & &", +" c / & & c c g ) h ) > e h e > e 4 e e e e F e e e e e e a a a z b = s v f m V ! 5 3 3 3 3 Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q E Q Q E E E E E d E d E d d d d U U j . r r % * / < = ; b y z z a z k < / f P ` 7 7 N N n n n ` v ; X X K K K y b z k z ) k ) k k k * / k m k m v k m < m / < * v k / k k < k k k k z < z b y X X X K K K X K X [ ; = v f ` 0 7 n n n N N # N # # # # # D # D # D D D D D # D # # _ N # N n 7 ` P v = ; X [ X X [ ; = s f ` 0 7 n n n 0 P < z e e e F F F e F e F e > > > h h g g g * & * c /", +" & & & c & & g g ) h ) h h e > e 4 e e F e e e e e e e e e a a z z b = s f m ] V 5 5 G 3 D 3 D Q D Q Q Q Q Q Q Q Q D Q D Q Q Q Q Q Q Q Q E Q Q E E E E E d E d E U E U U . o % % ] / < ; ; b b z a z a k < < f ` ` 7 N N n n n 0 f s [ X K K K y b z z k ) ) k c k * / * < / / / / * m / / / / k / * < / k k k k k z k k z z b b b y X K X K K X X X [ = s v P ` 0 n n N N N N # N _ # # # # # # D # D # # # # # # # # N N n 7 7 ` P v = [ [ K [ X [ ; s v f ` 0 n n n 7 0 f < a e e F F e F F F 4 4 > 4 > ) h g g c & c & & & &", +" / & * & c & g g ) h ) > e h e > e 4 e e e F e F e e e e e a a a z z = s v f m ] ! G G 3 _ 3 3 D D Q D D D D Q D D Q Q Q D Q D Q Q Q Q Q Q E Q E E E E E E E E E E j j j j r % ] * < s ; b y z a a z ) k < f P ` 0 7 7 n n n n P v ; X X K K y y z z ) ) ) k c k c k k / * k / / / / / / * m k m / k / k * k k k k k k z z < z b z y X K K K K K K X [ ; s v f ` 0 7 n n N N N N # N # # # # # # # # # # D # # # # _ N # N n n 0 P f s ; [ X X X X ; ; s v P ` 7 7 n n 7 ` v ) a e e F F F F e F 4 e 4 > e > ) h g g & * & * / &", +" & * * * & c * g g h h ) h > e > e 4 e F e e F e F e e e e e a a a z b < s f P m V ! 5 3 G D D 3 D D D D Q D D Q D Q D D Q D Q Q D Q Q Q Q Q Q Q E Q E E E E E E j U j . r % ] / / s = [ b z z a a ) z k k f P ` 7 n n n n n ` f = [ X K K X y z z z ) ) ) c c c / & * k * / * / * < / / / k m / * k / k * k k k k a k k k z z b b y X X X K K K X X [ ; = v f P ` 7 n n N N N N N # N # _ # # # # # # # # # # # N # N N n n 7 0 P v s ; X X X X [ ; ; s v P ` 7 n n 7 0 P < a e e F e F F F F 4 4 > 4 > h h h g g g & * & & & &", +" / & & & & & g g g ) h h e > > e 4 e 4 e e F e F e e F e e e e a a z z b = v f P ] V G 5 G ( _ ( D D D D D D Q D D D D Q D D D Q D Q D Q Q Q Q Q Q E Q E E E E E ( j j r r % ] / < = ; b y z a a z a ) k < f P 0 7 7 n n n 7 P s ; X K K K y y ) z c ) k c c c * c k / / * / / * / / * / * / * / k / * k k / c k ) k ) k z k z z b b y K K K K X K X X [ ; s v P ` 0 7 n n n N N N N # N # # # # # # # # # # _ # N N # N n n n ` f v = [ [ X X X [ [ = s f P ` 7 7 7 7 0 f k a e e F F F F e F 4 4 4 4 h > > g g g * g & * / & /", +" & * & * & * c g g g > ) h h > e > 4 e F e F e e F e F e e e e e a a a < b s s f P ] V G G G G 3 # 3 D D D D D D D D D D D Q D D Q D Q D Q Q Q Q Q Q Q Q Q E Q ( ( ( 3 r % ! / / s s b y z a a a a z k < / P ` 0 7 n n n 7 ` v = X K K K y b z z ) ) ) ) ) c c c & & * & / * * / * / * / * / k * / * k / * k c k c k ) k ) z k z y b y X K X K K K X X [ ; s v f ` ` 7 n n N N n # N N N # N _ N # _ # # # N # N # N N n n 7 0 P f s ; [ X X X X [ ; = s f P 0 7 7 7 7 ` m z a e F F F F F F F 4 4 4 > > > h g g & & & * & & * &", +" & / & & * & & g g g ) > h e > > e > 4 e 4 e F F e e F e F e e e e a a z z = s v P ] V V 5 G # G 3 # 3 D D D D D D D D D D D D D D D D Q D Q Q Q Q Q Q E Q Q ( ( ( 3 r r ! / m v = ; b z a a a a a ) c < f P ` 7 7 n n n 0 f s [ X K K K y z ) ) ) ) c c g c & c & k * / * / / * / * / / * / / * / * / c * c k c c ) ) z k ) z k z b z y X K K K K X X X ; = s f P ` 0 7 n n N N N N # N N # _ # _ # N _ # _ N # N N N N n n ` P v = ; X X X K X [ ; = v f P 0 7 7 7 0 P < ) e e F F F F F F F 4 4 > 4 h h h g g & & * & & / & /", +" & & / & * & & c g h ) h h > e > > e 4 4 e F e e F e F e F e e e e e a a z b < s v P ` V G G G 3 _ # # _ # D # D D D D D D D D D D Q D D Q D D Q Q Q Q Q Q ( Q 3 . 3 r ! ! m / s ; b z a a a a e a ) k / f ` 0 7 7 n 7 0 P v ; X K K K y z z a ) ) ) g ) g g c & * & / & & & / & / / * / * / * / k & k & k & c c c c k ) ) z k z z z y y K K K K K K X X [ ; s v f ` 0 7 n N n N n N N N # N N # N N _ # N N # N N N N n n 0 ` f s = [ X X X X [ [ ; = v f ` 0 7 7 7 ` P z e e e F F F F F F 4 4 > 4 > > h h g g & g & * & & / &", +" / & & * & * & g & g g h h ) > > 4 4 > 4 4 e F F e F e F e e F e e e a a a z < s s f P ] V V G G G # 3 # D _ D # D # D D D D D D D D D D D D Q D D Q Q D Q 3 ( 3 3 r ! ] m m s = b y z a a a a a a ) k m P ` 0 7 7 7 7 ` f = X X K K y b z ) ) c ) h ) g g * g & & & & * / & & / & & / & / & * * * * * * & c / c c ) c ) ) ) ) z z z b b K X K K K K X X X ; = v f P ` 0 7 n n n N N N N N N # N N # N # N # N N N N n n n ` P f s ; [ X K X X [ [ = s v P ` 0 7 7 0 ` / z e e F F F i F F F 4 w 4 > > > h g h & & & * & * ] & &", +" & / * & & & & & g g g h h > > e > > e 4 e F e F e F F e F F e e e e e a a z z < s v f P ` V G G G G _ 3 _ # # D # # D # # D # D D D D D D D D D Q D D 3 Q D 3 3 r 5 ! ] / v = ; b z a a a e a e c k < f P ` 7 7 7 7 ` f s [ X K K K y z ) ) ) ) h g g g g g * & * & * & & * & & ] & & & / & / & & / & c * c c c c c c c k ) k a k z z z y X K K K K K X [ [ = s v P ` ` 7 n n N N N N N N N N N # N N N N N N N N N n 7 0 ` f v = ; X K X X K [ [ = s v P ` 0 0 7 0 P k a e e F i F F F F F u 4 > 4 > > h g g L & & * & & & & /", +" & & & * & * & g & g g g h > h > e > 4 4 4 4 4 e F F e F e F e F e e e e a a z z < s v P ` ] 0 G G G _ _ _ 3 _ # # D # # D # D # D # D D D D D D D D D 3 3 3 3 G 5 ! ] m v s ; b z a a a e a e a ) k m m ` 0 7 7 7 0 P v ; X X K K b z a ) ) h ) h g g g g g g & & & * & * & & * & & * & & & & & / & c & c & c c c c ) ) c ) z ) z z b z y y K K K K K X X [ ; = v f P 0 0 7 n n n N N N N N N N N N # N N N N N n N n 7 0 P f s ; [ X X X K X [ ; = s f P ` 7 7 0 ` m k e e F F F F i F F 4 w 4 w > > > h g & g & & * & / & / &", +" & ] & * & * L & & g g h h h e > > > 4 > 4 e F F e F e F F F F e F e e e e a a z b < v f f ` 0 V 7 G G 5 # _ # _ # _ # # # # # # # D # D # D D D D D 3 3 D G 3 5 ! ] m f s = z y a a a e a e a ) ) * m P ` 0 7 7 0 ` f = [ X K K y z z ) ) h ) h g h g g g g & & L & L & L * L * L * & % & * & * & & * & c & & g c c c c ) ) ) ) ) z z z y y X K K K K X X X ; = s f P P ` 0 7 n N N n N N N N N N N n N N N N n n n n 0 ` f v = ; X X K K [ X [ ; = v f ` ` 0 0 0 P < a e e F i F i F F F u w 4 > > > h L g L & L * & % & * & &", +" & & * & * & * L g & h g h h > > > 4 > 4 4 4 4 4 F e F F F e F e F e e e e e a a z < = v f P ` ] 7 V G N G _ _ 3 _ # # # # # # # # # D # D # 3 # 3 # 3 # r G 5 5 ] m f v = b b a a a e e e e a ) k < P ` 0 7 0 7 ` P s [ X K K y y z ) ) g g h h h g g g g & g L & & & & L & & & & L * & & * & & & * & c & g ) & ) g ) c ) c ) ) z k z z b y K K K K K K X X [ ; s v f P ` 0 7 7 n n N n N N N N N N N N N n N N n n 0 ` P f s = [ X X X X K [ [ < s v f P 0 0 0 0 f k ) e F F F i F F F M 4 4 w w > > h h g & & & & * & * & / &", +" & / & % & * & & & g g g h h h > > e > 4 > 4 4 e F F F e F F F F e F F e e e a a a z k s v f P ` 0 V 7 G _ 5 N # _ _ 3 _ _ # _ # _ # # # _ # _ ( _ 3 # G G 5 G ] ] m v s b b z a a e e e a e ) ) * m P ` 0 7 0 0 P v ; X K K K b z ) ) ) h h h h h h g L h L L g L & L & L & L & L & & L & & L & & g & g g & g c g g ) g ) ) ) ) ) ) z z z b y X K K K K X X X ; = s v f ` ` 0 7 n n n N N n N n N n N n N N n n n 7 ` ` f v = ; X X K K K [ X ; < s v f ` 0 0 0 P / ) e e F F i F i F M F w w 4 > > h h L L g & & & * & & / & &", +" & * & * & L * & L g g h h h > > > > 4 > 4 4 4 4 4 F e F F F e F F e F e e e e a a a z < s v f P ` ` G 7 G G N G _ N _ # 3 _ # # # # _ # _ # _ # _ 3 G G 5 G ] ] f v s = b z a a e e e e e a ) ) / / ` ` 0 0 0 ` v = [ X K K y z ) ) g h h h h h h h g h g L & L g L L g L L L & L & L & & & L & & & g & g g g g g g ) g ) c ) ) ) z ) z z y y K K K K K K X X [ ; s v f P ` ` 0 7 n n n n N N n N N N N n N N n n ` ` P v s = [ X X K X X X b b < s f P ` 0 0 0 m k a e F F F i i F F + u 4 w J > > > T g g L * L * & * & & * /", +" * & * & * * L & & L L g h h h > > > > 4 > 4 4 4 F 4 F F F F F F F F e F F e e e a a z z < s f f P ` ` 0 V n V _ G _ N _ _ N 3 _ _ 3 _ 3 _ 3 _ 3 G G G G V ] m P f s = b y a e a e e e e e e ) * m P ` 0 0 0 ` f s [ X K K y z z ) ) h h h > > h h h L h L L g h L g g L g L g L L L L g & L & L & g & g g c g g h ) g h ) g ) ) ) ) a z z z y y K K K K K X X [ ; = s v f P ` 0 0 7 n n n N n N N N n N n n n 0 0 ` P f v = [ X X K K K X [ b ; < s f P ` 0 ` ` m k e e F F i i F + F u w w w w > > T h L L & & L * & & * & & &", +" & & & * & L * & g & h g h h > h > 4 > > 4 > w 4 4 F F e F F F F F F F e F e e e e e a z z < s v f P ` 0 0 G n V N G N N _ N _ _ _ _ _ # G _ G _ G G G V V ` P v s = z z a a e e e e e e a ) c * / ` ` 0 0 ` P s ; X X K X b z g ) h h > h h > T h T g T h g T h L T L h L g h L g g & L L g & g L & g & g g g g g h ) ) h ) g ) ) ) z ) z z b y X K K K K K K X [ ; = v v P P ` 0 0 7 7 7 n n n n n n n n n 7 0 ` P f v s ; [ X X K X K X b b < < v f P ` ` 0 P * ) e F F i i F i F M u 4 w 4 H > > T L g & g & & & * & & * & &", +" * & * & & & & L & g L L h h > > > > > J > 4 4 4 4 4 F F F F F e F F F F F F e e e e a a k z < v f f P ` ` 0 0 7 N V N G G N _ N _ G _ N _ G G N G V V 0 m P v v < b z a a e e e e e e e > ) * / P ` ` 0 0 ` v = [ X K X y z ) c h T h > > > T > T h T h T T h T > T > T > T h g L h L g L g L L g L g L g h g g g g h g h ) h ) ) ) ) ) z z z y y K K K K K X [ X ; ; s v f P ` ` 0 0 7 7 7 n n n n n n n 0 0 ` P P v s = [ X X K K X X X b < < < / f P ` ` ` m k e e F F F i i + F M u w w J J > > T L h & L & * L & * & & & *", +" & * g & & L * & L h g g h T h > > > 4 > 4 w 4 w 4 4 4 F F e F i F e F e F e F e e e e a a a k < s f f P ` ` 0 V 7 n V n G V N G N G N 5 V N G V V 0 ] P P v s < b z a a e e e e e e e e ) ) * m f ` 0 ` P f s [ X K K y z ) c h h > I I > T h T T T > T h T > T h > T h h T > T h L T g L L g L g L g h g g g h g h g h ) h ) g ) ) ) z ) z z y y K K K K K K K X [ ; = s v f f P ` ` 0 0 7 7 7 7 7 7 0 0 0 ` ` P v v = [ [ X K K K K X b b b < / v P ` ` ` m * ) e e F i i i F i M u w u w > > I T T g L g & g & & * & & * & &", +" * & & & & & L & g & L h g h > > > > > > w > 4 w 4 w F 4 F F F F F i F F F F F F e e e e a a z k < / v f P ` ` 0 0 0 n V n 7 G 7 G V 7 G n G 0 V 0 ` ` f v v = b z a a e e e e e e e e e g c m m ` ` ` ` P s ; X K K y b z c g h I T > I T I I h > h > T > T > > I h > > T > h T T > T L h h h L g h g L g L h g h g h h h g h ) h ) ) ) ) z z z b y K K K K K X [ X [ ; = s v f P P ` ` 0 0 ` 0 0 0 0 0 ` ` ` f v v = ; [ X X K K K X b b b k < < f P ` ` ` m c e e F F i i i F + u u u w J J J > > T g L & g & g & & & & & * &", +" & & & L * g & L L L g L L > h h > > 4 > 4 J 4 w 4 u 4 F F F F F F F F F F F e F F e e e e a a a z < s v f f P P ` ` 0 0 0 n 7 V n n V V 0 V 0 ` ` f f v s < z z a a e e e e F e F e e h c * m P ` 0 ` f v ; X X K X b z c h h T I I I > I > > I I I > I > > > > > > > > > > T > > T h T T h L T L L T h h h h h h h g h h ) h ) h ) ) ) z ) z z y y X K K K K K K [ [ ; = s s f f P P ` ` ` ` ` 0 ` ` ` P P f f v s ; [ X X K K K X X y b k k < / m P P ` m / ) e e F i i i i F + u u w w J 4 T I T L L g g g & & & & c & * g &", +" & g * & L & g & g g h h T h h > > > J > > J 4 w 4 4 4 u 4 F F F F F F F F F i e F F e e e e a a k z k < v f f P ` ` ` 0 0 ` 0 ` 0 0 0 0 0 ` ` P P f v s < z z a a e e e e e F e e e > g & / m ` ` ` P v = [ X K K b z ) g L T I I I I I > I I > > I > > > J > > J > > > > > > I h T > T h T T h h h L h T h L h h h h h h > h h ) h ) ) ) ) z z z y y K K K K K K X X [ [ = s s v f f P P P ` ` ` P ` P P f f v s ; [ [ K X K K K K b b z < k < < m P ` ` m / e e F F i i i + + M u u w w J I I T h L g L & g & & g * g & g & c", +" g * g & g & L L g L g L T h > > > > > 4 J 4 I 4 w w u F w F F F F F F F F F F F F e F e e e e a a a k < < / v f f P P ` ` ` ` ` ` ` ` ` P P P f v v < < z z a a e e e e F e F e e 4 ) ) * / m ` P P f s [ X X X y b ) c L T I I I I I I I > I I > I > J > > w > 4 > J > J > > > > T > T T > T h T T h T h T h T h h h h h h h h ) h ) ) ) ) z z z y y y K K K K K X K [ [ ; = s s v f f f P P f P P P f f v v s ; ; X X X K K K X y y b z k k < m f m m m / ) e e i i i i F i M M u. w w J > I > L T h L g & g g g & g c * g *", +" & g & g L & g L g L L h T T h > > I > > J 4 J w 4 4 4 u 4 u F F F F i F i F F F F F F F e e e e a a a z k < < v f f f f P P P P P P P P P f v v v < b z a a a e e e e F e F e e 4 e h g / m P ` P f s = X X K X b ) c g T q I q H H > J I J > J > J > > w > 4 > w > J 4 > 4 > I > I > I h T > T T h T T T h T h > T h > h h h h h h ) h ) ) a k z z b y K K K K K K X X X [ ; = s s s v f f f f f f v v s s = ; ; X X X K K K K K z b z k k k / m m P ] m g ) e F F i i i i + 6 M x. w J J J I T T g L g & g g g & c & & g & g", +" g & g & & g L g L g T g T T > I > > J > 4 J > 4 w w w F u 4 M F F F F F F F i F F F F e F e e e e a a a k z < < < v v f f f f P f f f v v v < < < z z a a e e e e F F e F e F 4 e h & c / m P P P v = [ X K X b z c g q T I q H H J I H > J I J J 4 J 4 J 4 J 4 J 4 > w > H > 4 > I > > T T T h T T T > T T > T h T > h h h > h h ) h g ) ) ) a z z z y K K K K K K X X X X [ ; ; s s s s v v v v v v s s = = [ [ X X K K K K X b y z k k k k k m m m m / c e F F F i i i + M M x x. w J J > I T T L g h g g g g c g g & g c g", +" g g g L g L g L h L h T h T > > I > J > I J w w w 4 w w 4 u 4 + F F F i F i F F F F F F F F F e e e e a a a k k < k < v / v v v v v v v < < < z k z a a e e e F e F e F e F e e > h c / ] P P P f = [ X X X y k c L g q q q H H H I J > J J I 4 > w > w > J 4 J 4 > J 4 J 4 J > J > I > I > I I T > T T T h T T > T > h > h > h h h > ) g ) ) ) ) z z y y X K K K K K X X X [ [ ; ; = = s s s s s = s = = ; [ X X X K K K K K y z z z k ) k k / m m ] m & ) e F F i i i i + M 6 x w. w J I I T T T L g L g & & g g * g c g g g", +" g & g & L g L g L T L T T T > I > I > J 4 > w w w w 4 u 4 u F u F F F F F i F i F F F F F e F e e e e e a a a ) a k k k < < < < < k < k < z k a a a e e e e e e F F F e F e 4 4 ) g & / m P P f s ; X X K X b k g L L q q H H H J J J J J > w J J 4 w 4 w 4 w > w 4 w > 4 I J > J > > I > > I > I T I > T I T > T h > h > T > h h h h h ) h ) ) z z z b y y K K K K K K K X X X [ [ ; ; ; = = = = = = ; ; [ [ X X K K K K K X y z z k ) ) k / / / m m * g e 4 F i i i i + + 6 x x. 8 w J H I I T h L g g g g g g g g g & g * g", +" g g & h g L g L T g T T T I > I > > J I J J 4 J 4 w w w u w u F u + F F F i F F i F i F F F e F F e e e e e a a z a ) z < ) k k k k k z k a a a a e e e e e F F F e F F F 4 e > g g / m P m f s ; [ X X X b ) & & L q Y H Y H J H J J J J w J 4 w w w 4 w 4 w 4 4 w 4 J J 4 > w > J J > J I > I > I > I T > > I > I > I I h > T > > h h h ) ) ) ) ) z z z y X K K K K K K X X [ X [ [ [ ; ; ; ; ; ; ; [ [ X X X X K K K K K z b z z ) ) c c * m / m / c > e e F i i i i + M ~ x ~. R J H I I T T T g h L g g g & g c g g g g g", +" g L g L g L h T L T T T T > > I I J > > w J J w w w 4 u w F u w u F + F F F i F i F F i F F F F e F e e e e e e a a a a a a z a ) z a a a a a e e e e e F F e F F F F e e 4 > > g & * m m f v < [ X X X b z k L L q q q Y J R J J J J J 4 J w w w 4 w w u 4 w w w 4 w 4 J J J 4 I 4 I J > > J > I I I > I I > I > I T > > I T I h T h h h h g ) ) z ) z z y y K K K K K K K K X X X X [ X [ [ [ [ [ X X X X K K K K K K K b y z z ) ) k k / k / m * / g e 4 F i i i i { M 6 6 ~. . . J J H I T T L L g g g g c g g g g c g g g", +" h & h g L g L h T T T T > I I > I > J > w > w > w w w w w w u u F M F + F i F i F i i F F i F F F e F F e e e e a e e a a a a a a a a a e e e e e e e F e F F F F e F 4 4 4 > h g / m m m f < ; [ X X [ b * & L q $ q Y H J J J J J > J w w 4 w w 4 u 4 4 u 4 u 4 w w w > w 4 J > J J > J I > J I > I I > I I > I I > I I I T > h > T h h g h ) c ) a z z z y y X K K K K K K K K X X X X [ X X X X X X X X K K K K K K y b z z ) ) ) c c g / * ] / L h e e i i i i i + 6 6 ~ ~ 8 R R J H > q T T T L g L g g g g ) & g g g g g", +" g L L L g T T T T T T T I I > I J I J J J J J 4 w w w u 4 u u u u u M F + F F i F F i F i F i F F F F e F e e e e e e e e e e e e e e e e e e e e F F F F F F F F F e F 4 > ) g & / m m f < s b X K X b k g L o q Y Y R R R H J J w w w w w w 4 u w u 4 u w 4 u 4 w w 4 w 4 H J w > J > J > J I J > I J > I I I > I I > I > I I T I T > h h g g ) ) ) ) z z z y K K K K K K K K X X K X X X X X X X X K K K K K K K K y y z z ) ) ) c c c / * / * & g e 4 F i i i i { + 6 ~ ~ ~. . J J H q > T T L g h g g g g g g g g & g g g", +" L g g h L T L T T T I T > I I > J > J I 4 J w J w w w w u w w u F u M M F M i F F i i F i F F i F F F F F e F F e e e e e e e e a e e e e e F e F F F F F F F F F F F > 4 > > & * / / m / = b X X X b k & & o q $ Y Y R H R w J w w w w w w u w u 4 F u w F w u w 4 w 4 w w w > J J w J J J > J > J J > J I I J I I I I H > q > I T > T T h h g h ) k ) z z z y b X K K K K K K K K K K X K X X X K X K K K K K K K y z z z ) z ) ) ) c & & * * * g h 4 e i i i i i { 6 Z ~ ~ ~ 8 R R H H I q T T g L g g g g g & g g g g h & g", +" L h L T T T T T T T I > H I H J > J J J J J J w w w 4 w w w u w u u F M M + + F i F i F i i F i F F F F F F F e F e e e e e e e e e e e F e F F F e F F F F F F e F 4 4 > ) h & / * m < s b [ y [ [ z k & o o q Y Y H R R R J w w J w w w 4 u 4 u u u w F w u 4 w u w w w w J w > w > w > J > J I > H J I J > I H I I I I I > H I I I T T T h h g ) g ) ) z z b z y K X K K K K K K K K K K K K K K K K K K K K K y y b z a ) ) c c g g c & / & & g e 4 F i i i i { 6 6 6 1 1 8 8 R R J H I I T T L h L g g g g g g g g g g L h", +" h g T L T T T T I I I I I I > H J J > J J J J J w w J u w u w u u u u u M M F + F i F i F i i F i i i F F F F F F F F F F F e F e F F F e F F F F i F F F F F F F 4 4 > > h & & / m m < b b b X X b * * L o Y $ Y Y , R H. R w. w x 4 u u u u u 4 u 4 u F w u 4 w w w w > w 4 w J J J J J H J J I J I H I H H > H J I I H I I T I I I > T T h g h ) k ) ) z z z y y y X K K K K K K K K K K K K K K K K K K K y y z z z ) ) ) h ) g g & & & * L h e F F i i i i { 6 ~ 1 1 8 p R J R H q I L q g L h g g L g g g g g L g h g L", +" L T T T T T I I T I I I H I J I J I w J J J w w w w w. w w u w u u u u F M + + + + i F i i F i F i F F i F F F F F e F e F F F F e F F F F F F F F F i F F F F 4 4 > 4 h g & / * m < < < X X X < k k o o o q $ R Y R R. R w w w. w u u F u u F u F u w u u 4 u w 4 w w w w J w > w > J J J > J J H J J H J H I H H I H H I H I I T I q h T T g h g ) ) ) ) z z b z y y K K K K K K K K K K K K K K K K K X y b z z z ) ) ) g ) h g g * & & L h e 4 F i i i i i 6 6 ~ 1 1 p 8 8 R H H I q T T T L g L h g g g g g g g L g L g", +" T T T T T I T I I I I J I J H J J J J J J w J w J w w w. w. u w u u u M u u + F + F i F i i i i i F i i F F F F F F F F F F F F F F F F F F F i F i F F F F F w 4 J > h g * * / / < b b X X [ < k % L o $ t t , Y R 8 J 8 w. w u w u w u u F u u u u u u F w w u w w w w w w J J J J w J J J J J H J I J H J J H H H H H I H H q I I I I T T T h g h ) k ) ) z z z y y y X X K K K K K K K K K K K K K y y y z z a ) ) ) ) h h ) g & L & & g > 4 e i i i i i { 6 Z 1 1 p p 8 R R Y H I I q L T g L g L g g L h g h g L g T L", +" T T L T T I q I I H H H H H J J J J J J w J w w w w w. w u w. u u x u M M u + M + + + i F F i i i i i F i i F i F F F F F F F F F F F i F i F F F i F F F F w 4 4 > > g & & / * < < b b X ; b k & % o o $ t Y Y p R R. R w u w u u F u u u u u F u u F u u w u 4 w w w w w J w w J J J J J J J J J H J H J I H H H H H H H H I I q I q T I L T L g g g ) c ) z k z b z y y y X K X K X K K K X K X y y b y z z z ) ) g h ) h g h g g & L g h > 4 F i i i i i 6 6 Z 1 p p p R 8 R J q H q T T L T L g h g L g L g L L g T L T", +" T T H T q I I I H H I H H J H J J J J w H w R w R w R. w. . w x w x u u u M u + F + + F i i i F i F i i F i F i F i i F i F i F i F i F i F i F i F F F 4 u 4 w I > h L * * / < k b b X [ ; k / & o o $ $ t , Y 8 R 8. . . . u u u u M u M F M u u u u w u w w u w w w w w w w J J w J J J J J J J J J J H J H J H H H H H H H H H I I q I q T T T L h ) c c ) ) z z z b z y y y K y X K X K y y y b y z z z ) ) ) ) ) h h h h g h & g L h > e F i i i i { { 6 1 1 : ^ p , p Y R H q I h q L T g L L g L g g L g L T h L T T", +" q T I H I I q H H H H J J J J J R J w R 8 w R w R. w. . w. u. u x u x M M M M 6 + + + + F i i i i i i i i i i i F i i F i F i F i i F i i F i F F F + u 4 w 4 > > L & & / * k < b b [ [ k k / o o $ $ t , , 8 R. . w. u u u u u u F M u M F M u F u u w u w w w w J w w H w w H J J J J J R H J H J H J H J H J H H H H I H q H q I q > q T T g L g h c c ) ) k z z z b b y b y y y b y y z y z z z z ) ) ) g h h h h h h g L L L g > 4 4 F F i i i i { Z 1 ^ ^ p p , 8 Y R Y I q I q T L L g L L g L L g L g L T T L T", +" T I q q I H H H H J H J R J J R J 8 R J w R. R w 8. w. . . . x. x x x u ~ M u + u + + + + i F i F i F i i F i i i i F i i i i i F i i F i F F i F M F w 4 w > > h L & c * k k b b X [ b k * % o . $ | t t , R 8 8. . . u u u u u u M M u M u u u u u u w u w. w w. w R w 8 J R J 8 R R H R J J R H R J R J Y J Y H H H H H Y H q H I I q T q L T L h g g ) k ) ) k z z z z b z z b z y z y b z z z z ) ) ) ) h ) h h h h h h g h g > > e F i i i i i { 6 1 1 ^ ^ ^ ^ p R R R H q I q L L T L h L g L L g L T L T L T T q", +" I q I I H H H H J R J R H R R J 8 J 8 R 8 J 8 w 8. R. . . . . . u x x x x M x 6 M u M + + + + + i i i i i i i i i F i i i F i F i i i F i F i F M F M w u w J > > L g * / k k b b b [ ; < / / o r o | C t - , p R p. . x x u u u M M + u M u M u u u u u w u w u w 8 w R. R w R. J R J J 8 R H R R J R R I R J H J Y J Y Y H H H q H q q H q I q L T T L g g ) ) c ) ) z k z z z z z z z z z z z ) ) ) ) ) ) h h h > > h T h L L T h > 4 4 F F i i i i 6 ~ 1 ^ ^ ^ ^ , , p H Y H q H q L I L L L T L g T L T g L T q q T T", +" H I H H H H R R H R R J R R. 8 R. R w R. . R. . . . . . . x. x. x x x x x x M M M M M + + + + F i F i i F i i i i F i i i i i i F i F i F + M u u 4 w > w > > L & & & k k z b [ [ < * * % o . | | | , , , 8 8 8. . x x x M u M u u + u M M u u u u w u w. w. w. R w w R J R R. R R R J R H R R H Y R R Y R R H R H H H Y H Y q Y H q I q T q q L h L g g g ) c c ) ) z ) k z z k z k z ) ) ) ) c ) g g h h h > h > T > T T > > > 4 F i i i i i { 6 ~ ^ ^ ^ ^ - , p Y Y Y q q q I q L L L L L T L L L L q T q T T q I", +" q H H Y J R H R R H R R. R J R 8 J 8 R 8. . R. 8 R 8. . . . 8 x. x x x 6 x 6 x 6 M M M M + + + + + i i F i i i i i i i F i i F i i F i + F M F u w u w 4 I > g L c & k k z b b [ ; < / / % . o | | C t - p , 8 ~ x x x u x M M u M u u M u M u u u u. u. . . . . . J 8 R. J 8 R J R R R R R R Y R R R H R H Y H Y R q R Y H H Y I Y q q q q q T L q L L L L g g c c c c ) ) ) ) k ) ) ) ) ) k ) c g h h h T T > I T > T T h T h > 4 4 F i i i i i + Z p ^ ^ } ^ - - , R R H Y q q T q L q L q g q T L T L T q I q I H I", +" H Y H R H Y R R R R. R R 8 8 R 8 8 8 8 8 R 8 8 8 8 x 8. ~ 8 ~. 8 x ~ x ~ x x x x 6 x 6 M 6 M M + + + + + + i i F i F i i i i i F i F + + M M u u u w 4 w J I T L & & & k k k b [ ; < < ] % o . W | C t p , 8 p 8 x x x x M M u M M M M u M u u u x u x. . . . . R. 8 R. R 8 R R R R R R R R H R H R H R R H R R R H R Y H H Y H Y H q Y q q q q q L I q L g L L g g g c c c c ) k ) ) c ) c g ) h g h T T > T > I h I T > h > > 4 4 F F i i i i { 6 ~ ^ ^ } B - - , p Y Y Y q q q q q L q L L T L L q L q q T q I q q H", +" H R R H R R J R R 8 R 8 8 R p 8 8 p 8 8 ~ 8 ~ 8 8 8 8. 8 p. 8 ~ x p x 8 x ~ ~ M x 6 x M 6 M M M M M + + + + + + i i + i F i F + i + + + u + u M u w u w J > > T g g & k k z b b ; ; < / * r r . | | t C - , p ~ 8 ~ x x x x 6 u 6 M M M M u M M x u x. . . . . . . R. R R R 8 R R R 8 Y R Y R , R Y Y R Y R Y R Y H Y R H R Y R H Y H q Y q H q Y q q q q L q L L g L g g g g g ) g ) g ) & ) g g g g h T T T I I T I > > I T > I > 4 4 F i i i i i { 1 p - - } - } - - Y R Y H Y q q q T q L q L q L q L q I L q I q H Y H", +" q R R Y R R , 8 8 R 8 , 8 8 R p 8 8 8 8 p 8 8 p 8 ~ p 8 ~ 8 8. ~ 8 ~ 8 ~ ~ ~ x ~ ~ x ~ 6 x 6 6 + 6 M M + + + + + + + + + + + + + + + u + M u u u w w w > J I T g L & * ) k k b ; ; < / ] % r r . | 9 C C - p p 8 8 ~ x ~ x M 6 M x M M 6 u 6 x u x x x x x. . . 8 8 R 8 R 8 8 R , 8 Y 8 Y 8 Y R Y R Y R , Y R Y Y R Y R Y t H Y Y H Y Y Y Y H Y q q q q q q q L q L q L L L L g g g & g g g g h g L T T T T I I I I I I I > > I > > J 4 F i i i i i { 6 8 p ^ } } } - - p , Y Y Y q q I q L q L q q L q T q I q q q q H q H Y", +" R Y Y 8 R , 8 , , - p p p , 1 p 8 p p p p 8 p 8 ~ 8 8 ~ 8 p 8 ~ p 8 ~ ~ ~ x ~ ~ ~ ~ 6 x ~ M x 6 6 6 M 6 M M + M + + + + + + + + + M M M u u M u u w u w J > I T h g g c k z z b ; = < / ] % r . U | 9 C C , - p p ~ ~ ~ x 6 x x 6 M x 6 u 6 u x x x x. . . 8 8 8 8 p 8 8 , 8 , Y p Y , , , Y , Y , Y , Y Y R t Y R Y Y Y Y H , Y R Y Y Y H Y q Y q Y q q q q q q q L L q L L L L L g L g L g L L L T L q T q I q I I I I I I > I > 4 4 F F i i i i i + x p - } } } } - - t , Y Y Y H Y q q q q L q L q q L q q I q H q Y H Y J", +" Y , R p , p , p p 1 , p , p p p p p p p p p p 8 p p 8 p 8 8 p ~ 8 ~ p 8 ~ 8 8 ~ ~ ~ ~ ~ ~ ~ ~ 6 x M 6 6 M 6 M 6 M M M M + M M M M M M M M M x u w. w w > J T T L g c c k z < ; ; < / / % % . . W 9 C - - , p ~ 8 ~ x ~ u 6 M 6 x 6 x M x 6 x x x x x 8 ~ 8 p 8 8 8 R , p , R , , Y , , Y , , Y , Y , R Y Y R Y , Y Y R , Y Y Y Y Y Y Y Y Y Y q Y Y H $ Y q q q q q q q L L q L L q L L q L q L T L q q I q I I I I H > J > I J > w 4 F i i i i i { 6 8 p - } } } } } - - , , Y Y q q q q q q q q q T q q q q q Y q Y H Y R Y", +" , 8 , , p , p , p , p p p p p p p p p p p p p p p p p p p ~ p 8 p 8 ~ 8 1 ~ ~ 8 ~ ~ ~ ~ 6 ~ Z ~ Z 6 6 6 6 6 6 M M 6 + 6 M 6 M 6 M 6 M 6 u x u x. w w J J I T T g g c ) k z < [ = < m ] ! r 3 j O 9 t C C - p p p ~ ~ ~ 6 6 x x 6 M 6 x 6 x x x ~ ~ 8 8 p 8 8 ~ , , , p , , t p t , , t , t , t t , t Y t C t Y , Y Y Y Y Y Y R Y Y Y Y Y Y Y Y Y Y q $ q Y q $ q o q q q q q L q L L q L q L L q q I q I I q H H H H J I J I J 4 J 4 4 i i i i i i { x p - - C } 2 } - C , t Y Y Y q Y q q q q q q q q q q q q Y q H Y R Y Y ,", +" p t p - p - p - ^ ^ ^ ^ ^ ^ - p ^ p ^ p p p p p p p p p p p p p ~ p p 1 p p ~ 1 ~ 1 ~ ~ ~ ~ 6 ~ 6 ~ ~ 6 x 6 M 6 6 6 6 6 6 M 6 M 6 x 6 x x x x. . w w H J > T g g g c k k b ; ; s / / ! % 3 . . O 9 2 C - - p p p 1 ~ ~ x ~ Z M 6 x 6 x x 6 x ~ ~ x ~ ~ 8 ~ 8 , p , p , , , , t , t , t t t t t t t t t t t , t Y t , Y , Y , Y Y Y R Y Y Y Y Y Y Y Y Y Y Y $ q Y q Y o q q o q q q q q q T q q q q q I q H q H H H I J I J > J > w F F F i i i i { M ~ , - C 2 2 } } C - t , , Y Y Y $ q q q o q q q q q q Y q q Y R Y R Y R ,", +" , - , - - ^ - ^ ^ - ^ ^ - ^ ^ ^ ^ ^ p ^ ^ ^ p ^ p p 1 p p p p p p p 8 p 1 ~ p 1 8 1 ~ 1 ~ 1 ~ ~ ~ ~ ~ 6 ~ 6 Z 6 x 6 6 M 6 6 x 6 6 M x x x. . w 8 w H I H T T L g g ) k z b = = < m m ! r r . U O 9 2 C } ^ p p 1 ~ ~ ~ 6 ~ 6 ~ 6 x 6 ~ x ~ ~ ~ 8 8 8 p p , p , p , , C , C t C t t t C t t t t t t $ t t t t t t t Y t , Y Y Y Y Y Y Y Y Y Y Y Y $ Y q Y $ $ q $ q q q q o q q o q q q q q q H q Y H H H H H J I J > w 4 w 4 F + i i i i i { x 8 p C 2 } 2 2 } C } , t Y Y Y $ q q Y q q q q q q Y q Y H Y Y Y Y , Y p ,", +" - - - ^ - ^ - ^ - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ p : ^ p ^ p 1 p 1 p p 1 p p p ~ p 1 1 p 1 ~ 1 ~ 1 ~ 1 Z ~ ~ ~ ~ 6 ~ 6 ~ ~ 6 ~ x 6 x ~ x ~ x x. . w J J H I T L g c c c k b < ; s / m ] ! 3 3 ( U O 9 2 C - - ^ p p 1 1 ~ ~ ~ ~ x 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ p p p p , - - C - t C t C | C $ t | $ | | t | | t | t | t $ t t t t t t t Y t t t , Y t Y t Y Y Y Y Y Y Y Y q Y Y q Y $ Y $ q $ q q q q q Y q q Y q H Y H Y J H J I w J J J 4 u F i i i i i { M. , - C 2 2 2 2 } C C C , t t Y Y Y Y $ q $ Y q $ q Y q Y Y Y , Y R , , - ,", +" - - - - - B - ^ } ^ } ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ : ^ ^ ^ ^ : p ^ ^ p ^ p p p p 1 p p 1 p p ~ p 1 1 1 ~ 1 1 ~ 1 6 ~ ~ ~ ~ ~ ~ 6 ~ ~ ~ ~ ~ ~ x ~. . R. R J H I I T h g g c ) k z s = < m m ! 5 r 3 j U 9 C 2 - ^ ^ p 1 ~ 1 ~ ~ 6 ~ 6 ~ ~ ~ ~ ~ ~ p p p p p , ^ - - - , C C C t | C | | | | $ | | t | $ | t | t $ t $ t t t t t t t Y t t Y t Y t t Y t $ Y Y $ Y $ q $ Y q q $ q q Y $ Y q $ q q Y H Y Y H J J H J J J J J J w u F + i i i i i { x 8 p C C 2 2 2 2 2 } C , t t Y Y q $ q q Y q Y $ H $ Y Y Y Y Y t Y , - , - -", +" } - } } B - } B - B ^ - B - B ^ ^ ^ : ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 ^ p ^ 1 ^ p p p p p p 1 p 1 p p 1 1 1 1 ~ 1 1 1 ~ 1 ~ 1 ~ ~ ~ ~ ~ ~ x ~ ~. 8. . R w J H H T T L g ) c k k b = = v m ] ! 5 3 ( j U O S } } - ^ p p 1 1 1 Z ~ 1 ~ ~ ~ 1 ~ 1 1 ~ p p p , - - - , C C C C | C | | | W | | W | | | | $ W | | t W t | | | t | $ t t t t t t t t t t t Y t Y t Y t Y t Y Y Y $ Y $ Y Y $ Y q $ Y Y Y q Y H Y H J Y R J J J J J 4 w 4 u F F i i i i { +. 8 t C 2 2 } 2 C C C , t t t Y Y $ Y Y $ q Y Y Y Y Y t Y , , - , - - - -", +" } } } } } } B } ^ } } ^ - ^ ^ B ^ ^ - ^ : ^ ^ ^ : ^ ^ ^ ^ ^ ^ : ^ ^ p ^ ^ 1 ^ p 1 p p 1 p 1 p 1 1 1 1 1 ~ 1 1 1 1 ~ 1 ~ 1 ~ ~ ~ ~ 8 8 ~. 8 R J J H H I T T L g c c k b < = s / m m ! 5 r 3 U O l 2 C } ^ ^ ^ p 1 1 1 ~ 1 Z ~ 1 1 ~ 1 p p p p ^ - - - C C C C | 9 | O | | | | W W W $ . W W | $ W W | $ | $ | t | t $ | t t t t t t Y t t t t t Y t Y t $ $ $ Y $ Y q Y $ Y q Y Y Y Y Y Y Y R H R R H J J R J J w w w 4 + F i i i i i { u 8 - , @ @ 2 2 2 C C , t t t Y $ Y q $ Y $ Y Y t Y t Y , t , t - - C } }", +" } } } } } } } - } } ^ } ^ B - ^ - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ p ^ ^ ^ p ^ p p 1 p p 1 p 1 1 1 ~ 1 1 ~ 1 1 ~ 1 ~ 1 ~ 8 p 8 8 R w R J H I I T g g g c ) k < = = s m m ] 5 G 3 ( E U O 2 2 } - ^ ^ : p 1 1 1 1 1 1 1 1 1 p p ^ p ^ - - - - C C 2 t 9 9 | O | O W U W . W W . . . W . . . W $ W W $ W | $ | | t | t | $ C $ t t t t t t t t t t $ t t Y t Y $ Y t $ Y $ $ Y Y Y Y Y Y Y R Y Y R R R J J J w w w w M F i i i i i { M u 8 Y C S 2 2 2 2 C C C t t t t Y $ t Y Y Y t Y t t t , , C , } C } } } }", +" } } } } } } } - } ^ - ^ - ^ - ^ ^ ^ - ^ - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ p ^ p ^ 1 ^ p p 1 p 1 p p 1 1 1 1 1 p 1 8 1 p 8 8 p. . 8 8 R J J H I T T T g g c k b < = s v m ] V 5 5 3 3 ( l 9 S 2 C } } ^ ^ ^ : p 1 1 1 1 1 1 p ^ p ^ ^ - - - } C 2 C 9 9 9 | O | U W W . . . . r . o . r o . o . . W $ . W $ W | $ | | t | t | t | t t t t t t t t t t t t t $ Y t Y t Y t Y t Y Y Y Y R Y Y R J R R J R J w w w w F M + { i i i { { +. R , t S S 2 @ 2 C C C C t t t $ Y t t t t t t t , , C C - C } C } C } 2", +" 2 2 } 2 } - } - - - - ^ - p ^ ^ , ^ ^ ^ ^ - ^ ^ - B ^ B ^ B ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ p ^ p ^ 1 ^ p p p 1 p p 1 8 p ~ p 8 p R 8 J R R H H I q T L g c c k k = s s / m ] V 5 G D ( U U l 9 2 2 } } - ^ p ^ : p : p : p : p ^ ^ ^ ^ - } C C 2 9 9 | O O U . j . . . 3 . r . r j o . r . r . o . . . $ W W W W | | W | | | | C | t | t | t t $ t t t t t t t t t t t Y t Y t Y Y Y Y R R Y R R J R R w w w w w w F u i i i i i { + u. Y t 9 9 S S 2 2 2 C C t t t t t t t t t t t C t C C C C } 2 } 2 A 2 }" +}; diff --git a/hacks/images/sball.xpm b/hacks/images/sball.xpm new file mode 100644 index 00000000..dc7a88e7 --- /dev/null +++ b/hacks/images/sball.xpm @@ -0,0 +1,131 @@ +/* XPM */ +static char * sball[] = { +"64 64 64 1", +". c #3A127E", +"+ c #326DB3", +"@ c #12E6FA", +"# c #1CB9E2", +"$ c #3655A6", +"% c #34499D", +"& c #1EB0DD", +"* c #4AE6F6", +"= c #38368F", +"- c #2298CF", +"; c #32E2F2", +"> c #3A2C8C", +", c #12D6EE", +"' c #22A6D6", +") c #2A76B6", +"! c #2AEAFA", +"~ c #16CEEA", +"{ c #228BC6", +"] c #0EF2FE", +"^ c #47BEE8", +"/ c #3A2286", +"( c #2EAEDA", +"_ c #4A76C6", +": c #1EEAFE", +"< c #3B95D5", +"[ c #16DAF2", +"} c #1EFEFE", +"| c #36F8FE", +"1 c #3EBBE5", +"2 c #32A2D2", +"3 c #3A1E82", +"4 c #2EEEFA", +"5 c #36D6FE", +"6 c #2A7EBE", +"7 c #3BA8DE", +"8 c #2F60AA", +"9 c #23C2EB", +"0 c #268AC6", +"a c #419EDD", +"b c #0AFAFE", +"c c #387EC1", +"d c #56B2F2", +"e c #3A1A82", +"f c #16FEFE", +"g c #50FEFE", +"h c #32BAE6", +"i c #2ECCF3", +"j c #3E127E", +"k c #43D5F8", +"l c #4896D6", +"m c #2BFDFE", +"n c #436AB9", +"o c #4AA4E4", +"p c #4060B0", +"q c #22BEE6", +"r c #4656AE", +"s c #46F4FE", +"t c #318CCC", +"u c #2883C0", +"v c #38167E", +"w c #393E97", +"x c #404AA0", +"y c #50ABEC", +"z c #4381C6", +"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj", +"..........................v/>>>/.....v.........................v", +"jjjjjjjjjjjjjjjjjjjjjjj>8u--{)%=.j..e>w%w>3.jjjjjjjjjjjjjjjjj.jj", +"..................../%-&###-{)%=...v/=%$)6)%>e...............j..", +"jvvvvvvvvvvvvvvvvv/6'#&####'{)$=.j..vew%66{6{+>3vvvvvvvvvvvvv.jj", +".jjjjjjjjjjjjjj.>8-#&######&-6%=.v....v/%+)u)uu83jjjjjjjjjjjj.v.", +"..jjj..jjj..jj.=#######&##&&-{8=...v/>>/./=uu{u6u%>...j..jj.j.jj", +"j....jj...j..v)&&&##########-{$w...e>w$8%/v=$)uuuu+3...jj..j.j..", +"jjjj..jjj...>)##########&##-)%vv...3>%8)6)$.3=)666u)%3...j.j.jjv", +"v...jj.....%-######&##&#-8=v3/%=..ve=%8)u6u$=e=8{u6{)8vj..j.j..j", +".jj..jjj..=&###&######&)vv%,@~{8.../=%+666uu68v/))uuuu%3j.j.jj.j", +"...j.....w{&#########-//)~]]],{8..v/w%)6u{u)66=3%)6u666$.j.j..j.", +"jj..jj..=-##&####&#'8>8#bbbbb@{+..v/%%6)6){{6u)%v=8{6u)u>v.jj.jj", +"..jj.../&&########'/38]bbbbb]@-8vv.=%8){u{)u6u{)>e=)u){6)=...j..", +"j..j...$###&#&##&'8%#]bbb]bbb]'+..v>%8666{6{)6uu+=386u666+w..jjj", +".jj...%-########-==,]]b]]bb]]]-).vv=$8uuu6uu{u{6{8==8)uuu68vj...", +"..j..v'&#######'>={]bbbbbbbbb]&).vv=8){{{{{{u6uu{)8v%+u6u)6/v.jj", +"j...v%&#######&)/'@bbbbbbbbbbb#6.v3%860{u0u{{{{{u{)//$){uu{$>...", +"..../+&#######uw-@bbfbffbbfbbb#{..v%)){tt8u66uu{$v.", +"..v$'####9#~#+89fff}}fffbbbbb]]'.v/+)uuutu<<<<<<<-t{)w%)u6u)u8ej", +"..v{&#####99-$#]bf}fffffbbbbbbb&vv/66uuuttt<<<<<", +"..8&####9i9'w+b}}}}}}fbfbb]bb]],..vvv3.v$c0<8tooooaa.&]@]@@::@i/=naoo7oo2z/x<<0uuuu$", +"v%{#&##99ii=%2mmmmm}}}f93=-]bbb~v&@@@@@]:]!z=xlodooooc3x8}fb]]bbbv&@@@@::!!4;i)xlyyyoar>c<6##99iiik58%;mmmm|4<%h}}}fbfbb.#@::::!!444t=j/_lolw/z<<<wo2<raa<-t0u)6=", +".v$&#q99ii55k2=7;hev/3c;|mmmm(.ph4|4|!c>>ks*lwe=/xzya&##q9iiii;k<===/e/wcz.3ni4mm2j$(m4;arjp1g4gdrjj3looo<ejv/=///r^**ssg1xj/pyyoa<_ddyoaae.jj", +"......$-qq99iiik5k;k^_/cgggggggggggggggss^n>_ldyyoa<<-tu6u8e....", +".......8&##99iki5kkk*kp/r1*gggggggggggg*r//dddyyaoaattt0u+=..vvj", +"j...v../'##9i9ii;i;ki*k^=j=d*gggggggs*n=/_yddyoooa<rzoddyyyoalaaxpzzaa<<.....j..jj.jj", +".j....j.jj.j..jj=8-qqq99iiih12c833e3/xpnt)'99999i9h(cpeee3/=r8cu0uu)=/.......j..jj.jjj", +"j....j.j..j..jjjjjjv>%-&q99q#(0n//ej3>w$)66w=e...j...jj.jj..j...", +"jjjj.j.jj.jj...j..j...e>8u-#&#t+//3v3/==w>/.......v...j..jj.jjjj", +"....j.j..j..jj...j.j....vje/=w%w>/ej.v.v.v...j.....jjj.jj..j...."}; diff --git a/hacks/images/tree.xpm b/hacks/images/tree.xpm new file mode 100644 index 00000000..7fb01c7c --- /dev/null +++ b/hacks/images/tree.xpm @@ -0,0 +1,226 @@ +/* XPM */ +static char *tree[] = { +/* width height ncolors chars_per_pixel */ +"128 128 91 1", +/* colors */ +" c None", +". c #4E561E", +"X c #AE9D44", +"o c #E2DFC3", +"O c #D8D3A2", +"+ c #CCC489", +"@ c #7F8965", +"# c #CCB65E", +"$ c #2A4622", +"% c #AFB59E", +"& c #847B2B", +"* c #988B59", +"= c #22361D", +"- c #989548", +"; c #5E7130", +": c #060412", +"> c #928D42", +", c #A29D55", +"< c #F2F2E9", +"1 c #AAA26A", +"2 c #958627", +"3 c #B7A64F", +"4 c #313C1E", +"5 c #7B8260", +"6 c #E1E2D8", +"7 c #989858", +"8 c #A69948", +"9 c #677635", +"0 c #787328", +"q c #D8D8CF", +"w c #A9A458", +"e c #67684C", +"r c #49662B", +"t c #B8B577", +"y c #E6E8E3", +"u c #697651", +"i c #D0CE9F", +"p c #D3BF6D", +"a c #C8B976", +"s c #121416", +"d c #888837", +"f c #BDB061", +"g c #464921", +"h c #ECEBE5", +"j c #9E9974", +"k c #4B5929", +"l c #BBC28D", +"z c #85884E", +"x c #CFCDC5", +"c c #0C1216", +"v c #4E4E39", +"b c #83832E", +"n c #9C922C", +"m c #585832", +"M c #A9AD88", +"N c #C4BA9F", +"B c #C4C395", +"V c #ACB37A", +"C c #B8B893", +"Z c #C3A955", +"A c #666A35", +"S c #7A8438", +"D c #8A9476", +"F c #161A18", +"G c #586827", +"H c #90955E", +"J c #9A9E75", +"K c #C9C8AD", +"L c #3C3F29", +"P c #B9C0B4", +"I c #767947", +"U c #61692F", +"Y c #7A7041", +"T c #2F2C29", +"R c #98A386", +"E c #DDD6A2", +"W c #B4AA87", +"Q c #0A0C15", +"! c #A59639", +"~ c #8B9247", +"^ c #A7A67D", +"/ c #3B482A", +"( c #1A261A", +") c #989339", +"_ c #B6A867", +"` c #60614E", +"' c #26291F", +"] c #767A35", +"[ c #3A5525", +"{ c #7B795B", +"} c #6C762B", +/* pixels */ +" h qMt-1X,zIIDRVIHH@J#ftV1fta+iifC < K6~z9>zCHH9H59U5rzw,)]--7%f]oJ,f{zYHfttp+Coh< ", +" +_,7VK%1Ct31-w1^wf,,X-9SSwH=I%Juz-w#3Y,w99-!16^jC<]qD*7f+a+++Chxy ", +" 61SH`R<@H1^wZ_838,H311w]Swv=PH5M~_w->]N&U^A>,3p7718-wwwJf1VV+1K%q ", +" tWZ8#zuz1t>]w7-I97w#f,JJwIwSKIt,S~SUI7d73w#~~S;S-ww,H~7+JVaVx6xh ", +" hK^+_HK_tV,X8_1YH]~-3-J,X~zI3DzI;9A;Ad>-X3d-fd;S~Iz>Ia1H@^CV6 %x ", +" 6 PR3f#pa##pfzwf8-~-]~~~,Hz-SH;5rrU9A99>dz]>8H7fwfpf-#+CMllMq R ", +" qxK8p#appwX*-X-W1IIr%Iz-Hdw~zIz5KAA K^x)~--]wdd>3-X,X,w7Rq< D% ", +" 6d]r/Hj*S9->}IrIo q%N,>SS;)X~~Xw]]-~9~>wz`P%Pu% ", +" hPffat81>,*I~DzIIYv@H8-->-Sd9$$]]M*wS;dIrbI}dSd]d)~KD>~HHD%{vv ", +" Pe%NH>IKx8]U9u6]II9]d>3X>SA;;/k[`r9;;;9d;]99[r0^j DS99MR`Dv{ ", +" +oNCD@uRKP1*K^599zdd&dI9U>-/>9`]k[[/rIIb;AGrdUASrAq^eK M-]IGI%RD= PD ", +" qN+f3fI*Cq@xP%6P%<5Av{7&CqI4II'I]SS;;rU@`;8eW,*UI1-)1oYN <6%AdA]IH%`DxDP ", +" C3ppppHjJYRJ%PPP`%%L4sFT%RI]rA5=);r;[;S-3]>)73WN1_bzz^ q 6&RI-t787+++a_%x ", +" Kt< %zp^33##1##f3XX1a5tvgFF`vL5,A};/38ddk`d)-!*g*m*>w]S8-1q9*o6Dj*1WKot*fa_#fx ", +" MCq << DCt##pp3w>)83zP1m{TF_t{*>Yk/$S9d]9[`r[dYm]f3#p#bS)]S9kzNh6R1fj>,qDh@Ivy ", +" DMK PKajZ,aZp3#)fZp3#p&]8]A1)w-1RLDm]]r;;r99XSr;df#f8))-&}5I^Ho hzHHdIz6y P@D ", +" RKP,o< %eWx^8,f##fX)X#pX-fz--]3-}{Grg9veg$[r`rr9[r]!nb}r9)SdH@9S9r% yKqID ", +" 6 5KHMiCN+N%1pf_tZ#_3_3ZX-3#wddzd])w~5;79k99VA]rr;;d/k;;}};rbdG%5u[J~0Aq P 6 ", +" %hHH76C,~a)9w>~*__f*f-Z3!#3,~)HMMI8]zqyKY[vDr9->b]rg;G9]r[r}}-]IK %%2)S* h%q ", +" xP@rrN%yU[rrr;;9-Xh6]Z8>33,8-8)w#!-XtN1D(/Tgze/$k==[9>S>SI;[;r[[^MUIxH- h ^H*xh ", +" K% yR %;[9]rrIdI* 6^17H tMd9S,a>3&~ISUYv'FgA~`$`($k/;S99}5UPR%@[IK6%M1qKoHIq ", +" D% D@HoRzI76x h x8XS-,wS})8)]S)m.=eU`Ue4=/k;%``;I yy DRHr0GtJxq%w__aE% yfZ8)->))dz,`;999Gd0*A4/b8Ikuq Dx PPPHm]}Jk]Kx ", +" hI%vNW]~-Sm>U;]~I}U}L=}.0b//% `Igr/k%% ", +" 5;*xPKP)!U)X83ZX)XzxHd8I!)}]g;9>Xm$U&{`b'./U[R% 6%U;7 ", +" hRiahq,J&gz03XdI&)3w0}!]3)}ddz)wU(.z4v3kXI*H6 qB8d)3)*m-)d8bbb)b4/csFXm>m&>zH q x ", +" q!K CPi+_3ap*YjwI0)dmGI>]mH;}bGYm(=(..1bA]~m%<@y < ", +" KPK%z_p#p+3XtDH}!&z7z9]ddw.'zz4G{cFvv(U;.gbU`$k]b0)i ", +" D)~d*>!S3-Kxo%t1mvY'>mUm'ee'cQcsvscvvg4=4GHy`G]gn;Ki h ", +" M%Kb@H%`TmZj)f__*`Fs'F*g0'4;AsTcFcQFs4Gmk]q%e C]}0;S;r;JMAz^qI%< ", +" yP$F`Dh WC%W3Z#3AY'ssYL'vTL`s'5scFcc4G[;M`u19;kr[;`}SG;b99d~zK9]x ", +" iKH)4=)X8Y{gY3)-;*YdmsL.{A'T8!I4s'$U(%KH@gvjK%5K%k`vr}S}d!d-+-;;zh ", +" qd88Ifu4!>gs`vI!90db8b4^Fumm]Z3#3'!((]VYg[G)ah<>J9.y`D%z7z-&*zHq@P9h ", +" qIbS-3w3&TL>YZ*`emI)!!!b-#ZnZm{0Xg!sgs'U8UU]9XZ*sLccF'{8CH8#Z)_)!8!0Hz9NmmN)0>mw%h J9>Kh ", +" qhK Pu9]9AIK{[[zZp]zS8>>##3-33bUU-d)0{;!*m'LTj3b)bn!20{)f87>]IXw_@MI7kH1zd@K}k{IKh ", +" ^~~9r[/kjYUkre//r]ddz))83XZXZ-d9->SS]V-}8Z0m{sm>>&&I0wz&dYmge>_d,de45m`'eM1j94r%h ", +" ~I;rr;9z[/k]k[md73,d}}IX)&n3nd!SU)]b8-rb!>S{45L0vgXn!!aw0X0!e.0w>;rGUR'/GIm]ArSM ", +" qKh '$$=Jvvm(L4=g'4Y@>)9]])3#Z)z,9;;U;]m]}k$9G;m=4=~`QggInZZ2)!Z!gA]&00=GkG[4I7bIU/r9D ", +" _pa30(FcvFcYv]ZbG==IHt,KMU7~83X!b8;Idmkm4//$$[[9;4F0)mTQQ.0)2!!X_Xn0&db)&0;[k;]h {9PPP ", +" LmZ>>'>8emvww!04AI1>IUMdbt]d>S]!)Y3X_'FT*0mg('[GkGvXX#)Z04F'2)Y..bzH0m.'F=G$(=/H y ", +" x/&II3TT>*pZ8b0r0b>0d!&Y)d]d]MI)003!)p#&g/v'{Qc(===.=mu&2'(F.mv,0)>IGYe)UzGgQFkz]} ", +" Kw#3&3Z#pw]#))gkGU&G&&&!8!nd7z7^GUvFvgY^#Deg'=4(gcsFc(4Fs:Qcs((mv'mb.d;b}YSG/cckS>C ", +" R/o^t&#Z!Ge33SGrk[kG.{'4Um4s`K^yDDvFs5TF4QT((=GkF('`v$k.4:::v((4/sF/r[;Ib)X}bS09;dd)q ", +" DF`5Y!!2mmb&rrkk0_44F4=:Lv ` %x yuFsGmd/0gQFc(=./QQQF[mg.4vYQQT`@9AU.$}r;r};]kG[9IrSSM ", +" `ccs'mFmbSUk}0&}I``vQ:vqx `%@ xsQ:4=kgL:QQQ4('s(cg202G.dbG4v%5KhyRRUHU$$kUkePP=/kk[[@ ", +" DFsQe`w3Ukm[v'gvWhKoxL<g20G.UUM {Hq PohK%(4]>4PP yGb9=F` ", +" hPPvg,>YA'4/>(FPhxKK-Nhh vD:v `vsTT::::::Tss`c(FF'emv]Lcgg(q 6 yH1%RCh5y Rr%x^H ", +" i,wd_ZsQQ'QcQTRoP h<<< 6vQ:Tvxqs`4mFvQQT:::QF4(vLTvPRL'4'sL4^ Kxy yh ", +" Rx1Xt*DvDILvY`KNP 6RF:QTsvTQF:'LQ:T:::QccmmmD%j{v'DK`44.zaK ", +" hP6N%Z#papafa_tNh %xqvT@`::TQ:Qssgk(`JyQ:QQQQc4T%RYm< oAm0G0G ", +" q 6jXN_a1>*WP yxsPRv::v:::L0m40v4`B5QQccQTR`sQvu@.HM=Pq4G0K ", +" 6PPqx^K< %%`vR@T:::::Q'Fv9(/L0gv:QQQ::::::R yqP% ", +" 6hh6 hR4{#XZ{`gdU&zww]I{{.'T:QcQQ:Q:Q'>% q4 K u/^y ", +" PQUn))ppZ333w>>J-b`]mA-mcQQ:`vT.*N oiR5Uh9zM ", +" K1Z#&&)`2XZ3Gbbz;bb}zI0k;&UF(Qssv:% y RzMB0UUgIC ", +" Xp#XX)GtvYGGk/[}db0;GG]0G.'4[k$'Q:T a0G.G&=/4Gb3>Cq ", +" 6t8f5A>TQ'm.kU4.))0;SrG([r[]'T($vLT` %;0;;U>D`{9}}}bKh +< ", +" qqxyD`$I~-;[/kG}bbrk.gG;rG[k[=4csT` h @vvu`$;>dm`(v=G2tz!@y ", +" `[$kG[G$$gkGG;r[0Sk[$/v[IkA=4RD _e` ", +" 6C*oPqP0Tvm44}v/(4'G./G;GGGr$F=k(QFm4dYmUgF% x% @5U/9rb/P ", +" yz7,Kh0mFTQTmU7c::sgg-mD44.9G(===(FH>vmm@)~X~H %kD};rS1K ", +" >*+)dmY!ZZ3)0bgF=.=bd{qqx D=}g/==480^AsD DKuy x hx[H ", +" CK]tv8t3###))G==F4G0b7>MRIUgKRzmcc'9U8fLN yx ", +" tBCi^#I]!)X!$.Um3-'4gMhC-MK%GKgQc(g$/>Zt,+ ", +" hCI h5^{&,0z&m}372g]30!h `x'Qcs94s/H/,-% ", +" +Wy ", +" PHH)K qxD9bbXX>%0YXG>b) #include +#include #include /* for gettimeofday() */ #include diff --git a/hacks/interference.c b/hacks/interference.c index 7f66b01b..fefaf9d9 100644 --- a/hacks/interference.c +++ b/hacks/interference.c @@ -69,6 +69,8 @@ char *progclass="Interference"; char *defaults [] = { + ".background: black", + ".foreground: white", "*count: 3", /* number of waves */ "*gridsize: 4", /* pixel size, smaller values for better resolution */ "*ncolors: 128", /* number of colours used */ diff --git a/hacks/juggle.c b/hacks/juggle.c new file mode 100644 index 00000000..758d2576 --- /dev/null +++ b/hacks/juggle.c @@ -0,0 +1,1549 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* juggle */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)juggle.c 5.00 2000/11/01 xlockmore"; + +#endif + +/*- + * Copyright (c) 1996 by Tim Auckland + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History + * 01-Nov-2000: Allocation checks + * 1996: Written + */ + +/*- + * TODO + * Fix timing to run at approx same speed on all machines. + * Store shorter pattern and refill when required. + * Use -cycles and -count in a rational manner. + * Merge pattern selector with pattern generator. + * Add clubs + * Clap when all the balls are in the air + */ + + +/*- +Notes on Adam Chalcraft Juggling Notation (used by permission) +a-> Adam's notation s-> Site swap (Cambridge) notation + +To define a map from a-notation to s-notation +("site-swap"), both of which look like doubly infinite sequences of natural +numbers. In s-notation, there is a restriction on what is allowed, namely +for the sequence s_n, the associated function f(n)=n+s_n must be a +bijection. In a-notation, there is no restriction. + +To go from a-notation to s-notation, you start by mapping each a_n to a +permutation of N, the natural numbers. + +0 -> the identity +1 -> (10) [i.e. f(1)=0, f(0)=1] +2 -> (210) [i.e. f(2)=1, f(1)=0, f(0)=2] +3 -> (3210) [i.e. f(3)=2, f(2)=1, f(1)=0, f(0)=3] +etc. + +Then for each n, you look at how long 0 takes to get back to 0 again and +you call this t_n. If a_n=0, for example, then since the identity leaves 0 +alone, it gets back to 0 in 1 step, so t_n=1. If a_n=1, then f(0)=1. Now any +further a_n=0 leave 1 alone, but the next a_n>0 sends 1 back to 0. Hence t_n +is 2 + the number of 0's following the 1. Finally, set s_n = t_n - 1. + +To give some examples, it helps to have a notation for cyclic sequences. By +(123), for example, I mean ...123123123123... . Now under the a-notation -> +s-notation mapping we have some familiar examples: + +(0)->(0), (1)->(1), (2)->(2) etc. +(21)->(31), (31)->(51), (41)->(71) etc. +(10)->(20), (20)->(40), (30)->(60) etc. +(331)->(441), (312)->(612), (303)->(504), (321)->(531) +(43)->(53), (434)->(534), (433)->(633) +(552)->(672) + +In general, the number of balls is the *average* of the s-notation, and the +*maximum* of the a-notation. Another theorem is that the minimum values in +the a-notation and the s-notation and equal, and preserved in the same +positions. + +The usefulness of a-notation is the fact that there are no restrictions on +what is allowed. This makes random juggle generation much easier. It also +makes enumeration very easy. Another handy feature is computing changes. +Suppose you can do (5) and want a neat change up to (771) in s-notation +[Mike Day actually needed this example!]. Write them both in a-notation, +which gives (5) and (551). Now concatenate them (in general, there may be +more than one way to do this, but not in this example), to get +...55555555551551551551551... +Now convert back to s-notation, to get +...55555566771771771771771... +So the answer is to do two 6 throws and then go straight into (771). +Coming back down of course, +...5515515515515515555555555... +converts to +...7717717717716615555555555... +so the answer is to do a single 661 and then drop straight down to (5). + +[The number of balls in the generated pattern occasionally changes. In + order to decrease the number of balls I had to introduce a new symbol + into the Adam notation, [*] which means 'lose the current ball'.] +*/ + +#define STANDALONE +#ifdef STANDALONE +#define MODE_juggle +#define PROGCLASS "Juggle" +#define HACK_INIT init_juggle +#define HACK_DRAW draw_juggle +#define juggle_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ +"*count: 150 \n" \ +"*cycles: 30 \n" \ +"*ncolors: 32 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_juggle + +#define DEF_PATTERN "." /* All patterns */ +#define DEF_TRAIL "0" /* No trace */ +#ifdef UNI +#define DEF_UNI "FALSE" /* No unicycle */ /* Not implemented yet */ +#endif +#define DEF_SOLID "FALSE" /* Not solid */ + +static char *pattern; +static int trail; +#ifdef UNI +static Bool uni; +#endif +static Bool solid; + +static XrmOptionDescRec opts[] = +{ + {(char* ) "-pattern", (char *) ".juggle.pattern", + XrmoptionSepArg, (caddr_t) NULL}, + {(char* ) "-trail", (char *) ".juggle.trail", + XrmoptionSepArg, (caddr_t) NULL}, +#ifdef UNI + {(char *) "-uni", (char *) ".juggle.uni", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+uni", (char *) ".juggle.uni", XrmoptionNoArg, (caddr_t) "off"}, +#endif + {(char *) "-solid", (char *) ".juggle.solid", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+solid", (char *) ".juggle.solid", XrmoptionNoArg, (caddr_t) "off"} +}; +static argtype vars[] = +{ + {(caddr_t *) &pattern, (char *) "pattern", + (char *) "Pattern", (char *) DEF_PATTERN, t_String}, + {(caddr_t *) &trail, (char *) "trail", + (char *) "Trail", (char *) DEF_TRAIL, t_Int}, +#ifdef UNI + {(caddr_t *) &uni, (char *) "uni", + (char *) "Uni", (char *) DEF_UNI, t_Bool}, +#endif + {(caddr_t *) &solid, (char *) "solid", + (char *) "Solid", (char *) DEF_SOLID, t_Bool} +}; +static OptionStruct desc[] = +{ + {(char *) "-pattern string", (char *) "Cambridge Juggling Pattern"}, + {(char *) "-trail num", (char *) "Trace Juggling Patterns"}, +#ifdef UNI + {(char *) "-/+uni", (char *) "Unicycle"}, +#endif + {(char *) "-/+solid", (char *) "solid color (else its a 4 panel look (half white))"} +}; + +ModeSpecOpt juggle_opts = +{sizeof opts / sizeof opts[0], opts, + sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct juggle_description = { + "juggle", "init_juggle", "draw_juggle", "release_juggle", + "draw_juggle", "init_juggle", (char *) NULL, &juggle_opts, + 10000, 150, 30, 1, 64, 1.0, "", + "Shows a Juggler, juggling", 0, NULL +}; + +#endif + +#ifdef USE_XVMSUTILS +#include +#endif +#include +#if HAVE_SYS_TIME_H +#include +#else +#if HAVE_SYS_SELECT_H +#include +#endif +#endif + +/* Figure */ +#define ARMLENGTH ((int) (40.0 * sp->scale)) +#define ARMWIDTH ((int) (8.0 * sqrt(sp->scale))) +#define POSE ((int) (10.0 * sp->scale)) +#define SX ((int) (25.0 * sp->scale)) +#define SZ ((int) (25.0 * sp->scale)) +#define SY ((int) (25.0 * sp->scale)) +#define HIPY ((int) (85.0 * sp->scale)) +#define RHIPX ((int) (-15.0 * sp->scale)) +#define LHIPX ((int) (15.0 * sp->scale)) +#define RFX ((int) (-25.0 * sp->scale)) +#define LFX ((int) (25.0 * sp->scale)) +#define FY ((int) (155.0 * sp->scale)) +#define WSTY ((int) (65.0 * sp->scale)) +#define NEY ((int) (15.0 * sp->scale)) +#define HED ((int) (35.0 * sp->scale)) +#define BALLRADIUS ARMWIDTH +#define FIGURE1 7 +#define FIGURE2 3 +#define TRACE_LENGTH 50 +#define SPIN_DEGREES 750 /* Average spinning between a throw and the next catch */ + +/* macros */ + +#ifndef XtNumber +#define XtNumber(arr) ((unsigned int) (sizeof(arr) / sizeof(arr[0]))) +#endif + +#define GRAVITY(h, t) 4*(double)(h)/((t)*(t)) + +#define THROW_CATCH_INTERVAL (sp->count) +#define THROW_NULL_INTERVAL (sp->count * 0.5) +#define CATCH_THROW_INTERVAL (sp->count * 0.2) +#define COR 0.8 /* coeff of restitution of balls (1 = perfect bounce) */ + + +/* typedefs */ + +typedef enum {HEIGHT, ADAM} Notation; +typedef enum {Empty, Full, Ball} Throwable; +typedef enum {LEFT, RIGHT} Hand; +typedef enum {THROW, CATCH} Action; /* DROP is not an option */ +typedef enum {ATCH, THRATCH, ACTION, LINKEDACTION, PTHRATCH, BPREDICTOR, + PREDICTOR} TrajectoryStatus; + +typedef struct trajectory *TrajectoryPtr; + +typedef struct {double a, b, c, d; } Spline; + +typedef struct trajectory { + TrajectoryPtr prev, next; /* for building list */ + TrajectoryStatus status; + + /* Throw */ + char posn; + int height; + int adam; + + /* Action */ + Hand hand; + Action action; + + /* LinkedAction */ + int color; + int spin, divisions; + double degree_offset; + TrajectoryPtr balllink; + TrajectoryPtr handlink; + + /* PThratch */ + + double dx; /* initial velocity */ + double dy; + + /* Predictor */ + Throwable type; + int start, finish; + Spline xp, yp; + int x, y; /* current position */ +} Trajectory; + +/* structs */ + +typedef struct { + int width; + int height; + double scale; + int complexity; + int cx; + int cy; + double Gr; + int pattern; + Trajectory *head; + XPoint figure_path[FIGURE1]; + XSegment figure_segs[FIGURE2]; + XPoint arm[2][3]; + XPoint *trace; + int traceindex; + int count; + time_t begintime; /* seconds */ + int time; /* millisecond timer */ + Bool solid, uni; +} jugglestruct; + +static jugglestruct *juggles = (jugglestruct *) NULL; + +typedef struct { + char * pattern; + char * name; +} patternstruct; + +#define MINBALLS 2 +#define MAXBALLS 7 + +typedef struct { + int start; + int number; +} PatternIndex; + +static PatternIndex* patternindex = (PatternIndex *) NULL; + +/* List of popular patterns, in any order */ +static patternstruct portfolio[] = { + {(char *) "[+2 1]", (char *) "+3 1, Typical 2 ball juggler"}, + {(char *) "[2 0]", (char *) "4 0, 2 balls 1 hand"}, + {(char *) "[2 0 1]", (char *) "5 0 1"}, + {(char *) "[+2 0 +2 0 0]", (char *) "+5 0 +5 0 0"}, + {(char *) "[3]", (char *) "3, cascade"}, + {(char *) "[+3]", (char *) "+3, reverse cascade"}, + {(char *) "[=3]", (char *) "=3, cascade under arm"}, + {(char *) "[&3]", (char *) "&3, cascade catching under arm"}, + {(char *) "[_3]", (char *) "_3, bouncing cascade"}, + {(char *) "[+3 x3 =3]", (char *) "+3 x3 =3, Mill's mess"}, + {(char *) "[3 2 1]", (char *) "5 3 1"}, + {(char *) "[3 3 1]", (char *) "4 4 1"}, + {(char *) "[3 1 2]", (char *) "6 1 2, See-saw"}, + {(char *) "[=3 3 1 2]", (char *) "=4 5 1 2"}, + {(char *) "[=3 2 2 3 1 2]", (char *) "=6 2 2 5 1 2, =4 5 1 2 stretched"}, + {(char *) "[+3 3 1 3]", (char *) "+4 4 1 3, anemic shower box"}, + {(char *) "[3 3 1]", (char *) "4 4 1"}, + {(char *) "[+3 2 3]", (char *) "+4 2 3"}, + {(char *) "[+3 1]", (char *) "+5 1, 3 shower"}, + {(char *) "[_3 1]", (char *) "_5 1, bouncing 3 shower"}, + {(char *) "[3 0 3 0 3]", (char *) "5 0 5 0 5, shake 3 out of 5"}, + {(char *) "[3 3 3 0 0]", (char *) "5 5 5 0 0, flash 3 out of 5"}, + {(char *) "[3 3 0]", (char *) "4 5 0, complete waste of a 5 ball juggler"}, + {(char *) "[3 3 3 0 0 0 0]", (char *) "7 7 7 0 0 0 0, 3 flash"}, + {(char *) "[+3 0 +3 0 +3 0 0]", (char *) "+7 0 +7 0 +7 0 0"}, + {(char *) "[4]", (char *) "4, 4 cascade"}, + {(char *) "[+4 3]", (char *) "+5 3, 4 ball half shower"}, + {(char *) "[4 4 2]", (char *) "5 5 2"}, + {(char *) "[+4 4 4 +4]", (char *) "+4 4 4 +4, 4 columns"}, + {(char *) "[4 3 +4]", (char *) "5 3 +4"}, + {(char *) "[+4 1]", (char *) "+7 1, 4 shower"}, + {(char *) "[4 4 4 4 0]", (char *) "5 5 5 5 0, learning 5"}, + {(char *) "[5]", (char *) "5, 5 cascade"}, + {(char *) "[_5 _5 _5 _5 _5 5 5 5 5 5]", (char *) "_5 _5 _5 _5 _5 5 5 5 5 5, jump rope"}, + {(char *) "[+5 x5 =5]", (char *) "+5 x5 =5, Mill's mess for 5"}, + {(char *) "[6]", (char *) "6, 6 cascade"}, + {(char *) "[7]", (char *) "7, 7 cascade"}, + {(char *) "[_7]", (char *) "_7, bouncing 7 cascade"}, +}; + +/* Private Functions */ + +/* list management */ + +/* t receives trajectory to be created. ot must point to an existing + trajectory or be identical to t to start a new list. */ +#define INSERT_AFTER_TOP(t, ot) \ + if ((t = (Trajectory *)calloc(1, sizeof(Trajectory))) == NULL) \ + {free_juggle(sp); return;} \ + (t)->next = (ot)->next; \ + (t)->prev = (ot); \ + (ot)->next = (t); \ + (t)->next->prev = (t) +#define INSERT_AFTER(t, ot) \ + if ((t = (Trajectory *)calloc(1, sizeof(Trajectory))) == NULL) \ + {free_juggle(sp); return False;} \ + (t)->next = (ot)->next; \ + (t)->prev = (ot); \ + (ot)->next = (t); \ + (t)->next->prev = (t) + + +/* t must point to an existing trajectory. t must not be an + expression ending ->next or ->prev */ +#define REMOVE(t) \ + (t)->next->prev = (t)->prev; \ + (t)->prev->next = (t)->next; \ + (void) free((void *) t) + +static void +free_pattern(jugglestruct *sp) { + if (sp->head != NULL) { + while (sp->head->next != sp->head) { + Trajectory *t = sp->head->next; + + REMOVE(t); /* don't eliminate t */ + } + (void) free((void *) sp->head); + sp->head = (Trajectory *) NULL; + } +} + +static void +free_juggle(jugglestruct *sp) +{ + if (sp->trace != NULL) { + (void) free((void *) sp->trace); + sp->trace = (XPoint *) NULL; + } + free_pattern(sp); +} + +static Bool +add_throw(jugglestruct *sp, char type, int h, Notation n) +{ + Trajectory *t; + + INSERT_AFTER(t, sp->head->prev); + t->posn = type; + if (n == ADAM) { + t->adam = h; + t->status = ATCH; + } else { + t->height = h; + t->status = THRATCH; + } + return True; +} + +/* add a Thratch to the performance */ +static Bool +program(ModeInfo *mi, const char *patn, int repeat) +{ + jugglestruct *sp = &juggles[MI_SCREEN(mi)]; + const char *p; + int h, i, seen; + Notation notation; + char type; + + if (MI_IS_VERBOSE(mi)) { + (void) fprintf(stderr, "%s x %d\n", patn, repeat); + } + + for(i=0; i < repeat; i++) { + type=' '; + h = 0; + seen = 0; + notation = HEIGHT; + for(p=patn; *p; p++) { + if (*p >= '0' && *p <='9') { + seen = 1; + h = 10*h + (*p - '0'); + } else { + Notation nn = notation; + switch (*p) { + case '[': /* begin Adam notation */ + notation = ADAM; + break; + case '-': /* Inside throw */ + case '+': /* Outside throw */ + case '=': /* Cross throw */ + case '&': /* Cross catch */ + case 'x': /* Cross throw and catch */ + case '_': /* Bounce */ + type = *p; + break; + case '*': /* Lose ball */ + seen = 1; + h = -1; + /* fall through */ + case ']': /* end Adam notation */ + nn = HEIGHT; + /* fall through */ + case ' ': + if (seen) { + if (!add_throw(sp, type, h, notation)) + return False; + type=' '; + h = 0; + seen = 0; + } + notation = nn; + break; + default: + (void) fprintf(stderr, "Unexpected pattern instruction: '%s'\n", p); + break; + } + } + } + if (seen) { + if (!add_throw(sp, type, h, notation)) + return False; + } + } + return True; +} + +/* + ~~~~\~~~~~\~~~ + \\~\\~\~\\\~~~ + \\~\\\\~\\\~\~ + \\\\\\\\\\\~\\ + +[33134231334021] + +4 4 1 3 12 2 4 1 4 4 13 0 3 1 + +*/ +#define BOUNCEOVER 10 + +static void +adam(jugglestruct *sp) +{ + Trajectory *t, *p; + for(t = sp->head->next; t != sp->head; t = t->next) { + if (t->status == ATCH) { + int a = t->adam; + t->height = 0; + for(p = t->next; a > 0 && p != sp->head; p = p->next) { + if (p->status != ATCH || p->adam < 0 || p->adam>= a) { + a--; + } + t->height++; + } + if(t->height > BOUNCEOVER && t->posn == ' '){ + t->posn = '_'; /* high defaults can be bounced */ + } + t->status = THRATCH; +#if 0 + (void) fprintf(stderr, "%d\t%d\n", t->adam, t->height); +#endif + } + } +} + +/* Split Thratch notation into explicit throws and catches. + Usually Catch follows Throw in same hand, but take care of special + cases. */ + +/* ..n1.. -> .. LTn RT1 LC RC .. */ +/* ..nm.. -> .. LTn LC RTm RC .. */ + +static Bool +part(jugglestruct *sp) +{ + Trajectory *t, *nt, *p; + Hand hand = (LRAND() & 1) ? RIGHT : LEFT; + + for (t = sp->head->next; t != sp->head; t = t->next) { + if (t->status > THRATCH) { + hand = t->hand; + } else if (t->status == THRATCH) { + char posn = '='; + + /* plausibility check */ + if (t->height <= 2 && t->posn == '_') { + t->posn = ' '; /* no short bounces */ + } + if (t->height <= 1 && (t->posn == '=' || t->posn == '&')) { + t->posn = ' '; /* 1's need close catches */ + } + + switch (t->posn) { + /* throw catch */ + case ' ': /* fall through */ + case '-': posn = '-'; t->posn = '+'; break; + case '+': posn = '+'; t->posn = '-'; break; + case '=': posn = '='; t->posn = '+'; break; + case '&': posn = '+'; t->posn = '='; break; + case 'x': posn = '='; t->posn = '='; break; + case '_': posn = '_'; t->posn = '-'; break; + default: (void) fprintf(stderr, "unexpected posn %c\n", t->posn); break; + } + hand = (Hand) ((hand + 1) % 2); + t->status = ACTION; + t->hand = hand; + p = t->prev; + + if (t->height == 1) { + p = p->prev; /* early throw */ + } + t->action = CATCH; + INSERT_AFTER(nt, p); + nt->status = ACTION; + nt->action = THROW; + nt->height = t->height; + nt->hand = hand; + nt->posn = posn; + } + } + return True; +} + +/* Connnect up throws and catches to figure out which ball goes where. + Do the same with the juggler's hands. */ + +static void +lob(ModeInfo *mi) +{ + jugglestruct *sp = &juggles[MI_SCREEN(mi)]; + Trajectory *t, *p; + int h; + for (t = sp->head->next; t != sp->head; t = t->next) { + if (t->status == ACTION) { +#if 0 + (void) fprintf(stderr, (t->action == CATCH) ? "A %c%c%c\n" : "A %c%c%c%d\n", + t->posn, + t->hand ? 'R' : 'L', + (t->action == THROW) ? 'T' : (t->action == CATCH ? 'C' : 'N'), + t->height); +#endif + if (t->action == THROW) { + if (t->type == Empty) { + if (MI_NPIXELS(mi) > 2) { + t->color = 1 + NRAND(MI_NPIXELS(mi) - 2); + } + t->spin = NRAND(5) - 2; + t->degree_offset = NRAND(360); + t->divisions = 2 * ((LRAND() & 1) + 1); + } + + /* search forward for next hand catch */ + for (p = t->next; t->handlink == NULL && p != sp->head; p = p->next) { + if (p->action == CATCH) { + if (t->handlink == NULL && p->hand == t->hand) { + t->handlink = p; /* next catch in this hand */ + } + } + } + + if (t->height > 0) { + h = t->height - 1; + + /* search forward for next ball catch */ + for (p = t->next; t->balllink == NULL&& p != sp->head; p = p->next) { + if (p->action == CATCH) { + if (t->balllink == NULL && --h < 1) { /* caught */ +#if 0 + if (p->type == Full) { + /* dropped */ + } +#endif + t->balllink = p; /* complete trajectory */ + p->type = Full; + p->color = t->color; /* accept catch */ + p->spin = t->spin; + p->degree_offset = t->degree_offset; + p->divisions = t->divisions; + } + } + } + } + t->type = Empty; /* thrown */ + } else if (t->action == CATCH) { + /* search forward for next throw from this hand */ + for (p = t->next; t->handlink == NULL && p != sp->head; p = p->next) { + if (p->action == THROW && p->hand == t->hand) { + p->type = t->type; /* pass ball */ + p->color = t->color; /* pass color */ + p->spin = NRAND(5) - 2; + p->degree_offset = NRAND(360); + p->divisions = 2 * ((LRAND() & 1) + 1); + t->handlink = p; + } + } + } + t->status = LINKEDACTION; + } + } +} + +/* Convert hand position symbols into actual time/space coordinates */ +static void +positions(jugglestruct *sp) +{ + Trajectory *t; + int now = 0; + for (t = sp->head->next; t != sp->head; t = t->next) { + if (t->status == PTHRATCH) { + now = t->start; + } else if (t->status == LINKEDACTION) { + int xo = 0, yo; + + /* time */ + if (t->action == CATCH) { + if (t->type == Empty) { + now += (int) THROW_NULL_INTERVAL; /* failed catch is short */ + } else { + now += THROW_CATCH_INTERVAL; /* successful catch */ + } + } else { + now += (int) CATCH_THROW_INTERVAL; /* throws are very short */ + } + t->start = now; + + /* space */ + yo = ARMLENGTH; + switch (t->posn) { + case '-': xo = SX - POSE; break; + case '_': + case '+': xo = SX + POSE; break; + case '=': xo = - SX - POSE; yo += 2 * POSE; break; + default: (void) fprintf(stderr, "unexpected posn %c\n", t->posn); break; + } + t->x = sp->cx + ((t->hand == LEFT) ? xo : -xo); + t->y = sp->cy + yo; + + t->status = PTHRATCH; + } + } +} + + +/* Private physics functions */ + +static Spline +makeSpline(int x0, double dx0, int t0, int x1, double dx1, int t1) +{ + Spline s; + double a, b, c, d; + int x10; + double t10; + + x10 = x1 - x0; + t10 = t1 - t0; + a = ((dx0 + dx1)*t10 - 2*x10) / (t10*t10*t10); + b = (3*x10 - (2*dx0 + dx1)*t10) / (t10*t10); + c = dx0; + d = x0; + s.a = a; + s.b = -3*a*t0 + b; + s.c = (3*a*t0 - 2*b)*t0 + c; + s.d = ((-a*t0 + b)*t0 - c)*t0 +d; + return s; +} + +static double +makeSplinePair(Spline *s1, Spline *s2, + int x0, double dx0, int t0, + int x1, int t1, + int x2, double dx2, int t2) +{ + int x10, x21; + double t21, t10, t20, dx1; + x10 = x1 - x0; + x21 = x2 - x1; + t21 = t2 - t1; + t10 = t1 - t0; + t20 = t2 - t0; + dx1 = (3*x10*t21*t21 + 3*x21*t10*t10 + 3*dx0*t10*t21*t21 + - dx2*t10*t10*t21 - 4*dx0*t10*t21*t21) / + (2*t10*t21*t20); + *s1 = makeSpline(x0, dx0, t0, x1, dx1, t1); + *s2 = makeSpline(x1, dx1, t1, x2, dx2, t2); + return dx1; +} + +/* Turn abstract timings into physically appropriate ball trajectories. */ +static Bool +projectile(jugglestruct *sp) +{ + Trajectory *t, *n; + for (t = sp->head->next; t != sp->head; t = t->next) { + if (t->status != PTHRATCH) { + continue; + } + if (t->action == THROW) { + if (t->balllink != NULL) { + if (t->posn == '_') { /* Bounce once */ + double tc, y0, yf, yc, tb, e, i; + + tc = t->balllink->start - t->start; + + yf = sp->cy + FY; + y0 = t->y; + yc = t->balllink->y; + e = 1; /* permissible error in yc */ + + /* + tb = time to bounce + yt = height at catch time after one bounce + one or three roots according to timing + find one by interval bisection + */ + tb = tc; + for(i = tc / 2; i > 0; i/=2){ + double dy, dt, yt; + if(tb == 0){ + (void) fprintf(stderr, "div by zero!\n"); + break; + } + dy = (yf - y0)/tb + 0.5*sp->Gr*tb; + dt = tc - tb; + yt = -COR*dy*dt + 0.5*sp->Gr*dt*dt + yf; + if(yt > yc + e){ + tb-=i; + }else if(yt < yc - e){ + tb+=i; + }else{ + break; + } + } + + { + double t0, dy; + + t->dx = (t->balllink->x - t->x) / tc; + + /* ball follows parabola down */ + INSERT_AFTER(n, t->prev); + n->start = t->start; + n->finish = (int) (t->start + tb); + n->type = Ball; + n->color = t->color; + n->spin = t->spin; + n->degree_offset = t->degree_offset; + n->divisions = t->divisions; + n->status = PREDICTOR; + + t->dy = (yf - y0)/tb - 0.5*sp->Gr*tb; + t0 = n->start; + /* Represent parabola as a degenerate spline - + linear in x, quadratic in y */ + n->xp.a = 0; + n->xp.b = 0; + n->xp.c = t->dx; + n->xp.d = -t->dx*t0 + t->x; + n->yp.a = 0; + n->yp.b = sp->Gr/2; + n->yp.c = -sp->Gr*t0 + t->dy; + n->yp.d = sp->Gr/2*t0*t0 - t->dy*t0 + t->y; + + + /* ball follows parabola up */ + INSERT_AFTER(n, t->prev); + n->start = (int) (t0 + tb); + n->finish = (int) (t0 + tc); + n->type = Ball; + n->color = t->color; + n->spin = t->spin; + n->degree_offset = t->degree_offset; + n->divisions = t->divisions; + n->status = PREDICTOR; + + n->xp.a = 0; + n->xp.b = 0; + n->xp.c = t->dx; + n->xp.d = -t->dx*t0 + t->x; + + dy = (yf - y0)/tb + 0.5*sp->Gr*tb; + t0 = n->start; + /* Represent parabola as a degenerate spline - + linear in x, quadratic in y */ + n->yp.a = 0; + n->yp.b = sp->Gr/2; + n->yp.c = -sp->Gr*t0 - COR*dy; + n->yp.d = sp->Gr/2*t0*t0 + COR*dy*t0 + yf; + } + + t->status = BPREDICTOR; + + } else { + double t0, dt; + + /* ball follows parabola */ + INSERT_AFTER(n, t->prev); + n->start = t->start; + n->finish = t->balllink->start; + n->type = Ball; + n->color = t->color; + n->spin = t->spin; + n->degree_offset = t->degree_offset; + n->divisions = t->divisions; + n->status = PREDICTOR; + + t0 = n->start; + dt = t->balllink->start - t->start; + t->dx = (t->balllink->x - t->x) / dt; + t->dy = (t->balllink->y - t->y) / dt - sp->Gr/2 * dt; + + /* Represent parabola as a degenerate spline - + linear in x, quadratic in y */ + n->xp.a = 0; + n->xp.b = 0; + n->xp.c = t->dx; + n->xp.d = -t->dx*t0 + t->x; + n->yp.a = 0; + n->yp.b = sp->Gr/2; + n->yp.c = -sp->Gr*t0 + t->dy; + n->yp.d = sp->Gr/2*t0*t0 - t->dy*t0 + t->y; + + + t->status = BPREDICTOR; + } + } else { /* Zero Throw */ + t->status = BPREDICTOR; + } + } + } + return True; +} + +/* Turn abstract hand motions into cubic splines. */ +static void +hands(jugglestruct *sp) +{ + Trajectory *t, *u, *v; + for (t = sp->head->next; t != sp->head; t = t->next) { + /* no throw => no velocity */ + if (t->status != BPREDICTOR) { + continue; + } + + u = t->handlink; + if (u == NULL) { /* no next catch */ + continue; + } + v = u->handlink; + if (v == NULL) { /* no next throw */ + continue; + } + + /* double spline takes hand from throw, thru catch, to + next throw */ + + t->finish = u->start; + t->status = PREDICTOR; + + u->finish = v->start; + u->status = PREDICTOR; + + (void) makeSplinePair(&t->xp, &u->xp, + t->x, t->dx, t->start, + u->x, u->start, + v->x, v->dx, v->start); + (void) makeSplinePair(&t->yp, &u->yp, + t->y, t->dy, t->start, + u->y, u->start, + v->y, v->dy, v->start); + + t->status = PREDICTOR; + } +} + +/* Given target x, y find_elbow puts hand at target if possible, + * otherwise makes hand point to the target */ +static void +find_elbow(jugglestruct *sp, XPoint *h, XPoint *e, int x, int y, int z) +{ + double r, h2, t; + + h2 = x*x + y*y + z*z; + if (h2 > 4*ARMLENGTH*ARMLENGTH) { + t = ARMLENGTH/sqrt(h2); + e->x = (short) (t*x); + e->y = (short) (t*y); + h->x = 2 * e->x; + h->y = 2 * e->y; + } else { + r = sqrt((double)(x*x + z*z)); + t = sqrt(4 * ARMLENGTH * ARMLENGTH / h2 - 1); + e->x = (short) (x*(1 - y*t/r)/2); + e->y = (short) ((y + r*t)/2); + h->x = x; + h->y = y; + } +} + +/* NOTE: returned x, y adjusted for arm reach */ +static void +draw_arm(ModeInfo * mi, Hand side, int *x, int *y) +{ + Display *dpy = MI_DISPLAY(mi); + Window win = MI_WINDOW(mi); + GC gc = MI_GC(mi); + jugglestruct *sp = &juggles[MI_SCREEN(mi)]; + + int sig = (side == LEFT) ? 1 : -1; + + XSetLineAttributes(dpy, gc, + ARMWIDTH, LineSolid, CapRound, JoinRound); + if (sp->arm[side][0].x != *x || sp->arm[side][0].y != *y) { + XPoint h, e; + XSetForeground(dpy, gc, MI_BLACK_PIXEL(mi)); + find_elbow(sp, &h, &e, *x - sig*SX - sp->cx, *y - SY - sp->cy, SZ); + XDrawLines(dpy, win, gc, sp->arm[side], 3, CoordModeOrigin); + *x = sp->arm[side][0].x = sp->cx + sig*SX + h.x; + *y = sp->arm[side][0].y = sp->cy + SY + h.y; + sp->arm[side][1].x = sp->cx + sig*SX + e.x; + sp->arm[side][1].y = sp->cy + SY + e.y; + } + XSetForeground(dpy, gc, MI_WHITE_PIXEL(mi)); + XDrawLines(dpy, win, gc, sp->arm[side], 3, CoordModeOrigin); + XSetLineAttributes(dpy, gc, + 1, LineSolid, CapNotLast, JoinRound); +} + +static void +draw_figure(ModeInfo * mi) +{ + Display *dpy = MI_DISPLAY(mi); + Window win = MI_WINDOW(mi); + GC gc = MI_GC(mi); + jugglestruct *sp = &juggles[MI_SCREEN(mi)]; + + XSetLineAttributes(dpy, gc, + ARMWIDTH, LineSolid, CapRound, JoinRound); + XSetForeground(dpy, gc, MI_WHITE_PIXEL(mi)); + XDrawLines(dpy, win, gc, sp->figure_path, FIGURE1, CoordModeOrigin); + XDrawSegments(dpy, win, gc, sp->figure_segs, FIGURE2); + XDrawArc(dpy, win, gc, + sp->cx - HED/2, sp->cy + NEY - HED, HED, HED, 0, 64*360); + XSetLineAttributes(dpy, gc, + 1, LineSolid, CapNotLast, JoinRound); +} + + +/* dumps a human-readable rendition of the current state of the juggle + pipeline to stderr for debugging */ +#ifdef OLDDEBUG +static void +dump(jugglestruct *sp) +{ + Trajectory *t; + + for (t = sp->head->next; t != sp->head; t = t->next) { + switch (t->status) { + case THROW: + (void) fprintf(stderr, "T %c%d\n", t->posn, t->height); + break; + case ACTION: + (void) fprintf(stderr, t->action == CATCH?"A %c%c%c\n":"A %c%c%c%d\n", + t->posn, + t->hand ? 'R' : 'L', + (t->action == THROW)?'T':(t->action == CATCH?'C':'N'), + t->height); + break; + case LINKEDACTION: + (void) fprintf(stderr, "L %c%c%c%d %d\n", + t->posn, + t->hand?'R':'L', + (t->action == THROW)?'T':(t->action == CATCH?'C':'N'), + t->height, t->color); + break; + case PTHRATCH: + (void) fprintf(stderr, "O %c%c%c%d %d %2d %6d %6d\n", t->posn, + t->hand?'R':'L', + (t->action == THROW)?'T':(t->action == CATCH?'C':'N'), + t->height, t->type, t->color, + t->start, t->finish); + break; + case PREDICTOR: + (void) fprintf(stderr, "P %c %2d %6d %6d %g\n", + t->type == Ball?'b':t->type == Empty?'e':'f', + t->color, + t->start, t->finish, t->yp.c); + break; + default: + (void) fprintf(stderr, "status %d not implemented\n", t->status); + break; + } + } +} +#endif + +static int get_num_balls(const char *j) +{ + int balls = 0; + const char *p; + int h = 0; + for (p = j; *p; p++) { + if (*p >= '0' && *p <='9') { /* digit */ + h = 10*h + (*p - '0'); + } else { + if (h > balls) { + balls = h; + } + h = 0; + } + } + return balls; +} + +#ifdef __cplusplus +extern "C" { +#endif + +static int compare_num_balls(const void *p1, const void *p2) +{ + int i = get_num_balls(((patternstruct*)p1)->pattern); + int j = get_num_balls(((patternstruct*)p2)->pattern); + if (i > j) { + return (1); + } else if (i < j) { + return (-1); + } else { + return (0); + } +} + +#ifdef __cplusplus +} +#endif + +/* Public functions */ + +void +release_juggle(ModeInfo * mi) +{ + if (juggles != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_juggle(&juggles[screen]); + (void) free((void *) juggles); + juggles = (jugglestruct *) NULL; + } + if (patternindex != NULL) { + (void) free((void *) patternindex); + patternindex = (PatternIndex *) NULL; + } +} + +void +init_juggle(ModeInfo * mi) +{ + jugglestruct *sp; + int i; + XPoint figure1[FIGURE1]; + XSegment figure2[FIGURE2]; + if (pattern != NULL && *pattern == '.') { + pattern = NULL; + } + if (pattern == NULL && patternindex == NULL) { + /* pattern list needs indexing */ + int i; + int nelements = sizeof(portfolio)/sizeof(patternstruct); + int maxballs; + int numpat = 0; + + /* sort according to number of balls */ + qsort((void*)portfolio, nelements, + sizeof(patternstruct), compare_num_balls); + + /* last pattern has most balls */ + maxballs = get_num_balls(portfolio[nelements - 1].pattern); + /* allocate index */ + if ((patternindex = (PatternIndex *) calloc(maxballs + 1, + sizeof (PatternIndex))) == NULL) { + return; + } + + /* run through sorted list, indexing start of each group + and number in group */ + maxballs = 1; + for (i = 0; i < nelements; i++) { + int b = get_num_balls(portfolio[i].pattern); + if (b > maxballs) { + if (MI_IS_VERBOSE(mi)) { + (void) fprintf(stderr, "%d %d ball pattern%s\n", + numpat, maxballs, (numpat == 1) ? "" : "s"); + } + patternindex[maxballs].number = numpat; + maxballs = b; + numpat = 1; + patternindex[maxballs].start = i; + } else { + numpat++; + } + } + if (MI_IS_VERBOSE(mi)) { + (void) fprintf(stderr, "%d %d ball pattern%s\n", + numpat, maxballs, (numpat == 1) ? "" : "s"); + } + patternindex[maxballs].number = numpat; + } + + if (juggles == NULL) { /* allocate jugglestruct */ + if ((juggles = (jugglestruct *) calloc(MI_NUM_SCREENS(mi), + sizeof (jugglestruct))) == NULL) { + release_juggle(mi); + return; + } + } + sp = &juggles[MI_SCREEN(mi)]; + + sp->count = 0; + + if (MI_IS_FULLRANDOM(mi)) { + sp->solid = (Bool) (LRAND() & 1); +#ifdef UNI + sp->uni = (Bool) (LRAND() & 1); +#endif + } else { + sp->solid = solid; +#ifdef UNI + sp->uni = uni; +#endif + } + + sp->width = MI_WIDTH(mi); + sp->height = MI_HEIGHT(mi); + sp->count = ABS(MI_COUNT(mi)); + if (sp->count == 0) + sp->count = 150; + sp->scale = sp->height / 480.0; + /* vary x a little so the juggler does not burn the screen */ + sp->cx = sp->width / 2 + RFX + NRAND(LFX - RFX + 1); + sp->cy = sp->height - FY - ((int) sp->uni) * FY / 3; /* raise higher */ + /* "7" hits top of screen */ + sp->Gr = GRAVITY(sp->cy, 7 * THROW_CATCH_INTERVAL); + + figure1[0].x = LHIPX, figure1[0].y = HIPY; + figure1[1].x = 0, figure1[1].y = WSTY; + figure1[2].x = SX, figure1[2].y = SY; + figure1[3].x = -SX, figure1[3].y = SY; + figure1[4].x = 0, figure1[4].y = WSTY; + figure1[5].x = RHIPX, figure1[5].y = HIPY; + figure1[6].x = LHIPX, figure1[6].y = HIPY; + figure2[0].x1 = 0, figure2[0].y1 = SY, + figure2[0].x2 = 0, figure2[0].y2 = NEY; + figure2[1].x1 = LHIPX, figure2[1].y1 = HIPY, + figure2[1].x2 = LFX, figure2[1].y2 = FY; + figure2[2].x1 = RHIPX, figure2[2].y1 = HIPY, + figure2[2].x2 = RFX, figure2[2].y2 = FY; + + /* Body Path */ + for (i = 0; i < FIGURE1; i++) { + sp->figure_path[i].x = figure1[i].x + sp->cx; + sp->figure_path[i].y = figure1[i].y + sp->cy; + } + /* Body Segments */ + for (i = 0; i < FIGURE2; i++) { + sp->figure_segs[i].x1 = figure2[i].x1 + sp->cx; + sp->figure_segs[i].y1 = figure2[i].y1 + sp->cy; + sp->figure_segs[i].x2 = figure2[i].x2 + sp->cx; + sp->figure_segs[i].y2 = figure2[i].y2 + sp->cy; + } + /* Shoulders */ + sp->arm[LEFT][2].x = sp->cx + SX; + sp->arm[LEFT][2].y = sp->cy + SY; + sp->arm[RIGHT][2].x = sp->cx - SX; + sp->arm[RIGHT][2].y = sp->cy + SY; + + if (sp->trace == NULL) { + if ((sp->trace = (XPoint *)calloc(trail, sizeof(XPoint))) == NULL) { + free_juggle(sp); + return; + } + } + + /* Clear the background. */ + MI_CLEARWINDOW(mi); + + draw_figure(mi); + + /* record start time */ + sp->begintime = time(NULL); + + free_pattern(sp); + + /* create circular list */ + INSERT_AFTER_TOP(sp->head, sp->head); + + /* generate pattern */ + if (pattern == NULL) { + +#define MAXPAT 10 +#define MAXREPEAT 30 +#define CHANGE_BIAS 8 /* larger makes num_ball changes less likely */ +#define POSITION_BIAS 20 /* larger makes hand movements less likely */ + + int count = 0; + int num_balls = MINBALLS + NRAND(MAXBALLS - MINBALLS); + while (count < MI_CYCLES(mi)) { + char buf[MAXPAT * 3 + 3], *b = buf; + int maxseen = 0; + int l = NRAND(MAXPAT) + 1; + int t = NRAND(MAXREPEAT) + 1; + + { /* vary number of balls */ + int new_balls = num_balls; + int change; + + if (new_balls == 2) /* Do not juggle 2 that often */ + change = NRAND(2 + CHANGE_BIAS / 4); + else + change = NRAND(2 + CHANGE_BIAS); + switch (change) { + case 0: + new_balls++; + break; + case 1: + new_balls--; + break; + default: + break; /* NO-OP */ + } + if (new_balls < MINBALLS) { + new_balls += 2; + } + if (new_balls > MAXBALLS) { + new_balls -= 2; + } + if (new_balls < num_balls) { + if (!program(mi, "[*]", 1)) /* lose ball */ + return; + } + num_balls = new_balls; + } + count++; + + if (NRAND(2) && patternindex[num_balls].number) { + /* Pick from PortFolio */ + if (!program(mi, + portfolio[patternindex[num_balls].start + + NRAND(patternindex[num_balls].number)].pattern, + t)) + return; + } else { + /* Invent a new pattern */ + *b++='['; + for(i = 0; i < l; i++){ + int n, m; + do { /* Triangular Distribution => high values more likely */ + m = NRAND(num_balls + 1); + n = NRAND(num_balls + 1); + } while(m >= n); + if (n == num_balls) { + maxseen = 1; + } + switch(NRAND(6 + POSITION_BIAS)){ + case 0: /* Inside throw */ + *b++ = '-'; break; + case 1: /* Outside throw */ + *b++ = '+'; break; + case 2: /* Cross throw */ + *b++ = '='; break; + case 3: /* Cross catch */ + *b++ = '&'; break; + case 4: /* Cross throw and catch */ + *b++ = 'x'; break; + case 5: /* Bounce */ + *b++ = '_'; break; + default: + break; /* NO-OP */ + } + + *b++ = n + '0'; + *b++ = ' '; + } + *b++ = ']'; + *b = '\0'; + if (maxseen) { + if (!program(mi, buf, t)) + return; + } + } + } + } else { /* pattern supplied in height or 'a' notation */ + if (!program(mi, pattern, MI_CYCLES(mi))) + return; + } + + adam(sp); + + if (!part(sp)) + return; + + lob(mi); + + positions(sp); + + if (!projectile(sp)) + return; + + hands(sp); + +#ifdef OLDDEBUG + dump(sp); +#endif +} + +#define CUBIC(s, t) ((((s).a * (t) + (s).b) * (t) + (s).c) * (t) + (s).d) + +#ifdef SUNOS4 +/*- + * Workaround SunOS 4 framebuffer bug which causes balls to leave dust + * trace behind when erased + */ +#define ERASE_BALL(x,y) \ + XSetForeground(dpy, gc, MI_BLACK_PIXEL(mi)); \ + XFillArc(dpy, window, gc, \ + (x) - BALLRADIUS - 2, (y) - BALLRADIUS - 2, \ + 2*(BALLRADIUS + 2), 2*(BALLRADIUS + 2), 0, 23040) +#else + +#define ERASE_BALL(x,y) \ + XSetForeground(dpy, gc, MI_BLACK_PIXEL(mi)); \ + XFillArc(dpy, window, gc, \ + (x) - BALLRADIUS, (y) - BALLRADIUS, \ + 2*BALLRADIUS, 2*BALLRADIUS, 0, 23040) +#endif + +static void +draw_juggle_ball(ModeInfo *mi, unsigned long color, int x, int y, double degree_offset, int divisions) +{ + Display *dpy = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + jugglestruct *sp = &juggles[MI_SCREEN(mi)]; + int offset; + + XSetForeground(dpy, gc, color); + if ((color == MI_WHITE_PIXEL(mi)) || + ((divisions != 2) && (divisions != 4)) || sp->solid) { + XFillArc(dpy, window, gc, + x - BALLRADIUS, y - BALLRADIUS, + 2*BALLRADIUS, 2*BALLRADIUS, + 0, 23040); + return; + } + offset = (int) (degree_offset * 64); + if (divisions == 4) { /* 90 degree divisions */ + XFillArc(dpy, window, gc, + x - BALLRADIUS, y - BALLRADIUS, + 2*BALLRADIUS, 2*BALLRADIUS, + offset, 5760); + XFillArc(dpy, window, gc, + x - BALLRADIUS, y - BALLRADIUS, + 2*BALLRADIUS, 2*BALLRADIUS, + (offset + 11520) % 23040, 5760); + XSetForeground(dpy, gc, MI_WHITE_PIXEL(mi)); + XFillArc(dpy, window, gc, + x - BALLRADIUS, y - BALLRADIUS, + 2*BALLRADIUS, 2*BALLRADIUS, + (offset + 5760) % 23040, 5760); + XFillArc(dpy, window, gc, + x - BALLRADIUS, y - BALLRADIUS, + 2*BALLRADIUS, 2*BALLRADIUS, + (offset + 17280) % 23040, 5760); + } else { /* 180 degree divisions */ + XFillArc(dpy, window, gc, + x - BALLRADIUS, y - BALLRADIUS, + 2*BALLRADIUS, 2*BALLRADIUS, + offset, 11520); + XSetForeground(dpy, gc, MI_WHITE_PIXEL(mi)); + XFillArc(dpy, window, gc, + x - BALLRADIUS, y - BALLRADIUS, + 2*BALLRADIUS, 2*BALLRADIUS, + (offset + 11520) % 23040, 11520); + } + XFlush(dpy); +} + +void +draw_juggle(ModeInfo * mi) +{ + Display *dpy = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + Trajectory *traj; + int future = 0; + int length = 0; + jugglestruct *sp; + + if (juggles == NULL) + return; + sp = &juggles[MI_SCREEN(mi)]; + if (sp->trace == NULL) + return; + + MI_IS_DRAWN(mi) = True; + + draw_figure(mi); + + { + struct timeval tv; + (void)gettimeofday(&tv, NULL); + sp->time = (int) ((tv.tv_sec - sp->begintime)*1000 + tv.tv_usec/1000); + } + for (traj = sp->head->next; traj != sp->head; traj = traj->next) { + length++; + if (traj->status != PREDICTOR) { + continue; + } + if (traj->start > future) { + future = traj->start; + } + if (sp->time < traj->start) { /* early */ + continue; + } else if (sp->time < traj->finish) { /* working */ + int x = (int) CUBIC(traj->xp, sp->time); + int y = (int) CUBIC(traj->yp, sp->time); + unsigned long color; + + if (MI_NPIXELS(mi) > 2) { + color = MI_PIXEL(mi, traj->color); + } else { + color = MI_WHITE_PIXEL(mi); + } + if (traj->type == Empty || traj->type == Full) { + draw_arm(mi, traj->hand, &x, &y); + } + if (traj->type == Ball || traj->type == Full) { + if(trail > 0) { + ERASE_BALL(sp->trace[sp->traceindex].x, + sp->trace[sp->traceindex].y); + sp->trace[sp->traceindex].x = traj->x; + sp->trace[sp->traceindex].y = traj->y; + if (++sp->traceindex >= trail) { + sp->traceindex = 0; + } + } else { + ERASE_BALL(traj->x, traj->y); + } + draw_juggle_ball(mi, color, x, y, traj->degree_offset, traj->divisions); + traj->degree_offset = traj->degree_offset + + SPIN_DEGREES * traj->spin / sp->count; + if (traj->degree_offset < 0.0) + traj->degree_offset += 360.0; + else if (traj->degree_offset >= 360.0) + traj->degree_offset -= 360.0; + } + traj->x = x; + traj->y = y; + } else { /* expired */ + Trajectory *n = traj; + + ERASE_BALL(traj->x, traj->y); + traj=traj->prev; + REMOVE(n); + } + } + + /*** FIXME-BEGIN ***/ + /* pattern generator would refill here when necessary */ +#if 1 + if (future == 0) { +#else + if (sp->count > MI_CYCLES(mi)) { /* pick a new juggle */ +#endif + init_juggle(mi); + } + /*** FIXME-END ***/ + +} + +#endif /* MODE_juggle */ diff --git a/hacks/laser.c b/hacks/laser.c index de2a9144..2b0622dd 100644 --- a/hacks/laser.c +++ b/hacks/laser.c @@ -1,41 +1,61 @@ -/* -*- Mode: C; tab-width: 4 -*- - * laser --- draws swinging laser beams. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* laser --- spinning lasers */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)laser.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)laser.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1995 Pascal Pensa +/*- + * Copyright (c) 1995 Pascal Pensa * - * 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. + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 1995: Written. */ #ifdef STANDALONE -# define PROGCLASS "Laser" -# define HACK_INIT init_laser -# define HACK_DRAW draw_laser -# define laser_opts xlockmore_opts -# define DEFAULTS "*count: 10 \n" \ - "*cycles: 200 \n" \ - "*delay: 40000 \n" \ - "*ncolors: 64 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -ModeSpecOpt laser_opts = { - 0, NULL, 0, NULL, NULL }; +#define MODE_laser +#define PROGCLASS "Laser" +#define HACK_INIT init_laser +#define HACK_DRAW draw_laser +#define laser_opts xlockmore_opts +#define DEFAULTS "*delay: 40000 \n" \ + "*count: 10 \n" \ + "*cycles: 200 \n" \ + "*ncolors: 64 \n" +#define BRIGHT_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_laser + +ModeSpecOpt laser_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct laser_description = +{"laser", "init_laser", "draw_laser", "release_laser", + "refresh_laser", "init_laser", (char *) NULL, &laser_opts, + 20000, -10, 200, 1, 64, 1.0, "", + "Shows spinning lasers", 0, NULL}; + +#endif #define MINREDRAW 3 /* Number of redrawn on each frame */ #define MAXREDRAW 8 @@ -52,7 +72,7 @@ ModeSpecOpt laser_opts = { #define COLORSTEP 2 /* Laser color step */ -#define RANGE_RAND(min,max) ((min) + LRAND() % ((max) - (min))) +#define RANGE_RAND(min,max) (int) ((min) + LRAND() % ((max) - (min))) typedef enum { TOP, RIGHT, BOTTOM, LEFT @@ -85,12 +105,25 @@ typedef struct { laserstruct *laser; } lasersstruct; -static lasersstruct *lasers = NULL; +static lasersstruct *lasers = (lasersstruct *) NULL; +static void +free_laser(Display *display, lasersstruct *lp) +{ + if (lp->laser != NULL) { + (void) free((void *) lp->laser); + lp->laser = (laserstruct *) NULL; + } + if (lp->stippledGC != None) { + XFreeGC(display, lp->stippledGC); + lp->stippledGC = None; + } +} void init_laser(ModeInfo * mi) { + Display *display = MI_DISPLAY(mi); int i, c = 0; lasersstruct *lp; @@ -101,34 +134,41 @@ init_laser(ModeInfo * mi) } lp = &lasers[MI_SCREEN(mi)]; - lp->width = MI_WIN_WIDTH(mi); - lp->height = MI_WIN_HEIGHT(mi); + lp->width = MI_WIDTH(mi); + lp->height = MI_HEIGHT(mi); lp->time = 0; - lp->ln = MI_BATCHCOUNT(mi); + lp->ln = MI_COUNT(mi); if (lp->ln < -MINLASER) { /* if lp->ln is random ... the size can change */ if (lp->laser != NULL) { (void) free((void *) lp->laser); - lp->laser = NULL; + lp->laser = (laserstruct *) NULL; } lp->ln = NRAND(-lp->ln - MINLASER + 1) + MINLASER; } else if (lp->ln < MINLASER) lp->ln = MINLASER; - if (!lp->laser) { - lp->laser = (laserstruct *) malloc(lp->ln * sizeof (laserstruct)); + if (lp->laser == NULL) { + if ((lp->laser = (laserstruct *) malloc(lp->ln * + sizeof (laserstruct))) == NULL) { + free_laser(display, lp); + return; + } } - if (lp->stippledGC == NULL) { + if (lp->stippledGC == None) { XGCValues gcv; - gcv.foreground = MI_WIN_WHITE_PIXEL(mi); - gcv.background = MI_WIN_BLACK_PIXEL(mi); - lp->gcv_black.foreground = MI_WIN_BLACK_PIXEL(mi); - lp->stippledGC = XCreateGC(MI_DISPLAY(mi), MI_WINDOW(mi), - GCForeground | GCBackground, &gcv); + gcv.foreground = MI_WHITE_PIXEL(mi); + gcv.background = MI_BLACK_PIXEL(mi); + lp->gcv_black.foreground = MI_BLACK_PIXEL(mi); + if ((lp->stippledGC = XCreateGC(display, MI_WINDOW(mi), + GCForeground | GCBackground, &gcv)) == None) { + free_laser(display, lp); + return; + } } - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + MI_CLEARWINDOW(mi); if (MINDIST < lp->width - MINDIST) lp->cx = RANGE_RAND(MINDIST, lp->width - MINDIST); @@ -169,13 +209,13 @@ init_laser(ModeInfo * mi) l->by = NRAND(lp->height); } - l->dir = LRAND() & 1; + l->dir = (int) (LRAND() & 1); l->speed = ((RANGE_RAND(MINSPEED, MAXSPEED) * lp->width) / 1000) + 1; if (MI_NPIXELS(mi) > 2) { l->gcv.foreground = MI_PIXEL(mi, c); c = (c + COLORSTEP) % MI_NPIXELS(mi); } else - l->gcv.foreground = MI_WIN_WHITE_PIXEL(mi); + l->gcv.foreground = MI_WHITE_PIXEL(mi); } } @@ -283,9 +323,16 @@ draw_laser_once(ModeInfo * mi) void draw_laser(ModeInfo * mi) { - lasersstruct *lp = &lasers[MI_SCREEN(mi)]; int i; + lasersstruct *lp; + if (lasers == NULL) + return; + lp = &lasers[MI_SCREEN(mi)]; + if (lp->laser == NULL) + return; + + MI_IS_DRAWN(mi) = True; for (i = 0; i < lp->lr; i++) draw_laser_once(mi); @@ -299,21 +346,17 @@ release_laser(ModeInfo * mi) if (lasers != NULL) { int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - lasersstruct *lp = &lasers[screen]; - - if (lp->laser != NULL) - (void) free((void *) lp->laser); - if (lp->stippledGC != NULL) - XFreeGC(MI_DISPLAY(mi), lp->stippledGC); - } + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_laser(MI_DISPLAY(mi), &lasers[screen]); (void) free((void *) lasers); - lasers = NULL; + lasers = (lasersstruct *) NULL; } } void refresh_laser(ModeInfo * mi) { - /* Do nothing, it will refresh by itself */ + MI_CLEARWINDOW(mi); } + +#endif /* MODE_laser */ diff --git a/hacks/lightning.c b/hacks/lightning.c index 77be5783..deb37411 100644 --- a/hacks/lightning.c +++ b/hacks/lightning.c @@ -1,11 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * lightning --- fractal lightning bolts. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* lightning --- fractal lightning bolds */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)lightning.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)lightning.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1996 by Keith Romberg . +/*- + * Copyright (c) 1996 by Keith Romberg * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,28 +22,38 @@ static const char sccsid[] = "@(#)lightning.c 4.00 97/01/01 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 14-Jul-96: Cleaned up code. - * 27-Jun-96: Written and submitted by Keith Romberg . + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 14-Jul-1996: Cleaned up code. + * 27-Jun-1996: Written and submitted by Keith Romberg . */ #ifdef STANDALONE -# define PROGCLASS "Lightning" -# define HACK_INIT init_lightning -# define HACK_DRAW draw_lightning -# define lightning_opts xlockmore_opts -# define DEFAULTS "*delay: 10000 \n" \ - "*ncolors: 200 \n" -# define BRIGHT_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -ModeSpecOpt lightning_opts = { - 0, NULL, 0, NULL, NULL }; - -/*---------------------------- defines -------------------------------*/ +#define MODE_lightning +#define PROGCLASS "Lightning" +#define HACK_INIT init_lightning +#define HACK_DRAW draw_lightning +#define lightning_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" +#define BRIGHT_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_lightning + +ModeSpecOpt lightning_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct lightning_description = +{"lightning", "init_lightning", "draw_lightning", "release_lightning", + "refresh_lightning", "init_lightning", (char *) NULL, &lightning_opts, + 10000, 1, 1, 1, 64, 0.6, "", + "Shows Keith's fractal lightning bolts", 0, NULL}; + +#endif #define BOLT_NUMBER 4 #define BOLT_ITERATION 4 @@ -100,10 +112,11 @@ typedef struct { int give_it_hell; int draw_time; int stage; + int busyLoop; unsigned long color; } Storm; -static Storm *Helga = NULL; +static Storm *Helga = (Storm *) NULL; /*------------------- function prototypes ----------------------------*/ @@ -113,7 +126,7 @@ static int setup_multi_strike(void); static int flashing_strike(void); static void flash_duration(int *start, int *end, int total_duration); static void random_storm(Storm * st); -static void generate(XPoint A, XPoint B, int iter, XPoint * verts, int *index); +static void generate(XPoint A, XPoint B, int iter, XPoint * verts, int *vert_index); static void create_fork(Fork * f, XPoint start, XPoint end, int level); static void first_strike(Lightning bolt, ModeInfo * mi); @@ -123,7 +136,7 @@ static void level1_strike(Lightning bolt, ModeInfo * mi); static void level2_strike(Lightning bolt, ModeInfo * mi); static int storm_active(Storm * st); -static void update_bolt(Lightning * bolt, int time); +static void update_bolt(Lightning * bolt, int time_now); static void wiggle_bolt(Lightning * bolt); static void wiggle_line(XPoint * p, int number, int wiggle_amount); @@ -220,7 +233,7 @@ random_storm(Storm * st) } static void -generate(XPoint A, XPoint B, int iter, XPoint * verts, int *index) +generate(XPoint A, XPoint B, int iter, XPoint * verts, int *vert_index) { XPoint mid; @@ -228,13 +241,13 @@ generate(XPoint A, XPoint B, int iter, XPoint * verts, int *index) mid.y = (A.y + B.y) / 2 + NRAND(HEIGHT_VARIATION) - HEIGHT_VARIATION / 2; if (!iter) { - verts[*index].x = mid.x; - verts[*index].y = mid.y; - (*index)++; + verts[*vert_index].x = mid.x; + verts[*vert_index].y = mid.y; + (*vert_index)++; return; } - generate(A, mid, iter - 1, verts, index); - generate(mid, B, iter - 1, verts, index); + generate(A, mid, iter - 1, verts, vert_index); + generate(mid, B, iter - 1, verts, vert_index); } /*------------------------------------------------------------------------*/ @@ -270,30 +283,30 @@ create_fork(Fork * f, XPoint start, XPoint end, int level) /*------------------------------------------------------------------------*/ static void -update_bolt(Lightning * bolt, int time) +update_bolt(Lightning * bolt, int time_now) { wiggle_bolt(bolt); if ((bolt->wiggle_amount == 0) && (bolt->wiggle_number > 2)) bolt->wiggle_number = 0; - if (((time % 3) == 0)) + if (((time_now % 3) == 0)) bolt->wiggle_amount++; - if (((time >= bolt->delay_time) && (time < bolt->flash_begin)) || - (time > bolt->flash_stop)) + if (((time_now >= bolt->delay_time) && (time_now < bolt->flash_begin)) || + (time_now > bolt->flash_stop)) bolt->visible = 1; else bolt->visible = 0; - if (time == bolt->delay_time) + if (time_now == bolt->delay_time) bolt->strike_level = FIRST_LEVEL_STRIKE; - else if (time == (bolt->delay_time + 1)) + else if (time_now == (bolt->delay_time + 1)) bolt->strike_level = LEVEL_ONE_STRIKE; - else if ((time > (bolt->delay_time + 1)) && - (time <= (bolt->delay_time + bolt->flash_begin - 2))) + else if ((time_now > (bolt->delay_time + 1)) && + (time_now <= (bolt->delay_time + bolt->flash_begin - 2))) bolt->strike_level = LEVEL_TWO_STRIKE; - else if (time == (bolt->delay_time + bolt->flash_begin - 1)) + else if (time_now == (bolt->delay_time + bolt->flash_begin - 1)) bolt->strike_level = LEVEL_ONE_STRIKE; - else if (time == (bolt->delay_time + bolt->flash_stop + 1)) + else if (time_now == (bolt->delay_time + bolt->flash_stop + 1)) bolt->strike_level = LEVEL_ONE_STRIKE; else bolt->strike_level = LEVEL_TWO_STRIKE; @@ -324,7 +337,7 @@ first_strike(Lightning bolt, ModeInfo * mi) GC gc = MI_GC(mi); int i; - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); XDrawLine(display, window, gc, bolt.end1.x, bolt.end1.y, bolt.middle[0].x, bolt.middle[0].y); draw_line(mi, bolt.middle, BOLT_VERTICIES, gc, 0); @@ -375,7 +388,7 @@ level1_strike(Lightning bolt, ModeInfo * mi) if (MI_NPIXELS(mi) > 2) /* color */ XSetForeground(display, gc, MI_PIXEL(mi, st->color)); else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); XDrawLine(display, window, gc, bolt.end1.x - 1, bolt.end1.y, bolt.middle[0].x - 1, bolt.middle[0].y); draw_line(mi, bolt.middle, BOLT_VERTICIES, gc, -1); @@ -403,7 +416,7 @@ level1_strike(Lightning bolt, ModeInfo * mi) static int distance(XPoint a, XPoint b) { - return ((int) sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y))); + return ((int) sqrt((double) (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y))); } /*------------------------------------------------------------------------*/ @@ -424,7 +437,7 @@ level2_strike(Lightning bolt, ModeInfo * mi) if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, st->color)); else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); XDrawLine(display, window, gc, bolt.end1.x - 2, bolt.end1.y, bolt.middle[0].x - 2, bolt.middle[0].y); draw_line(mi, bolt.middle, BOLT_VERTICIES, gc, -2); @@ -513,8 +526,8 @@ init_lightning(ModeInfo * mi) } st = &Helga[MI_SCREEN(mi)]; - st->scr_width = MI_WIN_WIDTH(mi); - st->scr_height = MI_WIN_HEIGHT(mi); + st->scr_width = MI_WIDTH(mi); + st->scr_height = MI_HEIGHT(mi); st->multi_strike = setup_multi_strike(); random_storm(st); @@ -526,18 +539,25 @@ init_lightning(ModeInfo * mi) void draw_lightning(ModeInfo * mi) { - Storm *st = &Helga[MI_SCREEN(mi)]; int i; + Storm *st; + if (Helga == NULL) + return; + st = &Helga[MI_SCREEN(mi)]; + MI_IS_DRAWN(mi) = True; switch (st->stage) { case 0: - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + MI_IS_DRAWN(mi) = False; + MI_CLEARWINDOW(mi); + MI_IS_DRAWN(mi) = True; + st->color = NRAND(MI_NPIXELS(mi)); st->draw_time = 0; if (storm_active(st)) st->stage++; else - st->stage = 3; + st->stage = 4; break; case 1: for (i = 0; i < st->multi_strike; i++) { @@ -546,19 +566,29 @@ draw_lightning(ModeInfo * mi) update_bolt(&(st->bolts[i]), st->draw_time); } st->draw_time++; - XFlush(MI_DISPLAY(mi)); - MI_PAUSE(mi) = 60000; st->stage++; + st->busyLoop = 0; break; case 2: - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + if (++st->busyLoop > 6) { + st->stage++; + st->busyLoop = 0; + } + break; + case 3: + MI_IS_DRAWN(mi) = False; + MI_CLEARWINDOW(mi); + MI_IS_DRAWN(mi) = True; + if (storm_active(st)) st->stage = 1; else st->stage++; break; - case 3: - MI_PAUSE(mi) = 1000000; + case 4: + if (++st->busyLoop > 100) { + st->busyLoop = 0; + } init_lightning(mi); break; } @@ -569,7 +599,7 @@ release_lightning(ModeInfo * mi) { if (Helga != NULL) { (void) free((void *) Helga); - Helga = NULL; + Helga = (Storm *) NULL; } } @@ -578,3 +608,5 @@ refresh_lightning(ModeInfo * mi) { /* Do nothing, it will refresh by itself */ } + +#endif /* MODE_lightning */ diff --git a/hacks/link_axp.com b/hacks/link_axp.com index 2de66901..203affc2 100644 --- a/hacks/link_axp.com +++ b/hacks/link_axp.com @@ -23,7 +23,7 @@ $ link/exe=grav.exe screenhack-xlock,grav,xlockmore,vms_axp_12.opt/opt $ link/exe=greynetic screenhack,greynetic,vms_axp_12.opt/opt $ link/exe=halo.exe screenhack,halo,vms_axp_12.opt/opt $ link/exe=helix.exe screenhack,helix,vms_axp_12.opt/opt -$ link/exe=hopalong.exe screenhack-xlock,hopalong,xlockmore,vms_axp_12.opt/opt +$ link/exe=hop.exe screenhack-xlock,hop,xlockmore,vms_axp_12.opt/opt $ link/exe=hypercube.exe screenhack,hypercube,vms_axp_12.opt/opt $ link/exe=ifs.exe screenhack-xlock,ifs,xlockmore,vms_axp_12.opt/opt $ link/exe=imsmap.exe screenhack,imsmap,vms_axp_12.opt/opt @@ -74,7 +74,7 @@ $ link/exe=grav.exe screenhack-xlock,grav,xlockmore,vms_axp.opt/opt $ link/exe=greynetic screenhack,greynetic,vms_axp.opt/opt $ link/exe=halo.exe screenhack,halo,vms_axp.opt/opt $ link/exe=helix.exe screenhack,helix,vms_axp.opt/opt -$ link/exe=hopalong.exe screenhack-xlock,hopalong,xlockmore,vms_axp.opt/opt +$ link/exe=hop.exe screenhack-xlock,hop,xlockmore,vms_axp.opt/opt $ link/exe=hypercube.exe screenhack,hypercube,vms_axp.opt/opt $ link/exe=ifs.exe screenhack-xlock,ifs,xlockmore,vms_axp.opt/opt $ link/exe=imsmap.exe screenhack,imsmap,vms_axp.opt/opt diff --git a/hacks/link_decc.com b/hacks/link_decc.com index 50bda20f..15ccb75a 100644 --- a/hacks/link_decc.com +++ b/hacks/link_decc.com @@ -23,7 +23,7 @@ $ link/exe=grav.exe screenhack-xlock,grav,xlockmore,vms_decc_12.opt/opt $ link/exe=greynetic screenhack,greynetic,vms_decc_12.opt/opt $ link/exe=halo.exe screenhack,halo,vms_decc_12.opt/opt $ link/exe=helix.exe screenhack,helix,vms_decc_12.opt/opt -$ link/exe=hopalong.exe screenhack-xlock,hopalong,xlockmore,vms_decc_12.opt/opt +$ link/exe=hop.exe screenhack-xlock,hop,xlockmore,vms_decc_12.opt/opt $ link/exe=hypercube.exe screenhack,hypercube,vms_decc_12.opt/opt $ link/exe=ifs.exe screenhack-xlock,ifs,xlockmore,vms_decc_12.opt/opt $ link/exe=imsmap.exe screenhack,imsmap,vms_decc_12.opt/opt @@ -74,7 +74,7 @@ $ link/exe=grav.exe screenhack-xlock,grav,xlockmore,vms_decc.opt/opt $ link/exe=greynetic screenhack,greynetic,vms_decc.opt/opt $ link/exe=halo.exe screenhack,halo,vms_decc.opt/opt $ link/exe=helix.exe screenhack,helix,vms_decc.opt/opt -$ link/exe=hopalong.exe screenhack-xlock,hopalong,xlockmore,vms_decc.opt/opt +$ link/exe=hop.exe screenhack-xlock,hop,xlockmore,vms_decc.opt/opt $ link/exe=hypercube.exe screenhack,hypercube,vms_decc.opt/opt $ link/exe=ifs.exe screenhack-xlock,ifs,xlockmore,vms_decc.opt/opt $ link/exe=imsmap.exe screenhack,imsmap,vms_decc.opt/opt diff --git a/hacks/lisa.c b/hacks/lisa.c index af680ea2..63d7d837 100644 --- a/hacks/lisa.c +++ b/hacks/lisa.c @@ -2,10 +2,12 @@ /* lisa --- animated full-loop lisajous figures */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)lisa.c 4.04 97/07/28 xlockmore"; +static const char sccsid[] = "@(#)lisa.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1997 by Caleb Cullen. +/*- + * Copyright (c) 1997 by Caleb Cullen. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,9 +22,10 @@ static const char sccsid[] = "@(#)lisa.c 4.04 97/07/28 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: Compatible with xscreensaver + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver * - * The inspiration for this program, Lasp, was written by Adam B. Roach + * The inspiration for this program, Lasp, was written by Adam B. Roach * in 1990, assisted by me, Caleb Cullen. It was written first in C, then * in assembly, and used pre-calculated data tables to graph lisajous * figures on 386 machines and lower. This version bears only superficial @@ -34,46 +37,57 @@ static const char sccsid[] = "@(#)lisa.c 4.04 97/07/28 xlockmore"; */ #ifdef STANDALONE -# define PROGCLASS "Lisa" -# define HACK_INIT init_lisa -# define HACK_DRAW draw_lisa -# define lisa_opts xlockmore_opts -# define DEFAULTS "*delay: 25000 \n" \ - "*count: 1 \n" \ - "*cycles: 256 \n" \ - "*size: -1 \n" \ - "*ncolors: 200 \n" -# define UNIFORM_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ - void refresh_lisa(ModeInfo * mi); - void change_lisa(ModeInfo * mi); -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ +#define MODE_lisa +#define PROGCLASS "Lisa" +#define HACK_INIT init_lisa +#define HACK_DRAW draw_lisa +#define lisa_opts xlockmore_opts +#define DEFAULTS "*delay: 25000 \n" \ + "*count: 1 \n" \ + "*cycles: 256 \n" \ + "*size: -1 \n" \ + "*ncolors: 200 \n" +#define UNIFORM_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ + +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ + +#endif /* STANDALONE */ + +#ifdef MODE_lisa #define DEF_ADDITIVE "True" static Bool additive; -static XrmOptionDescRec lisa_xrm_opts[] = +static XrmOptionDescRec opts[] = { - {"-additive", ".lisa.additive", XrmoptionNoArg, (caddr_t) "True"}, - {"+additive", ".lisa.additive", XrmoptionNoArg, (caddr_t) "False"} + {(char *) "-additive", (char *) ".lisa.additive", XrmoptionNoArg, (caddr_t) "True"}, + {(char *) "+additive", (char *) ".lisa.additive", XrmoptionNoArg, (caddr_t) "False"} }; -static argtype lisa_vars[] = +static argtype vars[] = { - {(caddr_t *) & additive, "additive", "Additive", DEF_ADDITIVE, t_Bool} + {(caddr_t *) & additive, (char *) "additive", (char *) "Additive", (char *) DEF_ADDITIVE, t_Bool} }; -static OptionStruct lisa_vars_desc[] = +static OptionStruct desc[] = { - {"-/+additive", "turn on/off additive functions mode"} + {(char *) "-/+additive", (char *) "turn on/off additive functions mode"} }; ModeSpecOpt lisa_opts = -{2, lisa_xrm_opts, 1, lisa_vars, lisa_vars_desc}; +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct lisa_description = +{"lisa", "init_lisa", "draw_lisa", "release_lisa", + "refresh_lisa", "change_lisa", (char *) NULL, &lisa_opts, + 25000, 1, 256, -1, 64, 1.0, "", + "Shows animated lisajous loops", 0, NULL}; +#endif #define DRAWLINES 1 #define TWOLOOPS 1 @@ -82,12 +96,12 @@ ModeSpecOpt lisa_opts = #define LISAMAXFUNCS 2 #define NUMSTDFUNCS 10 #define MAXCYCLES 3 -#define MINLISAS 1 +#define MINLISAS 1 #define lisasetcolor() \ if (MI_NPIXELS(mi) > 2) { \ XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_PIXEL(mi, loop->color)); \ - if (++(loop->color) >= MI_NPIXELS(mi)) { loop->color=0; } \ - } else { XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_WHITE_PIXEL(mi)); } + if (++(loop->color) >= (unsigned) MI_NPIXELS(mi)) { loop->color=0; } \ + } else { XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); } #define getRadius(context) \ ((context->width > context->height)?context->height:context->width) * 3 / 8 #define checkRadius(loop, context) \ @@ -105,19 +119,22 @@ typedef struct lisafunc_struct { } lisafuncs; typedef struct lisa_struct { - int radius, color, dx, dy, nsteps, nfuncs, melting; + unsigned long color; + int radius, dx, dy, nsteps, nfuncs, melting; double pistep, phi, theta; XPoint center, *lastpoint; lisafuncs *function[LISAMAXFUNCS]; + int linewidth; } lisas; typedef struct lisacontext_struct { lisas *lisajous; int width, height, nlisajous, loopcount; int maxcycles; + Bool painted; } lisacons; -static lisacons *Lisa = NULL; +static lisacons *Lisa = (lisacons *) NULL; static lisafuncs Function[NUMSTDFUNCS] = { @@ -154,6 +171,20 @@ static lisafuncs Function[NUMSTDFUNCS] = }; static void +free_lisa(lisacons *lc) +{ + while (lc->lisajous) { + int lctr; + + for (lctr = 0; lctr < lc->nlisajous; lctr++) { + (void) free((void *) lc->lisajous[lctr].lastpoint); + } + (void) free((void *) lc->lisajous); + lc->lisajous = (lisas *) NULL; + } +} + +static Bool drawlisa(ModeInfo * mi, lisas * loop) { XPoint *np; @@ -165,7 +196,10 @@ drawlisa(ModeInfo * mi, lisas * loop) double xprod, yprod, xsum, ysum; /* Allocate the np array */ - np = (XPoint *) calloc(loop->nsteps, sizeof (XPoint)); + if ((np = (XPoint *) calloc(loop->nsteps, sizeof (XPoint))) == NULL) { + free_lisa(lc); + return False; + } /* Update the center */ loop->center.x += loop->dx; @@ -204,42 +238,31 @@ drawlisa(ModeInfo * mi, lisas * loop) yprod += sin(lf[fctr]->ycoeff[yctr] * loop->phi); if (loop->melting) { if (fctr) { - xsum += xprod \ - *(double) (loop->nsteps - loop->melting) \ - /(double) loop->nsteps; - ysum += yprod \ - *(double) (loop->nsteps - loop->melting) \ - /(double) loop->nsteps; + xsum += xprod * (double) (loop->nsteps - loop->melting) / + (double) loop->nsteps; + ysum += yprod * (double) (loop->nsteps - loop->melting) / + (double) loop->nsteps; } else { - xsum += xprod \ - *(double) loop->melting \ - /(double) loop->nsteps; - ysum += yprod \ - *(double) loop->melting \ - /(double) loop->nsteps; + xsum += xprod * (double) loop->melting / (double) loop->nsteps; + ysum += yprod * (double) loop->melting / (double) loop->nsteps; } } else { xsum = xprod; ysum = yprod; } if (!fctr) { - xsum = xsum \ - *(double) loop->radius \ - /(double) lf[fctr]->nx; - ysum = ysum \ - *(double) loop->radius \ - /(double) lf[fctr]->ny; + xsum = xsum * (double) loop->radius / (double) lf[fctr]->nx; + ysum = ysum * (double) loop->radius / (double) lf[fctr]->ny; } } else { if (loop->melting) { if (fctr) { - yprod = xprod = (double) loop->radius \ - *(double) (loop->nsteps - loop->melting) \ - /(double) (loop->nsteps); + yprod = xprod = (double) loop->radius * + (double) (loop->nsteps - loop->melting) / + (double) (loop->nsteps); } else { - yprod = xprod = (double) loop->radius \ - *(double) (loop->melting) \ - /(double) (loop->nsteps); + yprod = xprod = (double) loop->radius * + (double) (loop->melting) / (double) (loop->nsteps); } } else { xprod = yprod = (double) loop->radius; @@ -271,40 +294,45 @@ drawlisa(ModeInfo * mi, lisas * loop) for (pctr = 0; pctr < loop->nsteps; pctr++) { #if defined DRAWLINES + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), loop->linewidth, + LineSolid, CapProjecting, JoinMiter); /* erase the last cycle's point */ - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi)); - XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), \ - MI_GC(mi), lp[pctr].x, lp[pctr].y, \ - lp[(pctr + 1) % loop->nsteps].x, \ + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), + MI_GC(mi), lp[pctr].x, lp[pctr].y, + lp[(pctr + 1) % loop->nsteps].x, lp[(pctr + 1) % loop->nsteps].y); /* Set the new color */ lisasetcolor(); /* plot this cycle's point */ - XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), \ - MI_GC(mi), np[pctr].x, np[pctr].y, \ - np[(pctr + 1) % loop->nsteps].x, \ + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), + MI_GC(mi), np[pctr].x, np[pctr].y, + np[(pctr + 1) % loop->nsteps].x, np[(pctr + 1) % loop->nsteps].y); + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 1, + LineSolid, CapProjecting, JoinMiter); #else /* erase the last cycle's point */ - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi)); - XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), \ + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), lp[pctr].x, lp[pctr].y); /* Set the new color */ lisasetcolor(); /* plot this cycle's point */ - XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), \ + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), np[pctr].x, np[pctr].y); #endif } (void) free((void *) lp); loop->lastpoint = np; + return True; } -static void +static Bool initlisa(ModeInfo * mi, lisas * loop) { lisacons *lc = &Lisa[MI_SCREEN(mi)]; @@ -316,7 +344,7 @@ initlisa(ModeInfo * mi, lisas * loop) if (MI_NPIXELS(mi) > 2) { loop->color = 0; } else - loop->color = MI_WIN_WHITE_PIXEL(mi); + loop->color = MI_WHITE_PIXEL(mi); loop->nsteps = MI_CYCLES(mi); if (loop->nsteps == 0) loop->nsteps = 1; @@ -326,7 +354,7 @@ initlisa(ModeInfo * mi, lisas * loop) loop->pistep = 2.0 * M_PI / (double) loop->nsteps; loop->center.x = lc->width / 2; loop->center.y = lc->height / 2; - loop->radius = MI_SIZE(mi); + loop->radius = (int) MI_SIZE(mi); checkRadius(loop, lc); loop->dx = NRAND(XVMAX); loop->dy = NRAND(YVMAX); @@ -334,8 +362,10 @@ initlisa(ModeInfo * mi, lisas * loop) loop->dy++; lf[0] = &Function[lc->loopcount % NUMSTDFUNCS]; if ((lp = loop->lastpoint = (XPoint *) - calloc(loop->nsteps, sizeof (XPoint))) == NULL) - return; + calloc(loop->nsteps, sizeof (XPoint))) == NULL) { + free_lisa(lc); + return False; + } phase = lc->loopcount % loop->nsteps; for (pctr = 0; pctr < loop->nsteps; pctr++) { @@ -364,122 +394,156 @@ initlisa(ModeInfo * mi, lisas * loop) lp[pctr].x = (int) ceil(xsum); lp[pctr].y = (int) ceil(ysum); } +#if defined DRAWLINES + { + loop->linewidth = -8; /* #### make this a resource */ + + if (loop->linewidth == 0) + loop->linewidth = 1; + if (loop->linewidth < 0) + loop->linewidth = NRAND(-loop->linewidth) + 1; + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), loop->linewidth, + LineSolid, CapProjecting, JoinMiter); + } +#endif for (pctr = 0; pctr < loop->nsteps; pctr++) { /* Set the color */ lisasetcolor(); #if defined DRAWLINES - XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), \ - MI_GC(mi), lp[pctr].x, lp[pctr].y, \ - lp[(pctr + 1) % loop->nsteps].x, \ + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), + MI_GC(mi), lp[pctr].x, lp[pctr].y, + lp[(pctr + 1) % loop->nsteps].x, lp[(pctr + 1) % loop->nsteps].y); #else - XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), \ + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), lp[pctr].x, lp[pctr].y); #endif } +#if defined DRAWLINES + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 1, + LineSolid, CapProjecting, JoinMiter); +#endif + return True; +} - { - int line_width = -15; /* #### make this a resource */ - if (line_width == 0) - line_width = -8; - if (line_width < 0) - line_width = NRAND(-line_width)+1; - XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), line_width, - LineSolid, CapProjecting, JoinMiter); +static void +refreshlisa(ModeInfo * mi) +{ + lisacons *lc = &Lisa[MI_SCREEN(mi)]; + int lctr; + + for (lctr = 0; lctr < lc->nlisajous; lctr++) { + if (!drawlisa(mi, &lc->lisajous[lctr])) + return; } } void -init_lisa(ModeInfo * mi) +refresh_lisa(ModeInfo * mi) { lisacons *lc; + + if (Lisa == NULL) + return; + lc = &Lisa[MI_SCREEN(mi)]; + if (lc->lisajous == NULL) + return; + + if (lc->painted) { + lc->painted = False; + MI_CLEARWINDOW(mi); + refreshlisa(mi); + } +} + +void +change_lisa(ModeInfo * mi) +{ + lisas *loop; + int lctr; + lisacons *lc; + + if (Lisa == NULL) + return; + lc = &Lisa[MI_SCREEN(mi)]; + if (lc->lisajous == NULL) + return; + + lc->loopcount = 0; + for (lctr = 0; lctr < lc->nlisajous; lctr++) { + loop = &lc->lisajous[lctr]; + loop->function[1] = &Function[(loop->function[0]->index + 1) % + NUMSTDFUNCS]; + loop->melting = loop->nsteps - 1; + loop->nfuncs = 2; + } +} + +void +init_lisa(ModeInfo * mi) +{ int lctr; + lisacons *lc; if (Lisa == NULL) { - if ((Lisa = (lisacons *) calloc(MI_NUM_SCREENS(mi), sizeof (lisacons))) \ - == NULL) + if ((Lisa = (lisacons *) calloc(MI_NUM_SCREENS(mi), + sizeof (lisacons))) == NULL) return; } lc = &Lisa[MI_SCREEN(mi)]; - lc->width = MI_WIN_WIDTH(mi); - lc->height = MI_WIN_HEIGHT(mi); + lc->width = MI_WIDTH(mi); + lc->height = MI_HEIGHT(mi); lc->loopcount = 0; - lc->nlisajous = MI_BATCHCOUNT(mi); + lc->nlisajous = MI_COUNT(mi); if (lc->nlisajous <= 0) lc->nlisajous = 1; + MI_CLEARWINDOW(mi); + lc->painted = False; if (lc->lisajous == NULL) { - if ((lc->lisajous = (lisas *) calloc(lc->nlisajous, sizeof (lisas))) \ - == NULL) + if ((lc->lisajous = (lisas *) calloc(lc->nlisajous, + sizeof (lisas))) == NULL) return; - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); for (lctr = 0; lctr < lc->nlisajous; lctr++) { - initlisa(mi, &lc->lisajous[lctr]); + if (!initlisa(mi, &lc->lisajous[lctr])) + return; lc->loopcount++; } } else { - refresh_lisa(mi); + refreshlisa(mi); } - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); } void draw_lisa(ModeInfo * mi) { - lisacons *lc = &Lisa[MI_SCREEN(mi)]; + lisacons *lc; + if (Lisa == NULL) + return; + lc = &Lisa[MI_SCREEN(mi)]; + if (lc->lisajous == NULL) + return; + + MI_IS_DRAWN(mi) = True; + lc->painted = True; if (++lc->loopcount > lc->maxcycles) { change_lisa(mi); } - refresh_lisa(mi); -} - -void -refresh_lisa(ModeInfo * mi) -{ - lisacons *lc = &Lisa[MI_SCREEN(mi)]; - int lctr; - - for (lctr = 0; lctr < lc->nlisajous; lctr++) { - drawlisa(mi, &lc->lisajous[lctr]); - } + refreshlisa(mi); } void release_lisa(ModeInfo * mi) { - lisacons *lc; - int lctr, sctr; - if (Lisa) { - for (sctr = 0; sctr < MI_NUM_SCREENS(mi); sctr++) { - lc = &Lisa[sctr]; - while (lc->lisajous) { - for (lctr = 0; lctr < lc->nlisajous; lctr++) { - (void) free(lc->lisajous[lctr].lastpoint); - } - (void) free(lc->lisajous); - lc->lisajous = NULL; - } - } + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_lisa(&Lisa[screen]); (void) free(Lisa); - Lisa = NULL; + Lisa = (lisacons *) NULL; } } -void -change_lisa(ModeInfo * mi) -{ - lisacons *lc = &Lisa[MI_SCREEN(mi)]; - lisas *loop; - int lctr; - - lc->loopcount = 0; - for (lctr = 0; lctr < lc->nlisajous; lctr++) { - loop = &lc->lisajous[lctr]; - loop->function[1] = &Function[(loop->function[0]->index + 1) % - NUMSTDFUNCS]; - loop->melting = loop->nsteps - 1; - loop->nfuncs = 2; - } -} +#endif /* MODE_lisa */ diff --git a/hacks/lissie.c b/hacks/lissie.c index 2a8fafac..1f2e7c15 100644 --- a/hacks/lissie.c +++ b/hacks/lissie.c @@ -2,7 +2,8 @@ /* lissie --- the Lissajous worm */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)lissie.c 4.04 97/07/28 xlockmore"; +static const char sccsid[] = "@(#)lissie.c 5.00 2000/11/01 xlockmore"; + #endif /*- @@ -24,29 +25,42 @@ static const char sccsid[] = "@(#)lissie.c 4.04 97/07/28 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: Compatible with xscreensaver - * 18-Aug-96: added refresh-hook. - * 01-May-96: written. + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 18-Aug-1996: added refresh-hook. + * 01-May-1996: written. */ #ifdef STANDALONE -# define PROGCLASS "Lissie" -# define HACK_INIT init_lissie -# define HACK_DRAW draw_lissie -# define lissie_opts xlockmore_opts -# define DEFAULTS "*delay: 10000 \n" \ - "*count: 1 \n" \ - "*cycles: 2000 \n" \ - "*size: -200 \n" \ - "*ncolors: 64 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* in xscreensaver distribution */ +#define MODE_lissie +#define PROGCLASS "Lissie" +#define HACK_INIT init_lissie +#define HACK_DRAW draw_lissie +#define lissie_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 1 \n" \ + "*cycles: 20000 \n" \ + "*size: -200 \n" \ + "*ncolors: 200 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ -# include "xlock.h" /* in xlockmore distribution */ +#include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ +#ifdef MODE_lissie + ModeSpecOpt lissie_opts = -{0, NULL, 0, NULL, NULL}; +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct lissie_description = +{"lissie", "init_lissie", "draw_lissie", "release_lissie", + "refresh_lissie", "init_lissie", (char *) NULL, &lissie_opts, + 10000, 1, 2000, -200, 64, 0.6, "", + "Shows lissajous worms", 0, NULL}; + +#endif #define MINSIZE 1 @@ -81,17 +95,18 @@ typedef struct { int xi, yi, ri, rx, ry, len, pos; int redrawing, redrawpos; XPoint loc[MAXLISSIELEN]; - int color; + unsigned long color; } lissiestruct; typedef struct { + Bool painted; int width, height; int nlissies; lissiestruct *lissie; int loopcount; } lissstruct; -static lissstruct *lisses = NULL; +static lissstruct *lisses = (lissstruct *) NULL; static void @@ -127,16 +142,16 @@ drawlissie(ModeInfo * mi, lissiestruct * lissie) lissie->loc[p].y = lissie->yi + (int) (sin(lissie->ty) * lissie->ry); /* Mask */ - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); Lissie(oldp); /* Redraw */ if (MI_NPIXELS(mi) > 2) { XSetForeground(display, gc, MI_PIXEL(mi, lissie->color)); - if (++lissie->color >= MI_NPIXELS(mi)) + if (++lissie->color >= (unsigned) MI_NPIXELS(mi)) lissie->color = 0; } else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); Lissie(p); if (lissie->redrawing) { int i; @@ -165,7 +180,7 @@ initlissie(ModeInfo * mi, lissiestruct * lissie) if (MI_NPIXELS(mi) > 2) lissie->color = NRAND(MI_NPIXELS(mi)); else - lissie->color = MI_WIN_WHITE_PIXEL(mi); + lissie->color = MI_WHITE_PIXEL(mi); /* Initialize parameters */ if (size < -MINSIZE) lissie->ri = NRAND(MIN(-size, MAX(MINSIZE, @@ -214,14 +229,14 @@ init_lissie(ModeInfo * mi) } lp = &lisses[MI_SCREEN(mi)]; - lp->width = MI_WIN_WIDTH(mi); - lp->height = MI_WIN_HEIGHT(mi); + lp->width = MI_WIDTH(mi); + lp->height = MI_HEIGHT(mi); - lp->nlissies = MI_BATCHCOUNT(mi); + lp->nlissies = MI_COUNT(mi); if (lp->nlissies < -MINLISSIES) { if (lp->lissie) { (void) free((void *) lp->lissie); - lp->lissie = NULL; + lp->lissie = (lissiestruct *) NULL; } lp->nlissies = NRAND(-lp->nlissies - MINLISSIES + 1) + MINLISSIES; } else if (lp->nlissies < MINLISSIES) @@ -229,9 +244,14 @@ init_lissie(ModeInfo * mi) lp->loopcount = 0; - if (!lp->lissie) - lp->lissie = (lissiestruct *) calloc(lp->nlissies, sizeof (lissiestruct)); - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + if (lp->lissie == NULL) + if ((lp->lissie = (lissiestruct *) calloc(lp->nlissies, + sizeof (lissiestruct))) == NULL) + return; + + MI_CLEARWINDOW(mi); + lp->painted = False; + for (ball = 0; ball < (unsigned char) lp->nlissies; ball++) initlissie(mi, &lp->lissie[ball]); @@ -240,14 +260,24 @@ init_lissie(ModeInfo * mi) void draw_lissie(ModeInfo * mi) { - lissstruct *lp = &lisses[MI_SCREEN(mi)]; register unsigned char ball; + lissstruct *lp; + + if (lisses == NULL) + return; + lp = &lisses[MI_SCREEN(mi)]; + if (lp->lissie == NULL) + return; + + MI_IS_DRAWN(mi) = True; - if (++lp->loopcount > MI_CYCLES(mi)) + if (++lp->loopcount > MI_CYCLES(mi)) { init_lissie(mi); - else + } else { + lp->painted = True; for (ball = 0; ball < (unsigned char) lp->nlissies; ball++) drawlissie(mi, &lp->lissie[ball]); + } } void @@ -259,26 +289,35 @@ release_lissie(ModeInfo * mi) for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { lissstruct *lp = &lisses[screen]; - if (lp->lissie) { + if (lp->lissie != NULL) { (void) free((void *) lp->lissie); - lp->lissie = NULL; + /* lp->lissie = NULL; */ } } (void) free((void *) lisses); - lisses = NULL; + lisses = (lissstruct *) NULL; } } void refresh_lissie(ModeInfo * mi) { - if (lisses != NULL) { - lissstruct *lp = &lisses[MI_SCREEN(mi)]; - int i; + int i; + lissstruct *lp; + if (lisses == NULL) + return; + lp = &lisses[MI_SCREEN(mi)]; + if (lp->lissie == NULL) + return; + + if (lp->painted) { + MI_CLEARWINDOW(mi); for (i = 0; i < lp->nlissies; i++) { lp->lissie[i].redrawing = 1; lp->lissie[i].redrawpos = 0; } } } + +#endif /* MODE_lissie */ diff --git a/hacks/loop.c b/hacks/loop.c index c7280eaa..04419801 100644 --- a/hacks/loop.c +++ b/hacks/loop.c @@ -2,7 +2,7 @@ /* loop --- Chris Langton's self-producing loops */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)loop.c 4.13 98/10/18 xlockmore"; +static const char sccsid[] = "@(#)loop.c 5.01 2000/03/15 xlockmore"; #endif @@ -22,20 +22,35 @@ static const char sccsid[] = "@(#)loop.c 4.13 98/10/18 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 18-Oct-98: Started creating a hexagon version, probably will not work - * for a while since some work has to go into getting not - * only the program to handle the hexagonal data but the loop - * has to be "programmed" as well. I suspect it should be easier - * than the original since the loop will have six sides to - * store its genes (data). - * 10-May-97: Compatible with xscreensaver - * 15-Nov-95: Coded from Chris Langton's Self-Reproduction in Cellular - * Automata Physica 10D 135-144 1984 - * also used wire.c as a guide. + * 15-Mar-2001: Added some flaws, random blue wall spots, to liven it up. + * This mod seems to expose a bug where hexagons are erased + * for no apparent reason. + * 01-Nov-2000: Allocation checks + * 16-Jun-2000: Fully coded the hexagonal rules. (Rules that end up in + * state zero were not bothered with since a calloc was used + * to set non-explicit rules to zero. This allows the + * compile-time option RAND_RULES to work here (at least to + * generation 540).) + * Also added compile-time option DELAYDEBUGLOOP for debugging + * life form. This also turns off the random initial direction + * of the loop. Set DELAYDEBUGLOOP to be 10 and use with + * something like this: + * xlock -mode loop -neighbors 6 -size 5 -delay 1 -count 540 -nolock + * 18-Oct-1998: Started creating a hexagon version. + * It proved not that difficult because I used Langton's Loop + * as a guide, hexagons have more neighbors so there is more + * freedom to program, and the loop will has six sides to + * store its genes (data). + * (Soon after this a triangular version with neighbors = 6 + * was attempted but was unsuccessful). + * 10-May-1997: Compatible with xscreensaver + * 15-Nov-1995: Coded from Chris Langton's Self-Reproduction in Cellular + * Automata Physica 10D 135-144 1984, also used wire.c as a + * guide. */ /*- - Grid Number of Neigbors + Grid Number of Neighbors ---- ------------------ Square 4 Hexagon 6 (currently in development) @@ -59,54 +74,84 @@ static const char sccsid[] = "@(#)loop.c 4.13 98/10/18 xlockmore"; machine is not contained in the loop. This is a simplification of von Neumann and Codd's self-producing Turing machine. The data spinning around could be viewed as both its DNA and its internal - clock. + clock. The program can be initalized to have the loop spin both ways... + but only one way around will work for a given rule. An open question (at + least to me): Is handedness a requirement for (artificial) life? Here + there is handedness at both the initial condition and the transition rule. */ #ifdef STANDALONE -# define PROGCLASS "loop" -# define HACK_INIT init_loop -# define HACK_DRAW draw_loop -# define loop_opts xlockmore_opts -# define DEFAULTS "*delay: 100000 \n" \ - "*cycles: 1600 \n" \ - "*size: -12 \n" \ - "*ncolors: 15 \n" \ - "*neighbors: 0 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* in xscreensaver distribution */ +#define MODE_loop +#define PROGCLASS "loop" +#define HACK_INIT init_loop +#define HACK_DRAW draw_loop +#define loop_opts xlockmore_opts +#define DEFAULTS "*delay: 100000 \n" \ + "*count: -5 \n" \ + "*cycles: 1600 \n" \ + "*size: -12 \n" \ + "*ncolors: 15 \n" \ + "*neighbors: 0 \n" +#define UNIFORM_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ -# include "xlock.h" /* in xlockmore distribution */ +#include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ - #include "automata.h" +#ifdef MODE_loop + /*- * neighbors of 0 randomizes between 4 and 6. */ -#ifdef STANDALONE -static int neighbors; -#else -extern int neighbors; -#endif /* !STANDALONE */ +#define DEF_NEIGHBORS "0" /* choose random value */ + +static int neighbors; + +static XrmOptionDescRec opts[] = +{ + {(char *) "-neighbors", (char *) ".loop.neighbors", XrmoptionSepArg, (caddr_t) NULL} +}; + +static argtype vars[] = +{ + {(caddr_t *) & neighbors, (char *) "neighbors", (char *) "Neighbors", (char *) DEF_NEIGHBORS, t_Int} +}; + +static OptionStruct desc[] = +{ + {(char *) "-neighbors num", (char *) "squares 4 or hexagons 6"} +}; ModeSpecOpt loop_opts = -{0, NULL, 0, NULL, NULL}; +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; + #ifdef USE_MODULES ModStruct loop_description = {"loop", "init_loop", "draw_loop", "release_loop", - "refresh_loop", "init_loop", NULL, &loop_opts, - 100000, 1, 1600, -12, 64, 1.0, "", + "refresh_loop", "init_loop", (char *) NULL, &loop_opts, + 100000, 5, 1600, -12, 64, 1.0, "", "Shows Langton's self-producing loops", 0, NULL}; #endif #define LOOPBITS(n,w,h)\ - lp->pixmaps[lp->init_bits++]=\ - XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1) + if ((lp->pixmaps[lp->init_bits]=\ + XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1))==None){\ + free_loop(display,lp); return;} else {lp->init_bits++;} static int local_neighbors = 0; -static int neighbor_kind = 0; + +#if 0 +/* Used to fast forward to troubled generations, mainly used for debugging. + -delay 1 -count 170 -neighbors 6 # divisions starts + 540 first cell collision + 1111 mutant being born from 2 parents + 1156 mutant born + */ +#define DELAYDEBUGLOOP 10 +#endif #define COLORS 8 #define REALCOLORS (COLORS-2) @@ -114,33 +159,35 @@ static int neighbor_kind = 0; #define REDRAWSTEP 2000 /* How many cells to draw per cycle */ #define ADAM_SIZE 8 /* MIN 5 */ #if 1 -# define ADAM_LOOPX (ADAM_SIZE+2) -# define ADAM_LOOPY (ADAM_SIZE+2) +#define ADAM_LOOPX (ADAM_SIZE+2) +#define ADAM_LOOPY (ADAM_SIZE+2) #else -# define ADAM_LOOPX 16 -# define ADAM_LOOPY 10 +#define ADAM_LOOPX 16 +#define ADAM_LOOPY 10 #endif #define MINGRIDSIZE (3*ADAM_LOOPX) +#if 0 /* TRIA stuff was an attempt to make a triangular lifeform on a - hex grid but I got bored. You probably need an additional 7th - state for a coherent step by step process of separation and + hexagonal grid but I got bored. You may need an additional 7th + state for a coherent step by step process of cell separation and initial stem development. */ -/* #define TRIA 1 */ +#define TRIA 1 +#endif #ifdef TRIA -# define HEX_ADAM_SIZE 3 /* MIN 3 */ +#define HEX_ADAM_SIZE 3 /* MIN 3 */ #else -# define HEX_ADAM_SIZE 5 /* MIN 3 */ +#define HEX_ADAM_SIZE 5 /* MIN 3 */ #endif #if 1 -# define HEX_ADAM_LOOPX (2*HEX_ADAM_SIZE+1) -# define HEX_ADAM_LOOPY (2*HEX_ADAM_SIZE+1) +#define HEX_ADAM_LOOPX (2*HEX_ADAM_SIZE+1) +#define HEX_ADAM_LOOPY (2*HEX_ADAM_SIZE+1) #else -# define HEX_ADAM_LOOPX 3 -# define HEX_ADAM_LOOPY 7 +#define HEX_ADAM_LOOPX 3 +#define HEX_ADAM_LOOPY 7 #endif #define HEX_MINGRIDSIZE (6*HEX_ADAM_LOOPX) -#define MINSIZE 5 /* jwz -- really tiny cells don't look good */ +#define MINSIZE ((MI_NPIXELS(mi)>=COLORS)?1:(2+(local_neighbors==6))) #define NEIGHBORKINDS 2 #define ANGLES 360 #define MAXNEIGHBORS 6 @@ -161,6 +208,7 @@ typedef struct { int mincol, minrow, maxcol, maxrow; int width, height; int redrawing, redrawpos; + Bool dead, clockwise; unsigned char *newcells, *oldcells; int ncells[COLORS]; CellList *cellList[COLORS]; @@ -172,12 +220,22 @@ typedef struct { } shape; } loopstruct; -static loopstruct *loops = NULL; +static loopstruct *loops = (loopstruct *) NULL; #define TRANSITION(TT,V) V=TT&7;TT>>=3 +#define FINALTRANSITION(TT,V) V=TT&7 #define TABLE(R,T,L,B) (table[((B)<<9)|((L)<<6)|((T)<<3)|(R)]) #define HEX_TABLE(R,T,t,l,b,B) (table[((B)<<15)|((b)<<12)|((l)<<9)|((t)<<6)|((T)<<3)|(R)]) -#ifdef RAND_RULES /* Hack, see below */ + +#if 0 +/* Instead of setting "unused" state rules to zero it randomizes them. + These rules take over when something unexpected happens... like when a + cell hits a wall (the end of the screen). + */ +#define RAND_RULES +#endif + +#ifdef RAND_RULES #define TABLE_IN(C,R,T,L,B,I) (TABLE(R,T,L,B)&=~(7<<((C)*3)));\ (TABLE(R,T,L,B)|=((I)<<((C)*3))) #define HEX_TABLE_IN(C,R,T,t,l,b,B,I) (HEX_TABLE(R,T,t,l,b,B)&=~(7<<((C)*3)));\ @@ -189,8 +247,9 @@ static loopstruct *loops = NULL; #define TABLE_OUT(C,R,T,L,B) ((TABLE(R,T,L,B)>>((C)*3))&7) #define HEX_TABLE_OUT(C,R,T,t,l,b,B) ((HEX_TABLE(R,T,t,l,b,B)>>((C)*3))&7) -static unsigned int *table = NULL; /* 8*8*8*8 = 2^12 = 2^3^4 = 4K */ - /* 8*8*8*8*8*8 = too big? */ +static unsigned int *table = (unsigned int *) NULL; + /* square: 8*8*8*8 = 2^12 = 2^3^4 = 4096 */ + /* hexagon: 8*8*8*8*8*8 = 2^18 = 2^3^6 = 262144 = too big? */ static char plots[NEIGHBORKINDS] = { @@ -395,7 +454,7 @@ static unsigned int hex_transition_table[] = 020102022, 020202112, 000000012, 000000122, 000000212, - 010002121, + 010002121, 020001122, 020002112, 020011122, @@ -442,7 +501,7 @@ static unsigned int hex_transition_table[] = 020040422, 040002022, - + 010224224, 010222424, 010202424, 020142022, 020202412, 020011722, 020112072, 020172072, 020142072, @@ -450,7 +509,7 @@ static unsigned int hex_transition_table[] = 000210225, 000022015, 000022522, - 011225521, + 011225521, 020120525, 020020152, 020005122, 020214255, 020021152, 020255242, 050215222, 050225121, @@ -465,7 +524,7 @@ static unsigned int hex_transition_table[] = 001224251, 010022152, 010251221, 010522121, 011212151, 011221251, 011215221, - 020000220, 020002152, 020020220, 020021020, 020022152, + 020000220, 020002152, 020020220, 020022152, 020021422, 020022152, 020022522, 020025425, 020050422, 020051022, 020051122, 020211122, 020211222, 020215222, 020245122, @@ -486,7 +545,7 @@ static unsigned int hex_transition_table[] = 020021552, 012252277, 050002521, - 020005725, + 020005725, 050011022, 000000155, @@ -544,7 +603,7 @@ static unsigned int hex_transition_table[] = 020521122, 020025022, 020025522, - 020020522, + 020020522, 020202222, 020212222, @@ -557,7 +616,6 @@ static unsigned int hex_transition_table[] = 020212122, 020027222, 020024222, - 020020222, 020212722, 020212422, 020202122, @@ -569,6 +627,33 @@ static unsigned int hex_transition_table[] = 020212052, 020205052, + 070221250, + + 000000050, 000005220, 000002270, 070252220, + 000000450, 000007220, + 000220220, 000202220, 000022020, 000020220, + + 000222040, + 000220440, + 000022040, + 000040220, + + 000252220, + 050221120, 010221520, + 002222220, + + 000070220, 000220720, + 000020520, 000070250, 000222070, 000027020, + 000022070, 000202270, 000024020, 000220420, + 000220270, 000220240, 000072020, 000042020, + 000002020, 000002070, 000020270, 000020250, + 000270270, 000007020, 000040270, + + /* Collision starts (gen 540), not sure to have rules to save it + or depend on calloc to intialize remaining rules to 0 so that + the mutant will be born + */ + 000050220, #endif }; @@ -687,30 +772,26 @@ position_of_neighbor(int dir, int *pcol, int *prow) if (local_neighbors == 6) { switch (dir) { case 0: - col = col + 1; + col++; break; case 60: - if (row & 1) - col = col + 1; - row = row - 1; + col += (row & 1); + row--; break; case 120: - if (!(row & 1)) - col = col - 1; - row = row - 1; + col -= !(row & 1); + row--; break; case 180: - col = col - 1; + col--; break; case 240: - if (!(row & 1)) - col = col - 1; - row = row + 1; + col -= !(row & 1); + row++; break; case 300: - if (row & 1) - col = col + 1; - row = row + 1; + col += (row & 1); + row++; break; default: (void) fprintf(stderr, "wrong direction %d\n", dir); @@ -718,16 +799,16 @@ position_of_neighbor(int dir, int *pcol, int *prow) } else { switch (dir) { case 0: - col = col + 1; + col++; break; case 90: - row = row - 1; + row--; break; case 180: - col = col - 1; + col--; break; case 270: - row = row + 1; + row++; break; default: (void) fprintf(stderr, "wrong direction %d\n", dir); @@ -755,8 +836,8 @@ fillcell(ModeInfo * mi, GC gc, int col, int row) lp->shape.hexagon[0].x = lp->xb + ccol * lp->xs; lp->shape.hexagon[0].y = lp->yb + crow * lp->ys; if (lp->xs == 1 && lp->ys == 1) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc, - lp->shape.hexagon[0].x, lp->shape.hexagon[0].y, 1, 1); + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc, + lp->shape.hexagon[0].x, lp->shape.hexagon[0].y); else XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, lp->shape.hexagon, 6, Convex, CoordModePrevious); @@ -788,23 +869,6 @@ drawcell(ModeInfo * mi, int col, int row, int state) fillcell(mi, gc, col, row); } -static void -addtolist(ModeInfo * mi, int col, int row, unsigned char state) -{ - loopstruct *lp = &loops[MI_SCREEN(mi)]; - CellList *current = lp->cellList[state]; - - lp->cellList[state] = NULL; - if ((lp->cellList[state] = (CellList *) malloc(sizeof (CellList))) == NULL) { - lp->cellList[state] = current; - return; - } - lp->cellList[state]->pt.x = col; - lp->cellList[state]->pt.y = row; - lp->cellList[state]->next = current; - lp->ncells[state]++; -} - #ifdef DEBUG static void print_state(ModeInfo * mi, int state) @@ -838,21 +902,75 @@ free_state(loopstruct * lp, int state) } static void +free_list(loopstruct * lp) +{ + int state; + + for (state = 0; state < COLORS; state++) + free_state(lp, state); +} + +static void +free_loop(Display *display, loopstruct * lp) +{ + int shade; + + for (shade = 0; shade < lp->init_bits; shade++) + if (lp->pixmaps[shade] != None) { + XFreePixmap(display, lp->pixmaps[shade]); + lp->pixmaps[shade] = None; + } + if (lp->stippledGC != None) { + XFreeGC(display, lp->stippledGC); + lp->stippledGC = None; + } + if (lp->oldcells != NULL) { + (void) free((void *) lp->oldcells); + lp->oldcells = (unsigned char *) NULL; + } + if (lp->newcells != NULL) { + (void) free((void *) lp->newcells); + lp->newcells = (unsigned char *) NULL; + } + free_list(lp); +} + +static Bool +addtolist(ModeInfo * mi, int col, int row, unsigned char state) +{ + loopstruct *lp = &loops[MI_SCREEN(mi)]; + CellList *current = lp->cellList[state]; + + if ((lp->cellList[state] = (CellList *) malloc(sizeof (CellList))) == + NULL) { + lp->cellList[state] = current; + free_loop(MI_DISPLAY(mi), lp); + return False; + } + lp->cellList[state]->pt.x = col; + lp->cellList[state]->pt.y = row; + lp->cellList[state]->next = current; + lp->ncells[state]++; + return True; +} + +static Bool draw_state(ModeInfo * mi, int state) { loopstruct *lp = &loops[MI_SCREEN(mi)]; + Display *display = MI_DISPLAY(mi); GC gc; XGCValues gcv; CellList *current = lp->cellList[state]; if (MI_NPIXELS(mi) >= COLORS) { gc = MI_GC(mi); - XSetForeground(MI_DISPLAY(mi), gc, lp->colors[state]); + XSetForeground(display, gc, lp->colors[state]); } else { gcv.stipple = lp->pixmaps[state]; gcv.foreground = MI_WHITE_PIXEL(mi); gcv.background = MI_BLACK_PIXEL(mi); - XChangeGC(MI_DISPLAY(mi), lp->stippledGC, + XChangeGC(display, lp->stippledGC, GCStipple | GCForeground | GCBackground, &gcv); gc = lp->stippledGC; } @@ -867,21 +985,22 @@ draw_state(ModeInfo * mi, int state) lp->shape.hexagon[0].x = lp->xb + ccol * lp->xs; lp->shape.hexagon[0].y = lp->yb + crow * lp->ys; if (lp->xs == 1 && lp->ys == 1) - XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc, - lp->shape.hexagon[0].x, lp->shape.hexagon[0].y, 1, 1); + XDrawPoint(display, MI_WINDOW(mi), gc, + lp->shape.hexagon[0].x, lp->shape.hexagon[0].y); else - XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, + XFillPolygon(display, MI_WINDOW(mi), gc, lp->shape.hexagon, 6, Convex, CoordModePrevious); current = current->next; } } else { /* Take advantage of XFillRectangles */ - XRectangle *rects = NULL; + XRectangle *rects; int nrects = 0; /* Create Rectangle list from part of the cellList */ - if ((rects = (XRectangle *) malloc(lp->ncells[state] * sizeof (XRectangle))) == NULL) { - return; + if ((rects = (XRectangle *) malloc(lp->ncells[state] * + sizeof (XRectangle))) == NULL) { + return False; } while (current) { @@ -893,15 +1012,16 @@ draw_state(ModeInfo * mi, int state) nrects++; } /* Finally get to draw */ - XFillRectangles(MI_DISPLAY(mi), MI_WINDOW(mi), gc, rects, nrects); + XFillRectangles(display, MI_WINDOW(mi), gc, rects, nrects); /* Free up rects list and the appropriate part of the cellList */ (void) free((void *) rects); } free_state(lp, state); - XFlush(MI_DISPLAY(mi)); + XFlush(display); + return True; } -static int +static Bool init_table(void) { if (table == NULL) { @@ -917,16 +1037,21 @@ init_table(void) mult *= 8; if ((table = (unsigned int *) calloc(mult, sizeof (unsigned int))) == NULL) { - return 1; + return False; } + #ifdef RAND_RULES /* Here I was interested to see what happens when it hits a wall.... Rules not normally used take over... takes too much time though */ - { + /* Each state = 3 bits */ + if (MAXRAND < 16777216.0) { for (j = 0; j < mult; j++) { - for (k = 0; k < 8; k++) - table[j] |= (unsigned int) ((unsigned int) (NRAND(8)) << (k * 3)); + table[j] = (unsigned int) ((NRAND(4096) << 12) & NRAND(4096)); + } + } else { + for (j = 0; j < mult; j++) { + table[j] = (unsigned int) (NRAND(16777216)); } } #endif @@ -937,7 +1062,7 @@ init_table(void) for (k = 0; k < local_neighbors; k++) { TRANSITION(tt, n[k]); } - TRANSITION(tt, c); + FINALTRANSITION(tt, c); HEX_TABLE_IN(c, n[0], n[1], n[2], n[3], n[4], n[5], i); HEX_TABLE_IN(c, n[1], n[2], n[3], n[4], n[5], n[0], i); HEX_TABLE_IN(c, n[2], n[3], n[4], n[5], n[0], n[1], i); @@ -952,7 +1077,7 @@ init_table(void) for (k = 0; k < local_neighbors; k++) { TRANSITION(tt, n[k]); } - TRANSITION(tt, c); + FINALTRANSITION(tt, c); TABLE_IN(c, n[0], n[1], n[2], n[3], i); TABLE_IN(c, n[1], n[2], n[3], n[0], i); TABLE_IN(c, n[2], n[3], n[0], n[1], i); @@ -960,7 +1085,56 @@ init_table(void) } } } - return 0; + return True; +} + +static void +init_flaw(ModeInfo * mi) +{ + loopstruct *lp = &loops[MI_SCREEN(mi)]; + int a, b; + +#define BLUE 2 + if (lp->bncols <= 3 || lp->bnrows <= 3) + return; + a = MIN(lp->bncols - 3, 2 * ((local_neighbors == 6) ? + HEX_MINGRIDSIZE : MINGRIDSIZE)); + a = NRAND(a) + (lp->bncols - a) / 2; + b = MIN(lp->bnrows - 3, 2 * ((local_neighbors == 6) ? + HEX_MINGRIDSIZE : MINGRIDSIZE)); + b = NRAND(b) + (lp->bnrows - b) / 2; + if (lp->mincol > a) + lp->mincol = a; + if (lp->minrow > b) + lp->minrow = b; + if (lp->maxcol < a + 2) + lp->maxcol = a + 2; + if (lp->maxrow < b + 2) + lp->maxrow = b + 2; + + if (local_neighbors == 6) { + lp->newcells[b * lp->bncols + a + !(b % 2) ] = BLUE; + lp->newcells[b * lp->bncols + a + 1 + !(b % 2)] = BLUE; + lp->newcells[(b + 1) * lp->bncols + a] = BLUE; + lp->newcells[(b + 1) * lp->bncols + a + 2] = BLUE; + lp->newcells[(b + 2) * lp->bncols + a + !(b % 2)] = BLUE; + lp->newcells[(b + 2) * lp->bncols + a + 1 + !(b % 2)] = BLUE; + } else { + int orient = NRAND(4); + lp->newcells[lp->bncols * (b + 1) + a + 1] = BLUE; + if (orient == 0 || orient == 1) { + lp->newcells[lp->bncols * b + a + 1] = BLUE; + } + if (orient == 1 || orient == 2) { + lp->newcells[lp->bncols * (b + 1) + a + 2] = BLUE; + } + if (orient == 2 || orient == 3) { + lp->newcells[lp->bncols * (b + 2) + a + 1] = BLUE; + } + if (orient == 3 || orient == 0) { + lp->newcells[lp->bncols * (b + 1) + a] = BLUE; + } + } } static void @@ -968,165 +1142,232 @@ init_adam(ModeInfo * mi) { loopstruct *lp = &loops[MI_SCREEN(mi)]; XPoint start, dirx, diry; - int i, j; + int i, j, dir; - if (local_neighbors == 6) { +#ifdef DELAYDEBUGLOOP + lp->clockwise = 0; + if (!MI_COUNT(mi)) /* Probably doing testing so do not confuse */ +#endif + lp->clockwise = (Bool) (LRAND() & 1); +#ifdef DELAYDEBUGLOOP + dir = 0; + if (!MI_COUNT(mi)) /* Probably doing testing so do not confuse */ +#endif + dir = NRAND(local_neighbors); + if (local_neighbors == 6) { int k; - /* switch (0) */ - switch (NRAND(6)) { + switch (dir) { case 0: start.x = (lp->bncols - HEX_ADAM_LOOPX / 2) / 2; start.y = (lp->bnrows - HEX_ADAM_LOOPY) / 2; - lp->mincol = start.x - 2; - lp->minrow = start.y - 1; - lp->maxcol = start.x + HEX_ADAM_LOOPX + 1; - lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; + if (lp->mincol > start.x - 2) + lp->mincol = start.x - 2; + if (lp->minrow > start.y - 1) + lp->minrow = start.y - 1; + if (lp->maxcol < start.x + HEX_ADAM_LOOPX + 1) + lp->maxcol = start.x + HEX_ADAM_LOOPX + 1; + if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1) + lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; for (j = 0; j < HEX_ADAM_LOOPY; j++) { for (i = 0; i < HEX_ADAM_LOOPX; i++) { k = (((lp->bnrows / 2 + HEX_ADAM_LOOPY / 2) % 2) ? -j / 2 : -(j + 1) / 2); lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] = - hex_self_reproducing_loop[j][i]; + (lp->clockwise) ? + hex_self_reproducing_loop[i][j] : + hex_self_reproducing_loop[j][i]; } } break; case 1: start.x = (lp->bncols - (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) / 2; start.y = (lp->bnrows - HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2; - lp->mincol = start.x - 1; - lp->minrow = start.y - HEX_ADAM_LOOPX; - lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1; - lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; + if (lp->mincol > start.x - 1) + lp->mincol = start.x - 1; + if (lp->minrow > start.y - HEX_ADAM_LOOPX) + lp->minrow = start.y - HEX_ADAM_LOOPX; + if (lp->maxcol < start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1) + lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1; + if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1) + lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; for (j = 0; j < HEX_ADAM_LOOPY; j++) { for (i = 0; i < HEX_ADAM_LOOPX; i++) { k = (((lp->bnrows / 2 + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) % 2) ? -(i + j + 1) / 2 : -(i + j) / 2); lp->newcells[(start.y + j - i) * lp->bncols + start.x + i + j + k] = - hex_self_reproducing_loop[j][i]; + (lp->clockwise) ? + hex_self_reproducing_loop[i][j] : + hex_self_reproducing_loop[j][i]; } } break; case 2: start.x = (lp->bncols - HEX_ADAM_LOOPY / 2) / 2; start.y = (lp->bnrows - HEX_ADAM_LOOPX) / 2; - lp->mincol = start.x - 2; - lp->minrow = start.y - 1; - lp->maxcol = start.x + HEX_ADAM_LOOPY + 1; - lp->maxrow = start.y + HEX_ADAM_LOOPX + 1; + if (lp->mincol > start.x - 2) + lp->mincol = start.x - 2; + if (lp->minrow > start.y - 1) + lp->minrow = start.y - 1; + if (lp->maxcol < start.x + HEX_ADAM_LOOPX + 1) + lp->maxcol = start.x + HEX_ADAM_LOOPX + 1; + if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1) + lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; for (j = 0; j < HEX_ADAM_LOOPX; j++) { for (i = 0; i < HEX_ADAM_LOOPY; i++) { k = (((lp->bnrows / 2 + HEX_ADAM_LOOPX / 2) % 2) ? -(HEX_ADAM_LOOPX - j - 1) / 2 : -(HEX_ADAM_LOOPX - j) / 2); lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] = - hex_self_reproducing_loop[i][HEX_ADAM_LOOPX - j - 1]; + (lp->clockwise) ? + hex_self_reproducing_loop[j][HEX_ADAM_LOOPX - i - 1] : + hex_self_reproducing_loop[i][HEX_ADAM_LOOPY - j - 1]; } } break; case 3: start.x = (lp->bncols - HEX_ADAM_LOOPX / 2) / 2; start.y = (lp->bnrows - HEX_ADAM_LOOPY) / 2; - lp->mincol = start.x - 1, lp->minrow = start.y - 1; - lp->maxcol = start.x + HEX_ADAM_LOOPX + 1, lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; + if (lp->mincol > start.x - 1) + lp->mincol = start.x - 1; + if (lp->minrow > start.y - 1) + lp->minrow = start.y - 1; + if (lp->maxcol < start.x + HEX_ADAM_LOOPX + 1) + lp->maxcol = start.x + HEX_ADAM_LOOPX + 1; + if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1) + lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; for (j = 0; j < HEX_ADAM_LOOPY; j++) { for (i = 0; i < HEX_ADAM_LOOPX; i++) { k = (((lp->bnrows / 2 + HEX_ADAM_LOOPY / 2) % 2) ? -j / 2 : -(j + 1) / 2); lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] = - hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1]; + (lp->clockwise) ? + hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][HEX_ADAM_LOOPY - j - 1] : + hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1]; } } break; case 4: start.x = (lp->bncols - (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) / 2; start.y = (lp->bnrows - HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2; - lp->mincol = start.x - 1; - lp->minrow = start.y - HEX_ADAM_LOOPX; - lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1; - lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; + if (lp->mincol > start.x - 1) + lp->mincol = start.x - 1; + if (lp->minrow > start.y - HEX_ADAM_LOOPX) + lp->minrow = start.y - HEX_ADAM_LOOPX; + if (lp->maxcol < start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1) + lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1; + if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1) + lp->maxrow = start.y + HEX_ADAM_LOOPY + 1; for (j = 0; j < HEX_ADAM_LOOPY; j++) { for (i = 0; i < HEX_ADAM_LOOPX; i++) { k = (((lp->bnrows / 2 + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) % 2) ? -(i + j + 1) / 2 : -(i + j) / 2); lp->newcells[(start.y + j - i) * lp->bncols + start.x + i + j + k] = - hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1]; + (lp->clockwise) ? + hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][HEX_ADAM_LOOPY - j - 1] : + hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1]; } } break; case 5: start.x = (lp->bncols - HEX_ADAM_LOOPY / 2) / 2; start.y = (lp->bnrows - HEX_ADAM_LOOPX) / 2; - lp->mincol = start.x - 2; - lp->minrow = start.y - 1; - lp->maxcol = start.x + HEX_ADAM_LOOPY + 1; - lp->maxrow = start.y + HEX_ADAM_LOOPX + 1; + if (lp->mincol > start.x - 2) + lp->mincol = start.x - 2; + if (lp->minrow > start.y - 1) + lp->minrow = start.y - 1; + if (lp->maxcol < start.x + HEX_ADAM_LOOPY + 1) + lp->maxcol = start.x + HEX_ADAM_LOOPY + 1; + if (lp->maxrow < start.y + HEX_ADAM_LOOPX + 1) + lp->maxrow = start.y + HEX_ADAM_LOOPX + 1; for (j = 0; j < HEX_ADAM_LOOPX; j++) { for (i = 0; i < HEX_ADAM_LOOPY; i++) { k = (((lp->bnrows / 2 + HEX_ADAM_LOOPX / 2) % 2) ? -(HEX_ADAM_LOOPX - j - 1) / 2 : -(HEX_ADAM_LOOPX - j) / 2); lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] = - hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][j]; + (lp->clockwise) ? + hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][i] : + hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][j]; } } break; } #if DEBUGTEST - /* printf ("s %d s %d \n", start.x, start.y); */ - printf ("%d %d %d %d %d\t", + /* (void) printf ("s %d s %d \n", start.x, start.y); */ + (void) printf ("%d %d %d %d %d\n", start.x + i + ((lp->bnrows / 2 % 2) ? -j / 2 : -(j + 1) / 2) - lp->bx, start.y + j - lp->by, i, j, hex_self_reproducing_loop[j][i]); /* Draw right away */ drawcell(mi, start.x + i + ((lp->bnrows / 2 % 2) ? -j / 2 : -(j + 1) / 2) - lp->bx, start.y + j - lp->by, hex_self_reproducing_loop[j][i]); -#endif -#if DEBUGTEST - printf ("\n"); -#endif -#if DEBUGTEST - printf ("\n"); #endif } else { - switch (NRAND(4)) { + switch (dir) { case 0: start.x = (lp->bncols - ADAM_LOOPX) / 2; start.y = (lp->bnrows - ADAM_LOOPY) / 2; dirx.x = 1, dirx.y = 0; diry.x = 0, diry.y = 1; - lp->mincol = start.x, lp->minrow = start.y; - lp->maxcol = start.x + ADAM_LOOPX, lp->maxrow = start.y + ADAM_LOOPY; + if (lp->mincol > start.x) + lp->mincol = start.x; + if (lp->minrow > start.y) + lp->minrow = start.y; + if (lp->maxcol < start.x + ADAM_LOOPX) + lp->maxcol = start.x + ADAM_LOOPX; + if (lp->maxrow < start.y + ADAM_LOOPY) + lp->maxrow = start.y + ADAM_LOOPY; break; case 1: start.x = (lp->bncols + ADAM_LOOPY) / 2; start.y = (lp->bnrows - ADAM_LOOPX) / 2; dirx.x = 0, dirx.y = 1; diry.x = -1, diry.y = 0; - lp->mincol = start.x - ADAM_LOOPY, lp->minrow = start.y; - lp->maxcol = start.x, lp->maxrow = start.y + ADAM_LOOPX; + if (lp->mincol > start.x - ADAM_LOOPY) + lp->mincol = start.x - ADAM_LOOPY; + if (lp->minrow > start.y) + lp->minrow = start.y; + if (lp->maxcol < start.x) + lp->maxcol = start.x; + if (lp->maxrow < start.y + ADAM_LOOPX) + lp->maxrow = start.y + ADAM_LOOPX; break; case 2: start.x = (lp->bncols + ADAM_LOOPX) / 2; start.y = (lp->bnrows + ADAM_LOOPY) / 2; dirx.x = -1, dirx.y = 0; diry.x = 0, diry.y = -1; - lp->mincol = start.x - ADAM_LOOPX, lp->minrow = start.y - ADAM_LOOPY; - lp->maxcol = start.x, lp->maxrow = start.y; + if (lp->mincol > start.x - ADAM_LOOPX) + lp->mincol = start.x - ADAM_LOOPX; + if (lp->minrow > start.y - ADAM_LOOPY) + lp->minrow = start.y - ADAM_LOOPY; + if (lp->maxcol < start.x) + lp->maxcol = start.x; + if (lp->maxrow < start.y) + lp->maxrow = start.y; break; case 3: start.x = (lp->bncols - ADAM_LOOPY) / 2; start.y = (lp->bnrows + ADAM_LOOPX) / 2; dirx.x = 0, dirx.y = -1; diry.x = 1, diry.y = 0; - lp->mincol = start.x, lp->minrow = start.y - ADAM_LOOPX; - lp->maxcol = start.x + ADAM_LOOPY, lp->maxrow = start.y; + if (lp->mincol > start.x) + lp->mincol = start.x; + if (lp->minrow > start.y - ADAM_LOOPX) + lp->minrow = start.y - ADAM_LOOPX; + if (lp->maxcol < start.x + ADAM_LOOPX) + lp->maxcol = start.x + ADAM_LOOPX; + if (lp->maxrow < start.y) + lp->maxrow = start.y; break; } for (j = 0; j < ADAM_LOOPY; j++) for (i = 0; i < ADAM_LOOPX; i++) - lp->newcells[(start.y + dirx.y * i + diry.y * j) * lp->bncols + - start.x + dirx.x * i + diry.x * j] = - self_reproducing_loop[j][i]; + lp->newcells[lp->bncols * (start.y + dirx.y * i + diry.y * j) + + start.x + dirx.x * i + diry.x * j] = + (lp->clockwise) ? + self_reproducing_loop[j][ADAM_LOOPX - i - 1] : + self_reproducing_loop[j][i]; #if DEBUG /* Draw right away */ drawcell(mi, start.x + dirx.x * i + diry.x * j - lp->bx, start.y + dirx.y * i + diry.y * j - lp->by, - self_reproducing_loop[j][i]); + (lp->clockwise) ? self_reproducing_loop[j][ADAM_LOOPX - i - i] : self_reproducing_loop[j][i]); #endif } } @@ -1156,50 +1397,32 @@ do_gen(loopstruct * lp) } } if (local_neighbors == 6) { - *z = HEX_TABLE_OUT(c, n[0], n[1], n[2], n[3], n[4], n[5]); + *z = (lp->clockwise) ? + HEX_TABLE_OUT(c, n[5], n[4], n[3], n[2], n[1], n[0]) : + HEX_TABLE_OUT(c, n[0], n[1], n[2], n[3], n[4], n[5]); } else { - *z = TABLE_OUT(c, n[0], n[1], n[2], n[3]); + *z = (lp->clockwise) ? + TABLE_OUT(c, n[3], n[2], n[1], n[0]) : + TABLE_OUT(c, n[0], n[1], n[2], n[3]); } } } } -static void -free_list(loopstruct * lp) -{ - int state; - - for (state = 0; state < COLORS; state++) - free_state(lp, state); -} - void release_loop(ModeInfo * mi) { if (loops != NULL) { int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - loopstruct *lp = &loops[screen]; - int shade; - - for (shade = 0; shade < lp->init_bits; shade++) - if (lp->pixmaps[shade] != None) - XFreePixmap(MI_DISPLAY(mi), lp->pixmaps[shade]); - if (lp->stippledGC != None) - XFreeGC(MI_DISPLAY(mi), lp->stippledGC); - if (lp->oldcells != NULL) - (void) free((void *) lp->oldcells); - if (lp->newcells != NULL) - (void) free((void *) lp->newcells); - free_list(lp); - } + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_loop(MI_DISPLAY(mi), &loops[screen]); (void) free((void *) loops); - loops = NULL; + loops = (loopstruct *) NULL; } if (table != NULL) { (void) free((void *) table); - table = NULL; + table = (unsigned int *) NULL; } } @@ -1224,9 +1447,9 @@ init_loop(ModeInfo * mi) if ((MI_NPIXELS(mi) < COLORS) && (lp->init_bits == 0)) { if (lp->stippledGC == None) { gcv.fill_style = FillOpaqueStippled; - lp->stippledGC = XCreateGC(display, window, GCFillStyle, &gcv); - if (lp->stippledGC == None) { - release_loop(mi); + if ((lp->stippledGC = XCreateGC(display, window, + GCFillStyle, &gcv)) == None) { + free_loop(display, lp); return; } } @@ -1238,10 +1461,6 @@ init_loop(ModeInfo * mi) LOOPBITS(stipples[7], STIPPLESIZE, STIPPLESIZE); LOOPBITS(stipples[8], STIPPLESIZE, STIPPLESIZE); LOOPBITS(stipples[10], STIPPLESIZE, STIPPLESIZE); - if (lp->pixmaps[COLORS - 1] == None) { - release_loop(mi); - return; - } } if (MI_NPIXELS(mi) >= COLORS) { /* Maybe these colors should be randomized */ @@ -1259,21 +1478,17 @@ init_loop(ModeInfo * mi) lp->width = MI_WIDTH(mi); lp->height = MI_HEIGHT(mi); - if (!local_neighbors) { - for (i = 0; i < NEIGHBORKINDS; i++) { - if (neighbors == plots[i]) { - local_neighbors = neighbors; - neighbor_kind = i; - break; - } + if (!local_neighbors) { + for (i = 0; i < NEIGHBORKINDS; i++) { + if (neighbors == plots[i]) { + local_neighbors = neighbors; + break; + } if (i == NEIGHBORKINDS - 1) { - #if 1 local_neighbors = plots[NRAND(NEIGHBORKINDS)]; - neighbor_kind = (local_neighbors == 4) ? 0 : 1; #else local_neighbors = 4; - neighbor_kind = 0; #endif break; } @@ -1284,10 +1499,10 @@ init_loop(ModeInfo * mi) if (local_neighbors == 6) { int nccols, ncrows; - if (lp->width < 4) - lp->width = 4; - if (lp->height < 4) - lp->height = 4; + if (lp->width < 8) + lp->width = 8; + if (lp->height < 8) + lp->height = 8; if (size < -MINSIZE) { lp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(lp->width, lp->height) / HEX_MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE; @@ -1300,11 +1515,11 @@ init_loop(ModeInfo * mi) lp->ys = MIN(size, MAX(MINSIZE, MIN(lp->width, lp->height) / HEX_MINGRIDSIZE)); lp->xs = lp->ys; - nccols = MAX(lp->width / lp->xs - 2, HEX_ADAM_LOOPX + 1); - ncrows = MAX(lp->height / lp->ys - 1, HEX_ADAM_LOOPY + 1); + nccols = MAX(lp->width / lp->xs - 2, HEX_MINGRIDSIZE); + ncrows = MAX(lp->height / lp->ys - 1, HEX_MINGRIDSIZE); lp->ncols = nccols / 2; lp->nrows = ncrows / 2; - lp->nrows -= !(lp->nrows & 1); /* Must be odd */ + lp->nrows -= !(lp->nrows & 1); /* Must be odd */ lp->xb = (lp->width - lp->xs * nccols) / 2 + lp->xs; lp->yb = (lp->height - lp->ys * ncrows) / 2 + lp->ys; for (i = 0; i < 6; i++) { @@ -1338,39 +1553,65 @@ init_loop(ModeInfo * mi) if (lp->oldcells != NULL) { (void) free((void *) lp->oldcells); - lp->oldcells = NULL; - } - if ((lp->oldcells = (unsigned char *) calloc(lp->bncols * lp->bnrows, sizeof (unsigned char))) == NULL) { - release_loop(mi); + lp->oldcells = (unsigned char *) NULL; + } + if ((lp->oldcells = (unsigned char *) calloc(lp->bncols * lp->bnrows, + sizeof (unsigned char))) == NULL) { + free_loop(display, lp); return; } if (lp->newcells != NULL) { (void) free((void *) lp->newcells); - lp->newcells = NULL; + lp->newcells = (unsigned char *) NULL; } - if ((lp->newcells = (unsigned char *) calloc(lp->bncols * lp->bnrows, sizeof (unsigned char))) == NULL) { - release_loop(mi); + if ((lp->newcells = (unsigned char *) calloc(lp->bncols * lp->bnrows, + sizeof (unsigned char))) == NULL) { + free_loop(display, lp); return; } - if (init_table()) { + if (!init_table()) { release_loop(mi); return; } + lp->mincol = lp->bncols - 1; + lp->minrow = lp->bnrows - 1; + lp->maxcol = 0; + lp->maxrow = 0; +#ifndef DELAYDEBUGLOOP + { + int flaws = MI_COUNT(mi); + + if (flaws < 0) + flaws = NRAND(-MI_COUNT(mi) + 1); + for (i = 0; i < flaws; i++) { + init_flaw(mi); + } + /* actual flaws might be less since the adam loop done next */ + } +#endif init_adam(mi); } void draw_loop(ModeInfo * mi) { - loopstruct *lp = &loops[MI_SCREEN(mi)]; - int offset, i, j, life = 0; + int offset, i, j; unsigned char *z, *znew; + loopstruct *lp; - if (loops == NULL) { - init_loop(mi); + if (loops == NULL) return; - } + lp = &loops[MI_SCREEN(mi)]; + if (lp->newcells == NULL) + return; + MI_IS_DRAWN(mi) = True; + lp->dead = True; +#ifdef DELAYDEBUGLOOP + if (MI_COUNT(mi) && lp->generation > MI_COUNT(mi)) { + (void) sleep(DELAYDEBUGLOOP); + } +#endif for (j = lp->minrow; j <= lp->maxrow; j++) { for (i = lp->mincol; i <= lp->maxcol; i++) { @@ -1378,9 +1619,10 @@ draw_loop(ModeInfo * mi) z = lp->oldcells + offset; znew = lp->newcells + offset; if (*z != *znew) { + lp->dead = False; *z = *znew; - addtolist(mi, i - lp->bx, j - lp->by, *znew); - life = 1; + if (!addtolist(mi, i - lp->bx, j - lp->by, *znew)) + return; if (i == lp->mincol && i > lp->bx) lp->mincol--; if (j == lp->minrow && j > lp->by) @@ -1393,8 +1635,11 @@ draw_loop(ModeInfo * mi) } } for (i = 0; i < COLORS; i++) - draw_state(mi, i); - if (++lp->generation > MI_CYCLES(mi) /* || !life */) { + if (!draw_state(mi, i)) { + free_loop(MI_DISPLAY(mi), lp); + return; + } + if (++lp->generation > MI_CYCLES(mi) || lp->dead) { init_loop(mi); return; } else @@ -1418,13 +1663,15 @@ draw_loop(ModeInfo * mi) void refresh_loop(ModeInfo * mi) { - loopstruct *lp = &loops[MI_SCREEN(mi)]; + loopstruct *lp; - if (loops == NULL) { - init_loop(mi); + if (loops == NULL) return; - } + lp = &loops[MI_SCREEN(mi)]; + MI_CLEARWINDOW(mi); lp->redrawing = 1; lp->redrawpos = lp->by * lp->ncols + lp->bx; } + +#endif /* MODE_loop */ diff --git a/hacks/mountain.c b/hacks/mountain.c index 621a0bd0..6b237889 100644 --- a/hacks/mountain.c +++ b/hacks/mountain.c @@ -2,7 +2,7 @@ /* mountain -- square grid mountains */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)mountain.c 4.04 97/07/28 xlockmore"; +static const char sccsid[] = "@(#)mountain.c 5.00 2000/11/01 xlockmore"; #endif @@ -22,25 +22,40 @@ static const char sccsid[] = "@(#)mountain.c 4.04 97/07/28 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: Compatible with xscreensaver + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 1995: Written */ #ifdef STANDALONE -# define PROGCLASS "Mountain" -# define HACK_INIT init_mountain -# define HACK_DRAW draw_mountain -# define mountain_opts xlockmore_opts -# define DEFAULTS "*delay: 0 \n" \ - "*count: 30 \n" \ - "*ncolors: 64 \n" -# define SMOOTH_COLORS +#define MODE_mountain +#define PROGCLASS "Mountain" +#define HACK_INIT init_mountain +#define HACK_DRAW draw_mountain +#define mountain_opts xlockmore_opts +#define DEFAULTS "*delay: 1000 \n" \ + "*count: 30 \n" \ + "*cycles: 4000 \n" \ + "*ncolors: 64 \n" +#define SMOOTH_COLORS #include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ #include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ +#ifdef MODE_mountain + ModeSpecOpt mountain_opts = -{0, NULL, 0, NULL, NULL}; +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct mountain_description = +{"mountain", "init_mountain", "draw_mountain", "release_mountain", + "refresh_mountain", "init_mountain", (char *) NULL, &mountain_opts, + 1000, 30, 4000, 1, 64, 1.0, "", + "Shows Papo's mountain range", 0, NULL}; + +#endif /* ~ 5000 Max mountain height (1000 - 10000) */ #define MAXHEIGHT (3 * (mp->width + mp->height)) @@ -57,12 +72,13 @@ typedef struct { int offset; int stage; int h[WORLDWIDTH][WORLDWIDTH]; - int time; /* up time */ - int first; - GC stippled_GC; + long time; /* up time */ + Bool wireframe; + Bool joke; + GC stippledGC; } mountainstruct; -static mountainstruct *mountains = NULL; +static mountainstruct *mountains = (mountainstruct *) NULL; static void spread(int (*m)[50], int x, int y) @@ -115,12 +131,29 @@ drawamountain(ModeInfo * mi) if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, c)); else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); - XFillPolygon(display, window, gc, p, 4, Complex, CoordModeOrigin); - - if (!mp->pixelmode) { - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); - XDrawLines(display, window, gc, p, 5, CoordModeOrigin); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + + if (mp->joke) { + if ((Bool) (LRAND() & 1)) + XDrawLines(display, window, gc, p, 5, CoordModeOrigin); + else { + XFillPolygon(display, window, gc, p, 4, Complex, CoordModeOrigin); + if (!mp->pixelmode) { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + XDrawLines(display, window, gc, p, 5, CoordModeOrigin); + } + } + } else { + if (mp->wireframe) { + XDrawLines(display, window, gc, p, 5, CoordModeOrigin); + } else { + XFillPolygon(display, window, gc, p, 4, Complex, CoordModeOrigin); + + if (!mp->pixelmode) { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + XDrawLines(display, window, gc, p, 5, CoordModeOrigin); + } + } } mp->x++; if (mp->x == WORLDWIDTH - 1) { @@ -134,9 +167,9 @@ drawamountain(ModeInfo * mi) void init_mountain(ModeInfo * mi) { - mountainstruct *mp; int i, j, x, y; XGCValues gcv; + mountainstruct *mp; if (mountains == NULL) { if ((mountains = (mountainstruct *) calloc(MI_NUM_SCREENS(mi), @@ -144,27 +177,35 @@ init_mountain(ModeInfo * mi) return; } mp = &mountains[MI_SCREEN(mi)]; - mp->width = MI_WIN_WIDTH(mi); - mp->height = MI_WIN_HEIGHT(mi); + + mp->width = MI_WIDTH(mi); + mp->height = MI_HEIGHT(mi); mp->pixelmode = (mp->width + mp->height < 200); mp->stage = 0; mp->time = 0; mp->x = mp->y = 0; - if (!mp->first) { - mp->first = 1; - gcv.foreground = MI_WIN_WHITE_PIXEL(mi); - gcv.background = MI_WIN_BLACK_PIXEL(mi); + if (MI_IS_FULLRANDOM(mi)) { + mp->joke = (Bool) (NRAND(10) == 0); + mp->wireframe = (Bool) (LRAND() & 1); + } else { + mp->joke = False; + mp->wireframe = MI_IS_WIREFRAME(mi); + } - mp->stippled_GC = XCreateGC(MI_DISPLAY(mi), MI_WINDOW(mi), - GCForeground | GCBackground, &gcv); + if (mp->stippledGC == None) { + gcv.foreground = MI_WHITE_PIXEL(mi); + gcv.background = MI_BLACK_PIXEL(mi); + if ((mp->stippledGC = XCreateGC(MI_DISPLAY(mi), MI_WINDOW(mi), + GCForeground | GCBackground, &gcv)) == None) + return; } - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + MI_CLEARWINDOW(mi); - for (y = 0; y < WORLDWIDTH; y++) - for (x = 0; x < WORLDWIDTH; x++) + for (y = 0; y < (int) WORLDWIDTH; y++) + for (x = 0; x < (int) WORLDWIDTH; x++) mp->h[x][y] = 0; - j = MI_BATCHCOUNT(mi); + j = MI_COUNT(mi); if (j < 0) j = NRAND(-j) + 1; for (i = 0; i < j; i++) @@ -191,16 +232,23 @@ init_mountain(ModeInfo * mi) void draw_mountain(ModeInfo * mi) { - mountainstruct *mp = &mountains[MI_SCREEN(mi)]; + mountainstruct *mp; + + if (mountains == NULL) + return; + mp = &mountains[MI_SCREEN(mi)]; + if (mp->stippledGC == NULL) + return; + + MI_IS_DRAWN(mi) = True; switch (mp->stage) { case 0: drawamountain(mi); break; case 1: - MI_PAUSE(mi) = 2000000; - /*if (++mp->time > MI_CYCLES(mi)); */ - mp->stage++; + if (++mp->time > MI_CYCLES(mi)) + mp->stage++; break; case 2: init_mountain(mi); @@ -217,18 +265,26 @@ release_mountain(ModeInfo * mi) for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { mountainstruct *mp = &mountains[screen]; - XFreeGC(MI_DISPLAY(mi), mp->stippled_GC); + if (mp->stippledGC) + XFreeGC(MI_DISPLAY(mi), mp->stippledGC); } (void) free((void *) mountains); - mountains = NULL; + mountains = (mountainstruct *) NULL; } } void refresh_mountain(ModeInfo * mi) { - mountainstruct *mp = &mountains[MI_SCREEN(mi)]; + mountainstruct *mp; + + if (mountains == NULL) + return; + mp = &mountains[MI_SCREEN(mi)]; + MI_CLEARWINDOW(mi); mp->x = 0; mp->y = 0; } + +#endif /* MODE_mountain */ diff --git a/hacks/noseguy.c b/hacks/noseguy.c index 0bf10d82..f7c8013d 100644 --- a/hacks/noseguy.c +++ b/hacks/noseguy.c @@ -16,6 +16,7 @@ */ #include "screenhack.h" +#include "xpm-pixmap.h" #include extern FILE *popen (const char *, const char *); @@ -56,9 +57,7 @@ static int state; /* indicates states: walking or getting passwd */ static void (*next_fn) (void); -#ifdef HAVE_XPM -# include - +#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) # include "images/noseguy/nose-f1.xpm" # include "images/noseguy/nose-f2.xpm" # include "images/noseguy/nose-f3.xpm" @@ -86,41 +85,19 @@ init_images (void) &left_front, &right_front, &front, &down }; int i; -#ifdef HAVE_XPM +#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) + static char **bits[] = { nose_l1_xpm, nose_l2_xpm, nose_r1_xpm, nose_r2_xpm, nose_f2_xpm, nose_f3_xpm, nose_f1_xpm, nose_f4_xpm }; + + for (i = 0; i < sizeof (images) / sizeof(*images); i++) { - XWindowAttributes xgwa; - XpmAttributes xpmattrs; - Pixmap pixmap = 0; - int result; - xpmattrs.valuemask = 0; - - XGetWindowAttributes (dpy, window, &xgwa); - -# ifdef XpmCloseness - xpmattrs.valuemask |= XpmCloseness; - xpmattrs.closeness = 40000; -# endif -# ifdef XpmVisual - xpmattrs.valuemask |= XpmVisual; - xpmattrs.visual = xgwa.visual; -# endif -# ifdef XpmDepth - xpmattrs.valuemask |= XpmDepth; - xpmattrs.depth = xgwa.depth; -# endif -# ifdef XpmColormap - xpmattrs.valuemask |= XpmColormap; - xpmattrs.colormap = xgwa.colormap; -# endif - - result = XpmCreatePixmapFromData(dpy, window, bits[i], - &pixmap, 0 /* mask */, &xpmattrs); - if (!pixmap || (result != XpmSuccess && result != XpmColorError)) + Pixmap pixmap = xpm_data_to_pixmap (dpy, window, bits[i], + 0, 0, 0); + if (!pixmap) { fprintf (stderr, "%s: Can't load nose images\n", progname); exit (1); diff --git a/hacks/penrose.c b/hacks/penrose.c index 07e351fc..0ec7d973 100644 --- a/hacks/penrose.c +++ b/hacks/penrose.c @@ -1,6 +1,5 @@ -/* -*- Mode: C; tab-width: 4 -*- - * penrose --- quasiperiodic tilings. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* penrose --- quasiperiodic tilings */ /* As reported in News of the Weird: @@ -19,12 +18,13 @@ http://www.nine.org/notw/notw.html */ - #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)penrose.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)penrose.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1996 by Timo Korvola +/*- + * Copyright (c) 1996 by Timo Korvola * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -39,8 +39,10 @@ static const char sccsid[] = "@(#)penrose.c 4.00 97/01/01 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 09-Sep-96: Written. */ + * 01-Nov-2000: Allocation checks + * 10-May-1997: Jamie Zawinski compatible with xscreensaver + * 09-Sep-1996: Written. + */ /*- Be careful, this probably still has a few bugs (many of which may only @@ -63,7 +65,7 @@ If one of these are hit penrose will reinitialize. * untiled area. Whenever this is in danger of happening, we just * do not add the tile, hoping for a better random choice the next * time. Second, when choosing a vertex randomly, we will take - * one that lies withing the viewport if available. If this seems to + * one that lies within the viewport if available. If this seems to * cause enclosures in the forced rule case, we will allow invisible * vertices to be chosen. * @@ -73,65 +75,78 @@ If one of these are hit penrose will reinitialize. * horizontally or vertically or forced rule choice has failed 100 * times due to areas about to become enclosed. * + * Introductory info: + * Science News March 23 1985 Vol 127, No. 12 + * Science News July 16 1988 Vol 134, No. 3 + * The Economist Sept 17 1988 pg. 100 + * */ #ifdef STANDALONE -# define PROGCLASS "Penrose" -# define HACK_INIT init_penrose -# define HACK_DRAW draw_penrose -# define penrose_opts xlockmore_opts -# define DEFAULTS "*delay: 10000 \n" \ - "*size: 40 \n" \ - "*ncolors: 64 \n" -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ +#define MODE_penrose +#define PROGCLASS "Penrose" +#define HACK_INIT init_penrose +#define HACK_DRAW draw_penrose +#define penrose_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*size: 40 \n" \ + "*ncolors: 64 \n" +#include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ +#ifdef MODE_penrose -/*- - * Annoyingly the ANSI C library people have reserved all identifiers - * ending with _t for future use. Hence we use _c as a suffix for - * typedefs (c for class, although this is not C++). - */ - -#define MINSIZE 5 - -/*- - * In theory one could fit 10 tiles to a single vertex. However, the - * vertex rules only allow at most seven tiles to meet at a vertex. - */ - -#define MAX_TILES_PER_VERTEX 7 -#define N_VERTEX_RULES 8 -#define ALLOC_NODE( type) ((type *)malloc( sizeof( type))) #define DEF_AMMANN "False" static Bool ammann; -/* How long in seconds should we wait before starting a new tiling? */ -static long redo_delay = 3; -static long redo_delay_usec; - static XrmOptionDescRec opts[] = { - {"-ammann", ".penrose.ammann", XrmoptionNoArg, (caddr_t) "on"}, - {"+ammann", ".penrose.ammann", XrmoptionNoArg, (caddr_t) "off"}, - {"-redoDelay", ".penrose.redoDelay", XrmoptionSepArg, NULL} + {(char *) "-ammann", (char *) ".penrose.ammann", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+ammann", (char *) ".penrose.ammann", XrmoptionNoArg, (caddr_t) "off"} }; static argtype vars[] = { - {(caddr_t *) & ammann, "ammann", "Ammann", DEF_AMMANN, t_Bool}, - {(caddr_t *) & redo_delay, "redoDelay", "RedoDelay", "3", t_Int} + {(caddr_t *) & ammann, (char *) "ammann", (char *) "Ammann", (char *) DEF_AMMANN, t_Bool} }; static OptionStruct desc[] = { - {"-/+ammann", "turn on/off Ammann lines"}, - {"-redoDelay", "delay between new tilings"} + {(char *) "-/+ammann", (char *) "turn on/off Ammann lines"} }; -ModeSpecOpt penrose_opts = { 3, opts, 2, vars, desc }; +ModeSpecOpt penrose_opts = +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct penrose_description = +{"penrose", "init_penrose", "draw_penrose", "release_penrose", + "init_penrose", "init_penrose", (char *) NULL, &penrose_opts, + 10000, 1, 1, -40, 64, 1.0, "", + "Shows Penrose's quasiperiodic tilings", 0, NULL}; + +#endif + +/*- + * Annoyingly the ANSI C library people have reserved all identifiers + * ending with _t for future use. Hence we use _c as a suffix for + * typedefs (c for class, although this is not C++). + */ + +#define MINSIZE 5 + +/*- + * In theory one could fit 10 tiles to a single vertex. However, the + * vertex rules only allow at most seven tiles to meet at a vertex. + */ + +#define CELEBRATE 31415 /* This causes a pause, an error occurred. */ +#define COMPLETION 3141 /* This causes a pause, tiles filled up screen. */ +#define MAX_TILES_PER_VERTEX 7 +#define N_VERTEX_RULES 8 +#define ALLOC_NODE(type) (type *)malloc(sizeof (type)) /*- * These are used to specify directions. They can also be used in bit @@ -180,7 +195,7 @@ typedef unsigned char vertex_type_c; * to fill. * * Here we use a doubly chained ring-like structure as vertices often need - * to be removed or inserted (they are kept in geometrical order + * to be removed or inserted (they are kept in geometrical order * circling the tiled area counterclockwise). The ring is refered to by * a pointer to one more or less random node. When deleting nodes one * must make sure that this pointer continues to refer to a valid @@ -249,11 +264,12 @@ typedef struct { fringe_c fringe; forced_pool_c forced; int done, failures; - int thick_color, thin_color; + unsigned long thick_color, thin_color; + int busyLoop; + Bool ammann; } tiling_c; -static tiling_c *tilings; /* = {0} */ - +static tiling_c *tilings = (tiling_c *) NULL; /* The tiles are listed in counterclockwise order. */ typedef struct { @@ -323,14 +339,14 @@ vertex_dir(ModeInfo * mi, fringe_node_c * vertex, unsigned side) return (2 * i + 5) % 10; } tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, - "Weirdness in vertex_dir (this has been reported)\n"); + "Weirdness in vertex_dir (this has been reported)\n"); for (i = 0; i < 5; i++) (void) fprintf(stderr, "v2->fived[%d]=%d, vertex->fived[%d]=%d\n", - i, v2->fived[i], i, vertex->fived[i]); + i, v2->fived[i], i, vertex->fived[i]); } - MI_PAUSE(mi) = redo_delay_usec; + tp->busyLoop = CELEBRATE; return 0; } @@ -356,8 +372,8 @@ add_unit_vec(angle_c dir, int *fived) * This computes screen coordinates from 5D representation. Note that X * uses left-handed coordinates (y increases downwards). */ -static XPoint -fived_to_loc(int fived[], tiling_c * tp) +static void +fived_to_loc(int fived[], tiling_c * tp, XPoint *pt) { static fcoord_c fived_table[5] = { @@ -365,10 +381,11 @@ fived_to_loc(int fived[], tiling_c * tp) float fifth = 8 * atan(1.) / 5; register int i; register float r; - register fcoord_c offset = - {.0, .0}; - XPoint pt = tp->origin; + register fcoord_c offset; + *pt = tp->origin; + offset.x = 0.0; + offset.y = 0.0; if (fived_table[0].x == .0) for (i = 0; i < 5; i++) { fived_table[i].x = cos(fifth * i); @@ -379,32 +396,31 @@ fived_to_loc(int fived[], tiling_c * tp) offset.x += r * fived_table[i].x; offset.y -= r * fived_table[i].y; } - pt.x += (int) (offset.x + .5); - pt.y += (int) (offset.y + .5); - return pt; + (*pt).x += (int) (offset.x + .5); + (*pt).y += (int) (offset.y + .5); } /* Mop up dynamic data for one screen. */ static void -release_screen(tiling_c * tp) +free_penrose(tiling_c * tp) { register fringe_node_c *fp1, *fp2; register forced_node_c *lp1, *lp2; - if (tp->fringe.nodes == 0) + if (tp->fringe.nodes == NULL) return; fp1 = tp->fringe.nodes; do { fp2 = fp1; fp1 = fp1->next; - (void) free((char *) fp2); + (void) free((void *) fp2); } while (fp1 != tp->fringe.nodes); - tp->fringe.nodes = 0; + tp->fringe.nodes = (fringe_node_c *) NULL; for (lp1 = tp->forced.first; lp1 != 0;) { lp2 = lp1; lp1 = lp1->next; - (void) free((char *) lp2); + (void) free((void *) lp2); } tp->forced.first = 0; } @@ -418,18 +434,22 @@ init_penrose(ModeInfo * mi) fringe_node_c *fp; int i, size; - redo_delay_usec = redo_delay * 1000000; - if (tilings == NULL) { if ((tilings = (tiling_c *) calloc(MI_NUM_SCREENS(mi), sizeof (tiling_c))) == NULL) return; } tp = &tilings[MI_SCREEN(mi)]; + + if (MI_IS_FULLRANDOM(mi)) + tp->ammann = (Bool) (LRAND() & 1); + else + tp->ammann = ammann; tp->done = False; + tp->busyLoop = 0; tp->failures = 0; - tp->width = MI_WIN_WIDTH(mi); - tp->height = MI_WIN_HEIGHT(mi); + tp->width = MI_WIDTH(mi); + tp->height = MI_HEIGHT(mi); if (MI_NPIXELS(mi) > 2) { tp->thick_color = NRAND(MI_NPIXELS(mi)); /* Insure good contrast */ @@ -451,36 +471,48 @@ init_penrose(ModeInfo * mi) tp->origin.x = (tp->width / 2 + NRAND(tp->width)) / 2; tp->origin.y = (tp->height / 2 + NRAND(tp->height)) / 2; tp->fringe.n_nodes = 2; - if (tp->fringe.nodes != 0) - release_screen(tp); - if (tp->fringe.nodes != 0 || tp->forced.first != 0) { - if (MI_WIN_IS_VERBOSE(mi)) { + if (tp->fringe.nodes != NULL) + free_penrose(tp); + if (tp->fringe.nodes != NULL || tp->forced.first != 0) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in init_penrose()\n"); - (void) fprintf(stderr, "tp->fringe.nodes = 0 && tp->forced.first = 0\n"); + (void) fprintf(stderr, "tp->fringe.nodes = NULL && tp->forced.first = 0\n"); } - release_screen(tp); /* Try again */ + free_penrose(tp); /* Try again */ tp->done = True; } tp->forced.n_nodes = tp->forced.n_visible = 0; - fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c); + if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) { + free_penrose(tp); + return; + } if (fp == 0) { - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in init_penrose()\n"); (void) fprintf(stderr, "fp = 0\n"); } - fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c); + if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) { + free_penrose(tp); + return; + } tp->done = True; } /* First vertex. */ fp->rule_mask = (1 << N_VERTEX_RULES) - 1; fp->list_ptr = 0; - fp->prev = fp->next = ALLOC_NODE(fringe_node_c); + if ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) { + free_penrose(tp); + return; + } if (fp->next == 0) { - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in init_penrose()\n"); (void) fprintf(stderr, "fp->next = 0\n"); } - fp->prev = fp->next = ALLOC_NODE(fringe_node_c); + if ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) { + free_penrose(tp); + return; + } tp->done = True; } fp->n_tiles = 0; @@ -495,7 +527,7 @@ init_penrose(ModeInfo * mi) fp = fp->next; i = NRAND(5); fp->fived[i] = 2 * NRAND(2) - 1; - fp->loc = fived_to_loc(fp->fived, tp); + fived_to_loc(fp->fived, tp, &(fp->loc)); /* That's it! We have created our first edge. */ } @@ -646,12 +678,12 @@ draw_tile(fringe_node_c * v1, fringe_node_c * v2, else XSetForeground(display, gc, MI_PIXEL(mi, tp->thin_color)); } else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); XFillPolygon(display, window, gc, pts, 4, Convex, CoordModeOrigin); - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); XDrawLines(display, window, gc, pts, 5, CoordModeOrigin); - if (ammann) { + if (tp->ammann) { /* Draw some Ammann lines for debugging purposes. This will probably fail miserably on a b&w display. */ @@ -666,7 +698,7 @@ draw_tile(fringe_node_c * v1, fringe_node_c * v2, if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, tp->thin_color)); else { - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); XSetLineAttributes(display, gc, 1, LineOnOffDash, CapNotLast, JoinMiter); } XDrawLine(display, window, gc, @@ -680,7 +712,7 @@ draw_tile(fringe_node_c * v1, fringe_node_c * v2, if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, tp->thick_color)); else { - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); XSetLineAttributes(display, gc, 1, LineOnOffDash, CapNotLast, JoinMiter); } XDrawLine(display, window, gc, @@ -707,7 +739,7 @@ draw_tile(fringe_node_c * v1, fringe_node_c * v2, * might get called with an untileable vertex, causing ( n <= 1). * (This is what the tp->done checks for). * - * A MI_PAUSE celebrates the dislocation. + * A delayLoop celebrates the dislocation. */ static void check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp) @@ -718,10 +750,10 @@ check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp) if (vertex->rule_mask == 0) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { - (void) fprintf(stderr, "Dislocation occured!\n"); + if (MI_IS_VERBOSE(mi)) { + (void) fprintf(stderr, "Dislocation occurred!\n"); } - MI_PAUSE(mi) = redo_delay_usec; /* Should be able to recover */ + tp->busyLoop = CELEBRATE; /* Should be able to recover */ } if (1 == find_completions(vertex, hits, n_hits, S_LEFT, 0 /*, False */ )) forced_sides |= S_LEFT; @@ -734,7 +766,7 @@ check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp) *vertex->list_ptr = node->next; if (node->next != 0) node->next->vertex->list_ptr = vertex->list_ptr; - free(node); + (void) free((void *) node); tp->forced.n_nodes--; if (!vertex->off_screen) tp->forced.n_visible--; @@ -744,7 +776,8 @@ check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp) forced_node_c *node; if (vertex->list_ptr == 0) { - node = ALLOC_NODE(forced_node_c); + if ((node = ALLOC_NODE(forced_node_c)) == NULL) + return; node->vertex = vertex; node->next = tp->forced.first; if (tp->forced.first != 0) @@ -772,11 +805,11 @@ delete_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp) { if (tp->fringe.nodes == vertex) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in delete_penrose()\n"); (void) fprintf(stderr, "tp->fringe.nodes == vertex\n"); } - MI_PAUSE(mi) = redo_delay_usec; + tp->busyLoop = CELEBRATE; } if (vertex->list_ptr != 0) { forced_node_c *node = *vertex->list_ptr; @@ -784,19 +817,21 @@ delete_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp) *vertex->list_ptr = node->next; if (node->next != 0) node->next->vertex->list_ptr = vertex->list_ptr; - free(node); + (void) free((void *) node); tp->forced.n_nodes--; if (!vertex->off_screen) tp->forced.n_visible--; } if (!vertex->off_screen) tp->fringe.n_nodes--; - free(vertex); + (void) free((void *) vertex); } -/* Check whether the addition of a tile of type vtype would completely fill * - the space available at vertex. */ +/*- + * Check whether the addition of a tile of type vtype would completely fill + * the space available at vertex. + */ static int fills_vertex(ModeInfo * mi, vertex_type_c vtype, fringe_node_c * vertex) { @@ -834,7 +869,7 @@ fringe_changes(ModeInfo * mi, fringe_node_c * vertex, fringe_node_c ** right, fringe_node_c ** far, fringe_node_c ** left) { - fringe_node_c *v, *f = NULL; + fringe_node_c *v, *f = (fringe_node_c *) NULL; unsigned result = FC_NEW_FAR; /* We clear this later if necessary. */ if (far) @@ -908,19 +943,19 @@ add_vtype(fringe_node_c * vertex, unsigned side, vertex_type_c vtype) static fringe_node_c * alloc_vertex(ModeInfo * mi, angle_c dir, fringe_node_c * from, tiling_c * tp) { - fringe_node_c *v = ALLOC_NODE(fringe_node_c); + fringe_node_c *v; - if (v == 0) { + if ((v = ALLOC_NODE(fringe_node_c)) == NULL) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { - (void) fprintf(stderr, "Weirdness in alloc_vertex()\n"); - (void) fprintf(stderr, "v = 0\n"); + if (MI_IS_VERBOSE(mi)) { + (void) fprintf(stderr, "No memory in alloc_vertex()\n"); } - MI_PAUSE(mi) = redo_delay_usec; + tp->busyLoop = CELEBRATE; + return v; } *v = *from; add_unit_vec(dir, v->fived); - v->loc = fived_to_loc(v->fived, tp); + fived_to_loc(v->fived, tp, &(v->loc)); if (v->loc.x < 0 || v->loc.y < 0 || v->loc.x >= tp->width || v->loc.y >= tp->height) { v->off_screen = True; @@ -937,7 +972,7 @@ alloc_vertex(ModeInfo * mi, angle_c dir, fringe_node_c * from, tiling_c * tp) return v; } -/* +/*- * Add a tile described by vtype to the side of vertex. This must be * allowed by the rules -- we do not check it here. New vertices are * allocated as necessary. The fringe and the forced vertex pool are updated. @@ -954,9 +989,9 @@ add_tile(ModeInfo * mi, tiling_c *tp = &tilings[MI_SCREEN(mi)]; fringe_node_c - * left = 0, - *right = 0, - *far = 0, + *left = (fringe_node_c *) NULL, + *right = (fringe_node_c *) NULL, + *far = (fringe_node_c *) NULL, *node; unsigned fc = fringe_changes(mi, vertex, side, vtype, &right, &far, &left); @@ -971,25 +1006,29 @@ add_tile(ModeInfo * mi, /* This should never occur. */ if (fc & FC_BAG) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_tile()\n"); (void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG); } } if (side == S_LEFT) { - if (right == 0) - right = alloc_vertex(mi, - vertex_dir(mi, vertex, S_LEFT) - vtype_angle(vtype), vertex, tp); - if (far == 0) - far = alloc_vertex(mi, - vertex_dir(mi, left, S_RIGHT) + vtype_angle(ltype), left, tp); + if (right == NULL) + if ((right = alloc_vertex(mi, vertex_dir(mi, vertex, S_LEFT) - + vtype_angle(vtype), vertex, tp)) == NULL) + return False; + if (far == NULL) + if ((far = alloc_vertex(mi, vertex_dir(mi, left, S_RIGHT) + + vtype_angle(ltype), left, tp)) == NULL) + return False; } else { - if (left == 0) - left = alloc_vertex(mi, - vertex_dir(mi, vertex, S_RIGHT) + vtype_angle(vtype), vertex, tp); - if (far == 0) - far = alloc_vertex(mi, - vertex_dir(mi, right, S_LEFT) - vtype_angle(rtype), right, tp); + if (left == NULL) + if ((left = alloc_vertex(mi, vertex_dir(mi, vertex, S_RIGHT) + + vtype_angle(vtype), vertex, tp)) == NULL) + return False; + if (far == NULL) + if ((far = alloc_vertex(mi, vertex_dir(mi, right, S_LEFT) - + vtype_angle(rtype), right, tp)) == NULL) + return False; } /* Having allocated the new vertices, but before joining them with @@ -1092,7 +1131,7 @@ add_forced_tile(ModeInfo * mi, forced_node_c * node) n = find_completions(node->vertex, hits, n, side, &vtype /*, True */ ); if (n <= 0) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_forced_tile()\n"); (void) fprintf(stderr, "n = %d\n", n); } @@ -1145,14 +1184,14 @@ add_random_tile(fringe_node_c * vertex, ModeInfo * mi) tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color + MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi); } else - tp->thick_color = tp->thin_color = MI_WIN_WHITE_PIXEL(mi); + tp->thick_color = tp->thin_color = MI_WHITE_PIXEL(mi); n_hits = match_rules(vertex, hits, False); side = NRAND(2) ? S_LEFT : S_RIGHT; n = find_completions(vertex, hits, n_hits, side, vtypes /*, False */ ); /* One answer would mean a forced tile. */ if (n <= 0) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "n = %d\n", n); } @@ -1163,7 +1202,7 @@ add_random_tile(fringe_node_c * vertex, ModeInfo * mi) fc = fringe_changes(mi, vertex, side, vtypes[i], &right, &far, &left); if (fc & FC_BAG) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG); } @@ -1194,7 +1233,7 @@ add_random_tile(fringe_node_c * vertex, ModeInfo * mi) } if (n_good <= 0) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "n_good = %d\n", n_good); } @@ -1204,13 +1243,12 @@ add_random_tile(fringe_node_c * vertex, ModeInfo * mi) while (no_good & (1 << j)) j++; - i = add_tile(mi, vertex, side, vtypes[j - 1]); - if (!i) { + if (!add_tile(mi, vertex, side, vtypes[j - 1])) { tp->done = True; - if (MI_WIN_IS_VERBOSE(mi)) { + if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); - (void) fprintf(stderr, "i = %d\n", i); } + free_penrose(tp); } } @@ -1218,26 +1256,40 @@ add_random_tile(fringe_node_c * vertex, ModeInfo * mi) void draw_penrose(ModeInfo * mi) { - tiling_c *tp = &tilings[MI_SCREEN(mi)]; int i = 0, n; - forced_node_c *p = tp->forced.first; + forced_node_c *p; + tiling_c *tp; + if (tilings == NULL) + return; + tp = &tilings[MI_SCREEN(mi)]; + if (tp->fringe.nodes == NULL) + return; + + MI_IS_DRAWN(mi) = True; + p = tp->forced.first; + if (tp->busyLoop > 0) { + tp->busyLoop--; + return; + } if (tp->done || tp->failures >= 100) { init_penrose(mi); return; } /* Check for the initial "2-gon". */ if (tp->fringe.nodes->prev == tp->fringe.nodes->next) { - vertex_type_c vtype = VT_TOTAL_MASK & LRAND(); + vertex_type_c vtype = (unsigned char) (VT_TOTAL_MASK & LRAND()); + + MI_CLEARWINDOW(mi); - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); - (void) add_tile(mi, tp->fringe.nodes, S_LEFT, vtype); + if (!add_tile(mi, tp->fringe.nodes, S_LEFT, vtype)) + free_penrose(tp); return; } /* No visible nodes left. */ if (tp->fringe.n_nodes == 0) { tp->done = True; - MI_PAUSE(mi) = redo_delay_usec; /* Just finished drawing */ + tp->busyLoop = COMPLETION; /* Just finished drawing */ return; } if (tp->forced.n_visible > 0 && tp->failures < 10) { @@ -1255,15 +1307,15 @@ draw_penrose(ModeInfo * mi) while (i++ < n) p = p->next; } else { - fringe_node_c *p = tp->fringe.nodes; + fringe_node_c *fringe_p = tp->fringe.nodes; n = NRAND(tp->fringe.n_nodes); i = 0; for (; i <= n; i++) do { - p = p->next; - } while (p->off_screen); - add_random_tile(p, mi); + fringe_p = fringe_p->next; + } while (fringe_p->off_screen); + add_random_tile(fringe_p, mi); tp->failures = 0; return; } @@ -1281,12 +1333,11 @@ release_penrose(ModeInfo * mi) if (tilings != NULL) { int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - tiling_c *tp = &tilings[screen]; - - release_screen(tp); - } + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_penrose(&tilings[screen]); (void) free((void *) tilings); - tilings = NULL; + tilings = (tiling_c *) NULL; } } + +#endif /* MODE_penrose */ diff --git a/hacks/polyominoes.c b/hacks/polyominoes.c new file mode 100644 index 00000000..87b5c744 --- /dev/null +++ b/hacks/polyominoes.c @@ -0,0 +1,2315 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* polyominoes --- Shows attempts to place polyominoes into a rectangle */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)polyominoes.c 5.01 2000/12/18 xlockmore"; + +#endif + +/* + * Copyright (c) 2000 by Stephen Montgomery-Smith + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * 07-Jan-2001: Made improvement to the search algorithm for the puzzles + * involving identical polyominoes (via the variable + * reason_to_not_attach). By Stephen Montgomery-Smith. + * 20-Dec-2000: Added more puzzles at David Bagley's request. + * 27-Nov-2000: Adapted from euler2d.c Copyright (c) 2000 by Stephen + * Montgomery-Smith + * 05-Jun-2000: Adapted from flow.c Copyright (c) 1996 by Tim Auckland + * 18-Jul-1996: Adapted from swarm.c Copyright (c) 1991 by Patrick J. Naughton. + * 31-Aug-1990: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org) + */ + +#ifdef STANDALONE +#define MODE_polyominoes +#define PROGCLASS "Polyominoes" +#define HACK_INIT init_polyominoes +#define HACK_DRAW draw_polyominoes +#define polyominoes_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ +"*cycles: 2000 \n" \ +"*ncolors: 64 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#include "erase.h" +#include +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_polyominoes +#define DEF_IDENTICAL "False" +#define DEF_PLAIN "False" + +static Bool identical; +static Bool plain; + +static XrmOptionDescRec opts[] = +{ + {(char *) "-identical", (char *) ".polyominoes.identical", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+identical", (char *) ".polyominoes.identical", XrmoptionNoArg, (caddr_t) "off"}, + {(char *) "-plain", (char *) ".polyominoes.plain", XrmoptionNoArg, (caddr_t) "on"}, + {(char *) "+plain", (char *) ".polyominoes.plain", XrmoptionNoArg, (caddr_t) "off"} +}; +static argtype vars[] = +{ + {(caddr_t *) &identical, (char *) "identical", (char *) "Identical", (char *) DEF_IDENTICAL, t_Bool}, + {(caddr_t *) & plain, (char *) "plain", (char *) "Plain", (char *) DEF_PLAIN, t_Bool} +}; +static OptionStruct desc[] = +{ + {(char *) "-/+identical", (char *) "turn on/off puzzles where the polyomino pieces are identical"}, + {(char *) "-/+plain", (char *) "turn on/off plain pieces"} +}; + +ModeSpecOpt polyominoes_opts = +{sizeof opts / sizeof opts[0], opts, + sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct polyominoes_description = { + "polyominoes", "init_polyominoes", "draw_polyominoes", "release_polyominoes", + "refresh_polyominoes", "init_polyominoes", (char *) NULL, &polyominoes_opts, + 6000, 1, 8192, 1, 64, 1.0, "", + "Shows attempts to place polyominoes into a rectangle", 0, NULL +}; + +#endif + +/* Each polyomino is described by several quantities: + len: the number of squares in the polyomino; + point: the list of points; + tranform_len: the number of items in transform_list; + transform_list: a list of transformations that need to be done in order + to get all rotations and reflections (see the function + transform below); + max_white: the maximum number of white squares covered if polyomino + is placed on a chess board; + color: it's display color; + attached: whether it is currently attached to the rectangle; + attach_point: point on rectangle where attached; + point_no: the number of the point where it is attached; + transform_index: which element of transform_list is currently being used. +*/ + +typedef struct {int x,y;} point_type; + +typedef struct {int len; point_type *point; + int transform_len, transform_list[8], max_white; + unsigned long color; + int attached; + point_type attach_point; + int point_no, transform_index;} polyomino_type; + + +typedef struct _polyominoesstruct{ + int wait; + + int width, height; + unsigned border_color; + int mono; + + polyomino_type *polyomino; + int nr_polyominoes; + Bool identical, use3D; + int *attach_list; + int nr_attached; + +/* The array that tells where the polyominoes are attached. */ + int *array, *changed_array; + +/* These specify the dimensions of how things appear on the screen. */ + int box, x_margin, y_margin; + +/* These booleans decide in which way to try to attach the polyominoes. */ + int left_right, top_bottom; + +/* Bitmaps for display purposes. */ + int use_bitmaps; + XImage *bitmaps[256]; + +/* Structures used for display purposes if there is not enough memory + to allocate bitmaps (or if the screen is small). */ + XSegment *lines; + XRectangle *rectangles; + +/* A procedure that may be used to see if certain configurations + are permissible. */ + int (*check_ok)(struct _polyominoesstruct *sp); + +/* Tells program that solutions are invariant under 180 degree + rotation. */ + int rot180; + +/* This is a variable used in the case that all the polyominoes are identical + that will further prune the search tree. Essentially it will be + int reason_to_not_attach[nr_polynominoes][nr_polynominoes]; + Let me first explain the effect it is trying to overcome. Often + in the search process, the computer will first try to fit shapes into + a region (call it A), and then into another region (call it B) that is + essentially disjoint from A. But it may be that it just is not possible + to fit shapes into region B. So it fits something into A, and then + tries to fit something into B. Failing it fits something else into A, + and then tried again to fit something into B. Thus the program is trying + again and again to fit something into B, when it should have figured out + the first time that it was impossible. + + To overcome this, everytime we try to attach a piece, we collect the reasons + why it cannot be attached (a boolean for each piece that got in the way). + If we see that a piece cannot be attached, we detach the other pieces until + we have detached at least one piece for which the boolean reason_to_not_attach + is set. +*/ + int *reason_to_not_attach; + + int counter; +} polyominoesstruct; + +#define ARRAY(x,y) (sp->array[(x)*sp->height+(y)]) +#define CHANGED_ARRAY(x,y) (sp->changed_array[(x)*sp->height+(y)]) +#define ARRAY_P(p) (sp->array[(p).x*sp->height+(p).y]) +#define CHANGED_ARRAY_P(p) (sp->changed_array[(p).x*sp->height+(p).y]) +#define ARR(x,y) (((x)<0||(x)>=sp->width||(y)<0||(y)>=sp->height)?-2:ARRAY(x,y)) + +#define REASON_TO_NOT_ATTACH(x,y) (sp->reason_to_not_attach[(x)*sp->nr_polyominoes+(y)]) + +#define ROUND8(n) ((((n)+7)/8)*8) + +/* Defines to index the bitmaps. A set bit indicates that an edge or + corner is required. */ +#define LEFT (1<<0) +#define RIGHT (1<<1) +#define UP (1<<2) +#define DOWN (1<<3) +#define LEFT_UP (1<<4) +#define LEFT_DOWN (1<<5) +#define RIGHT_UP (1<<6) +#define RIGHT_DOWN (1<<7) +#define IS_LEFT(n) ((n) & LEFT) +#define IS_RIGHT(n) ((n) & RIGHT) +#define IS_UP(n) ((n) & UP) +#define IS_DOWN(n) ((n) & DOWN) +#define IS_LEFT_UP(n) ((n) & LEFT_UP) +#define IS_LEFT_DOWN(n) ((n) & LEFT_DOWN) +#define IS_RIGHT_UP(n) ((n) & RIGHT_UP) +#define IS_RIGHT_DOWN(n) ((n) & RIGHT_DOWN) + +/* Defines to access the bitmaps. */ +#define BITNO(x,y) ((x)+(y)*ROUND8(sp->box)) +#define SETBIT(n,x,y) {data[BITNO(x,y)/8] |= 1<<(BITNO(x,y)%8);} +#define RESBIT(n,x,y) {data[BITNO(x,y)/8] &= ~(1<<(BITNO(x,y)%8));} +#define TWOTHIRDSBIT(n,x,y) {if ((x+y-1)%3) SETBIT(n,x,y) else RESBIT(n,x,y)} +#define HALFBIT(n,x,y) {if ((x-y)%2) SETBIT(n,x,y) else RESBIT(n,x,y)} +#define THIRDBIT(n,x,y) {if (!((x-y-1)%3)) SETBIT(n,x,y) else RESBIT(n,x,y)} +#define THREEQUARTERSBIT(n,x,y) \ + {if ((y%2)||((x+2+y/2+1)%2)) SETBIT(n,x,y) else RESBIT(n,x,y)} +#define NOTHALFBIT(n,x,y) {if ((x-y)%2) RESBIT(n,x,y) else SETBIT(n,x,y)} + +/* Parameters for bitmaps. */ +#define G ((sp->box/45)+1) /* 1/2 of gap between polyominoes. */ +#define T ((sp->box<=12)?1:(G*2)) /* Thickness of walls of polyominoes. */ +#define R ((sp->box<=12)?1:(G*6)) /* Amount of rounding. */ +#define RT ((sp->box<=12)?1:(G*3)) /* Thickness of wall of rounded parts. + Here 3 is an approximation to 2 sqrt(2). */ +#define RR 0 /* Roof ridge thickness */ + +#if 0 +/* A list of those bitmaps we need to create to display any pentomino. */ +/* (not used right now because it does not seem to work for hexonimoes.) */ + +static int bitmaps_needed[] = +{ + LEFT_UP|LEFT_DOWN|RIGHT_UP|RIGHT_DOWN, + + LEFT|RIGHT_UP|RIGHT_DOWN, + RIGHT|LEFT_UP|LEFT_DOWN, + UP|LEFT_DOWN|RIGHT_DOWN, + DOWN|LEFT_UP|RIGHT_UP, + LEFT|RIGHT_UP, + RIGHT|LEFT_UP, + UP|LEFT_DOWN, + DOWN|LEFT_UP, + LEFT|RIGHT_DOWN, + RIGHT|LEFT_DOWN, + UP|RIGHT_DOWN, + DOWN|RIGHT_UP, + +/* These needed for hexonimoes*/ + LEFT, + RIGHT, + UP, + DOWN, + LEFT_DOWN|RIGHT_UP|RIGHT_DOWN, + LEFT_UP|RIGHT_UP|RIGHT_DOWN, + LEFT_UP|LEFT_DOWN|RIGHT_DOWN, + LEFT_UP|LEFT_DOWN|RIGHT_UP, + + LEFT|UP|RIGHT_DOWN, + LEFT|DOWN|RIGHT_UP, + RIGHT|UP|LEFT_DOWN, + RIGHT|DOWN|LEFT_UP, + LEFT|UP, + LEFT|DOWN, + RIGHT|UP, + RIGHT|DOWN, + + LEFT|RIGHT, + UP|DOWN, + + RIGHT|UP|DOWN, + LEFT|UP|DOWN, + LEFT|RIGHT|DOWN, + LEFT|RIGHT|UP, + + -1 +}; + +static int bitmap_needed(int n) { + int i; + + for (i=0;bitmaps_needed[i]!=-1;i++) + if (n == bitmaps_needed[i]) + return 1; + return 0; +} + +#endif + +/* Some debugging routines. + +static void print_board(polyominoesstruct *sp) { + int x,y; + for (y=0;yheight;y++) { + for (x=0;xwidth;x++) + if (ARRAY(x,y) == -1) + fprintf(stderr," "); + else + fprintf(stderr,"%c",'a'+ARRAY(x,y)); + fprintf(stderr,"\n"); + } + fprintf(stderr,"\n"); +} + +static void print_points(point_type *point, int len) { + int i; + + for (i=0;ix=in.x-offset.x+attach_point.x; + out->y=in.y-offset.y+attach_point.y; + break; + case 1: out->x=-(in.y-offset.y)+attach_point.x; + out->y=in.x-offset.x+attach_point.y; + break; + case 2: out->x=-(in.x-offset.x)+attach_point.x; + out->y=-(in.y-offset.y)+attach_point.y; + break; + case 3: out->x=in.y-offset.y+attach_point.x; + out->y=-(in.x-offset.x)+attach_point.y; + break; + case 4: out->x=-(in.x-offset.x)+attach_point.x; + out->y=in.y-offset.y+attach_point.y; + break; + case 5: out->x=in.y-offset.y+attach_point.x; + out->y=in.x-offset.x+attach_point.y; + break; + case 6: out->x=in.x-offset.x+attach_point.x; + out->y=-(in.y-offset.y)+attach_point.y; + break; + case 7: out->x=-(in.y-offset.y)+attach_point.x; + out->y=-(in.x-offset.x)+attach_point.y; + break; + } +} + +static int first_poly_no(polyominoesstruct *sp) { + int poly_no; + + poly_no = 0; + while(poly_nonr_polyominoes && sp->polyomino[poly_no].attached) + poly_no++; + return poly_no; +} + +static void next_poly_no(polyominoesstruct *sp, int *poly_no) { + + if (sp->identical) { + *poly_no = sp->nr_polyominoes; + } else { + do { + (*poly_no)++; + } while (*poly_nonr_polyominoes && sp->polyomino[*poly_no].attached); + } +} + +/* check_all_regions_multiple_of looks for connected regions of + blank spaces, and returns 0 if it finds a connected region containing + a number of blanks that is not a multiple of n. +*/ + +static void count_adjacent_blanks(polyominoesstruct *sp, int *count, int x, int y, int blank_mark) { + + if (ARRAY(x,y) == -1) { + (*count)++; + ARRAY(x,y) = blank_mark; + if (x>=1) count_adjacent_blanks(sp, count,x-1,y,blank_mark); + if (xwidth-1) count_adjacent_blanks(sp, count,x+1,y,blank_mark); + if (y>=1) count_adjacent_blanks(sp, count,x,y-1,blank_mark); + if (yheight-1) count_adjacent_blanks(sp, count,x,y+1,blank_mark); + } +} + +static int check_all_regions_multiple_of(polyominoesstruct *sp, int n) { + int x,y,count,good = 1; + + for (x=0;xwidth && good;x++) for (y=0;yheight && good;y++) { + count = 0; + count_adjacent_blanks(sp, &count,x,y,-2); + good = count%n == 0; + } + + for (x=0;xwidth;x++) for (y=0;yheight;y++) + if (ARRAY(x,y) == -2) + ARRAY(x,y) = -1; + + return good; +} + +static int check_all_regions_positive_combination_of(polyominoesstruct *sp, int m, int n) { + int x,y,count,good = 1; + + for (x=0;xwidth && good;x++) for (y=0;yheight && good;y++) { + count = 0; + count_adjacent_blanks(sp, &count,x,y,-2); + good = 0; + for (;count>=0 && !good;count-=m) + good = count%n == 0; + } + + for (x=0;xwidth;x++) for (y=0;yheight;y++) + if (ARRAY(x,y) == -2) + ARRAY(x,y) = -1; + + return good; +} + +static int find_smallest_blank_component(polyominoesstruct *sp) { + int x,y,size,smallest_size,blank_mark,smallest_mark; + + smallest_mark = blank_mark = -10; + smallest_size = 1000000000; + for (x=0;xwidth;x++) for (y=0;yheight;y++) if (ARRAY(x,y) == -1) { + size = 0; + count_adjacent_blanks(sp, &size,x,y,blank_mark); + if (sizewidth;x++) for (y=0;yheight;y++) { + if (ARRAY(x,y) == -1 && (x+y)%2) whites++; + if (ARRAY(x,y) == -1 && (x+y+1)%2) blacks++; + } + for (poly_no=0;poly_nonr_polyominoes;poly_no++) if (!sp->polyomino[poly_no].attached) { + max_white += sp->polyomino[poly_no].max_white; + min_white += sp->polyomino[poly_no].len - sp->polyomino[poly_no].max_white; + } + return (min_white <= blacks && min_white <= whites + && blacks <= max_white && whites <= max_white); +} + +/* This routine looks at the point (x,y) and sees how many polyominoes + and all their various transforms may be attached there. +*/ + +static int +score_point(polyominoesstruct *sp, int x, int y, int min_score_so_far) { + int poly_no, point_no, transform_index, i, attachable; + point_type attach_point, target_point; + int score = 0; + + if (x>=1 && xwidth-1 && y>=1 && yheight-1 && + ARRAY(x-1,y-1)<0 && ARRAY(x-1,y)<0 && ARRAY(x-1,y+1)<0 && + ARRAY(x+1,y-1)<0 && ARRAY(x+1,y)<0 && ARRAY(x+1,y+1)<0 && + ARRAY(x,y-1)<0 && ARRAY(x,y+1)<0) + return 10000; + + attach_point.x = x; + attach_point.y = y; + for (poly_no=first_poly_no(sp);poly_nonr_polyominoes;next_poly_no(sp,&poly_no)) + if (!sp->polyomino[poly_no].attached) { + for (point_no=0;point_nopolyomino[poly_no].len;point_no++) + for (transform_index=0;transform_indexpolyomino[poly_no].transform_len;transform_index++) { + attachable = 1; + for (i=0;ipolyomino[poly_no].len;i++) { + transform(sp->polyomino[poly_no].point[i], + sp->polyomino[poly_no].point[point_no], + sp->polyomino[poly_no].transform_list[transform_index], + attach_point, &target_point); + if ( ! ((target_point.x>=0) && (target_point.xwidth) + && (target_point.y>=0) && (target_point.yheight) + && (ARRAY_P(target_point)<0))) { + attachable = 0; + break; + } + } + if (attachable) { + score++; + if (score>=min_score_so_far) + return score; + } + } + } + + return score; +} + +static void find_blank(polyominoesstruct *sp, point_type *point) { + int score, worst_score; + int x, y; + int blank_mark; + + blank_mark = find_smallest_blank_component(sp); + + worst_score = 1000000; + for (x=0;xwidth;x++) for (y=0;yheight;y++) if (ARRAY(x,y)==blank_mark) { + score = 100*score_point(sp,x,y,worst_score); + if (score>0) { + if (sp->left_right) score += 10*x; + else score += 10*(sp->width-1-x); + if (sp->top_bottom) score += y; + else score += (sp->height-1-y); + } + if (scorex = x; + point->y = y; + worst_score = score; + } + } + + for (x=0;xwidth;x++) for (y=0;yheight;y++) + if (ARRAY(x,y)<0) ARRAY(x,y) = -1; +} + +/* Detaches the most recently attached polyomino. */ + +static +void detach(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_index, point_type *attach_point, int rot180) { + int i; + point_type target_point; + + if (sp->nr_attached == 0) return; + sp->nr_attached--; + *poly_no = sp->attach_list[sp->nr_attached]; + *point_no = sp->polyomino[*poly_no].point_no; + *transform_index = sp->polyomino[*poly_no].transform_index; + *attach_point = sp->polyomino[*poly_no].attach_point; + for (i=0;ipolyomino[*poly_no].len;i++) { + transform(sp->polyomino[*poly_no].point[i], + sp->polyomino[*poly_no].point[*point_no], + sp->polyomino[*poly_no].transform_list[*transform_index]^(rot180<<1), + *attach_point, &target_point); + ARRAY_P(target_point) = -1; + CHANGED_ARRAY_P(target_point) = 1; + } + + sp->polyomino[*poly_no].attached = 0; +} + +/* Attempts to attach a polyomino at point (x,y) at the + point_no-th point of that polyomino, using the transform + transform_no. Returns 1 if successful. +*/ + +static +int attach(polyominoesstruct *sp, int poly_no, int point_no, int transform_index, point_type attach_point, int rot180, + int *reason_to_not_attach) { + point_type target_point; + int i; + int attachable = 1, worst_reason_not_to_attach = 1000000000; + + if (rot180) { + attach_point.x = sp->width-1-attach_point.x; + attach_point.y = sp->height-1-attach_point.y; + } + + if (sp->polyomino[poly_no].attached) + return 0; + + for (i=0;ipolyomino[poly_no].len;i++) { + transform(sp->polyomino[poly_no].point[i], + sp->polyomino[poly_no].point[point_no], + sp->polyomino[poly_no].transform_list[transform_index]^(rot180<<1), + attach_point, &target_point); + if ( ! ((target_point.x>=0) && (target_point.xwidth) + && (target_point.y>=0) && (target_point.yheight) + && (ARRAY_P(target_point) == -1))) { + if (sp->identical) { + attachable = 0; + if ((target_point.x>=0) && (target_point.xwidth) + && (target_point.y>=0) && (target_point.yheight) + && (ARRAY_P(target_point) >= 0) + && (ARRAY_P(target_point)identical && !attachable) { + if (worst_reason_not_to_attach < 1000000000) + reason_to_not_attach[worst_reason_not_to_attach] = 1; + return 0; + } + + for (i=0;ipolyomino[poly_no].len;i++) { + transform(sp->polyomino[poly_no].point[i], + sp->polyomino[poly_no].point[point_no], + sp->polyomino[poly_no].transform_list[transform_index]^(rot180<<1), + attach_point, &target_point); + ARRAY_P(target_point) = poly_no; + CHANGED_ARRAY_P(target_point) = 1; + } + + sp->attach_list[sp->nr_attached] = poly_no; + sp->nr_attached++; + + sp->polyomino[poly_no].attached = 1; + sp->polyomino[poly_no].point_no = point_no; + sp->polyomino[poly_no].attach_point = attach_point; + sp->polyomino[poly_no].transform_index = transform_index; + + if (!sp->check_ok(sp)) { + detach(sp,&poly_no,&point_no,&transform_index,&attach_point,rot180); + return 0; + } + + return 1; +} + +static +int next_attach_try(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_index) { + + (*transform_index)++; + if (*transform_index>=sp->polyomino[*poly_no].transform_len) { + *transform_index = 0; + (*point_no)++; + if (*point_no>=sp->polyomino[*poly_no].len) { + *point_no = 0; + next_poly_no(sp,poly_no); + if (*poly_no>=sp->nr_polyominoes) { + *poly_no = first_poly_no(sp); + return 0; + } + } + } + return 1; +} + + +/******************************************************* +Display routines. +*******************************************************/ + +static void +draw_without_bitmaps(ModeInfo * mi, polyominoesstruct *sp) { + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + int x,y,poly_no,nr_lines,nr_rectangles; + + XSetLineAttributes(display,gc,sp->box/10+1,LineSolid,CapRound,JoinRound); + + for (poly_no=-1;poly_nonr_polyominoes;poly_no++) { + nr_rectangles = 0; + for (x=0;xwidth;x++) for (y=0;yheight;y++) + if (CHANGED_ARRAY(x,y) && ARRAY(x,y) == poly_no) { + sp->rectangles[nr_rectangles].x = sp->x_margin + sp->box*x; + sp->rectangles[nr_rectangles].y = sp->y_margin + sp->box*y; + sp->rectangles[nr_rectangles].width = sp->box; + sp->rectangles[nr_rectangles].height = sp->box; + nr_rectangles++; + } + if (poly_no == -1) + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + else + XSetForeground(display, gc, sp->polyomino[poly_no].color); + XFillRectangles(display, window, gc, sp->rectangles, nr_rectangles); + } + + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + + nr_lines = 0; + for (x=0;xwidth-1;x++) for (y=0;yheight;y++) { + if (ARRAY(x,y) == -1 && ARRAY(x+1,y) == -1 + && (CHANGED_ARRAY(x,y) || CHANGED_ARRAY(x+1,y))) { + sp->lines[nr_lines].x1 = sp->x_margin + sp->box*(x+1); + sp->lines[nr_lines].y1 = sp->y_margin + sp->box*y; + sp->lines[nr_lines].x2 = sp->x_margin + sp->box*(x+1); + sp->lines[nr_lines].y2 = sp->y_margin + sp->box*(y+1); + nr_lines++; + } + } + XDrawSegments(display, window, gc, sp->lines, nr_lines); + + nr_lines = 0; + for (x=0;xwidth;x++) for (y=0;yheight-1;y++) { + if (ARRAY(x,y) == -1 && ARRAY(x,y+1) == -1 + && (CHANGED_ARRAY(x,y) || CHANGED_ARRAY(x,y+1))) { + sp->lines[nr_lines].x1 = sp->x_margin + sp->box*x; + sp->lines[nr_lines].y1 = sp->y_margin + sp->box*(y+1); + sp->lines[nr_lines].x2 = sp->x_margin + sp->box*(x+1); + sp->lines[nr_lines].y2 = sp->y_margin + sp->box*(y+1); + nr_lines++; + } + } + XDrawSegments(display, window, gc, sp->lines, nr_lines); + + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + XDrawRectangle(display, window, gc, sp->x_margin, sp->y_margin, sp->box*sp->width, sp->box*sp->height); + + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + + nr_lines = 0; + for (x=0;xwidth-1;x++) for (y=0;yheight;y++) { + if (ARRAY(x+1,y) != ARRAY(x,y)) { + sp->lines[nr_lines].x1 = sp->x_margin + sp->box*(x+1); + sp->lines[nr_lines].y1 = sp->y_margin + sp->box*y; + sp->lines[nr_lines].x2 = sp->x_margin + sp->box*(x+1); + sp->lines[nr_lines].y2 = sp->y_margin + sp->box*(y+1); + nr_lines++; + } + } + XDrawSegments(display, window, gc, sp->lines, nr_lines); + + nr_lines = 0; + for (x=0;xwidth;x++) for (y=0;yheight-1;y++) { + if (ARRAY(x,y+1) != ARRAY(x,y)) { + sp->lines[nr_lines].x1 = sp->x_margin + sp->box*x; + sp->lines[nr_lines].y1 = sp->y_margin + sp->box*(y+1); + sp->lines[nr_lines].x2 = sp->x_margin + sp->box*(x+1); + sp->lines[nr_lines].y2 = sp->y_margin + sp->box*(y+1); + nr_lines++; + } + } + XDrawSegments(display, window, gc, sp->lines, nr_lines); + XSetLineAttributes(display,gc,1,LineSolid,CapRound,JoinRound); + XFlush(display); +} + +static void create_bitmaps(ModeInfo * mi, polyominoesstruct *sp) { + int x,y,n; + char *data; + + for (n=0;n<256;n++) { + +/* Avoid duplication of identical bitmaps. */ + if (IS_LEFT_UP(n) && (IS_LEFT(n) || IS_UP(n))) + sp->bitmaps[n] = sp->bitmaps[n & ~LEFT_UP]; + else if (IS_LEFT_DOWN(n) && (IS_LEFT(n) || IS_DOWN(n))) + sp->bitmaps[n] = sp->bitmaps[n & ~LEFT_DOWN]; + else if (IS_RIGHT_UP(n) && (IS_RIGHT(n) || IS_UP(n))) + sp->bitmaps[n] = sp->bitmaps[n & ~RIGHT_UP]; + else if (IS_RIGHT_DOWN(n) && (IS_RIGHT(n) || IS_DOWN(n))) + sp->bitmaps[n] = sp->bitmaps[n & ~RIGHT_DOWN]; + + else /* if (bitmap_needed(n)) */ { + data = (char *) malloc(sizeof(char)*(sp->box*ROUND8(sp->box)/8)); + if (data == NULL) { + sp->use_bitmaps = 0; + return; + } + + for (y=0;ybox;y++) for (x=0;xbox;x++) { + if (!sp->use3D) { +#ifdef SMALL_BELLYBUTTON + if (x >= sp->box / 2 && x <= sp->box / 2 + 1 && + y >= sp->box / 2 && y <= sp->box / 2 + 1) + NOTHALFBIT(n,x,y) + else +#endif + HALFBIT(n,x,y) + } else if ((x>=y && x<=sp->box-y-1 && IS_UP(n)) + || (x<=y && x<=sp->box-y-1 && ybox/2 && !IS_LEFT(n)) + || (x>=y && x>=sp->box-y-1 && ybox/2 && !IS_RIGHT(n))) + SETBIT(n,x,y) + else if ((x<=y && x<=sp->box-y-1 && IS_LEFT(n)) + || (x>=y && x<=sp->box-y-1 && xbox/2 && !IS_UP(n)) + || (x<=y && x>=sp->box-y-1 && xbox/2 && !IS_DOWN(n))) + TWOTHIRDSBIT(n,x,y) + else if ((x>=y && x>=sp->box-y-1 && IS_RIGHT(n)) + || (x>=y && x<=sp->box-y-1 && x>=sp->box/2 && !IS_UP(n)) + || (x<=y && x>=sp->box-y-1 && x>=sp->box/2 && !IS_DOWN(n))) + HALFBIT(n,x,y) + else if ((x<=y && x>=sp->box-y-1 && IS_DOWN(n)) + || (x<=y && x<=sp->box-y-1 && y>=sp->box/2 && !IS_LEFT(n)) + || (x>=y && x>=sp->box-y-1 && y>=sp->box/2 && !IS_RIGHT(n))) + THIRDBIT(n,x,y) + } + + if (IS_LEFT(n)) + for (y=0;ybox;y++) for (x=G;xbox;y++) for (x=G;xbox-1-x,y) + if (IS_UP(n)) + for (x=0;xbox;x++) for (y=G;ybox;x++) for (y=G;ybox-1-y) + if (IS_LEFT(n)) + for (y=0;ybox;y++) for (x=0;xbox;y++) for (x=0;xbox-1-x,y) + if (IS_UP(n)) + for (x=0;xbox;x++) for (y=0;ybox;x++) for (y=0;ybox-1-y) + + if (IS_LEFT(n) && IS_UP(n)) + for (x=G;x<=G+R;x++) + for (y=G;y<=R+2*G-x;y++) { + if (x+y>R+2*G-RT) + SETBIT(n,x,y) + else + RESBIT(n,x,y) + } + if (IS_LEFT(n) && IS_DOWN(n)) + for (x=G;x<=G+R;x++) + for (y=G;y<=R+2*G-x;y++) { + if (x+y>R+2*G-RT) + SETBIT(n,x,sp->box-1-y) + else + RESBIT(n,x,sp->box-1-y) + } + if (IS_RIGHT(n) && IS_UP(n)) + for (x=G;x<=G+R;x++) + for (y=G;y<=R+2*G-x;y++) { + if (x+y>R+2*G-RT) + SETBIT(n,sp->box-1-x,y) + else + RESBIT(n,sp->box-1-x,y) + } + if (IS_RIGHT(n) && IS_DOWN(n)) + for (x=G;x<=G+R;x++) + for (y=G;y<=R+2*G-x;y++) { + if (x+y>R+2*G-RT) + SETBIT(n,sp->box-1-x,sp->box-1-y) + else + RESBIT(n,sp->box-1-x,sp->box-1-y) + } + + if (!IS_LEFT(n) && !IS_UP(n) && IS_LEFT_UP(n)) { + for (x=0;xbox-1-y) + for (x=G;xbox-1-y) + for (x=0;xbox-1-y) + } + if (!IS_RIGHT(n) && !IS_UP(n) && IS_RIGHT_UP(n)) { + for (x=0;xbox-1-x,y) + for (x=G;xbox-1-x,y) + for (x=0;xbox-1-x,y) + } + if (!IS_RIGHT(n) && !IS_DOWN(n) && IS_RIGHT_DOWN(n)) { + for (x=0;xbox-1-x,sp->box-1-y) + for (x=G;xbox-1-x,sp->box-1-y) + for (x=0;xbox-1-x,sp->box-1-y) + } + +#ifdef LARGE_BELLYBUTTON + if (!sp->use3D) { + if (!IS_LEFT(n) && !IS_UP(n) && !IS_LEFT_UP(n)) + for (x=0;xbox-G-T;ybox;y++) + SETBIT(n,x,y) + if (!IS_RIGHT(n) && !IS_UP(n) && !IS_RIGHT_UP(n)) + for (x=sp->box-G-T;xbox;x++) for(y=0;ybox-G-T;xbox;x++) for(y=sp->box-G-T;ybox;y++) + SETBIT(n,x,y) + } else +#else + if (sp->use3D) +#endif + { + if (!IS_LEFT(n) && !IS_UP(n) && !IS_LEFT_UP(n)) + for (x=0;xbox/2-RR;x++) for(y=0;ybox/2-RR;y++) + THREEQUARTERSBIT(n,x,y) + if (!IS_LEFT(n) && !IS_DOWN(n) && !IS_LEFT_DOWN(n)) + for (x=0;xbox/2-RR;x++) for(y=sp->box/2+RR;ybox;y++) + THREEQUARTERSBIT(n,x,y) + if (!IS_RIGHT(n) && !IS_UP(n) && !IS_RIGHT_UP(n)) + for (x=sp->box/2+RR;xbox;x++) for(y=0;ybox/2-RR;y++) + THREEQUARTERSBIT(n,x,y) + if (!IS_RIGHT(n) && !IS_DOWN(n) && !IS_RIGHT_DOWN(n)) + for (x=sp->box/2+RR;xbox;x++) for(y=sp->box/2+RR;ybox;y++) + THREEQUARTERSBIT(n,x,y) + } + + sp->bitmaps[n] = XCreateImage(MI_DISPLAY(mi), MI_VISUAL(mi), 1, XYBitmap, + 0, data, sp->box, sp->box, 8, 0); + if (sp->bitmaps[n] == None) { + free(data); + sp->use_bitmaps = 0; + return; + } + sp->bitmaps[n]->byte_order = MSBFirst; + sp->bitmaps[n]->bitmap_unit = 8; + sp->bitmaps[n]->bitmap_bit_order = LSBFirst; + } + } + + sp->use_bitmaps = 1; +} + +static void draw_with_bitmaps(ModeInfo * mi, polyominoesstruct *sp) { + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + int x,y,t,bitmap_index; + + for (x=0;xwidth;x++) for (y=0;yheight;y++) { + if (ARRAY(x,y) == -1) { + if (CHANGED_ARRAY(x,y)) { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + XFillRectangle(display,window,gc, + sp->x_margin + sp->box*x, + sp->y_margin + sp->box*y, + sp->box,sp->box); + } + } + else { + XSetForeground(display, gc, sp->polyomino[ARRAY(x,y)].color); + bitmap_index = 0; + if (ARR(x,y) != ARR(x-1,y)) bitmap_index |= LEFT; + if (ARR(x,y) != ARR(x+1,y)) bitmap_index |= RIGHT; + if (ARR(x,y) != ARR(x,y-1)) bitmap_index |= UP; + if (ARR(x,y) != ARR(x,y+1)) bitmap_index |= DOWN; + if (ARR(x,y) != ARR(x-1,y-1)) bitmap_index |= LEFT_UP; + if (ARR(x,y) != ARR(x-1,y+1)) bitmap_index |= LEFT_DOWN; + if (ARR(x,y) != ARR(x+1,y-1)) bitmap_index |= RIGHT_UP; + if (ARR(x,y) != ARR(x+1,y+1)) bitmap_index |= RIGHT_DOWN; + (void) XPutImage(display,window,gc, + sp->bitmaps[bitmap_index], + 0,0, + sp->x_margin + sp->box*x, + sp->y_margin + sp->box*y, + sp->box,sp->box); + } + } + + XSetForeground(display, gc, sp->border_color); + for (t=G;tx_margin-t-1,sp->y_margin-t-1, + sp->box*sp->width+1+2*t, sp->box*sp->height+1+2*t); + XFlush(display); +} + + +/*************************************************** +Routines to initialise and close down polyominoes. +***************************************************/ + +static void free_bitmaps(polyominoesstruct *sp) { + int n; + + for (n=0;n<256;n++) +/* Don't bother to free duplicates */ + if (IS_LEFT_UP(n) && (IS_LEFT(n) || IS_UP(n))) + sp->bitmaps[n] = None; + else if (IS_LEFT_DOWN(n) && (IS_LEFT(n) || IS_DOWN(n))) + sp->bitmaps[n] = None; + else if (IS_RIGHT_UP(n) && (IS_RIGHT(n) || IS_UP(n))) + sp->bitmaps[n] = None; + else if (IS_RIGHT_DOWN(n) && (IS_RIGHT(n) || IS_DOWN(n))) + sp->bitmaps[n] = None; + + else if (sp->bitmaps[n] != None) { + XDestroyImage(sp->bitmaps[n]); + sp->bitmaps[n] = None; + } +} + +#define deallocate(p,t) if ((p)!=NULL) {free(p); p=(t*)NULL;} + +static void free_polyominoes(polyominoesstruct *sp) { + int n; + + for (n=0;nnr_polyominoes;n++) { + deallocate(sp->polyomino[n].point, point_type); + } + + deallocate(sp->polyomino, polyomino_type); + deallocate(sp->attach_list, int); + deallocate(sp->rectangles, XRectangle); + deallocate(sp->lines, XSegment); + deallocate(sp->reason_to_not_attach, int); + deallocate(sp->array, int); + deallocate(sp->changed_array, int); + + free_bitmaps(sp); +} + +#define set_allocate(p,type,size) p = (type *) malloc(size); \ + if ((p)==NULL) {free_polyominoes(sp);return 0;} + +#define copy_polyomino(dst,src,new_rand) \ + (dst).len=(src).len; \ + (dst).max_white = (src).max_white; \ + set_allocate((dst).point,point_type,sizeof(point_type)*(src).len); \ + (dst).len = (src).len; \ + if (new_rand) \ + random_permutation((src).len,perm_point); \ + for (i=0;i<(src).len;i++) \ + (dst).point[i] = (src).point[perm_point[i]]; \ + (dst).transform_len = (src).transform_len; \ + if (new_rand) \ + random_permutation((src).transform_len,perm_transform); \ + for (i=0;i<(src).transform_len;i++) \ + (dst).transform_list[i] = (src).transform_list[perm_transform[i]]; \ + (dst).attached = 0 + + +/*************************************************** +Puzzle specific initialization routines. +***************************************************/ + +static +int check_pentomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_multiple_of(sp, 5) && whites_ok(sp); +} + +static +int check_hexomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_multiple_of(sp, 6) && whites_ok(sp); +} + +static +int check_tetr_pentomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_positive_combination_of(sp, 5, 4) && whites_ok(sp); +} + +static +int check_pent_hexomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_positive_combination_of(sp, 6, 5) && whites_ok(sp); +} + +static +int check_heptomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_multiple_of(sp, 7) && whites_ok(sp); +} + +static +int check_octomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_multiple_of(sp, 8) && whites_ok(sp); +} + +static +int check_dekomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_multiple_of(sp, 10) && whites_ok(sp); +} + +static +int check_elevenomino_puzzle(polyominoesstruct *sp) { + return check_all_regions_multiple_of(sp, 11) && whites_ok(sp); +} + +static struct {int len; point_type point[4]; + int transform_len, transform_list[8], max_white;} tetromino[5] = +{ +/* +xxxx +*/ + {4, {{0,0}, {1,0}, {2,0}, {3,0}}, + 2, {0, 1, -1, -1, -1, -1, -1, -1}, 2}, +/* +xxx + x +*/ + {4, {{0,0}, {1,0}, {2,0}, {2,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 2}, +/* +xxx + x +*/ + {4, {{0,0}, {1,0}, {1,1}, {2,0}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* +xx + xx +*/ + {4, {{0,0}, {1,0}, {1,1}, {2,1}}, + 4, {0, 1, 4, 5, -1, -1, -1, -1}, 2}, +/* +xx +xx +*/ + {4, {{0,0}, {0,1}, {1,0}, {1,1}}, + 1, {0, -1, -1, -1, -1, -1, -1, -1}, 2}}; + + +static struct pentomino_struct {int len; point_type point[5]; + int transform_len, transform_list[8], max_white;} + pentomino[12] = +{ +/* +xxxxx +*/ + {5, {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}}, + 2, {0, 1, -1, -1, -1, -1, -1, -1}, 3}, +/* +xxxx + x +*/ + {5, {{0,0}, {1,0}, {2,0}, {3,0}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxxx + x +*/ + {5, {{0,0}, {1,0}, {2,0}, {2,1}, {3,0}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* + x +xxx + x +*/ + {5, {{0,0}, {1,0}, {2,-1}, {2,0}, {2,1}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* +xxx + xx +*/ + {5, {{0,0}, {1,0}, {2,0}, {2,1}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxx + xx +*/ + {5, {{0,0}, {1,0}, {1,1}, {2,0}, {2,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxx + x + x +*/ + {5, {{0,0}, {1,0}, {2,0}, {2,1}, {2,2}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* + x +xxx + x +*/ + {5, {{0,0}, {1,-1}, {1,0}, {2,0}, {2,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxx +x x +*/ + {5, {{0,0}, {0,1}, {1,0}, {2,0}, {2,1}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* + x +xxx +x +*/ + {5, {{0,0}, {0,1}, {1,0}, {2,-1}, {2,0}}, + 4, {0, 1, 4, 5, -1, -1, -1, -1}, 3}, +/* + x +xxx + x +*/ + {5, {{0,0}, {1,-1}, {1,0}, {1,1}, {2,0}}, + 1, {0, -1, -1, -1, -1, -1, -1, -1}, 4}, +/* +xx + xx + x +*/ + {5, {{0,0}, {1,0}, {1,1}, {2,1}, {2,2}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}}; + + +static struct hexomino_struct {int len; point_type point[6]; + int transform_len, transform_list[8], max_white;} + hexomino[35] = +{ +/* +xxxxxx +*/ + {6, {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}}, + 2, {0, 1, -1, -1, -1, -1, -1, -1}, 3}, +/* +xxxxx + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {4,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxxxx + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {3,0}, {3,1}, {4,0}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}, +/* +xxxxx + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {2,1}, {3,0}, {4,0}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* + x +xxxx + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {3,-1}, {3,0}, {3,1}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 4}, +/* +xxxx + xx +*/ + {6, {{0,0}, {1,0}, {2,0}, {3,0}, {3,1}, {4,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxxx + xx +*/ + {6, {{0,0}, {1,0}, {2,0}, {2,1}, {3,0}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxxx + x + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {3,0}, {3,1}, {3,2}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* + x +xxxx + x +*/ + {6, {{0,0}, {1,0}, {2,-1}, {2,0}, {3,0}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxxx + x x +*/ + {6, {{0,0}, {1,0}, {1,1}, {2,0}, {3,0}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}, +/* + x +xxxx + x +*/ + {6, {{0,0}, {1,-1}, {1,0}, {2,0}, {3,0}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}, +/* +xxxx +x x +*/ + {6, {{0,0}, {0,1}, {1,0}, {2,0}, {3,0}, {3,1}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* + x +xxxx +x +*/ + {6, {{0,0}, {0,1}, {1,0}, {2,0}, {3,-1}, {3,0}}, + 4, {0, 1, 4, 5, -1, -1, -1, -1}, 3}, +/* + x +xxxx + x +*/ + {6, {{0,0}, {1,0}, {2,-1}, {2,0}, {2,1}, {3,0}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 4}, +/* +xxxx + xx +*/ + {6, {{0,0}, {1,0}, {1,1}, {2,0}, {2,1}, {3,0}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* +xxxx + x + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {3,0}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* + x +xxxx + x +*/ + {6, {{0,0}, {1,-1}, {1,0}, {2,0}, {2,1}, {3,0}}, + 4, {0, 1, 4, 5, -1, -1, -1, -1}, 3}, +/* + xx +xxx + x +*/ + {6, {{0,0}, {1,0}, {2,-1}, {2,0}, {2,1}, {3,-1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* + xx +xxx + x +*/ + {6, {{0,0}, {1,-1}, {1,0}, {2,-1}, {2,0}, {2,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* + x +xxx +x x +*/ + {6, {{0,0}, {0,1}, {1,0}, {2,-1}, {2,0}, {2,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}, +/* +xxx + xxx +*/ + {6, {{0,0}, {1,0}, {2,0}, {2,1}, {3,1}, {4,1}}, + 4, {0, 1, 4, 5, -1, -1, -1, -1}, 3}, +/* +xxx + xx + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {2,1}, {3,1}, {3,2}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxx + xxx +*/ + {6, {{0,0}, {1,0}, {1,1}, {2,0}, {2,1}, {3,1}}, + 4, {0, 1, 4, 5, -1, -1, -1, -1}, 4}, +/* +xxx + xx + x +*/ + {6, {{0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}, +/* + x +xxx + xx +*/ + {6, {{0,0}, {1,-1}, {1,0}, {2,0}, {2,1}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}, +/* +xxx +x xx +*/ + {6, {{0,0}, {0,1}, {1,0}, {2,0}, {2,1}, {3,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxx + xx + x +*/ + {6, {{0,0}, {1,0}, {1,1}, {2,0}, {2,1}, {2,2}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 4}, +/* + x +xxx + xx +*/ + {6, {{0,0}, {1,-1}, {1,0}, {1,1}, {2,0}, {2,1}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 4}, +/* +xxx +xxx +*/ + {6, {{0,0}, {0,1}, {1,0}, {1,1}, {2,0}, {2,1}}, + 2, {0, 1, -1, -1, -1, -1, -1, -1}, 3}, +/* +xxx + x + xx +*/ + {6, {{0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {3,2}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xxx + x + xx +*/ + {6, {{0,0}, {1,0}, {1,2}, {2,0}, {2,1}, {2,2}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* + x +xxx +x x +*/ + {6, {{0,0}, {0,1}, {1,-1}, {1,0}, {2,0}, {2,1}}, + 4, {0, 1, 2, 3, -1, -1, -1, -1}, 3}, +/* + xx +xxx +x +*/ + {6, {{0,0}, {0,1}, {1,0}, {2,-1}, {2,0}, {3,-1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* + xx +xxx +x +*/ + {6, {{0,0}, {0,1}, {1,-1}, {1,0}, {2,-1}, {2,0}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}, +/* +xx + xx + xx +*/ + {6, {{0,0}, {1,0}, {1,1}, {2,1}, {2,2}, {3,2}}, + 4, {0, 1, 4, 5, -1, -1, -1, -1}, 3}}; + +static struct pentomino_struct one_sided_pentomino[60]; + +void make_one_sided_pentomino(void) { + int i,j,t,u; + + j=0; + for (i=0;i<18;i++) { + one_sided_pentomino[j] = pentomino[i]; + for (t=0;t<8;t++) + if (one_sided_pentomino[j].transform_list[t]>=4) { + one_sided_pentomino[j].transform_len = t; + j++; + one_sided_pentomino[j] = pentomino[i]; + for (u=t;u<8;u++) one_sided_pentomino[j].transform_list[u-t] = one_sided_pentomino[j].transform_list[u]; + one_sided_pentomino[j].transform_len -= t; + break; + } + j++; + } +} + +static struct hexomino_struct one_sided_hexomino[60]; + +void make_one_sided_hexomino(void) { + int i,j,t,u; + + j=0; + for (i=0;i<35;i++) { + one_sided_hexomino[j] = hexomino[i]; + for (t=0;t<8;t++) + if (one_sided_hexomino[j].transform_list[t]>=4) { + one_sided_hexomino[j].transform_len = t; + j++; + one_sided_hexomino[j] = hexomino[i]; + for (u=t;u<8;u++) one_sided_hexomino[j].transform_list[u-t] = one_sided_hexomino[j].transform_list[u]; + one_sided_hexomino[j].transform_len -= t; + break; + } + j++; + } +} + +/* +Find all the ways of placing all twelve pentominoes +into a rectangle whose size is 20x3, 15x4, 12x5 or 10x6. +*/ + +static +int set_pentomino_puzzle(polyominoesstruct *sp) { + int perm_poly[12], perm_point[5], perm_transform[8], i, p; + + switch (NRAND(4)) { + case 0: + sp->width = 20; + sp->height = 3; + break; + case 1: + sp->width = 15; + sp->height = 4; + break; + case 2: + sp->width = 12; + sp->height = 5; + break; + case 3: + sp->width = 10; + sp->height = 6; + break; + } + + sp->nr_polyominoes = 12; + set_allocate(sp->polyomino,polyomino_type,12*sizeof(polyomino_type)); + random_permutation(12,perm_poly); + for (p=0;p<12;p++) { + copy_polyomino(sp->polyomino[p],pentomino[perm_poly[p]],1); + } + + sp->check_ok = check_pentomino_puzzle; + + return 1; +} + +/* +Many of the following puzzles are inspired by +http://www.xs4all.nl/~gp/PolyominoSolver/Polyomino.html +*/ + +/* +Find all the ways of placing all eighteen one-sided pentominoes +into a rectangle. +*/ + +static +int set_one_sided_pentomino_puzzle(polyominoesstruct *sp) { + int perm_poly[18], perm_point[5], perm_transform[8], i, p; + + make_one_sided_pentomino(); + + switch (NRAND(4)) { + case 0: + sp->width = 30; + sp->height = 3; + break; + case 1: + sp->width = 18; + sp->height = 5; + break; + case 2: + sp->width = 15; + sp->height = 6; + break; + case 3: + sp->width = 10; + sp->height = 9; + break; + } + + sp->nr_polyominoes = 18; + set_allocate(sp->polyomino,polyomino_type,18*sizeof(polyomino_type)); + random_permutation(18,perm_poly); + for (p=0;p<18;p++) { + copy_polyomino(sp->polyomino[p],one_sided_pentomino[perm_poly[p]],1); + } + + sp->check_ok = check_pentomino_puzzle; + + return 1; +} + +/* +Find all the ways of placing all sixty one-sided hexominoes +into a rectangle. +*/ + +static +int set_one_sided_hexomino_puzzle(polyominoesstruct *sp) { + int perm_poly[60], perm_point[6], perm_transform[8], i, p; + + make_one_sided_hexomino(); + + switch (NRAND(8)) { + case 0: + sp->width = 20; + sp->height = 18; + break; + case 1: + sp->width = 24; + sp->height = 15; + break; + case 2: + sp->width = 30; + sp->height = 12; + break; + case 3: + sp->width = 36; + sp->height = 10; + break; + case 4: + sp->width = 40; + sp->height = 9; + break; + case 5: + sp->width = 45; + sp->height = 8; + break; + case 6: + sp->width = 60; + sp->height = 6; + break; + case 7: + sp->width = 72; + sp->height = 5; + break; + } + + sp->nr_polyominoes = 60; + set_allocate(sp->polyomino,polyomino_type,60*sizeof(polyomino_type)); + random_permutation(60,perm_poly); + for (p=0;p<60;p++) { + copy_polyomino(sp->polyomino[p],one_sided_hexomino[perm_poly[p]],1); + } + + sp->check_ok = check_hexomino_puzzle; + + return 1; +} + +/* +Find all the ways of placing all five tetrominoes and all twelve +pentominoes into a rectangle. +*/ + +static +int set_tetr_pentomino_puzzle(polyominoesstruct *sp) { + int perm_poly[17], perm_point[5], perm_transform[8], i, p; + + switch (NRAND(3)) { + case 0: + sp->width = 20; + sp->height = 4; + break; + case 1: + sp->width = 16; + sp->height = 5; + break; + case 2: + sp->width = 10; + sp->height = 8; + break; + } + + sp->nr_polyominoes = 17; + set_allocate(sp->polyomino,polyomino_type,17*sizeof(polyomino_type)); + random_permutation(17,perm_poly); + for (p=0;p<5;p++) { + copy_polyomino(sp->polyomino[perm_poly[p]],tetromino[p],1); + } + for (p=0;p<12;p++) { + copy_polyomino(sp->polyomino[perm_poly[p+5]],pentomino[p],1); + } + + sp->check_ok = check_tetr_pentomino_puzzle; + + return 1; +} +/* +Find all the ways of placing all twelve pentominoes and all thirty five +hexominoes into a rectangle whose size is 18x15. +*/ + +static +int set_pent_hexomino_puzzle(polyominoesstruct *sp) { + int perm_poly[47], perm_point[6], perm_transform[8], i, p; + + switch (NRAND(5)) { + case 0: + sp->width = 54; + sp->height = 5; + break; + case 1: + sp->width = 45; + sp->height = 6; + break; + case 2: + sp->width = 30; + sp->height = 9; + break; + case 3: + sp->width = 27; + sp->height = 10; + break; + case 4: + sp->width = 18; + sp->height = 15; + break; + } + + sp->nr_polyominoes = 47; + set_allocate(sp->polyomino,polyomino_type,47*sizeof(polyomino_type)); + random_permutation(47,perm_poly); + for (p=0;p<12;p++) { + copy_polyomino(sp->polyomino[perm_poly[p]],pentomino[p],1); + } + for (p=0;p<35;p++) { + copy_polyomino(sp->polyomino[perm_poly[p+12]],hexomino[p],1); + } + + sp->check_ok = check_pent_hexomino_puzzle; + + return 1; +} + +/* +Other puzzles: + +Science News September 20, 1986 Vol 130, No 12 +Science News November 14, 1987 Vol 132, Pg 310 +*/ + +/* + + * +**** fills a 10x5 rectangle + +*/ + +static struct {int len; point_type point[5]; + int transform_len, transform_list[8], max_white;} pentomino1 = + {5, {{0,0}, {1,0}, {2,0}, {3,0}, {1,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 3}; + +static +int set_pentomino_puzzle1(polyominoesstruct *sp) { + int perm_point[5], perm_transform[8], i, p; + + sp->width = 10; + sp->height =5; + + sp->nr_polyominoes = 10; + set_allocate(sp->polyomino,polyomino_type,10*sizeof(polyomino_type)); + for (p=0;p<10;p++) { + copy_polyomino(sp->polyomino[p],pentomino1,1); + } + + sp->check_ok = check_pentomino_puzzle; + + return 1; +} + +/* + + * +***** fills a 24x23 rectangle + +*/ + +static struct {int len; point_type point[6]; + int transform_len, transform_list[8], max_white;} hexomino1 = + {6, {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {1,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}; + +static +int set_hexomino_puzzle1(polyominoesstruct *sp) { + int perm_point[6], perm_transform[8], i, p; + + sp->width = 24; + sp->height =23; + + sp->nr_polyominoes = 92; + set_allocate(sp->polyomino,polyomino_type,92*sizeof(polyomino_type)); + for (p=0;p<92;p++) { + copy_polyomino(sp->polyomino[p],hexomino1,1); + } + + sp->check_ok = check_hexomino_puzzle; + + return 1; +} + +/* + + ** +***** fills a 21x26 rectangle + +(All solutions have 180 degree rotational symmetry) + +*/ + +static struct {int len; point_type point[7]; + int transform_len, transform_list[8], max_white;} heptomino1 = + {7, {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {1,1}, {2,1}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 4}; + +static +int set_heptomino_puzzle1(polyominoesstruct *sp) { + int perm_point[7], perm_transform[8], i, p; + + sp->rot180 = 1; + + sp->width = 26; + sp->height =21; + + sp->nr_polyominoes = 78; + set_allocate(sp->polyomino,polyomino_type,78*sizeof(polyomino_type)); + for (p=0;p<78;p+=2) { + copy_polyomino(sp->polyomino[p],heptomino1,1); + copy_polyomino(sp->polyomino[p+1],heptomino1,0); + } + + sp->check_ok = check_heptomino_puzzle; + + return 1; +} + +/* The following puzzles from +Polyominoes Puzzles, Patterns, Problems, and Packings Revised (2nd) Edition +by Solomon W. Golomb Princeton University Press 1994 +*/ + +/* + + ** +***** fills a 28x19 rectangle + +*/ +static +int set_heptomino_puzzle2(polyominoesstruct *sp) { + int perm_point[7], perm_transform[8], i, p; + + sp->width = 28; + sp->height =19; + + sp->nr_polyominoes = 76; + set_allocate(sp->polyomino,polyomino_type,76*sizeof(polyomino_type)); + for (p=0;p<76;p++) { + copy_polyomino(sp->polyomino[p],heptomino1,1); + } + + sp->check_ok = check_heptomino_puzzle; + + return 1; +} + +/* + +*** +**** fills a 25x22 rectangle +**** + +*/ + +static struct {int len; point_type point[11]; + int transform_len, transform_list[8], max_white;} elevenomino1 = + {11, {{0,0}, {1,0}, {2,0}, + {0,1}, {1,1}, {2,1}, {3,1}, + {0,2}, {1,2}, {2,2}, {3,2}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 6}; + +static +int set_elevenomino_puzzle1(polyominoesstruct *sp) { + int perm_point[11], perm_transform[8], i, p; + + sp->rot180 = 1; + + sp->width = 25; + sp->height =22; + + sp->nr_polyominoes = 50; + set_allocate(sp->polyomino,polyomino_type,50*sizeof(polyomino_type)); + for (p=0;p<50;p+=2) { + copy_polyomino(sp->polyomino[p],elevenomino1,1); + copy_polyomino(sp->polyomino[p+1],elevenomino1,0); + } + + sp->check_ok = check_elevenomino_puzzle; + + return 1; +} + +/* + + * + * +**** fills 32 x 30 rectangle +**** + +*/ + +static struct {int len; point_type point[10]; + int transform_len, transform_list[8], max_white;} dekomino1 = + {10, { {1,-1}, + {1,0}, + {0,1}, {1,1}, {2,1}, {3,1}, + {0,2}, {1,2}, {2,2}, {3,2}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 5}; + +static +int set_dekomino_puzzle1(polyominoesstruct *sp) { + int perm_point[10], perm_transform[8], i, p; + + sp->width = 32; + sp->height =30; + + sp->nr_polyominoes = 96; + set_allocate(sp->polyomino,polyomino_type,96*sizeof(polyomino_type)); + for (p=0;p<96;p++) { + copy_polyomino(sp->polyomino[p],dekomino1,1); + } + + sp->check_ok = check_dekomino_puzzle; + + return 1; +} + +/* + + * +*** fills 96 x 26 rectangle +**** + +*/ + +static struct {int len; point_type point[10]; + int transform_len, transform_list[8], max_white;} octomino1 = + {8, { {1,0}, + {0,1}, {1,1}, {2,1}, + {0,2}, {1,2}, {2,2}, {3,2}}, + 8, {0, 1, 2, 3, 4, 5, 6, 7}, 5}; + +static +int set_octomino_puzzle1(polyominoesstruct *sp) { + int perm_point[8], perm_transform[8], i, p; + + sp->width = 96; + sp->height =26; + + sp->nr_polyominoes = 312; + set_allocate(sp->polyomino,polyomino_type,312*sizeof(polyomino_type)); + for (p=0;p<312;p++) { + copy_polyomino(sp->polyomino[p],octomino1,1); + } + + sp->check_ok = check_octomino_puzzle; + + return 1; +} + +/* + + * fills 15 x 15 rectangle +**** + +*/ + +static +int set_pentomino_puzzle2(polyominoesstruct *sp) { + int perm_point[5], perm_transform[8], i, p; + + sp->width = 15; + sp->height =15; + + sp->nr_polyominoes = 45; + set_allocate(sp->polyomino,polyomino_type,45*sizeof(polyomino_type)); + for (p=0;p<45;p++) { + copy_polyomino(sp->polyomino[p],pentomino1,1); + } + + sp->check_ok = check_pentomino_puzzle; + + return 1; +} + +/* + +*** +**** fills a 47x33 rectangle +**** + +*/ + +static +int set_elevenomino_puzzle2(polyominoesstruct *sp) { + int perm_point[11], perm_transform[8], i, p; + + sp->width = 47; + sp->height =33; + + sp->nr_polyominoes = 141; + set_allocate(sp->polyomino,polyomino_type,141*sizeof(polyomino_type)); + for (p=0;p<141;p++) { + copy_polyomino(sp->polyomino[p],elevenomino1,1); + } + + sp->check_ok = check_elevenomino_puzzle; + + return 1; +} + +/************************************************** +The main functions. +**************************************************/ + +#define allocate(p,type,size) p = (type *) malloc(size); if ((p)==NULL) {free_polyominoes(sp); return;} + +void +init_polyominoes(ModeInfo * mi) { + polyominoesstruct *sp; + int i,x,y, start; + int box1, box2; + int *perm; + + if (polyominoeses == NULL) { + if ((polyominoeses + = (polyominoesstruct *) calloc(MI_NUM_SCREENS(mi),sizeof (polyominoesstruct))) + == NULL) + return; + } + sp = &polyominoeses[MI_SCREEN(mi)]; + + free_polyominoes(sp); + + sp->rot180 = 0; + sp->counter = 0; + + if (MI_IS_FULLRANDOM(mi)) { + sp->identical = (Bool) (LRAND() & 1); + sp->use3D = (Bool) (NRAND(4)); + } else { + sp->identical = identical; + sp->use3D = !plain; + } + if (sp->identical) { + switch (NRAND(9)) { + case 0: + if (!set_pentomino_puzzle1(sp)) + return; + break; + case 1: + if (!set_hexomino_puzzle1(sp)) + return; + break; + case 2: + if (!set_heptomino_puzzle1(sp)) + return; + break; + case 3: + if (!set_heptomino_puzzle2(sp)) + return; + break; + case 4: + if (!set_elevenomino_puzzle1(sp)) + return; + break; + case 5: + if (!set_dekomino_puzzle1(sp)) + return; + break; + case 6: + if (!set_octomino_puzzle1(sp)) + return; + break; + case 7: + if (!set_pentomino_puzzle2(sp)) + return; + break; + case 8: + if (!set_elevenomino_puzzle2(sp)) + return; + break; + } + } else { + switch (NRAND(5)) { + case 0: + if (!set_pentomino_puzzle(sp)) + return; + break; + case 1: + if (!set_one_sided_pentomino_puzzle(sp)) + return; + break; + case 2: + if (!set_one_sided_hexomino_puzzle(sp)) + return; + break; + case 3: + if (!set_pent_hexomino_puzzle(sp)) + return; + break; + case 4: + if (!set_tetr_pentomino_puzzle(sp)) + return; + break; + } + } + + allocate(sp->attach_list,int,sp->nr_polyominoes*sizeof(int)); + sp->nr_attached = 0; + + if (sp->identical) { + allocate(sp->reason_to_not_attach,int,sp->nr_polyominoes*sp->nr_polyominoes*sizeof(int)); + } + + allocate(sp->array,int,sp->width*sp->height*sizeof(int)); + allocate(sp->changed_array,int,sp->width*sp->height*sizeof(int)); + for (x=0;xwidth;x++) for (y=0;yheight;y++) ARRAY(x,y) = -1; + + sp->left_right = NRAND(2); + sp->top_bottom = NRAND(2); + + box1 = MI_WIDTH(mi)/(sp->width+2); + box2 = MI_HEIGHT(mi)/(sp->height+2); + if (box1box = box1; + else + sp->box = box2; + + if (sp->box >= 12) { + sp->box = (sp->box/12)*12; + create_bitmaps(mi,sp); + if (!sp->use_bitmaps) + free_bitmaps(sp); + } + else + sp->use_bitmaps = 0; + + if (!sp->use_bitmaps) { + allocate(sp->rectangles,XRectangle,sp->width*sp->height*sizeof(XRectangle)); + allocate(sp->lines,XSegment,sp->width*sp->height*sizeof(XSegment)); + } + + allocate(perm,int,sp->nr_polyominoes*sizeof(int)); + random_permutation(sp->nr_polyominoes, perm); + sp->mono = MI_NPIXELS(mi) < 12; + start = NRAND(MI_NPIXELS(mi)); + for (i=0;inr_polyominoes;i++) + if (!sp->mono) { + sp->polyomino[i].color = MI_PIXEL(mi,(perm[i]*MI_NPIXELS(mi) / sp->nr_polyominoes + start) % MI_NPIXELS(mi)); + if (sp->rot180) { + sp->polyomino[i+1].color = sp->polyomino[i].color; + i++; + } + } + else + if(sp->use_bitmaps) + sp->polyomino[i].color = MI_WHITE_PIXEL(mi); + else + sp->polyomino[i].color = MI_BLACK_PIXEL(mi); + free(perm); + + if (sp->use_bitmaps) { + if (sp->mono) + sp->border_color = MI_WHITE_PIXEL(mi); + else + sp->border_color = MI_PIXEL(mi,NRAND(MI_NPIXELS(mi))); + } + + sp->x_margin = (MI_WIDTH(mi)-sp->box*sp->width)/2; + sp->y_margin = (MI_HEIGHT(mi)-sp->box*sp->height)/2; + + sp->wait = 0; + + /* Clear the background. */ + MI_CLEARWINDOW(mi); + +} + +void +draw_polyominoes(ModeInfo * mi) { + polyominoesstruct *sp; + int poly_no,point_no,transform_index,done,another_attachment_try; + point_type attach_point; + int i,detach_until; + + if (polyominoeses == NULL) + return; + sp = &polyominoeses[MI_SCREEN(mi)]; + + if (MI_CYCLES(mi) != 0) { + if (++sp->counter > MI_CYCLES(mi)) { +#ifdef STANDALONE + erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi)); +#endif /* STANDALONE */ + init_polyominoes(mi); + return; + } + } + + if (sp->box == 0) { +#ifdef STANDALONE + erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi)); +#endif /* STANDALONE */ + init_polyominoes(mi); + return; + } + + MI_IS_DRAWN(mi) = True; + sp->wait--; + if (sp->wait>0) return; + + memset(sp->changed_array,0,sp->width*sp->height*sizeof(int)); + + poly_no = first_poly_no(sp); + point_no = 0; + transform_index = 0; + done = 0; + another_attachment_try = 1; + find_blank(sp,&attach_point); + if (sp->identical && sp->nr_attached < sp->nr_polyominoes) + memset(&REASON_TO_NOT_ATTACH(sp->nr_attached,0),0,sp->nr_polyominoes*sizeof(int)); + while(!done) { + if (sp->nr_attached < sp->nr_polyominoes) { + while (!done && another_attachment_try) { + done = attach(sp,poly_no,point_no,transform_index,attach_point,0,&REASON_TO_NOT_ATTACH(sp->nr_attached,0)); + if (done && sp->rot180) { + poly_no = first_poly_no(sp); + done = attach(sp,poly_no,point_no,transform_index,attach_point,1,&REASON_TO_NOT_ATTACH(sp->nr_attached-1,0)); + if (!done) + detach(sp,&poly_no,&point_no,&transform_index,&attach_point,0); + } + if (!done) + another_attachment_try = next_attach_try(sp,&poly_no,&point_no,&transform_index); + } + } + + if (sp->identical) { + if (!done) { + if (sp->nr_attached == 0) + done = 1; + else { + detach_until=sp->nr_attached-1; + if (sp->nr_attached < sp->nr_polyominoes) + while (detach_until>0 && REASON_TO_NOT_ATTACH(sp->nr_attached,detach_until)==0) + detach_until--; + while (sp->nr_attached>detach_until) { + if (sp->rot180) + detach(sp,&poly_no,&point_no,&transform_index,&attach_point,1); + detach(sp,&poly_no,&point_no,&transform_index,&attach_point,0); + if (sp->nr_attached+1+sp->rot180 < sp->nr_polyominoes) + for (i=0;inr_polyominoes;i++) + REASON_TO_NOT_ATTACH(sp->nr_attached,i) |= REASON_TO_NOT_ATTACH(sp->nr_attached+1+sp->rot180,i); + } + another_attachment_try = next_attach_try(sp,&poly_no,&point_no,&transform_index); + } + } + } + else { + if (!done) { + if (sp->nr_attached == 0) + done = 1; + else { + if (sp->rot180) + detach(sp,&poly_no,&point_no,&transform_index,&attach_point,1); + detach(sp,&poly_no,&point_no,&transform_index,&attach_point,0); + } + another_attachment_try = next_attach_try(sp,&poly_no,&point_no,&transform_index); + } + } + } + + if (sp->use_bitmaps) + draw_with_bitmaps(mi,sp); + else + draw_without_bitmaps(mi,sp); + + if (sp->nr_attached == sp->nr_polyominoes) + sp->wait = 100; + else + sp->wait = 0; +} + +void +release_polyominoes(ModeInfo * mi) { + int screen; + + if (polyominoeses != NULL) { + for (screen=0;screen - * 11-Nov-90: put into xlock by Steve Zellers - * 16-Oct-90: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' simulator) + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver + * 08-Mar-1995: CAT stuff for ## was tripping up some C compilers. Removed. + * 01-Dec-1993: added patch for AIXV3 from Tom McConnell + * + * 11-Nov-1990: put into xlock by Steve Zellers + * 16-Oct-1990: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' + * simulator) */ #ifdef STANDALONE -# define PROGCLASS "Rotor" -# define HACK_INIT init_rotor -# define HACK_DRAW draw_rotor -# define rotor_opts xlockmore_opts -# define DEFAULTS "*delay: 10000 \n" \ - "*count: 4 \n" \ - "*size: -6 \n" \ - "*cycles: 20 \n" \ - "*ncolors: 200 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* in xscreensaver distribution */ +#define MODE_rotor +#define PROGCLASS "Rotor" +#define HACK_INIT init_rotor +#define HACK_DRAW draw_rotor +#define rotor_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 4 \n" \ + "*cycles: 20 \n" \ + "*size: -6 \n" \ + "*ncolors: 200 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ -# include "xlock.h" /* in xlockmore distribution */ +#include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ +#ifdef MODE_rotor + ModeSpecOpt rotor_opts = -{0, NULL, 0, NULL, NULL}; +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct rotor_description = +{"rotor", "init_rotor", "draw_rotor", "release_rotor", + "refresh_rotor", "init_rotor", (char *) NULL, &rotor_opts, + 100, 4, 100, -6, 64, 0.3, "", + "Shows Tom's Roto-Rooter", 0, NULL}; + +#endif /*- * A 'batchcount' of 3 or 4 works best! */ -#define MAXANGLE 3000.0 /* irrectangular (jwz: was 10000.0) */ +#define MAXANGLE 3000.0 /* irrectangular (was 10000.0) */ /* How many segments to draw per cycle when redrawing */ #define REDRAWSTEP 3 @@ -88,17 +102,31 @@ typedef struct { elem *elements; XPoint *save; int redrawing, redrawpos; + int linewidth; } rotorstruct; -static rotorstruct *rotors = NULL; +static rotorstruct *rotors = (rotorstruct *) NULL; + +static void +free_rotor(rotorstruct *rp) +{ + if (rp->elements != NULL) { + (void) free((void *) rp->elements); + rp->elements = (elem *) NULL; + } + if (rp->save != NULL) { + (void) free((void *) rp->save); + rp->save = (XPoint *) NULL; + } +} void init_rotor(ModeInfo * mi) { - rotorstruct *rp; int x; elem *pelem; unsigned char wasiconified; + rotorstruct *rp; if (rotors == NULL) { if ((rotors = (rotorstruct *) calloc(MI_NUM_SCREENS(mi), @@ -110,8 +138,8 @@ init_rotor(ModeInfo * mi) rp->prevcenterx = rp->centerx; rp->prevcentery = rp->centery; - rp->centerx = MI_WIN_WIDTH(mi) / 2; - rp->centery = MI_WIN_HEIGHT(mi) / 2; + rp->centerx = MI_WIDTH(mi) / 2; + rp->centery = MI_HEIGHT(mi) / 2; rp->redrawing = 0; /* @@ -122,7 +150,7 @@ init_rotor(ModeInfo * mi) */ wasiconified = rp->iconifiedscreen; - rp->iconifiedscreen = MI_WIN_IS_ICONIC(mi); + rp->iconifiedscreen = MI_IS_ICONIC(mi); if (wasiconified && !rp->iconifiedscreen) rp->firsttime = True; @@ -137,21 +165,33 @@ init_rotor(ModeInfo * mi) if (!rp->prevcentery) rp->prevcentery = rp->centery * 12; - rp->num = MI_BATCHCOUNT(mi); + rp->num = MI_COUNT(mi); if (rp->num < 0) { rp->num = NRAND(-rp->num) + 1; if (rp->elements != NULL) { (void) free((void *) rp->elements); - rp->elements = NULL; + rp->elements = (elem *) NULL; } } if (rp->elements == NULL) - rp->elements = (elem *) calloc(rp->num, sizeof (elem)); + if ((rp->elements = (elem *) calloc(rp->num, + sizeof (elem))) == NULL) { + free_rotor(rp); + return; + } rp->nsave = MI_CYCLES(mi); if (rp->nsave <= 1) rp->nsave = 2; if (rp->save == NULL) - rp->save = (XPoint *) calloc(rp->nsave, sizeof (XPoint)); + if ((rp->save = (XPoint *) malloc(rp->nsave * + sizeof (XPoint))) == NULL) { + free_rotor(rp); + return; + } + for (x = 0; x < rp->nsave; x++) { + rp->save[x].x = rp->centerx; + rp->save[x].y = rp->centery; + } pelem = rp->elements; @@ -175,18 +215,14 @@ init_rotor(ModeInfo * mi) rp->angle = (float) NRAND((long) MAXANGLE) / 3.0; rp->forward = rp->firsttime = True; } + rp->linewidth = MI_SIZE(mi); - { - int line_width = MI_SIZE(mi); - if (line_width == 0) - line_width = -5; - if (line_width < 0) - line_width = NRAND(-line_width)+1; - XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), line_width, - LineSolid, CapButt, JoinMiter); - } + if (rp->linewidth == 0) + rp->linewidth = 1; + if (rp->linewidth < 0) + rp->linewidth = NRAND(-rp->linewidth) + 1; - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + MI_CLEARWINDOW(mi); } void @@ -194,12 +230,19 @@ draw_rotor(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - register rotorstruct *rp = &rotors[MI_SCREEN(mi)]; register elem *pelem; int thisx, thisy; int i; int x_1, y_1, x_2, y_2; + rotorstruct *rp; + if (rotors == NULL) + return; + rp = &rotors[MI_SCREEN(mi)]; + if (rp->elements == NULL) + return; + + MI_IS_DRAWN(mi) = True; if (!rp->iconifiedscreen) { thisx = rp->centerx; thisy = rp->centery; @@ -207,6 +250,8 @@ draw_rotor(ModeInfo * mi) thisx = rp->prevcenterx; thisy = rp->prevcentery; } + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), rp->linewidth, + LineSolid, CapButt, JoinMiter); for (i = rp->num, pelem = rp->elements; --i >= 0; pelem++) { if (pelem->radius_drift_max <= pelem->radius_drift_now) { pelem->start_radius = pelem->end_radius; @@ -237,7 +282,7 @@ draw_rotor(ModeInfo * mi) if (rp->firsttime) rp->firsttime = False; else { - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); x_1 = (int) rp->save[rp->rotor].x; y_1 = (int) rp->save[rp->rotor].y; @@ -257,7 +302,7 @@ draw_rotor(ModeInfo * mi) if (++rp->pix >= MI_NPIXELS(mi)) rp->pix = 0; } else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); x_1 = rp->lastx; y_1 = rp->lasty; @@ -317,6 +362,8 @@ draw_rotor(ModeInfo * mi) } } } + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 1, + LineSolid, CapButt, JoinMiter); } void @@ -325,24 +372,25 @@ release_rotor(ModeInfo * mi) if (rotors != NULL) { int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - rotorstruct *rp = &rotors[screen]; - - if (rp->elements != NULL) - (void) free((void *) rp->elements); - if (rp->save != NULL) - (void) free((void *) rp->save); - } + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_rotor(&rotors[screen]); (void) free((void *) rotors); - rotors = NULL; + rotors = (rotorstruct *) NULL; } } void refresh_rotor(ModeInfo * mi) { - rotorstruct *rp = &rotors[MI_SCREEN(mi)]; + rotorstruct *rp; + if (rotors == NULL) + return; + rp = &rotors[MI_SCREEN(mi)]; + + MI_CLEARWINDOW(mi); rp->redrawing = 1; rp->redrawpos = 1; } + +#endif /* MODE_rotor */ diff --git a/hacks/shadebobs.c b/hacks/shadebobs.c index d384605a..d0942bcf 100644 --- a/hacks/shadebobs.c +++ b/hacks/shadebobs.c @@ -45,6 +45,8 @@ char *progclass = "ShadeBobs"; char *defaults [] = { + ".background: black", + ".foreground: white", "*degrees: 0", /* default: Automatic degree calculation */ "*color: random", "*count: 4", diff --git a/hacks/sierpinski.c b/hacks/sierpinski.c index ca22999c..e0a5ac21 100644 --- a/hacks/sierpinski.c +++ b/hacks/sierpinski.c @@ -2,10 +2,12 @@ /* sierpinski --- Sierpinski's triangle fractal */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)sierpinski.c 4.05 97/09/19 xlockmore"; +static const char sccsid[] = "@(#)sierpinski.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1996 by Desmond Daignault +/*- + * Copyright (c) 1996 by Desmond Daignault * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -19,31 +21,47 @@ static const char sccsid[] = "@(#)sierpinski.c 4.05 97/09/19 xlockmore"; * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * + * Dots initially appear where they "should not". Later they get + * "focused". This is correct behavior. + * * Revision History: - * 18-Sep-97: 3D version Antti Kuntsi . - * 20-May-97: Changed the name tri to sierpinski for more compatiblity - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 05-Sep-96: Desmond Daignault Datatimes Incorporated + * 01-Nov-2000: Allocation checks + * 18-Sep-1997: 3D version Antti Kuntsi . + * 20-May-1997: Changed the name tri to sierpinski for more compatiblity + * 10-May-1997: Jamie Zawinski compatible with xscreensaver + * 05-Sep-1996: Desmond Daignault Datatimes Incorporated * . */ #ifdef STANDALONE -# define PROGCLASS "Sierpinski" -# define HACK_INIT init_sierpinski -# define HACK_DRAW draw_sierpinski -# define sierpinski_opts xlockmore_opts -# define DEFAULTS "*delay: 400000 \n" \ - "*count: 2000 \n" \ - "*cycles: 100 \n" \ - "*ncolors: 64 \n" -# define BRIGHT_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ +#define MODE_sierpinski +#define PROGCLASS "Sierpinski" +#define HACK_INIT init_sierpinski +#define HACK_DRAW draw_sierpinski +#define sierpinski_opts xlockmore_opts +#define DEFAULTS "*delay: 400000 \n" \ + "*count: 2000 \n" \ + "*cycles: 100 \n" \ + "*ncolors: 64 \n" +#define BRIGHT_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_sierpinski ModeSpecOpt sierpinski_opts = -{0, NULL, 0, NULL, NULL}; +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct sierpinski_description = +{"sierpinski", "init_sierpinski", "draw_sierpinski", "release_sierpinski", + "refresh_sierpinski", "init_sierpinski", (char *) NULL, &sierpinski_opts, + 400000, 2000, 100, 1, 64, 1.0, "", + "Shows Sierpinski's triangle", 0, NULL}; + +#endif #define MAXCORNERS 4 @@ -52,14 +70,14 @@ typedef struct { int time; int px, py; int total_npoints; - int corners; + int corners; int npoints[MAXCORNERS]; unsigned long colors[MAXCORNERS]; XPoint *pointBuffer[MAXCORNERS]; XPoint vertex[MAXCORNERS]; } sierpinskistruct; -static sierpinskistruct *tris = NULL; +static sierpinskistruct *tris = (sierpinskistruct *) NULL; static void startover(ModeInfo * mi) @@ -68,23 +86,23 @@ startover(ModeInfo * mi) sierpinskistruct *sp = &tris[MI_SCREEN(mi)]; if (MI_NPIXELS(mi) > 2) { - if (sp->corners == 3) { - sp->colors[0] = (NRAND(MI_NPIXELS(mi))); - sp->colors[1] = (sp->colors[0] + MI_NPIXELS(mi) / 7 + + if (sp->corners == 3) { + sp->colors[0] = (NRAND(MI_NPIXELS(mi))); + sp->colors[1] = (sp->colors[0] + MI_NPIXELS(mi) / 7 + NRAND(2 * MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); - sp->colors[2] = (sp->colors[0] + 4 * MI_NPIXELS(mi) / 7 + + sp->colors[2] = (sp->colors[0] + 4 * MI_NPIXELS(mi) / 7 + NRAND(2 * MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); - } else if (sp->corners == 4) { - sp->colors[0] = (NRAND(MI_NPIXELS(mi))); - sp->colors[1] = (sp->colors[0] + MI_NPIXELS(mi) / 7 + - NRAND(MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); - sp->colors[2] = (sp->colors[0] + 3 * MI_NPIXELS(mi) / 7 + - NRAND(MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); - sp->colors[3] = (sp->colors[0] + 5 * MI_NPIXELS(mi) / 7 + - NRAND(MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); - } else { - (void) fprintf(stderr, "colors not set for %d corners\n", sp->corners); - } + } else if (sp->corners == 4) { + sp->colors[0] = (NRAND(MI_NPIXELS(mi))); + sp->colors[1] = (sp->colors[0] + MI_NPIXELS(mi) / 7 + + NRAND(MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); + sp->colors[2] = (sp->colors[0] + 3 * MI_NPIXELS(mi) / 7 + + NRAND(MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); + sp->colors[3] = (sp->colors[0] + 5 * MI_NPIXELS(mi) / 7 + + NRAND(MI_NPIXELS(mi) / 7 + 1)) % MI_NPIXELS(mi); + } else { + (void) fprintf(stderr, "colors not set for %d corners\n", sp->corners); + } } for (j = 0; j < sp->corners; j++) { sp->vertex[j].x = NRAND(sp->width); @@ -93,14 +111,27 @@ startover(ModeInfo * mi) sp->px = NRAND(sp->width); sp->py = NRAND(sp->height); sp->time = 0; - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + + MI_CLEARWINDOW(mi); +} + +static void +free_sierpinski(sierpinskistruct *sp) +{ + int corner; + + for (corner = 0; corner < MAXCORNERS; corner++) + if (sp->pointBuffer[corner] != NULL) { + (void) free((void *) sp->pointBuffer[corner]); + sp->pointBuffer[corner] = (XPoint *) NULL; + } } void init_sierpinski(ModeInfo * mi) { - sierpinskistruct *sp; int i; + sierpinskistruct *sp; if (tris == NULL) { if ((tris = (sierpinskistruct *) calloc(MI_NUM_SCREENS(mi), @@ -109,20 +140,23 @@ init_sierpinski(ModeInfo * mi) } sp = &tris[MI_SCREEN(mi)]; - sp->width = MI_WIN_WIDTH(mi); - sp->height = MI_WIN_HEIGHT(mi); + sp->width = MI_WIDTH(mi); + sp->height = MI_HEIGHT(mi); - sp->total_npoints = MI_BATCHCOUNT(mi); + sp->total_npoints = MI_COUNT(mi); if (sp->total_npoints < 1) sp->total_npoints = 1; - sp->corners = MI_SIZE(mi); + sp->corners = MI_SIZE(mi); if (sp->corners < 3 || sp->corners > 4) { - sp->corners = (LRAND() & 1) + 3; + sp->corners = (int) (LRAND() & 1) + 3; } for (i = 0; i < sp->corners; i++) { if (!sp->pointBuffer[i]) - sp->pointBuffer[i] = (XPoint *) malloc(sp->total_npoints * - sizeof (XPoint)); + if ((sp->pointBuffer[i] = (XPoint *) malloc(sp->total_npoints * + sizeof (XPoint))) == NULL) { + free_sierpinski(sp); + return; + } } startover(mi); } @@ -132,12 +166,19 @@ draw_sierpinski(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - sierpinskistruct *sp = &tris[MI_SCREEN(mi)]; XPoint *xp[MAXCORNERS]; - int i = 0, v; + int i, v; + sierpinskistruct *sp; + + if (tris == NULL) + return; + sp = &tris[MI_SCREEN(mi)]; + if (sp->pointBuffer[0] == NULL) + return; + MI_IS_DRAWN(mi) = True; if (MI_NPIXELS(mi) <= 2) - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); for (i = 0; i < sp->corners; i++) xp[i] = sp->pointBuffer[i]; for (i = 0; i < sp->total_npoints; i++) { @@ -164,21 +205,19 @@ void release_sierpinski(ModeInfo * mi) { if (tris != NULL) { - int screen, i; + int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - for (i = 0; i < MAXCORNERS; i++) - if (tris[screen].pointBuffer[i] != NULL) { - (void) free((void *) tris[screen].pointBuffer[i]); - } - } + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_sierpinski(&tris[screen]); (void) free((void *) tris); - tris = NULL; + tris = (sierpinskistruct *) NULL; } } void refresh_sierpinski(ModeInfo * mi) { - /* Do nothing, it will refresh by itself */ + MI_CLEARWINDOW(mi); } + +#endif /* MODE_sierpinski */ diff --git a/hacks/slip.c b/hacks/slip.c index 5c512436..44672e7b 100644 --- a/hacks/slip.c +++ b/hacks/slip.c @@ -1,11 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * slip --- lots of blits. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* slip --- lots of slipping blits */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)slip.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)slip.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1992 by Scott Draves (spot@cs.cmu.edu) +/*- + * Copyright (c) 1992 by Scott Draves * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -19,27 +21,39 @@ static const char sccsid[] = "@(#)slip.c 4.00 97/01/01 xlockmore"; * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * - * Revision History: - * 12-May-97: jwz@jwz.org: turned into a standalone program. - * 01-Dec-95: Patched for VMS . + * 01-Nov-2000: Allocation checks + * 10-May-1997: Jamie Zawinski compatible with xscreensaver + * 01-Dec-1995: Patched for VMS */ #ifdef STANDALONE -# define PROGCLASS "Slip" -# define HACK_INIT init_slip -# define HACK_DRAW draw_slip -# define slip_opts xlockmore_opts -# define DEFAULTS "*count: 35 \n" \ - "*cycles: 50 \n" \ - "*delay: 50000 \n" \ - "*ncolors: 200 \n" -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -ModeSpecOpt slip_opts = { - 0, NULL, 0, NULL, NULL }; +#define MODE_slip +#define PROGCLASS "Slip" +#define HACK_INIT init_slip +#define HACK_DRAW draw_slip +#define slip_opts xlockmore_opts +#define DEFAULTS "*delay: 50000 \n" \ + "*count: 35 \n" \ + "*cycles: 50 \n" \ + "*ncolors: 200 \n" +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_slip + +ModeSpecOpt slip_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct slip_description = +{"slip", "init_slip", "draw_slip", "release_slip", + "init_slip", "init_slip", (char *) NULL, &slip_opts, + 50000, 35, 50, 1, 64, 1.0, "", + "Shows slipping blits", 0, NULL}; + +#endif typedef struct { int width, height; @@ -47,40 +61,40 @@ typedef struct { int blit_width, blit_height; int mode; int first_time; - int backwards; + int backwards; + short lasthalf; + int stage; + unsigned long r; } slipstruct; -static slipstruct *slips = NULL; +static slipstruct *slips = (slipstruct *) NULL; static short -halfrandom(int mv) +halfrandom(slipstruct *sp, int mv) { - static short lasthalf = 0; unsigned long r; - if (lasthalf) { - r = lasthalf; - lasthalf = 0; + if (sp->lasthalf) { + r = sp->lasthalf; + sp->lasthalf = 0; } else { r = LRAND(); - lasthalf = r >> 16; + sp->lasthalf = (short) (r >> 16); } return r % mv; } static int -erandom(int mv) +erandom(slipstruct *sp, int mv) { - static int stage = 0; - static unsigned long r; int res; - if (0 == stage) { - r = LRAND(); - stage = 7; + if (0 == sp->stage) { + sp->r = LRAND(); + sp->stage = 7; } - res = r & 0xf; - r = r >> 4; - stage--; + res = (int) (sp->r & 0xf); + sp->r = sp->r >> 4; + sp->stage--; if (res & 8) return res & mv; else @@ -88,60 +102,59 @@ erandom(int mv) } static void -prepare_screen(ModeInfo * mi, slipstruct * s) +prepare_screen(ModeInfo * mi, slipstruct * sp) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - int i, n, w = s->width / 20; - int not_solid = halfrandom(10); + int i, n, w = sp->width / 20; + int not_solid = halfrandom(sp, 10); #ifdef STANDALONE /* jwz -- sometimes hack the desktop image! */ - if (halfrandom(2) == 0) - { - grab_screen_image(DefaultScreenOfDisplay (MI_DISPLAY(mi)), - MI_WINDOW(mi)); - return; - } + if (halfrandom(sp, 2) == 0) { + grab_screen_image(DefaultScreenOfDisplay(display), + MI_WINDOW(mi)); + } #endif - s->backwards = LRAND() & 1; /* jwz: go the other way sometimes */ + sp->backwards = (int) (LRAND() & 1); /* jwz: go the other way sometimes */ - if (s->first_time || (0 == halfrandom(10))) { - XClearWindow(display, MI_WINDOW(mi)); + if (sp->first_time || !halfrandom(sp, 10)) { + MI_CLEARWINDOW(mi); n = 300; } else { - if (halfrandom(5)) + if (halfrandom(sp, 5)) return; - if (halfrandom(5)) + if (halfrandom(sp, 5)) n = 100; else n = 2000; } if (MI_NPIXELS(mi) > 2) - XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(MI_NPIXELS(mi)))); - else if (halfrandom(2)) - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(sp, MI_NPIXELS(mi)))); + else if (halfrandom(sp, 2)) + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); else - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); for (i = 0; i < n; i++) { - int ww = ((w/2) + halfrandom(w)); + int ww = ((w / 2) + halfrandom(sp, MAX(w, 1))); + if (not_solid) { if (MI_NPIXELS(mi) > 2) - XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(MI_NPIXELS(mi)))); - else if (halfrandom(2)) - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_PIXEL(mi, halfrandom(sp, MI_NPIXELS(mi)))); + else if (halfrandom(sp, 2)) + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); else - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); } XFillRectangle(display, MI_WINDOW(mi), gc, - halfrandom(s->width - ww), - halfrandom(s->height - ww), + halfrandom(sp, MAX(sp->width - ww, 1)), + halfrandom(sp, MAX(sp->height - ww, 1)), ww, ww); } - s->first_time = 0; + sp->first_time = 0; } static int @@ -167,8 +180,8 @@ init_slip(ModeInfo * mi) } sp = &slips[MI_SCREEN(mi)]; - sp->width = MI_WIN_WIDTH(mi); - sp->height = MI_WIN_HEIGHT(mi); + sp->width = MI_WIDTH(mi); + sp->height = MI_HEIGHT(mi); sp->blit_width = sp->width / 25; sp->blit_height = sp->height / 25; @@ -186,34 +199,40 @@ draw_slip(ModeInfo * mi) Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); - slipstruct *s = &slips[MI_SCREEN(mi)]; int timer; + slipstruct *sp; - timer = MI_BATCHCOUNT(mi) * MI_CYCLES(mi); + if (slips == NULL) + return; + sp = &slips[MI_SCREEN(mi)]; + + timer = MI_COUNT(mi) * MI_CYCLES(mi); + + MI_IS_DRAWN(mi) = True; while (timer--) { - int xi = halfrandom(s->width - s->blit_width); - int yi = halfrandom(s->height - s->blit_height); + int xi = halfrandom(sp, MAX(sp->width - sp->blit_width, 1)); + int yi = halfrandom(sp, MAX(sp->height - sp->blit_height, 1)); double x, y, dx = 0, dy = 0, t, s1, s2; - if (0 == s->nblits_remaining--) { - static int lut[] = + if (0 == sp->nblits_remaining--) { + static int lut[] = {0, 0, 0, 1, 1, 1, 2}; - prepare_screen(mi, s); - s->nblits_remaining = MI_BATCHCOUNT(mi) * - (2000 + halfrandom(1000) + halfrandom(1000)); - if (s->mode == 2) - s->mode = halfrandom(2); + prepare_screen(mi, sp); + sp->nblits_remaining = MI_COUNT(mi) * + (2000 + halfrandom(sp, 1000) + halfrandom(sp, 1000)); + if (sp->mode == 2) + sp->mode = halfrandom(sp, 2); else - s->mode = lut[halfrandom(7)]; + sp->mode = lut[halfrandom(sp, 7)]; } - x = (2 * xi + s->blit_width) / (double) s->width - 1; - y = (2 * yi + s->blit_height) / (double) s->height - 1; + x = (2 * xi + sp->blit_width) / (double) sp->width - 1; + y = (2 * yi + sp->blit_height) / (double) sp->height - 1; /* (x,y) is in biunit square */ - switch (s->mode) { - case 0: /* rotor */ + switch (sp->mode) { + case 0: /* rotor */ dx = x; dy = y; @@ -232,16 +251,17 @@ draw_slip(ModeInfo * mi) s2 = 2 * dx * dy / t; dx = s1 * 5; dy = s2 * 5; - if (s->backwards) { /* jwz: go the other way sometimes */ + + if (sp->backwards) { /* jwz: go the other way sometimes */ dx = -dx; dy = -dy; } break; - case 1: /* shuffle */ - dx = erandom(3); - dy = erandom(3); + case 1: /* shuffle */ + dx = erandom(sp, 3); + dy = erandom(sp, 3); break; - case 2: /* explode */ + case 2: /* explode */ dx = x * 3; dy = y * 3; break; @@ -251,38 +271,46 @@ draw_slip(ModeInfo * mi) int wrap; if (qx < 0 || qy < 0 || - qx >= s->width - s->blit_width || - qy >= s->height - s->blit_height) + qx >= sp->width - sp->blit_width || + qy >= sp->height - sp->blit_height) continue; +/*- +Seems to cause problems using Exceed +with PseudoColor +X Error of failed request: BadGC (invalid GC parameter) +with TrueColor +X Error of failed request: BadDrawable (invalid Pixmap or Window parameter) + Major opcode of failed request: 62 (X_CopyArea) + */ XCopyArea(display, window, window, gc, xi, yi, - s->blit_width, s->blit_height, + sp->blit_width, sp->blit_height, qx, qy); - - switch (s->mode) { + switch (sp->mode) { case 0: /* wrap */ - wrap = s->width - (2 * s->blit_width); - if (qx > wrap) + wrap = sp->width - (2 * sp->blit_width); + if (qx > wrap ) { XCopyArea(display, window, window, gc, qx, qy, - s->blit_width, s->blit_height, + sp->blit_width, sp->blit_height, qx - wrap, qy); - - if (qx < 2 * s->blit_width) + } + if (qx < 2 * sp->blit_width) { XCopyArea(display, window, window, gc, qx, qy, - s->blit_width, s->blit_height, + sp->blit_width, sp->blit_height, qx + wrap, qy); - - wrap = s->height - (2 * s->blit_height); - if (qy > wrap) + } + wrap = sp->height - (2 * sp->blit_height); + if (qy > wrap) { XCopyArea(display, window, window, gc, qx, qy, - s->blit_width, s->blit_height, + sp->blit_width, sp->blit_height, qx, qy - wrap); - - if (qy < 2 * s->blit_height) + } + if (qy < 2 * sp->blit_height) { XCopyArea(display, window, window, gc, qx, qy, - s->blit_width, s->blit_height, + sp->blit_width, sp->blit_height, qx, qy + wrap); + } break; case 1: case 2: @@ -297,6 +325,8 @@ release_slip(ModeInfo * mi) { if (slips != NULL) { (void) free((void *) slips); - slips = NULL; + slips = (slipstruct *) NULL; } } + +#endif /* MODE_slip */ diff --git a/hacks/sonar.c b/hacks/sonar.c index 1988821b..3a3e6ce8 100644 --- a/hacks/sonar.c +++ b/hacks/sonar.c @@ -38,7 +38,7 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * $Revision: 1.20 $ + * $Revision: 1.21 $ * * Version 1.0 April 27, 1998. * - Initial version @@ -1153,7 +1153,12 @@ getping(sonar_info *si, ping_info *pi) while (! timer_expired) { tv.tv_usec=pi->timeout; tv.tv_sec=0; +#if 0 + /* This breaks on BSD, which uses bzero() in the definition of FD_ZERO */ FD_ZERO(&rfds); +#else + memset (&rfds, 0, sizeof(rfds)); +#endif FD_SET(pi->icmpsock,&rfds); /* only wait a little while, in case we raced with the timer expiration. From Valentijn Sessink */ diff --git a/hacks/sphere.c b/hacks/sphere.c index e0a81e3a..c8ca46ca 100644 --- a/hacks/sphere.c +++ b/hacks/sphere.c @@ -1,11 +1,39 @@ -/* -*- Mode: C; tab-width: 4 -*- - * sphere.c --- draw a bunch of shaded spheres - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* sphere --- a bunch of shaded spheres */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)sphere.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)sphere.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright 1988 by Sun Microsystems, Inc. Mountain View, CA. +/*- + * Copyright (c) 1988 by Sun Microsystems + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * 01-Nov-2000: Allocation checks + * 30-May-1997: made it go vertically as well as horizontally. + * 27-May-1997: turned into a standalone program. + * 02-Sep-1993: xlock version David Bagley + * 1988: Revised to use SunView canvas instead of gfxsw Sun Microsystems + * 1982: Orignal Algorithm Tom Duff Lucasfilm Ltd. + */ + +/*- + * original copyright + * ************************************************************************** + * Copyright 1988 by Sun Microsystems, Inc. Mountain View, CA. * * All Rights Reserved * @@ -27,30 +55,37 @@ static const char sccsid[] = "@(#)sphere.c 4.00 97/01/01 xlockmore"; * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * *************************************************************************** - * - * Revision History: - * 30-May-97: jwz@jwz.org: made it go vertically as well as horizontally. - * 27-May-97: jwz@jwz.org: turned into a standalone program. - * 2-Sep-93: xlock version (David Bagley bagleyd@bigfoot.com) - * 1988: Revised to use SunView canvas instead of gfxsw Sun Microsystems - * 1982: Orignal Algorithm Tom Duff Lucasfilm Ltd. */ #ifdef STANDALONE -# define PROGCLASS "Sphere" -# define HACK_INIT init_sphere -# define HACK_DRAW draw_sphere -# define sphere_opts xlockmore_opts -# define DEFAULTS "*delay: 1000 \n" \ - "*ncolors: 64 \n" -# define BRIGHT_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ +#define MODE_sphere +#define PROGCLASS "Sphere" +#define HACK_INIT init_sphere +#define HACK_DRAW draw_sphere +#define sphere_opts xlockmore_opts +#define DEFAULTS "*delay: 1000 \n" \ + "*cycles: 20 \n" \ + "*size: 0 \n" \ + "*ncolors: 64 \n" +#define BRIGHT_COLORS +#include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ -ModeSpecOpt sphere_opts = { - 0, NULL, 0, NULL, NULL }; +#ifdef MODE_sphere + +ModeSpecOpt sphere_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct sphere_description = +{"sphere", "init_sphere", "draw_sphere", "release_sphere", + "refresh_sphere", "init_sphere", (char *) NULL, &sphere_opts, + 5000, 1, 20, 0, 64, 1.0, "", + "Shows a bunch of shaded spheres", 0, NULL}; + +#endif /*- * (NX, NY, NZ) is the light source vector -- length should be 100 @@ -69,11 +104,12 @@ typedef struct { int color; int x, y; int dirx, diry; + int shadowx, shadowy; int maxx, maxy; XPoint *points; } spherestruct; -static spherestruct *spheres = NULL; +static spherestruct *spheres = (spherestruct *) NULL; void init_sphere(ModeInfo * mi) @@ -87,17 +123,23 @@ init_sphere(ModeInfo * mi) } sp = &spheres[MI_SCREEN(mi)]; - if (sp->points) { + if (sp->points != NULL) { (void) free((void *) sp->points); - sp->points = NULL; + sp->points = (XPoint *) NULL; + } + sp->width = MAX(MI_WIDTH(mi), 4); + sp->height = MAX(MI_HEIGHT(mi), 4); + if ((sp->points = (XPoint *) malloc(MIN(sp->width, sp->height) * + sizeof (XPoint))) == NULL) { + return; } - sp->width = MI_WIN_WIDTH(mi); - sp->height = MI_WIN_HEIGHT(mi); - sp->points = (XPoint *) malloc(sp->height * sizeof (XPoint)); - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + MI_CLEARWINDOW(mi); sp->dirx = 1; + sp->x = sp->radius; + sp->shadowx = (LRAND() & 1) ? 1 : -1; + sp->shadowy = (LRAND() & 1) ? 1 : -1; } void @@ -105,19 +147,27 @@ draw_sphere(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - spherestruct *sp = &spheres[MI_SCREEN(mi)]; - int minx = 0, maxx = 0, miny = 0, maxy = 0, npts = 0; + int sqrd, nd; + register int minx = 0, maxx = 0, miny = 0, maxy = 0, npts = 0; + spherestruct *sp; + if (spheres == NULL) + return; + sp = &spheres[MI_SCREEN(mi)]; + if (sp->points == NULL) + return; + + MI_IS_DRAWN(mi) = True; if ((sp->dirx && ABS(sp->x) >= sp->radius) || (sp->diry && ABS(sp->y) >= sp->radius)) { sp->radius = NRAND(MIN(sp->width / 2, sp->height / 2) - 1) + 1; if (LRAND() & 1) { - sp->dirx = (LRAND() & 1) * 2 - 1; + sp->dirx = (int) (LRAND() & 1) * 2 - 1; sp->diry = 0; } else { sp->dirx = 0; - sp->diry = (LRAND() & 1) * 2 - 1; + sp->diry = (int) (LRAND() & 1) * 2 - 1; } sp->x0 = NRAND(sp->width); sp->y0 = NRAND(sp->height); @@ -164,7 +214,7 @@ draw_sphere(ModeInfo * mi) if (sp->x0 + sp->maxx >= sp->width) maxx = sp->width - sp->x0; } - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); if (sp->dirx) XDrawLine(display, MI_WINDOW(mi), gc, @@ -176,26 +226,30 @@ draw_sphere(ModeInfo * mi) if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, sp->color)); else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); - if (sp->dirx) + if (sp->dirx) { + sqrd = sp->radius * sp->radius - sp->x * sp->x; + nd = NX * sp->shadowx * sp->x; for (sp->y = miny; sp->y <= maxy; sp->y++) - if ((NRAND(sp->radius * NR)) <= - (NX * sp->x + NY * sp->y + NZ * - SQRT(sp->radius * sp->radius - sp->x * sp->x - sp->y * sp->y))) { + if ((NRAND(sp->radius * NR)) <= nd + NY * sp->shadowy * sp->y + + NZ * SQRT(sqrd - sp->y * sp->y)) { sp->points[npts].x = sp->x + sp->x0; sp->points[npts].y = sp->y + sp->y0; npts++; } - if (sp->diry) + } + if (sp->diry) { + sqrd = sp->radius * sp->radius - sp->y * sp->y; + nd = NY * sp->shadowy * sp->y; for (sp->x = minx; sp->x <= maxx; sp->x++) - if ((NRAND(sp->radius * NR)) <= - (NX * sp->x + NY * sp->y + NZ * - SQRT(sp->radius * sp->radius - sp->x * sp->x - sp->y * sp->y))) { + if ((NRAND(sp->radius * NR)) <= NX * sp->shadowx * sp->x + nd + + NZ * SQRT(sqrd - sp->x * sp->x)) { sp->points[npts].x = sp->x + sp->x0; sp->points[npts].y = sp->y + sp->y0; npts++; } + } XDrawPoints(display, MI_WINDOW(mi), gc, sp->points, npts, CoordModeOrigin); if (sp->dirx == 1) { sp->x++; @@ -228,19 +282,26 @@ release_sphere(ModeInfo * mi) if (sp->points) { (void) free((void *) sp->points); - sp->points = NULL; + /* sp->points = NULL; */ } } (void) free((void *) spheres); - spheres = NULL; + spheres = (spherestruct *) NULL; } } void refresh_sphere(ModeInfo * mi) { - spherestruct *sp = &spheres[MI_SCREEN(mi)]; + spherestruct *sp; + + if (spheres == NULL) + return; + sp = &spheres[MI_SCREEN(mi)]; + + MI_CLEARWINDOW(mi); - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); sp->x = -sp->radius; } + +#endif /* MODE_sphere */ diff --git a/hacks/spiral.c b/hacks/spiral.c index 10d319a6..214cbfbb 100644 --- a/hacks/spiral.c +++ b/hacks/spiral.c @@ -1,11 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * spiral --- low cpu screen design. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* spiral --- spiraling dots */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)spiral.c 4.00 97/01/01 xlockmore"; +static const char sccsid[] = "@(#)spiral.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1994 Darrick Brown. +/*- + * Copyright (c) 1994 by Darrick Brown. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -19,38 +21,48 @@ static const char sccsid[] = "@(#)spiral.c 4.00 97/01/01 xlockmore"; * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * - * Idea based on a graphics demo I saw a *LONG* time ago. - * - * See xlock.c for copying information. - * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 24-Jul-95: Fix to allow cycles not to have an arbitrary value by - * Peter Schmitzberger (schmitz@coma.sbg.ac.at). - * 06-Mar-95: Finished cleaning up and final testing. - * Copyright (c) 1994 by Darrick Brown. + * 01-Nov-2000: Allocation checks + * 10-May-1997: jwz@jwz.org: turned into a standalone program. + * 24-Jul-1995: Fix to allow cycles not to have an arbitrary value by + * Peter Schmitzberger (schmitz@coma.sbg.ac.at). + * 06-Mar-1995: Finished cleaning up and final testing. + * 03-Mar-1995: Cleaned up code. + * 12-Jul-1994: Written. * - * 03-Mar-95: Cleaned up code. - * 12-Jul-94: Written. + * Low CPU usage mode. + * Idea based on a graphics demo I saw a *LONG* time ago. */ #ifdef STANDALONE -# define PROGCLASS "Spiral" -# define HACK_INIT init_spiral -# define HACK_DRAW draw_spiral -# define spiral_opts xlockmore_opts -# define DEFAULTS "*count: 40 \n" \ - "*cycles: 350 \n" \ - "*delay: 50000 \n" \ - "*ncolors: 64 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ +#define MODE_spiral +#define PROGCLASS "Spiral" +#define HACK_INIT init_spiral +#define HACK_DRAW draw_spiral +#define spiral_opts xlockmore_opts +#define DEFAULTS "*delay: 50000 \n" \ + "*count: 40 \n" \ + "*cycles: 350 \n" \ + "*ncolors: 64 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ -ModeSpecOpt spiral_opts = { - 0, NULL, 0, NULL, NULL }; +#ifdef MODE_spiral + +ModeSpecOpt spiral_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct spiral_description = +{"spiral", "init_spiral", "draw_spiral", "release_spiral", + "refresh_spiral", "init_spiral", (char *) NULL, &spiral_opts, + 5000, -40, 350, 1, 64, 1.0, "", + "Shows a helical locus of points", 0, NULL}; + +#endif #define MAXTRAIL 512 /* The length of the trail */ #define MAXDOTS 40 @@ -62,6 +74,7 @@ ModeSpecOpt spiral_opts = { /* How many segments to draw per cycle when redrawing */ #define REDRAWSTEP 3 + typedef struct { float hx, hy, ha, hr; } Traildots; @@ -82,7 +95,7 @@ typedef struct { int redrawing, redrawpos; } spiralstruct; -static spiralstruct *spirals = NULL; +static spiralstruct *spirals = (spiralstruct *) NULL; static void draw_dots(ModeInfo * mi, int in); @@ -122,16 +135,19 @@ init_spiral(ModeInfo * mi) } sp = &spirals[MI_SCREEN(mi)]; - sp->width = MI_WIN_WIDTH(mi); - sp->height = MI_WIN_HEIGHT(mi); + sp->width = MI_WIDTH(mi); + sp->height = MI_HEIGHT(mi); - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + MI_CLEARWINDOW(mi); /* Init */ sp->nlength = MI_CYCLES(mi); if (!sp->traildots) - sp->traildots = (Traildots *) malloc(sp->nlength * sizeof (Traildots)); + if ((sp->traildots = (Traildots *) malloc(sp->nlength * + sizeof (Traildots))) == NULL) { + return; + } /* initialize the allocated array */ for (i = 0; i < sp->nlength; i++) { @@ -167,7 +183,7 @@ init_spiral(ModeInfo * mi) sp->traildots[sp->inc].hr = sp->radius; sp->inc++; - sp->dots = MI_BATCHCOUNT(mi); + sp->dots = MI_COUNT(mi); if (sp->dots < -MINDOTS) sp->dots = NRAND(sp->dots - MINDOTS + 1) + MINDOTS; /* Absolute minimum */ @@ -180,11 +196,18 @@ draw_spiral(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - spiralstruct *sp = &spirals[MI_SCREEN(mi)]; int i, j; + spiralstruct *sp; + + if (spirals == NULL) + return; + sp = &spirals[MI_SCREEN(mi)]; + if (sp->traildots == NULL) + return; + MI_IS_DRAWN(mi) = True; if (sp->erase == 1) { - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); draw_dots(mi, sp->inc); } sp->cx += sp->dx; @@ -252,7 +275,7 @@ draw_spiral(ModeInfo * mi) if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, (int) sp->colors)); else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); draw_dots(mi, sp->inc); sp->inc++; @@ -286,15 +309,22 @@ release_spiral(ModeInfo * mi) (void) free((void *) sp->traildots); } (void) free((void *) spirals); - spirals = NULL; + spirals = (spiralstruct *) NULL; } } void refresh_spiral(ModeInfo * mi) { - spiralstruct *sp = &spirals[MI_SCREEN(mi)]; + spiralstruct *sp; + if (spirals == NULL) + return; + sp = &spirals[MI_SCREEN(mi)]; + + MI_CLEARWINDOW(mi); sp->redrawing = 1; sp->redrawpos = 0; } + +#endif /* MODE_spiral */ diff --git a/hacks/spotlight.c b/hacks/spotlight.c index 209a67c8..71c190d4 100644 --- a/hacks/spotlight.c +++ b/hacks/spotlight.c @@ -217,6 +217,8 @@ onestep (Display *dpy, Window window) char *progclass = "Spotlight"; char *defaults [] = { + ".background: black", + ".foreground: white", "*dontClearRoot: True", #ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */ diff --git a/hacks/starfish.c b/hacks/starfish.c index 070c0341..c0cf0757 100644 --- a/hacks/starfish.c +++ b/hacks/starfish.c @@ -10,6 +10,7 @@ */ #include +#include #include /* for gettimeofday() */ #include "screenhack.h" #include "spline.h" diff --git a/hacks/strange.c b/hacks/strange.c index a1bda34f..f8f88a66 100644 --- a/hacks/strange.c +++ b/hacks/strange.c @@ -1,11 +1,13 @@ -/* -*- Mode: C; tab-width: 4 -*- - * strange --- Strange attractors are not so hard to find... - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* strange --- strange attractors */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)strange.c 4.02 97/04/01 xlockmore"; +static const char sccsid[] = "@(#)strange.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1997 by Massimino Pascal (Pascal.Massimon@ens.fr) +/*- + * Copyright (c) 1997 by Massimino Pascal * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,28 +22,41 @@ static const char sccsid[] = "@(#)strange.c 4.02 97/04/01 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 30-Jul-98: sineswiper@resonatorsoft.com: added curve factor (discovered - * while experimenting with the Gauss_Rand function). - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * Made it render into an offscreen bitmap and then copy - * that onto the screen, to reduce flicker. + * 01-Nov-2000: Allocation checks + * 10-May-1997: jwz@jwz.org: turned into a standalone program. + * Made it render into an offscreen bitmap and then copy + * that onto the screen, to reduce flicker. + * + * strange attractors are not so hard to find... */ #ifdef STANDALONE -# define PROGCLASS "Strange" -# define HACK_INIT init_strange -# define HACK_DRAW draw_strange -# define strange_opts xlockmore_opts -# define DEFAULTS "*delay: 2000 \n" \ - "*ncolors: 100 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ +#define MODE_strange +#define PROGCLASS "Strange" +#define HACK_INIT init_strange +#define HACK_DRAW draw_strange +#define strange_opts xlockmore_opts +#define DEFAULTS "*delay: 2000 \n" \ + "*ncolors: 100 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ -/*****************************************************/ -/*****************************************************/ +#ifdef MODE_strange + +ModeSpecOpt strange_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct strange_description = +{"strange", "init_strange", "draw_strange", "release_strange", + "init_strange", "init_strange", (char *) NULL, &strange_opts, + 1000, 1, 1, 1, 64, 1.0, "", + "Shows strange attractors", 0, NULL}; + +#endif typedef float DBL; typedef int PRM; @@ -55,52 +70,33 @@ typedef int PRM; #define DBL_To_PRM(x) (PRM)( (DBL)(UNIT)*(x) ) -#define DO_FOLD(a) (a)<0 ? -Fold[ (-(a))&(UNIT2-1) ] : Fold[ (a)&(UNIT2-1) ] +#define DO_FOLD(a) (a)<0 ? -A->Fold[ (-(a))&(UNIT2-1) ] : A->Fold[ (a)&(UNIT2-1) ] -/* - #define DO_FOLD(a) (a)<-UNIT2 ? -Fold[(-(a))%UNIT2] : (a)<0 ? -Fold[ -(a) ] - - : \ (a)>UNIT2 ? Fold[ (a)%UNIT2 ] : Fold[ (a) ] */ -/* #define DO_FOLD(a) DBL_To_PRM( sin( (DBL)(a)/UNIT ) ) */ -/* - #define DO_FOLD(a) (a)<0 ? DBL_To_PRM( exp( 16.0*(a)/UNIT2 ) )-1.0 : \ - DBL_To_PRM( 1.0-exp( -16.0*(a)/UNIT2 ) ) */ +#if 0 +#define DO_FOLD(a) (a)<-UNIT2 ? -A->Fold[(-(a))%UNIT2] : (a)<0 ? -A->Fold[ -(a) ] :\ +(a)>UNIT2 ? A->Fold[ (a)%UNIT2 ] : A->Fold[ (a) ] +#define DO_FOLD(a) DBL_To_PRM( sin( (DBL)(a)/UNIT ) ) +#define DO_FOLD(a) (a)<0 ? DBL_To_PRM( exp( 16.0*(a)/UNIT2 ) )-1.0 : \ +DBL_To_PRM( 1.0-exp( -16.0*(a)/UNIT2 ) ) +#endif /******************************************************************/ #define MAX_PRM 3*5 -typedef struct { +typedef struct _ATTRACTOR { DBL Prm1[MAX_PRM], Prm2[MAX_PRM]; - void (*Iterate) (PRM, PRM, PRM *, PRM *); + PRM Prm[MAX_PRM], *Fold; + void (*Iterate) (struct _ATTRACTOR *, PRM, PRM, PRM *, PRM *); XPoint *Buffer1, *Buffer2; int Cur_Pt, Max_Pt; int Col, Count, Speed; int Width, Height; - Pixmap dbuf; /* jwz */ - GC dbuf_gc; + Pixmap dbuf; /* jwz */ + GC dbuf_gc; } ATTRACTOR; -static ATTRACTOR *Root; -static PRM xmin, xmax, ymin, ymax; -static PRM Prm[MAX_PRM]; -static PRM *Fold = NULL; - -static int curve; - -static XrmOptionDescRec opts[] = -{ - {"-curve", ".strange.curve", XrmoptionSepArg, (caddr_t) "10"}, -}; -static OptionStruct desc[] = -{ - {"-curve", "set the curve factor of the attractors"}, -}; - -ModeSpecOpt strange_opts = { 1, opts, 0, NULL, desc }; - -/******************************************************************/ -/******************************************************************/ +static ATTRACTOR *Root = (ATTRACTOR *) NULL; static DBL Amp_Prm[MAX_PRM] = { @@ -118,11 +114,10 @@ static DBL Mid_Prm[MAX_PRM] = static DBL Gauss_Rand(DBL c, DBL A, DBL S) { - DBL y,z; + DBL y; y = (DBL) LRAND() / MAXRAND; - z = curve / 10; - y = A * (z - exp(-y * y * S)) / (z - exp(-S)); + y = A * (1.0 - exp(-y * y * S)) / (1.0 - exp(-S)); if (NRAND(2)) return (c + y); else @@ -143,7 +138,7 @@ Random_Prm(DBL * Prm) /* 2 examples of non-linear map */ static void -Iterate_X2(PRM x, PRM y, PRM * xo, PRM * yo) +Iterate_X2(ATTRACTOR * A, PRM x, PRM y, PRM * xo, PRM * yo) { PRM xx, yy, xy, x2y, y2x, Tmp; @@ -153,16 +148,16 @@ Iterate_X2(PRM x, PRM y, PRM * xo, PRM * yo) y2x = (yy * x) / UNIT; xy = (x * y) / UNIT; - Tmp = Prm[1] * xx + Prm[2] * xy + Prm[3] * yy + Prm[4] * x2y; - Tmp = Prm[0] - y + (Tmp / UNIT); + Tmp = A->Prm[1] * xx + A->Prm[2] * xy + A->Prm[3] * yy + A->Prm[4] * x2y; + Tmp = A->Prm[0] - y + (Tmp / UNIT); *xo = DO_FOLD(Tmp); - Tmp = Prm[6] * xx + Prm[7] * xy + Prm[8] * yy + Prm[9] * y2x; - Tmp = Prm[5] + x + (Tmp / UNIT); + Tmp = A->Prm[6] * xx + A->Prm[7] * xy + A->Prm[8] * yy + A->Prm[9] * y2x; + Tmp = A->Prm[5] + x + (Tmp / UNIT); *yo = DO_FOLD(Tmp); } static void -Iterate_X3(PRM x, PRM y, PRM * xo, PRM * yo) +Iterate_X3(ATTRACTOR * A, PRM x, PRM y, PRM * xo, PRM * yo) { PRM xx, yy, xy, x2y, y2x, Tmp_x, Tmp_y, Tmp_z; @@ -172,60 +167,85 @@ Iterate_X3(PRM x, PRM y, PRM * xo, PRM * yo) y2x = (yy * x) / UNIT; xy = (x * y) / UNIT; - Tmp_x = Prm[1] * xx + Prm[2] * xy + Prm[3] * yy + Prm[4] * x2y; - Tmp_x = Prm[0] - y + (Tmp_x / UNIT); + Tmp_x = A->Prm[1] * xx + A->Prm[2] * xy + A->Prm[3] * yy + A->Prm[4] * x2y; + Tmp_x = A->Prm[0] - y + (Tmp_x / UNIT); Tmp_x = DO_FOLD(Tmp_x); - Tmp_y = Prm[6] * xx + Prm[7] * xy + Prm[8] * yy + Prm[9] * y2x; - Tmp_y = Prm[5] + x + (Tmp_y / UNIT); + Tmp_y = A->Prm[6] * xx + A->Prm[7] * xy + A->Prm[8] * yy + A->Prm[9] * y2x; + Tmp_y = A->Prm[5] + x + (Tmp_y / UNIT); Tmp_y = DO_FOLD(Tmp_y); - Tmp_z = Prm[11] * xx + Prm[12] * xy + Prm[13] * yy + Prm[14] * y2x; - Tmp_z = Prm[10] + x + (Tmp_z / UNIT); + Tmp_z = A->Prm[11] * xx + A->Prm[12] * xy + A->Prm[13] * yy + A->Prm[14] * y2x; + Tmp_z = A->Prm[10] + x + (Tmp_z / UNIT); Tmp_z = UNIT + Tmp_z * Tmp_z / UNIT; *xo = (Tmp_x * UNIT) / Tmp_z; *yo = (Tmp_y * UNIT) / Tmp_z; } -static void (*Funcs[2]) (PRM, PRM, PRM *, PRM *) = { +static void (*Funcs[2]) (ATTRACTOR *, PRM, PRM, PRM *, PRM *) = { Iterate_X2, Iterate_X3 }; /***************************************************************/ +static void +free_strange(Display *display, ATTRACTOR *A) +{ + if (A->Buffer1 != NULL) { + (void) free((void *) A->Buffer1); + A->Buffer1 = (XPoint *) NULL; + } + if (A->Buffer2 != NULL) { + (void) free((void *) A->Buffer2); + A->Buffer2 = (XPoint *) NULL; + } + if (A->dbuf) { + XFreePixmap(display, A->dbuf); + A->dbuf = None; + } + if (A->dbuf_gc) { + XFreeGC(display, A->dbuf_gc); + A->dbuf_gc = None; + } + if (A->Fold != NULL) { + (void) free((void *) A->Fold); + A->Fold = (PRM *) NULL; + } +} + void draw_strange(ModeInfo * mi) { - int i, j, n, Max_Colors, Cur_Pt; + int i, j, n, Cur_Pt; PRM x, y, xo, yo; DBL u; - ATTRACTOR *A; XPoint *Buf; - Display *display; - GC gc; - Window window; + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); DBL Lx, Ly; - void (*Iterate) (PRM, PRM, PRM *, PRM *); - - display = MI_DISPLAY(mi); - window = MI_WINDOW(mi); - gc = MI_GC(mi); - Max_Colors = MI_NPIXELS(mi); + void (*Iterate) (ATTRACTOR *, PRM, PRM, PRM *, PRM *); + PRM xmin, xmax, ymin, ymax; + ATTRACTOR *A; + if (Root == NULL) + return; A = &Root[MI_SCREEN(mi)]; + if (A->Fold == NULL) + return; Cur_Pt = A->Cur_Pt; Iterate = A->Iterate; u = (DBL) (A->Count) / 1000.0; for (j = MAX_PRM - 1; j >= 0; --j) - Prm[j] = DBL_To_PRM((1.0 - u) * A->Prm1[j] + u * A->Prm2[j]); + A->Prm[j] = DBL_To_PRM((1.0 - u) * A->Prm1[j] + u * A->Prm2[j]); x = y = DBL_To_PRM(.0); for (n = SKIP_FIRST; n; --n) { - (*Iterate) (x, y, &xo, &yo); + (*Iterate) (A, x, y, &xo, &yo); x = xo + NRAND(8) - 4; y = yo + NRAND(8) - 4; } @@ -239,9 +259,9 @@ draw_strange(ModeInfo * mi) Lx = (DBL) A->Width / UNIT / 2.2; Ly = (DBL) A->Height / UNIT / 2.2; for (n = A->Max_Pt; n; --n) { - (*Iterate) (x, y, &xo, &yo); - Buf->x = (short) (Lx * (x + DBL_To_PRM(1.1))); - Buf->y = (short) (Ly * (DBL_To_PRM(1.1) - y)); + (*Iterate) (A, x, y, &xo, &yo); + Buf->x = (int) (Lx * (x + DBL_To_PRM(1.1))); + Buf->y = (int) (Ly * (DBL_To_PRM(1.1) - y)); /* (void) fprintf( stderr, "X,Y: %d %d ", Buf->x, Buf->y ); */ Buf++; A->Cur_Pt++; @@ -257,34 +277,30 @@ draw_strange(ModeInfo * mi) y = yo + NRAND(8) - 4; } - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + MI_IS_DRAWN(mi) = True; - if (A->dbuf) /* jwz */ - { - XSetForeground(display, A->dbuf_gc, 0); -/* XDrawPoints(display, A->dbuf, A->dbuf_gc, A->Buffer1, - Cur_Pt,CoordModeOrigin);*/ - XFillRectangle(display, A->dbuf, A->dbuf_gc, 0,0, A->Width, A->Height); - } - else - XDrawPoints(display, window, gc, A->Buffer1, Cur_Pt, CoordModeOrigin); + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); - if (Max_Colors < 2) - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); + if (A->dbuf != None) { /* jwz */ + XSetForeground(display, A->dbuf_gc, 0); +/* XDrawPoints(display, A->dbuf, A->dbuf_gc, A->Buffer1, + Cur_Pt,CoordModeOrigin); */ + XFillRectangle(display, A->dbuf, A->dbuf_gc, 0, 0, A->Width, A->Height); + } else + XDrawPoints(display, window, gc, A->Buffer1, Cur_Pt, CoordModeOrigin); + + if (MI_NPIXELS(mi) < 2) + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); else - XSetForeground(display, gc, MI_PIXEL(mi, A->Col % Max_Colors)); + XSetForeground(display, gc, MI_PIXEL(mi, A->Col % MI_NPIXELS(mi))); - if (A->dbuf) - { + if (A->dbuf != None) { XSetForeground(display, A->dbuf_gc, 1); XDrawPoints(display, A->dbuf, A->dbuf_gc, A->Buffer2, A->Cur_Pt, - CoordModeOrigin); - } - else - XDrawPoints(display, window, gc, A->Buffer2, A->Cur_Pt, CoordModeOrigin); - - if (A->dbuf) - XCopyPlane(display, A->dbuf, window, gc, 0,0,A->Width,A->Height,0,0, 1); + CoordModeOrigin); + XCopyPlane(display, A->dbuf, window, gc, 0, 0, A->Width, A->Height, 0, 0, 1); + } else + XDrawPoints(display, window, gc, A->Buffer2, A->Cur_Pt, CoordModeOrigin); Buf = A->Buffer1; A->Buffer1 = A->Buffer2; @@ -309,23 +325,26 @@ draw_strange(ModeInfo * mi) void init_strange(ModeInfo * mi) { + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); ATTRACTOR *Attractor; - curve = get_integer_resource ("curve", "Integer"); - if (curve <= 0) curve = 10; - if (Root == NULL) { - Root = (ATTRACTOR *) calloc( - MI_NUM_SCREENS(mi), sizeof (ATTRACTOR)); - if (Root == NULL) + if ((Root = (ATTRACTOR *) calloc(MI_NUM_SCREENS(mi), + sizeof (ATTRACTOR))) == NULL) return; } - if (Fold == NULL) { + Attractor = &Root[MI_SCREEN(mi)]; + + if (Attractor->Fold == NULL) { int i; - Fold = (PRM *) calloc(UNIT2 + 1, sizeof (PRM)); - if (Fold == NULL) + if ((Attractor->Fold = (PRM *) calloc(UNIT2 + 1, + sizeof (PRM))) == NULL) { + free_strange(display, Attractor); return; + } for (i = 0; i <= UNIT2; ++i) { DBL x; @@ -336,21 +355,25 @@ init_strange(ModeInfo * mi) /* x = x*(1.0-x)*4.0; */ x = (DBL) (i) / UNIT; x = sin(x); - Fold[i] = DBL_To_PRM(x); + Attractor->Fold[i] = DBL_To_PRM(x); } } - Attractor = &Root[MI_SCREEN(mi)]; - - Attractor->Buffer1 = (XPoint *) calloc(MAX_POINTS, sizeof (XPoint)); if (Attractor->Buffer1 == NULL) - goto Abort; - Attractor->Buffer2 = (XPoint *) calloc(MAX_POINTS, sizeof (XPoint)); + if ((Attractor->Buffer1 = (XPoint *) calloc(MAX_POINTS, + sizeof (XPoint))) == NULL) { + free_strange(display, Attractor); + return; + } if (Attractor->Buffer2 == NULL) - goto Abort; + if ((Attractor->Buffer2 = (XPoint *) calloc(MAX_POINTS, + sizeof (XPoint))) == NULL) { + free_strange(display, Attractor); + return; + } Attractor->Max_Pt = MAX_POINTS; - Attractor->Width = MI_WIN_WIDTH(mi); - Attractor->Height = MI_WIN_HEIGHT(mi); + Attractor->Width = MI_WIDTH(mi); + Attractor->Height = MI_HEIGHT(mi); Attractor->Cur_Pt = 0; Attractor->Count = 0; Attractor->Col = NRAND(MI_NPIXELS(mi)); @@ -359,37 +382,41 @@ init_strange(ModeInfo * mi) Attractor->Iterate = Funcs[NRAND(2)]; Random_Prm(Attractor->Prm1); Random_Prm(Attractor->Prm2); +#ifndef NO_DBUF + if (Attractor->dbuf != None) + XFreePixmap(display, Attractor->dbuf); + Attractor->dbuf = XCreatePixmap(display, window, + Attractor->Width, Attractor->Height, 1); + /* Allocation checked */ + if (Attractor->dbuf != None) { + XGCValues gcv; - Attractor->dbuf = XCreatePixmap(MI_DISPLAY(mi), MI_WINDOW(mi), - Attractor->Width, Attractor->Height, 1); - if (Attractor->dbuf) - { - XGCValues gcv; gcv.foreground = 0; gcv.background = 0; + gcv.graphics_exposures = False; gcv.function = GXcopy; - Attractor->dbuf_gc = XCreateGC(MI_DISPLAY(mi), Attractor->dbuf, - GCForeground|GCBackground|GCFunction, - &gcv); - XFillRectangle(MI_DISPLAY(mi), Attractor->dbuf, - Attractor->dbuf_gc, 0,0, Attractor->Width, - Attractor->Height); - XSetBackground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi)); - XSetFunction(MI_DISPLAY(mi), MI_GC(mi), GXcopy); - } - - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); - return; - - Abort: - if (Attractor->Buffer1 != NULL) - free(Attractor->Buffer1); - if (Attractor->Buffer2 != NULL) - free(Attractor->Buffer2); - Attractor->Buffer1 = NULL; - Attractor->Buffer2 = NULL; - Attractor->Cur_Pt = 0; - return; + + if (Attractor->dbuf_gc != None) + XFreeGC(display, Attractor->dbuf_gc); + + if ((Attractor->dbuf_gc = XCreateGC(display, Attractor->dbuf, + GCForeground | GCBackground | GCGraphicsExposures | GCFunction, + &gcv)) == None) { + XFreePixmap(display, Attractor->dbuf); + Attractor->dbuf = None; + } else { + XFillRectangle(display, Attractor->dbuf, Attractor->dbuf_gc, + 0, 0, Attractor->Width, Attractor->Height); + XSetBackground(display, gc, MI_BLACK_PIXEL(mi)); + XSetFunction(display, gc, GXcopy); + } + } +#endif + + MI_CLEARWINDOW(mi); + + /* Do not want any exposure events from XCopyPlane */ + XSetGraphicsExposures(display, MI_GC(mi), False); } /***************************************************************/ @@ -397,24 +424,14 @@ init_strange(ModeInfo * mi) void release_strange(ModeInfo * mi) { - int i; + if (Root != NULL) { + int screen; - if (Root == NULL) - return; - - for (i = 0; i < MI_NUM_SCREENS(mi); ++i) { - if (Root[i].Buffer1 != NULL) - free(Root[i].Buffer1); - if (Root[i].Buffer2 != NULL) - free(Root[i].Buffer2); - if (Root[i].dbuf) - XFreePixmap(MI_DISPLAY(mi), Root[i].dbuf); - if (Root[i].dbuf_gc) - XFreeGC(MI_DISPLAY(mi), Root[i].dbuf_gc); + for (screen = 0; screen < MI_NUM_SCREENS(mi); ++screen) + free_strange(MI_DISPLAY(mi), &Root[screen]); + (void) free((void *) Root); + Root = (ATTRACTOR *) NULL; } - free(Root); - Root = NULL; - if (Fold != NULL) - free(Fold); - Fold = NULL; } + +#endif /* MODE_strange */ diff --git a/hacks/thornbird.c b/hacks/thornbird.c new file mode 100644 index 00000000..eb35ae2b --- /dev/null +++ b/hacks/thornbird.c @@ -0,0 +1,270 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* thornbird --- continuously varying Thornbird set */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)thornbird.c 5.00 2000/11/01 xlockmore"; + +#endif + +/*- + * Copyright (c) 1996 by Tim Auckland + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * "thornbird" shows a view of the "Bird in a Thornbush" fractal, + * continuously varying the three free parameters. + * + * Revision History: + * 01-Nov-2000: Allocation checks + * 04-Jun-1999: 3D tumble added by Tim Auckland + * 31-Jul-1997: Adapted from discrete.c Copyright (c) 1996 by Tim Auckland + */ + +#ifdef STANDALONE +#define MODE_thornbird +#define PROGCLASS "Thornbird" +#define HACK_INIT init_thornbird +#define HACK_DRAW draw_thornbird +#define thornbird_opts xlockmore_opts +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 800 \n" \ + "*cycles: 16 \n" \ + "*ncolors: 64 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_thornbird + +ModeSpecOpt thornbird_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct thornbird_description = +{"thornbird", "init_thornbird", "draw_thornbird", "release_thornbird", + "refresh_thornbird", "init_thornbird", (char *) NULL, þbird_opts, + 1000, 800, 16, 1, 64, 1.0, "", + "Shows an animated Bird in a Thorn Bush fractal map", 0, NULL}; + +#endif + +#define balance_rand(v) ((LRAND()/MAXRAND*(v))-((v)/2)) /* random around 0 */ + +typedef struct { + int maxx; + int maxy; /* max of the screen */ + double a; + double b; + double c; + double d; + double e; + double i; + double j; /* thornbird parameters */ + struct { + double f1; + double f2; + } liss; + struct { + double theta; + double dtheta; + double phi; + double dphi; + } tumble; + int inc; + int pix; + int count; + int nbuffers; + XPoint **pointBuffer; /* pointer for XDrawPoints */ +} thornbirdstruct; + +static thornbirdstruct *thornbirds = (thornbirdstruct *) NULL; + +static void +free_thornbird(thornbirdstruct *hp) +{ + if (hp->pointBuffer != NULL) { + int buffer; + + for (buffer = 0; buffer < hp->nbuffers; buffer++) + if (hp->pointBuffer[buffer] != NULL) + (void) free((void *) hp->pointBuffer[buffer]); + (void) free((void *) hp->pointBuffer); + hp->pointBuffer = (XPoint **) NULL; + } +} + +void +init_thornbird(ModeInfo * mi) +{ + thornbirdstruct *hp; + + if (thornbirds == NULL) { + if ((thornbirds = + (thornbirdstruct *) calloc(MI_NUM_SCREENS(mi), + sizeof (thornbirdstruct))) == NULL) + return; + } + hp = þbirds[MI_SCREEN(mi)]; + + + hp->maxx = MI_WIDTH(mi); + hp->maxy = MI_HEIGHT(mi); + + hp->b = 0.1; + hp->i = hp->j = 0.1; + + hp->pix = 0; + hp->inc = 0; + + hp->nbuffers = MI_CYCLES(mi); + + if (hp->pointBuffer == NULL) + if ((hp->pointBuffer = (XPoint **) calloc(MI_CYCLES(mi), + sizeof (XPoint *))) == NULL) { + free_thornbird(hp); + return; + } + + if (hp->pointBuffer[0] == NULL) + if ((hp->pointBuffer[0] = (XPoint *) malloc(MI_COUNT(mi) * + sizeof (XPoint))) == NULL) { + free_thornbird(hp); + return; + } + + /* select frequencies for parameter variation */ + hp->liss.f1 = LRAND() % 5000; + hp->liss.f2 = LRAND() % 2000; + + /* choose random 3D tumbling */ + hp->tumble.theta = 0; + hp->tumble.phi = 0; + hp->tumble.dtheta = balance_rand(0.001); + hp->tumble.dphi = balance_rand(0.005); + + /* Clear the background. */ + MI_CLEARWINDOW(mi); + + hp->count = 0; +} + + +void +draw_thornbird(ModeInfo * mi) +{ + Display *dsp = MI_DISPLAY(mi); + Window win = MI_WINDOW(mi); + double oldj, oldi; + int batchcount = MI_COUNT(mi); + int k; + XPoint *xp; + GC gc = MI_GC(mi); + int erase; + int current; + + double sint, cost, sinp, cosp; + thornbirdstruct *hp; + + if (thornbirds == NULL) + return; + hp = þbirds[MI_SCREEN(mi)]; + if (hp->pointBuffer == NULL) + return; + + erase = (hp->inc + 1) % MI_CYCLES(mi); + current = hp->inc % MI_CYCLES(mi); + k = batchcount; + + + xp = hp->pointBuffer[current]; + + /* vary papameters */ + hp->a = 1.99 + (0.4 * sin(hp->inc / hp->liss.f1) + + 0.05 * cos(hp->inc / hp->liss.f2)); + hp->c = 0.80 + (0.15 * cos(hp->inc / hp->liss.f1) + + 0.05 * sin(hp->inc / hp->liss.f2)); + + /* vary view */ + hp->tumble.theta += hp->tumble.dtheta; + hp->tumble.phi += hp->tumble.dphi; + sint = sin(hp->tumble.theta); + cost = cos(hp->tumble.theta); + sinp = sin(hp->tumble.phi); + cosp = cos(hp->tumble.phi); + + while (k--) { + oldj = hp->j; + oldi = hp->i; + + hp->j = oldi; + hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b; + hp->b = oldj; + + xp->x = (short) + (hp->maxx / 2 * (1 + + sint*hp->j + cost*cosp*hp->i - cost*sinp*hp->b)); + xp->y = (short) + (hp->maxy / 2 * (1 + - cost*hp->j + sint*cosp*hp->i - sint*sinp*hp->b)); + xp++; + } + + MI_IS_DRAWN(mi) = True; + + if (hp->pointBuffer[erase] == NULL) { + if ((hp->pointBuffer[erase] = (XPoint *) malloc(MI_COUNT(mi) * + sizeof (XPoint))) == NULL) { + free_thornbird(hp); + return; + } + } else { + XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi)); + XDrawPoints(dsp, win, gc, hp->pointBuffer[erase], + batchcount, CoordModeOrigin); + } + if (MI_NPIXELS(mi) > 2) { + XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); + if (erase == 0) /* change colours after "cycles" cycles */ + if (++hp->pix >= MI_NPIXELS(mi)) + hp->pix = 0; + } else + XSetForeground(dsp, gc, MI_WHITE_PIXEL(mi)); + + XDrawPoints(dsp, win, gc, hp->pointBuffer[current], + batchcount, CoordModeOrigin); + hp->inc++; + +} + +void +release_thornbird(ModeInfo * mi) +{ + if (thornbirds != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_thornbird(þbirds[screen]); + (void) free((void *) thornbirds); + thornbirds = (thornbirdstruct *) NULL; + } +} + +void +refresh_thornbird(ModeInfo * mi) +{ + MI_CLEARWINDOW(mi); +} + +#endif /* MODE_thornbird */ diff --git a/hacks/twang.c b/hacks/twang.c new file mode 100644 index 00000000..8b975dce --- /dev/null +++ b/hacks/twang.c @@ -0,0 +1,763 @@ +/* twang, twist around screen bits, v1.3 + * by Dan Bornstein, danfuzz@milk.com + * Copyright (c) 2003 Dan Bornstein. All rights reserved. + * + * 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. + * + * See the included man page for more details. + */ + +#include +#include "screenhack.h" +#include + +#ifdef HAVE_XSHM_EXTENSION +#include "xshm.h" +#endif + +#define FLOAT double + +/* random float in the range (-1..1) */ +#define RAND_FLOAT_PM1 \ + (((FLOAT) ((random() >> 8) & 0xffff)) / ((FLOAT) 0x10000) * 2 - 1) + +/* random float in the range (0..1) */ +#define RAND_FLOAT_01 \ + (((FLOAT) ((random() >> 8) & 0xffff)) / ((FLOAT) 0x10000)) + + + +/* parameters that are user configurable */ + +/* whether or not to use xshm */ +#ifdef HAVE_XSHM_EXTENSION +static Bool useShm; +#endif + +/* delay (usec) between iterations */ +static int delay; + +/* the maximum number of columns of tiles */ +static int maxColumns; + +/* the maximum number of rows of tiles */ +static int maxRows; + +/* the size (width and height) of a tile */ +static int tileSize; + +/* the width of the border around each tile */ +static int borderWidth; + +/* the chance, per iteration, of an interesting event happening */ +static FLOAT eventChance; + +/* friction: the fraction (0..1) by which velocity decreased per iteration */ +static FLOAT friction; + +/* springiness: the fraction (0..1) of the orientation that turns into + * velocity towards the center */ +static FLOAT springiness; + +/* transference: the fraction (0..1) of the orientations of orthogonal + * neighbors that turns into velocity (in the same direction as the + * orientation) */ +static FLOAT transference; + + + +/* non-user-modifiable immutable definitions */ + +/* width and height of the window */ +static int windowWidth; +static int windowHeight; + +static Display *display; /* the display to draw on */ +static Window window; /* the window to draw on */ +static Screen *screen; /* the screen to draw on */ + +static XImage *sourceImage; /* image source of stuff to draw */ +static XImage *workImage; /* work area image, used when rendering */ +static XImage *backgroundImage; /* image filled with background pixels */ + +static GC backgroundGC; /* GC for the background color */ +static GC foregroundGC; /* GC for the foreground color */ +static GC borderGC; /* GC for the border color */ +unsigned long backgroundPixel; /* background color as a pixel value */ +unsigned long borderPixel; /* border color as a pixel value */ + +#ifdef HAVE_XSHM_EXTENSION +XShmSegmentInfo shmInfo; +#endif + + + +/* the model */ + +typedef struct +{ + int x; /* x coordinate of the center of the tile */ + int y; /* y coordinate of the center of the tile */ + FLOAT angle; /* angle of the tile (-pi..pi) */ + FLOAT zoom; /* log of the zoom of the tile (-1..1) */ + FLOAT vAngle; /* angular velocity (-pi/4..pi/4) */ + FLOAT vZoom; /* zoomular velocity (-0.25..0.25) */ +} +Tile; + +static Tile *tiles; /* array of tiles (left->right, top->bottom, row major) */ +static int rows; /* number of rows of tiles */ +static int columns; /* number of columns of tiles */ + +static Tile **sortedTiles; /* array of tile pointers, sorted by zoom */ +static int tileCount; /* total number of tiles */ + +#define TILE_AT(col,row) (&tiles[(row) * columns + (col)]) + +#define MAX_VANGLE (M_PI / 4.0) +#define MAX_VZOOM 0.25 + +#define RAND_ANGLE (RAND_FLOAT_PM1 * M_PI) +#define RAND_ZOOM (RAND_FLOAT_PM1) +#define RAND_VANGLE (RAND_FLOAT_PM1 * MAX_VANGLE) +#define RAND_VZOOM (RAND_FLOAT_PM1 * MAX_VZOOM) + + + +/* + * overall setup stuff + */ + +/* grab the source image */ +static void grabImage (XWindowAttributes *xwa) +{ + XFillRectangle (display, window, backgroundGC, 0, 0, + windowWidth, windowHeight); + backgroundImage = + XGetImage (display, window, 0, 0, windowWidth, windowHeight, + ~0L, ZPixmap); + + grab_screen_image (screen, window); + sourceImage = XGetImage (display, window, 0, 0, windowWidth, windowHeight, + ~0L, ZPixmap); + +#ifdef HAVE_XSHM_EXTENSION + workImage = NULL; + if (useShm) + { + workImage = create_xshm_image (display, xwa->visual, xwa->depth, + ZPixmap, 0, &shmInfo, + windowWidth, windowHeight); + if (!workImage) + { + useShm = False; + fprintf (stderr, "create_xshm_image failed\n"); + } + } + + if (workImage == NULL) +#endif /* HAVE_XSHM_EXTENSION */ + + /* just use XSubImage to acquire the right visual, depth, etc; + * easier than the other alternatives */ + workImage = XSubImage (sourceImage, 0, 0, windowWidth, windowHeight); +} + +/* set up the system */ +static void setup (void) +{ + XWindowAttributes xgwa; + XGCValues gcv; + + XGetWindowAttributes (display, window, &xgwa); + + screen = xgwa.screen; + windowWidth = xgwa.width; + windowHeight = xgwa.height; + + gcv.line_width = borderWidth; + gcv.foreground = get_pixel_resource ("borderColor", "BorderColor", + display, xgwa.colormap); + borderPixel = gcv.foreground; + borderGC = XCreateGC (display, window, GCForeground | GCLineWidth, + &gcv); + + gcv.foreground = get_pixel_resource ("background", "Background", + display, xgwa.colormap); + backgroundPixel = gcv.foreground; + backgroundGC = XCreateGC (display, window, GCForeground, &gcv); + + gcv.foreground = get_pixel_resource ("foreground", "Foreground", + display, xgwa.colormap); + foregroundGC = XCreateGC (display, window, GCForeground, &gcv); + + grabImage (&xgwa); +} + + + +/* + * the simulation + */ + +/* event: randomize all the angular velocities */ +static void randomizeAllAngularVelocities (void) +{ + int c; + int r; + + for (r = 0; r < rows; r++) + { + for (c = 0; c < columns; c++) + { + TILE_AT (c, r)->vAngle = RAND_VANGLE; + } + } +} + +/* event: randomize all the zoomular velocities */ +static void randomizeAllZoomularVelocities (void) +{ + int c; + int r; + + for (r = 0; r < rows; r++) + { + for (c = 0; c < columns; c++) + { + TILE_AT (c, r)->vZoom = RAND_VZOOM; + } + } +} + +/* event: randomize all the velocities */ +static void randomizeAllVelocities (void) +{ + randomizeAllAngularVelocities (); + randomizeAllZoomularVelocities (); +} + +/* event: randomize all the angular orientations */ +static void randomizeAllAngularOrientations (void) +{ + int c; + int r; + + for (r = 0; r < rows; r++) + { + for (c = 0; c < columns; c++) + { + TILE_AT (c, r)->angle = RAND_ANGLE; + } + } +} + +/* event: randomize all the zoomular orientations */ +static void randomizeAllZoomularOrientations (void) +{ + int c; + int r; + + for (r = 0; r < rows; r++) + { + for (c = 0; c < columns; c++) + { + TILE_AT (c, r)->zoom = RAND_ZOOM; + } + } +} + +/* event: randomize all the orientations */ +static void randomizeAllOrientations (void) +{ + randomizeAllAngularOrientations (); + randomizeAllZoomularOrientations (); +} + +/* event: randomize everything */ +static void randomizeEverything (void) +{ + randomizeAllVelocities (); + randomizeAllOrientations (); +} + +/* event: pick one tile and randomize all its stats */ +static void randomizeOneTile (void) +{ + int c = RAND_FLOAT_01 * columns; + int r = RAND_FLOAT_01 * rows; + + Tile *t = TILE_AT (c, r); + t->angle = RAND_ANGLE; + t->zoom = RAND_ZOOM; + t->vAngle = RAND_VANGLE; + t->vZoom = RAND_VZOOM; +} + +/* event: pick one row and randomize everything about each of its tiles */ +static void randomizeOneRow (void) +{ + int c; + int r = RAND_FLOAT_01 * rows; + + for (c = 0; c < columns; c++) + { + Tile *t = TILE_AT (c, r); + t->angle = RAND_ANGLE; + t->zoom = RAND_ZOOM; + t->vAngle = RAND_VANGLE; + t->vZoom = RAND_VZOOM; + } +} + +/* event: pick one column and randomize everything about each of its tiles */ +static void randomizeOneColumn (void) +{ + int c = RAND_FLOAT_01 * columns; + int r; + + for (r = 0; r < rows; r++) + { + Tile *t = TILE_AT (c, r); + t->angle = RAND_ANGLE; + t->zoom = RAND_ZOOM; + t->vAngle = RAND_VANGLE; + t->vZoom = RAND_VZOOM; + } +} + +/* do model event processing */ +static void modelEvents (void) +{ + int which; + + if (RAND_FLOAT_01 > eventChance) + { + return; + } + + which = RAND_FLOAT_01 * 10; + + switch (which) + { + case 0: randomizeAllAngularVelocities (); break; + case 1: randomizeAllZoomularVelocities (); break; + case 2: randomizeAllVelocities (); break; + case 3: randomizeAllAngularOrientations (); break; + case 4: randomizeAllZoomularOrientations (); break; + case 5: randomizeAllOrientations (); break; + case 6: randomizeEverything (); break; + case 7: randomizeOneTile (); break; + case 8: randomizeOneColumn (); break; + case 9: randomizeOneRow (); break; + } +} + +/* update the model for one iteration */ +static void updateModel (void) +{ + int r; + int c; + + /* for each tile, decrease its velocities according to the friction, + * and increase them based on its current orientation and the orientations + * of its orthogonal neighbors */ + for (r = 0; r < rows; r++) + { + for (c = 0; c < columns; c++) + { + Tile *t = TILE_AT (c, r); + FLOAT a = t->angle; + FLOAT z = t->zoom; + FLOAT va = t->vAngle; + FLOAT vz = t->vZoom; + + va -= t->angle * springiness; + vz -= t->zoom * springiness; + + if (c > 0) + { + Tile *t2 = TILE_AT (c - 1, r); + va += (t2->angle - a) * transference; + vz += (t2->zoom - z) * transference; + } + + if (c < (columns - 1)) + { + Tile *t2 = TILE_AT (c + 1, r); + va += (t2->angle - a) * transference; + vz += (t2->zoom - z) * transference; + } + + if (r > 0) + { + Tile *t2 = TILE_AT (c, r - 1); + va += (t2->angle - a) * transference; + vz += (t2->zoom - z) * transference; + } + + if (r < (rows - 1)) + { + Tile *t2 = TILE_AT (c, r + 1); + va += (t2->angle - a) * transference; + vz += (t2->zoom - z) * transference; + } + + va *= (1.0 - friction); + vz *= (1.0 - friction); + + if (va > MAX_VANGLE) va = MAX_VANGLE; + else if (va < -MAX_VANGLE) va = -MAX_VANGLE; + t->vAngle = va; + + if (vz > MAX_VZOOM) vz = MAX_VZOOM; + else if (vz < -MAX_VZOOM) vz = -MAX_VZOOM; + t->vZoom = vz; + } + } + + /* for each tile, update its orientation based on its velocities */ + for (r = 0; r < rows; r++) + { + for (c = 0; c < columns; c++) + { + Tile *t = TILE_AT (c, r); + FLOAT a = t->angle + t->vAngle; + FLOAT z = t->zoom + t->vZoom; + + if (a > M_PI) a = M_PI; + else if (a < -M_PI) a = -M_PI; + t->angle = a; + + if (z > 1.0) z = 1.0; + else if (z < -1.0) z = -1.0; + t->zoom = z; + } + } +} + +/* the comparator to us to sort the tiles (used immediately below); it'd + * sure be nice if C allowed inner functions (or jeebus-forbid *real + * closures*!) */ +static int sortTilesComparator (const void *v1, const void *v2) +{ + Tile *t1 = *(Tile **) v1; + Tile *t2 = *(Tile **) v2; + + if (t1->zoom < t2->zoom) + { + return -1; + } + + if (t1->zoom > t2->zoom) + { + return 1; + } + + return 0; +} + +/* sort the tiles in sortedTiles by zoom */ +static void sortTiles (void) +{ + qsort (sortedTiles, tileCount, sizeof (Tile *), sortTilesComparator); +} + +/* render the given tile */ +static void renderTile (Tile *t) +{ + /* note: the zoom as stored per tile is log-based (centered on 0, with + * 0 being no zoom, but the range for zoom-as-drawn is 0.4..2.5, + * hence the alteration of t->zoom, below */ + + int x, y; + + int tx = t->x; + int ty = t->y; + + FLOAT zoom = pow (2.5, t->zoom); + FLOAT ang = -t->angle; + FLOAT sinAng = sin (ang); + FLOAT cosAng = cos (ang); + + FLOAT innerBorder = (tileSize - borderWidth) / 2.0; + FLOAT outerBorder = innerBorder + borderWidth; + + int maxCoord = outerBorder * zoom * (fabs (sinAng) + fabs (cosAng)); + int minX = tx - maxCoord; + int maxX = tx + maxCoord; + int minY = ty - maxCoord; + int maxY = ty + maxCoord; + + FLOAT prey; + + if (minX < 0) minX = 0; + if (maxX > windowWidth) maxX = windowWidth; + if (minY < 0) minY = 0; + if (maxY > windowHeight) maxY = windowHeight; + + sinAng /= zoom; + cosAng /= zoom; + + for (y = minY, prey = y - ty; y < maxY; y++, prey++) + { + FLOAT prex = minX - tx; + FLOAT srcx = prex * cosAng - prey * sinAng; + FLOAT srcy = prex * sinAng + prey * cosAng; + + for (x = minX; + x < maxX; + x++, srcx += cosAng, srcy += sinAng) + { + if ((srcx < -innerBorder) || (srcx >= innerBorder) || + (srcy < -innerBorder) || (srcy >= innerBorder)) + { + if ((srcx < -outerBorder) || (srcx >= outerBorder) || + (srcy < -outerBorder) || (srcy >= outerBorder)) + { + continue; + } + XPutPixel (workImage, x, y, borderPixel); + } + else + { + unsigned long p = + XGetPixel (sourceImage, srcx + tx, srcy + ty); + XPutPixel (workImage, x, y, p); + } + } + } +} + +/* render and display the current model */ +static void renderFrame (void) +{ + int n; + + memcpy (workImage->data, backgroundImage->data, + workImage->bytes_per_line * workImage->height); + + sortTiles (); + + for (n = 0; n < tileCount; n++) + { + renderTile (sortedTiles[n]); + } + +#ifdef HAVE_XSHM_EXTENSION + if (useShm) + XShmPutImage (display, window, backgroundGC, workImage, 0, 0, 0, 0, + windowWidth, windowHeight, False); + else +#endif /* HAVE_XSHM_EXTENSION */ + XPutImage (display, window, backgroundGC, workImage, + 0, 0, 0, 0, windowWidth, windowHeight); +} + +/* set up the model */ +static void setupModel (void) +{ + int c; + int r; + + int leftX; /* x of the center of the top-left tile */ + int topY; /* y of the center of the top-left tile */ + + if (tileSize > (windowWidth / 2)) + { + tileSize = windowWidth / 2; + } + + if (tileSize > (windowHeight / 2)) + { + tileSize = windowHeight / 2; + } + + columns = windowWidth / tileSize; + rows = windowHeight / tileSize; + + if ((maxColumns != 0) && (columns > maxColumns)) + { + columns = maxColumns; + } + + if ((maxRows != 0) && (rows > maxRows)) + { + rows = maxRows; + } + + tileCount = rows * columns; + + leftX = (windowWidth - (columns * tileSize) + tileSize) / 2; + topY = (windowHeight - (rows * tileSize) + tileSize) / 2; + + tiles = calloc (tileCount, sizeof (Tile)); + sortedTiles = calloc (tileCount, sizeof (Tile *)); + + for (r = 0; r < rows; r++) + { + for (c = 0; c < columns; c++) + { + Tile *t = TILE_AT (c, r); + t->x = leftX + c * tileSize; + t->y = topY + r * tileSize; + sortedTiles[c + r * columns] = t; + } + } + + randomizeEverything (); +} + +/* do one iteration */ +static void oneIteration (void) +{ + modelEvents (); + updateModel (); + renderFrame (); +} + + + +/* main and options and stuff */ + +char *progclass = "Twang"; + +char *defaults [] = { + ".background: black", + ".foreground: white", + "*borderColor: blue", + "*borderWidth: 3", + "*delay: 10000", + "*eventChance: 0.01", + "*friction: 0.05", + "*maxColumns: 0", + "*maxRows: 0", + "*springiness: 0.1", + "*tileSize: 120", + "*transference: 0.025", +#ifdef HAVE_XSHM_EXTENSION + "*useSHM: True", +#endif + 0 +}; + +XrmOptionDescRec options [] = { + { "-border-color", ".borderColor", XrmoptionSepArg, 0 }, + { "-border-width", ".borderWidth", XrmoptionSepArg, 0 }, + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-event-chance", ".eventChance", XrmoptionSepArg, 0 }, + { "-friction", ".friction", XrmoptionSepArg, 0 }, + { "-max-columns", ".maxColumns", XrmoptionSepArg, 0 }, + { "-max-rows", ".maxRows", XrmoptionSepArg, 0 }, + { "-springiness", ".springiness", XrmoptionSepArg, 0 }, + { "-tile-size", ".tileSize", XrmoptionSepArg, 0 }, + { "-transference", ".transference", XrmoptionSepArg, 0 }, +#ifdef HAVE_XSHM_EXTENSION + { "-shm", ".useSHM", XrmoptionNoArg, "True" }, + { "-no-shm", ".useSHM", XrmoptionNoArg, "False" }, +#endif + { 0, 0, 0, 0 } +}; + +/* initialize the user-specifiable params */ +static void initParams (void) +{ + int problems = 0; + + borderWidth = get_integer_resource ("borderWidth", "Integer"); + if (borderWidth < 0) + { + fprintf (stderr, "error: border width must be at least 0\n"); + problems = 1; + } + + delay = get_integer_resource ("delay", "Delay"); + if (delay < 0) + { + fprintf (stderr, "error: delay must be at least 0\n"); + problems = 1; + } + + eventChance = get_float_resource ("eventChance", "Double"); + if ((eventChance < 0.0) || (eventChance > 1.0)) + { + fprintf (stderr, "error: eventChance must be in the range 0..1\n"); + problems = 1; + } + + friction = get_float_resource ("friction", "Double"); + if ((friction < 0.0) || (friction > 1.0)) + { + fprintf (stderr, "error: friction must be in the range 0..1\n"); + problems = 1; + } + + maxColumns = get_integer_resource ("maxColumns", "Integer"); + if (maxColumns < 0) + { + fprintf (stderr, "error: max columns must be at least 0\n"); + problems = 1; + } + + maxRows = get_integer_resource ("maxRows", "Integer"); + if (maxRows < 0) + { + fprintf (stderr, "error: max rows must be at least 0\n"); + problems = 1; + } + + springiness = get_float_resource ("springiness", "Double"); + if ((springiness < 0.0) || (springiness > 1.0)) + { + fprintf (stderr, "error: springiness must be in the range 0..1\n"); + problems = 1; + } + + tileSize = get_integer_resource ("tileSize", "Integer"); + if (tileSize < 1) + { + fprintf (stderr, "error: tile size must be at least 1\n"); + problems = 1; + } + + transference = get_float_resource ("transference", "Double"); + if ((transference < 0.0) || (transference > 1.0)) + { + fprintf (stderr, "error: transference must be in the range 0..1\n"); + problems = 1; + } + +#ifdef HAVE_XSHM_EXTENSION + useShm = get_boolean_resource ("useSHM", "Boolean"); +#endif + + if (problems) + { + exit (1); + } +} + +/* main function */ +void screenhack (Display *dpy, Window win) +{ + display = dpy; + window = win; + + initParams (); + setup (); + setupModel (); + + for (;;) + { + oneIteration (); + XSync (dpy, False); + screenhack_handle_events (dpy); + usleep (delay); + } +} diff --git a/hacks/twang.man b/hacks/twang.man new file mode 100644 index 00000000..27cdc2ee --- /dev/null +++ b/hacks/twang.man @@ -0,0 +1,107 @@ +.TH XScreenSaver 1 "07-Feb-2002" "X Version 11" +.SH NAME +twang - pluck pieces of the screen +.SH SYNOPSIS +.B twang +[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-install] [\-visual \fIvisual\fP] [\-shm] [\-no-shm] [\-delay \fImicroseconds\fP] [\-border-color \fIcolor\fP] [\-border-width \fIinteger\fP] [\-event-chance \fIfraction\fP] [\-friction \fIfraction\fP] [\-springiness \fIfraction\fP] [\-tile-size \fIinteger\fP] [\-transference \fIfraction\fP] +.SH DESCRIPTION +\fITwang\fP divides the screen into equal-sized tiles, and then plucks +them in various ways. Tiles are affected by their neighbors, so waves +of motion flow through the grid. This manpage +describes v1.3 of the program. +.SH OPTIONS +.I twang +accepts the following options: +.TP 8 +.B \-window +Draw on a newly-created window. This is the default. +.TP 8 +.B \-root +Draw on the root window. +.TP 8 +.B \-mono +If on a color display, pretend we're on a monochrome display. +.TP 8 +.B \-install +Install a private colormap for the window. +.TP 8 +.B \-visual \fIvisual\fP +Which visual to use. Legal values are the name of a visual class, +or the id number (decimal or hex) of a specific visual. +.TP 8 +.B \-shm +.TP 8 +.B \-no-shm +Use the shared memory extension (or not, respectively), if available. +This may speed things +up a bit, but probably won't make that much difference. If available, +defaults to true, resource \fIuseSHM\fP. +.TP 8 +.B \-delay \fImicroseconds\fP +The interframe delay, in microseconds. Defaults to 10000, resource +\fIdelay\fP. +.TP 8 +.B \-border-color \fIcolor\fP +Color of the border surrounding each tile. Defaults to blue, resource +\fIborderColor\fP. +.TP 8 +.B \-border-width \fIinteger\fP +Width of the border surrounding each tile. Defaults to 3, resource +\fIborderWidth\fP. +.TP 8 +.B \-event-chance \fIfraction\fP +The chance, per iteration, for an event to occur (such as tweaking +the orientation of a tile), in the range 0..1. Defaults to 0.01, +resource \fIeventChance\fP. +.TP 8 +.B \-friction \fIfraction\fP +How much friction there is in the system, in the range 0..1. +This is the amount by which velocities are damped per iteration. +Defaults to 0.05, resource \fIfriction\fP. +.TP 8 +.B \-springiness \fIfraction\fP +How springy the tiles are, in the range 0..1. +This is the fraction of an orientation that gets turned into a velocity +towards the center (resting point). Defaults to 0.1, resource +\fIspringiness\fP. +.TP 8 +.B \-tile-size \fIinteger\fP +Size (width and height) of each tile, not including the outer edge +of the border. Defaults to 120, resource \fItileSize\fP. +.TP 8 +.B \-transference \fIfraction\fP +How much a tile's neighbors affect it, in the range 0..1. +This is the fraction of an orientation of a neighbor that gets turned +into a velocity in the same direction Defaults to 0.025, resource +\fItransference\fP. +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH X RESOURCES +There are resource equivalents for each option, noted above. +.SH BUGS +.I twang +should have more interesting events. +.TP 8 +Ways of speeding it up need to be investigated. It's kinda sluggish, +especially on hugeass displays. +.SH SEE ALSO +.BR xscreensaver (1) +.SH COPYRIGHT +Copyright \(co 2002 by Dan Bornstein. All rights reserved. + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. No representations are made about the suitability of this +software for any purpose. It is provided "as is" without express or +implied warranty. +.SH AUTHOR +Dan Bornstein . diff --git a/hacks/vidwhacker b/hacks/vidwhacker index dbe6e327..8308ccca 100755 --- a/hacks/vidwhacker +++ b/hacks/vidwhacker @@ -21,7 +21,7 @@ use diagnostics; use strict; my $progname = $0; $progname =~ s@.*/@@g; -my $version = q{ $Revision: 1.18 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; +my $version = q{ $Revision: 1.19 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; my $verbose = 0; my $use_stdin = 0; @@ -324,6 +324,7 @@ sub get_ppm { if ($fn =~ m/\.gif/i) { $cmd = "giftopnm < \"$fn\""; } elsif ($fn =~ m/\.jpe?g/i) { $cmd = "djpeg < \"$fn\""; } + elsif ($fn =~ m/\.png/i) { $cmd = "pngtopnm < \"$fn\""; } else { error "unrecognized file extension on $fn"; } diff --git a/hacks/vines.c b/hacks/vines.c index 4c562f9d..f4151cd4 100644 --- a/hacks/vines.c +++ b/hacks/vines.c @@ -1,46 +1,77 @@ -/* -*- Mode: C; tab-width: 4 -*- - * vines --- another geometric pattern generator. - */ +/* -*- Mode: C; tab-width: 4 -*- */ +/* vines --- vine fractals */ + #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)vines.c 4.02 97/04/01 xlockmore"; +static const char sccsid[] = "@(#)vines.c 5.00 2000/11/01 xlockmore"; + #endif -/* xlockmore mode written by Tracy Camp - * campt@hurrah.com 1997 - * released to the public domain +/*- + * Copyright (c) 1997 by Tracy Camp campt@hurrah.com + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * If you make a modification I would of course appreciate a copy. + * + * Revision History: + * 01-Nov-2000: Allocation checks + * 11-Jul-1997: David Hansen + * Changed names to vines and modified draw loop + * to honor batchcount so vines can be grown or plotted. + * 10-May-1997: Compatible with xscreensaver + * 21-Mar-1997: David Hansen + * Updated mode to draw complete patterns on every + * iteration instead of growing the vine. Also made + * adjustments to randomization and changed variable + * names to make logic easier to follow. + */ + +/*- * This was modifed from a 'screen saver' that a friend and I * wrote on our TI-8x calculators in high school physics one day * Basically another geometric pattern generator, this ones claim * to fame is a pseudo-fractal looking vine like pattern that creates * nifty whorls and loops. - * - * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * 21-Mar-97: David Hansen - * Updated mode to draw complete patterns on every - * iteration instead of growing the vine. Also made - * adjustments to randomization and changed variable - * names to make logic easier to follow. */ #ifdef STANDALONE -# define PROGCLASS "Vines" -# define HACK_INIT init_vines -# define HACK_DRAW draw_vines -# define vines_opts xlockmore_opts -# define DEFAULTS "*delay: 200000 \n" \ - "*ncolors: 64 \n" \ - "*eraseSpeed: 400 \n" \ - "*eraseMode: -1 \n" -# include "xlockmore.h" /* from the xscreensaver distribution */ -# include "erase.h" -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -ModeSpecOpt vines_opts = { - 0, NULL, 0, NULL, NULL }; +#define MODE_vines +#define PROGCLASS "Vines" +#define HACK_INIT init_vines +#define HACK_DRAW draw_vines +#define vines_opts xlockmore_opts +#define DEFAULTS "*delay: 200000 \n" \ + "*count: 0 \n" \ + "*ncolors: 64 \n" +#include "xlockmore.h" /* in xscreensaver distribution */ +#include "erase.h" +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_vines + +ModeSpecOpt vines_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct vines_description = +{"vines", "init_vines", "draw_vines", "release_vines", + "refresh_vines", "init_vines", (char *) NULL, &vines_opts, + 200000, 0, 1, 1, 64, 1.0, "", + "Shows fractals", 0, NULL}; + +#endif typedef struct { int a; @@ -48,6 +79,7 @@ typedef struct { int y1; int x2; int y2; + int i; int length; int iterations; int constant; @@ -56,87 +88,102 @@ typedef struct { int centery; } vinestruct; -static vinestruct *vines = NULL; +static vinestruct *vines = (vinestruct *) NULL; void refresh_vines(ModeInfo * mi) { -} + MI_CLEARWINDOW(mi); +} /* refresh_vines */ void init_vines(ModeInfo * mi) { - Display *display = MI_DISPLAY(mi); vinestruct *fp; if (vines == NULL) { - if ((vines = (vinestruct *) calloc(MI_NUM_SCREENS(mi), sizeof (vinestruct))) == NULL) { + if ((vines = (vinestruct *) calloc(MI_NUM_SCREENS(mi), + sizeof (vinestruct))) == NULL) { return; } } fp = &vines[MI_SCREEN(mi)]; + fp->i = 0; + fp->length = 0; fp->iterations = 30 + NRAND(100); - XClearWindow(display, MI_WINDOW(mi)); -} + MI_CLEARWINDOW(mi); +} /* init_vines */ void draw_vines(ModeInfo * mi) { - vinestruct *fp = &vines[MI_SCREEN(mi)]; Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); - int i; + int count; + vinestruct *fp; + + if (vines == NULL) + return; + fp = &vines[MI_SCREEN(mi)]; - if (--(fp->iterations) == 0) { + /* MI_IS_DRAWN(mi) = True; */ + if (fp->i >= fp->length) { + if (--(fp->iterations) == 0) { #ifdef STANDALONE erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi)); #endif /* STANDALONE */ - init_vines(mi); + init_vines(mi); + } + fp->centerx = NRAND(MI_WIDTH(mi)); + fp->centery = NRAND(MI_HEIGHT(mi)); + + fp->ang = 60 + NRAND(720); + fp->length = 100 + NRAND(3000); + fp->constant = fp->length * (10 + NRAND(10)); + + fp->i = 0; + fp->a = 0; + fp->x1 = 0; + fp->y1 = 0; + fp->x2 = 1; + fp->y2 = 0; + + if (MI_NPIXELS(mi) > 2) + XSetForeground(display, gc, MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)))); + else + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); } + count = fp->i + MI_COUNT(mi); + if ((count <= fp->i) || (count > fp->length)) + count = fp->length; - fp->centerx = NRAND(MI_WIN_WIDTH(mi)); - fp->centery = NRAND(MI_WIN_HEIGHT(mi)); - - fp->ang = 60 + NRAND(720); - fp->length = 100 + NRAND(3000); - fp->constant = fp->length * (10 + NRAND(10)); - - fp->a = 0; - fp->x1 = 0; - fp->y1 = 0; - fp->x2 = 1; - fp->y2 = 0; - - if (MI_NPIXELS(mi) > 2) - XSetForeground(display, gc, MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)))); - else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); - - - for (i = 0; i < fp->length; i++) { + while (fp->i < count) { XDrawLine(display, MI_WINDOW(mi), gc, fp->centerx + (fp->x1 / fp->constant), fp->centery - (fp->y1 / fp->constant), fp->centerx + (fp->x2 / fp->constant), fp->centery - (fp->y2 / fp->constant)); - fp->a += (fp->ang * i); + fp->a += (fp->ang * fp->i); fp->x1 = fp->x2; fp->y1 = fp->y2; - fp->x2 += (int) (i * ((cos(fp->a) * 360) / (2 * M_PI))); - fp->y2 += (int) (i * ((sin(fp->a) * 360) / (2 * M_PI))); + fp->x2 += (int) (fp->i * (cos((double) fp->a) * 360.0) / (2.0 * M_PI)); + fp->y2 += (int) (fp->i * (sin((double) fp->a) * 360.0) / (2.0 * M_PI)); + fp->i++; } -} +} /* draw_vines */ void release_vines(ModeInfo * mi) { if (vines != NULL) { (void) free((void *) vines); - vines = NULL; + vines = (vinestruct *) NULL; } -} +} /* release_vines */ + +#endif /* MODE_vines */ diff --git a/hacks/wander.c b/hacks/wander.c index d64bdd51..8938ccad 100644 --- a/hacks/wander.c +++ b/hacks/wander.c @@ -174,6 +174,8 @@ char *progclass = "Wander"; char *defaults [] = { + ".background: black", + ".foreground: white", ".advance: 1", ".density: 2", ".length: 25000", diff --git a/hacks/webcollage b/hacks/webcollage index 330a363d..bb3c66ef 100755 --- a/hacks/webcollage +++ b/hacks/webcollage @@ -1,6 +1,6 @@ #!/usr/bin/perl -w # -# webcollage, Copyright (c) 1999-2001 by Jamie Zawinski +# webcollage, Copyright (c) 1999-2002 by Jamie Zawinski # This program decorates the screen with random images from the web. # One satisfied customer described it as "a nonstop pop culture brainbath." # @@ -35,8 +35,8 @@ use POSIX qw(strftime); my $progname = $0; $progname =~ s@.*/@@g; -my $version = q{ $Revision: 1.82 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; -my $copyright = "WebCollage $version, Copyright (c) 1999-2001" . +my $version = q{ $Revision: 1.87 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; +my $copyright = "WebCollage $version, Copyright (c) 1999-2002" . " Jamie Zawinski \n" . " http://www.jwz.org/xscreensaver/\n"; @@ -56,16 +56,14 @@ my @search_methods = ( 30, "imagevista", \&pick_from_alta_vista_images, # 0, "hotbot", \&pick_from_hotbot_text, ); -#@search_methods=(100, "googleimgs",\&pick_from_google_images); - # programs we can use to write to the root window (tried in ascending order.) # my @root_displayers = ( - "xloadimage -quiet -onroot -center -border black", - "xli -quiet -onroot -center -border black", - "xv -root -quit -viewonly +noresetroot -rmode 5" . + "chbg -once -xscreensaver -max_size 100", + "xv -root -quit -viewonly -noresetroot -quick24 -rmode 5" . " -rfg black -rbg black", - "chbg -once -xscreensaver", + "xli -quiet -onroot -center -border black", + "xloadimage -quiet -onroot -center -border black", # this lame program wasn't built with vroot.h: # "xsri -scale -keep-aspect -center-horizontal -center-vertical", @@ -85,6 +83,20 @@ my %cookies = ( ); +# If this is set, it's a helper program to use for pasting images together: +# this is a lot faster and more efficient than using PPM pipelines, which is +# what we do if this program doesn't exist. (We check for "webcollage-helper" +# on $PATH at startup, and set this variable appropriately.) +# +my $webcollage_helper = undef; + + +# If we have the webcollage-helper program, then it will paste the images +# together with transparency! 0.0 is invisible, 1.0 is totally opaque. +# +my $opacity = 0.85; + + # Some sites have managed to poison the search engines. These are they. # (We auto-detect sites that have poisoned the search engines via excessive # keywords or dictionary words, but these are ones that slip through @@ -104,6 +116,9 @@ my %poisoners = ( "bartleby.com" => 1, # Dictionary, cluttering altavista. "encyclopedia.com" => 1, # Dictionary, cluttering altavista. "onlinedictionary.datasegment.com" => 1, # Dictionary, cluttering altavista. + "hotlinkpics.com" => 1, # Porn site that has poisoned imagevista + # (I don't see how they did it, though!) + "alwayshotels.com" => 1, # Poisoned Lycos pretty heavily. ); @@ -276,7 +291,7 @@ sub get_document_1 { LOG ($verbose_http, " ==> $_"); } print S $hdrs; - my $http = ; + my $http = || ""; $_ = $http; s/[\r\n]+$//s; @@ -704,10 +719,12 @@ sub random_word { } sub random_words { - return (random_word . "%20" . - random_word . "%20" . - random_word . "%20" . - random_word . "%20" . + my ($or_p) = @_; + my $sep = ($or_p ? "%20OR%20" : "%20"); + return (random_word . $sep . + random_word . $sep . + random_word . $sep . + random_word . $sep . random_word); } @@ -976,7 +993,7 @@ my $alta_vista_images_url = "http://www.altavista.com/cgi-bin/query" . sub pick_from_alta_vista_images { my ( $timeout ) = @_; - my $words = random_words; + my $words = random_words(1); my $page = (int(rand(9)) + 1); my $search_url = $alta_vista_images_url . $words; @@ -1082,7 +1099,7 @@ my $alta_vista_url = $alta_vista_url_2; sub pick_from_alta_vista_text { my ( $timeout ) = @_; - my $words = random_words; + my $words = random_words(1); my $page = (int(rand(9)) + 1); my $search_url = $alta_vista_url . $words; @@ -1137,7 +1154,7 @@ my $hotbot_search_url = "http://hotbot.lycos.com/" . sub pick_from_hotbot_text { my ( $timeout ) = @_; - my $words = random_words; + my $words = random_words(0); my $search_url = $hotbot_search_url . $words; my ($search_hit_count, @subpages) = @@ -1174,7 +1191,7 @@ my $lycos_search_url = "http://lycospro.lycos.com/srchpro/" . sub pick_from_lycos_text { my ( $timeout ) = @_; - my $words = random_words; + my $words = random_words(0); my $start = int(rand(8)) * 10 + 1; my $search_url = $lycos_search_url . $words . "&start=$start"; @@ -1213,7 +1230,7 @@ my $yahoo_news_url = "http://search.news.yahoo.com/search/news_photos?" . sub pick_from_yahoo_news_text { my ( $timeout ) = @_; - my $words = random_words; + my $words = random_words(1); my $search_url = $yahoo_news_url . $words; my ($search_hit_count, @subpages) = @@ -1222,7 +1239,8 @@ sub pick_from_yahoo_news_text { my @candidates = (); foreach my $u (@subpages) { # only accept URLs on Yahoo's news site - next unless ($u =~ m@^http://dailynews.yahoo.com/@i); + next unless ($u =~ m@^http://dailynews\.yahoo\.com/@i || + $u =~ m@^http://story\.news\.yahoo\.com/@i); LOG ($verbose_filter, " candidate: $u"); push @candidates, $u; @@ -1810,9 +1828,27 @@ my $ppm_to_root_window_cmd = undef; sub x_or_pbm_output { + # Check for our helper program, to see whether we need to use PPM pipelines. + # + $_ = "webcollage-helper"; + if (defined ($webcollage_helper) || which ($_)) { + $webcollage_helper = $_ unless (defined($webcollage_helper)); + LOG ($verbose_pbm, "found \"$webcollage_helper\""); + $webcollage_helper .= " -v"; + } else { + LOG (($verbose_pbm || $verbose_load), "no $_ program"); + } + # make sure the various programs we execute exist, right up front. # - foreach ("ppmmake", "giftopnm", "djpeg", "pnmpaste", "pnmscale", "pnmcut") { + my @progs = ("ppmmake"); # always need this one + + if (!defined($webcollage_helper)) { + # Only need these others if we don't have the helper. + @progs = (@progs, "giftopnm", "djpeg", "pnmpaste", "pnmscale", "pnmcut"); + } + + foreach (@progs) { which ($_) || error "$_ not found on \$PATH."; } @@ -1940,11 +1976,34 @@ sub paste_image { LOG ($verbose_pbm, "got $img (" . length($body) . ")"); - my ($iw, $ih) = image_to_pnm ($img, $body, $image_tmp1); - $body = undef; - if (!$iw || !$ih) { - LOG ($verbose_pbm, "unable to make PBM from $img"); - return 0; + my ($iw, $ih); + + if (defined ($webcollage_helper)) { + + ($iw, $ih) = image_size ($body); + if (!$iw || !$ih) { + LOG (($verbose_pbm || $verbose_load), + "not a GIF or JPG" . + (($body =~ m@<(base|html|head|body|script|table|a href)>@i) + ? " (looks like HTML)" : "") . + ": $img"); + $suppress_audit = 1; + $body = undef; + return 0; + } + + local *OUT; + open (OUT, ">$image_tmp1") || error ("writing $image_tmp1: $!"); + print OUT $body || error ("writing $image_tmp1: $!"); + close OUT || error ("writing $image_tmp1: $!"); + + } else { + ($iw, $ih) = image_to_pnm ($img, $body, $image_tmp1); + $body = undef; + if (!$iw || !$ih) { + LOG ($verbose_pbm, "unable to make PBM from $img"); + return 0; + } } record_success ($load_method, $img, $base); @@ -1981,6 +2040,7 @@ sub paste_image { my $target_h = $img_height; my $cmd = ""; + my $scale = 1.0; # Usually scale the image to fit on the screen -- but sometimes scale it @@ -1988,8 +2048,8 @@ sub paste_image { # scale it to fit, we instead cut it in half until it fits -- that should # give a wider distribution of sizes. # - if (rand() < 0.3) { $target_w /= 2; $target_h /= 2; } - if (rand() < 0.3) { $target_w /= 2; $target_h /= 2; } + if (rand() < 0.3) { $target_w /= 2; $target_h /= 2; $scale /= 2; } + if (rand() < 0.3) { $target_w /= 2; $target_h /= 2; $scale /= 2; } if ($iw > $target_w || $ih > $target_h) { while ($iw > $target_w || @@ -2102,23 +2162,46 @@ sub paste_image { $cmd =~ s@^ *\| *@@; - $_ = "($cmd)"; - $_ .= " < $image_tmp1 > $image_tmp2"; + if (defined ($webcollage_helper)) { + $cmd = "$webcollage_helper $image_tmp1 $image_ppm " . + "$scale $opacity " . + "$crop_x $crop_y $x $y " . + "$iw $ih"; + $_ = $cmd; + + } else { + # use a PPM pipeline + $_ = "($cmd)"; + $_ .= " < $image_tmp1 > $image_tmp2"; + } if ($verbose_pbm) { $_ = "($_) 2>&1 | sed s'/^/" . blurb() . "/'"; } else { $_ .= " 2> /dev/null"; } + my $rc = nontrapping_system ($_); + if (defined ($webcollage_helper) && -z $image_ppm) { + LOG (1, "failed command: \"$cmd\""); + print STDERR "\naudit log:\n\n\n"; + print STDERR ("#" x 78) . "\n"; + print STDERR blurb() . "$image_ppm has zero size\n"; + showlog(); + print STDERR "\n\n"; + exit (1); + } + if ($rc != 0) { LOG (($verbose_pbm || $verbose_load), "failed command: \"$cmd\""); LOG (($verbose_pbm || $verbose_load), "failed URL: \"$img\" (${ow}x$oh)"); return; } - rename ($image_tmp2, $image_ppm) || return; + if (!defined ($webcollage_helper)) { + rename ($image_tmp2, $image_ppm) || return; + } my $target = "$image_ppm"; @@ -2231,6 +2314,24 @@ sub main { $http_proxy = shift @ARGV; } elsif ($_ eq "-dictionary" || $_ eq "-dict") { $dict = shift @ARGV; + } elsif ($_ eq "-debug" || $_ eq "--debug") { + my $which = shift @ARGV; + my @rest = @search_methods; + my $ok = 0; + while (@rest) { + my $pct = shift @rest; + my $name = shift @rest; + my $tfn = shift @rest; + + if ($name eq $which) { + @search_methods = (100, $name, $tfn); + $ok = 1; + last; + } + } + error "no such search method as \"$which\"" unless ($ok); + LOG (1, "DEBUG: using only \"$which\""); + } else { print STDERR "$copyright\nusage: $progname [-root]" . " [-display dpy] [-root] [-verbose] [-timeout secs]\n" . diff --git a/hacks/webcollage-helper.c b/hacks/webcollage-helper.c new file mode 100644 index 00000000..0b95dc5f --- /dev/null +++ b/hacks/webcollage-helper.c @@ -0,0 +1,360 @@ +/* webcollage-helper --- scales and pastes one image into another + * xscreensaver, Copyright (c) 2002 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined(HAVE_GDK_PIXBUF) && defined(HAVE_JPEGLIB) /* whole file */ + +#include +#include +#include +#include +#include +#include + +#include +#include + + +char *progname; +static int verbose_p = 0; + +static void add_jpeg_comment (struct jpeg_compress_struct *cinfo); +static void write_pixbuf (GdkPixbuf *pb, const char *file); + + +static void +paste (const char *paste_file, + const char *base_file, + double from_scale, + double opacity, + int from_x, int from_y, int to_x, int to_y, + int w, int h) +{ + GdkPixbuf *paste_pb; + GdkPixbuf *base_pb; + + int paste_w, paste_h; + int base_w, base_h; + + paste_pb = gdk_pixbuf_new_from_file (paste_file); + + if (!paste_pb) + { + fprintf (stderr, "%s: unable to load %s\n", progname, paste_file); + exit (1); + } + + base_pb = gdk_pixbuf_new_from_file (base_file); + if (!base_pb) + { + fprintf (stderr, "%s: unable to load %s\n", progname, base_file); + exit (1); + } + + paste_w = gdk_pixbuf_get_width (paste_pb); + paste_h = gdk_pixbuf_get_height (paste_pb); + + base_w = gdk_pixbuf_get_width (base_pb); + base_h = gdk_pixbuf_get_height (base_pb); + + if (verbose_p) + { + fprintf (stderr, "%s: loaded %s: %dx%d\n", + progname, base_file, base_w, base_h); + fprintf (stderr, "%s: loaded %s: %dx%d\n", + progname, paste_file, paste_w, paste_h); + } + + if (from_scale != 1.0) + { + int new_w = paste_w * from_scale; + int new_h = paste_h * from_scale; + GdkPixbuf *new_pb = gdk_pixbuf_scale_simple (paste_pb, new_w, new_h, + GDK_INTERP_HYPER); + gdk_pixbuf_unref (paste_pb); + paste_pb = new_pb; + paste_w = gdk_pixbuf_get_width (paste_pb); + paste_h = gdk_pixbuf_get_height (paste_pb); + + if (verbose_p) + fprintf (stderr, "%s: %s: scaled to %dx%d (%.2f)\n", + progname, paste_file, paste_w, paste_h, from_scale); + } + + if (w == 0) w = paste_w - from_x; + if (h == 0) h = paste_h - from_y; + + { + int ofx = from_x; + int ofy = from_y; + int otx = to_x; + int oty = to_y; + int ow = w; + int oh = h; + + int clipped = 0; + + if (from_x < 0) /* from left out of bounds */ + { + w += from_x; + from_x = 0; + clipped = 1; + } + + if (from_y < 0) /* from top out of bounds */ + { + h += from_y; + from_y = 0; + clipped = 1; + } + + if (to_x < 0) /* to left out of bounds */ + { + w += to_x; + from_x -= to_x; + to_x = 0; + clipped = 1; + } + + if (to_y < 0) /* to top out of bounds */ + { + h += to_y; + from_y -= to_y; + to_y = 0; + clipped = 1; + } + + if (from_x + w > paste_w) /* from right out of bounds */ + { + w = paste_w - from_x; + clipped = 1; + } + + if (from_y + h > paste_h) /* from bottom out of bounds */ + { + h = paste_h - from_y; + clipped = 1; + } + + if (to_x + w > base_w) /* to right out of bounds */ + { + w = base_w - to_x; + clipped = 1; + } + + if (to_y + h > base_h) /* to bottom out of bounds */ + { + h = base_h - to_y; + clipped = 1; + } + + + if (clipped && verbose_p) + { + fprintf (stderr, "clipped from: %dx%d %d,%d %d,%d\n", + ow, oh, ofx, ofy, otx, oty); + fprintf (stderr, "clipped to: %dx%d %d,%d %d,%d\n", + w, h, from_x, from_y, to_x, to_y); + } + } + + if (opacity == 1.0) + gdk_pixbuf_copy_area (paste_pb, + from_x, from_y, w, h, + base_pb, + to_x, to_y); + else + gdk_pixbuf_composite (paste_pb, base_pb, + to_x, to_y, w, h, + to_x - from_x, to_y - from_y, + 1.0, 1.0, + GDK_INTERP_HYPER, + opacity * 255); + + if (verbose_p) + fprintf (stderr, "%s: pasted %dx%d from %d,%d to %d,%d\n", + progname, paste_w, paste_h, from_x, from_y, to_x, to_y); + + gdk_pixbuf_unref (paste_pb); + write_pixbuf (base_pb, base_file); + gdk_pixbuf_unref (base_pb); +} + + +static void +write_pixbuf (GdkPixbuf *pb, const char *file) +{ + int jpeg_quality = 85; + + int w = gdk_pixbuf_get_width (pb); + int h = gdk_pixbuf_get_height (pb); + guchar *data = gdk_pixbuf_get_pixels (pb); + int ww = gdk_pixbuf_get_rowstride (pb); + int channels = gdk_pixbuf_get_n_channels (pb); + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE *out; + + if (channels != 3) + { + fprintf (stderr, "%s: %d channels?\n", progname); + exit (1); + } + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_compress (&cinfo); + + out = fopen (file, "wb"); + if (!out) + { + char buf[255]; + sprintf (buf, "%.100s: %.100s", progname, file); + perror (buf); + exit (1); + } + else if (verbose_p) + fprintf (stderr, "%s: writing %s...", progname, file); + + jpeg_stdio_dest (&cinfo, out); + + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = channels; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults (&cinfo); + cinfo.progressive_mode = TRUE; + jpeg_set_quality (&cinfo, jpeg_quality, TRUE); + + jpeg_start_compress (&cinfo, TRUE); + add_jpeg_comment (&cinfo); + + { + guchar *d = data; + guchar *end = d + (ww * h); + while (d < end) + { + jpeg_write_scanlines (&cinfo, &d, 1); + d += ww; + } + } + + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + + if (verbose_p) + { + struct stat st; + fflush (out); + if (fstat (fileno (out), &st)) + { + char buf[255]; + sprintf (buf, "%.100s: %.100s", progname, file); + perror (buf); + exit (1); + } + fprintf (stderr, " %dK\n", (st.st_size + 1023) / 1024); + } + + fclose (out); +} + + +static void +add_jpeg_comment (struct jpeg_compress_struct *cinfo) +{ + time_t now = time ((time_t *) 0); + struct tm *tm = localtime (&now); + const char fmt[] = + "\r\n" + " Generated by WebCollage: Exterminate All Rational Thought. \r\n" + " Copyright (c) 1999-%Y by Jamie Zawinski \r\n" + "\r\n" + " http://www.jwz.org/webcollage/ \r\n" + "\r\n" + " This is what the web looked like on %d %b %Y at %I:%M:%S %p %Z. \r\n" + "\r\n"; + char comment[sizeof(fmt) + 100]; + strftime (comment, sizeof(comment)-1, fmt, tm); + jpeg_write_marker (cinfo, JPEG_COM, comment, strlen (comment)); +} + + +static void +usage (void) +{ + fprintf (stderr, "usage: %s [-v] paste-file base-file\n" + "\t from-scale opacity\n" + "\t from-x from-y to-x to-y w h\n" + "\n" + "\t Pastes paste-file into base-file.\n" + "\t base-file will be overwritten (with JPEG data.)\n" + "\t scaling is applied first: coordinates apply to scaled image.\n", + progname); + exit (1); +} + + +int +main (int argc, char **argv) +{ + int i; + char *paste_file, *base_file, *s, dummy; + double from_scale, opacity; + int from_x, from_y, to_x, to_y, w, h; + + i = 0; + progname = argv[i++]; + s = strrchr (progname, '/'); + if (s) progname = s+1; + + if (argc != 11 && argc != 12) usage(); + + if (!strcmp(argv[i], "-v")) + verbose_p++, i++; + + paste_file = argv[i++]; + base_file = argv[i++]; + + if (*paste_file == '-') usage(); + if (*base_file == '-') usage(); + + s = argv[i++]; + if (1 != sscanf (s, " %lf %c", &from_scale, &dummy)) usage(); + if (from_scale <= 0 || from_scale > 100) usage(); + + s = argv[i++]; + if (1 != sscanf (s, " %lf %c", &opacity, &dummy)) usage(); + if (opacity <= 0 || opacity > 1) usage(); + + s = argv[i++]; if (1 != sscanf (s, " %d %c", &from_x, &dummy)) usage(); + s = argv[i++]; if (1 != sscanf (s, " %d %c", &from_y, &dummy)) usage(); + s = argv[i++]; if (1 != sscanf (s, " %d %c", &to_x, &dummy)) usage(); + s = argv[i++]; if (1 != sscanf (s, " %d %c", &to_y, &dummy)) usage(); + s = argv[i++]; if (1 != sscanf (s, " %d %c", &w, &dummy)) usage(); + s = argv[i++]; if (1 != sscanf (s, " %d %c", &h, &dummy)) usage(); + + if (w < 0) usage(); + if (h < 0) usage(); + + paste (paste_file, base_file, + from_scale, opacity, + from_x, from_y, to_x, to_y, + w, h); + exit (0); +} + +#endif /* HAVE_GDK_PIXBUF && HAVE_JPEGLIB -- whole file */ diff --git a/hacks/whirlygig.c b/hacks/whirlygig.c index 4f550c28..3757f961 100644 --- a/hacks/whirlygig.c +++ b/hacks/whirlygig.c @@ -16,7 +16,7 @@ #include #include "screenhack.h" -#define NCOLORS 1000 +#define NCOLORS 100 #define FULL_CYCLE 429496729 #define START_ARC 0 #define END_ARC 23040 diff --git a/hacks/xflame.c b/hacks/xflame.c index bd2be990..d3f2ed5c 100644 --- a/hacks/xflame.c +++ b/hacks/xflame.c @@ -40,6 +40,7 @@ - General cleanup and portability tweaks. * 4-Oct-99, jwz: added support for packed-24bpp (versus 32bpp.) + * 16-Jan-2002, jwz: added gdk_pixbuf support. */ @@ -48,6 +49,7 @@ #include "screenhack.h" +#include "xpm-pixmap.h" #include #include @@ -55,21 +57,6 @@ # include "xshm.h" #endif /* HAVE_XSHM_EXTENSION */ -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif - -#ifdef HAVE_XMU -# ifndef VMS -# include -# else /* VMS */ -# include -# endif /* VMS */ -#endif /* HAVE_XMU */ - #include "images/bob.xbm" #define MAX_VAL 255 @@ -640,115 +627,41 @@ loadBitmap(int *w, int *h) } else /* load a bitmap file */ { -#ifdef HAVE_XPM - XpmInfo xpm_info = { 0, }; - XpmImage xpm_image = { 0, }; - - int result = XpmReadFileToXpmImage (bitmap_name, &xpm_image, &xpm_info); - if (result == XpmSuccess) - { - int x, y; - unsigned char *result, *o; - unsigned char *grays; - XWindowAttributes xgwa; - - *w = xpm_image.width; - *h = xpm_image.height; - result = (unsigned char *) malloc ((*w) * (*h)); - if (!result) - { - fprintf(stderr, "%s: out of memory loading %s\n", - progname, bitmap_name); - exit (1); - } - - XGetWindowAttributes (display, window, &xgwa); - - grays = (unsigned char *) calloc (xpm_image.ncolors+1, 1); - for (x = 0; x < xpm_image.ncolors; x++) - { - XColor xc; - XpmColor *xpmc = &xpm_image.colorTable[x]; - char *cstring = 0; - if (xpmc->g_color && *xpmc->g_color) - cstring = xpmc->g_color; - else if (xpmc->g4_color && *xpmc->g4_color) - cstring = xpmc->g4_color; - else if (xpmc->c_color && *xpmc->c_color) - cstring = xpmc->c_color; - else - cstring = xpmc->m_color; - - memset (&xc, 0, sizeof(xc)); - if (!cstring || - !*cstring || - !XParseColor (display, xgwa.colormap, cstring, &xc)) - grays[x] = 0; - else - grays[x] = (int) (((xc.red * 0.299) + - (xc.green * 0.587) + - (xc.blue * 0.114)) - / 255); - } - - o = result; - for (y = 0; y < *h; y++) - for (x = 0; x < *w; x++) - { - int color = xpm_image.data[(y * (*w)) + x]; - if (color < 0 || color > xpm_image.ncolors) abort(); - *o++ = grays[color]; - } - return result; - } - else /* failed to read XPM -- fall through and try XBM */ -#endif /* HAVE_XPM */ - { -#ifdef HAVE_XMU - XImage *ximage = 0; - int width, height, xh, yh; - int x, y; - unsigned char *result, *o; - Pixmap bitmap = - XmuLocateBitmapFile (DefaultScreenOfDisplay (display), - bitmap_name, 0, 0, &width, &height, &xh, &yh); - if (!bitmap) - { - fprintf(stderr, "%s: unable to load bitmap file %s\n", - progname, bitmap_name); - exit (1); - } - ximage = XGetImage (display, bitmap, 0, 0, width, height, - 1L, XYPixmap); - XFreePixmap (display, bitmap); - - if (ximage->depth != 1) abort(); - - *w = ximage->width; - *h = ximage->height; - result = (unsigned char *) malloc ((*w) * (*h)); - if (!result) - { - fprintf(stderr, "%s: out of memory loading %s\n", - progname, bitmap_name); - exit (1); - } - - o = result; - for (y = 0; y < *h; y++) - for (x = 0; x < *w; x++) - *o++ = (XGetPixel(ximage, x, y) ? 255 : 0); - - return result; + Pixmap pixmap = + xpm_file_to_pixmap (display, window, bitmap_name, &width, &height, 0); + XImage *image; + int x, y; + unsigned char *result, *o; -#else /* !XMU */ - fprintf (stderr, - "%s: your vendor doesn't ship the standard Xmu library.\n", - progname); - fprintf (stderr, "\tWe can't load XBM files without it.\n"); - exit (1); -#endif /* !XMU */ - } + image = XGetImage (display, pixmap, 0, 0, width, height, ~0L, ZPixmap); + XFreePixmap(display, pixmap); + + result = (unsigned char *) malloc (width * height); + o = result; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++) + { + int rgba = XGetPixel (image, x, y); + /* This is *so* not handling all the cases... */ + int gray = (image->depth > 16 + ? ((((rgba >> 24) & 0xFF) + + ((rgba >> 16) & 0xFF) + + ((rgba >> 8) & 0xFF) + + ((rgba ) & 0xFF)) >> 2) + : ((((rgba >> 12) & 0x0F) + + ((rgba >> 8) & 0x0F) + + ((rgba >> 4) & 0x0F) + + ((rgba ) & 0x0F)) >> 1)); + *o++ = 255 - gray; + } + + XFree (image->data); + image->data = 0; + XDestroyImage (image); + + *w = width; + *h = height; + return result; } *w = 0; diff --git a/hacks/xlockmore.c b/hacks/xlockmore.c index 6ca7164f..28828beb 100644 --- a/hacks/xlockmore.c +++ b/hacks/xlockmore.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "screenhack.h" #include "xlockmoreI.h" diff --git a/hacks/xmatrix.c b/hacks/xmatrix.c index 1a6bebf1..016ec771 100644 --- a/hacks/xmatrix.c +++ b/hacks/xmatrix.c @@ -42,11 +42,11 @@ */ #include "screenhack.h" +#include "xpm-pixmap.h" #include #include -#ifdef HAVE_XPM -# include +#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) # include "images/matrix0.xpm" # include "images/matrix1.xpm" # include "images/matrix2.xpm" @@ -144,47 +144,21 @@ typedef struct { static void load_images_1 (m_state *state, int which) { -#ifdef HAVE_XPM +#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) if (!get_boolean_resource ("mono", "Boolean") && state->xgwa.depth > 1) { - - - XpmAttributes xpmattrs; - int result; - xpmattrs.valuemask = 0; - -# ifdef XpmCloseness - xpmattrs.valuemask |= XpmCloseness; - xpmattrs.closeness = 40000; -# endif -# ifdef XpmVisual - xpmattrs.valuemask |= XpmVisual; - xpmattrs.visual = state->xgwa.visual; -# endif -# ifdef XpmDepth - xpmattrs.valuemask |= XpmDepth; - xpmattrs.depth = state->xgwa.depth; -# endif -# ifdef XpmColormap - xpmattrs.valuemask |= XpmColormap; - xpmattrs.colormap = state->xgwa.colormap; -# endif - - result = XpmCreatePixmapFromData (state->dpy, state->window, - (which == 0 ? (state->small_p ? matrix0b_xpm : matrix0_xpm) : - which == 1 ? (state->small_p ? matrix1b_xpm : matrix1_xpm) : - (state->small_p ? matrix2b_xpm : matrix2_xpm)), - &state->images[which], 0 /* mask */, - &xpmattrs); - if (!state->images || (result != XpmSuccess && result != XpmColorError)) - state->images[which] = 0; - - state->image_width = xpmattrs.width; - state->image_height = xpmattrs.height; + char **bits = + (which == 0 ? (state->small_p ? matrix0b_xpm : matrix0_xpm) : + which == 1 ? (state->small_p ? matrix1b_xpm : matrix1_xpm) : + (state->small_p ? matrix2b_xpm : matrix2_xpm)); + + state->images[which] = + xpm_data_to_pixmap (state->dpy, state->window, bits, + &state->image_width, &state->image_height, 0); } else -#endif /* !HAVE_XPM */ +#endif /* !HAVE_XPM && !HAVE_GDK_PIXBUF */ { unsigned long fg, bg; state->image_width = (state->small_p ? matrix0b_width :matrix0_width); diff --git a/hacks/xpm-pixmap.c b/hacks/xpm-pixmap.c new file mode 100644 index 00000000..a4b3e2af --- /dev/null +++ b/hacks/xpm-pixmap.c @@ -0,0 +1,281 @@ +/* xpm-pixmap.c --- converts XPM data to a Pixmap. + * xscreensaver, Copyright (c) 1998, 2001, 2002 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "visual.h" /* for screen_number() */ + +extern char *progname; + + +#if defined(HAVE_GDK_PIXBUF) + +# include +# include + + +/* Returns a Pixmap structure containing the bits of the given XPM image. + This is the gdk_pixbuf version of this function. + */ +static Pixmap +xpm_to_pixmap_1 (Display *dpy, Window window, + int *width_ret, int *height_ret, + Pixmap *mask_ret, + const char *filename, + char **xpm_data) +{ + GdkPixbuf *pb; + static int initted = 0; + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + + if (!initted) + { + gdk_pixbuf_xlib_init (dpy, screen_number (xgwa.screen)); + xlib_rgb_init (dpy, xgwa.screen); + initted = 1; + } + + pb = (filename + ? gdk_pixbuf_new_from_file (filename) + : gdk_pixbuf_new_from_xpm_data ((const char **) xpm_data)); + if (pb) + { + int w = gdk_pixbuf_get_width (pb); + int h = gdk_pixbuf_get_height (pb); + Pixmap pixmap = 0; + + /* #### Note that this always uses the default colormap! Morons! + Owen says that in Gnome 2.0, I should try using + gdk_pixbuf_render_pixmap_and_mask_for_colormap() instead. + But I don't have Gnome 2.0 yet. + */ + gdk_pixbuf_xlib_render_pixmap_and_mask (pb, &pixmap, mask_ret, 128); + + if (!pixmap) + { + fprintf (stderr, "%s: out of memory (%d x %d)\n", progname, w, h); + exit (-1); + } + /* gdk_pixbuf_unref (pb); -- #### does doing this free colors? */ + + if (width_ret) *width_ret = w; + if (height_ret) *height_ret = h; + + return pixmap; + } + else if (filename) + { + fprintf (stderr, "%s: unable to load %s\n", progname, filename); + exit (-1); + } + else + { + fprintf (stderr, "%s: unable to initialize built-in images\n", progname); + exit (-1); + } +} + + +#elif defined(HAVE_XPM) + +#include +#include +#include + +#ifdef HAVE_XMU +# ifndef VMS +# include +#else /* VMS */ +# include +# endif /* VMS */ +#endif + +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + + +static int +handle_xpm_error (const char *filename, int status) +{ + if (!filename) filename = "builtin"; + switch (status) + { + case XpmSuccess: + return 0; + break; + case XpmColorError: + fprintf (stderr, "%s: %s: warning: color substitution performed\n", + progname, filename); + return 0; + break; + case XpmFileInvalid: + return 1; + break; + case XpmOpenFailed: + fprintf (stderr, "%s: %s: no such file\n", progname, filename); + break; + case XpmNoMemory: + fprintf (stderr, "%s: %s: out of memory\n", progname, filename); + break; + case XpmColorFailed: + fprintf (stderr, "%s: %s: color allocation failed\n", + progname, filename); + break; + default: + fprintf (stderr, "%s: %s: unknown XPM error %d\n", progname, + filename, status); + break; + } + exit (-1); +} + + +/* The libxpm version of this function... + */ +static Pixmap +xpm_to_pixmap_1 (Display *dpy, Window window, + int *width_ret, int *height_ret, + Pixmap *mask_ret, + const char *filename, + char **xpm_data) +{ + Pixmap pixmap = 0; + XpmAttributes xpmattrs; + XpmImage xpm_image; + XpmInfo xpm_info; + int status; + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + + memset (&xpm_image, 0, sizeof(xpm_image)); + memset (&xpm_info, 0, sizeof(xpm_info)); + + if (filename) + { + xpm_data = 0; + status = XpmReadFileToData ((char *) filename, &xpm_data); + if (handle_xpm_error (filename, status)) + goto TRY_XBM; + } + + xpmattrs.valuemask = 0; + +# ifdef XpmCloseness + xpmattrs.valuemask |= XpmCloseness; + xpmattrs.closeness = 40000; +# endif +# ifdef XpmVisual + xpmattrs.valuemask |= XpmVisual; + xpmattrs.visual = xgwa.visual; +# endif +# ifdef XpmDepth + xpmattrs.valuemask |= XpmDepth; + xpmattrs.depth = xgwa.depth; +# endif +# ifdef XpmColormap + xpmattrs.valuemask |= XpmColormap; + xpmattrs.colormap = xgwa.colormap; +# endif + + status = XpmCreatePixmapFromData (dpy, window, xpm_data, + &pixmap, mask_ret, &xpmattrs); + if (handle_xpm_error (filename, status)) + pixmap = 0; + else + { + if (width_ret) *width_ret = xpmattrs.width; + if (height_ret) *height_ret = xpmattrs.height; + } + + TRY_XBM: + +#ifdef HAVE_XMU + if (! pixmap) + { + unsigned long fg = BlackPixelOfScreen (xgwa.screen); + unsigned long bg = WhitePixelOfScreen (xgwa.screen); + int xh, yh; + Pixmap b2; + pixmap = XmuLocateBitmapFile (xgwa.screen, filename, + 0, 0, width_ret, height_ret, &xh, &yh); + if (! pixmap) + { + fprintf (stderr, "%s: couldn't find XBM %s\n", progname, + filename); + exit (-1); + } + b2 = XmuCreatePixmapFromBitmap (dpy, window, pixmap, + *width_ret, *height_ret, + xgwa.depth, fg, bg); + XFreePixmap (dpy, pixmap); + pixmap = b2; + + if (!pixmap) + { + fprintf (stderr, "%s: couldn't load XBM %s\n", progname, filename); + exit (-1); + } + } +#else /* !XMU */ + { + fprintf (stderr, + "%s: your vendor doesn't ship the standard Xmu library.\n", + progname); + fprintf (stderr, "\tWe can't load XBM files without it.\n"); + exit (-1); + } +#endif /* !XMU */ + + return pixmap; +} + +#else /* !HAVE_XPM && !HAVE_GDK_PIXBUF */ + +static Pixmap +xpm_to_pixmap_1 (Display *dpy, Window window, + int *width_ret, int *height_ret, + Pixmap *mask_ret, + const char *filename, + char **xpm_data) +{ + fprintf(stderr, "%s: not compiled with XPM or Pixbuf support.\n", progname); + exit (-1); +} + +#endif /* !HAVE_XPM */ + + +Pixmap +xpm_data_to_pixmap (Display *dpy, Window window, char **xpm_data, + int *width_ret, int *height_ret, + Pixmap *mask_ret) +{ + return xpm_to_pixmap_1 (dpy, window, width_ret, height_ret, mask_ret, + 0, xpm_data); +} + + +Pixmap +xpm_file_to_pixmap (Display *dpy, Window window, const char *filename, + int *width_ret, int *height_ret, + Pixmap *mask_ret) +{ + return xpm_to_pixmap_1 (dpy, window, width_ret, height_ret, mask_ret, + filename, 0); +} diff --git a/hacks/xpm-pixmap.h b/hacks/xpm-pixmap.h new file mode 100644 index 00000000..90e4ff57 --- /dev/null +++ b/hacks/xpm-pixmap.h @@ -0,0 +1,25 @@ +/* xpm-pixmap.h --- converts XPM data to Pixmaps. + * xscreensaver, Copyright (c) 1998, 2002 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifndef _XPM_PIXMAP_H_ +#define _XPM_PIXMAP_H_ + +/* Returns a Pixmap structure containing the bits of the given XPM image. + */ +extern Pixmap xpm_data_to_pixmap (Display *, Window, char **xpm_data, + int *width_ret, int *height_ret, + Pixmap *mask_ret); +extern Pixmap xpm_file_to_pixmap (Display *, Window, const char *filename, + int *width_ret, int *height_ret, + Pixmap *mask_ret); + +#endif /* _XPM_PIXMAP_H_ */ diff --git a/hacks/xspirograph.c b/hacks/xspirograph.c index 0853faa5..2cc52f28 100644 --- a/hacks/xspirograph.c +++ b/hacks/xspirograph.c @@ -12,6 +12,10 @@ * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. + * + * Modified (Dec 2001) by Matthew Strait + * Added -subdelay and -alwaysfinish + * Prevented redrawing over existing lines */ #include @@ -20,8 +24,10 @@ static GC draw_gc; static int sleep_time; +static int sub_sleep_time; static int num_layers; static unsigned int default_fg_pixel; +static Bool always_finish_p; static void init_tsg (Display *dpy, Window window) @@ -48,6 +54,8 @@ go (Display *dpy, Window window, int width, height; int xmid, ymid; int x1, y1, x2, y2; + float firstx = 0, firsty = 0; + float tmpx, tmpy; int theta; int delta; @@ -62,9 +70,10 @@ go (Display *dpy, Window window, y1 = ymid; - for (theta = 1; theta < ( 360 * 100 ); theta++) + for (theta = 1; /* theta < ( 360 * 100 ) */; theta++) + /* see below about alwaysfinish */ { - x2 = xmid + (( radius1 /* * * * * */ + tmpx = xmid + (( radius1 /* * * * * */ - radius2 ) /* This algo simulates */ * cos(( theta /* the rotation of a */ * M_PI ) /* circular disk inside */ @@ -78,7 +87,7 @@ go (Display *dpy, Window window, / 180 ) /* of delta needs to be */ ); /* given, which greatly */ /* adds to the beauty */ - y2 = ymid + ( /* of the figure. */ + tmpy = ymid + ( /* of the figure. */ ( radius1 - radius2 /* */ ) * sin /* Imperfection adds to */ ( /* beauty, symbolically */ @@ -96,14 +105,39 @@ go (Display *dpy, Window window, ) * M_PI / 180 ) ); - + + /*makes integers from the calculated values to do the drawing*/ + x2 = tmpx; + y2 = tmpy; + + /*stores the first values for later reference*/ + if(theta == 1) + { + firstx = tmpx; + firsty = tmpy; + } XDrawLine (dpy, window, draw_gc, x1, y1, x2, y2); x1 = x2; y1 = y2; XFlush (dpy); - } + + /* compares the exact values calculated to the first + exact values calculated */ + /* this will break when nothing new is being drawn */ + if(tmpx == firstx && tmpy == firsty && theta != 1) + break; + + /* this will break after 36000 iterations if + the -alwaysfinish option is not specified */ + if(!always_finish_p && theta > ( 360 * 100 ) ) + break; + + /* usleeping every time is too slow */ + if(theta%100 == 0) + usleep(sub_sleep_time); + } } @@ -130,7 +164,7 @@ getset (Display *dpy, Window window, XColor *color, Bool *got_color) XClearWindow (dpy, window); - for(counter = 0; counter < num_layers; counter ++) + for(counter = 0; counter < num_layers; counter++) { divisor = ((frand (3.0) + 1) * (((random() & 1) * 2) - 1)); @@ -149,6 +183,7 @@ getset (Display *dpy, Window window, XColor *color, Bool *got_color) else XSetForeground (dpy, draw_gc, default_fg_pixel); } + go (dpy, window, radius1, -radius2, distance); /* once again, with a parameter negated, just for kicks */ @@ -163,6 +198,7 @@ getset (Display *dpy, Window window, XColor *color, Bool *got_color) else XSetForeground (dpy, draw_gc, default_fg_pixel); } + go (dpy, window, radius1, radius2, distance); } } @@ -201,15 +237,20 @@ getset_go (Display *dpy, Window window) char *progclass = "XSpiroGraph"; char *defaults [] = { - ".background: black", - "*delay: 5", - "*layers: 1", + ".background: black", + "*delay: 5", + "*subdelay: 0", + "*layers: 1", + "*alwaysfinish: false", 0 }; XrmOptionDescRec options [] = { { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-layers", ".layers", XrmoptionSepArg, 0 }, + { "-subdelay", ".subdelay", XrmoptionSepArg, 0 }, + { "-layers", ".layers", XrmoptionSepArg, 0 }, + { "-alwaysfinish", ".alwaysfinish", XrmoptionNoArg, "true"}, + { "-noalwaysfinish", ".alwaysfinish", XrmoptionNoArg, "false"}, { 0, 0, 0, 0 } }; int options_size = (sizeof (options) / sizeof (options[0])); @@ -218,7 +259,10 @@ void screenhack (Display *dpy, Window window) { sleep_time = get_integer_resource("delay", "Integer"); + sub_sleep_time = get_integer_resource("subdelay", "Integer"); num_layers = get_integer_resource("layers", "Integer"); + always_finish_p = get_boolean_resource ("alwaysfinish", "Boolean"); + init_tsg (dpy, window); while (1) getset_go (dpy, window); diff --git a/hacks/xspirograph.man b/hacks/xspirograph.man new file mode 100644 index 00000000..2175e437 --- /dev/null +++ b/hacks/xspirograph.man @@ -0,0 +1,70 @@ +.TH XScreenSaver 1 "9-Dec-2001" "X Version 11" +.SH NAME +xspirograph - simulates the rotation of a disk inside a circular rim +.SH SYNOPSIS +.B xspirograph +[\-display \fIhost:display.screen\fP] [\-window] [\-root] [\-install] +[\-visual \fIvisual\fP] +[\-delay \fIseconds\fP] +[\-subdelay \fIuseconds\fP] +[\-layers \fIinteger\fP] +[\-alwaysfinish] [\-noalwaysfinish] +.SH DESCRIPTION +\fIxspirograph\fP draws patterns such as those made by a +spirograph, that is, the curve traced by a point on a circular +disk rotating on the inside of a hollow circular rim. +.SH OPTIONS +.I xspirograph +accepts the following options: +.TP 8 +.B \-window +Draw on a newly-created window. This is the default. +.TP 8 +.B \-root +Draw on the root window. +.TP 8 +.B \-install +Install a private colormap for the window. +.TP 8 +.B \-visual \fIvisual\fP\fP +Specify which visual to use. Legal values are the name of a visual class, +or the id number (decimal or hex) of a specific visual. +.TP 8 +.B \-delay \fIsecs\fP +The delay between finishing one draw and starting the next. Default: +5 seconds. +.TP 8 +.B \-subdelay \fIusec\fP +The time to delay between each hundred line draws. Use this if you +want to see the pattern form. Default: 0. +.TP 8 +.B \-alwaysfinish\fP \fB\-noalwaysfinish\fP +If you want each pattern to draw until it is done, specify the first. +Otherwise, they will stop after a set number of iterations. Default: +no. +.TP 8 +.B \-layers \fIinteger\fP +Number of pairs of patterns to draw between each erase. + +.SH ENVIRONMENT +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH SEE ALSO +.BR X (1), +.BR xscreensaver (1) +.SH COPYRIGHT +Copyright \(co 2000 by Rohit Singh + 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. +.P +Modified by Matthew Strait Dec 2001. diff --git a/hacks/xteevee.c b/hacks/xteevee.c index df4ce24a..90d3e0fc 100644 --- a/hacks/xteevee.c +++ b/hacks/xteevee.c @@ -26,6 +26,8 @@ #include "screenhack.h" #include "colorbars.h" #include +#include +#include /* Defines *******************************************************************/ diff --git a/setup.com b/setup.com index e08a7777..c986b602 100644 --- a/setup.com +++ b/setup.com @@ -4,6 +4,7 @@ $ set def [.HACKS] $ mydisk = f$trnlmn("SYS$DISK") $ mydir = mydisk+f$directory() $ ant :== $'mydir'ant +$ apollonian :== $'mydir'apollonian $ attraction :== $'mydir'attraction $ blaster :== $'mydir'blaster $ blitspin :== $'mydir'blitspin @@ -26,6 +27,7 @@ $ discrete :== $'mydir'discrete $ distort :== $'mydir'distort $ drift :== $'mydir'drift $ epicycle :== $'mydir'epicycle +$ euler2d :== $'mydir'euler2d $ fadeplot :== $'mydir'fadeplot $ flag :== $'mydir'flag $ flame :== $'mydir'flame @@ -44,6 +46,7 @@ $ ifs :== $'mydir'ifs $ imsmap :== $'mydir'imsmap $ interference :== $'mydir'interference $ jigsaw :== $'mydir'jigsaw +$ juggle :== $'mydir'juggle $ julia :== $'mydir'julia $ kaleidescope :== $'mydir'kaleidescope $ kumppa :== $'mydir'kumppa @@ -65,6 +68,7 @@ $ penetrate :== $'mydir'penetrate $ penrose :== $'mydir'penrose $ petri :== $'mydir'petri $ phosphor :== $'mydir'phosphor +$ polyominoes :== $'mydir'polyominoes $ pyro :== $'mydir'pyro $ qix :== $'mydir'qix $ rd-bomb :== $'mydir'rd-bomb @@ -87,11 +91,14 @@ $ starfish :== $'mydir'starfish $ strange :== $'mydir'strange $ swirl :== $'mydir'swirl $ t3d :== $'mydir't3d +$ thornbird :== $'mydir'thornbird $ triangle :== $'mydir'triangle $ truchet :== $'mydir'truchet +$ twang :== $'mydir'twang $ vermiculate :== $'mydir'vermiculate $ vines :== $'mydir'vines $ wander :== $'mydir'wander +$ webcollage-helper :== $'mydir'webcollage-helper $ whirlwindwarp :== $'mydir'whirlwindwarp $ whirlygig :== $'mydir'whirlygig $ worm :== $'mydir'worm diff --git a/utils/grabscreen.c b/utils/grabscreen.c index 5ef32e1e..f2abe8cb 100644 --- a/utils/grabscreen.c +++ b/utils/grabscreen.c @@ -267,12 +267,19 @@ grab_screen_image (Screen *screen, Window window) { Display *dpy = DisplayOfScreen (screen); XWindowAttributes xgwa; - Window real_root = XRootWindowOfScreen (screen); /* not vroot */ - Bool root_p = (window == real_root); - Bool saver_p = xscreensaver_window_p (dpy, window); + Window real_root; + Bool root_p; + Bool saver_p; Bool grab_mouse_p = False; int unmap_time = 0; + real_root = XRootWindowOfScreen (screen); /* not vroot */ + root_p = (window == real_root); + saver_p = xscreensaver_window_p (dpy, window); + + XGetWindowAttributes (dpy, window, &xgwa); + screen = xgwa.screen; + if (saver_p) /* I think this is redundant, but just to be safe... */ root_p = False; @@ -300,15 +307,13 @@ grab_screen_image (Screen *screen, Window window) if (grab_verbose_p) { - XWindowAttributes xgwa2; fprintf(stderr, "\n%s: window 0x%08lX root: %d saver: %d grab: %d wait: %.1f\n", progname, (unsigned long) window, root_p, saver_p, grab_mouse_p, ((double)unmap_time)/1000000.0); - XGetWindowAttributes (dpy, window, &xgwa2); fprintf(stderr, "%s: ", progname); - describe_visual(stderr, screen, xgwa2.visual, False); + describe_visual(stderr, screen, xgwa.visual, False); fprintf (stderr, "\n"); } @@ -344,8 +349,6 @@ grab_screen_image (Screen *screen, Window window) usleep(unmap_time); /* wait for everyone to swap in and handle exposes */ } - XGetWindowAttributes (dpy, window, &xgwa); - if (!root_p) { #ifdef HAVE_READ_DISPLAY_EXTENSION @@ -371,15 +374,13 @@ grab_screen_image (Screen *screen, Window window) else /* root_p */ { Pixmap pixmap; - XWindowAttributes xgwa; - XGetWindowAttributes(dpy, window, &xgwa); pixmap = XCreatePixmap(dpy, window, xgwa.width, xgwa.height, xgwa.depth); #ifdef HAVE_READ_DISPLAY_EXTENSION if (! read_display(screen, window, pixmap, True)) #endif { - Window real_root = XRootWindowOfScreen (xgwa.screen); /* not vroot */ + Window real_root = XRootWindowOfScreen (screen); /* not vroot */ XGCValues gcv; GC gc; diff --git a/utils/version.h b/utils/version.h index 1531d72a..942d03b9 100644 --- a/utils/version.h +++ b/utils/version.h @@ -1,2 +1,2 @@ static const char screensaver_id[] = - "@(#)xscreensaver 4.00 (21-Nov-2001), by Jamie Zawinski (jwz@jwz.org)"; + "@(#)xscreensaver 4.01 (24-Feb-2002), by Jamie Zawinski (jwz@jwz.org)"; diff --git a/xscreensaver.lsm b/xscreensaver.lsm index 1904d75c..d8983cb5 100644 --- a/xscreensaver.lsm +++ b/xscreensaver.lsm @@ -1,25 +1,25 @@ Begin3 Title: xscreensaver -Version: 4.00 -Entered-date: 02JAN02 +Version: 4.01 +Entered-date: 24FEB02 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. - More than 120 display modes are included in this package. + More than 140 display modes are included in this package. Keywords: screen saver, screen lock, lock, xlock, X11 Author: jwz@jwz.org (Jamie Zawinski) Maintained-by: jwz@jwz.org (Jamie Zawinski) Primary-site: http://www.jwz.org/xscreensaver/ - xscreensaver-4.00.tar.gz - 54K xscreensaver.README + 2156K xscreensaver-4.01.tar.gz + 56K xscreensaver.README 1K xscreensaver.lsm Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/ - xscreensaver-4.00.tar.gz - 54K xscreensaver.README + 2156K xscreensaver-4.01.tar.gz + 56K xscreensaver.README 1K xscreensaver.lsm Alternate-site: ftp.x.org /contrib/applications/ - xscreensaver-4.00.tar.gz - 54K xscreensaver.README + 2156K xscreensaver-4.01.tar.gz + 56K xscreensaver.README 1K xscreensaver.lsm Platforms: Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD, BSDI, SCO, OSF1, Ultrix, VMS. diff --git a/xscreensaver.lsm.sh b/xscreensaver.lsm.sh index fc1103f9..65f489f7 100755 --- a/xscreensaver.lsm.sh +++ b/xscreensaver.lsm.sh @@ -27,7 +27,7 @@ Entered-date: $DATE 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. - More than 120 display modes are included in this package. + More than 140 display modes are included in this package. Keywords: screen saver, screen lock, lock, xlock, X11 Author: jwz@jwz.org (Jamie Zawinski) Maintained-by: jwz@jwz.org (Jamie Zawinski) diff --git a/xscreensaver.spec b/xscreensaver.spec index 1ffda636..6d7a6cb1 100644 --- a/xscreensaver.spec +++ b/xscreensaver.spec @@ -1,5 +1,5 @@ %define name xscreensaver -%define version 4.00 +%define version 4.01 %define release 1 %define serial 1 %define x11_prefix /usr/X11R6 @@ -7,7 +7,8 @@ %define kde_prefix /usr %define gnome_datadir %{gnome_prefix}/share -%define gnome_ccdir %{gnome_datadir}/control-center/Desktop +%define gnome_ccdir_1 %{gnome_datadir}/control-center/Desktop +%define gnome_ccdir_2 %{gnome_datadir}/control-center/capplets %define gnome_paneldir %{gnome_datadir}/gnome/apps/Settings/Desktop %define gnome_icondir %{gnome_datadir}/pixmaps @@ -29,11 +30,15 @@ Vendor: Jamie Zawinski Source: %{name}-%{version}.tar.gz Buildroot: %{_tmppath}/%{name}-%{version}-root +# This package really should be made to depend on +# control-center >= 1.4.0.2 -OR- control-center >= 1.5.12 +# but there's no way to express that. + %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. -More than 120 display modes are included in this package. +More than 140 display modes are included in this package. %{?USE_GL:See also the xscreensaver-gl package, which} %{?USE_GL:includes optional OpenGL display modes.} @@ -87,7 +92,8 @@ make # directory instead (/usr/bin/). # mkdir -p $RPM_BUILD_ROOT%{gnome_prefix}/bin -mkdir -p $RPM_BUILD_ROOT%{gnome_ccdir} +mkdir -p $RPM_BUILD_ROOT%{gnome_ccdir_1} +mkdir -p $RPM_BUILD_ROOT%{gnome_ccdir_2} mkdir -p $RPM_BUILD_ROOT%{gnome_paneldir} # Likewise for KDE: the .kss file goes in the KDE bin directory (/usr/bin/). @@ -144,6 +150,15 @@ install -m 4755 driver/xscreensaver $RPM_BUILD_ROOT%{x11_prefix}/bin # chmod -R a+r,u+w,og-w $RPM_BUILD_ROOT +%post +# This part runs on the end user's system, when the RPM is installed. + +pids=`pidof xscreensaver` +if [ -n "$pids" ]; then + echo "sending SIGHUP to running xscreensaver ($pids)..." >&2 + kill -HUP $pids +fi + %clean if [ -d $RPM_BUILD_ROOT ]; then rm -r $RPM_BUILD_ROOT ; fi if [ -d $RPM_BUILD_ROOT-gl ]; then rm -r $RPM_BUILD_ROOT-gl ; fi @@ -162,7 +177,8 @@ if [ -d $RPM_BUILD_ROOT-gl ]; then rm -r $RPM_BUILD_ROOT-gl ; fi %config(missingok) %{kde_prefix}/bin/*.kss %config(missingok) %{gnome_prefix}/bin/*-capplet -%config(missingok) %{gnome_ccdir}/*.desktop +%config(missingok) %{gnome_ccdir_1}/*.desktop +%config(missingok) %{gnome_ccdir_2}/*.desktop %config(missingok) %{gnome_paneldir}/*.desktop %config(missingok) %{gnome_icondir}/*