http://ftp.x.org/contrib/applications/xscreensaver-3.10.tar.gz
authorZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:33 +0000 (00:42 -0500)
committerZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:33 +0000 (00:42 -0500)
-rw-r--r-- 1 zblaxell zblaxell 1085749 Apr 26  1999 xscreensaver-3.10.tar.gz
0ef47faea495b2452c4ffee0c809d8205e314864  xscreensaver-3.10.tar.gz

41 files changed:
README
configure
configure.in
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/passwd-pwent.c
driver/passwd.c
driver/prefs.c
driver/subprocs.c
driver/windows.c
driver/xscreensaver-command.man
driver/xscreensaver-demo.man
driver/xscreensaver.c
driver/xscreensaver.h
driver/xscreensaver.man
hacks/Makefile.in
hacks/compile_axp.com
hacks/compile_decc.com
hacks/critical.c
hacks/glx/Makefile.in
hacks/glx/glplanet.c
hacks/glx/pulsar.c [new file with mode: 0644]
hacks/images/matrix.xbm [new file with mode: 0644]
hacks/images/matrix.xpm [new file with mode: 0644]
hacks/penrose.c
hacks/penrose.man
hacks/phosphor.c [new file with mode: 0644]
hacks/screenhack.c
hacks/slip.c
hacks/sphere.c
hacks/squiral.c
hacks/t3d.c
hacks/xflame.c
hacks/xlyap.c
hacks/xmatrix.c [new file with mode: 0644]
setup.com
utils/colors.c
utils/version.h
xscreensaver.lsm
xscreensaver.spec

diff --git a/README b/README
index 889044378762937c5232784ca195ae5e923ad717..417e248a26821e8165e3088f190f2c556f4afa91 100644 (file)
--- a/README
+++ b/README
@@ -77,6 +77,17 @@ http://www.jwz.org/xscreensaver/.
 
                               ============
 
 
                               ============
 
+Changes since 3.09:   * Added `phosphor', `xmatrix', and `pulsar' hacks.
+                      * Fixed a bug in the color allocator that sometimes
+                        caused `starfish' to fall back to monochrome.
+                      * Reduced the amount of code that runs before root
+                        privileges are disavowed: "normal" and "shadow"
+                        passwords now do some initialization as root, but the
+                        PAM and Kerberos authorization schemes will be
+                        initialized while running as "nobody".  Supposedly 
+                        this closes a potential security hole when using
+                        Kerberos.
+                      * Added some more sanity checking to configure.
 Changes since 3.08:   * Added `compass', `squiral', `xflame', `wander',
                         `spotlight', and `critical' hacks.
                       * Added some new modes to `decayscreen'.
 Changes since 3.08:   * Added `compass', `squiral', `xflame', `wander',
                         `spotlight', and `critical' hacks.
                       * Added some new modes to `decayscreen'.
index 43a972c2ee534dd6e352cea86695085ce1b30ede..5d61f180ad3f110a752a3164d55d24bc4fa8d145 100755 (executable)
--- a/configure
+++ b/configure
@@ -8327,7 +8327,60 @@ eval HACKDIR=${HACKDIR}
 bindir=`echo  "${bindir}"  | sed 's@/$@@;s@//*@/@g'`
 HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'`
 
 bindir=`echo  "${bindir}"  | sed 's@/$@@;s@//*@/@g'`
 HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'`
 
+
+# Sanity check the subdir
+for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command ; do
+  if test "${HACKDIR}" = "${bindir}/${bad_choice}" ; then
+    echo ""
+    { echo "configure: error: \"--enable-subdir=${bindir}/${bad_choice}\" won't work.
+                   There will be an executable installed with that name, so
+                   that can't be the name of a directory as well.  Please
+                   re-configure with a different directory name." 1>&2; exit 1; }
+  fi
+done
+
+
+do_dir_warning=no
+
+# Now let's see if there's a previous RPM version already installed.  Blargh!
+
+# M4 sucks!!
+
+rpmv=`(rpm -qv xscreensaver) 2>&- | \
+      sed 's/^xscreensaver-\([0-9][0-9]*[.][0-9][0-9]*\)-[0-9][0-9]*$/\1/'`
+
+
+if test \! -z "$rpmv" ; then
+  rpmbdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/xscreensaver-demo$@\1@p'`
+  rpmhdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/attraction$@\1@p'`
+
+  warning=no
+  warnL "There is already an installed RPM of xscreensaver $rpmv"
+  warn2 "on this system.  You might want to remove it (with"
+  warn2 '"rpm -ve xscreensaver") before running "make install"'
+  warn2 "from this directory."
+  echo ""
+  warn2 "Alternately, you could build this version of xscreensaver"
+  warn2 'as an RPM, and then install that.  An "xscreensaver.spec"'
+  warn2 "file is included.  See the RPM documentation for more info."
+  echo ""
+
+  if test "$rpmbdir" = "$rpmhdir" ; then
+    warn2 "The RPM version was installed in $rpmbdir."
+  else
+    warn2 "The RPM version was installed in $rpmbdir,"
+    warn2 "with demos in $rpmhdir."
+  fi
+
+  do_dir_warning=yes
+fi
+
+
 if test "${bindir}" = "${HACKDIR}" ; then
 if test "${bindir}" = "${HACKDIR}" ; then
+  do_dir_warning=yes
+fi
+
+if test "$do_dir_warning" = yes; then
   echo ""
   echo "$warnsep"
   echo ""
   echo ""
   echo "$warnsep"
   echo ""
index 39a30f9daf980d8f22962c02c833d03dab3dee55..75a8fe321785428a76d7c25d05815aee43202f25 100644 (file)
@@ -2180,7 +2180,60 @@ eval HACKDIR=${HACKDIR}
 bindir=`echo  "${bindir}"  | sed 's@/$@@;s@//*@/@g'`
 HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'`
 
 bindir=`echo  "${bindir}"  | sed 's@/$@@;s@//*@/@g'`
 HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'`
 
+
+# Sanity check the subdir
+for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command ; do
+  if test "${HACKDIR}" = "${bindir}/${bad_choice}" ; then
+    echo ""
+    AC_MSG_ERROR([\"--enable-subdir=${bindir}/${bad_choice}\" won't work.
+                   There will be an executable installed with that name, so
+                   that can't be the name of a directory as well.  Please
+                   re-configure with a different directory name.])
+  fi
+done
+
+
+do_dir_warning=no
+
+# Now let's see if there's a previous RPM version already installed.  Blargh!
+
+# M4 sucks!!
+changequote(X,Y)
+rpmv=`(rpm -qv xscreensaver) 2>&- | \
+      sed 's/^xscreensaver-\([0-9][0-9]*[.][0-9][0-9]*\)-[0-9][0-9]*$/\1/'`
+changequote([,])
+
+if test \! -z "$rpmv" ; then
+  rpmbdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/xscreensaver-demo$@\1@p'`
+  rpmhdir=`rpm -ql xscreensaver | sed -n 's@^\(.*\)/attraction$@\1@p'`
+
+  warning=no
+  warnL "There is already an installed RPM of xscreensaver $rpmv"
+  warn2 "on this system.  You might want to remove it (with"
+  warn2 '"rpm -ve xscreensaver") before running "make install"'
+  warn2 "from this directory."
+  echo ""
+  warn2 "Alternately, you could build this version of xscreensaver"
+  warn2 'as an RPM, and then install that.  An "xscreensaver.spec"'
+  warn2 "file is included.  See the RPM documentation for more info."
+  echo ""
+
+  if test "$rpmbdir" = "$rpmhdir" ; then
+    warn2 "The RPM version was installed in $rpmbdir."
+  else
+    warn2 "The RPM version was installed in $rpmbdir,"
+    warn2 "with demos in $rpmhdir."
+  fi
+
+  do_dir_warning=yes
+fi
+
+
 if test "${bindir}" = "${HACKDIR}" ; then
 if test "${bindir}" = "${HACKDIR}" ; then
+  do_dir_warning=yes
+fi
+
+if test "$do_dir_warning" = yes; then
   echo ""
   echo "$warnsep"
   echo ""
   echo ""
   echo "$warnsep"
   echo ""
index d9b512295c178766710b84e45e79fa0d0b5ef618..0187e2172b6773762c86a92fe2f4858bb6dcc191 100644 (file)
@@ -176,6 +176,7 @@ install-program: $(EXES)
           else                                                         \
            e=echo ;                                                    \
  $$e ""                                                                             ;\
           else                                                         \
            e=echo ;                                                    \
  $$e ""                                                                             ;\
+ $$e "  ####################################################################";\
  $$e "  Warning: xscreensaver has been compiled with support for shadow"     ;\
  $$e "           passwords.  If your system actually uses shadow passwords," ;\
  $$e "           then xscreensaver must be installed as a setuid root"      ;\
  $$e "  Warning: xscreensaver has been compiled with support for shadow"     ;\
  $$e "           passwords.  If your system actually uses shadow passwords," ;\
  $$e "           then xscreensaver must be installed as a setuid root"      ;\
@@ -184,6 +185,7 @@ install-program: $(EXES)
  $$e ""                                                                             ;\
  $$e "           For now, xscreensaver will be installed non-setuid, which"  ;\
  $$e "           means that locking might not work.  (Try it and see.)"             ;\
  $$e ""                                                                             ;\
  $$e "           For now, xscreensaver will be installed non-setuid, which"  ;\
  $$e "           means that locking might not work.  (Try it and see.)"             ;\
+ $$e "  ####################################################################";\
  $$e ""                                                                             ;\
           fi ;                                                         \
        fi ;                                                            \
  $$e ""                                                                             ;\
           fi ;                                                         \
        fi ;                                                            \
@@ -194,7 +196,32 @@ install-program: $(EXES)
 
 install-ad: XScreenSaver.ad
        @if [ ! -d $(AD_DIR) ]; then $(INSTALL_DIRS) $(AD_DIR) ; fi
 
 install-ad: XScreenSaver.ad
        @if [ ! -d $(AD_DIR) ]; then $(INSTALL_DIRS) $(AD_DIR) ; fi
-       $(INSTALL_DATA) XScreenSaver.ad $(AD_DIR)/XScreenSaver
+       @-echo $(INSTALL_DATA) XScreenSaver.ad $(AD_DIR)/XScreenSaver ;       \
+       if $(INSTALL_DATA) XScreenSaver.ad $(AD_DIR)/XScreenSaver ; then      \
+         true ;                                                              \
+       else                                                                  \
+         e=echo ;                                                            \
+         if [ -f $(AD_DIR)/XScreenSaver ]; then                              \
+ $$e ""                                                                             ;\
+ $$e "  ####################################################################";\
+ $$e "  Warning: unable to install $(AD_DIR)/XScreenSaver"                  ;\
+ $$e "           That file exists, and is unwritable.  It is probably from"  ;\
+ $$e "           an older version of xscreensaver, and could cause things"   ;\
+ $$e "           to malfunction.  Please delete it!"                        ;\
+ $$e "  ####################################################################";\
+ $$e ""                                                                             ;\
+           exit 1 ;                                                          \
+         else                                                                \
+ $$e ""                                                                             ;\
+ $$e "  ####################################################################";\
+ $$e "  Warning: unable to install $(AD_DIR)/XScreenSaver"                  ;\
+ $$e "           The directory is unwritable.  This is probably ok;"        ;\
+ $$e "           xscreensaver should work without that file."               ;\
+ $$e "  ####################################################################";\
+ $$e ""                                                                             ;\
+           exit 0 ;                                                          \
+         fi                                                                  \
+       fi
 
 install-man: $(MEN)
        @men="$(MEN)" ;                                                 \
 
 install-man: $(MEN)
        @men="$(MEN)" ;                                                 \
@@ -235,11 +262,14 @@ install-pam:
          if [ ! -f $$dir/$$dest ]; then                                \
            e=echo ;                                                    \
  $$e ""                                                                             ;\
          if [ ! -f $$dir/$$dest ]; then                                \
            e=echo ;                                                    \
  $$e ""                                                                             ;\
+ $$e "  ####################################################################";\
  $$e "  Warning: xscreensaver has been compiled with support for Pluggable"  ;\
  $$e "           Authentication Modules (PAM).  However, we were unable to"  ;\
  $$e "  Warning: xscreensaver has been compiled with support for Pluggable"  ;\
  $$e "           Authentication Modules (PAM).  However, we were unable to"  ;\
- $$e "           install the file $$dir/$$dest.  PAM is unlikely to work"    ;\
- $$e "           without this file (and old-style password authentication"   ;\
- $$e "           will be used instead, which may or may not work.)"         ;\
+ $$e "           install the file $$dir/$$dest.  PAM is unlikely"           ;\
+ $$e "           to work without this file (and old-style password"         ;\
+ $$e "           authentication will be used instead, which may or may not"  ;\
+ $$e "           work.)"                                                    ;\
+ $$e "  ####################################################################";\
  $$e ""                                                                             ;\
          fi ;                                                          \
        elif [ -f $$conf ]; then                                        \
  $$e ""                                                                             ;\
          fi ;                                                          \
        elif [ -f $$conf ]; then                                        \
@@ -248,9 +278,11 @@ install-pam:
          else                                                          \
            e=echo ;                                                    \
  $$e ""                                                                             ;\
          else                                                          \
            e=echo ;                                                    \
  $$e ""                                                                             ;\
+ $$e "  ####################################################################";\
  $$e "  Warning: xscreensaver has been compiled with support for Pluggable"  ;\
  $$e "           Authentication Modules (PAM).  To complete the installation";\
  $$e "           of PAM support, you must add this to the file $$conf:"             ;\
  $$e "  Warning: xscreensaver has been compiled with support for Pluggable"  ;\
  $$e "           Authentication Modules (PAM).  To complete the installation";\
  $$e "           of PAM support, you must add this to the file $$conf:"             ;\
+ $$e "  ####################################################################";\
  $$e ""                                                                             ;\
            cat $$src | grep -v '#%' | sed "s/^/        $$dest  /" ;    \
            echo "";                                                    \
  $$e ""                                                                             ;\
            cat $$src | grep -v '#%' | sed "s/^/        $$dest  /" ;    \
            echo "";                                                    \
index bdfcc5868dc07442a422e1cc655bcf13de359ee2..cc35ca4a413b1104613e32e0276669c01823f066 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 3.09
-!                                11-Apr-99
+!                              version 3.10
+!                                27-Apr-99
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
                wander -root -advance 0 -size 10 -circles True            \
                  -length 10000 -reset 100000                           \n\
                critical -root                                          \n\
                wander -root -advance 0 -size 10 -circles True            \
                  -length 10000 -reset 100000                           \n\
                critical -root                                          \n\
+               phosphor -root                                          \n\
+               xmatrix -root                                           \n\
                                                                          \
        mono:   rocks -root                                             \n\
        color:  rocks -root -fg darksalmon                              \n\
                                                                          \
        mono:   rocks -root                                             \n\
        color:  rocks -root -fg darksalmon                              \n\
 @GL_KLUDGE@    atlantis -root                                          \n\
 @GL_KLUDGE@    lament -root                                            \n\
 @GL_KLUDGE@    bubble3d -root                                          \n\
 @GL_KLUDGE@    atlantis -root                                          \n\
 @GL_KLUDGE@    lament -root                                            \n\
 @GL_KLUDGE@    bubble3d -root                                          \n\
-@GL_KLUDGE@    glplanet -root                                          \n
+@GL_KLUDGE@    glplanet -root                                          \n\
+@GL_KLUDGE@    pulsar -root                                            \n
  
 
 ! A few of the hacks require OpenGL, and will only be built if you have it.
  
 
 ! A few of the hacks require OpenGL, and will only be built if you have it.
index 9d4c348e1a773e419177b8b070396e039c168b4e..0178752289600f139216242742b22ac2e6e7bb52 100644 (file)
                wander -root -advance 0 -size 10 -circles True            \
                  -length 10000 -reset 100000                           \\n\
                critical -root                                          \\n\
                wander -root -advance 0 -size 10 -circles True            \
                  -length 10000 -reset 100000                           \\n\
                critical -root                                          \\n\
+               phosphor -root                                          \\n\
+               xmatrix -root                                           \\n\
                                                                          \
        mono:   rocks -root                                             \\n\
        color:  rocks -root -fg darksalmon                              \\n\
                                                                          \
        mono:   rocks -root                                             \\n\
        color:  rocks -root -fg darksalmon                              \\n\
                atlantis -root                                          \\n\
                lament -root                                            \\n\
                bubble3d -root                                          \\n\
                atlantis -root                                          \\n\
                lament -root                                            \\n\
                bubble3d -root                                          \\n\
-               glplanet -root                                          \\n",
+               glplanet -root                                          \\n\
+               pulsar -root                                            \\n",
 " ",
 "XScreenSaver.pointerPollTime:         5",
 "XScreenSaver.initialDelay:            0",
 " ",
 "XScreenSaver.pointerPollTime:         5",
 "XScreenSaver.initialDelay:            0",
index 6e83e0f4a5440f757353b2c7dcb108b01a28f42f..5bfaec9ec860fa32cc6b53c7d18b02bac01842af 100644 (file)
@@ -213,7 +213,7 @@ get_encrypted_passwd(const char *user)
 #ifndef VMS
 
 Bool
 #ifndef VMS
 
 Bool
-pwent_lock_init (int argc, char **argv, Bool verbose_p)
+pwent_priv_init (int argc, char **argv, Bool verbose_p)
 {
   char *u;
 
 {
   char *u;
 
@@ -234,6 +234,17 @@ pwent_lock_init (int argc, char **argv, Bool verbose_p)
 }
 
 
 }
 
 
+Bool
+pwent_lock_init (int argc, char **argv, Bool verbose_p)
+{
+  if (encrypted_user_passwd)
+    return True;
+  else
+    return False;
+}
+
+
+
 static Bool
 passwds_match_p (const char *cleartext, const char *ciphertext)
 {
 static Bool
 passwds_match_p (const char *cleartext, const char *ciphertext)
 {
index 25b3b04880ab2d41d7b2b279aa64b380fbc8931e..1847d1be1f7cddce077ccc22ffdfc35c0787a96c 100644 (file)
@@ -39,8 +39,10 @@ extern char *blurb(void);
 struct auth_methods {
   const char *name;
   Bool (*init) (int argc, char **argv, Bool verbose_p);
 struct auth_methods {
   const char *name;
   Bool (*init) (int argc, char **argv, Bool verbose_p);
+  Bool (*priv_init) (int argc, char **argv, Bool verbose_p);
   Bool (*valid_p) (const char *typed_passwd, Bool verbose_p);
   Bool initted_p;
   Bool (*valid_p) (const char *typed_passwd, Bool verbose_p);
   Bool initted_p;
+  Bool priv_initted_p;
 };
 
 
 };
 
 
@@ -53,6 +55,7 @@ extern Bool pam_lock_init (int argc, char **argv, Bool verbose_p);
 extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 #endif
 extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p);
 extern Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 #endif
 extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p);
+extern Bool pwent_priv_init (int argc, char **argv, Bool verbose_p);
 extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 
 
 extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 
 
@@ -63,15 +66,41 @@ extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
  */
 struct auth_methods methods[] = {
 # ifdef HAVE_KERBEROS
  */
 struct auth_methods methods[] = {
 # ifdef HAVE_KERBEROS
-  { "Kerberos",        kerberos_lock_init,     kerberos_passwd_valid_p, False },
+  { "Kerberos",         kerberos_lock_init, 0, kerberos_passwd_valid_p,
+                        False, False },
 # endif
 # ifdef HAVE_PAM
 # endif
 # ifdef HAVE_PAM
-  { "PAM",     pam_lock_init,          pam_passwd_valid_p,      False },
+  { "PAM",              pam_lock_init, 0, pam_passwd_valid_p, 
+                        False, False },
 # endif
 # endif
-  { "normal",  pwent_lock_init,        pwent_passwd_valid_p,    False }
+  { "normal",           pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p,
+                        False, False }
 };
 
 
 };
 
 
+Bool
+lock_priv_init (int argc, char **argv, Bool verbose_p)
+{
+  int i;
+  Bool any_ok = False;
+  for (i = 0; i < countof(methods); i++)
+    {
+      if (!methods[i].priv_init)
+        methods[i].priv_initted_p = True;
+      else
+        methods[i].priv_initted_p = methods[i].priv_init (argc, argv,
+                                                          verbose_p);
+
+      if (methods[i].priv_initted_p)
+        any_ok = True;
+      else if (verbose_p)
+        fprintf (stderr, "%s: initialization of %s passwords failed.\n",
+                 blurb(), methods[i].name);
+    }
+  return any_ok;
+}
+
+
 Bool
 lock_init (int argc, char **argv, Bool verbose_p)
 {
 Bool
 lock_init (int argc, char **argv, Bool verbose_p)
 {
@@ -79,6 +108,9 @@ lock_init (int argc, char **argv, Bool verbose_p)
   Bool any_ok = False;
   for (i = 0; i < countof(methods); i++)
     {
   Bool any_ok = False;
   for (i = 0; i < countof(methods); i++)
     {
+      if (!methods[i].priv_initted_p)  /* Bail if lock_priv_init failed. */
+        continue;
+
       methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
       if (methods[i].initted_p)
         any_ok = True;
       methods[i].initted_p = methods[i].init (argc, argv, verbose_p);
       if (methods[i].initted_p)
         any_ok = True;
index e006e5778050259893f6aa65eb0ff3df81d36248..e191314292ad6aaa599d17099f4082b74b8992f5 100644 (file)
@@ -800,7 +800,6 @@ load_init_file (saver_preferences *p)
    */
   if (p->passwd_timeout <= 0) p->passwd_timeout = 30000;        /* 30 secs */
   if (p->timeout < 10000) p->timeout = 10000;                   /* 10 secs */
    */
   if (p->passwd_timeout <= 0) p->passwd_timeout = 30000;        /* 30 secs */
   if (p->timeout < 10000) p->timeout = 10000;                   /* 10 secs */
-  if (p->cycle < 0) p->cycle = 0;
   if (p->cycle != 0 && p->cycle < 2000) p->cycle = 2000;        /*  2 secs */
   if (p->pointer_timeout <= 0) p->pointer_timeout = 5000;       /*  5 secs */
   if (p->notice_events_timeout <= 0)
   if (p->cycle != 0 && p->cycle < 2000) p->cycle = 2000;        /*  2 secs */
   if (p->pointer_timeout <= 0) p->pointer_timeout = 5000;       /*  5 secs */
   if (p->notice_events_timeout <= 0)
index 0e104c7ff6c85a7c51b325d660f904c0492cfb35..8b6187d9a1b6732cfb17ee13c895e3c570df625c 100644 (file)
@@ -739,7 +739,7 @@ select_visual_of_hack (saver_screen_info *ssi, const char *hack)
               (si->demoing_p
                ? "%s: warning, no \"%s\" visual for \"%s\".\n"
                : "%s: no \"%s\" visual; skipping \"%s\".\n"),
               (si->demoing_p
                ? "%s: warning, no \"%s\" visual for \"%s\".\n"
                : "%s: no \"%s\" visual; skipping \"%s\".\n"),
-              blurb(), (vis ? vis : "???"), in);
+              blurb(), (*vis ? vis : "???"), in);
     }
 
   return selected;
     }
 
   return selected;
index 909abe513d4817d4c351b8ffdcc81483ed98d26b..4945202a1f228690bb8b4abe2e6b0f6ffe0659bb 100644 (file)
@@ -98,11 +98,11 @@ grab_string(int status)
 {
   switch (status)
     {
 {
   switch (status)
     {
-    case GrabSuccess:     return "GrabSuccess";     break;
-    case AlreadyGrabbed:  return "AlreadyGrabbed";  break;
-    case GrabInvalidTime: return "GrabInvalidTime"; break;
-    case GrabNotViewable: return "GrabNotViewable"; break;
-    case GrabFrozen:      return "GrabFrozen";      break;
+    case GrabSuccess:     return "GrabSuccess";
+    case AlreadyGrabbed:  return "AlreadyGrabbed";
+    case GrabInvalidTime: return "GrabInvalidTime";
+    case GrabNotViewable: return "GrabNotViewable";
+    case GrabFrozen:      return "GrabFrozen";
     default:
       {
        static char foo[255];
     default:
       {
        static char foo[255];
index fb31471061251cfb5a91684d0c87e99bc4edeab5..88d09d29297620c6cb15c1bb427d8f8f538476ff 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "11-Apr-99 (3.09)" "X Version 11"
+.TH XScreenSaver 1 "27-Apr-99 (3.10)" "X Version 11"
 .SH NAME
 xscreensaver-command - control a running xscreensaver process
 .SH SYNOPSIS
 .SH NAME
 xscreensaver-command - control a running xscreensaver process
 .SH SYNOPSIS
index 86a470aa12f9dd15b53f82fae1a7c25e61d7c06b..01adfdcff2f24e1cd53d760f354524fc54247944 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "11-Apr-99 (3.09)" "X Version 11"
+.TH XScreenSaver 1 "27-Apr-99 (3.10)" "X Version 11"
 .SH NAME
 xscreensaver-demo - interactively control the background xscreensaver daemon
 .SH SYNOPSIS
 .SH NAME
 xscreensaver-demo - interactively control the background xscreensaver daemon
 .SH SYNOPSIS
index dda587a12f81c2da057bdff4c884b2760224a66e..4460c19df6125b9c358df07e4a3a179bb06f98e4 100644 (file)
@@ -419,12 +419,29 @@ set_version_string (saver_info *si, int *argc, char **argv)
 static void
 privileged_initialization (saver_info *si, int *argc, char **argv)
 {
 static void
 privileged_initialization (saver_info *si, int *argc, char **argv)
 {
+#ifndef NO_LOCKING
+  /* before hack_uid() for proper permissions */
+  lock_priv_init (*argc, argv, si->prefs.verbose_p);
+#endif /* NO_LOCKING */
+
+#ifndef NO_SETUID
+  hack_uid (si);
+#endif /* NO_SETUID */
+}
+
+
+/* Figure out what locking mechanisms are supported.
+ */
+static void
+lock_initialization (saver_info *si, int *argc, char **argv)
+{
 #ifdef NO_LOCKING
   si->locking_disabled_p = True;
   si->nolock_reason = "not compiled with locking support";
 #else /* !NO_LOCKING */
   si->locking_disabled_p = False;
 #ifdef NO_LOCKING
   si->locking_disabled_p = True;
   si->nolock_reason = "not compiled with locking support";
 #else /* !NO_LOCKING */
   si->locking_disabled_p = False;
-  /* before hack_uid() for proper permissions */
+
+  /* Finish initializing locking, now that we're out of privileged code. */
   if (! lock_init (*argc, argv, si->prefs.verbose_p))
     {
       si->locking_disabled_p = True;
   if (! lock_init (*argc, argv, si->prefs.verbose_p))
     {
       si->locking_disabled_p = True;
@@ -894,7 +911,7 @@ main_loop (saver_info *si)
 
           fprintf (stderr,
                   "%s: unable to grab keyboard or mouse!  Blanking aborted.\n",
 
           fprintf (stderr,
                   "%s: unable to grab keyboard or mouse!  Blanking aborted.\n",
-                   blurb(), timestring ());
+                   blurb());
           continue;
         }
 
           continue;
         }
 
@@ -1015,6 +1032,7 @@ main (int argc, char **argv)
       exit (1);
 
   load_init_file (p);
       exit (1);
 
   load_init_file (p);
+  lock_initialization (si, &argc, argv);
 
   if (p->xsync_p) XSynchronize (si->dpy, True);
   blurb_timestamp_p = p->timestamp_p;  /* kludge */
 
   if (p->xsync_p) XSynchronize (si->dpy, True);
   blurb_timestamp_p = p->timestamp_p;  /* kludge */
index 7860dfe4f41f8f15484d28e4901ebfc3ce20e352..7a61d166b2d306bf69e27af82ae6f31ba3f7942d 100644 (file)
@@ -279,6 +279,7 @@ extern void unblank_screen (saver_info *si);
 
 #ifndef NO_LOCKING
 extern Bool unlock_p (saver_info *si);
 
 #ifndef NO_LOCKING
 extern Bool unlock_p (saver_info *si);
+extern Bool lock_priv_init (int argc, char **argv, Bool verbose_p);
 extern Bool lock_init (int argc, char **argv, Bool verbose_p);
 extern Bool passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 
 extern Bool lock_init (int argc, char **argv, Bool verbose_p);
 extern Bool passwd_valid_p (const char *typed_passwd, Bool verbose_p);
 
index 445075874bb1e4ecbb52c70c55f4ebdb9219b51b..9c468f75728f6c97e7a1edace6c2802fb264f7da 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "11-Apr-99 (3.09)" "X Version 11"
+.TH XScreenSaver 1 "27-Apr-99 (3.10)" "X Version 11"
 .SH NAME
 xscreensaver - graphics hack and screen locker, launched when the user is idle
 .SH SYNOPSIS
 .SH NAME
 xscreensaver - graphics hack and screen locker, launched when the user is idle
 .SH SYNOPSIS
index e9ce414e314cf6ec7671c61146e29c856f8fcc7d..fb393afa5addd44f3cd42dc18975a962b287f1d4 100644 (file)
@@ -82,7 +82,8 @@ SRCS          = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
                  cynosure.c moire2.c flow.c epicycle.c interference.c \
                  truchet.c bsod.c crystal.c discrete.c distort.c kumppa.c \
                  sonar.c demon.c loop.c t3d.c penetrate.c deluxe.c compass.c \
                  cynosure.c moire2.c flow.c epicycle.c interference.c \
                  truchet.c bsod.c crystal.c discrete.c distort.c kumppa.c \
                  sonar.c demon.c loop.c t3d.c penetrate.c deluxe.c compass.c \
-                 squiral.c xflame.c wander.c spotlight.c critical.c
+                 squiral.c xflame.c wander.c spotlight.c critical.c \
+                 phosphor.c xmatrix.c
 
 OBJS           = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  bubbles-default.o decayscreen.o deco.o drift.o flag.o \
 
 OBJS           = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  bubbles-default.o decayscreen.o deco.o drift.o flag.o \
@@ -98,7 +99,8 @@ OBJS          = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  cynosure.o moire2.o flow.o epicycle.o interference.o \
                  truchet.o bsod.o crystal.o discrete.o distort.o kumppa.o \
                  sonar.o demon.o loop.o t3d.o penetrate.o deluxe.o compass.o \
                  cynosure.o moire2.o flow.o epicycle.o interference.o \
                  truchet.o bsod.o crystal.o discrete.o distort.o kumppa.o \
                  sonar.o demon.o loop.o t3d.o penetrate.o deluxe.o compass.o \
-                 squiral.o xflame.o wander.o spotlight.o critical.o
+                 squiral.o xflame.o wander.o spotlight.o critical.o \
+                 phosphor.o xmatrix.o
 
 EXES           = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
 
 EXES           = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
@@ -110,7 +112,7 @@ EXES                = attraction blitspin bouboule braid bubbles decayscreen deco \
                  ant xjack xlyap jigsaw cynosure moire2 flow epicycle \
                  interference truchet bsod crystal discrete distort kumppa \
                  sonar demon loop t3d penetrate deluxe compass squiral \
                  ant xjack xlyap jigsaw cynosure moire2 flow epicycle \
                  interference truchet bsod crystal discrete distort kumppa \
                  sonar demon loop t3d penetrate deluxe compass squiral \
-                 xflame wander spotlight critical
+                 xflame wander spotlight critical phosphor xmatrix
 
 HACK_OBJS_1    = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
 
 HACK_OBJS_1    = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
@@ -492,6 +494,12 @@ spotlight: spotlight.o     $(HACK_OBJS) $(GRAB)
 critical:      critical.o      $(HACK_OBJS) $(COL) $(ERASE)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS)
 
 critical:      critical.o      $(HACK_OBJS) $(COL) $(ERASE)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS)
 
+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)
+
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
@@ -1594,4 +1602,24 @@ critical.o: $(UTILS_SRC)/colors.h
 critical.o: $(UTILS_SRC)/grabscreen.h
 critical.o: $(UTILS_SRC)/visual.h
 critical.o: $(UTILS_SRC)/erase.h
 critical.o: $(UTILS_SRC)/grabscreen.h
 critical.o: $(UTILS_SRC)/visual.h
 critical.o: $(UTILS_SRC)/erase.h
+phosphor.o: $(srcdir)/screenhack.h
+phosphor.o: ../config.h
+phosphor.o: $(UTILS_SRC)/yarandom.h
+phosphor.o: $(UTILS_SRC)/usleep.h
+phosphor.o: $(UTILS_SRC)/resources.h
+phosphor.o: $(UTILS_SRC)/hsv.h
+phosphor.o: $(UTILS_SRC)/colors.h
+phosphor.o: $(UTILS_SRC)/grabscreen.h
+phosphor.o: $(UTILS_SRC)/visual.h
+xmatrix.o: $(srcdir)/screenhack.h
+xmatrix.o: ../config.h
+xmatrix.o: $(UTILS_SRC)/yarandom.h
+xmatrix.o: $(UTILS_SRC)/usleep.h
+xmatrix.o: $(UTILS_SRC)/resources.h
+xmatrix.o: $(UTILS_SRC)/hsv.h
+xmatrix.o: $(UTILS_SRC)/colors.h
+xmatrix.o: $(UTILS_SRC)/grabscreen.h
+xmatrix.o: $(UTILS_SRC)/visual.h
+xmatrix.o: $(srcdir)/images/matrix.xpm
+xmatrix.o: $(srcdir)/images/matrix.xbm
 
 
index 676d5e25e30478c9b45b9a7ffab065365e379758..13adf73932e3e1d1a7b8950bce59cbfa59011e53 100644 (file)
@@ -54,6 +54,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]) PEDAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENETRATE.C
 $ 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]) PEDAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENETRATE.C
 $ 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]) PHOSPHOR.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
 $ 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
@@ -82,6 +83,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]) XJACK.C
 $ 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]) XJACK.C
 $ 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]) XROGER-HACK.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,XLOCKMORE)/INCL=([],[-],[-.UTILS])/OBJ=SCREENHACK-XLOCK.OBJ SCREENHACK.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XROGER-HACK.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,XLOCKMORE)/INCL=([],[-],[-.UTILS])/OBJ=SCREENHACK-XLOCK.OBJ SCREENHACK.C
index 676d5e25e30478c9b45b9a7ffab065365e379758..13adf73932e3e1d1a7b8950bce59cbfa59011e53 100644 (file)
@@ -54,6 +54,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]) PEDAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENETRATE.C
 $ 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]) PEDAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) PENETRATE.C
 $ 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]) PHOSPHOR.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
 $ 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
@@ -82,6 +83,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]) XJACK.C
 $ 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]) XJACK.C
 $ 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]) XROGER-HACK.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,XLOCKMORE)/INCL=([],[-],[-.UTILS])/OBJ=SCREENHACK-XLOCK.OBJ SCREENHACK.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) XROGER-HACK.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,XLOCKMORE)/INCL=([],[-],[-.UTILS])/OBJ=SCREENHACK-XLOCK.OBJ SCREENHACK.C
index ae3df0b13bd8a986a0027afa004ab4369ec2807e..17abf8f4c398b9b6e95e7b3003bec4a0a77ed120 100644 (file)
@@ -308,12 +308,11 @@ screenhack (Display *dpy, Window window)
                 x2 * cell_size + cell_size/2,
                 y2 * cell_size + cell_size/2);
 
                 x2 * cell_size + cell_size/2,
                 y2 * cell_size + cell_size/2);
 
-      /* Flush changes to display, and discard any pending input --
-        we'll never look at it anyhow, and it saves it filling up
-        memory. */
-      XSync (dpy, True); 
+      XSync (dpy, False); 
+      screenhack_handle_events (dpy);
 
 
-      usleep (delay_usecs);
+      if (delay_usecs)
+        usleep (delay_usecs);
     }
 
     i_restart = (i_restart + 1) % n_restart;
     }
 
     i_restart = (i_restart + 1) % n_restart;
index 16b8bd68e6b661a5d09e440e08b6a2a46de60dab..cd0820023cb153ee4248f19676f85024ae864c92 100644 (file)
@@ -64,17 +64,17 @@ SRCS                = atlantis.c b_draw.c b_lockglue.c b_sphere.c bubble3d.c \
                  morph3d.c pipeobjs.c pipes.c rubik.c s1_1.c s1_2.c s1_3.c \
                  s1_4.c s1_5.c s1_6.c s1_b.c shark.c sproingies.c \
                  sproingiewrap.c stairs.c superquadrics.c swim.c whale.c \
                  morph3d.c pipeobjs.c pipes.c rubik.c s1_1.c s1_2.c s1_3.c \
                  s1_4.c s1_5.c s1_6.c s1_b.c shark.c sproingies.c \
                  sproingiewrap.c stairs.c superquadrics.c swim.c whale.c \
-                 xlock-gl.c xpm-ximage.c glplanet.c
+                 xlock-gl.c xpm-ximage.c glplanet.c pulsar.c
 
 OBJS           = atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
                  buildlwo.o cage.o dolphin.o gears.o lament.o moebius.o \
                  morph3d.o pipeobjs.o pipes.o rubik.o s1_1.o s1_2.o s1_3.o \
                  s1_4.o s1_5.o s1_6.o s1_b.o shark.o sproingies.o \
                  sproingiewrap.o stairs.o superquadrics.o swim.o whale.o \
 
 OBJS           = atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
                  buildlwo.o cage.o dolphin.o gears.o lament.o moebius.o \
                  morph3d.o pipeobjs.o pipes.o rubik.o s1_1.o s1_2.o s1_3.o \
                  s1_4.o s1_5.o s1_6.o s1_b.o shark.o sproingies.o \
                  sproingiewrap.o stairs.o superquadrics.o swim.o whale.o \
-                 xlock-gl.o xpm-ximage.o glplanet.o
+                 xlock-gl.o xpm-ximage.o glplanet.o pulsar.o
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
-                 morph3d rubik atlantis lament bubble3d glplanet
+                 morph3d rubik atlantis lament bubble3d glplanet pulsar
 EXES           = @GL_EXES@
 
 HACK_OBJS      = screenhack-gl.o xlock-gl.o $(HACK_BIN)/xlockmore.o \
 EXES           = @GL_EXES@
 
 HACK_OBJS      = screenhack-gl.o xlock-gl.o $(HACK_BIN)/xlockmore.o \
@@ -249,6 +249,9 @@ bubble3d:   bubble3d.o      $(HACK_OBJS) $(B3D)
 glplanet:      glplanet.o      $(HACK_OBJS) xpm-ximage.o
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) xpm-ximage.o $(XPM_LIBS)
 
 glplanet:      glplanet.o      $(HACK_OBJS) xpm-ximage.o
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) xpm-ximage.o $(XPM_LIBS)
 
+pulsar:                pulsar.o                $(HACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(HACK_LIBS)
+
 
 ##############################################################################
 #
 
 ##############################################################################
 #
@@ -505,4 +508,16 @@ glplanet.o: $(UTILS_SRC)/visual.h
 glplanet.o: $(UTILS_SRC)/xshm.h
 glplanet.o: $(HACK_SRC)/images/earth.xbm
 glplanet.o: $(srcdir)/xpm-ximage.h
 glplanet.o: $(UTILS_SRC)/xshm.h
 glplanet.o: $(HACK_SRC)/images/earth.xbm
 glplanet.o: $(srcdir)/xpm-ximage.h
+pulsar.o: $(HACK_SRC)/xlockmore.h
+pulsar.o: ../../config.h
+pulsar.o: $(HACK_SRC)/xlockmoreI.h
+pulsar.o: $(HACK_SRC)/screenhack.h
+pulsar.o: $(UTILS_SRC)/yarandom.h
+pulsar.o: $(UTILS_SRC)/usleep.h
+pulsar.o: $(UTILS_SRC)/resources.h
+pulsar.o: $(UTILS_SRC)/hsv.h
+pulsar.o: $(UTILS_SRC)/colors.h
+pulsar.o: $(UTILS_SRC)/grabscreen.h
+pulsar.o: $(UTILS_SRC)/visual.h
+pulsar.o: $(UTILS_SRC)/xshm.h
 
 
index 7c71fc7d135c75e015801c462e70df6e16851c29..39ae21bb05cb8e23f709b83e00250790afc6655a 100644 (file)
@@ -323,7 +323,7 @@ setup_file_texture (ModeInfo *mi, char *filename)
                exit (1);
          }
 
                exit (1);
          }
 
-       setup_xbm_texture (data, width, height, &gp->fg, &gp->bg);
+       setup_xbm_texture ((char *) data, width, height, &gp->fg, &gp->bg);
   }
 #else  /* !XMU */
 
   }
 #else  /* !XMU */
 
diff --git a/hacks/glx/pulsar.c b/hacks/glx/pulsar.c
new file mode 100644 (file)
index 0000000..b7a8e43
--- /dev/null
@@ -0,0 +1,783 @@
+/* -*- Mode: C; tab-width: 4 -*- */
+/* pulsar --- pulsar module for xscreensaver */
+/*-
+ * 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:
+ * 4-Apr-1999:  dek@cgl.ucsf.edu  Created module "pulsar"
+ *
+ */
+
+#include <math.h> 
+#include <stdio.h>
+#include <stdlib.h>
+
+/*-
+ * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
+ * otherwise caddr_t is not defined correctly
+ */
+
+#include <X11/Intrinsic.h>
+
+#ifdef STANDALONE
+# define PROGCLASS                                             "Screensaver"
+# define HACK_INIT                                             init_screensaver
+# define HACK_DRAW                                             draw_screensaver
+# define screensaver_opts                              xlockmore_opts
+#define        DEFAULTS                        "*light:                        False   \n" \
+                                        "*wire:                                False   \n" \
+                                        "*blend:                       True    \n" \
+                                        "*fog:                         False   \n" \
+                                        "*antialias:           False   \n" \
+                                        "*texture:                     False   \n" \
+                                        "*texture_quality:     False   \n" \
+                                        "*mipmap:                      False   \n" \
+                                        "*fps:                         False   \n" \
+                                        "*doDepth:                     False   \n" \
+
+# include "xlockmore.h"                                /* from the xscreensaver distribution */
+#else /* !STANDALONE */
+# include "xlock.h"                                    /* from the xlockmore distribution */
+#endif /* !STANDALONE */
+
+#ifdef USE_GL /* whole file */
+
+#ifdef HAVE_XPM
+# include <X11/xpm.h>
+# ifndef PIXEL_ALREADY_TYPEDEFED
+# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */
+# endif
+#endif
+
+#ifdef HAVE_XMU
+# ifndef VMS
+#  include <X11/Xmu/Drawing.h>
+#else  /* VMS */
+#  include <Xmu/Drawing.h>
+# endif /* VMS */
+#endif
+
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+
+/* Functions for loading and storing textures */
+
+#define checkImageWidth 64
+#define checkImageHeight 64
+
+char *Textures[] = {
+  "./test.ppm4",
+};
+
+typedef struct {
+    int sizeX, sizeY;
+    GLubyte *data;
+} PPMImage;
+
+/* Functions for handling the frames per second timer */
+#include "GL/glx.h"
+
+#ifndef SAMPLE_FRAMES
+#define SAMPLE_FRAMES 10
+#endif
+
+static GLint base;
+static int FrameCounter = 0;
+static double oldtime=-1., newtime=-1.;
+static char FPSstring[1024]="FPS: NONE"; 
+
+static float x_pos=0, y_pos=0;
+
+#define FONT "-*-courier-medium-r-normal-*-240-*"
+
+
+
+#define NUM_TRIANGLES 5
+static float scale_x=1, scale_y=1, scale_z=1;
+static int frame = 0;
+struct triangle
+{
+  GLfloat tx, ty, tz;
+  GLfloat rx, ry, rz;
+
+  GLfloat dtx, dty, dtz;
+  GLfloat drx, dry, drz;
+
+};
+struct triangle triangles[NUM_TRIANGLES];
+GLint tri_list;
+
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#define WIDTH 800
+#define HEIGHT 600
+
+int global_width=WIDTH, global_height=HEIGHT;
+
+
+static XrmOptionDescRec opts[] = {
+  {"-light",   ".pulsar.light",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+light",   ".pulsar.light",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-wire",   ".pulsar.wire",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+wire",   ".pulsar.wire",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-blend",   ".pulsar.blend",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+blend",   ".pulsar.blend",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-fog",   ".pulsar.fog",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+fog",   ".pulsar.fog",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-antialias",   ".pulsar.antialias",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+antialias",   ".pulsar.antialias",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-texture",   ".pulsar.texture",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+texture",   ".pulsar.texture",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-texture_quality",   ".pulsar.texture_quality",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+texture_quality",   ".pulsar.texture_quality",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-mipmap",   ".pulsar.mipmap",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+mipmap",   ".pulsar.mipmap",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-fps",   ".pulsar.fps",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+fps",   ".pulsar.fps",   XrmoptionNoArg, (caddr_t) "false" },
+  {"-do_depth",   ".pulsar.doDepth",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+do_depth",   ".pulsar.doDepth",   XrmoptionNoArg, (caddr_t) "false" },
+};
+
+#define DEF_LIGHT  "False"
+#define DEF_WIRE   "False"
+#define DEF_BLEND   "True"
+#define DEF_FOG   "False"
+#define DEF_ANTIALIAS   "False"
+#define DEF_TEXTURE   "False"
+#define DEF_TEXTURE_QUALITY   "False"
+#define DEF_MIPMAP   "False"
+#define DEF_FPS   "False"
+#define DEF_DO_DEPTH   "False"
+
+static int do_light;
+static int do_wire;
+static int do_blend;
+static int do_fog;
+static int do_antialias;
+static int do_texture;
+static int do_texture_quality;
+static int do_mipmap;
+static int do_fps;
+static int do_depth;
+
+static argtype vars[] = {
+  {(caddr_t *) &do_light,    "light",   "Light",   DEF_LIGHT,   t_Bool},
+  {(caddr_t *) &do_wire,    "wire",   "Wire",   DEF_WIRE,   t_Bool},
+  {(caddr_t *) &do_blend,    "blend",   "Blend",   DEF_BLEND,   t_Bool},
+  {(caddr_t *) &do_fog,    "fog",   "Fog",   DEF_FOG,   t_Bool},
+  {(caddr_t *) &do_antialias,    "antialias",   "Antialias",   DEF_ANTIALIAS,   t_Bool},
+  {(caddr_t *) &do_texture,    "texture",   "Texture",   DEF_TEXTURE,   t_Bool},
+  {(caddr_t *) &do_texture_quality,    "texture_quality",   "Texture_quality",   DEF_TEXTURE_QUALITY,   t_Bool},
+  {(caddr_t *) &do_mipmap,    "mipmap",   "Mipmap",   DEF_MIPMAP,   t_Bool},
+  {(caddr_t *) &do_fps,    "fps",   "fps",   DEF_FPS,   t_Bool},
+  {(caddr_t *) &do_depth,    "doDepth",   "DoDepth",   DEF_DO_DEPTH,   t_Bool},
+};
+
+
+ModeSpecOpt screensaver_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+#ifdef USE_MODULES
+ModStruct   screensaver_description =
+{"screensaver", "init_screensaver", "draw_screensaver", "release_screensaver",
+ "draw_screensaver", "init_screensaver", NULL, &screensaver_opts,
+ 1000, 1, 2, 1, 4, 1.0, "",
+ "OpenGL screensaver", 0, NULL};
+#endif
+
+
+/* structure for holding the screensaver data */
+typedef struct {
+  int screen_width, screen_height;
+  GLXContext *glx_context;
+  Window window;
+  XColor fg, bg;
+} screensaverstruct;
+
+static screensaverstruct *Screensaver = NULL;
+
+
+void FPS_Setup(void)
+{
+  Display *Dpy;
+  XFontStruct *fontInfo;
+  Font id;
+  int first=0, last=255;
+
+  Dpy = XOpenDisplay(NULL);
+  fontInfo = XLoadQueryFont(Dpy, FONT);
+  if (fontInfo == NULL)
+    {
+      fprintf(stderr, "Failed to load font %s\n", FONT);
+      exit(1);
+    }
+
+  id = fontInfo->fid;
+  first = fontInfo->min_char_or_byte2;
+  last = fontInfo->max_char_or_byte2;
+  
+  base = glGenLists((GLuint) last+1);
+  if (base == 0) {
+    fprintf (stderr, "out of display lists\n");
+    exit(1);
+  }
+  glXUseXFont(id, first, last-first+1, base+first);
+
+}
+
+void PrintString(float x, float y, char *string)
+{
+  int len, i;
+
+  /* save the current state */
+  /* note: could be expensive! */
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluOrtho2D(0, global_width, 0, global_height);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+
+  /* disable lighting and texturing when drawing bitmaps! */
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_LIGHTING);
+  glDisable(GL_BLEND);
+
+  /* draw a black background */
+
+  /* draw the text */
+  glColor3f(1,1,1);
+  glRasterPos2f( x, y);
+  len = (int) strlen(string);
+  for (i = 0; i < len; i++) {
+    glCallList(base+string[i]);
+  }
+
+  /* clean up after our state changes */
+  glPopAttrib();
+}
+
+double gettime(void)
+{
+  struct timeval now;
+#ifdef GETTIMEOFDAY_TWO_ARGS
+  struct timezone tzp;
+  gettimeofday(&now, &tzp);
+#else
+  gettimeofday(&now);
+#endif
+  return (double) (now.tv_sec + (((double) now.tv_usec) * 0.000001));
+}
+
+void DoFPS(void)
+{
+  /* every SAMPLE_FRAMES frames, get the time and use it to get the 
+     frames per second */
+  if (!(FrameCounter % SAMPLE_FRAMES)) {
+    oldtime = newtime;
+    newtime = gettime();
+    sprintf(FPSstring, "FPS: %.02f", SAMPLE_FRAMES/(newtime-oldtime));
+  }
+
+  PrintString(x_pos,y_pos,FPSstring);
+
+  FrameCounter++;
+}
+
+GLubyte *Generate_Image(int *width, int *height, int *format)
+{
+  GLubyte *result;
+  int i, j, c;
+  int counter=0;
+
+  *width = checkImageWidth;
+  *height = checkImageHeight;
+  result = (GLubyte *)malloc(4 * *width * *height);
+
+  counter = 0;
+  for (i = 0; i < checkImageWidth; i++) {
+    for (j = 0; j < checkImageHeight; j++) {
+      c = (((((i&0x8)==0))^(((j&0x8))==0)))*255;
+      result[counter++] = (GLubyte) c;
+      result[counter++] = (GLubyte) c;
+      result[counter++] = (GLubyte) c;
+      result[counter++] = (GLubyte) 255;
+    }
+  }
+
+  *format = GL_RGBA;
+  return result;
+}
+
+
+
+#ifdef TIFF
+#include <tiffio>
+/* Load a TIFF texture: requires libtiff */
+uint32 *LoadTIFF(char *filename, int *width, int *height, int *format)
+{
+  TIFF *tif;
+  char emsg[1024];
+  uint32 *raster;
+  TIFFRGBAImage img;
+  tsize_t npixels;
+
+  tif = TIFFOpen(filename, "r");
+  if (tif == NULL) {
+    fprintf(stderr, "Problem showing %s\n", filename);
+    return Generate_Image(&width, &height, &format);
+  }
+  if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
+    npixels = (tsize_t) (img.width * img.height);
+    raster = (uint32 *) _TIFFmalloc(npixels * (tsize_t) sizeof(uint32));
+    if (raster != NULL) {
+      if (TIFFRGBAImageGet(&img, raster, img.width, img.height) == 0) {
+        TIFFError(filename, emsg);
+       return Generate_Image(&width, &height, &format);
+      }
+    }
+    TIFFRGBAImageEnd(&img);
+  } else {
+    TIFFError(filename, emsg);
+    return Generate_Image(&width, &height, &format);
+  }
+
+  *width = img.width;
+  *height = img.height;
+  *format = GL_RGBA;
+
+  TIFFClose(tif);
+  return raster;
+}
+#endif
+
+
+/* Load a modified version of PPM format with an extra byte for alpha */
+GLubyte *LoadPPM4(const char *filename, int *width, int *height, int *format)
+{
+  char buff[1024];
+  PPMImage *result;
+  FILE *fp;
+  int maxval;
+
+  fp = fopen(filename, "rb");
+  if (!fp)
+    {
+      fprintf(stderr, "Unable to open file '%s'\n", filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  if (!fgets(buff, sizeof(buff), fp))
+    {
+      perror(filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  if (buff[0] != '6' || buff[1] != 'P')
+    {
+      fprintf(stderr, "Invalid image format (must be `6P')\n");
+      return  Generate_Image(width, height, format);
+    }
+
+  result = malloc(sizeof(PPMImage));
+  if (!result)
+    {
+      fprintf(stderr, "Unable to allocate memory\n");
+      return  Generate_Image(width, height, format);
+    }
+
+  do
+    {
+      fgets(buff, sizeof(buff), fp);
+    }
+  while (buff[0] == '#');
+    
+  if (sscanf(buff, "%d %d", &result->sizeX, &result->sizeY) != 2)
+    {
+      fprintf(stderr, "Error loading image `%s'\n", filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  if (fscanf(fp, "%d", &maxval) != 1)
+    {
+      fprintf(stderr, "Error loading image `%s'\n", filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  while (fgetc(fp) != '\n')
+    ;
+
+  result->data = (GLubyte *)malloc(4 * result->sizeX * result->sizeY);
+  if (!result)
+    {
+      fprintf(stderr, "Unable to allocate memory\n");
+      exit(1);
+    }
+
+  if (fread(result->data, 4 * result->sizeX, result->sizeY, fp) != result->sizeY)
+    {
+      fprintf(stderr, "Error loading image `%s'\n", filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  fclose(fp);
+
+  *width = result->sizeX;
+  *height = result->sizeY;
+  *format = GL_RGBA;
+  return result->data;
+}
+
+/* Load a plain PPM image */
+GLubyte *LoadPPM(const char *filename, int *width, int *height, int *format)
+{
+  char buff[1024];
+  PPMImage *result;
+  FILE *fp;
+  int maxval;
+
+  fp = fopen(filename, "rb");
+  if (!fp)
+    {
+      fprintf(stderr, "Unable to open file '%s'\n", filename);
+      return  Generate_Image(width, height, format);
+      exit(1);
+    }
+  if (!fgets(buff, sizeof(buff), fp))
+    {
+      perror(filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  if (buff[0] != 'P' || buff[1] != '6')
+    {
+      fprintf(stderr, "Invalid image format (must be `P6')\n");
+      return  Generate_Image(width, height, format);
+    }
+
+  result = malloc(sizeof(PPMImage));
+  if (!result)
+    {
+      fprintf(stderr, "Unable to allocate memory\n");
+      return  Generate_Image(width, height, format);
+    }
+
+  do
+    {
+      fgets(buff, sizeof(buff), fp);
+    }
+  while (buff[0] == '#');
+    
+  if (sscanf(buff, "%d %d", &result->sizeX, &result->sizeY) != 2)
+    {
+      fprintf(stderr, "Error loading image `%s'\n", filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  if (fscanf(fp, "%d", &maxval) != 1)
+    {
+      fprintf(stderr, "Error loading image `%s'\n", filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  while (fgetc(fp) != '\n')
+    ;
+
+  result->data = (GLubyte *)malloc(3 * result->sizeX * result->sizeY);
+  if (!result)
+    {
+      fprintf(stderr, "Unable to allocate memory\n");
+      return  Generate_Image(width, height, format);
+    }
+
+  if (fread(result->data, 3 * result->sizeX, result->sizeY, fp) != result->sizeY)
+    {
+      fprintf(stderr, "Error loading image `%s'\n", filename);
+      return  Generate_Image(width, height, format);
+    }
+
+  fclose(fp);
+
+  *width = result->sizeX;
+  *height = result->sizeY;
+  *format = GL_RGB;
+  return result->data;
+}
+
+/* Create a texture in OpenGL.  First an image is loaded 
+   and stored in a raster buffer, then it's  */
+void Create_Texture(char *filename)
+{
+  int height, width;
+  GLubyte *image;
+  GLint a;
+  int format;
+
+  fprintf(stdout, "Loading texture '%s'\n", filename);
+
+  if ( !strncmp((filename+strlen(filename)-3), "ppm", 3))
+    image = LoadPPM(filename, &width, &height, &format);
+  else if ( !strncmp((filename+strlen(filename)-4), "ppm4", 4))
+    image = LoadPPM4(filename, &width, &height, &format);
+#ifdef TIFF
+  else if ( !strncmp((filename+strlen(filename)-4), "tiff", 4))
+    image = (GLubyte *)LoadTIFF(filename, &width, &height, &format);
+#endif
+  else {
+    fprintf(stderr, "Unknown file format extension: '%s'\n", filename);
+    image = Generate_Image(&width, &height, &format);
+  }
+
+  /* GL_MODULATE or GL_DECAL depending on what you want */
+  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);
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+  if (do_texture_quality) {
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+  }
+  else {
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+  }
+
+  if (do_mipmap)
+       a=gluBuild2DMipmaps(GL_TEXTURE_2D, format, width, height, format, GL_UNSIGNED_BYTE, image);
+  else 
+       glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
+                                format, GL_UNSIGNED_BYTE, image);
+
+  free(image);
+}
+
+void resetProjection(void) {
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glFrustum(-1, 1, -1, 1, 1, 100); 
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+}
+
+
+void GenerateTriangle(void)
+{
+  int i;
+
+  tri_list = glGenLists(1);
+  glNewList(tri_list,GL_COMPILE);
+/*    glBegin(GL_TRIANGLES); */
+  glBegin(GL_QUADS);
+  glColor4f(1,0,0,.4); glNormal3f(0,0,1);  glTexCoord2f(0,0); glVertex2f(-1, -1);
+  glColor4f(0,1,0,.4); glNormal3f(0,0,1);  glTexCoord2f(0,1); glVertex2f(-1,  1);
+  glColor4f(0,0,1,.4); glNormal3f(0,0,1);  glTexCoord2f(1,1); glVertex2f( 1,  1);
+  glColor4f(1,1,1,1); glNormal3f(0,0,1);  glTexCoord2f(1,0); glVertex2f( 1,  -1);
+  glEnd();
+  glEndList();
+
+  for (i=0; i < NUM_TRIANGLES; i++)
+    {
+      triangles[i].rx = 0.;
+      triangles[i].ry = 0.;
+      triangles[i].rz = 0.;
+      triangles[i].tx = 0.;
+      triangles[i].ty = 0.;
+      triangles[i].tz = -10;
+
+      triangles[i].drx = drand48() * 5.;
+      triangles[i].dry = drand48() * 5.;
+      triangles[i].drz = 0;
+    }
+}
+
+void initializeGL(GLsizei width, GLsizei height) 
+{
+  GLfloat fogColor[4] = { 0.1, 0.1, 0.1, 0.1 };
+
+  global_width=width;
+  global_height=height;
+
+  glViewport( 0, 0, width, height ); 
+  resetProjection();
+
+  if (do_depth)
+       glEnable(GL_DEPTH_TEST);
+
+  if (do_fps)
+       FPS_Setup();
+
+  if (do_antialias) {
+       do_blend = 1;
+       glEnable(GL_LINE_SMOOTH);
+  }
+
+  if (do_blend) {
+       glEnable(GL_BLEND);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  }
+
+
+  if (do_light) {
+       glShadeModel(GL_SMOOTH);
+       glEnable(GL_COLOR_MATERIAL);
+       glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+  }
+
+  if (do_wire)
+       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+  else 
+       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+  if (do_fog) {
+       glEnable(GL_FOG);
+       glFogi(GL_FOG_MODE, GL_LINEAR);
+       glFogfv(GL_FOG_COLOR, fogColor);
+       glFogf(GL_FOG_DENSITY, 0.35);
+/*     glHint(GL_FOG_HINT, GL_FASTEST); */
+       glFogf(GL_FOG_START, 50.0);
+       glFogf(GL_FOG_END, 100.0);
+  }
+       
+
+  if (do_texture)
+       {
+         Create_Texture(Textures[0]); 
+       }
+
+  GenerateTriangle();
+}
+void drawTriangles(void) {
+  int i;
+  for (i=0; i < NUM_TRIANGLES; i++)
+    {
+      glPushMatrix();
+      glTranslatef(triangles[i].tx,0,0);
+      glTranslatef(0,triangles[i].ty,0);
+      glTranslatef(0,0,triangles[i].tz);
+      glRotatef(triangles[i].rx, 1,0,0);
+      glRotatef(triangles[i].ry, 0,1,0);
+      glRotatef(triangles[i].rz, 0,0,1);
+      glCallList(tri_list);
+      glPopMatrix();
+
+      triangles[i].rx += triangles[i].drx;
+      triangles[i].ry += triangles[i].dry;
+      triangles[i].rz += triangles[i].drz;
+
+    }
+}
+
+GLvoid drawScene(GLvoid) 
+{
+
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  /* we have to do this here because the FPS meter turns these 3 features off!! */
+  {
+       if (do_light) {
+         glEnable(GL_LIGHTING);
+         glEnable(GL_LIGHT0);
+       }
+       
+       if (do_texture) {
+         glEnable(GL_TEXTURE_2D);
+       }
+       
+       if (do_blend) {
+         glEnable(GL_BLEND);
+         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       }
+  }
+
+  resetProjection();
+  glScalef(scale_x, scale_y, scale_z);
+  drawTriangles();
+  
+  scale_x = cos(frame/360.)*10.;
+  scale_y = sin(frame/360.)*10.;
+  scale_z = 1;
+
+  frame++;
+  DoFPS();
+}
+
+
+void draw_screensaver(ModeInfo * mi)
+{
+  screensaverstruct *gp = &Screensaver[MI_SCREEN(mi)];
+  Display    *display = MI_DISPLAY(mi);
+  Window      window = MI_WINDOW(mi);
+
+  if (!gp->glx_context)
+       return;
+
+  glXMakeCurrent(display, window, *(gp->glx_context));
+  drawScene();
+  glXSwapBuffers(display, window);
+}
+
+/* Standard reshape function */
+static void
+reshape(int width, int height)
+{
+  glViewport( 0, 0, global_width, global_height );
+  resetProjection();
+}
+
+void
+init_screensaver(ModeInfo * mi)
+{
+  int screen = MI_SCREEN(mi);
+
+  screensaverstruct *gp;
+
+  if (Screensaver == NULL) {
+       if ((Screensaver = (screensaverstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (screensaverstruct))) == NULL)
+         return;
+  }
+  gp = &Screensaver[screen];
+
+  gp->window = MI_WINDOW(mi);
+  if ((gp->glx_context = init_GL(mi)) != NULL) {
+       reshape(MI_WIDTH(mi), MI_HEIGHT(mi));
+       initializeGL(MI_WIDTH(mi), MI_HEIGHT(mi));
+  } else {
+       MI_CLEARWINDOW(mi);
+  }
+}
+
+
+/* all sorts of nice cleanup code should go here! */
+void release_screensaver(ModeInfo * mi)
+{
+  int screen;
+  if (Screensaver != NULL) {
+       for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
+/*       screensaverstruct *gp = &Screensaver[screen];*/
+       }
+       (void) free((void *) Screensaver);
+       Screensaver = NULL;
+  }
+  FreeAllGL(mi);
+}
+#endif
+
diff --git a/hacks/images/matrix.xbm b/hacks/images/matrix.xbm
new file mode 100644 (file)
index 0000000..9d29751
--- /dev/null
@@ -0,0 +1,394 @@
+#define matrix_width 56
+#define matrix_height 837
+static char matrix_bits[] = {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xf7,0xff,0xff,0x7b,0xff,
+ 0xff,0xaf,0xc8,0xff,0xff,0x4d,0xfd,0xff,0x0f,0x22,0xff,0x7f,0x75,0xfb,0xff,
+ 0x17,0x89,0xff,0xff,0xda,0xf5,0xff,0x47,0x25,0xfe,0xff,0xfd,0xfb,0xff,0x0b,
+ 0x1f,0xff,0x7f,0xfa,0xf2,0xff,0x85,0x17,0xfe,0xbf,0xfd,0xf5,0xff,0x45,0x9d,
+ 0xfe,0x7f,0xf5,0xf7,0xff,0x52,0x17,0xfd,0xaf,0xfd,0xe9,0xff,0x81,0x1f,0xfe,
+ 0xbf,0xfe,0xf7,0xff,0x4a,0x2d,0xfa,0xbf,0xfa,0xe9,0xff,0xa1,0x1f,0xfd,0xbf,
+ 0xfd,0xf7,0xff,0x92,0x2e,0xfc,0xdf,0xda,0xe9,0xff,0x85,0x9b,0xfe,0x7f,0xfd,
+ 0xf7,0xff,0x52,0x0f,0xfe,0xdf,0xfa,0xf2,0xff,0x85,0x3d,0xfe,0xff,0xfa,0xfb,
+ 0xff,0x47,0x8f,0xfe,0x7f,0xf9,0xea,0xff,0x0b,0x15,0xfe,0xff,0xdd,0xf5,0xff,
+ 0x87,0x0b,0xff,0x7f,0x75,0xfb,0xff,0x17,0xad,0xfe,0xff,0xff,0xfe,0xff,0x5f,
+ 0xa1,0xff,0xff,0x4b,0xff,0xff,0x5f,0xd4,0xff,0xff,0xff,0xff,0xff,0x77,0xeb,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xff,
+ 0xff,0xff,0xf4,0xff,0xff,0x57,0xff,0xff,0x3f,0x90,0xff,0xff,0x4b,0xfd,0xff,
+ 0x7f,0x48,0xff,0xff,0xa7,0xff,0xff,0x7f,0xe8,0xff,0xff,0xcf,0xff,0xff,0x3f,
+ 0xe8,0xff,0xff,0xa7,0xff,0xff,0x7f,0xf8,0xff,0xff,0xcb,0xff,0xff,0x3f,0xfc,
+ 0xff,0xff,0xcf,0xff,0xff,0x7f,0xf8,0xff,0xff,0xc7,0xff,0xff,0x3f,0xfa,0xff,
+ 0xff,0xeb,0xff,0xff,0x7f,0xf8,0xff,0xff,0xa7,0xff,0xff,0x3f,0xfc,0xff,0xff,
+ 0xcf,0xff,0xff,0x7f,0xf8,0xff,0xff,0xe7,0xff,0xff,0x3f,0xfa,0xff,0xff,0xcb,
+ 0xff,0xff,0x7f,0xf8,0xff,0xff,0xcf,0xff,0xff,0x3f,0xfc,0xff,0xff,0xc7,0xff,
+ 0xff,0x7f,0xf8,0xff,0xff,0xd7,0xff,0xff,0x3f,0xfc,0xff,0xff,0xcb,0xff,0xff,
+ 0x7f,0xf8,0xff,0xff,0xcf,0xff,0xff,0x3f,0xf8,0xff,0xff,0xe7,0xff,0xff,0x5f,
+ 0xfa,0xff,0xff,0xad,0xff,0xff,0x3f,0xe8,0xff,0xff,0xd7,0xff,0xff,0x57,0xf5,
+ 0xff,0xff,0xff,0xff,0xff,0xbf,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0x7f,0xfb,0xff,0xff,0xed,0xff,0xff,0x4f,0xad,0xff,0xff,0xb5,0xfa,0xff,
+ 0x0f,0x12,0xff,0x7f,0x79,0xfb,0xff,0x07,0x09,0xff,0xff,0xea,0xf5,0xff,0x97,
+ 0x2a,0xff,0x7f,0xfd,0xff,0xff,0x87,0x5e,0xff,0xff,0xf4,0xf5,0xff,0x4b,0x2b,
+ 0xff,0xff,0xfa,0xff,0xff,0x05,0xbf,0xff,0xff,0xfa,0xff,0xff,0x8b,0xfd,0xff,
+ 0xff,0xfa,0xff,0xff,0x47,0xf7,0xff,0xff,0xda,0xff,0xff,0x8f,0xfe,0xff,0xff,
+ 0xf5,0xff,0xff,0x27,0xfa,0xff,0xff,0xdb,0xff,0xff,0x1f,0xfd,0xff,0xff,0xee,
+ 0xff,0xff,0xaf,0xea,0xff,0xff,0x57,0xff,0xff,0x5f,0xf4,0xff,0xff,0xef,0xff,
+ 0xff,0x77,0xd1,0xff,0xff,0xbb,0xfe,0xff,0xaf,0xd4,0xff,0xbf,0x5f,0xfd,0xff,
+ 0xbb,0x42,0xff,0xff,0x75,0xfb,0xff,0x4f,0x29,0xff,0x7f,0xdf,0xfa,0xff,0x25,
+ 0x05,0xff,0xff,0x55,0xfb,0xff,0x97,0x40,0xff,0x7f,0xab,0xfa,0xff,0x2f,0x12,
+ 0xff,0xff,0x75,0xfd,0xff,0x8b,0x44,0xff,0xff,0xdf,0xff,0xff,0x7f,0xb5,0xff,
+ 0xff,0xff,0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5f,0xf5,0xff,0xff,0x55,0xff,0xff,
+ 0x8f,0xd2,0xff,0xff,0x7a,0xfd,0xff,0x17,0x44,0xff,0x7f,0x55,0xff,0xff,0x07,
+ 0xa3,0xff,0xff,0xf9,0xfb,0xff,0x4f,0xa9,0xff,0xff,0xfc,0xfe,0xff,0x05,0x57,
+ 0xff,0xff,0xda,0xff,0xff,0x8b,0xad,0xff,0x7f,0xf5,0xff,0xff,0x47,0xfa,0xff,
+ 0xff,0xba,0xff,0xff,0x0f,0xfd,0xff,0xff,0xea,0xff,0xff,0x0f,0xf5,0xff,0xff,
+ 0xd5,0xff,0xff,0x47,0xfc,0xff,0x7f,0xf5,0xff,0xff,0x17,0xf5,0xff,0xff,0xaa,
+ 0xff,0xff,0x05,0xfa,0xff,0xbf,0xfd,0xff,0xff,0x4b,0xfd,0xff,0xff,0xf6,0xff,
+ 0xff,0x25,0xfb,0xff,0x5f,0xfd,0xff,0xff,0x91,0xff,0xff,0xbf,0xfb,0xff,0xff,
+ 0xc5,0xb6,0xff,0x7f,0xdd,0xfb,0xff,0x15,0x5b,0xff,0xff,0xfd,0xfa,0xff,0xc7,
+ 0x0d,0xff,0xff,0x76,0xfb,0xff,0x95,0x26,0xff,0xff,0xdd,0xff,0xff,0x5f,0x91,
+ 0xff,0xff,0x77,0xfd,0xff,0xaf,0xd4,0xff,0xff,0xdf,0xff,0xff,0x5f,0xd5,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x5f,0xfd,0xff,0xff,0xd7,0xff,0xff,0x7f,0xfc,0xff,0xff,0xe5,0xff,0xff,0x17,
+ 0xf8,0xff,0xff,0xab,0xff,0xff,0xaf,0xf4,0xff,0xff,0xd7,0xff,0xff,0x2f,0xe8,
+ 0xff,0xff,0x55,0xff,0xff,0x9f,0xe4,0xff,0x7f,0xaf,0xfe,0xff,0x57,0xd0,0xff,
+ 0xff,0x55,0xff,0xff,0x2f,0xa2,0xff,0xff,0xaf,0xfa,0xff,0x5f,0x11,0xff,0xff,
+ 0x6a,0xfb,0xff,0x2f,0x44,0xff,0xff,0xad,0xf5,0xff,0x97,0x22,0xfe,0xff,0xd6,
+ 0xfa,0xff,0x2b,0x14,0xfd,0xff,0x55,0xeb,0xff,0x8f,0x48,0xfe,0xff,0x6a,0xf5,
+ 0xff,0x05,0x02,0xfa,0x7f,0x91,0xed,0xff,0x17,0x50,0xfd,0xff,0x4a,0xf5,0xff,
+ 0x03,0x08,0xfd,0x7f,0xeb,0xff,0xff,0x4d,0xd2,0xfe,0xff,0xb5,0xfe,0xff,0x2f,
+ 0xfa,0xff,0xff,0xef,0xff,0xff,0x57,0xed,0xff,0xff,0xfb,0xff,0xff,0xaf,0xfc,
+ 0xff,0xff,0xff,0xff,0xff,0x5f,0xff,0xff,0xff,0xef,0xff,0xff,0x7f,0xfd,0xff,
+ 0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,
+ 0xaf,0xf6,0xff,0xff,0x55,0xff,0xff,0x5f,0xc1,0xff,0xff,0x5f,0xfd,0xff,0x97,
+ 0xa8,0xff,0xff,0xaa,0xfe,0xff,0x17,0x81,0xff,0xff,0x5f,0xfd,0xff,0x6f,0x62,
+ 0xff,0xff,0xf7,0xfe,0xff,0xbf,0x95,0xff,0xff,0x5f,0xfb,0xff,0xdf,0xa2,0xff,
+ 0xff,0xfe,0xfe,0xff,0xbf,0x4a,0xff,0xff,0x2b,0xfd,0xff,0xaf,0xa0,0xff,0xff,
+ 0xab,0xfe,0xff,0x17,0x80,0xff,0x7f,0x55,0xfb,0xff,0x4f,0xd5,0xff,0xff,0xfa,
+ 0xff,0xff,0x05,0xd2,0xff,0xff,0x6d,0xff,0xff,0x4b,0xf5,0xff,0x5f,0xf9,0xff,
+ 0xff,0x85,0xfe,0xff,0x7f,0xfd,0xff,0xff,0x13,0xf7,0xff,0xdf,0xf6,0xff,0xff,
+ 0xc5,0xfd,0xff,0xbf,0xfd,0xff,0xff,0x51,0xff,0xff,0xff,0xbe,0xff,0xff,0x8f,
+ 0xa5,0xff,0xff,0xf5,0xfa,0xff,0x4b,0x2b,0xff,0xff,0xfe,0xff,0xff,0x97,0x95,
+ 0xff,0xff,0xb7,0xfa,0xff,0xaf,0x4a,0xff,0xff,0xdf,0xff,0xff,0x5f,0xe5,0xff,
+ 0xff,0x7b,0xff,0xff,0x7f,0xd2,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xfe,0xff,0xff,0xeb,0xff,0xff,
+ 0x3f,0xfd,0xff,0xff,0xff,0xff,0xff,0xaf,0xfa,0xff,0xff,0xad,0xff,0xff,0x7f,
+ 0xe9,0xff,0xff,0xff,0xfe,0xff,0xbf,0xd2,0xff,0xff,0x2f,0xff,0xff,0xff,0xc2,
+ 0xff,0xff,0xff,0xfa,0xff,0x7f,0x2b,0xff,0xff,0xbf,0xfb,0xff,0xff,0x15,0xff,
+ 0xff,0xff,0xf5,0xff,0x7f,0x8b,0xfe,0xff,0x5b,0xf5,0xff,0x4f,0x11,0xfe,0x7f,
+ 0x6d,0xf1,0xff,0x97,0x04,0xff,0xff,0xa9,0xf4,0xff,0x0f,0x01,0xfe,0x7f,0xdd,
+ 0xf2,0xff,0x45,0x14,0xfe,0xff,0xf5,0xf5,0xff,0x0b,0x8b,0xfe,0xbf,0xfe,0xf5,
+ 0xff,0xc2,0x1d,0xff,0xdf,0xba,0xf7,0xff,0x2b,0x17,0xfe,0x7f,0xfd,0xf2,0xff,
+ 0x81,0x9d,0xfe,0xbf,0xff,0xfb,0xff,0x55,0x17,0xfe,0xff,0xfa,0xf5,0xff,0xa5,
+ 0x1b,0xff,0x7f,0xfb,0xf5,0xff,0x4b,0x8d,0xfe,0xff,0xbd,0xfa,0xff,0x0f,0x27,
+ 0xff,0x7f,0xf5,0xf7,0xff,0xcb,0x92,0xfe,0xff,0x7f,0xfd,0xff,0xaf,0xaa,0xff,
+ 0xff,0xd7,0xff,0xff,0x5f,0xd5,0xff,0xff,0x7f,0xff,0xff,0x7f,0xf5,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x5f,0xf5,0xff,0xff,0xdb,0xff,0xff,0xef,0x96,0xff,0xff,0x7e,0xfd,0xff,0x1f,
+ 0x55,0xff,0xff,0xa9,0xf7,0xff,0x87,0x90,0xfe,0xff,0x74,0xf9,0xff,0x0f,0x0a,
+ 0xfd,0xff,0xd2,0xee,0xff,0x07,0x49,0xfe,0xff,0xfa,0xfb,0xff,0x17,0x55,0xff,
+ 0xff,0xad,0xff,0xff,0x4f,0xfa,0xff,0xff,0xfb,0xff,0xff,0x17,0xbd,0xff,0xff,
+ 0xee,0xff,0xff,0xaf,0xfa,0xff,0xff,0xd7,0xff,0xff,0x5f,0xfa,0xff,0xff,0xef,
+ 0xff,0xff,0x7f,0xfa,0xff,0xff,0xb7,0xff,0xff,0xbf,0xf8,0xff,0xff,0xef,0xff,
+ 0xff,0x7f,0xed,0xff,0xff,0xbf,0xff,0xff,0xbf,0xf4,0xff,0xff,0xef,0xff,0xff,
+ 0xff,0xea,0xff,0xff,0xbf,0xfe,0xff,0xff,0xe5,0xff,0xff,0x7f,0xff,0xff,0xff,
+ 0xe7,0xff,0xff,0x7f,0xff,0xff,0xff,0xd3,0xff,0xff,0xff,0xfd,0xff,0xff,0xa5,
+ 0xff,0xff,0xbf,0xfe,0xff,0xff,0xa7,0xff,0xff,0xff,0xfb,0xff,0xff,0x57,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0x2f,0xff,0xff,0xff,0xfb,0xff,0xff,0xbf,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x5f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0xff,0xff,0x6f,0xff,0xff,0xbf,0xd4,
+ 0xff,0xff,0xfb,0xff,0xff,0xaf,0x56,0xff,0xff,0xb6,0xfa,0xff,0x5f,0x29,0xff,
+ 0xff,0xfb,0xf5,0xff,0x87,0x8e,0xfe,0x7f,0xd9,0xf5,0xff,0x8f,0x12,0xfe,0xff,
+ 0xfd,0xf5,0xff,0x0f,0x1b,0xff,0xff,0x74,0xf3,0xff,0x07,0x15,0xfe,0xff,0xda,
+ 0xfa,0xff,0x97,0x8a,0xfe,0xff,0x6b,0xf5,0xff,0x0f,0x01,0xfe,0xff,0x15,0xf2,
+ 0xff,0x5f,0x20,0xff,0xff,0x56,0xf9,0xff,0x17,0x04,0xfe,0xff,0xab,0xea,0xff,
+ 0x4f,0x10,0xfd,0x7f,0xa5,0xf5,0xff,0x17,0x82,0xfe,0xff,0xda,0xf5,0xff,0x4f,
+ 0x28,0xfe,0xff,0xe9,0xf6,0xff,0x0f,0x16,0xfd,0xff,0xfd,0xeb,0xff,0x87,0x55,
+ 0xfd,0xff,0xb4,0xff,0xff,0x97,0x2e,0xfa,0xff,0xfb,0xea,0xff,0x0f,0x9b,0xfe,
+ 0x7f,0xf9,0xf3,0xff,0x47,0x1d,0xfd,0xff,0xfd,0xeb,0xff,0x97,0x16,0xfe,0xff,
+ 0xd7,0xfd,0xff,0x4f,0xab,0xfe,0xff,0x7d,0xf7,0xff,0x7f,0x55,0xff,0xff,0xff,
+ 0xff,0xff,0xbf,0xaa,0xff,0xff,0xb7,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe8,
+ 0xff,0xff,0x5f,0xff,0xff,0xbf,0xd6,0xff,0xff,0xf7,0xfd,0xff,0xaf,0x52,0xff,
+ 0xff,0xdd,0xf7,0xff,0x5f,0x2d,0xff,0xff,0xf5,0xfa,0xff,0x07,0x15,0xfe,0xff,
+ 0xfa,0xeb,0xff,0x97,0xae,0xfe,0xff,0xdd,0xfd,0xff,0x4f,0x1b,0xfa,0xff,0xfa,
+ 0xf7,0xff,0x8f,0xae,0xfd,0xff,0xfd,0xdb,0xff,0x47,0x5b,0xfc,0xff,0xf4,0xf6,
+ 0xff,0x0f,0x2f,0xfb,0xff,0xda,0xf7,0xff,0x8f,0x9a,0xfc,0xff,0xfa,0xea,0xff,
+ 0x87,0x2a,0xfe,0xff,0x55,0xfb,0xff,0x17,0x04,0xfd,0xff,0x50,0xe9,0xff,0x0f,
+ 0x81,0xfe,0xff,0xad,0xfa,0xff,0x07,0x14,0xff,0xff,0xd6,0xff,0xff,0x5f,0x50,
+ 0xff,0xff,0xeb,0xff,0xff,0x97,0xfc,0xff,0xff,0x57,0xff,0xff,0x3f,0xea,0xff,
+ 0xff,0xef,0xff,0xff,0xbf,0xe8,0xff,0xff,0xaf,0xfe,0xff,0x7f,0xe4,0xff,0xff,
+ 0x77,0xff,0xff,0xff,0xd2,0xff,0xff,0xbf,0xff,0xff,0x7f,0xd5,0xff,0xff,0xff,
+ 0xfd,0xff,0xff,0x57,0xff,0xff,0x7f,0xff,0xff,0xff,0xab,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0x7f,0xff,0xff,0xff,0xe2,0xff,0xff,
+ 0x5f,0xff,0xff,0xff,0xe5,0xff,0xff,0xbf,0xfe,0xff,0xff,0xd3,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0xe1,0xff,0xff,0xbf,0xfe,0xff,0xff,0xc7,0xff,0xff,0x7f,0xff,
+ 0xff,0xff,0xe1,0xff,0xff,0xbf,0xfd,0xff,0xff,0x97,0xff,0xff,0xff,0xfe,0xff,
+ 0xff,0x53,0xff,0xff,0xff,0xfb,0xff,0x7f,0xab,0xff,0xff,0x7f,0xff,0xff,0xdf,
+ 0x16,0xff,0xff,0xed,0xf5,0xff,0x5f,0xad,0xfe,0xff,0xff,0xfb,0xff,0xa7,0x3f,
+ 0xff,0xff,0xfa,0xfb,0xff,0x5b,0x8d,0xfe,0x7f,0xff,0xf7,0xff,0xa5,0x3f,0xff,
+ 0xbf,0xed,0xfa,0xff,0x92,0x8a,0xfc,0xaf,0xbe,0xa5,0xff,0xc9,0x0a,0xe2,0xbf,
+ 0xd6,0x52,0xff,0x20,0x02,0xd0,0x9f,0xbd,0xaa,0xff,0xa1,0x55,0xe8,0xff,0xff,
+ 0xff,0xfe,0xf5,0x56,0xf7,0xbf,0xff,0xff,0xff,0xf5,0xff,0xfd,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
+ 0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xef,0xff,0xff,0xaf,0xfc,0xff,0xff,
+ 0xf5,0xff,0xff,0x2f,0xfd,0xff,0xff,0xdb,0xff,0xff,0x5f,0xfa,0xff,0xff,0xb7,
+ 0xff,0xff,0x7f,0xe9,0xff,0xff,0xdf,0xfe,0xff,0xbf,0xe4,0xff,0xff,0x7f,0xff,
+ 0xff,0xff,0xd2,0xff,0xff,0xdf,0xfd,0xff,0xff,0x4b,0xff,0xff,0x7f,0xf7,0xff,
+ 0xff,0x2d,0xff,0xff,0xff,0xfb,0xff,0xff,0x17,0xfe,0xff,0xff,0xf5,0xff,0xff,
+ 0x5f,0xff,0xff,0xff,0xf5,0xff,0xff,0x1f,0xfd,0xff,0xff,0xf7,0xff,0xff,0x17,
+ 0xfe,0xff,0x7f,0xfb,0xff,0xff,0xad,0xff,0xff,0xff,0xff,0xff,0xff,0x53,0xff,
+ 0xff,0xbf,0xfe,0xff,0xff,0xe5,0xff,0xff,0xdf,0xff,0xff,0x7f,0xea,0xff,0xff,
+ 0x6b,0xff,0xff,0xbf,0xf4,0xff,0xff,0xef,0xff,0xff,0x7f,0xfa,0xff,0xff,0xef,
+ 0xff,0xff,0x2f,0xfc,0xff,0xff,0xfb,0xff,0xff,0x9f,0xff,0xff,0xff,0xfd,0xff,
+ 0xff,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0x7f,0xe5,0xff,0xff,0xb7,0xfe,0xff,0x5f,0xa9,0xff,0xff,0x7d,
+ 0xff,0xff,0x57,0x45,0xff,0xbf,0xbf,0xfa,0xff,0x55,0x53,0xfd,0xff,0x76,0xed,
+ 0xff,0xab,0x83,0xfa,0xbf,0xbf,0xf6,0xff,0xd1,0x51,0xfa,0x6f,0x7f,0xbf,0xff,
+ 0x6a,0xc7,0xfa,0xbf,0x7f,0xed,0xff,0xf1,0xa1,0xea,0xbf,0x7f,0xbf,0xff,0xf4,
+ 0xd7,0xea,0xdf,0xbe,0xf5,0xfe,0xd2,0x4b,0xd5,0xbf,0xff,0xdf,0x7d,0xf9,0xa5,
+ 0xca,0xaf,0xff,0xf5,0xfe,0xe2,0x1f,0xa6,0x7f,0xff,0xbb,0xff,0xb9,0x57,0xd5,
+ 0xaf,0xff,0xed,0xfd,0xe0,0x2f,0xca,0x7f,0xfb,0x77,0xff,0xf5,0x9f,0xea,0xbf,
+ 0xef,0xdb,0xff,0x97,0x3e,0xe9,0xff,0xfe,0x6f,0xff,0x6d,0xdb,0xf4,0xff,0xfb,
+ 0xbf,0xff,0x5f,0x7d,0xf9,0xff,0xef,0xff,0xff,0xff,0xff,0xfa,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0x7f,0x6d,0xfd,0xff,0xdf,0xab,0xff,0xbf,0x55,0xaa,0xff,0xbf,0xd6,
+ 0xfa,0xff,0x24,0x50,0xff,0xf7,0xd7,0xff,0x7f,0x5b,0xda,0xff,0xff,0xd7,0xff,
+ 0xff,0x57,0xe8,0xff,0xff,0xdb,0xff,0xff,0xbf,0xfc,0xff,0xbf,0xcf,0xff,0xbf,
+ 0x5a,0xb4,0xff,0xf7,0x6b,0xff,0xbf,0x5e,0xd8,0xff,0x7b,0xd7,0xfd,0x5f,0x25,
+ 0xea,0xfe,0xef,0xcb,0xff,0x3f,0x5d,0xb4,0xff,0xff,0x6f,0xff,0x7f,0x2b,0xd4,
+ 0xfe,0xff,0xd5,0xfb,0xff,0xbf,0xe8,0xff,0xdf,0xd7,0xff,0x7f,0x2b,0x7a,0xff,
+ 0xff,0xd7,0xff,0xff,0x7f,0xf8,0xff,0xff,0xef,0xff,0xff,0xbf,0xfc,0xff,0xff,
+ 0xd7,0xff,0xff,0x7f,0xfa,0xff,0xff,0xef,0xff,0xff,0x7f,0xfc,0xff,0xff,0xd7,
+ 0xff,0xff,0x7f,0xfa,0xff,0xff,0xef,0xff,0xff,0x7f,0xfc,0xff,0xff,0xd7,0xff,
+ 0xff,0xbf,0xf8,0xff,0xff,0xdf,0xff,0xff,0x7f,0xfa,0xff,0xff,0xe7,0xff,0xff,
+ 0x7f,0xf4,0xff,0xff,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
+ 0xff,0xff,0xff,0xbf,0xfe,0xff,0xff,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xef,
+ 0xff,0xff,0x7f,0xfc,0xff,0xff,0xef,0xff,0xff,0x7f,0xfc,0xff,0xff,0xef,0xff,
+ 0xff,0x7f,0xfd,0xff,0xff,0xef,0xff,0xff,0x7f,0xfc,0xff,0xff,0xef,0xff,0xff,
+ 0x7f,0xfd,0xff,0xff,0xef,0xff,0xff,0x7f,0xfc,0xff,0xff,0xeb,0xff,0xff,0xbf,
+ 0xfc,0xff,0xff,0xdf,0xff,0xff,0x7f,0xfc,0xff,0xff,0xef,0xff,0xff,0xbf,0xfc,
+ 0xff,0xff,0xef,0xff,0xff,0x7f,0xfc,0xff,0xff,0xd7,0xff,0xff,0x7f,0xfd,0xff,
+ 0xff,0xef,0xff,0xff,0x7f,0xfa,0xff,0xff,0xef,0xff,0xff,0x7f,0xfc,0xff,0xff,
+ 0xdf,0xff,0xff,0xbf,0xfa,0xff,0xff,0xef,0xff,0xff,0xff,0xf4,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0xea,0xff,0xff,0x7f,0xff,0xff,0xff,0xe3,0xff,0xff,0xbf,0xff,
+ 0xff,0xff,0xd5,0xff,0xff,0xff,0xfe,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xaf,0xaa,0xfe,0xff,0x55,0xf5,0xff,0x5f,0x95,0xfa,0xff,0xff,0xdf,
+ 0xff,0x2f,0x52,0xf9,0x7f,0xd9,0xb6,0xff,0x8f,0xad,0xfa,0xff,0xf6,0xdf,0xff,
+ 0x97,0xb6,0xf0,0xff,0xfb,0xab,0xff,0x0f,0x55,0xfa,0xff,0xac,0xde,0xff,0xa7,
+ 0x54,0xf1,0xff,0xd7,0xaa,0xff,0x17,0x02,0xf8,0xff,0xb4,0xaa,0xff,0x8d,0x54,
+ 0xf2,0x7f,0xab,0xd5,0xff,0x43,0x82,0xe8,0xbf,0xdd,0x6a,0xff,0x29,0x11,0xf4,
+ 0xaf,0xb6,0xda,0xff,0x05,0x8a,0xea,0x7f,0x6b,0xeb,0xff,0xaa,0x24,0xfa,0xff,
+ 0xbd,0xb1,0xff,0x57,0x09,0xfa,0xff,0xd6,0xed,0xff,0x8f,0x14,0xfd,0xff,0x7b,
+ 0xf5,0xff,0x2f,0x25,0xfa,0x7f,0xed,0xdb,0xff,0x8f,0x9a,0xfa,0xff,0xfa,0xff,
+ 0xff,0x4f,0xab,0xfa,0xff,0xdd,0xee,0xff,0x17,0xed,0xfe,0xff,0xf7,0xff,0xff,
+ 0x4f,0xb5,0xff,0xff,0x5a,0xff,0xff,0xaf,0xea,0xff,0xff,0xef,0xff,0xff,0x3f,
+ 0xf4,0xff,0xff,0xb7,0xff,0xff,0x5f,0xe9,0xff,0xff,0xcf,0xff,0xff,0x7f,0xf4,
+ 0xff,0xff,0x7f,0xff,0xff,0xbf,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xaf,0xff,0xff,0xff,0xff,0xff,0xff,0xb7,0xff,0xff,0xff,0xfa,0xff,
+ 0xff,0x4b,0xff,0xff,0x7f,0xff,0xff,0xff,0xa5,0xff,0xff,0xdf,0xfa,0xff,0xbf,
+ 0x25,0xff,0x7f,0x75,0xfb,0xff,0x41,0x95,0xfe,0x5f,0xad,0xf5,0xff,0x01,0x08,
+ 0xff,0xbf,0xd5,0xfa,0xff,0x4a,0x25,0xfe,0xff,0x7a,0xf7,0xff,0x15,0x92,0xfe,
+ 0xff,0xcf,0xfb,0xff,0x97,0xa8,0xfa,0xff,0xea,0xde,0xff,0x4f,0x56,0xfd,0xff,
+ 0xaf,0xf7,0xff,0x3f,0xb8,0xfa,0xff,0xeb,0xdf,0xff,0xff,0xec,0xfa,0xff,0xdf,
+ 0xff,0xff,0x3f,0xfa,0xfb,0xff,0xef,0xff,0xff,0x7f,0xe9,0xfd,0xff,0x7f,0xff,
+ 0xff,0xff,0xed,0xff,0xff,0xbf,0xff,0xff,0x7f,0xe5,0xff,0xff,0xff,0xfe,0xff,
+ 0xff,0xdb,0xff,0xff,0xff,0xff,0xff,0xff,0xab,0xff,0xff,0xff,0xfd,0xff,0xff,
+ 0xef,0xff,0xff,0xff,0xff,0xff,0xff,0x5b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,
+ 0xff,0xff,0xe7,0xff,0xff,0xbd,0xff,0xff,0x9f,0xf3,0xff,0xff,0xff,0xfe,0xff,
+ 0xaf,0xc5,0xff,0xff,0x5a,0xff,0xff,0x97,0xe2,0xff,0xff,0xbd,0xfe,0xff,0x4f,
+ 0xd3,0xff,0xff,0xba,0xfe,0xff,0x0f,0xc5,0xff,0xff,0x7b,0xff,0xff,0xa7,0xd1,
+ 0xff,0xff,0x5c,0xfd,0xff,0x8f,0x42,0xff,0xff,0x55,0xfe,0xff,0x8a,0x64,0xff,
+ 0x57,0xba,0xfa,0x3f,0x05,0x41,0xfd,0xef,0x29,0xd5,0xbf,0x44,0x80,0xfa,0x7b,
+ 0xb5,0xfe,0xbf,0x0a,0x45,0xfd,0xef,0xba,0xfa,0x7f,0x47,0xa1,0xfe,0xff,0x6d,
+ 0xff,0xff,0x17,0xa5,0xff,0x7f,0x7d,0xfd,0xff,0x8f,0x53,0xff,0xff,0xbb,0xf7,
+ 0xff,0xaf,0x4a,0xff,0xff,0xfd,0xfd,0xff,0x8f,0x55,0xff,0x7f,0x75,0xfb,0xff,
+ 0x4f,0x2b,0xff,0xff,0xfd,0xff,0xff,0x97,0x9f,0xfe,0xff,0xff,0xf5,0xff,0x4f,
+ 0x5f,0xff,0xff,0xfa,0xfb,0xff,0x97,0x2f,0xfe,0xff,0xfd,0xff,0xff,0xdf,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xaf,0xff,0xfa,0xff,0xff,0xdf,0xff,0xdf,0xff,0xfd,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xfe,0xff,0xff,0xef,0xff,0xff,0x7f,0xfd,0xff,0xff,0xf7,0xff,0xff,
+ 0x7f,0xfc,0xff,0xff,0xdf,0xff,0xff,0x7f,0xfa,0xff,0xff,0xe7,0xff,0xff,0xbf,
+ 0xf8,0xff,0xff,0xdb,0xff,0xff,0x5b,0xfc,0xff,0x7f,0xa7,0xff,0xff,0x2a,0x48,
+ 0xff,0x9f,0xad,0xf5,0xff,0xa1,0x24,0xfe,0xaf,0xc6,0xf6,0xff,0x10,0x10,0xfd,
+ 0x5f,0x6b,0xeb,0x7f,0x41,0x4a,0xfd,0x5f,0xd7,0xfd,0xff,0x34,0x28,0xfd,0xbf,
+ 0xcf,0xeb,0xff,0xa9,0x2c,0xfd,0x5f,0xe5,0xfe,0xff,0x20,0x94,0xfc,0x2f,0x57,
+ 0xeb,0xff,0x51,0x28,0xfe,0xbf,0xa5,0xf5,0xff,0x01,0x80,0xfa,0xdf,0xae,0xeb,
+ 0xff,0x6a,0x2a,0xfe,0xbf,0xd7,0xfe,0xff,0x35,0xb8,0xff,0xff,0xef,0xff,0xff,
+ 0xbb,0x5c,0xfd,0xff,0xd7,0xff,0xff,0x7f,0xf4,0xff,0xff,0xef,0xff,0xff,0xbf,
+ 0xfc,0xff,0xff,0xd7,0xff,0xff,0x7f,0xfa,0xff,0xff,0xef,0xff,0xff,0xbf,0xfc,
+ 0xff,0xff,0xff,0xff,0xff,0x7f,0xfd,0xff,0xff,0xef,0xff,0xff,0xff,0xfe,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xef,0xff,0xff,0x7f,0xff,0xff,0xff,0xd7,0xff,0xff,0xff,0xfd,0xff,0xff,
+ 0x53,0xff,0xff,0xbf,0xfe,0xff,0xff,0x45,0xfd,0xff,0x7f,0xf5,0xff,0xff,0x53,
+ 0xff,0xff,0x7f,0xff,0xff,0xff,0x85,0xfe,0xff,0xff,0xf2,0xff,0xff,0x2b,0xff,
+ 0xff,0xff,0xfb,0xff,0xff,0x97,0xfe,0xff,0x5f,0xf5,0xff,0xff,0x01,0xfe,0xff,
+ 0x7f,0xfd,0xff,0x7f,0x55,0xff,0xff,0x5f,0xf5,0xff,0xff,0x02,0xfd,0xff,0x7f,
+ 0xfb,0xff,0xff,0xa5,0xfe,0xff,0x5f,0xed,0xff,0xff,0x43,0xfd,0xff,0x7f,0xfd,
+ 0xff,0xff,0x92,0xfe,0xff,0xbf,0xea,0xff,0xff,0x45,0xfa,0xff,0x7f,0xdb,0xff,
+ 0xff,0x13,0xfa,0xff,0xff,0xed,0xff,0xff,0x85,0xfa,0xff,0x2f,0xf5,0xff,0x2f,
+ 0x25,0xfd,0xbf,0xf5,0xda,0xff,0xb5,0x10,0xfd,0x7f,0x97,0xfd,0xff,0x0a,0x8a,
+ 0xfe,0xff,0xfd,0xf7,0xff,0x6b,0x69,0xfd,0xdf,0xef,0xff,0xff,0xaa,0xbe,0xff,
+ 0x7f,0xff,0xdf,0xff,0xef,0xff,0xf9,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xfd,0xff,0xff,0xef,0xff,0xff,0xbf,0xfe,0xff,0xff,0xff,0xff,0xff,0x7f,
+ 0xf9,0xff,0xff,0xcf,0xff,0xff,0x7f,0xfc,0xff,0xff,0xeb,0xff,0xff,0x7f,0xf4,
+ 0xff,0xff,0xaf,0xff,0xff,0x2b,0xd8,0xff,0xaf,0xa2,0xfd,0xff,0x21,0xa2,0xfe,
+ 0x3f,0x8b,0xf6,0xff,0x08,0x28,0xfd,0x9f,0x6a,0xfb,0xff,0x50,0x80,0xfe,0xbf,
+ 0xd7,0xee,0xff,0xa2,0xd4,0xfe,0xaf,0xbe,0xff,0xff,0x51,0x52,0xff,0xbf,0x6f,
+ 0xfd,0xff,0x68,0xd5,0xff,0x5f,0xbf,0xff,0xff,0xb3,0xa2,0xff,0xbf,0xfb,0xfe,
+ 0xff,0xd0,0xd3,0xff,0x7f,0x5f,0xff,0xff,0x6b,0xe5,0xff,0xdf,0x7d,0xfd,0xff,
+ 0xa9,0xa2,0xff,0x7f,0xb7,0xff,0xff,0x55,0xd5,0xff,0xff,0xfd,0xfe,0xff,0x0b,
+ 0xd5,0xff,0xff,0xd5,0xfb,0xff,0xa7,0xaa,0xfe,0xff,0xfa,0xff,0xff,0x17,0x3d,
+ 0xff,0xff,0xed,0xeb,0xff,0x8f,0x5e,0xfd,0xff,0xff,0xff,0xff,0x5f,0x7f,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xbf,0xff,0xff,0xff,0x51,0x9f,
+ 0xfe,0xdf,0xfe,0xf5,0xff,0xea,0x5b,0xfe,0xbf,0xff,0xfb,0xff,0xb1,0x5f,0xfd,
+ 0xdf,0xfe,0xef,0xff,0xea,0x3e,0xfd,0xbf,0xff,0xf7,0xff,0xd1,0x57,0xfd,0x7f,
+ 0xff,0xdd,0xff,0x6a,0xaf,0xfa,0xaf,0xfb,0xf7,0xff,0xe9,0x3f,0xfd,0x7f,0xff,
+ 0xfb,0xff,0xb1,0x5b,0xfd,0xbf,0xff,0xdf,0xff,0xea,0x2f,0xfa,0xdf,0xfe,0xf5,
+ 0xff,0x69,0xbf,0xfd,0xbf,0xf7,0xef,0xff,0xe1,0x57,0xfc,0x5f,0xdf,0xf5,0xff,
+ 0xb5,0x2e,0xfb,0xbf,0xff,0xdb,0xff,0xa1,0x15,0xfd,0x7f,0x75,0xf5,0xff,0x54,
+ 0x95,0xfc,0x5f,0xdf,0xf7,0xff,0x43,0x15,0xfd,0xff,0xfd,0xed,0xff,0xb4,0x5b,
+ 0xfd,0xbf,0xff,0xfb,0xff,0xeb,0x5f,0xfe,0xdf,0xff,0xff,0xff,0xf2,0x7f,0xfb,
+ 0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xfe,0xff,0x7f,0xed,0xff,0xff,0x55,0x53,
+ 0xfd,0xbf,0xb6,0xea,0xff,0x02,0x09,0xfa,0x5f,0x59,0xb5,0xff,0x41,0xa2,0xf4,
+ 0xff,0xb6,0xfe,0xff,0x17,0x91,0xfa,0xff,0x5b,0xf7,0xff,0x57,0x64,0xff,0xff,
+ 0xb7,0xfe,0xff,0x5f,0xd1,0xff,0xff,0x6f,0xff,0xff,0xaf,0xc2,0xff,0xff,0x5f,
+ 0xfd,0xff,0xff,0x65,0xff,0xff,0x7f,0xff,0xff,0xff,0xd2,0xff,0xff,0xbf,0xfe,
+ 0xff,0xff,0xe3,0xff,0xff,0x7f,0xff,0xff,0xff,0xd3,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xe5,0xff,0xff,0xbf,0xfe,0xff,0xff,0xd7,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xd3,0xff,0xff,0xff,0xfe,0xff,0xff,0xaf,0xff,0xff,0xff,0xff,0xff,0xff,0xb7,
+ 0xff,0xff,0xff,0xfb,0xff,0xff,0xbf,0xfe,0xff,0xff,0xff,0xff,0xff,0x5f,0xff,
+ 0xff,0xff,0xfb,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,
+ 0x9c,0xfe,0xff,0xd7,0xf5,0xff,0x7f,0x5a,0xfe,0xff,0xef,0xf7,0xff,0xbf,0x2c,
+ 0xfd,0xff,0xdb,0xed,0xff,0x7f,0x3a,0xfd,0xff,0xef,0xfb,0xff,0x5f,0x98,0xfa,
+ 0xff,0xab,0xd7,0xff,0x77,0x4c,0xfc,0xff,0xd7,0xea,0xff,0x1f,0x28,0xf2,0xff,
+ 0x4a,0xab,0xff,0xa5,0x08,0xf9,0xff,0xd7,0xd5,0xff,0x17,0x52,0xe8,0xff,0x6b,
+ 0xbb,0xff,0x5f,0x14,0xfa,0xff,0xd7,0xed,0xff,0x7f,0xa8,0xfa,0xff,0xdf,0xf7,
+ 0xff,0xbf,0x2c,0xfd,0xff,0xe7,0xdb,0xff,0x7f,0xaa,0xfa,0xff,0xdf,0xf6,0xff,
+ 0x7f,0x38,0xfd,0xff,0xeb,0xdb,0xff,0xbf,0x4c,0xfa,0xff,0xcf,0xff,0xff,0x7f,
+ 0x3a,0xfd,0xff,0xef,0xeb,0xff,0x7f,0x94,0xfa,0xff,0xd7,0xf6,0xff,0x7f,0x5a,
+ 0xfd,0xff,0xef,0xdb,0xff,0x7f,0x14,0xfd,0xff,0xaf,0xf6,0xff,0x7f,0x54,0xfc,
+ 0xff,0xd7,0xf5,0xff,0x7f,0x08,0xfe,0xff,0xef,0xfb,0xff,0xbf,0xaa,0xfd,0xff,
+ 0xff,0xef,0xff,0xff,0xbe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,
+ 0xff,0xff,0x7f,0xff,0xff,0xff,0xa5,0xff,0xff,0xaf,0xfd,0xff,0xff,0xa9,0xeb,
+ 0xff,0xbf,0x77,0xff,0xff,0x52,0x95,0xfe,0xff,0xde,0xe9,0xff,0xab,0x2a,0xf2,
+ 0xff,0x6b,0x55,0xff,0x56,0x00,0xd4,0x7f,0xaf,0xeb,0xff,0x2b,0x15,0xf1,0xff,
+ 0xf5,0xb5,0xff,0xaf,0xac,0xfc,0xff,0xdf,0xff,0xff,0x57,0x2a,0xf6,0xff,0xea,
+ 0xd6,0xff,0x17,0xbd,0xfa,0xff,0xf5,0xff,0xff,0x4f,0xdd,0xfa,0xbf,0xde,0xbf,
+ 0xff,0x25,0xfa,0xfa,0xff,0xf5,0xef,0xff,0x4b,0xfd,0xf9,0x5f,0xff,0xbf,0xff,
+ 0x29,0xdd,0xf4,0x7f,0xd7,0xdf,0xff,0xe1,0xfa,0xfa,0xaf,0xff,0xbf,0xff,0x74,
+ 0x7e,0xf1,0xff,0xd7,0xdf,0xff,0xb7,0xfa,0xf9,0xff,0xef,0xaf,0xff,0x7d,0xfc,
+ 0xf8,0xff,0xb7,0xdf,0xff,0xbf,0x6c,0xf5,0xff,0xdf,0xf5,0xff,0xff,0x92,0xf8,
+ 0xff,0x6f,0xad,0xff,0xbf,0x08,0xfd,0xff,0xbf,0xf5,0xff,0x7f,0x25,0xfc,0xff,
+ 0xff,0xfe,0xff,0xff,0x95,0xff,0xff,0xff,0xfb,0xff,0xff,0x77,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,
+ 0xff,0xff,0xfd,0xff,0xff,0xdf,0xfe,0xff,0xff,0xf7,0xff,0xff,0xaf,0xfe,0xfa,
+ 0xff,0xff,0xdf,0xff,0x5f,0x5a,0xf9,0xff,0xd7,0xaf,0xff,0x2f,0xbd,0xf4,0xff,
+ 0xed,0xfb,0xff,0x7f,0x5a,0xfa,0xff,0xd7,0xed,0xff,0x5f,0x2c,0xfd,0xff,0xef,
+ 0xf7,0xff,0xbf,0xb8,0xfa,0xff,0xaf,0xfa,0xff,0x7f,0x0a,0xff,0xff,0xd7,0xff,
+ 0xff,0xbf,0xd0,0xfe,0xff,0x3f,0xf5,0xff,0xff,0x44,0xff,0xff,0xaf,0xfe,0xff,
+ 0x3f,0xa1,0xff,0xff,0xb7,0xfe,0xff,0xff,0xc4,0xff,0xff,0x2f,0xfd,0xff,0x5f,
+ 0x50,0xff,0xff,0xbb,0xfe,0xff,0x7f,0xa1,0xff,0xff,0xd6,0xf5,0xff,0x05,0x8a,
+ 0xfe,0xbf,0xea,0xfa,0xff,0x8b,0x14,0xfe,0xff,0xfa,0xf7,0xff,0x05,0x55,0xff,
+ 0xbf,0xef,0xfd,0xff,0xd5,0x5e,0xfd,0xff,0xfe,0xf7,0xff,0xd5,0xff,0xfb,0xdf,
+ 0xff,0xff,0xff,0xfb,0x7f,0xfd,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xe9,0xff,0xff,
+ 0x57,0xff,0xff,0xbf,0xd2,0xff,0xff,0xbf,0xfd,0xff,0xbf,0xc8,0xff,0xff,0xdf,
+ 0xfe,0xff,0xff,0xa2,0xff,0xff,0x7f,0xff,0xff,0xff,0x95,0xff,0xff,0xdf,0xfd,
+ 0xff,0xff,0xa3,0xff,0xff,0xff,0xfa,0xff,0xff,0x4a,0xff,0xfa,0x7f,0xfd,0xdf,
+ 0xff,0x87,0xff,0xfa,0x7f,0xf9,0xef,0xff,0x0b,0x3f,0xf9,0xff,0xfd,0xfb,0xff,
+ 0x8f,0x5d,0xfd,0xff,0xf6,0xef,0xff,0xa7,0xbe,0xfe,0xff,0xfb,0xfb,0xff,0x9f,
+ 0x2a,0xff,0xff,0xd6,0xff,0xff,0x4f,0xbe,0xff,0xff,0xef,0xff,0xff,0x7f,0xf8,
+ 0xff,0xff,0xab,0xff,0xff,0x3f,0xfc,0xff,0xff,0xef,0xff,0xff,0xff,0xea,0xff,
+ 0xff,0xbf,0xfe,0xff,0x7f,0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xff,0xff,
+ 0xff,0xfe,0xff,0xff,0xd7,0xff,0xff,0xbf,0xff,0xff,0xff,0x55,0xff,0xff,0xff,
+ 0xfb,0xff,0xff,0x2f,0xff,0xff,0xff,0xfd,0xff,0xff,0x5f,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
diff --git a/hacks/images/matrix.xpm b/hacks/images/matrix.xpm
new file mode 100644 (file)
index 0000000..f740ad7
--- /dev/null
@@ -0,0 +1,904 @@
+/* XPM */
+static char * matrix[] = {
+"56 837 64 1",
+".     c #000000",
+"+     c #178618",
+"@     c #26C227",
+"#     c #114410",
+"$     c #7AEB7A",
+"%     c #5AC254",
+"&     c #136314",
+"*     c #1AA614",
+"=     c #52DB51",
+"-     c #127410",
+";     c #169614",
+">     c #062604",
+",     c #32D634",
+"'     c #145417",
+")     c #B2F6B0",
+"!     c #42A244",
+"~     c #62E75C",
+"{     c #2F832F",
+"]     c #3AC237",
+"^     c #246624",
+"/     c #2B7729",
+"(     c #0C360E",
+"_     c #92F294",
+":     c #4CB34A",
+"<     c #298B27",
+"[     c #0E4E0C",
+"}     c #62DE64",
+"|     c #3B9439",
+"1     c #1D5E1D",
+"2     c #26B529",
+"3     c #CCFDD1",
+"4     c #73E774",
+"5     c #32CB34",
+"6     c #021804",
+"7     c #4ED64C",
+"8     c #7AF67C",
+"9     c #2E9A34",
+"0     c #26CB24",
+"a     c #166E14",
+"b     c #52BB54",
+"c     c #5ED05C",
+"d     c #36B634",
+"e     c #0B3008",
+"f     c #44AB42",
+"g     c #020E04",
+"h     c #8AEC8C",
+"i     c #1E751C",
+"j     c #2AA62C",
+"k     c #42D73C",
+"l     c #286E26",
+"m     c #1F561E",
+"n     c #368B34",
+"o     c #40CC44",
+"p     c #3E9C3C",
+"q     c #0D3E0E",
+"r     c #66E264",
+"s     c #76EE74",
+"t     c #269624",
+"u     c #A1F2A1",
+"v     c #1C4E1C",
+"w     c #3EDE3C",
+"x     c #5ACA5C",
+"y     c #52E24C",
+"z     c #021E04",
+"........................................................",
+"...........gggggg......................gggggg...........",
+"........gggg6gggggg.................g6g6>6666gg.........",
+".......g666>>>e>z66gg..............g66>eee#e>z66g.......",
+"......g6>>>>(>((ezz6g.............66eeeq[q[[#e>66.......",
+".....g6e#m'''&&1[v#e>gg..........6z[-t*;;**2;+-[e6g.....",
+"....g6>v^{{///n|{^1#(6g.........g>e<]k7,]===7]*i[6g.....",
+"...gzze^|:f!|!::!n/^q>6g.......g>zq@}h44rrhh4=o2&ezg....",
+"...g>>[/|b!|nnp!p|n/m>6g.......6e#-o}_4}==r44}=kt#z6....",
+"..g6e[m{:%!{^l/{n!:|1(>6g.....gz[+t7hu4k@5]k=4h}2[ezg...",
+".ggzqml|fxp/''''{!c:/q>gg....gg>&j]}hur5;;;;k4)ho&e6g...",
+"..g6#^/pbx|a[[[[/f}:/#>>g.....6>i2]4hur@++++]4)$o-qe6...",
+".gz>m/npfbnl[#[#l!x:{'(e6....gzqto=44_=@++++54uh7;[q6...",
+".g6em{|!!f{a[[[#/|xf{1#>6g...gzqjk}444w@+++-]}u$7ji#>g..",
+".gze^n!fff{1q#[#l|%:{^v(6g...6z#2=r4$4k2--+-]ruh72+[zg..",
+".g6e^n!!!p{&[[qq/|b:n^m(zg...g>#d=444r,2++--5}uh=2t[>g..",
+".g6(l|:!!p{'q##ql!%:|^1q6g...gz[]}h44r,*----]4uh}]j&>g..",
+".66e^|f!pp/&[[##/|%:|lmq6g...6>#dr44~r0*++--]}uh}]t&>g..",
+".66(mnpf!fn&[[##/|%:{mv(6g...6z[j=r44$=2++--5ru$=j+[>g..",
+".g6e1/n!:bn^[[[[lpbf{mq>6g...gzqjo=44_w@++++]}u47t&q6g..",
+".ggemln!:b9^[[#[l|%!/v(>g....gzqt]=4h_=@++++@ru4o+'e6...",
+".gg>#ml|:x!i['''/!%:/#e>6....g6e-j]}huy0+;;;54uh,-[ez...",
+"..g6([mp%}f/''1^{fx!/q>gg.....g>[+jy_)$,;;2274u4o&e6g...",
+"..g6e(v{%cfi'&&lnfc:/e>6g.....g6q&+7u)40;22@=4)h][e6g...",
+"...g>(#l!bp{a//{n|!/1e6g.......6e[-o4h~k@@0k7}47jq>6....",
+"...g6ze1/nn{<{n|n/l1#66g.......g6eqjo==7k=y}=kbj-z6g....",
+"....gz>q1l{npp!pn^#(e6g.........g>e&j]k=rr4472-'q>g.....",
+"....gg6(#mm^ll//^vq>6gg.........g66'-tjd]]]od+&q>gg.....",
+".....gg6e(##vvvvq(>6g............gg>q[--<<+<-[e6z.......",
+".......g666>>zz>z6g6...............g6>zeeeee>z6z........",
+"........ggg66zg66gg.................ggz6z>66zgg.........",
+"........................................................",
+"............g.g.........................g.g.............",
+"..........gg66g6gg....................g6>z666g..........",
+".........g6z>e>z6gg..................gzze#q>z6g.........",
+"........g6>(qe(e>zgg................g>e[&[[qe>6g........",
+".......g66vlnll^mv#eg..............g6>+]=5]2t+i[6.......",
+".......g6>^|%:|{/l^ve..............6>edruhr7k]d<#.......",
+".......66>{%8}%!nn/^q..............6zq7u3)u4}7]d&.......",
+"......g6>(/x8c!{/^mqe.............gze#ou3)4oodjiq.......",
+"......g6>({b8%|mmvve6.............g>e[7u3u}j9<iq>.......",
+"......g6een%8b/#q>>6g.............g>q[7u3_o-&qe>g.......",
+"......g6>(nb_:/qee6gg.............gzq[7u3ho&[qz6g.......",
+"......gz>(nb8:{q(>z6..............g>e'7u3hk&[e>z........",
+"......g6een%8b/qe>g6..............g>q[=u3ho&[e66........",
+"......g6een%8b/q>>zg..............gzq[7u3h5&qe>g........",
+"......66>enb8:/ee6gg..............zze[=u3ho[qzzg........",
+"......g6e(n%8:/q>>6...............g>qv7u3ho&qe6.........",
+".....g6>>enb_:/qe66..............g6eq[=u3$]&q>6.........",
+"......g6eqnx8b/(>>gg..............z>q&7u3hk[qe6g........",
+".....g6>eenb8b/qe>6g.............g6eq[=u3hk&qe6g........",
+".....g6>eqnx8b/qe>gg.............g>e[&7u3h0&[e6g........",
+".....gg>eq{%8b/(ee6g.............g6e[&=u3_o[[q>g........",
+".....gzzeqnx8:/(e>6g.............g>eq&cu3ho&q(zg........",
+".....gzee#{%sb{((>6g.............g>q[-=u3_k&[e>6........",
+".....6ge#mn:c!{&#q>6.............66[-97h)4k*-&e6........",
+".....g6qv^{f%!{^'q>zg............gz&<d=4u47];&qzg.......",
+".....ggqmln|f|{lm#e6g............g6&j]7}4}7]ji#>g.......",
+"......geqvm^/^mvqe66..............gq&<jdo]9{&q>6........",
+".......gze(q#qqee6g................6eqv&i&&q#>g.........",
+"........gg6g6gg6g...................g6666666g...........",
+".........gggggg......................ggg6gg.............",
+"...........ggggg.......................ggggg............",
+"........ggg6zgg6gg..................gg6z>zz66g..........",
+".......g6z>e(e>e>6gg...............g>>eq[q#qez6g........",
+".....gg6>eeqqqqqeezgg............g6>e[[&&&&&[q>6g.......",
+".....g6>##vv#v[[#q(>6g...........g6q&-++++++-&[qzg......",
+"....gz>m/n{ll^^^^^/1qg..........g>eto=7@]@22@]oj'6......",
+"...gg>el|%!|{{{{n||{v>g........g6e[]ru4}kk7k7}r7<eg.....",
+"...gzeq{bc%pn{nn|!b|m>g........g>q&7h)u4==7=r4h}jeg.....",
+"...g>qv{bc:|/l^l{|fnm>g........gq&+=h)$=55@]7}h=9e6.....",
+"...gev^|bcp{&&'m^np{m>g........6[+d}_u4k2**;]=r7teg.....",
+"..g6qm^|bx|l'[[#m/|{v6g.......gz&t]}hu}5;++-jo}7<>g.....",
+"..ggev^|bc!i[[##vm^me6g.......g6'+d}_u4@++a-+jd9'zg.....",
+"..g6e#m|:c!/[[#(####>g........g6[ij}h)45++-&-ii&eg......",
+"...g(#m|bc!i[[#q(e>6gg.........6[ij}h)40;+-&[qe>zg......",
+"...6e(v{!%p<a'[qee>zg..........6q[+74ur,@*+&[(ezz.......",
+"...g6e(/|f!n{a1(qe>6gg.........gz[&]}$r=,@*&&qe>gg......",
+"..g6zee^n|!!p{&#q>>66g........gz>q[2=r44r,*-&qe>6g......",
+"...g6>e'l{n9!{i'vq>>gg.........g>e[;@ky=~,0*+&qe6g......",
+"...66>e[1l{|f|</&[(e6g.........6>e[+j@kr~rw02+[q>6......",
+"...gz>(#['itpp9|/1q>>6g........gzq[-+;5w4~=y0*&qe6g.....",
+"..g6eeq['1lt|ppp{^'#e6g.......gzq[-+;*5wy~~~k@;-[z6.....",
+"...ge#m1&-{{{t9!p<{^#>6........6#-;*20,,kwy~~=,2-ez.....",
+"...6qv1ll{iii<pffp|/m>zg.......z&<2]@,500wr4~r}ktqzg....",
+"...6(m1i{{<{{tpf!f!<megg.......z'tj5k=wk,wr$$44=tqzg....",
+"...ge#m/np9||!f:ff!n'egg.......6qit]=ryyr~4$$44=tq6g....",
+"...ge(v/n!f!ff:f:!p{m>6........g#&<o}444$4hhh447tqz.....",
+"...g>(q^n!!!!p!!p||lv>g........ge[-d=4444444r}}o+e6.....",
+"....g>evm^lll/ll^^^v(6g.........6eq+9d]]d5]]]dd<'zg.....",
+".....g6>e(q(#q#qq((e6g...........6>e[v&&-&-&&[[(zg......",
+"......gg66>>>>>>66ggg.............g66zeeeeeezz6zg.......",
+"........gg.6gg6g6gg.................ggg6666zzgg.........",
+"..........gg6ggg......................gg6ggg............",
+"........g666>>>6gg..................6z>>eeezzg..........",
+"......g6z>e(qee(ezgg..............g6>e#[&[[[(>6g........",
+".....gg6eeq#####ee6gg............gz>q[&-----[qz6g.......",
+"....ggzqm1mmm11mvq(>g...........gzz&;jjtjjjj+&[e6.......",
+"....gz>m{pn/l//n/^m#>g..........g>q97~=o5ok=odtiqg......",
+"...g6>(/fx:p{n|!|{/mqg.........g6e[o4uhrk=}4r759v6......",
+"...g6e#nbc:|{||!|n/^q6.........g>#-=_)hr,=r4r=kd&6......",
+"...ge(vn:cfnl/{n{//mq6.........gq&{7h)47@o777o]9&>......",
+"...gevm|:c!/11lllllm(g.........6[+j}h)45*2@]o]]9'6......",
+"..g6qv^|:x|l'1mm^^^m(g........gz&<2}hur5;jjjdddt[g......",
+"..gg(#vnfxfn^a1mvv#(>g........g6[-t=hu4=@@*t+<i'eg......",
+"..g6>ev{fxf|</m#qeezg.........g6e[+74u$}k5j-a[qeg.......",
+"..g6>e#{!xbpn{m#ee6gg.........g>q[-k$u$4=5j-[qz6g.......",
+"..gzeqvn!x:f|{^#qe66g.........gzq&+k4uh~rk2-&qzzg.......",
+"..g6e#'n!%:f9{^mq>gg..........z>[-t=$uh4yk@t&q6g........",
+"..gzq[mnfx:!|{lm#(zgg.........g>&+j=$uh4r7]t-[>zg.......",
+".g66v^/|!:pn/^1[qez6g........g6z+20}4h~75@j+&q>6g.......",
+"..g>m/n|ppn/&'vqe>>ggg........ze9]=}rr=,2;+&[(e66g......",
+"..6>mnpp!9{&'[qq(>ez6g........zej=r~~y,2;+-&[qq>6g......",
+"..g>m/nppp{a[[[['1mveg........getorrrr,@++++;jj+[6......",
+"..g6vl{n!!{^'1'1l{n/v6g.......6>+]7}r4k@;***@k}o+>g.....",
+"..gzqml|p:n-''&l{!b|1>g.......g>&j]=4hk@;*2]74_rjeg.....",
+"...gq#m/n!n/&ll{{np{m6g........6[ito=~=02@@k7}}79zg.....",
+"...g>e#1/{{{/{{{n{{^q6g........ge[ijo=k,ok77777d&>g.....",
+"....66e#1ll{nnn|nlmv(gg.........6>#-j]]7===r=]j+[zg.....",
+"....g6gqvm^^///llmvq>6..........g66&+jd@]oo]]j<&e6......",
+".....g6>(q#vvvmmvq(egg...........g6e[&i++ttt{&[#6g......",
+".......gg6>>>e>>>6ggg..............g6>eeqqqeez6gg.......",
+"........ggg6g66666g.................gg66zz>>zzg.........",
+"...........gggggg.g....................gggggg.g.........",
+"..........g.g.........................g.g...............",
+"........g6g66gg.....................66zz66g.............",
+"......g66e>>e66gg.................g6>qe#q>zgg...........",
+"......g6e>((ee>6g.................g>qq[[[qe>6...........",
+".....g6>#[milmq>66...............g6q-+*@5t&ez6..........",
+".....66qvm{n!{1(e6gg.............6>&+jo}r,j[q>6g........",
+"....g6>v^l!%c!l((e6g............g6e+25~u)$5&[qzg........",
+"....g6z[^{p:cfn&[ezzg...........g>e+dk4h)4k2+[>>6.......",
+"....6z>'a{!:xfp{a[>z6g..........6>q;@krhusrk@+q>6g......",
+"....6>em^{|:b:!p{1(e6g..........zeqt2kr$_h4r,*[q>6......",
+"....g>>ml<|fbbf!n^[qe6g.........6eqt5ky4h$$$=@+&qzg.....",
+"...gzz(&/<9fffffp{im(>6g.......g>e[*5w=~$s4~rk5;&e>g....",
+"...gz>('/<9pfff!f9{/[e6g.......g>q[*0wy~~~$$~==5+qz6....",
+"...gzeq1/t|jffj:ppp{1(>6g......gzq&j5wyr~s~44~}7j&ezg...",
+"...g>e[a{|!!dfp!p!f|l'(zg......ge[+@ky~~4~~r~~4y];&eg...",
+"...g>q[^|!j::j!<!f:p{1#e6......zq&+@y~~ss~~wr$$4,j-qz...",
+"..g6e#&i9f:::f!<9:%!n^v(6g....gz#-*5=~sss~~w=sh4=2+[>g..",
+"..ggq'1n!b]xxdj!f!f!{^'ez.....g6&t2=~__uus~~~4h47@t[z...",
+"...6q1l!bcxccb:j::dp{lm(6......6&j]~huuuu_s~$$$r7]9'z...",
+"..g6qm/pbxcxcx:d!!p|{lmqz.....g>&jo~_uu)uuss~4r}7]t&>...",
+"...gq[1{!dbdbj|<{{llmvq>g......z[+*k~$$s$~ykw,]@j+&qg...",
+"...6>e#l{ppp!<{&1''[qe>6g......6e[-]kr~~4w52*;;+&[q6g...",
+"...g6>>'^{{n|i1#((e>>z6g.......g>eq;@kk==52-&'qqe>zg....",
+"....6ze[^i{{{^[e(>>z6g..........6eq+25ok=@+[[qqzzg......",
+"....g6zqm^a//1#e>zzggg..........g6z19d@o]j-qe>>6gg......",
+".....g6qvm^^lmq666g..............6>&+jdd]t&>z6g.........",
+".....gge(##vvqe6gg...............g6#'ii++&qzgg..........",
+".......g>e>e>>gg...................6eqqq#egg............",
+".........6ggg........................6ggg...............",
+"........................................................",
+"........................................................",
+"........gg6g6g6ggg..................gg666666gg..........",
+"......g6>>ee(e(e>6g...............g>e#q[[[[[qz6.........",
+".....ggeq#vvv'vvq(z6g............g6q&i++<t++&[>zg.......",
+".....6>(vm111m1^v#e6g............6e'<tj2jjjd<i#>6.......",
+"....gzevmll{{nnn{^v#>g..........6e#+joook==}kd+&eg......",
+"....6>q1/nnnn!fb|{mveg..........6q&j]===r4$hr7j+[g......",
+"....zeq^{|p!pbxcb|/m(6..........>q&d7r~4rhu)_}o9'z......",
+"....ge(v^/{n{|:bfn/m#6g.........6q[td]k=krhh$=oj&>g.....",
+"....6ze#m1aii<|f|n/1q6g.........ze#-;2@00w=$rk]j&6g.....",
+"...g6>e(#['1&i{|n{lm#gg........g6eq&-+;**0kyykoj-6g.....",
+"...gg>>#'1ai/|9fp{/1qzg........gzeq-;2@0,wy4rkoj&>g.....",
+"...g6>('a{{|t!fbfn/mqgg........gze[;@,,=y$$h$=oj&6g.....",
+"...g>>(m/n!f:bxx:|/mqzg........6>q[jo=4sshuuh}o9&>g.....",
+"..g6e([/|!!!f!f:|{^veg........g6q&+0=$4~~4$hrk2+[6......",
+"..ggev1<!%fp{nnn/1vq>g........gz[+j=$h4r=k==o2+&eg......",
+"..6z#1l!bxftii^1mvee6g........6>-*5r_)4w5@@2t{[#zg......",
+"..g>#l{!:x!{a&1'#q>6gg........gei]74hu4,@2*;-&q>6g......",
+"..6>'/n!:fnl1''[q(ezgg........6et]=4$hy5*;;+&[q>6g......",
+"..gzm{pp|!{&[##qe>>z6.........ze97~rrr,2+--&[qezz.......",
+"..g>m/np||{&[q##qqe>g.........geto}rr=k*+---&&[e6.......",
+"..gg#m/{|p{a'&&^^m^m(g........g6ij],r4,@;**22jdt'g......",
+"..66(#m{|p{^'1l/{{{l#g........z6'-jo}r7@;*]o777]i6......",
+"...geq[ln!{^'^/nn{|/#6.........zq&+]=4w@;@0===}oi6......",
+"...g6e(ml{/ial{n/{lm(g.........g>q&*]7o5@o7=77]j'g......",
+"....66>#'^l//{{n/^m#eg..........6>e-t2]oo777odjiqg......",
+"....ggze#'^/{{/{/m#(6g..........g6z[-;2o7o77]9iv>g......",
+".....g6>eq#vmm^mv#e>6............gzeq&i;tjjj<iqe6.......",
+"......gg6>eeqq((ee6...............g6>eq[&&v'qq>g........",
+"........gg66g666ggg.................g666zz>>6gg.........",
+"..........ggggggg.....................ggggggg...........",
+"........................................................",
+".......gg>>>ezg6gg.................g6eqeqe66gg..........",
+".......eq#vmmvq>6gg................q&i<9j+&#>6g.........",
+"......gqml//{^vqe>6gg.............g&9]5o7d+&qezgg.......",
+"......g#ml/{n/^[#e66g.............6&j]o7=]2+-[>>g.......",
+".....gg(vm^//{{/^'(>6g...........gg'{tdo7k7,2;[qzg......",
+".....ggz(#m^/{p!n&#(>6g..........g6e[-j25k}4=2-[e>g.....",
+".....gz>e(mm^n!:p/'#(6g..........gzeq[;j@74hr5;-[z6.....",
+".....66>eq['&/<!|nn^[ezg.........z>e[&+;25wrr==@+q>6....",
+"....g66eeq['&^{t|pf{^(z6........g6>q[&+;*@,wy~$=2[>6....",
+"....gg>>e([''aa{9fb!^q>6g.......gzeq[&+;;@@ky4h4]&q>g...",
+"....6zev^liii<<pf%c:/qe6g.......6>q+2@000wwr4_)h5&qzg...",
+"...g6>q^n!p||pffbx4b{[>>g......g>q&d=4rryr~$_u)_,+qe6...",
+"..gg>e#{!x:f!f:bxrsxn[e>6.....gge[-,4uh4~4shu)3u=+qe6...",
+"..g6(v1nf:f9+|9pdxrb{[e>gg....gz[+27$h4ywyy~$))u,+[e6g..",
+"..g6#^l|f:|{aii{|fc:{q(>6g....g>i2o}$hrk205,=$)hk-[e6g..",
+"..6>m/||f!na1''&/!%!i#(>gg....zeto}r4$k@****,4_4@-[#zg..",
+"..g>m/p|!!{&'''&+p%!{qe>gg....gejorr44k2;;;*,ru$o-qe6g..",
+"..g>m{|p|p{a['''/pxfi#ez6.....6e97}r}~,@+;;;5ru40-[z6...",
+"..g>m{p|||l&'[[[{9x!/qe6g.....6ej7rr}}52;+;+,ru$]&q>6...",
+"..g>vln|||{&[''&{!%!iq>zg.....ge<o==rr02+;**,4u40&q>g...",
+"..ggqmlnp!na'&&^{!%!l(>zg.....g6&t]=~$=@;*2@k4u4][e>g...",
+"..g6e(v/!b|l'&//|!b|1ezg......g6q&+o4h=0*25o=4hr2[z6....",
+"...g>(#l|!n/'li{{|!n1>6g.......6e[i]}$=5*@5k7r4=j#6g....",
+"...g6eevl{lill{{{/lmqz6g.......gzq[<]ko@]5k77o]9&zzg....",
+"....g6>(v1^///{{lm#(>gg.........g6e&+jdoooo7]j-[e6g.....",
+"....gggeq#1^//l/mv>66gg.........g66(&-jdo]ooj-q>>gg.....",
+".....gg6>(q#vvvvqez6g............gg>q[&-<++{&q>6g.......",
+".......g66>e>>e>>6gg...............g6>eqqqqqe66g........",
+".........ggg6g6ggg...................gg66666zg..........",
+"...........ggg.g.......................ggg.g............",
+"........................................................",
+"......g6>e>eee(e>e>>6g............gze(#[[[[[#qqezg......",
+".....g6eqvmmmvvmvvvq>6g..........g>[&+<tt<+t+++&qzg.....",
+"....g6e#m1^lll^l1^mmqe6g........g>#ij22]@]@]ddjt&#>g....",
+"....6>(m/n/{{//{l{l^vq>g........6e[9o=77oooooood<&e6....",
+"....g>q/!%f|nnnnn||n^vq>........6e&oru4r=====rr=d+&e....",
+"....>e#nb4xf||nn|!:|/m#e........e#i=u3u4ry==r4hr]jiq....",
+"....6e#|%4x:|||n||p|/m#>........zqi}u)uhy}y=}r4}o9iq....",
+"....g>(/!x:p<{/l///^mv(>........6ev74uh~wko@]oo]ji'e....",
+"....66(^|:p|{aa'vmm##(eg........zz[d}h~},@@;;tti^'q6....",
+"....66e1n!n{{l1#qq((ee>g........z>qj=4==k@*-&&&[[qe6....",
+"....g66v^/n9p{&q#eee>66.........g6>+do==r,2-a[qqe>6.....",
+".....66qv^{|:{^qqe>66g...........6>&<27rh72&&[ez6g......",
+".....g6>q#/|b|&qee>6g............g6(&+or_w@&[qe>z.......",
+"......g>e#ln!nl[qe>66.............geq-]7$7@+&[e66.......",
+"......ggzem{|n^1ve>6g.............g6e(j7}=@*+[e>g.......",
+".......66>m/|{l1vq>6g..............6>eto}7]j+&e>g.......",
+".......gz>qm^//{^#>zg..............g>e&j]]kk@-e>6.......",
+"........g6eqvln|/m>z6g..............g>q&+]7rote>6g......",
+"........g6zee1n:nm>>gg..............g6eq[2=h=*qe6g......",
+".........g6>emn!n/q(>g...............gzeqj=$=]-[eg......",
+".........g6>>m/!n/^veg...............gzeeto4y]d<#6......",
+"..........g6>vl|n//mq6................gze+]}=7]j&6......",
+"..........gg6qm///{lqg................gg>^9ooo7]&6......",
+"...........ggeqv^/{lvg.................g6q&<do7]i6......",
+"............gg>evl|/#6..................g6eq<]}ki6......",
+".............gg6qmlm(g...................g6>^9]jmg......",
+"...............ge(#(>......................gqvive.......",
+".................gg..........................gg.........",
+"........................................................",
+"........................................................",
+"........................................................",
+"...........ggggggg.....................ggg6ggg..........",
+".........ggg66z6g6gg.................g66z>z>666g........",
+".......ggze(qqq#eez6g..............g6>#[&&&-[qez6.......",
+"......g6>e#v11m1m#(ezgg...........g6eq-<jjjjt-[q>6g.....",
+".....gg6eqm^////l1qqe6g..........g6>#&t2ook5]j-&qz6.....",
+".....g6qm^ll////ii/1#>6g.........gz&j]]oo55o00oj-ez6....",
+"....gg>m{|n{l/il{np{1(z6........g6et7}=k@555k=~7j[>6....",
+"....gz>l|%p{laiinfx!iq>6g.......g>e]}_rk@@@@=4u45&q>g...",
+"....g6e/fx!{iiii<fx!l#e6g.......gzqo$u4k0000w4u$]&qz6...",
+"....g>e/:cf<^aaa|fx:{q>>6.......6e#oh)4k@@@@w$u4,-qez...",
+"....6>e{:}ftaaa&<fcf{[ez6g......6e[7h)sw@@@@,$uh,+qe6g..",
+"...gg>(lfx!9/{{{pb%:{[e>6g.....gze[]$u4w,0,,~su4,+[e>g..",
+"...gg>(l|:f!fjfd:]x!i'e>gg.....g6e[]}$$~~~4$s_u45+[e6g..",
+"...g6e(m/|fdbxcccxxf/[#>zg.....g>q[jor~s_uu)uuu$0+&q>g..",
+"...g6>em{n:%cxcccxbf+#(e6g.....g>e[j5}$_uuuuuu_~,+[q>g..",
+"...gz>(l{ff:xbb::bx!{'(>zg.....gzq[@=~4su__$$_u$,;&qz6..",
+"...gzee/pb]b%dfjfdx!{'#e66.....g>q[5~s___$~~~$u~,;&qz6..",
+"...gz>qipb:]bf9<p:bf{1#e6g.....g>q&5rh$_s~yw~$_4k*-[zg..",
+"...gze(/!xfp9<{i<9fp{&[(6g.....g>q&5$u$ryw,0k=$rk2+[>g..",
+"...g6zq/fxf<iia-/<!9{^m(>g.....gze&o4u~w00@@,w4rk@;&e6..",
+"...gz>q{:x!{''&'i<|n{^&qz6.....g>e&7hu4,****0,==k]j&>6..",
+"...gz>e/!cpia'&'in:!{^m(6g.....gzq[]4)r02**;5yh472;'zg..",
+"....6ze/!x!{&1&'ip%:{mv(gg......6>[o$u4,2**;0ruh7j+'6g..",
+"....66e/!%!/&''[/px:n1#e6.......z>q]4u~02*;+54uh=jiqz...",
+"....ggzm/|{/aa&&/n!n^#e6g.......g6>to}7o@@22574=di[>g...",
+"....gg6qm^ll/ll^///lve>6........gg>&9d@]0]@]5oo]<[e6....",
+"......g>e(m^l///l^mv(66g..........ge[&td]o]o]dj+[>6g....",
+"......ggz>qv1mmmm#v(>6g...........gzzq&+jt9jtii'e6g.....",
+".......g66>eq((((e>>.g.............gz>e#&''[[qqegg......",
+"...........6g6g6gggg..................g66>6>66gg........",
+"............gggggg......................gggggg..........",
+"..........gg6666ggg...................gg666zggg.........",
+"........gggg66666ggg................ggz6>>>>>z6g........",
+".......gg6eqv#vv#(e>gg.............g6>q&ii++-[qe6g......",
+"......g6z>#m^^^^1#q(z6g...........66>e-t@dddji&[e6g.....",
+".....g66eevl////l1[q(6gg.........g6>q[+@oooo]*+&[>6g....",
+"....g6zqm^ll///lll/^v(z6........gz>&t@]]o5o@5oo2+[e6....",
+"....g6>v{|{{/l^^/n|n1qe6g.......gzqtk==k55@@]=r=2&q>g...",
+"...g6z(^|:!nii&&{!:!lv(>g......gzz[drhr=5@22k~h4o+[q6...",
+"...g6>(lp:|{l^&1lnf|{'#e6g.....g6q[5rhr,@2**5=4rot-q6g..",
+"...gze(/pb|i&&''anpn/^'e6g.....g>q[o~_}52*;;@=r=o2t[>g..",
+"...g6e(l!b|i''''^/n|/^mqzg.....z>q&54_=0;;;;25}=k]j&z6..",
+"..g6>(#{!xpi'&'[a{||{l1qz6....g6e[-o4ur0**;;@kr=k]j&>6..",
+"...6z>q{fxp+'&''a{!|{l1q>g.....6eqak$uy,;**;@k~rk@j&eg..",
+"..g6eeq<:x!/'&1&i{!p{lmq6g....g6qq-kh)~,****0krr7]j&>6..",
+"...6ze#{:c:ti-ia{p:p{^vezg.....ze[a7$usw000@krh4k2+[>g..",
+"...6>>q<bc%dp|t|pfb!/m#e6g.....6eq-k_)_s~ywyr4h4oj-q6g..",
+"...gzeq{b}cbf::fbbx!{v(zg......g>q&kh)u_4s_4__u$k+[eg...",
+"...g6>q/fxx%b::p!ff|^qe6g......gzq&o$uu_hhs44$$}d&#>g...",
+"...g6>>^n!fbbf|{{{/^ve66.......gzeq2=44h_~},o7o]+[z6....",
+"....6>e'inpf:p+''mv#e>gg........6eq;5=~4hr,*;;+-#ezg....",
+"....gg>#1i|!b9{1'q(e>66g........g6eij5=4h=k*;-&qq>6g....",
+".....66(#'{t!|{i^[(e>ggg.........6>[-tky$rw52+&(e6gg....",
+".....g6>e(^nf!pni'(>zzg..........g6e[&d=44r=5;[q>>g.....",
+"......g6>>m/p|||{1qe6gg...........g6eq*or}r}o*&q>zg.....",
+".......66>qml/{n/1m#e6.............z>e^t]o7=o2;iq6......",
+"........gzeeqm^//llmeg..............gzq[&t2oo]]9[6......",
+".........gg6zqml^/lm#6...............gzze&9]]o]j&6......",
+"..........g66eqvvvvq>g................g6>q1<{<{&eg......",
+"...........ggg6>>e>6g..................gg6>e(qe>g.......",
+"..............ggg.g.......................6gggg.........",
+"........................................................",
+"........................................................",
+"........................................................",
+"........................................................",
+".............gggg........................gg6g...........",
+"...........gg6ee>g.....................g6z#qe6..........",
+"..........6>(#ml'#gg..................6q[ij]t&6g........",
+"..........>(v^{|/v6g..................e'+d7ro<z6........",
+".........geqv/|:n1>6g................g#&<orh=jez6.......",
+".........g>(vlp%|mez6................gevi]ru}jq>6.......",
+".........g6>(l|%|le>zg...............gzq'b}ur][e>6......",
+"........g66>e^px|lq>z6..............zz>e#]rur]&(>6......",
+"........ggz>(^|:|l'q>6g.............g6>q[d}$}5;&q66.....",
+"......ggzz>eem{!n/^v(z6...........gg>zeq[*747o2+&>6.....",
+"......g66>>((1l|{{l1qzgg..........gzzeq[[jo}=7]j&z6g....",
+".....g6ee##vvml//{/lv>6g.........66#[--++*]ook7]+e6g....",
+"....666qm1m111m^/{|/'>6gg.......6zz&tj**j*j257}ot#>6g...",
+"...g6z>v^/l^l&'[l{!{1(>6g......g>>q+2k5@]2;+@k47j[e6g...",
+"..g6>q#m/{i^m''#^{!n^q>6gg....g6q&-joo]2*;;+274=2&e>6g..",
+".ggzqm^l/{/&''[[a/!n1qe>6g...gzz&t2]ok52;;++@kr=2&qez6..",
+".gz>vl/{{{^1[[[v^{!n^q(>z6g..gze+]]kk7@*++++2k4=2-[q>zg.",
+".g6em{||n</&1''&{|:p<^m[qe>..g>[j7r}=k52***2,}hrk@t+&[e.",
+".geq/pb!|{{/^i{{|:%b!pnl^v(g.zq&o4h4y=k0@@,krhuh4r=o2+[6",
+"g6e#nbcb!{{{{npf:%cxxxb|/^#zg>qi=_)h~k7,k=r$hu)uuuhrodi>",
+".6e#/:xp{{/ii{n|!!::::p|/mqz.>q-7hu4=o55]k7}r4hhhh4}oj&z",
+".g>q^n!{^m1''m^1l/////l^1v(g.6e&d747@tj;tj2d]]oooo]dj<'6",
+".6>evl/m'(eee(e(qq#q#####qeg.zeqt]]j+&[[['[[^&i&iiiii&#g",
+".g6>qm1#(ee>>e>z>>e>e>e((e6..g>e19ji[qqeeqeeeq#eq(q''q>.",
+"..g6e(qe>66z6g6z6z666z66666...g>#'&[e>>>z6>z>zz>z>>z>>6.",
+"....g6zg66gggggggg6ggg6g........g>zz66gggggggg6gzg6g....",
+".......................g...........................g....",
+"........................................................",
+"........................................................",
+"..........g66gg.......................66>6g.............",
+"........g6>eqe6g....................g6e[&q>g............",
+".......ggz(#mq>gg..................g6>'it&q6g...........",
+".......6(qvm^vq6gg.................>[&+jd<'66g..........",
+"......gev1l/{^#>6gg...............g[<j]k72-ez6g.........",
+"......gvl{n||/'>>zgg..............gi]c7}}o;qe>6g........",
+"......g(^/n||/^vqe6gg.............g&d7=}}od+&qz6g.......",
+"......g(#ml/nn{/&#ezgg............g'i9]o==kk2-q>6g......",
+".......g>(ml/np!{1>>6g.............6evt]7=}47jqe66......",
+".......gg6#m/{!fn^#(>zg............g6>ijo74h=d-[q>6.....",
+".......g66(#m^/n/{/^#e>g...........g6>[itd]=kko2iqeg....",
+"........g6>(qvm^/n!{^q>6............66e[^+j2o74=2&qz....",
+"........gg6>e(#v/|:!/#(>g...........g6zeq[-<o}hroi[eg...",
+"........gg6zeeq#l|bp/ve6g...........ggzeq[&+]}h4]+[>g...",
+".........g6>eeq[l|:!/vq>g............66eq[&+@}_4o<&eg...",
+".........g66>e##^|:p/ve>g............g>zq[a-]}h4]+[eg...",
+"........gg>e(vml//n/mq>g............ggeq[+*]]7=o9&q6....",
+"........g6>e[^/n{lmmq>zg............g>([+2o=7]jt&q>g....",
+"........66(#vlnp{^qe>66.............6z[-+]=47d&'e6z.....",
+".......g6ev^{{/{^v(>zgg............6>q<d7777]+[e>6g.....",
+".......ze(^npn/mvee66g.............>#&d=47oj{[qzzg......",
+"......g>(v/!%p^(e>ggg.............ge&i74urd[qe6gg.......",
+"......g(v^/|p/m(zz6g..............g'<do}}o9[e>zg........",
+"......gq^{/llmq66gg...............g&d7ob]t&>zgg.........",
+".....ggv/|/m((e6g................gg<o}k9&'qzz...........",
+".......qm/m#(>ggg..................&j]9i'e6gg...........",
+".......>(vee6zg....................e'<[qz>g.............",
+"........gggggg......................g6gggg..............",
+"..........g...........................g.................",
+"........................................................",
+"........................................................",
+"........................................................",
+".........ggg6g6g6g...................gg666666g..........",
+".......gg6gz6z>z6g6gg..............g666>>>e>>666g.......",
+".....ggz>((q#####(e>6g...........gg>#[[&-----&#ezg......",
+".....g6eqmmm1^^l^m#(eggg........gg6[&ttjj2@b2t-&#6gg....",
+"...g66>qm^ll/{nn{l1vqzgg.......g6>e&t]]]o7==7]j+&e6g....",
+"..gg>e#m^llll{npn{l1vq(>g.....gge[-t2@]]]k=4=k]j+&[e6...",
+"..g6qml^l/^&1/p:pn{ll1v(6g....6>&9]]b5@2*or$4=,]]j+[zg..",
+".g6>mln{/l^'[/|bf|{{/l^#>6g..gzeto77k]2;+5}_4r=koodie>g.",
+"gg6e1{|{/l1'[/p%:p{{{{lv(>g.gg>#j7}75@j;+5ru$}kkkko<[e6.",
+".6e(^n|{1''#ql|bp{all//1#(eg.zq&d=}k2;;a-5}h4k@5]o@j-&qg",
+"g>e#l||{mqq##a|bp{1&/{/^1#ezgeq-]}roj----@=_}k*257k@ti[>",
+"g>e#/|!l'qqq#^n!|/&al//l^mq6ze[io}$];&&&&@=4r5*@55o]dj&z",
+"6eqvlpf{'q(qq'/|n{/{/ll//lv>6q&{5}$o;&&&&*o==koo5@]oo]<e",
+".e#m{|!l&(q(([^l{{|{ill{|nm>g#-97r$5*'&&[+2ok=yk5@@7y=9#",
+"6e#v/pf/1q(qe['1/{p|i&^{|n1(6qito}$k*&[&[+;25=~y52@xr=j[",
+".zev/|f{'#qeq(['lnp|{ll/n{vegeqior47*--[&&+;574}75]k77<q",
+".g>(lp:n^[#(((q#anf!nl//{/v>.6e'brh=2+-[[[&-@7$475@o7o<e",
+".6ge^|!{l'#q(e(qmn!!n{l//l#>.z6qd}47];--[[[&j=44=oooo]ie",
+".gg>v^{ll^1''#qq'l{{nn{l^v(g.g6e<do]]2*t;-&&;]77==7]2t'6",
+"..gge#vm^l^1^'#e#m1/{pnl##>6..gzqi<9d]djd;-[-;25=rybi&e6",
+"...gg>eqm//ll1[e(##m{!|^(>gg...g6eqij]o]]j+[&-ij74}d&ezg",
+"...ggg>(#vvvvq(ee((vm^^#>gg....gg6e[i<<<+&vqq[[ij]die6g.",
+".....g66eeeeeeee>>>e(qqe6g.......g6>(#[q[[#qeqeqv&&q6g..",
+".......gggg6g6z>6666gggg...........gg66666eez6>66zgg....",
+"..........ggggg6gggggg................gggg6zgggggg......",
+"...............g...........................g............",
+"........................................................",
+"........................................................",
+"........................................................",
+".........gg.g........................gg.g...............",
+"..ggg6g66g6g6g6ggg............gg666z66z6666ggg..........",
+".gg>>>ez6zzz>z6666gg.........g6eeqq>>>>>e>>>z66g........",
+".z>eeeq(ee>>e>e>>z6ggg.......>e[#[&[qqqqqqqee>z6gg......",
+"g>#vmm''['1^^^'[###(>6g.....gq-<tt;;;;*2@2;+---[qzg.....",
+"6qm^^/ll^i{||{ll111vq>6g....6&td]oo]@5k=}=o]2jj+&qzg....",
+"6#^/{{nn{{pf%fp/{/l^#e>g....>id]777=7krhu4roooodi#e6....",
+"g(vm^l^lal|f%!{^^11vqez6....6'<*2@@525=4u4k@2jj<&q>6....",
+"6ee#['&&1&{!bp{1''[#e>6g....zq[i+;**22k$h~k*;;+-[q>g....",
+"g>>ee(#[[&{fbpi[#q((e>6gg...6eeq[&-++*,~_r0;-&&[qe>6g...",
+">ev'''['1&<!x!/''[#qeee6g...e[+;;;+;*2k$ur,;;+-&[qq6g...",
+"(vll^''&1a<:%j<&'&[[q((6g...[<]o2***2@,4u~w2**;+-&[>g...",
+"(^np{l&a-ipfcf<a&'1'[#ee6...']7},@2@@@~hu4,@2**;+-[qz...",
+"em/{ll11^-p:cfna^11'v#(>g...q9o7]@*2@@ysu$=@2**;+-&e6...",
+"e#ml111^al|:xf<^&1[m[#(>g...#ij]jj*2@@~hu4,22j;t+i'eg...",
+"6(#vv['1&ln:x!{&&m'v##(>g...>vi<+;t*2@=hu$k22;;+i-[eg...",
+"g>eq#v['m&n!x!{1''##q(egg...ge[1-++;j*=$u4,*;;i-&[#zg...",
+".66>e((q['{!%|/##qee>>6g.....6>e#'&&+;,4u}]--&[qeezg....",
+"..gg66>ee(/|b|1q(>>6gg........g6>ze[[&o}_}2&[qe>6g......",
+"....66z>eelpb|1e(>>6g...........6zzeq[]}_=2[[ee66.......",
+".....g6>>(l|:n&(>>g6g............gzeq[]}h=2[qe6zg.......",
+".....g.>>>l|:n1(>>6g.............ggzeq@}_=j[qe6g........",
+"......g6>e^|bn1(ezgg..............g>eqdrhk2[q>zg........",
+"......gg6>^|%|lqe>6g..............g6zedrur@&[ezg........",
+".......gz>^|%|/vq>g................g>edrur5<&eg.........",
+".......gg61|%|/vq>g................g6>jru}]<&qg.........",
+"........g6vm{^v(e6g.................g6ij7d<&q6g.........",
+".........ge(q(e>6g...................gqv^&qe>g..........",
+"...........6g6gg......................g6666g............",
+"............gg.g........................gg.g............",
+"........................................................",
+"...........gg..........................gz...............",
+"........g6e(qeg.....................6zq'&#6.............",
+".......6>e#vm#>....................ze'i{j&e.............",
+".......ge(v^lme....................6#v<d]9v.............",
+".......6>em/|^(g...................6eq9orj&g............",
+".......g6em{!/#g...................gz#974kig............",
+".......ggem|:/vgg..................g6#j}ho<6g...........",
+".......gz6mn:{v6g..................g>>9=h7<6g...........",
+".......gzem|:/vgg..................gz#j}ho<66...........",
+".......6g>mn:{mzgg.................6ze9}$7t>gg..........",
+".......66>m|:/m66g.................6>ej}h79>6g..........",
+".......66e^{b{v>gg.................6>qj=h7<e6g..........",
+".......66em|:{m>6g.................6>qj}h7te>g..........",
+".......g6em|:nm>zg.................6>#j}h=tez6..........",
+".......66em|:{m>>6g................6>qj}h=jee6g.........",
+".......66>^nb{1>>6g................6>ed}h7*qe>g.........",
+".......g6>m|:{me>6g................g>ej}h7jqe>6.........",
+".......g6>^/:n1e>z6g...............g>ej7h=j[qz6g........",
+".......gg6mnp{^q(>gg...............g6>j=472&[(6g........",
+"........6zvl|{l^vezg................6>{]}7]2+[>6........",
+"........6g#m^//{l#e6g...............6z&9]o77]iq6g.......",
+".........geqv/|:{1>6g................6#&+]}h7jq>6.......",
+".........g6e(m/|/1#e6................g>q^joroj&qz.......",
+"..........g6e#m^1mvq>.................6z#&9dj9<&e.......",
+"...........gg>e(#mmv>..................g6eq'itj<q.......",
+"............gg6>(#m#e...................gz>e'i9i#.......",
+"..............gg6e(eg.....................g6z#'q6.......",
+".................gg..........................g6.........",
+"........................................................",
+"........................................................",
+"........................................................",
+"............g.ggg.g.....................g.ggg.g.........",
+"........ggg6g6gg66g6ggg.............gg666z666z666gg.....",
+".......gggz6z>>>>z>6z6gg...........gg6>>>eeee>e>>z6g....",
+"......g>eqqq#q#(#q##qqez6g........ge[&&&-&-&----&&[e6g..",
+".....ggqm^^^1^&^&&^&1'v(6g.......g6&t2d222222222*t+[>g..",
+"....g66v^{{{{{{{{{{{//1#>6g.....gz>+]7,7k,ko,7okk52-qzg.",
+"....g6>m{nn/{/{/{/{{<{{'ezg.....6>et7}77ook,okkkk=5;q>6.",
+"....66>^|!p{aiiaiii{||n1(>6g....6zqd=4=k@@@0@00,=~=j&e6g",
+"...gz>(l|bt{aaaaaiii9fp^#e6g...g>e[]r_y,@@@@@00,y4r@-q>g",
+"...gz>q/!:p{ai&iii+npdpaqe6g...6>q&]4hrw0@@0@00w~4~@-q>6",
+"..g6>(#/p:!9n<<<<<<9f:fi#ez6..g6e[a,~$~=,w,wwwwy~s4@-[>z",
+"..g6>([{|f!p!|9p!f!j::p+[>>g..g6q&+5r$~~~yyy~~~~ss~0+qe6",
+"..g6(v'{!:dfjf!jfjf:fd!/[(>6..gz[+;k~4s~~~~~~~~s$$4,+[ez",
+"..g>v^{np!p!!!f!fd:::!pl&q>6..6e+]7}~~~~~~~~~s$444r5*-(z",
+"..gzmnp!!!jppj9ffd:d!f9i1[(6..gej74~4~~}~~~~~sss~~y@*+[z",
+"..6>^|f!p!9!!p!jf:bd!9{l1v(g..zed}44~~y~~y~~~$ss~yk5j+[z",
+"..6zv^{n9p9|99p9!dxdf<{&[(e6..6>+dk==~yy=yyy~sus~w,2+&#6",
+"..gge#'ltp9||<|9fbcb!i&'q>6g..g6[i;5w~=yywyy48u_~52;&q6g",
+"...6zeq&{p|<t<t<f:cb9/'#e>gg...zzq&2k~ywwwww~$)sy0;-qe6g",
+"...gz>(l|f9<n{/+t!ffn/1#ezg....z>q[@=syww,,,wr$4=52-q>g.",
+"...gg>(a|bp<i+ii{<9n{/^#>6g....g6e[@~4~w0000,wy=k]2-q>g.",
+"...gz>>l|b|/-iaaii{///lv>g.....gzeq]rh=,00@@0@,oko]+eg..",
+"....66e^|!9{iaaa&^&111v(6g......z>(2=$y,0@@@@222jj+[>g..",
+"....g6>1{!n{{/il1'v##qe>g.......g>ej74=k,0@@2;+--&[eg...",
+".....66vl{n{{{la^[e(>66g.........zz<]==kkk5@2+[[#>6g....",
+".....g6#^l{{|n{l1#e>z6g..........g>-jo7=r=ko*-qez>6.....",
+".....g6eq'/|fn{l1#>66g...........g6#&;]}4}o]j-ezzg......",
+"......g6eelp%fnl'(>gg.............g>q']ru$=]t&e6g.......",
+"......gg6em/n{^'#e66..............gg>q9o}7dt-qz6........",
+".......ggz(vmmq(e6g................g6>v{jti[q>g.........",
+".........g6z>>z6gg...................6z>eezz6g..........",
+"........................................................",
+"........................................................",
+"...............g.g.........................g.g..........",
+".............gg>ze>>g....................g6eeqqe6.......",
+"...........gg>>(qqvq>g.................g6eq[&&+&eg......",
+".........gg6ze(qvmmveg...............g66>q[&<9j<[6......",
+"......gggz6>>q'^^^lm(6g...........gg6>>eq&;22d]t'6g.....",
+"....gg6gz>>>('l/{//1#6g.........gg66>eeq[;]oko]j->6.....",
+"...gg6z>>e(qq1{pn{l1#>66.......gg>>eqq[&&*kr=7oj-ez6....",
+"..g6e#'m'1''1l{p|nn/mezg......6>[it;;*;**57rr==otq>6....",
+".6z(m/n{{n{//{<pp!fn1(z6g....6z'9o====kookwy~44=2[>6g...",
+".6e#/!%:::!p9|nnp:bpl(>6g....>#io4uh$h4~y==wrh_4@&e>g...",
+".6>q^|f!::!f!p|<p!bpl#(6g....ze&d}44hh4~~~=wrrh}]-[>6...",
+".66>v^/n|!fpp9<{|np|l1#e6....zzq<do=}444~y=,w}~}ojiq6...",
+"..g6eqvln|!!f9{-{<n{/l1q6g....gzq&<]=r~~4yk0kk=ko]j&zg..",
+"..g6zeqm/np!:|{ail////m#6g....gzeq&jo=}4syw@55koo]ji>g..",
+"...gg>evm^nj:p/1&11^l/lv>6g....g6eq+j@=~h}5***j2]o]+#zg.",
+"...ggg>eq[/pb|i[[[#v^/lm(>g....gg6e[&+]~hr0+++-;do]t'eg.",
+"....ggz>>ql|:nl[#((#m/lv(>g.....g6>eq&]rh}@+-&[ij]]{'e6.",
+".....g6z>>m{nnl1'#((#vq(>g.......g6zeqto}=]2;-[[/<&'e6..",
+"......g6z>v^//{/^[>ee>>6g.........gz>e+2oookd+qqq#e>g...",
+".......gg6e#^^/{lve>6zgg...........g6z'+2]ok]+qe>z6g....",
+"........g6ee#ml/lv#(>6g.............g6q[ij]o]t-'ezg.....",
+".........g6>emm/lmm#egg..............g6e({jo]jti#6g.....",
+"..........gggqm/l^m#e6g...............gz6&jo]djiq6g.....",
+"...........gg>#vvmmv(g.................gge&<<99{'z......",
+"............gg>eq#m#(>g.................g6eq&i9ive6.....",
+"...............ge(v#(66...................ggq'<i'>6.....",
+"................ge(e>6......................6q[qez......",
+".................6ggg........................z66g.......",
+"........................................................",
+"........................................................",
+"...........gggggg......................gggggg...........",
+"........ggggggg6gg..................g6g6666>6g..........",
+".......6eqee>(vm#e6g...............z#&qqe[+9i[zg........",
+"......ge#m#qev^{^q>6g.............6#iti&q+d72&e>g.......",
+".....g6qm^mqq1{|/me66g...........g6&t];-&*7}otqz>g......",
+"....g66vl{l'qln:{1ee>gg.........66><]7];-@=h=*[qe6g.....",
+"...g66>mnp{^[lnb|a#>>6gg.......gz>(j=472+5}hr@-qez6g....",
+"...g6>e^|:ni1{!b|iqqe>6g.......gze#d}h=5*k4_r@-&qezg....",
+".g6z>ee/|:ni1{!xp+[q(>z6g....g>>eq[5rh=@*kru~0+-[qe6g...",
+".g>e>eq/!:p/at!xp{'[qeegg....6eqq[&]rhr,@w~uy,;+&qq6g...",
+"g6e((eq/p:9/a<fx!+'[(eezgg..g>[[[[&5~hy,@wsu~,*+&[qe6g..",
+"6(v111mnfxft/!dx:<i&&[q(zg..z[<jj*j=4u~,,~sus,02*+&[>g..",
+"6#l{/llpbxf!tf%}%p/ia1&(>6g.6i]7o55r_us~w~_)_~,0@2*&qzg.",
+">mn||n|!bcbfpdxcx:9t{{^vezg.ej=r}==4_)h4rsu)u4www5]+#>g.",
+"6v^////!:x:f<!%xd!{{i^1q>6g.6<dooo]~hus~w~_us~k,52j&q>g.",
+"ge#vmmmndbp<+9:x:9i^&'#ez6..gqi<ttj=$_4w,y4usy@@2;-[z6..",
+".gg>>(q/pb9{a<pdp<a1#qe>gg...g6eq[&o4hy,@w~s~k@*-&qezg..",
+".ggg>>(lpbn-1i9f9{a'[(>66g...gg6e#&]rh=@*0y~y,@*+[q>6g..",
+"..g6ze>l|:ni&a{|n{/^[(e6g.....g6zq(]rhy0*0kr==]@+[q>6...",
+"...g66e^|:{^[^i{{<ni'e>z6......gzzqd}h7@+25,kk=@;[ezz...",
+"....g6>^{:{^['&l/{nl'e>6g.......g>ed=$72+;2@,7=o;[e>g...",
+"....g66mn:{m##''^{|{1qezg.......gzzj=h7j--;t@7r7*&qz6...",
+".....gzmn!/mqqqqm{|n^(e>6g.......g>j=4oj&&&&j,}=2&qe6g..",
+".....g6m{!/meee(vl|{^#e>gg.......gz974ot[[[[{]r7d-[e6g..",
+"......gvl|^#>>>>qmmm1m#(6g........g<]}d-eeee&tjjj;i[>6..",
+".......#^{mq>6>6>(q#m^mq>6........gid79&eze>e[&itd9&e6..",
+".......(mlv(6g6g66ze#^mqegg........v9]<vz666zz>#idj&#6g.",
+".......>(#(66gggggg>eqqe6g.........e'i[>6ggggg6e#&&#6g..",
+"........g66g....g.gg6>6g............666g....g.gg>e>6....",
+"........................................................",
+"........................................................",
+"...........ggg.........................ggg..............",
+"........gg6>>>6gg...................gg>eqezgg...........",
+".......gg6ev^#(ggg.................g66[<di[66g..........",
+".....gg66>m/nlv>6g6g.............g6z>eto=]+ez66g........",
+"....g6z>>em{!/meez6gg...........g6>eeqj=rktq#>>6g.......",
+"...g66>>eql|:{&qee>6gg.........6>zeq[&]}h=2&[qez6g......",
+"..66>eeqqq/pb|^(qeeezgg.......66eq[&&a5rh}@&&[qq>6g.....",
+".g6>e###['{p%p/'[qq(ez6g.....6ze[---+;k4u}5;+--[qe6g....",
+"gz>q1/{{i^|:c!{aa/i1mqe6....g>e&*o,,0@=hu$,@@002t&[z....",
+"g>(v/f:p|{pb}bp{{|p{lm#>g...ge&+k4hr=wrh)hr,7=r=]tiqg...",
+"6e(1|b}bpt:%cbf<pp:!{^vqg...>q&j=u)h~w$_)_~wr4h47d<[6...",
+"ge([n:%!<{9%cdp/<|!|{^m(g...6q&+=hu4w,~_)sr5krrr7dt'6...",
+"6e(#n:%!{i9fxf<a/n|n/^me6...6q[+7hu~k@=$u4w@,=r=odt[6...",
+"g>(#{!%9i&|fxf{'a{|n/^m(g...6e[-k4_y02w4u~k*@,}=odt'6...",
+"6>eq{fxp{a9bcf<i{n!n/^m(6...6e[ak$uyw0=su$,5,=4=kdt'6...",
+"6>eq{f%dn{!bcbp{npf|{^v(g...zeq-ohu$=w~_)h~,=r4r7d<'6...",
+"g>>({:x:ptfx}bf{pf:!{^v(6...6eq&khu$r=$u)_4=r$hr=d+v6...",
+"gz>e^n!|{/p:cf|/{{!n/mveg...g>e[@}$}k5~hu$}57=4=oj+#g...",
+"g6>em/nl^&nfxf{1l///mv(>g...g6e(t5752*7$u4k*@]7oj<&eg...",
+".g6>(v1[[#l!bn^[v1^^vv(z.....6ze&<j++-]4_}@+<jdjtive....",
+".gg6eqv#((l|:|^qqvv#q(>z.....g6zq&+-&&]}h}2&-+ti&'ez....",
+"..gg>>e(((lpb{^qeq((e6g.......ggeq[[[']r_72&[&v'q>z.....",
+"....g66z>e^nb{mee>6gg...........g6z>e(d}_7jq(e>66.......",
+".....gg66>m{!{vz6z6g.............g6>>e9747<ez>6g........",
+".......666v/|l#>6gg................z6z<]}b-ez6g.........",
+"........gg#m{m#g6g..................ggij7j&66g..........",
+"..........(v^veg.g...................g'<d<#g.g..........",
+"..........6eqeg.......................z#&qz.............",
+"...........ggg.........................g6g..............",
+"........................................................",
+"........................................................",
+"...............gggggg......................gggggg.......",
+".............g6>>>666gg..................gzqqez>z6g.....",
+"............g>(#qe(e>66g................ge'i&[[#ez>g....",
+"............ge#mm#q((eeg................6#ijt-&&[#q6....",
+"...........6g#1/l1[##(e6g..............z6&jk]j+--&qzg...",
+"..........g6>v/pn/1'[#q>g.............g>e+or752;+-&eg...",
+"..........66>mnf|n^^1'q>g.............6zej7hrk@@jt&#6...",
+".........g6>>^n:!|{/1'qe6............g6eq2=h4}k5j;&q6...",
+".........gg>em{p||n{^#e>g............gze[j,rrr=k2-[e6...",
+".........gze('ln9!fn^#e66............zzq[;5==r4=@-q>6...",
+"........g6>(#&l<9pf|&#ez6g..........gzq[-25wy~$=2-qe6g..",
+"........gge#m/n!!ffn^[e>gg..........g6q-t5=~~~4=@+[e6g..",
+"........g6e'^{pdfp!<l[qegg..........g6[;2krs44~=]+&q6g..",
+"........66q'l{!%ffp{i'qezg..........6>&;d=4_$~rw@;&[>g..",
+".......g66e[1{pbf!9{l'[e6g.........g6z[+*,rh4~=w5;+[>6..",
+".......g6>eq[{!bdp<<i1[q>6.........g>eq-+k~_s~wk5*+&e6..",
+"......g66z(([a9::!n{i1'qz6g.......gz>e[&+@yh4~=,52;&e6g.",
+".....6g6>e(q#/|bfj!n{l1#egg......6zzeq[&-5yhs~~=,]*-q6g.",
+"...gg6z>>e(q[-<f:!f!<{^#e6g....gg6>eqq&-+@w$44~~=k@-#zg.",
+"...gg6>z(eqq[it!ffd!9{iv>6g....gz>ee[[&-+0w~$$sryk5+qzg.",
+".g6>(q#[''&aln|!f!!pn/1#z6g..g>e[&-+;;2@@=y4~~$~=]j-e>g.",
+".g>evml^l/{{p|9|p!!|l^[qz6g..6e[+j@]@@k=r~y}~~4=52+&z6g.",
+".z(q1/{{{n|!:f!9p||n^[(e6g...z[&jo777=}$h44=rrr=@+&q>6..",
+".6>(v^////{nn{/li/{i^1#e66...ze'<doooo7777o555o52j-[6z..",
+".g6ev1lllll^^m&m'1'1^mm(zg...6>q+j]]]]@2dj*t;j;j2jt&zg..",
+".g66qmm1mmv(e(e(eee(1l1#g....g6>&tjjjj+&[[[[q[[&j]j&z...",
+"..gge#vvv[q(e>>>ez>e#vveg.....g6'&+<<+&[qe(eqee[i<<qg...",
+"...g6>ee((>>6z6g6z6zee>6.......g>e[q[[qe>>zz>>6>q[e>....",
+".....ggg6666g6g6gggg.g...........gg66666zzg6gggg.g......",
+"........................................................",
+"........................................................",
+"...........gggg........................gggg.............",
+".........g6>e>>6gg...................gzq[qez6g..........",
+".......g6ge#vvq(>6g................g66#i<+&[ezg.........",
+"......ggz>#mlmvq(>gg..............g6>ei9]j+&[e6g........",
+"....gg6z>>m/n/1qe>z6g...........g6>>eq;o=oja[e>zg.......",
+"...g6>>>qe^|:n1#eee6g6.........g6eeq[[2}h=2-[[q>66......",
+"..gg6eeeq#/px|/qq(eezgg.......g6>q[[&-]4ur5-&[[q>6g.....",
+".g6>#1l^11nbc:na&'[#qe>6.....gzeij]2*2}h)h7@**+-&[qz....",
+".geq^n!n{{f%rbp{{/l^1mqeg....6q&d=4}kk$u)h4,k5]d*<&#g...",
+".>evn:xb!|bc4xbj||{{l^meg....e[+=huh4r_))uh~r==7]dt[6...",
+"g6eqnbx:p|f%cx:ppnn/lmveg...g>#i=_uhr=4u)uh~r==o]j<#g...",
+".6eq/f%!{in!b!!p|{ll1vq>g....zq&74u4k0=~s$~~yw5]j+&qg...",
+".6>(/!%n/'-<|9nt{{^mv(>6.....ze']4u=o*0ky==wko2j+[q6....",
+"g66(/!:ni1a/{t|9{i1'q(>6....g>>'o4h=@*@5kwy=k52;&[ez....",
+".66el!:n^&&ai{9!{^'#e>66.....6z[]4$=@*2@0ky~7@;-[e>z....",
+".66e^|!ni'&'&/|:|a#q>>6g.....6>qd}$=0*2**,}h=@-&qe6g....",
+".66e^|!na1&'&/n:na#(ez6g.....6>qd}4k@*2**0=h=@-[q>>g....",
+".g6>m/|/{/aa&{n!nl[q>>gg.....g6q9o}7o0@@2k=~=]+&qe6g....",
+".g66v^/{{{{/l{nn{1'#(6zg.....g6><do7kk,05,=},2;-[z>g....",
+"..g6q^l/nn{{i{{n/^'v(>gg......gz&j]o=}7k5kk7]];+[e66....",
+"..g6eqv/|fnn/i^1^/l^mqezg.....gz'i{o}4}7]5@d2]]dt&#>g...",
+"...g6eqlpb!n/^m[mlnl^m#>g......g>q&orh4=o2t+j]=o2tiqg...",
+"....66>l|%pn/m#ev^n{lm#eg.......6>e]ru4=oj-[+]=7]9iqg...",
+"....ggzv^{lmm#(>qv^mmvq>g.......g6>i]7bjt-'e&<djt+&q6...",
+".....ggz###((e>6ze(qqq(>g........g6e&iiv'qezeq[^&&'eg...",
+".......gg6g6gg6z6gg6eeezg..........6g>6666zz6z66#v#>g...",
+".........gggg6gggggg6>6g.............gggg6gggggg>ezg....",
+"....................ggg.........................ggg.....",
+"........................................................",
+"........................................................",
+"........................................................",
+"........................................................",
+"......gg6g6g6g6g6ggg..............g66666666666gg........",
+"....gg66z6>>z>z6z666gg..........g666>>ee>e>>>z>z6g......",
+"...g6z>>>e>>>>>e>e>>z6g........g6>qeqqeqeqqqeqee>zg.....",
+"..gg(v1'#(#e(ee>q#'v#e>6......g6[+j;-&&[[q[q&-;+-[qz....",
+"..g>vl{/&'[qqeqq[1/^m#q>g.....ge<]752;+&&[&&+jo]ti&eg...",
+".gg>^np{^&'[q#(('/n{l1#>6....gze2=47@*;+&-&&*5=7]j-q6...",
+".g6>^|!ni''[(###&lnnlmv(g....g6qd}4=@*;+&---*5==]j<[6...",
+".gz>^|!nl'[[##qq&lnn/^m(6g...gz#d}4=@*++-a&-*@==]2t'zg..",
+".g6e^|!{^&[[##q#'/{n/^mqzg...g>qd}4,@*++----*o=7,dt&>g..",
+".g6e^|!na[[q####1/n{/^1q6g...gz#d}$7@;+--a--*5==k@j&>g..",
+".g6(^|fn^&[#qq##'i|n{lmqzg...g>[]}4=@*+a&&--*5=7o@j&z6..",
+".66e^|!<a[[qq#q#'/n{/lmqzg...6zqd}4k@;+-&a&-*,==o]ja>g..",
+".6ze^|!n^&[[qqq#&i|n{l1q6g...z>[d}4k@*++&-&-*5y=5]j&zg..",
+".g6e^|f{a[[qqqqq1in{/^1q>g...g>q]}$k2;+-'&-a*5==o@j&e6..",
+".g6e^|!{^[[#q(qq&/|n{l1q66...g>qd}4k@;+-&&&a*,y=k]j&>6..",
+".g6e^|fni&&[[['[a{|n{^m#6g...g>q]}4=@2*;++;+@,}=k]*&>g..",
+".g6e^|!|{l-a&&&^/nf|{l1qzg...g6qd}$},0@@*222o=4r7@j&>6..",
+".g6>^|f||{{/{//{n!:!nlmqzg...g>ed}$r==k,o5ok=4h47]t&>g..",
+"..g>mn!pn{//lllln|!p{lmq6g....6ej=4r=ko555]5=r4rk]t&zg..",
+"..g>mn|{l^11m'1&l{pn/1m(gg....6ej=r752j*tt**@7r=o2t'6g..",
+"..gzm/|/1[#(qeq('^n//mm(6.....g>9or]j+-&&[&&;]=7ojtvz...",
+"...6vl{^v(((e>ee#mll1m#eg......6<]7d+&[[qqq[-j]]jjiqg...",
+"...ge#v#ee>>z>>e(#vv#ve>g......gqi<i[qeeeeeq[-{+ii[eg...",
+"....g>>>666zz66zz>ee>>>.........6eqezz>zz>zz>q(#qeeg....",
+"......ggggggggg6g6666g6...........gggggggggz66>6>z6.....",
+"........g.g......ggg................g.g......ggg........",
+"........................................................",
+"........................................................",
+"........................................................",
+".......gggggggggg..................gggg6ggggg...........",
+".....ggg666z66ggg6ggg............gg6>>>>>z66666gg.......",
+"....g6>>>>>ee>e>>z6gg6g.........6>eeeeeq#eqee>z666g.....",
+"...gze(ee(ee((e(>>e>z6zg.......g>q[[[[[[&[[[qq#e>>z6....",
+"...6>#[[[[[[[#[##qqq(e>66g.....6q-+++++++-+---&&[[ez6g..",
+"...6#l{{{{/iaa-iiii^&^mq>6g....>-]7k,,0@@@00@@5@22t&#zg.",
+"..g>^nf!ff|n{nn9||||n{lmq>6...ged=h4$$~w,k=yy}}}=7o9&#6.",
+"..g>^|b:bbf!n9!f!!!!||{1qeg...ged}hhh_4~=y~$~444r}7j&q6.",
+"..g6v^{n!!p!9p!:pn{//l^ve>6...gz<d7}r4r~y4~4r=k5o]di#e6.",
+"...geqvl{99pp!ff9{1mmvvq6g.....g#1<]7=y~~r~s=,2*jt+&>g..",
+"...gg>evl{|<|j::|i'###q>gg.....g6e(;5k==y~4_y@;---&e6g..",
+"....66>#'^i{{9!bpi[#qee6g.......z>e&t255ky$hr0+-&[#zg...",
+"....gg6e([''&npb|i[(e>>gg.......gz>q&+;*2,~_r5+&[qezg...",
+".....g66>e([[{9%pl((ezzg.........g6>eq&++krhr@&[qz>g....",
+"......g66eeq#^p:naqee66g..........g6>q[&-@rh=@&[q>6g....",
+".......g66>eq1n:n^(e>zg............g6>e[&2=hk2&qqzz.....",
+"........g6>>(1{p{&ee>6g.............gzee[j747*[qe6g.....",
+".........g6z>[/|{1#eezg..............g>zq;]}7*-[q>6.....",
+"..........gz>vl{l^[q>66...............g>e+]7]2+&qz6.....",
+"..........g66qm/lmm#(6g...............g6>^j]]jj-[66.....",
+"...........ggevm1^^mqe6g...............g6#+jj2dt&#zg....",
+"............6>(#v^l^vqe6................6e[i<2od<&#>....",
+".............ggz#^{lm#(6.................g6>id7]jivz....",
+".............g6g(ml^mq(z.................g66vt]dt&'>....",
+"..............g6>(#v((e6..................g6e'ii&v#z....",
+"................gg6>>>>6....................g6>eeeez....",
+"..................gg66gg......................gg>z6g....",
+"....................g6g.........................gzg.....",
+"........................................................",
+"........................................................",
+"........................................................",
+".........gg6g66gzg66ggg..............6g66z66z6z66gg.....",
+".......g66>#v((>(q##(>6g...........g6z#&+&[e[&i-&qzg....",
+"......gg>evm/1#>#^l^1v(>g.........g6e#+joj-qi2odji&eg...",
+"......g6eq^n!/1qm{pnl1#>g.........g>q&d=4oj&*or}ojiq6...",
+".....66eeql|f{1#m{!|{^'(zg.......6>q[&]}4=*-j74}od;[>g..",
+"....gz>(q#lnbn^#^{|n{^mq6g......6>#[&i]}_=@-2kr=kdt&z6..",
+"....ze(qqv/|%ni'1{|n{lm#>6g.....>qv&-<oru}5;*k}=,]j-ezg.",
+"....6(#vvm{f%!/'/{p|n{^ve6g.....>[i-+t74u45*5k~==k@+[zg.",
+"....eqvm^^|:xf|i{p!!|{{m#e6.....q&{j2]}hu4y5kr$$y=oj-#>.",
+"....e#ml/np%x:!<|fb:fp|lvq>g....#ij]]=4u)h~ky4sh44y]{&eg",
+"....e#mll{pbcbp{9!::!!nl'q>....gqi9]ox4h)h4ky4$h44=];&e.",
+"....6eq#m^n:xf|l<9!fpn/mqe6.....>q&itd=hu4y5ky4$}=oj&q>.",
+"....gg>e(#/!%p/&/n!|n/lve66.....g6qq&io4ur,*,k~=yo]+'>6.",
+".....6g>eel|%pi&a{9|{l^#>6g......66eq[]}u}5*@ky=k52-e>g.",
+".....g66e(lp:|l[a{pn{/^#>6g......gz>q[]rhr5;@kryk5d-e6g.",
+"......g6e>l|%|/[^{9|{im#>gg.......gzqq]}u}5+2k=rk5jie6g.",
+"......g6zel|bni[a/|n{l1q>6.......ggze(]}h}@;@,y=k@j&ez..",
+"......gg>>^|%|i[&{|{{/m#6g........gzeqdrur0+2,}=k5j-z6..",
+"......g66e^|b|l'&{9n/l1qz6........g6>qd}hr@;2,==o]j&>6..",
+".......66>^nb|l[&{n|{^mq6g.........6zed}hr@+*k}=,@j&>g..",
+".......g6>^|%|{&lnpn{l1qzg.........g>edrur,25=~}7]j&>g..",
+".......gg>^!%!nl{pf|{lme6g.........g6e24u475kr$r7]t[>g..",
+".......g66^px:|{n!:!{^m(6..........gz>d4uhr7=rh47dt'6...",
+"........ggv/|{l^//|{lm#eg...........g6<o}7]2o7=7]j-q6...",
+"........gg(m^mvqm^l^mvq>g...........ggv9dj{-td]29+&eg...",
+".........gg>eeez(qvvq(>6.............g6eq#(e[&{+^'q6....",
+"..........gg6666eeqee>>g..............g6>z>>q[&[qeeg....",
+"...........g6gggg6>>6gg................gzgg66>eezzg.....",
+".................g.g.........................g.g........",
+"........................................................",
+"........................................................",
+"...g6>>>e>>6gzg6g6ggg..........gzeqqqeez6z6666ggg.......",
+"..6>qm1m##q(>>eee>6gggg.......ze&;j;+-&[eq#[qq>66gg.....",
+".6>em/{/l1[q(qq#q(eez6g6g....ze[jo7]]*+&[&&-&[q#ez66g...",
+".6eql|!n{l1[(#vm'v((e>zggg...z#^]}4}752+&-+;;+&[qe>66g..",
+".g>(m/|{{/^i&^^il//^^mv#(>6..6e'jor7k5@@2@@5]5o]2;<-'q6.",
+".g6evl////{{{<{{{|fpn{/1m#>g.g>q{]o]o5k,7k7k=r$r=7]jti#g",
+".g6>#m^l/i{!!!|pfbxxf!|{l1(6.g>e-;d@55k~44}}4huuh4r7]j'6",
+"..z6qv'^i{||!|{{|!::!nn/mveg..z>&+*@5k==rrkk}$hh4}7oj{qg",
+".g66e#'&/{tn!n/&{|!!n{lmvqzg.gzz#-;25wwrrk52k=4r=7bj+^eg",
+"..gz>e[1+nn|9/a[1{nn{lmve>6g..6>q[-2,=y=yk@+2k==7]ji[e>g",
+"..6zeq[^{|9n|/1[1^////^v>>g...6zq&+@7=y==5*+*@ko552+qez.",
+"..66(v1/n!||{i1q[m^1/llvez6g..z>&+j0=~yyk5*-+t22o]]+q>6g",
+"..6zq'^{|!pn{l&q##[ml{lme6g...6>&;2kr4~==5*a-a+j@7ot[>6.",
+"..66#^/{9|9|{a'q((qml{/mez6...zzi@okyry=k@;&&&&;]=]tqzz.",
+"..g>1{pn{/{{{^'qq((m/|{m(6g...gej7r=,5kkk@;&&&&;or=j[66.",
+"..6>lpf|i&^l{^'qq((m/!|1e66...zq]rh}5*@]72;&&[[t7rrj[z6.",
+"..g>^p:{1'&/{a[(((qm{!|^e6g...gedrh72;2o72+&[&&;74rd[>g.",
+"..gg#^/mv#^n|/'q(qqm/fp1(zg...g6idoj<-2k}k;&[&&t74~j'>g.",
+"...geqv#qq^nf{1(qeqm{f|^egg....6q&i-&&d=47*&&[&97$rd(zg.",
+"....gze>>e^|!n&####^/!|^e6g.....6eqq([2}4=*--a-2x4}d#6g.",
+"....ggzz>>m/|n/^//{{||/v>g......g6z>eq9or=o@]o77}}o<q6..",
+"......g6z>vln||p|!!p|/l#>6........gz>e<]=rrrr444}7]iez..",
+".......gg6qm/n|!::%!|lmq6g.........g66&jo=r4h$u4}]9&zg..",
+"........ggeqvm//{/{{mvq>g...........g6#^<jooo777j{&eg...",
+"..........ze(qvmmmmm#(e6g.............z#[&<99jj<i'#>g...",
+"...........gzze((((e>gg................6>e#''vvqe6g.....",
+"............g66>>>>z6g..................g6>eeeee6gg.....",
+".............gg6ggggg....................g6666zgg.......",
+"................g...........................g...........",
+"........................................................",
+"........................................................",
+".........gggg........................gggg...............",
+".......6eqqee>ggggg666gg...........z[&&[qe6ggg66zz6g....",
+"......gevmvv#qe6666>eqeg..........g#<jt<i&#z>z>e#'#6....",
+"......gq1l^mm#(zz>>eeq(>g.........g&j]djj-[>>eq[[&'(g...",
+"......g(^llllm#e(q#m^l1#>g........6^j]b]]t-q[&itd]jieg..",
+"......6qml/{{^'e#v1^/|{meg........6&9]oc7];[-+jdo}79q6..",
+".....ggqml{{|/1q[m^/|!|^ezg......g6^j]k=}5*&+;2kr$}d[>g.",
+".....gg(#m/|!{1#ml{{nnlm(6g......gz[i9o}4k2-t]7x==ot'zg.",
+"......6e(v/|:n^[1/nn//1#(6g.......6q&+]rh=@+20}=ooji'>g.",
+".....ggze(/|%pi'^{!|lmvqe>g......gzz#&5r_r@;@74}]j<&qe6.",
+".....g6zeql|:p<i{{n{^vqe>g.......g6eq&@}h~w0kk}7d+&[e6..",
+".....g6>>elnff|||{{lm#(>6g.......gzeq[@=4$r==w,]t-[ezg..",
+".....g6>eq&{p!f:|nl^qe>ggg.......g6q[&2k~44sr752-qezgg..",
+".....gz>eqln!f:%!nlm#>>6g........6ze[&@7~$s_$k@t-qezg...",
+"....g66e(q&{|dbx:{1'#e6zg.......gz>q[&2kr4hu4k2;-qz>g...",
+"...ggz>>q#a{p:xc:t1[ee>gg......gg>eq&-@,~hu)h=*+[q(zg...",
+"...g6eq['1/{9!:%!nlm[>>6g......g>[&+;25ky4s_4=5*+qe6g...",
+"..gzqvm/n|p|p9|9ppp{1e>6g.....g>&+j57}rrr=ry~rr7j[e>6...",
+"..g>#m/|:%!!nn/ln!:!l#>z6g....zeij]rhu$~==o@=4h4]-qz6g..",
+"..6evl{|!:!|{/1m/n:|/#(>6g....6q<]7r4h4==52j]yh}5i[(zg..",
+"..g>vl{{nnllm'[#m^ll^mvq>>g...6e<]77==]]j;+-9d]]dj<&#eg.",
+"..g>vl{/l^m#(qeeqqvmm^mvqe6...ge{]7]]dt-[&[[&&<t9dj+&qz.",
+"...6#^/mm#qe>>>>>zeqvmmvqe6....zid7jti&[eeeeeeq&<jp+&#>.",
+"...ge#m#((e66z6g666>(#qezzg....gqi<i'[#>z>>66z>e'&&#e>g.",
+"....g6z>66gggggggg6g66666g......6>eez66ggggggg6gz>>>6g..",
+"........gggg.........g..............gggg.........g......",
+"........................................................",
+"........................................................",
+"........................................................",
+"........................................................",
+"........................................................",
+"...g66>6ggg....................gzzez6gg.................",
+"..gg>(ee>6g...................g6([[qe66.................",
+".g>eq#vqeez6g................6eq&i+-[qe6g...............",
+"6e#'^lll1'q>gg..............6#it2]o]j;&q6g..............",
+"g#^/{n|{/lm(6gg.............6ido7=}kkdt[>6g.............",
+"6v1/n|!nn/1q>6gg............6id]=r4}=7*&e6gg............",
+"ge#mln|nnn^[>>6ggggg6>>g6...g#i9]=}===d+qez6ggggzee66...",
+"g6eq^/|||nl[(>zzggg6>e>>zg..gz#&do}r}}]+[e>>666>eqqe>6..",
+".g6em//||p/'e>>zzzz>e#qe>6g..6>#to7=r~o;[qe>>>zq'-&[e6g.",
+".66z#^/|f:n^q(e>e(qmm/m#>g...66ei2]}4h=2&[qqq[&+j]jie6..",
+".g66#vl|fx|&qee>(vm^/n/veg...g6>-t@}hur2&[qq[+tdo=]<qg..",
+"..gze#m|bc!^#qe((m^ln|{m>g....6z[-jrhuy@-&[[&tdo=r=teg..",
+"..g6eqv/p%pi'[q([m///l^(6g....g6#&+k4ur5;+&[+jooo]d&>6..",
+"....>>q/|!n/&'#em^{/^m#e6g.....geq&]}$}52;-[;d7od9i#6g..",
+"...g66>1{!|{l&[(mln/mqe>g......g6zq*7ryk02+&;]=]j&qeg...",
+"....gzev^{n|pi'q#m^m#e>gg.......z>q<d77}r@;&itd9i'ezg...",
+"....ggzq'^{p:n&q##v#e>6g........g6z&;2k4$y2&--<-qe6z....",
+".....66>e#{!cplq((>e666g.........z>q[ik4)r@&&[qq>>6g....",
+"......gzeq^n!nl1[qe>>g6g..........g>[&d=4=5*+&qeez6g....",
+"......gg6ev^//{{l#(>>6gg..........g6>q+d]o7,@+[ee66g....",
+".......g66>qvl{p/m>e6zgg...........g>>q&+]7ro;qq>>6g....",
+"........6z>eqml{/^m#e>6g............6ze[&j]7o2;-[ezg....",
+".........g6>>#m^lll^#>66.............g>eqit]]]]2-q>z....",
+"..........g66eq#^/|/1q>z..............g6zq&a27}oj&e>....",
+"...........gg>e(v^/lmq(6g..............g6e#&{dkb;&[zg...",
+"............gg6e(#mvmv#eg...............g6z('it<t<i#g...",
+"..............ggz>eq#mv>g.................g6ze#&it+#6...",
+"...............gggg>(v#eg..................gg66#[<iqg...",
+"................g.gg>e>g....................g.g6eqe6....",
+".....................gg..........................gg.....",
+"........................................................"};
index 6e401aa673243b545f90a8fbd8fe719c8b216b81..a8af2e51d13b43196718cdc6efc1f0b1f87b7a9a 100644 (file)
@@ -102,9 +102,6 @@ If one of these are hit penrose will reinitialize.
  * vertex rules only allow at most seven tiles to meet at a vertex.
  */
 
  * vertex rules only allow at most seven tiles to meet at a vertex.
  */
 
-#define CELEBRATE 31415927     /* This causes a pause, an error occurred. */
-#define COMPLETION 3141593     /* This causes a pause, an error occurred. */
-
 #define MAX_TILES_PER_VERTEX 7
 #define N_VERTEX_RULES 8
 #define ALLOC_NODE( type) ((type *)malloc( sizeof( type)))
 #define MAX_TILES_PER_VERTEX 7
 #define N_VERTEX_RULES 8
 #define ALLOC_NODE( type) ((type *)malloc( sizeof( type)))
@@ -112,21 +109,28 @@ If one of these are hit penrose will reinitialize.
 
 static Bool ammann;
 
 
 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"},
 static XrmOptionDescRec opts[] =
 {
        {"-ammann", ".penrose.ammann", XrmoptionNoArg, (caddr_t) "on"},
-       {"+ammann", ".penrose.ammann", XrmoptionNoArg, (caddr_t) "off"}
+       {"+ammann", ".penrose.ammann", XrmoptionNoArg, (caddr_t) "off"},
+       {"-redoDelay", ".penrose.redoDelay", XrmoptionSepArg, NULL}
 };
 static argtype vars[] =
 {
 };
 static argtype vars[] =
 {
-       {(caddr_t *) & ammann, "ammann", "Ammann", DEF_AMMANN, t_Bool}
+       {(caddr_t *) & ammann, "ammann", "Ammann", DEF_AMMANN, t_Bool},
+       {(caddr_t *) & redo_delay, "redoDelay", "RedoDelay", "3", t_Int}
 };
 static OptionStruct desc[] =
 {
 };
 static OptionStruct desc[] =
 {
-       {"-/+ammann", "turn on/off Ammann lines"}
+       {"-/+ammann", "turn on/off Ammann lines"},
+       {"-redoDelay", "delay between new tilings"}
 };
 
 };
 
-ModeSpecOpt penrose_opts = { 2, opts, 1, vars, desc };
+ModeSpecOpt penrose_opts = { 3, opts, 2, vars, desc };
 
 
 /*-
 
 
 /*-
@@ -326,7 +330,7 @@ vertex_dir(ModeInfo * mi, fringe_node_c * vertex, unsigned side)
                        (void) fprintf(stderr, "v2->fived[%d]=%d, vertex->fived[%d]=%d\n",
                                      i, v2->fived[i], i, vertex->fived[i]);
        }
                        (void) fprintf(stderr, "v2->fived[%d]=%d, vertex->fived[%d]=%d\n",
                                      i, v2->fived[i], i, vertex->fived[i]);
        }
-       MI_PAUSE(mi) = CELEBRATE;
+       MI_PAUSE(mi) = redo_delay_usec;
        return 0;
 }
 
        return 0;
 }
 
@@ -414,6 +418,8 @@ init_penrose(ModeInfo * mi)
        fringe_node_c *fp;
        int         i, size;
 
        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)
        if (tilings == NULL) {
                if ((tilings = (tiling_c *) calloc(MI_NUM_SCREENS(mi),
                                                 sizeof (tiling_c))) == NULL)
@@ -715,7 +721,7 @@ check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp)
                if (MI_WIN_IS_VERBOSE(mi)) {
                        (void) fprintf(stderr, "Dislocation occured!\n");
                }
                if (MI_WIN_IS_VERBOSE(mi)) {
                        (void) fprintf(stderr, "Dislocation occured!\n");
                }
-               MI_PAUSE(mi) = CELEBRATE;       /* Should be able to recover */
+               MI_PAUSE(mi) = redo_delay_usec; /* Should be able to recover */
        }
        if (1 == find_completions(vertex, hits, n_hits, S_LEFT, 0 /*, False */ ))
                forced_sides |= S_LEFT;
        }
        if (1 == find_completions(vertex, hits, n_hits, S_LEFT, 0 /*, False */ ))
                forced_sides |= S_LEFT;
@@ -770,7 +776,7 @@ delete_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp)
                        (void) fprintf(stderr, "Weirdness in delete_penrose()\n");
                        (void) fprintf(stderr, "tp->fringe.nodes == vertex\n");
                }
                        (void) fprintf(stderr, "Weirdness in delete_penrose()\n");
                        (void) fprintf(stderr, "tp->fringe.nodes == vertex\n");
                }
-               MI_PAUSE(mi) = CELEBRATE;
+               MI_PAUSE(mi) = redo_delay_usec;
        }
        if (vertex->list_ptr != 0) {
                forced_node_c *node = *vertex->list_ptr;
        }
        if (vertex->list_ptr != 0) {
                forced_node_c *node = *vertex->list_ptr;
@@ -910,7 +916,7 @@ alloc_vertex(ModeInfo * mi, angle_c dir, fringe_node_c * from, tiling_c * tp)
                        (void) fprintf(stderr, "Weirdness in alloc_vertex()\n");
                        (void) fprintf(stderr, "v = 0\n");
                }
                        (void) fprintf(stderr, "Weirdness in alloc_vertex()\n");
                        (void) fprintf(stderr, "v = 0\n");
                }
-               MI_PAUSE(mi) = CELEBRATE;
+               MI_PAUSE(mi) = redo_delay_usec;
        }
        *v = *from;
        add_unit_vec(dir, v->fived);
        }
        *v = *from;
        add_unit_vec(dir, v->fived);
@@ -1230,7 +1236,7 @@ draw_penrose(ModeInfo * mi)
        /* No visible nodes left. */
        if (tp->fringe.n_nodes == 0) {
                tp->done = True;
        /* No visible nodes left. */
        if (tp->fringe.n_nodes == 0) {
                tp->done = True;
-               MI_PAUSE(mi) = COMPLETION;      /* Just finished drawing */
+               MI_PAUSE(mi) = redo_delay_usec; /* Just finished drawing */
                return;
        }
        if (tp->forced.n_visible > 0 && tp->failures < 10) {
                return;
        }
        if (tp->forced.n_visible > 0 && tp->failures < 10) {
index db4c818c6c9c33530c4d8ea32df0d4c3c2a28922..e4734bf82ff9be772959b5b7426b94e5a0548732 100644 (file)
@@ -3,7 +3,7 @@
 penrose - draws quasiperiodic tilings
 .SH SYNOPSIS
 .B penrose
 penrose - draws quasiperiodic tilings
 .SH SYNOPSIS
 .B penrose
-[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-install] [\-visual \fIvisual\fP] [\-ncolors \fIinteger\fP] [\-delay \fImicroseconds\fP] [\-size \fIinteger\fP] [\-ammann] [\-no\-ammann]
+[\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-install] [\-visual \fIvisual\fP] [\-ncolors \fIinteger\fP] [\-delay \fImicroseconds\fP] [\-redoDelay \fIseconds\fP] [\-size \fIinteger\fP] [\-ammann] [\-no\-ammann]
 
 .SH DESCRIPTION
 The \fIpenrose\fP program draws quasiperiodic tilings.
 
 .SH DESCRIPTION
 The \fIpenrose\fP program draws quasiperiodic tilings.
@@ -32,6 +32,10 @@ extended a window's length beyond the edge of the window
 horizontally or vertically or forced rule choice has failed 100
 times due to areas about to become enclosed.
 
 horizontally or vertically or forced rule choice has failed 100
 times due to areas about to become enclosed.
 
+Although quasiperiodic tilings are produced, the tiles themselves are
+not penrose tiles (darts and kites). In contrast to penrose tiles,
+these tiles can be arranged to form a periodic tiling.
+
 .SH OPTIONS
 .I penrose
 accepts the following options:
 .SH OPTIONS
 .I penrose
 accepts the following options:
@@ -59,6 +63,15 @@ The colors are chosen randomly.
 .B \-size \fIinteger\fP
 How big the tiles should be.  Default 40 pixels.
 
 .B \-size \fIinteger\fP
 How big the tiles should be.  Default 40 pixels.
 
+.TP 8
+.B \-delay \fImilliseconds\fP
+How long (in 1/1,000,000'ths of a second) to wait between drawing each
+tile.  Default 10,000 or .01 seconds.
+
+.TP 8
+.B \-redoDelay \fIseconds\fP
+How long to wait between starting a completely new tiling.  Default 3 seconds.
+
 .TP 8
 .B \-ammann \fIinteger\fP
 .TP 8
 .TP 8
 .B \-ammann \fIinteger\fP
 .TP 8
diff --git a/hacks/phosphor.c b/hacks/phosphor.c
new file mode 100644 (file)
index 0000000..c575bb2
--- /dev/null
@@ -0,0 +1,801 @@
+/* xscreensaver, Copyright (c) 1999 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * Phosphor -- simulate a glass tty with long-sustain phosphor.
+ */
+
+#include "screenhack.h"
+#include <stdio.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Intrinsic.h>
+
+extern XtAppContext app;
+
+#define FUZZY_BORDER
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BLANK  0
+#define FLARE  1
+#define NORMAL 2
+#define FADE   3
+
+#define CURSOR_INDEX 128
+
+typedef struct {
+  unsigned char name;
+  int width, height;
+  Pixmap pixmap;
+#ifdef FUZZY_BORDER
+  Pixmap pixmap2;
+#endif /* FUZZY_BORDER */
+  Bool blank_p;
+} p_char;
+
+typedef struct {
+  p_char *p_char;
+  int state;
+  Bool changed;
+} p_cell;
+
+typedef struct {
+  Display *dpy;
+  Window window;
+  XWindowAttributes xgwa;
+  XFontStruct *font;
+  int grid_width, grid_height;
+  int char_width, char_height;
+  int scale;
+  int ticks;
+  p_char **chars;
+  p_cell *cells;
+  XGCValues gcv;
+  GC gc0;
+  GC gc1;
+#ifdef FUZZY_BORDER
+  GC gc2;
+#endif /* FUZZY_BORDER */
+  GC *gcs;
+  XImage *font_bits;
+
+  int cursor_x, cursor_y;
+  XtIntervalId cursor_timer;
+  Time cursor_blink;
+
+  FILE *pipe;
+  XtInputId pipe_id;
+  Bool input_available_p;
+  Time subproc_relaunch_delay;
+
+} p_state;
+
+
+static void capture_font_bits (p_state *state);
+static p_char *make_character (p_state *state, int c);
+static void drain_input (p_state *state);
+static void char_to_pixmap (p_state *state, p_char *pc, int c);
+static void launch_text_generator (p_state *state);
+
+
+/* About font metrics:
+
+   "lbearing" is the distance from the leftmost pixel of a character to
+   the logical origin of that character.  That is, it is the number of
+   pixels of the character which are to the left of its logical origin.
+
+   "rbearing" is the distance from the logical origin of a character to
+   the rightmost pixel of a character.  That is, it is the number of
+   pixels of the character to the right of its logical origin.
+
+   "descent" is the distance from the bottommost pixel of a character to
+   the logical baseline.  That is, it is the number of pixels of the
+   character which are below the baseline.
+
+   "ascent" is the distance from the logical baseline to the topmost pixel.
+   That is, it is the number of pixels of the character above the baseline.
+
+   Therefore, the bounding box of the "ink" of a character is
+   lbearing + rbearing by ascent + descent;
+
+   "width" is the distance from the logical origin of this character to
+   the position where the logical orgin of the next character should be
+   placed.
+
+   For our purposes, we're only interested in the part of the character
+   lying inside the "width" box.  If the characters have ink outside of
+   that box (the "charcell" box) then we're going to lose it.  Alas.
+ */
+
+static p_state *
+init_phosphor (Display *dpy, Window window)
+{
+  int i;
+  unsigned long flags;
+  p_state *state = (p_state *) calloc (sizeof(*state), 1);
+  char *fontname = get_string_resource ("font", "Font");
+  XFontStruct *font;
+
+  state->dpy = dpy;
+  state->window = window;
+
+  XGetWindowAttributes (dpy, window, &state->xgwa);
+
+  state->font = XLoadQueryFont (dpy, fontname);
+
+  if (!state->font)
+    {
+      fprintf(stderr, "couldn't load font \"%s\"\n", fontname);
+      state->font = XLoadQueryFont (dpy, "fixed");
+    }
+  if (!state->font)
+    {
+      fprintf(stderr, "couldn't load font \"fixed\"");
+      exit(1);
+    }
+
+  font = state->font;
+  state->scale = get_integer_resource ("scale", "Integer");
+  state->ticks = 3 + get_integer_resource ("ticks", "Integer");
+
+#if 0
+  for (i = 0; i < font->n_properties; i++)
+    if (font->properties[i].name == XA_FONT)
+      printf ("font: %s\n", XGetAtomName(dpy, font->properties[i].card32));
+#endif /* 0 */
+
+  state->cursor_blink = get_integer_resource ("cursor", "Time");
+  state->subproc_relaunch_delay =
+    (1000 * get_integer_resource ("relaunch", "Time"));
+
+  state->char_width  = font->max_bounds.width;
+  state->char_height = font->max_bounds.ascent + font->max_bounds.descent;
+
+  state->grid_width = state->xgwa.width / (state->char_width * state->scale);
+  state->grid_height = state->xgwa.height /(state->char_height * state->scale);
+  state->cells = (p_cell *) calloc (sizeof(p_cell),
+                                    state->grid_width * state->grid_height);
+  state->chars = (p_char **) calloc (sizeof(p_char *), 256);
+
+  state->gcs = (GC *) calloc (sizeof(GC), state->ticks + 1);
+
+  {
+    int ncolors = MAX (0, state->ticks - 3);
+    XColor *colors = (XColor *) calloc (ncolors, sizeof(XColor));
+    int h1, h2;
+    double s1, s2, v1, v2;
+
+    unsigned long fg = get_pixel_resource ("foreground", "Foreground",
+                                           state->dpy, state->xgwa.colormap);
+    unsigned long bg = get_pixel_resource ("background", "Background",
+                                           state->dpy, state->xgwa.colormap);
+    unsigned long flare = get_pixel_resource ("flareForeground", "Foreground",
+                                              state->dpy,state->xgwa.colormap);
+    unsigned long fade = get_pixel_resource ("fadeForeground", "Foreground",
+                                             state->dpy,state->xgwa.colormap);
+
+    XColor start, end;
+
+    start.pixel = fade;
+    XQueryColor (state->dpy, state->xgwa.colormap, &start);
+
+    end.pixel = bg;
+    XQueryColor (state->dpy, state->xgwa.colormap, &end);
+
+    /* Now allocate a ramp of colors from the main color to the background. */
+    rgb_to_hsv (start.red, start.green, start.blue, &h1, &s1, &v1);
+    rgb_to_hsv (end.red, end.green, end.blue, &h2, &s2, &v2);
+    make_color_ramp (state->dpy, state->xgwa.colormap,
+                     h1, s1, v1,
+                     h2, s2, v2,
+                     colors, &ncolors,
+                     False, True, False);
+
+    /* Now, GCs all around.
+     */
+    state->gcv.font = font->fid;
+    state->gcv.cap_style = CapRound;
+#ifdef FUZZY_BORDER
+    state->gcv.line_width = (int) (((long) state->scale) * 1.3);
+    if (state->gcv.line_width == state->scale)
+      state->gcv.line_width++;
+#else /* !FUZZY_BORDER */
+    state->gcv.line_width = (int) (((long) state->scale) * 0.9);
+    if (state->gcv.line_width >= state->scale)
+      state->gcv.line_width = state->scale - 1;
+    if (state->gcv.line_width < 1)
+      state->gcv.line_width = 1;
+#endif /* !FUZZY_BORDER */
+
+    flags = (GCForeground | GCBackground | GCCapStyle | GCLineWidth);
+
+    state->gcv.background = bg;
+    state->gcv.foreground = bg;
+    state->gcs[BLANK] = XCreateGC (state->dpy, state->window, flags,
+                                   &state->gcv);
+
+    state->gcv.foreground = flare;
+    state->gcs[FLARE] = XCreateGC (state->dpy, state->window, flags,
+                                   &state->gcv);
+
+    state->gcv.foreground = fg;
+    state->gcs[NORMAL] = XCreateGC (state->dpy, state->window, flags,
+                                    &state->gcv);
+
+    for (i = 0; i < ncolors; i++)
+      {
+        state->gcv.foreground = colors[i].pixel;
+        state->gcs[FADE + i] = XCreateGC (state->dpy, state->window,
+                                          flags, &state->gcv);
+      }
+  }
+
+  capture_font_bits (state);
+
+  launch_text_generator (state);
+
+  return state;
+}
+
+
+static void
+capture_font_bits (p_state *state)
+{
+  XFontStruct *font = state->font;
+  int safe_width = font->max_bounds.rbearing - font->min_bounds.lbearing;
+  int height = state->char_height;
+  unsigned char string[257];
+  int i;
+  Pixmap p = XCreatePixmap (state->dpy, state->window,
+                            (safe_width * 256), height, 1);
+
+  for (i = 0; i < 256; i++)
+    string[i] = (unsigned char) i;
+  string[256] = 0;
+
+  state->gcv.foreground = 0;
+  state->gcv.background = 0;
+  state->gc0 = XCreateGC (state->dpy, p,
+                          (GCForeground | GCBackground),
+                          &state->gcv);
+
+  state->gcv.foreground = 1;
+  state->gc1 = XCreateGC (state->dpy, p,
+                          (GCFont | GCForeground | GCBackground |
+                           GCCapStyle | GCLineWidth),
+                          &state->gcv);
+
+#ifdef FUZZY_BORDER
+  {
+    state->gcv.line_width = (int) (((long) state->scale) * 0.8);
+    if (state->gcv.line_width >= state->scale)
+      state->gcv.line_width = state->scale - 1;
+    if (state->gcv.line_width < 1)
+      state->gcv.line_width = 1;
+    state->gc2 = XCreateGC (state->dpy, p,
+                            (GCFont | GCForeground | GCBackground |
+                             GCCapStyle | GCLineWidth),
+                            &state->gcv);
+  }
+#endif /* FUZZY_BORDER */
+
+  XFillRectangle (state->dpy, p, state->gc0, 0, 0, (safe_width * 256), height);
+
+  for (i = 0; i < 256; i++)
+    {
+      if (string[i] < font->min_char_or_byte2 ||
+          string[i] > font->max_char_or_byte2)
+        continue;
+      XDrawString (state->dpy, p, state->gc1,
+                   i * safe_width, font->ascent,
+                   string + i, 1);
+    }
+
+  /* Draw the cursor. */
+  XFillRectangle (state->dpy, p, state->gc1,
+                  (CURSOR_INDEX * safe_width), 1,
+                  (font->per_char
+                   ? font->per_char['n'-font->min_char_or_byte2].width
+                   : font->max_bounds.width),
+                  font->ascent - 1);
+
+#if 0
+  XCopyPlane (state->dpy, p, state->window, state->gcs[FLARE],
+              0, 0, (safe_width * 256), height, 0, 0, 1L);
+  XSync(state->dpy, False);
+#endif
+
+  XSync (state->dpy, False);
+  state->font_bits = XGetImage (state->dpy, p, 0, 0,
+                                (safe_width * 256), height, ~0L, XYPixmap);
+  XFreePixmap (state->dpy, p);
+
+  for (i = 0; i < 256; i++)
+    state->chars[i] = make_character (state, i);
+  state->chars[CURSOR_INDEX] = make_character (state, CURSOR_INDEX);
+}
+
+
+static p_char *
+make_character (p_state *state, int c)
+{
+  p_char *pc = (p_char *) malloc (sizeof (*pc));
+  pc->name = (unsigned char) c;
+  pc->width =  state->scale * state->char_width;
+  pc->height = state->scale * state->char_height;
+  char_to_pixmap (state, pc, c);
+  return pc;
+}
+
+
+static void
+char_to_pixmap (p_state *state, p_char *pc, int c)
+{
+  Pixmap p = 0;
+  GC gc;
+#ifdef FUZZY_BORDER
+  Pixmap p2 = 0;
+  GC gc2;
+#endif /* FUZZY_BORDER */
+  int from, to;
+  int x1, y;
+
+  XFontStruct *font = state->font;
+  int safe_width = font->max_bounds.rbearing - font->min_bounds.lbearing;
+
+  int width  = state->scale * state->char_width;
+  int height = state->scale * state->char_height;
+
+  if (c < font->min_char_or_byte2 ||
+      c > font->max_char_or_byte2)
+    goto DONE;
+
+  gc = state->gc1;
+  p = XCreatePixmap (state->dpy, state->window, width, height, 1);
+  XFillRectangle (state->dpy, p, state->gc0, 0, 0, width, height);
+#ifdef FUZZY_BORDER
+  gc2 = state->gc2;
+  p2 = XCreatePixmap (state->dpy, state->window, width, height, 1);
+  XFillRectangle (state->dpy, p2, state->gc0, 0, 0, width, height);
+#endif /* FUZZY_BORDER */
+
+  from = safe_width * c;
+  to =   safe_width * (c + 1);
+
+#if 0
+  if (c > 75 && c < 150)
+    {
+      printf ("\n=========== %d (%c)\n", c, c);
+      for (y = 0; y < state->char_height; y++)
+        {
+          for (x1 = from; x1 < to; x1++)
+            printf (XGetPixel (state->font_bits, x1, y) ? "* " : ". ");
+          printf ("\n");
+        }
+    }
+#endif
+
+  pc->blank_p = True;
+  for (y = 0; y < state->char_height; y++)
+    for (x1 = from; x1 < to; x1++)
+      if (XGetPixel (state->font_bits, x1, y))
+        {
+          int xoff = state->scale / 2;
+          int x2;
+          for (x2 = x1; x2 < to; x2++)
+            if (!XGetPixel (state->font_bits, x2, y))
+              break;
+          x2--;
+          XDrawLine (state->dpy, p, gc,
+                     (x1 - from) * state->scale + xoff, y * state->scale,
+                     (x2 - from) * state->scale + xoff, y * state->scale);
+#ifdef FUZZY_BORDER
+          XDrawLine (state->dpy, p2, gc2,
+                     (x1 - from) * state->scale + xoff, y * state->scale,
+                     (x2 - from) * state->scale + xoff, y * state->scale);
+#endif /* FUZZY_BORDER */
+          x1 = x2;
+          pc->blank_p = False;
+        }
+
+  /*  if (pc->blank_p && c == CURSOR_INDEX)
+    abort();*/
+
+ DONE:
+  pc->pixmap = p;
+#ifdef FUZZY_BORDER
+  pc->pixmap2 = p2;
+#endif /* FUZZY_BORDER */
+}
+
+\f
+/* Managing the display. 
+ */
+
+static void cursor_on_timer (XtPointer closure, XtIntervalId *id);
+static void cursor_off_timer (XtPointer closure, XtIntervalId *id);
+
+static Bool
+set_cursor_1 (p_state *state, Bool on)
+{
+  p_cell *cell = &state->cells[state->grid_width * state->cursor_y
+                              + state->cursor_x];
+  p_char *cursor = state->chars[CURSOR_INDEX];
+  int new_state = (on ? NORMAL : FADE);
+
+  if (cell->p_char != cursor)
+    cell->changed = True;
+
+  if (cell->state != new_state)
+    cell->changed = True;
+
+  cell->p_char = cursor;
+  cell->state = new_state;
+  return cell->changed;
+}
+
+static void
+set_cursor (p_state *state, Bool on)
+{
+  if (set_cursor_1 (state, on))
+;
+    {
+      if (state->cursor_timer)
+        XtRemoveTimeOut (state->cursor_timer);
+      state->cursor_timer = 0;
+      cursor_on_timer (state, 0);
+    }
+}
+
+
+
+
+static void
+cursor_off_timer (XtPointer closure, XtIntervalId *id)
+{
+  p_state *state = (p_state *) closure;
+  set_cursor_1 (state, False);
+  state->cursor_timer = XtAppAddTimeOut (app, state->cursor_blink,
+                                         cursor_on_timer, closure);
+}
+
+static void
+cursor_on_timer (XtPointer closure, XtIntervalId *id)
+{
+  p_state *state = (p_state *) closure;
+  set_cursor_1 (state, True);
+  state->cursor_timer = XtAppAddTimeOut (app, 2 * state->cursor_blink,
+                                         cursor_off_timer, closure);
+}
+
+
+static void
+clear (p_state *state)
+{
+  int x, y;
+  state->cursor_x = 0;
+  state->cursor_y = 0;
+  for (y = 0; y < state->grid_height; y++)
+    for (x = 0; x < state->grid_width; x++)
+      {
+        p_cell *cell = &state->cells[state->grid_width * y + x];
+        if (cell->state == FLARE || cell->state == NORMAL)
+          {
+            cell->state = FADE;
+            cell->changed = True;
+          }
+      }
+  set_cursor (state, True);
+}
+
+
+static void
+decay (p_state *state)
+{
+  int x, y;
+  for (y = 0; y < state->grid_height; y++)
+    for (x = 0; x < state->grid_width; x++)
+      {
+        p_cell *cell = &state->cells[state->grid_width * y + x];
+        if (cell->state == FLARE)
+          {
+            cell->state = NORMAL;
+            cell->changed = True;
+          }
+        else if (cell->state >= FADE)
+          {
+            cell->state++;
+            if (cell->state >= state->ticks)
+              cell->state = BLANK;
+            cell->changed = True;
+          }
+      }
+}
+
+
+static void
+scroll (p_state *state)
+{
+  int x, y;
+  for (x = 0; x < state->grid_width; x++)
+    {
+      p_cell *from, *to;
+      for (y = 1; y < state->grid_height; y++)
+        {
+          from = &state->cells[state->grid_width * y     + x];
+          to   = &state->cells[state->grid_width * (y-1) + x];
+
+          if ((from->state == FLARE || from->state == NORMAL) &&
+              !from->p_char->blank_p)
+            {
+              *to = *from;
+              to->state = NORMAL;  /* should be FLARE?  Looks bad... */
+            }
+          else
+            {
+              if (to->state == FLARE || to->state == NORMAL)
+                to->state = FADE;
+            }
+
+          to->changed = True;
+        }
+
+      to = from;
+      if (to->state == FLARE || to->state == NORMAL)
+        {
+          to->state = FADE;
+          to->changed = True;
+        }
+    }
+  set_cursor (state, True);
+}
+
+
+static void
+print_char (p_state *state, int c)
+{
+  p_cell *cell = &state->cells[state->grid_width * state->cursor_y
+                              + state->cursor_x];
+
+  /* Start the cursor fading (in case we don't end up overwriting it.) */
+  if (cell->state == FLARE || cell->state == NORMAL)
+    {
+      cell->state = FADE;
+      cell->changed = True;
+    }
+
+  if (c == '\t') c = ' ';   /* blah. */
+
+  if (c == '\r' || c == '\n')
+    {
+      state->cursor_x = 0;
+      if (state->cursor_y == state->grid_height - 1)
+        scroll (state);
+      else
+        state->cursor_y++;
+    }
+  else if (c == '\014')
+    {
+      clear (state);
+    }
+  else
+    {
+      cell->state = FLARE;
+      cell->p_char = state->chars[c];
+      cell->changed = True;
+      state->cursor_x++;
+
+      if (c != ' ' && cell->p_char->blank_p)
+        cell->p_char = state->chars[CURSOR_INDEX];
+
+      if (state->cursor_x >= state->grid_width - 1)
+        {
+          state->cursor_x = 0;
+          if (state->cursor_y >= state->grid_height - 1)
+            scroll (state);
+          else
+            state->cursor_y++;
+        }
+    }
+  set_cursor (state, True);
+}
+
+
+static void
+update_display (p_state *state, Bool changed_only)
+{
+  int x, y;
+
+  for (y = 0; y < state->grid_height; y++)
+    for (x = 0; x < state->grid_width; x++)
+      {
+        p_cell *cell = &state->cells[state->grid_width * y + x];
+        int width, height, tx, ty;
+
+        if (changed_only && !cell->changed)
+          continue;
+
+        width = state->char_width * state->scale;
+        height = state->char_height * state->scale;
+        tx = x * width;
+        ty = y * height;
+
+        if (cell->state == BLANK || cell->p_char->blank_p)
+          {
+            XFillRectangle (state->dpy, state->window, state->gcs[BLANK],
+                            tx, ty, width, height);
+          }
+        else
+          {
+#ifdef FUZZY_BORDER
+            GC gc1 = state->gcs[cell->state];
+            GC gc2 = ((cell->state + 2) < state->ticks
+                      ? state->gcs[cell->state + 2]
+                      : 0);
+            XCopyPlane (state->dpy, cell->p_char->pixmap, state->window,
+                        (gc2 ? gc2 : gc1),
+                        0, 0, width, height, tx, ty, 1L);
+            if (gc2)
+              {
+                XSetClipMask (state->dpy, gc1, cell->p_char->pixmap2);
+                XSetClipOrigin (state->dpy, gc1, tx, ty);
+                XFillRectangle (state->dpy, state->window, gc1,
+                                tx, ty, width, height);
+                XSetClipMask (state->dpy, gc1, None);
+              }
+#else /* !FUZZY_BORDER */
+
+            XCopyPlane (state->dpy,
+                        cell->p_char->pixmap, state->window,
+                        state->gcs[cell->state],
+                        0, 0, width, height, tx, ty, 1L);
+
+#endif /* !FUZZY_BORDER */
+          }
+
+        cell->changed = False;
+      }
+}
+
+
+static void
+run_phosphor (p_state *state)
+{
+  update_display (state, True);
+  decay (state);
+  drain_input (state);
+}
+
+\f
+/* Subprocess.
+ */
+
+static void
+subproc_cb (XtPointer closure, int *source, XtInputId *id)
+{
+  p_state *state = (p_state *) closure;
+  state->input_available_p = True;
+}
+
+
+static void
+launch_text_generator (p_state *state)
+{
+  char *oprogram = get_string_resource ("program", "Program");
+  char *program = (char *) malloc (strlen (oprogram) + 10);
+
+  strcpy (program, "( ");
+  strcat (program, oprogram);
+  strcat (program, " ) 2>&1");
+
+  if ((state->pipe = popen (program, "r")))
+    {
+      state->pipe_id =
+        XtAppAddInput (app, fileno (state->pipe),
+                       (XtPointer) (XtInputReadMask | XtInputExceptMask),
+                       subproc_cb, (XtPointer) state);
+    }
+  else
+    {
+      perror (program);
+    }
+}
+
+
+static void
+relaunch_generator_timer (XtPointer closure, XtIntervalId *id)
+{
+  p_state *state = (p_state *) closure;
+  launch_text_generator (state);
+}
+
+
+static void
+drain_input (p_state *state)
+{
+  if (state->input_available_p)
+    {
+      char s[2];
+      int n = read (fileno (state->pipe), (void *) s, 1);
+      if (n == 1)
+        {
+          print_char (state, s[0]);
+        }
+      else
+        {
+          XtRemoveInput (state->pipe_id);
+          state->pipe_id = 0;
+          pclose (state->pipe);
+          state->pipe = 0;
+
+          if (state->cursor_x != 0)    /* break line if unbroken */
+            print_char (state, '\n');  /* blank line */
+          print_char (state, '\n');
+
+          /* Set up a timer to re-launch the subproc in a bit. */
+          XtAppAddTimeOut (app, state->subproc_relaunch_delay,
+                           relaunch_generator_timer,
+                           (XtPointer) state);
+        }
+        
+      state->input_available_p = False;
+    }
+}
+
+
+\f
+char *progclass = "Phosphor";
+
+char *defaults [] = {
+  ".background:                   Black",
+  ".foreground:                   Green",
+  "*fadeForeground:       DarkGreen",
+  "*flareForeground:      White",
+  "*font:                 fixed",
+  "*scale:                6",
+  "*ticks:                20",
+  "*delay:                50000",
+  "*cursor:               333",
+  "*program:            " ZIPPY_PROGRAM,
+  "*relaunch:             5",
+  0
+};
+
+XrmOptionDescRec options [] = {
+  { "-font",           ".font",                XrmoptionSepArg, 0 },
+  { "-scale",          ".scale",               XrmoptionSepArg, 0 },
+  { "-ticks",          ".ticks",               XrmoptionSepArg, 0 },
+  { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { "-program",                ".program",             XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+
+void
+screenhack (Display *dpy, Window window)
+{
+  int delay = get_integer_resource ("delay", "Integer");
+  p_state *state = init_phosphor (dpy, window);
+
+  clear (state);
+
+  while (1)
+    {
+      run_phosphor (state);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
+
+      if (XtAppPending (app) & (XtIMTimer|XtIMAlternateInput|XtIMSignal))
+        XtAppProcessEvent (app, XtIMTimer|XtIMAlternateInput|XtIMSignal);
+
+      if (delay) usleep (delay);
+    }
+}
index 7c14734664f522227911b8c2f8d06ca788286f7d..eb9d7185e0058dd0cd3e3e1c042d8a94f26d1fcb 100644 (file)
@@ -59,6 +59,7 @@
 
 char *progname;
 XrmDatabase db;
 
 char *progname;
 XrmDatabase db;
+XtAppContext app;
 Bool mono_p;
 
 static XrmOptionDescRec default_options [] = {
 Bool mono_p;
 
 static XrmOptionDescRec default_options [] = {
@@ -240,7 +241,6 @@ screenhack_handle_events (Display *dpy)
 int
 main (int argc, char **argv)
 {
 int
 main (int argc, char **argv)
 {
-  XtAppContext app;
   Widget toplevel;
   Display *dpy;
   Window window;
   Widget toplevel;
   Display *dpy;
   Window window;
index 91694e93e994b332d606655d6ecb4e7e1eb15173..395fea1cd37c0d5804d5292ce047cdfb51f63b31 100644 (file)
@@ -196,7 +196,7 @@ draw_slip(ModeInfo * mi)
                double      x, y, dx = 0, dy = 0, t, s1, s2;
 
                if (0 == s->nblits_remaining--) {
                double      x, y, dx = 0, dy = 0, t, s1, s2;
 
                if (0 == s->nblits_remaining--) {
-                       static      lut[] =
+                       static int lut[] =
                        {0, 0, 0, 1, 1, 1, 2};
 
                        prepare_screen(mi, s);
                        {0, 0, 0, 1, 1, 1, 2};
 
                        prepare_screen(mi, s);
index cffe98424e79bf480eb8e31183719745932874c3..e0a81e3a197e8ef1fd0ef9d813bef2406599b054 100644 (file)
@@ -106,7 +106,7 @@ draw_sphere(ModeInfo * mi)
        Display    *display = MI_DISPLAY(mi);
        GC          gc = MI_GC(mi);
        spherestruct *sp = &spheres[MI_SCREEN(mi)];
        Display    *display = MI_DISPLAY(mi);
        GC          gc = MI_GC(mi);
        spherestruct *sp = &spheres[MI_SCREEN(mi)];
-       register    minx = 0, maxx = 0, miny = 0, maxy = 0, npts = 0;
+       int         minx = 0, maxx = 0, miny = 0, maxy = 0, npts = 0;
 
        if ((sp->dirx && ABS(sp->x) >= sp->radius) ||
            (sp->diry && ABS(sp->y) >= sp->radius)) {
 
        if ((sp->dirx && ABS(sp->x) >= sp->radius) ||
            (sp->diry && ABS(sp->y) >= sp->radius)) {
index 57feea0fbb6bf324b42036c1f617c8a74e476b1f..fb7868feff039fcdb649a726e9fd51cbdcba1318 100644 (file)
@@ -219,4 +219,5 @@ XrmOptionDescRec options[] = {
     {"-ncolors", ".ncolors", XrmoptionSepArg, 0},
     {"-cycle", ".cycle", XrmoptionNoArg, "True"},
     {"-no-cycle", ".cycle", XrmoptionNoArg, "False"},
     {"-ncolors", ".ncolors", XrmoptionSepArg, 0},
     {"-cycle", ".cycle", XrmoptionNoArg, "True"},
     {"-no-cycle", ".cycle", XrmoptionNoArg, "False"},
+    { 0, 0, 0, 0 }
 };
 };
index 58ec47f2bf01ae96dfe8b35326ece537e09350b8..b569c7511fc04dcfa7172d81506e5c728df09da3 100644 (file)
@@ -209,7 +209,7 @@ initColor (double r, double g, double b)
 {
   int n,n1;
   unsigned long pixels[12];
 {
   int n,n1;
   unsigned long pixels[12];
-  long dummy;
+  unsigned long dummy;
   
   cmap = xgwa.colormap;
   
   
   cmap = xgwa.colormap;
   
@@ -293,7 +293,7 @@ initialize (void)
     if (s && *s)
       {
         double hh, ss, vv;
     if (s && *s)
       {
         double hh, ss, vv;
-        if (3 == sscanf (s, "%lf %lf %lf", &hh, &ss, &vv, &dummy)) {
+        if (3 == sscanf (s, "%lf %lf %lf %c", &hh, &ss, &vv, &dummy)) {
           hue = hh, sat = ss, val = vv;
           hsv2rgb(hue,sat,val,&r,&g,&b);
         }
           hue = hh, sat = ss, val = vv;
           hsv2rgb(hue,sat,val,&r,&g,&b);
         }
@@ -816,7 +816,8 @@ screenhack (Display *d, Window w)
 {
   Window junk_win,in_win;
   
 {
   Window junk_win,in_win;
   
-  int px,py,junk,kb/*,wai*/;
+  int px,py,junk/*,wai*/;
+  unsigned int kb;
 /*  int act,act1,tc;*/
   double vnorm;
   /* double var=0.0; */
 /*  int act,act1,tc;*/
   double vnorm;
   /* double var=0.0; */
index 360ef379fc1d2515073e1335d37dc8870d8b79d8..dcac9600e7497ece737f5590d6d5f5cb608be535 100755 (executable)
@@ -125,9 +125,14 @@ MakeImage(void)
 {
   XGCValues gcv;
 
 {
   XGCValues gcv;
 
+#ifdef HAVE_XSHM_EXTENSION
   shared = True;
   xim = create_xshm_image (display, visual, depth, ZPixmap, NULL,
                            &shminfo, width, height);
   shared = True;
   xim = create_xshm_image (display, visual, depth, ZPixmap, NULL,
                            &shminfo, width, height);
+#else  /* !HAVE_XSHM_EXTENSION */
+  xim = 0;
+#endif /* !HAVE_XSHM_EXTENSION */
+
   if (!xim)
     {
       shared = False;
   if (!xim)
     {
       shared = False;
@@ -180,10 +185,12 @@ InitColors(void)
 static void
 DisplayImage(void)
 {
 static void
 DisplayImage(void)
 {
+#ifdef HAVE_XSHM_EXTENSION
   if (shared)
     XShmPutImage(display, window, gc, xim, 0,(top - 1) << 1, 0,
                  (top - 1) << 1, width, height - ((top - 1) << 1), False);
   else
   if (shared)
     XShmPutImage(display, window, gc, xim, 0,(top - 1) << 1, 0,
                  (top - 1) << 1, width, height - ((top - 1) << 1), False);
   else
+#endif /* HAVE_XSHM_EXTENSION */
     XPutImage(display, window, gc, xim, 0, (top - 1) << 1, 0,
               (top - 1) << 1, width, height - ((top - 1) << 1));
 }
     XPutImage(display, window, gc, xim, 0, (top - 1) << 1, 0,
               (top - 1) << 1, width, height - ((top - 1) << 1));
 }
@@ -521,6 +528,7 @@ loadBitmap(int *w, int *h)
       *bitmap_name &&
       !!strcmp(bitmap_name, "none"))
     {
       *bitmap_name &&
       !!strcmp(bitmap_name, "none"))
     {
+#ifdef HAVE_XPM
       XpmInfo xpm_info = { 0, };
       XpmImage xpm_image = { 0, };
 
       XpmInfo xpm_info = { 0, };
       XpmImage xpm_image = { 0, };
 
@@ -582,6 +590,7 @@ loadBitmap(int *w, int *h)
           return result;
         }
       else      /* failed to read XPM -- fall through and try XBM */
           return result;
         }
       else      /* failed to read XPM -- fall through and try XBM */
+#endif /* HAVE_XPM */
         {
 #ifdef HAVE_XMU
           XImage *ximage = 0;
         {
 #ifdef HAVE_XMU
           XImage *ximage = 0;
index b180fc43341828a85e6225e2fcb788491b2b6ad1..3742df68858b61e40a6d5236a70c3f87ae738a21 100644 (file)
@@ -599,7 +599,7 @@ main_event(void)
 static int
 complyap(void)
 {
 static int
 complyap(void)
 {
-  register i, bindex;
+  int i, bindex;
   double total, prod, x, dx, r;
 
   if (!run)
   double total, prod, x, dx, r;
 
   if (!run)
diff --git a/hacks/xmatrix.c b/hacks/xmatrix.c
new file mode 100644 (file)
index 0000000..38d9af1
--- /dev/null
@@ -0,0 +1,438 @@
+/* xscreensaver, Copyright (c) 1999 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * Matrix -- simulate the text scrolls from the movie "The Matrix".
+ *
+ * The movie people distribute their own Windows/Mac screensaver that does
+ * a similar thing, so I wrote one for Unix.  However, that version (the
+ * Windows/Mac version at http://www.whatisthematrix.com/) doesn't match my
+ * memory of what the screens in the movie looked like, so my `xmatrix'
+ * does things differently.
+ */
+
+#include "screenhack.h"
+#include <stdio.h>
+#include <X11/Xutil.h>
+
+#ifdef HAVE_XPM
+# include <X11/xpm.h>
+# include "images/matrix.xpm"
+#endif
+
+#include "images/matrix.xbm"
+
+#define CHAR_HEIGHT 31
+
+typedef struct {
+  int glyph;
+  Bool changed;
+  int glow;
+} m_cell;
+
+typedef struct {
+  int remaining;
+  int throttle;
+  int y;
+} m_feeder;
+
+typedef struct {
+  Display *dpy;
+  Window window;
+  XWindowAttributes xgwa;
+  GC draw_gc, erase_gc;
+  int grid_width, grid_height;
+  int char_width, char_height;
+  m_cell *cells;
+  m_feeder *feeders;
+  Bool insert_top_p, insert_bottom_p;
+  int density;
+
+  Pixmap images;
+  int image_width, image_height;
+  int nglyphs;
+
+} m_state;
+
+
+static void
+load_images (m_state *state)
+{
+#ifdef 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, matrix,
+                                        &state->images, 0 /* mask */,
+                                        &xpmattrs);
+      if (!state->images || (result != XpmSuccess && result != XpmColorError))
+        state->images = 0;
+
+      state->image_width = xpmattrs.width;
+      state->image_height = xpmattrs.height;
+      state->nglyphs = state->image_height / CHAR_HEIGHT;
+    }
+  else
+#endif /* !HAVE_XPM */
+    {
+      unsigned long fg, bg;
+      state->image_width = matrix_width;
+      state->image_height = matrix_height;
+      state->nglyphs = state->image_height / CHAR_HEIGHT;
+
+      fg = get_pixel_resource("foreground", "Foreground",
+                              state->dpy, state->xgwa.colormap);
+      bg = get_pixel_resource("background", "Background",
+                              state->dpy, state->xgwa.colormap);
+      state->images =
+        XCreatePixmapFromBitmapData (state->dpy, state->window,
+                                     (char *) matrix_bits,
+                                     state->image_width, state->image_height,
+                                     bg, fg, state->xgwa.depth);
+    }
+}
+
+
+static m_state *
+init_matrix (Display *dpy, Window window)
+{
+  XGCValues gcv;
+  char *insert;
+  m_state *state = (m_state *) calloc (sizeof(*state), 1);
+  state->dpy = dpy;
+  state->window = window;
+
+  XGetWindowAttributes (dpy, window, &state->xgwa);
+  load_images (state);
+
+  gcv.foreground = get_pixel_resource("foreground", "Foreground",
+                                      state->dpy, state->xgwa.colormap);
+  gcv.background = get_pixel_resource("background", "Background",
+                                      state->dpy, state->xgwa.colormap);
+  state->draw_gc = XCreateGC (state->dpy, state->window,
+                              GCForeground|GCBackground, &gcv);
+  gcv.foreground = gcv.background;
+  state->erase_gc = XCreateGC (state->dpy, state->window,
+                               GCForeground|GCBackground, &gcv);
+
+  state->char_width = state->image_width / 2;
+  state->char_height = CHAR_HEIGHT;
+
+  state->grid_width  = state->xgwa.width  / state->char_width;
+  state->grid_height = state->xgwa.height / state->char_height;
+  state->grid_width++;
+  state->grid_height++;
+
+  state->cells = (m_cell *)
+    calloc (sizeof(m_cell), state->grid_width * state->grid_height);
+  state->feeders = (m_feeder *) calloc (sizeof(m_feeder), state->grid_width);
+
+  state->density = get_integer_resource ("density", "Integer");
+
+  insert = get_string_resource("insert", "Insert");
+  if (insert && !strcmp(insert, "top"))
+    {
+      state->insert_top_p = True;
+      state->insert_bottom_p = False;
+    }
+  else if (insert && !strcmp(insert, "bottom"))
+    {
+      state->insert_top_p = False;
+      state->insert_bottom_p = True;
+    }
+  else if (insert && !strcmp(insert, "both"))
+    {
+      state->insert_top_p = True;
+      state->insert_bottom_p = True;
+    }
+  else
+    {
+      if (insert && *insert)
+        fprintf (stderr,
+                 "%s: `insert' must be `top', `bottom', or `both', not \%s'\n",
+                 progname, insert);
+      state->insert_top_p = False;
+      state->insert_bottom_p = True;
+    }
+
+  if (insert)
+    free (insert);
+
+  return state;
+}
+
+
+static void
+insert_glyph (m_state *state, int glyph, int x, int y)
+{
+  Bool bottom_feeder_p = (y >= 0);
+  m_cell *from, *to;
+
+  if (y >= state->grid_height)
+    return;
+
+  if (bottom_feeder_p)
+    {
+      to = &state->cells[state->grid_width * y + x];
+    }
+  else
+    {
+      for (y = state->grid_height-1; y > 0; y--)
+        {
+          from = &state->cells[state->grid_width * (y-1) + x];
+          to   = &state->cells[state->grid_width * y     + x];
+          *to = *from;
+          to->changed = True;
+        }
+      to = &state->cells[x];
+    }
+
+  to->glyph = glyph;
+  to->changed = True;
+
+  if (!to->glyph)
+    ;
+  else if (bottom_feeder_p)
+    to->glow = 1 + (random() % 2);
+  else
+    to->glow = 0;
+}
+
+
+static void
+feed_matrix (m_state *state)
+{
+  int x;
+
+  /* Update according to current feeders. */
+  for (x = 0; x < state->grid_width; x++)
+    {
+      m_feeder *f = &state->feeders[x];
+
+      if (f->throttle)         /* this is a delay tick, synced to frame. */
+        {
+          f->throttle--;
+        }
+      else if (f->remaining > 0)       /* how many items are in the pipe */
+        {
+          int g = (random() % state->nglyphs) + 1;
+          insert_glyph (state, g, x, f->y);
+          f->remaining--;
+          if (f->y >= 0)  /* bottom_feeder_p */
+            f->y++;
+        }
+      else                             /* if pipe is empty, insert spaces */
+        {
+          insert_glyph (state, 0, x, f->y);
+          if (f->y >= 0)  /* bottom_feeder_p */
+            f->y++;
+        }
+
+      if ((random() % 10) == 0)                /* randomly change throttle speed */
+        {
+          f->throttle = ((random() % 5) + (random() % 5));
+        }
+    }
+}
+
+static int
+densitizer (m_state *state)
+{
+  /* Horrid kludge that converts percentages (density of screen coverage)
+     to the parameter that actually controls this.  I got this mapping
+     empirically, on a 1024x768 screen.  Sue me. */
+  if      (state->density < 10) return 85;
+  else if (state->density < 15) return 60;
+  else if (state->density < 20) return 45;
+  else if (state->density < 25) return 25;
+  else if (state->density < 30) return 20;
+  else if (state->density < 35) return 15;
+  else if (state->density < 45) return 10;
+  else if (state->density < 50) return 8;
+  else if (state->density < 55) return 7;
+  else if (state->density < 65) return 5;
+  else if (state->density < 80) return 3;
+  else if (state->density < 90) return 2;
+  else return 1;
+}
+
+
+static void
+hack_matrix (m_state *state)
+{
+  int x;
+
+  /* Glow some characters. */
+  if (!state->insert_bottom_p)
+    {
+      int i = random() % (state->grid_width / 2);
+      while (--i > 0)
+        {
+          int x = random() % state->grid_width;
+          int y = random() % state->grid_height;
+          m_cell *cell = &state->cells[state->grid_width * y + x];
+          if (cell->glyph && cell->glow == 0)
+            {
+              cell->glow = random() % 10;
+              cell->changed = True;
+            }
+        }
+    }
+
+  /* Change some of the feeders. */
+  for (x = 0; x < state->grid_width; x++)
+    {
+      m_feeder *f = &state->feeders[x];
+      Bool bottom_feeder_p;
+
+      if (f->remaining > 0)    /* never change if pipe isn't empty */
+        continue;
+
+      if ((random() % densitizer(state)) != 0) /* then change N% of the time */
+        continue;
+
+      f->remaining = 3 + (random() % state->grid_height);
+      f->throttle = ((random() % 5) + (random() % 5));
+
+      if ((random() % 4) != 0)
+        f->remaining = 0;
+
+      if (state->insert_top_p && state->insert_bottom_p)
+        bottom_feeder_p = (random() & 1);
+      else
+        bottom_feeder_p = state->insert_bottom_p;
+
+      if (bottom_feeder_p)
+        f->y = random() % (state->grid_height / 2);
+      else
+        f->y = -1;
+    }
+}
+
+
+static void
+draw_matrix (m_state *state)
+{
+  int x, y;
+  int count = 0;
+
+  feed_matrix (state);
+  hack_matrix (state);
+
+  for (y = 0; y < state->grid_height; y++)
+    for (x = 0; x < state->grid_width; x++)
+      {
+        m_cell *cell = &state->cells[state->grid_width * y + x];
+
+        if (cell->glyph)
+          count++;
+
+        if (!cell->changed)
+          continue;
+
+        if (cell->glyph == 0)
+          XFillRectangle (state->dpy, state->window, state->erase_gc,
+                          x * state->char_width,
+                          y * state->char_height,
+                          state->char_width,
+                          state->char_height);
+        else
+          XCopyArea (state->dpy, state->images, state->window, state->draw_gc,
+                     (cell->glow ? state->char_width : 0),
+                     (cell->glyph - 1) * state->char_height,
+                     state->char_width, state->char_height,
+                     x * state->char_width,
+                     y * state->char_height);
+
+        cell->changed = False;
+
+        if (cell->glow > 0)
+          {
+            cell->glow--;
+            cell->changed = True;
+          }
+      }
+
+#if 0
+  {
+    static int i = 0;
+    static int ndens = 0;
+    static int tdens = 0;
+    i++;
+    if (i > 50)
+      {
+        int dens = (100.0 *
+                    (((double)count) /
+                     ((double) (state->grid_width * state->grid_height))));
+        tdens += dens;
+        ndens++;
+        printf ("density: %d%% (%d%%)\n", dens, (tdens / ndens));
+        i = 0;
+      }
+  }
+#endif
+
+}
+
+\f
+char *progclass = "XMatrix";
+
+char *defaults [] = {
+  ".background:                   black",
+  ".foreground:                   green",
+  "*delay:                10000",
+  "*insert:               both",
+  "*density:              85",
+  0
+};
+
+XrmOptionDescRec options [] = {
+  { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { "-top",            ".insert",              XrmoptionNoArg, "top" },
+  { "-bottom",         ".insert",              XrmoptionNoArg, "bottom" },
+  { "-both",           ".insert",              XrmoptionNoArg, "both" },
+  { "-density",                ".density",             XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+
+void
+screenhack (Display *dpy, Window window)
+{
+  m_state *state = init_matrix (dpy, window);
+  int delay = get_integer_resource ("delay", "Integer");
+  while (1)
+    {
+      draw_matrix (state);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
+      if (delay) usleep (delay);
+    }
+}
index a3a9a840c9c968f572eedf21c772f17ab298967c..ec96853e39367c6f46a662fc03933716a24ff35a 100644 (file)
--- a/setup.com
+++ b/setup.com
@@ -58,6 +58,7 @@ $ noseguy     :== $'mydir'noseguy
 $ pedal                :== $'mydir'pedal
 $ penetrate    :== $'mydir'penetrate
 $ penrose      :== $'mydir'penrose
 $ pedal                :== $'mydir'pedal
 $ penetrate    :== $'mydir'penetrate
 $ penrose      :== $'mydir'penrose
+$ phosphor     :== $'mydir'phosphor
 $ pyro         :== $'mydir'pyro
 $ qix          :== $'mydir'qix
 $ rd-bomb      :== $'mydir'rd-bomb
 $ pyro         :== $'mydir'pyro
 $ qix          :== $'mydir'qix
 $ rd-bomb      :== $'mydir'rd-bomb
@@ -84,6 +85,7 @@ $ worm                :== $'mydir'worm
 $ xflame       :== $'mydir'xflame
 $ xjack                :== $'mydir'xjack
 $ xlyap                :== $'mydir'xlyap
 $ xflame       :== $'mydir'xflame
 $ xjack                :== $'mydir'xjack
 $ xlyap                :== $'mydir'xlyap
+$ xmatrix      :== $'mydir'xmatrix
 $ xroger       :== $'mydir'xroger
 $ set def [-.DRIVER]
 $ mydir  = mydisk+f$directory()
 $ xroger       :== $'mydir'xroger
 $ set def [-.DRIVER]
 $ mydir  = mydisk+f$directory()
index b568a24dd11d9379b69034746bc1b855d3bc76ee..698bc9402fbeeec33d63570a0c6d240f2b645355 100644 (file)
@@ -560,7 +560,8 @@ make_uniform_colormap (Display *dpy, Visual *visual, Colormap cmap,
                  0,   S, V,
                  359, S, V,
                  colors, &ncolors,
                  0,   S, V,
                  359, S, V,
                  colors, &ncolors,
-                 False, True, wanted_writable);
+                 False, True,
+                  (writable_pP && *writable_pP));
 
   /* If we tried for writable cells and got none, try for non-writable. */
   if (allocate_p && *ncolorsP == 0 && writable_pP && *writable_pP)
 
   /* If we tried for writable cells and got none, try for non-writable. */
   if (allocate_p && *ncolorsP == 0 && writable_pP && *writable_pP)
index 6e82718df27444a602399a1fd6375a8e443bbba1..ddd415786ab1e6daf7be623cfb05734c15c25a28 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
 static const char screensaver_id[] =
-       "@(#)xscreensaver 3.09 (11-Apr-99), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 3.10 (27-Apr-99), by Jamie Zawinski (jwz@jwz.org)";
index dfe67b66de41a4541458799d8d2455ba15299b17..12e7a5b03be6fa6a1b2787d448f09914613b52c1 100644 (file)
@@ -1,7 +1,7 @@
 Begin3
 Title:          xscreensaver
 Begin3
 Title:          xscreensaver
-Version:        3.09
-Entered-date:   11APR99
+Version:        3.10
+Entered-date:   27APR99
 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.
 Description:    A modular screen saver and locker for the X Window System.
                 Highly customizable: allows the use of any program that
                 can draw on the root window as a display mode.
@@ -10,16 +10,16 @@ Keywords:       screen saver, screen lock, lock, xlock, X11
 Author:         jwz@jwz.org (Jamie Zawinski)
 Maintained-by:  jwz@jwz.org (Jamie Zawinski)
 Primary-site:   http://www.jwz.org/xscreensaver/
 Author:         jwz@jwz.org (Jamie Zawinski)
 Maintained-by:  jwz@jwz.org (Jamie Zawinski)
 Primary-site:   http://www.jwz.org/xscreensaver/
-                1047K xscreensaver-3.09.tar.gz
-                29K  xscreensaver.README
+                1081K xscreensaver-3.10.tar.gz
+                30K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
                 1K   xscreensaver.lsm
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
-                1047K xscreensaver-3.09.tar.gz
-                29K  xscreensaver.README
+                1081K xscreensaver-3.10.tar.gz
+                30K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: ftp.x.org /contrib/applications/
                 1K   xscreensaver.lsm
 Alternate-site: ftp.x.org /contrib/applications/
-                1047K xscreensaver-3.09.tar.gz
-                29K  xscreensaver.README
+                1081K xscreensaver-3.10.tar.gz
+                30K  xscreensaver.README
                 1K   xscreensaver.lsm
 Platforms:      Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
                 BSDI, SCO, OSF1, Ultrix, VMS.
                 1K   xscreensaver.lsm
 Platforms:      Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
                 BSDI, SCO, OSF1, Ultrix, VMS.
index bab9a8fc19ea6c3692af125bb806d08ec7a8da90..c7b265c29a9dc05800cf686e990c21ac64b67635 100644 (file)
@@ -1,7 +1,7 @@
 Name: xscreensaver
 Summary: X screen saver and locker
 Vendor: Jamie Zawinski <jwz@jwz.org>
 Name: xscreensaver
 Summary: X screen saver and locker
 Vendor: Jamie Zawinski <jwz@jwz.org>
-Version: 3.09
+Version: 3.10
 Release: 1
 URL: http://www.jwz.org/xscreensaver/
 Source: xscreensaver-%{version}.tar.gz
 Release: 1
 URL: http://www.jwz.org/xscreensaver/
 Source: xscreensaver-%{version}.tar.gz