]> git.hungrycats.org Git - xscreensaver/commitdiff
From https://www.jwz.org/xscreensaver/xscreensaver-6.13.tar.gz
authorZygo Blaxell <zblaxell@waya.furryterror.org>
Wed, 3 Dec 2025 16:59:57 +0000 (11:59 -0500)
committerZygo Blaxell <xss@mirrors.furryterror.org>
Wed, 3 Dec 2025 17:01:19 +0000 (12:01 -0500)
-rw-rw-r-- 1 zblaxell zblaxell 25233110 Dec  2 20:25 xscreensaver-6.13.tar.gz
7c48fc1dfbbe7a9f9852658d2437068c8bd0a5f2  xscreensaver-6.13.tar.gz

131 files changed:
Makefile.in
OSX/Randomizer.plist
OSX/SaverRunner.plist
OSX/Updater.plist
OSX/XScreenSaver.plist
OSX/bindist.rtf
OSX/iSaverRunner.plist
OSX/tvSaverRunner.plist
OSX/updates.xml
OSX/xscreensaver.xcodeproj/project.pbxproj
README
aclocal.m4
android/xscreensaver/jni/Android.mk
config.h.in
configure
configure.ac
debian/README [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/docs [new file with mode: 0644]
debian/postinst [new file with mode: 0755]
debian/prerm [new file with mode: 0755]
debian/rules [new file with mode: 0755]
debian/source/format [new file with mode: 0644]
debian/watch [new file with mode: 0644]
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/demo-Gtk.c
driver/dialog.c
driver/fade.c
driver/test-wayland-lock.c [new file with mode: 0644]
driver/wayland-dpms.c
driver/wayland-dpy.c
driver/wayland-dpy.h
driver/wayland-idle.c
driver/wayland-lock.h [new file with mode: 0644]
driver/wayland-protocols/ext-session-lock-v1-client-protocol.h [new file with mode: 0644]
driver/wayland-protocols/ext-session-lock-v1-protocol.c [new file with mode: 0644]
driver/wayland-protocols/ext-session-lock-v1.xml [new file with mode: 0644]
driver/wayland-protocols/xdg-shell-v1-client-protocol.h [deleted file]
driver/wayland-protocols/xdg-shell-v1-protocol.c [deleted file]
driver/wayland-protocols/xdg-shell.xml [deleted file]
driver/xscreensaver.c
hacks/Makefile.in
hacks/ansi-tty.c
hacks/binaryhorizon.man
hacks/bsod.c
hacks/celtic.man
hacks/config/README
hacks/config/endgame.xml
hacks/config/glslideshow.xml
hacks/droste.c
hacks/eruption.man
hacks/ffmpeg-out.c
hacks/filmleader.c
hacks/fonts/Makefile.in
hacks/fonts/OCRAStd.otf [deleted file]
hacks/fonts/gallant12x22-bsd.c [new file with mode: 0644]
hacks/glx/Makefile.in
hacks/glx/atunnel.man
hacks/glx/beats.man
hacks/glx/carousel.c
hacks/glx/chessgames.h
hacks/glx/chompytower.c
hacks/glx/crumbler.c
hacks/glx/cubestack.c
hacks/glx/cubetwist.c
hacks/glx/cubocteversion.man
hacks/glx/dumpsterfire.c
hacks/glx/dymaxionmap.c
hacks/glx/endgame.c
hacks/glx/endgame.man
hacks/glx/esper.c
hacks/glx/gibson.c
hacks/glx/glhanoi.c
hacks/glx/glslideshow.c
hacks/glx/glslideshow.man
hacks/glx/grab-ximage.c
hacks/glx/handsy.c
hacks/glx/hydrostat.c
hacks/glx/mapscroller.c
hacks/glx/mirrorblob.c
hacks/glx/nakagin.c
hacks/glx/noof.man
hacks/glx/polyhedra.man
hacks/glx/raverhoop.c
hacks/glx/skulloop.c
hacks/glx/sonar-icmp.c
hacks/glx/sonar.c
hacks/glx/sphereeversion.man
hacks/glx/squirtorus.c
hacks/glx/texfont.c
hacks/glx/tronbit.c
hacks/glx/unknownpleasures.c
hacks/glx/voronoi.c
hacks/glx/xlock-gl-utils.c
hacks/halftone.man
hacks/m6502.c
hacks/m6502.man
hacks/metaballs.man
hacks/pong.c
hacks/popsquares.man
hacks/recanim.c
hacks/tessellimage.c
hacks/vfeedback.c
hacks/xscreensaver-getimage-file
hacks/xscreensaver-getimage-file.man
hacks/xscreensaver-getimage-video.man
hacks/xscreensaver-getimage.c
hacks/xscreensaver-getimage.man
hacks/xscreensaver-text.man
jwxyz/jwxyz-android.c
jwxyz/jwxyz-timers.c
po/Makefile.in.in
po/POTFILES.in
po/ka.po [new file with mode: 0644]
utils/Makefile.in
utils/doubletime.c [new file with mode: 0644]
utils/doubletime.h [new file with mode: 0644]
utils/easing.c [new file with mode: 0644]
utils/easing.h [new file with mode: 0644]
utils/erase.c
utils/grabclient.c
utils/grabclient.h
utils/screenshot.c
utils/utf8wc.c
utils/version.h
utils/visual-gl.c
xscreensaver.spec

index df7843b08e8ce8fe8d8324a0712e13568e790676..fbac48c6046bd1ebd306dc65518ad86a4b32df5e 100644 (file)
@@ -14,10 +14,22 @@ TARFILES    = README README.hacking INSTALL \
                  install-sh config.guess config.rpath aclocal.m4 \
                  ax_pthread.m4 config.sub \
                  intltool-merge.in intltool-extract.in intltool-update.in \
-                 xscreensaver.spec
+                 xscreensaver.spec $(DEBFILES)
 
-TAR            = gnutar
-TAR_ARGS       = --owner=0 --group=0 --posix --no-acls --no-xattrs --no-selinux
+DEBFILES       = debian/changelog \
+                 debian/control \
+                 debian/copyright \
+                 debian/docs \
+                 debian/postinst \
+                 debian/prerm \
+                 debian/README \
+                 debian/rules \
+                 debian/source/format \
+                 debian/watch
+
+TAR            = @TAR@
+TAR_ARGS       = -v --owner=0 --group=0 --posix --no-acls --no-xattrs --no-selinux
+TAR_DIR                = archive
 
 
 # Using $(MAKE) directly means the shell executes things even with "make -n"
@@ -83,7 +95,8 @@ _tar:
   NAME="xscreensaver-$$VERS" ;                                             \
   rm -rf $$NAME ; ln -s . $$NAME ;                                         \
   LIST="tar$$$$.txt" ;                                                     \
-  ADIR=archive/ ;                                                          \
+  ADIR="$(TAR_DIR)" ;                                                      \
+  [ -d "$$ADIR" ] || mkdir "$$ADIR" ;                                      \
   rm -f "$$LIST" ;                                                         \
   for subdir in . $(SUBDIRS2) ; do                                         \
     ( cd $$subdir ;                                                        \
@@ -93,10 +106,10 @@ _tar:
         | sed -e "s@/\./@/@g"                                              \
     ) >> "$$LIST" ;                                                        \
   done ;                                                                   \
-  echo creating tar file $$ADIR$$NAME.tar.gz... ;                          \
+  echo creating tar file $$ADIR/$$NAME.tar.gz... ;                         \
   export COPYFILE_DISABLE=true ;                                           \
   export GZIP="-9v" ;                                                      \
-  $(TAR) -vczf $$ADIR$$NAME.tar.gz -T "$$LIST" $(TAR_ARGS) ;               \
+  $(TAR) -czf $$ADIR/$$NAME.tar.gz -T "$$LIST" $(TAR_ARGS) ;               \
   rm "$$LIST" "$$NAME"
 
 
@@ -234,20 +247,25 @@ version-date::
 
 
 update_spec_version::
-       @S=$(srcdir)/xscreensaver.spec ;                                    \
+       @                                                                   \
+       S1=$(srcdir)/xscreensaver.spec ;                                    \
+       S2=$(srcdir)/debian/changelog ;                                     \
        U=$(srcdir)/utils/version.h ;                                       \
        VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' < $$U |       \
          head -1` ;                                                        \
-       /bin/echo -n "Updating $$S to \"$$VERS\"... " ;                     \
        T=/tmp/xs.$$$$ ;                                                    \
-       sed "s/^\(%define.version[^0-9]*\)\(.*\)/\1$$VERS/"                 \
-         < $$S > $$T ;                                                     \
-       if cmp -s $$S $$T ; then                                            \
-         echo "unchanged." ;                                               \
-       else                                                                \
-         cat $$T > $$S ;                                                   \
-         echo "done." ;                                                    \
-       fi ;                                                                \
+       for F in "$$S1" "$$S2" ; do                                         \
+         /bin/echo -n "Updating $$F to \"$$VERS\"... " ;                   \
+         sed -e "s/^\(%define.version[^0-9]*\)\(.*\)/\1$$VERS/"            \
+             -e "s/([-0-9.]*)/($$VERS-1)/"                                 \
+           < "$$F" > "$$T" ;                                               \
+         if cmp -s "$$F" "$$T" ; then                                      \
+           echo "unchanged." ;                                             \
+         else                                                              \
+           cat "$$T" > "$$F" ;                                             \
+           echo "done." ;                                                  \
+         fi ;                                                              \
+       done ;                                                              \
        rm $$T
 
 rpm::
@@ -259,7 +277,7 @@ rpm::
   ADIR=archive/ ;                                                         \
   TGZ=xscreensaver-$$VERS.tar.gz ;                                        \
   if [ ! -f $${ADIR}$$TGZ ]; then                                         \
-    echo "$${ADIR}$$TGZ does not exist!  Did you forget to \`make tar'?" ; \
+    echo "$${ADIR}$$TGZ does not exist: do 'make tar' first." ;                   \
     exit 1 ;                                                              \
   fi ;                                                                    \
   rm -rf /var/tmp/xscreensaver-$$VERS-root ;                              \
@@ -284,6 +302,39 @@ rpm::
   echo '' ;                                                               \
   ls -lFG xscreensaver*-$$VERS-*.rpm
 
+deb::
+       @                                                                  \
+  VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' utils/version.h |  \
+         head -1` ;                                                       \
+  DIR=debian/build ;                                                      \
+  ADIR=archive/ ;                                                         \
+  TGZ=xscreensaver-$$VERS.tar.gz ;                                        \
+  TGZ2=xscreensaver_$$VERS.orig.tar.gz ;                                  \
+  if [ ! -f $${ADIR}$$TGZ ]; then                                         \
+    echo "$${ADIR}$$TGZ does not exist: do 'make tar' first." ;                   \
+    exit 1 ;                                                              \
+  fi ;                                                                    \
+                                                                          \
+  set -e ;                                                                \
+  set -x ;                                                                \
+  rm -rf $$DIR ;                                                          \
+  mkdir $$DIR ;                                                                   \
+  cp -p "$${ADIR}$$TGZ" "$$DIR/$$TGZ2" ;                                  \
+                                                                          \
+  ( cd $$DIR ;                                                            \
+    $(TAR) -zxf "$$TGZ2" ;                                                \
+    cd xscreensaver-$$VERS ;                                              \
+    dpkg-buildpackage -us -uc ;                                                   \
+  ) ;                                                                     \
+  set +x ;                                                                \
+  echo '' ;                                                               \
+  echo 'DEB build complete' ;                                             \
+  echo '' ;                                                               \
+  rm -rf "$$DIR/xscreensaver-$$VERS" ;                                    \
+  rm -f  "$$DIR/$$TGZ2" ;                                                 \
+  echo '' ;                                                               \
+  ls -lFGd "$$DIR/xscreensaver"*
+
 dmg::
        $(MAKE2) -C OSX release dmg
 apk::
@@ -458,12 +509,10 @@ install_links::
 
 
 cerebrum::
-       rsync -vax . 10.0.1.37:xscreensaver/ \
+       rsync -vax . 10.0.1.42:xscreensaver/ \
        --omit-dir-times \
        --delete-during \
        --exclude .git \
-       --exclude OSX \
-       --exclude android \
        --exclude archive \
        --exclude build \
        --exclude gen \
@@ -473,10 +522,12 @@ cerebrum::
        --include xscreensaver-getimage-file \
        --include xscreensaver-getimage-video \
        --include xscreensaver-text \
-       --exclude xscreensaver-5.45 \
-       --exclude xscreensaver-6.00 \
-       --exclude xscreensaver-6.01 \
-       --exclude xscreensaver-6.02 \
+       --exclude android/gradle \
+       --exclude android/xscreensaver/obj \
+       --exclude android/xscreensaver/res \
+       --exclude android/xscreensaver/libs \
+       --exclude android/.gradle \
+       --exclude android/.idea \
        --exclude '*~' \
        --include '*.asm' \
        --include '*.c' \
@@ -508,6 +559,20 @@ cerebrum::
        --include 'ad2c' \
        --include 'vidwhacker' \
        --include 'webcollage' \
+       --include 'debian/*' \
+       --include 'README' \
+       --include 'README.hacking' \
+       --include 'INSTALL' \
+       --include 'ChangeLog' \
+       --include '*.pdf' \
+       --include '*.pov' \
+       --include '*.txt' \
+       --include '*.tex' \
+       --include '*.dxf' \
+       --include '*.dtd' \
+       --include '*.xsd' \
+       --include '*.pbxproj' \
+       --include '.gdbinit' \
        --include '*/' \
        --exclude '*'
 
index 4be9147395daaa1ba2d400b811b59081d3e0f05d..e00b033815116849f366e423be35cf27adaf25b4 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>NSPrincipalClass</key>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.entertainment</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleLongVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleGetInfoString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSHumanReadableCopyright</key>
-       <string>6.12</string>
+       <string>6.13</string>
 </dict>
 </plist>
index 5018dfafa219233f62296e1da7a85e3f19eb9c42..3c5a81eab8eba8157c5bb9859303b26edf65fd8c 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>NSPrincipalClass</key>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.entertainment</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleLongVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleGetInfoString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSHumanReadableCopyright</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIconFile</key>
index 3e748a2773ce65962606b77fc2f2c2133ee6334b..c0428c10daa4210729e3e3b9844300001290ab6f 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>NSPrincipalClass</key>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.entertainment</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleLongVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleGetInfoString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSHumanReadableCopyright</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSMainNibFile</key>
        <string>Updater</string>
        <key>CFBundleIconFile</key>
index ff870205488805d6ae6b37b6b495a8c144f46afa..b3d7ebf00419fb3cbe651c4477acd13c11d9142f 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>NSPrincipalClass</key>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.entertainment</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleLongVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleGetInfoString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSHumanReadableCopyright</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
 </dict>
index 3c249e870eb5ed57ac302d871b86c10ccbd93325..2859048585868bc8ec666c2c32255201a82f9b61 100644 (file)
@@ -16,8 +16,8 @@
 \b0 by Jamie Zawinski\
 and many others\
 \
-version 6.12\
-07-Jul-2025\
+version 6.13\
+02-Dec-2025\
 \
 {\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 https://www.jwz.org/xscreensaver/}}\
 \pard\pardeftab720
index 12df7001bfc34a18f24a443c12b408ed55b6faac..20fde09732c2dd6a0c9b002fc37f0d0d148f3e67 100644 (file)
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.entertainment</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleLongVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleGetInfoString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSHumanReadableCopyright</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSMainNibFile</key>
        <string>iSaverRunner</string>
        <key>CFBundleDisplayName</key>
index 5ccbe808d4ae051e0f15026ca0784fc45a392029..14cbc742c1755be3b7bf51644a3edab2074bcfe9 100644 (file)
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.entertainment</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleLongVersionString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleGetInfoString</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>NSHumanReadableCopyright</key>
-       <string>6.12</string>
+       <string>6.13</string>
        <key>CFBundleDisplayName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundleIcons</key>
index 1971a9a15e7fea05a736e461ef651ce633ab4edb..3af125cbf300d0726932f00da06f6234d155069d 100644 (file)
@@ -7,6 +7,17 @@
   <link>https://www.jwz.org/xscreensaver/updates.xml</link>
   <description>Updates to xscreensaver.</description>
   <language>en</language>
+  <item>
+   <title>Version 6.13</title>
+   <link>https://www.jwz.org/xscreensaver/xscreensaver-6.13.dmg</link>
+   <description><![CDATA[&bull; Added a number of historical full chess games to `endgame`. <BR>&bull; Rewrote `glslideshow' to add more image-transition effects. <BR>&bull; Hacks that display images and their filenames will display their titles intead, if the image originated in an RSS feed (or has the "user.dublincore.title" xattr). ]]></description>
+   <pubDate>Tue, 02 Dec 2025 17:09:25 -0800</pubDate>
+   <enclosure url="https://www.jwz.org/xscreensaver/xscreensaver-6.13.dmg"
+    sparkle:version="6.13"
+    sparkle:edSignature="zQn7puQXjOWX0VQ05W9IUETdCkfAWOtugFaeqKnWT5E4d5+GCV1Aq6DMSOMqXzKjisKCXcsqAz5duVp7P8/kDw=="
+    length="102813232"
+    type="application/octet-stream" />
+  </item>
   <item>
    <title>Version 6.10</title>
    <link>https://www.jwz.org/xscreensaver/xscreensaver-6.10.dmg</link>
index 7d6d4b60320c2414b345b90db0f3c81daa00e7e1..17bcfed70de70f19d5dbc757e99743563fc595af 100644 (file)
                AF2D86B62DB2100A00B4F248 /* klondike-game.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86AD2DB2100A00B4F248 /* klondike-game.c */; };
                AF2D8F321CEBA10300198014 /* jwxyz-timers.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D8F301CEBA10300198014 /* jwxyz-timers.c */; };
                AF2D8F331CEBA10300198014 /* jwxyz-timers.h in Headers */ = {isa = PBXBuildFile; fileRef = AF2D8F311CEBA10300198014 /* jwxyz-timers.h */; };
+               AF2DBDFE2EDE7D1D008774B9 /* easing.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2DBDFD2EDE7D1D008774B9 /* easing.c */; };
+               AF2DBDFF2EDE7D1D008774B9 /* easing.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2DBDFD2EDE7D1D008774B9 /* easing.c */; };
+               AF2DBE002EDE7D1D008774B9 /* easing.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2DBDFD2EDE7D1D008774B9 /* easing.c */; };
+               AF2DBE022EDE97C1008774B9 /* doubletime.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2DBE012EDE97C1008774B9 /* doubletime.c */; };
+               AF2DBE032EDE97C1008774B9 /* doubletime.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2DBE012EDE97C1008774B9 /* doubletime.c */; };
+               AF2DBE042EDE97C1008774B9 /* doubletime.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2DBE012EDE97C1008774B9 /* doubletime.c */; };
                AF32D9E70F3AD0B40080F535 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF32D9FB0F3AD1200080F535 /* rubikblocks.c in Sources */ = {isa = PBXBuildFile; fileRef = AF32D9FA0F3AD1200080F535 /* rubikblocks.c */; };
                AF32D9FD0F3AD1330080F535 /* rubikblocks.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF32D9FC0F3AD1330080F535 /* rubikblocks.xml */; };
                AF2D86AD2DB2100A00B4F248 /* klondike-game.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "klondike-game.c"; path = "../hacks/glx/klondike-game.c"; sourceTree = SOURCE_ROOT; };
                AF2D8F301CEBA10300198014 /* jwxyz-timers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-timers.c"; path = "../jwxyz/jwxyz-timers.c"; sourceTree = "<group>"; };
                AF2D8F311CEBA10300198014 /* jwxyz-timers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "jwxyz-timers.h"; path = "../jwxyz/jwxyz-timers.h"; sourceTree = "<group>"; };
+               AF2DBDFD2EDE7D1D008774B9 /* easing.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = easing.c; path = utils/easing.c; sourceTree = "<group>"; };
+               AF2DBE012EDE97C1008774B9 /* doubletime.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = doubletime.c; path = utils/doubletime.c; sourceTree = "<group>"; };
                AF32D9F40F3AD0B40080F535 /* RubikBlocks.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RubikBlocks.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF32D9FA0F3AD1200080F535 /* rubikblocks.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = rubikblocks.c; path = hacks/glx/rubikblocks.c; sourceTree = "<group>"; };
                AF32D9FC0F3AD1330080F535 /* rubikblocks.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = rubikblocks.xml; sourceTree = "<group>"; };
                                AF9D473709B52EE0006E59CF /* colorbars.h */,
                                AFC25B990988BC08000655EE /* colors.c */,
                                AFC25B9A0988BC08000655EE /* colors.h */,
+                               AF2DBE012EDE97C1008774B9 /* doubletime.c */,
+                               AF2DBDFD2EDE7D1D008774B9 /* easing.c */,
                                AFE1FD530981E3CB00F7970E /* erase.c */,
                                AFE1FD540981E3CB00F7970E /* erase.h */,
                                AF939AD220351BFC0032DD23 /* font-retry.c */,
                                AFBF893E0E41D930006A2D66 /* fps.c in Sources */,
                                AFBF89AF0E423FC3006A2D66 /* fps-gl.c in Sources */,
                                5501D1961DBDCC3D00624BE9 /* xshm.c in Sources */,
+                               AF2DBE022EDE97C1008774B9 /* doubletime.c in Sources */,
                                AF4808C9098C3BEC00FB32B8 /* jwxyz.m in Sources */,
                                AFDA11251934424D003D397F /* aligned_malloc.c in Sources */,
                                AF4808CC098C3BF200FB32B8 /* spline.c in Sources */,
                                AFDA11271934424D003D397F /* thread_util.c in Sources */,
                                AF975C93099C929800B05160 /* ximage-loader.c in Sources */,
                                CE8EA1C21C35CF10002D1020 /* jwxyz-common.c in Sources */,
+                               AF2DBDFE2EDE7D1D008774B9 /* easing.c in Sources */,
                                AF4774E8099D8D8C001F091E /* logo.c in Sources */,
                                AF4775C0099D9E79001F091E /* resources.c in Sources */,
                                AF9D468F09B51567006E59CF /* grabclient-osx.m in Sources */,
                                AF568A5326E7060500CCBA38 /* slip.c in Sources */,
                                AF568A5426E7060500CCBA38 /* strange.c in Sources */,
                                AF568A5526E7060500CCBA38 /* swirl.c in Sources */,
+                               AF2DBE032EDE97C1008774B9 /* doubletime.c in Sources */,
                                AF568A5626E7060500CCBA38 /* textclient-mobile.c in Sources */,
                                AF568A5726E7060500CCBA38 /* tessellimage.c in Sources */,
                                AF568A5826E7060500CCBA38 /* triangle.c in Sources */,
                                AF568AA226E7060500CCBA38 /* gears.c in Sources */,
                                AF568AA326E7060500CCBA38 /* geodesicgears.c in Sources */,
                                AF568AA426E7060500CCBA38 /* gflux.c in Sources */,
+                               AF2DBDFF2EDE7D1D008774B9 /* easing.c in Sources */,
                                AF568AA526E7060500CCBA38 /* gibson.c in Sources */,
                                AF568AA626E7060500CCBA38 /* glblur.c in Sources */,
                                AF568AA726E7060500CCBA38 /* glcells.c in Sources */,
                                AF918A1F158FC38A002B5D1E /* slip.c in Sources */,
                                AF918A22158FC38A002B5D1E /* strange.c in Sources */,
                                AF918A23158FC38A002B5D1E /* swirl.c in Sources */,
+                               AF2DBE042EDE97C1008774B9 /* doubletime.c in Sources */,
                                AFA211891CD1AA2E00C0D2A1 /* textclient-mobile.c in Sources */,
                                AF68A49A19196E3E00D41CD1 /* tessellimage.c in Sources */,
                                AF918A25158FC38A002B5D1E /* triangle.c in Sources */,
                                AF918A5A158FC3E5002B5D1E /* gears.c in Sources */,
                                AFDDCCED19FF0EBD0072365B /* geodesicgears.c in Sources */,
                                AF918A5B158FC3E5002B5D1E /* gflux.c in Sources */,
+                               AF2DBE002EDE7D1D008774B9 /* easing.c in Sources */,
                                AFA0B137241CE7B60071E35D /* gibson.c in Sources */,
                                AF918A5C158FC3E5002B5D1E /* glblur.c in Sources */,
                                AF918A5D158FC3E5002B5D1E /* glcells.c in Sources */,
                                        "HAVE_ICMP=1",
                                        "HAVE_GETIFADDRS=1",
                                        "HAVE_FORKPTY=1",
+                                       "HAVE_GETXATTR=1",
+                                       "XATTR_ADDITIONAL_OPTIONS=1",
                                        "HAVE_UTIL_H=1",
                                        "HAVE_PTHREAD=1",
                                        "HAVE_GETADDRINFO=1",
                                        "HAVE_ICMP=1",
                                        "HAVE_GETIFADDRS=1",
                                        "HAVE_FORKPTY=1",
+                                       "HAVE_GETXATTR=1",
+                                       "XATTR_ADDITIONAL_OPTIONS=1",
                                        "HAVE_UTIL_H=1",
                                        "HAVE_PTHREAD=1",
                                        "HAVE_GETADDRINFO=1",
diff --git a/README b/README
index 9fc2c3151fa28a3b40e6a7dc67a162003da949c6..4199de03d8ce16bc5f1b6556fcb72e1b0dddf87e 100644 (file)
--- a/README
+++ b/README
@@ -41,6 +41,8 @@ To compile for a Unix system with X11:
         libxinerama libxrandr libxxf86vm libgl libglu libgle libgtk-3
         libgdk-pixbuf2.0 libjpeg libxml2 libpam libsystemd elogind libwayland
 
+    You can build a package-manager version with "make rpm" or "make deb".
+
     BSD systems might need gmake instead of make.
 
 
@@ -69,6 +71,17 @@ Interested in writing a new screen saver?
 Version History
 ===============================================================================
 
+6.13   * Added a number of historical full chess games to `endgame`.
+       * Rewrote `glslideshow' to add more image-transition effects.
+        * Hacks that display images and their filenames will display their
+          titles intead, if the image originated in an RSS feed (or has
+          the "user.dublincore.title" xattr).
+       * X11: Wayland fixes.
+       * X11: Some hacks were calling glXSwapBuffers before the first call
+         to glXMakeCurrent; allow it.
+       * X11: Added configuration files to allow building of a non-insane
+          `.deb' installer package.
+
 6.12   * X11: DPMS works on Wayland.
        * X11: Fading uses GL now which should be more performant.
 
index 02e15a036a9bc1ec4df28373f3b0744e0791af53..7f1f48d39b3eb9a20d08a1b092579f4ff26dbd46 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.17 -*- Autoconf -*-
+# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2024 Free Software Foundation, Inc.
+# Copyright (C) 1996-2025 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -3456,7 +3456,7 @@ fi
 AC_SUBST([$1])dnl
 ])
 
-# Copyright (C) 2006-2024 Free Software Foundation, Inc.
+# Copyright (C) 2006-2025 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index 28e0e1a163448a25fb58a78003674bbee9522acc..92f906629f10d5f5afc0a54810eede47efb1228b 100644 (file)
@@ -174,6 +174,8 @@ LOCAL_SRC_FILES += \
     utils/aligned_malloc.c \
     utils/colorbars.c \
     utils/colors.c \
+    utils/doubletime.c \
+    utils/easing.c \
     utils/erase.c \
     utils/font-retry.c \
     utils/grabclient.c \
index 94f888e124d453f3b2489218017b29de2982498c..af949bb50526e34863248dbd45aef33b39003e79 100644 (file)
@@ -90,6 +90,9 @@
 /* Define to 1 if you have the 'getwd' function. */
 #undef HAVE_GETWD
 
+/* Define to 1 if you have the 'getxattr' function. */
+#undef HAVE_GETXATTR
+
 /* Define this if you have OpenGL. */
 #undef HAVE_GL
 
    backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
+/* Define if xattr functions take additional arguments (macOS) */
+#undef XATTR_ADDITIONAL_OPTIONS
+
 /* Stare into the void. */
 #undef XPointer
 
index 894999ee2a4c0a83f627556eeca1645f824e4816..871581edd1bc7f14961ce38e93d18bffa312a541 100755 (executable)
--- a/configure
+++ b/configure
@@ -688,6 +688,7 @@ SETUID_HACKS
 SETUID_AUTH
 PROG_SETCAP
 WAYLAND_GTK_OBJS
+WAYLAND_LOCK_OBJS
 WAYLAND_DPMS_OBJS
 WAYLAND_IDLE_OBJS
 WAYLAND_DPY_OBJS
@@ -786,6 +787,7 @@ X_LIBS
 X_PRE_LIBS
 X_CFLAGS
 XMKMF
+TAR
 PERL
 SET_MAKE
 INSTALL_DATA
@@ -1575,7 +1577,9 @@ User Interface Options:
 Graphics Options:
 
   --with-gles             Emulate OpenGL 1.3 in terms of OpenGL ES 1.x.
+                          Do not do this: it doesn't mean what you think.
   --with-glx              Use GLX to interface OpenGL and X11 instead of EGL.
+                          Do not do this: it will make GLSL fail.
   --with-gle              Include support for the GL Extrusion library.
   --with-jpeg             Include support for the JPEG library.
   --with-png              Include support for the PNG library.
@@ -5385,6 +5389,49 @@ then :
 
 fi
 
+ac_fn_c_check_func "$LINENO" "getxattr" "ac_cv_func_getxattr"
+if test "x$ac_cv_func_getxattr" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETXATTR 1" >>confdefs.h
+
+fi
+
+  if test "$ac_cv_func_getxattr" = yes ; then
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getxattr extra args" >&5
+printf %s "checking for getxattr extra args... " >&6; }
+if test ${ac_cv_xattr_extra_args+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/xattr.h>
+int
+main (void)
+{
+getxattr("", "", "", 0, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_xattr_extra_args=yes
+else case e in #(
+  e) ac_cv_xattr_extra_args=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_xattr_extra_args" >&5
+printf "%s\n" "$ac_cv_xattr_extra_args" >&6; }
+    if test "$ac_cv_xattr_extra_args" = yes; then
+
+printf "%s\n" "#define XATTR_ADDITIONAL_OPTIONS 1" >>confdefs.h
+
+    fi
+  fi
 ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "#include <sys/socket.h>
 "
 if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes
@@ -5676,11 +5723,63 @@ printf "%s\n" "$ac_cv_perl_version" >&6; }
     PERL_VERSION=$ac_cv_perl_version
   fi
 
+for ac_prog in gnutar tar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_TAR+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) case $TAR in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_TAR="$TAR" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_TAR="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac ;;
+esac
+fi
+TAR=$ac_cv_path_TAR
+if test -n "$TAR"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TAR" >&5
+printf "%s\n" "$TAR" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  test -n "$TAR" && break
+done
+
 if test -z "$PERL" ; then
   # don't let it be blank...
   PERL=/usr/bin/perl
 fi
 
+if test -z "$TAR" ; then TAR=tar ; fi
+
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X" >&5
 printf %s "checking for X... " >&6; }
 
@@ -13532,6 +13631,7 @@ printf "%s\n" "$ac_cv_wayland_config_libs" >&6; }
   WAYLAND_DPY_OBJS=""
   WAYLAND_IDLE_OBJS=""
   WAYLAND_DPMS_OBJS=""
+  WAYLAND_LOCK_OBJS=""
   WAYLAND_GTK_OBJS=""
   if test "$have_wayland" = yes; then
     WAYLAND_DATADIR=`$pkg_config --variable=prefix wayland-client`
@@ -13540,6 +13640,7 @@ printf "%s\n" "$ac_cv_wayland_config_libs" >&6; }
     WAYLAND_DPY_OBJS='$(WAYLAND_DPY_OBJS_1)'
     WAYLAND_IDLE_OBJS='$(WAYLAND_IDLE_OBJS_1)'
     WAYLAND_DPMS_OBJS='$(WAYLAND_DPMS_OBJS_1)'
+    WAYLAND_LOCK_OBJS='$(WAYLAND_LOCK_OBJS_1)'
     WAYLAND_GTK_OBJS='$(WAYLAND_GTK_OBJS_1)'
   fi
 
@@ -18605,7 +18706,7 @@ elif test "$with_gl" = no; then
   # It is the Twenty-First Century, and in This Modern World, every
   # extant microcontroller is more performant than the desktop
   # computers on which I developed most of the OpenGL hacks.
-  exit 1
+  exit 1  # A hearty "fuck you" to my enemies at Debian who keep patching this out.
 
 elif test "$with_gl" != no; then
   echo "error: must be yes or no: --with-gl=$with_gl"
@@ -22960,10 +23061,11 @@ test -d driver/wayland-protocols || mkdir driver/wayland-protocols
 #
 ###############################################################################
 
-CONF_STATUS=0
+CONF_STATUS=0  # Hello Debian, eat my fuck.
 
 warn_prefix_1="    Warning:"
 warn_prefix_2="       Note:"
+warn_prefix_3="      Error:"
 warn_prefix="$warn_prefix_1"
 
 warning=no
@@ -23410,6 +23512,19 @@ if test "$ac_macosx" = yes -a "$enable_locking" = yes ; then
   warn2 "THIS DOES NOT WORK!  Don't do this!"
 fi
 
+# Fucking Gentoo...
+if test "$have_jwzgles" = yes ; then
+  warn_prefix="$warn_prefix_3"
+  warn "The --with-gles option does not do what you think. Do not use it."
+  exit 1
+fi
+
+if test "$have_egl" = no; then
+  warn_prefix="$warn_prefix_3"
+  warn "Using --with-glx means GLSL won't work. Don't do it!"
+  exit 1
+fi
+
 if test "$have_jwzgles" = yes ; then
   warn  "Do not use --with-gles unless you are sure that you know"
   warn2 "what you are doing!  It is not recommended on normal X11"
@@ -23421,6 +23536,11 @@ if test "$have_jwzgles" = yes ; then
   fi
 fi
 
+if test "$setuid_hacks" = no; then
+  warn  "Using --without-setuid-hacks breaks 'sonar' for no good reason."
+  warn2 "Don't do it."
+fi
+
 # You are in a twisty maze of namespaces and syntaxes, all alike.
 # Expand all of these as the Makefile will probably expand them.
 # Fuck the skull of Unix.
index 423ea450d228affdde147a23706251ff55327cd1..e49200f4e8703291a66f0402f968598f5ed0de8a 100644 (file)
@@ -478,6 +478,8 @@ AC_DEFUN([AC_PROG_PERL],
   fi
  ])
 
+AC_DEFUN([AC_PROG_TAR], [AC_PATH_PROGS(TAR, [gnutar tar],,)])
+
 
 ###############################################################################
 #
@@ -876,6 +878,23 @@ AC_DEFUN([AC_TYPE_SOCKLEN_T],
   [Define to `int' if <sys/types.h> or <sys/socket.h> does not define.])
   fi])
 
+AC_DEFUN([AC_CHECK_XATTR],
+ [AC_CHECK_FUNCS(getxattr)
+  if test "$ac_cv_func_getxattr" = yes ; then
+   AC_CACHE_CHECK([for getxattr extra args], ac_cv_xattr_extra_args,
+    [AC_COMPILE_IFELSE(
+     [AC_LANG_PROGRAM(
+      [#include <sys/xattr.h>],
+      [getxattr("", "", "", 0, 0, 0);])],
+     [ac_cv_xattr_extra_args=yes],
+     [ac_cv_xattr_extra_args=no])])
+    if test "$ac_cv_xattr_extra_args" = yes; then
+     AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1,
+      [Define if xattr functions take additional arguments (macOS)])
+    fi]
+  fi)
+
+
 ###############################################################################
 #
 #       Some utility functions to make checking for X things easier.
@@ -1069,6 +1088,7 @@ AC_CHECK_FUNCS(select fcntl uname nice setpriority getcwd getwd putenv sbrk)
 AC_CHECK_FUNCS(sigaction syslog realpath setrlimit)
 AC_CHECK_FUNCS(setlocale sqrtf)
 AC_CHECK_FUNCS(getaddrinfo)
+AC_CHECK_XATTR
 AC_CHECK_MEMBERS([struct sockaddr.sa_len],,, [#include <sys/socket.h>])
 AC_CHECK_ICMP
 AC_CHECK_ICMPHDR
@@ -1076,12 +1096,15 @@ AC_CHECK_GETIFADDRS
 AC_TYPE_SOCKLEN_T
 AC_CHECK_HEADERS(crypt.h sys/select.h)
 AC_PROG_PERL
+AC_PROG_TAR
 
 if test -z "$PERL" ; then
   # don't let it be blank...
   PERL=/usr/bin/perl
 fi
 
+if test -z "$TAR" ; then TAR=tar ; fi
+
 AC_PATH_XTRA
 
 if test "$have_x" != yes; then
@@ -1123,7 +1146,6 @@ if test -z "$pkg_config" ; then
   pkg_config="false"
 fi
 
-
 # Utility function for running pkg-config-based tests...
 #
 pkgs=''
@@ -2239,6 +2261,7 @@ if test "$with_wayland" = yes; then
   WAYLAND_DPY_OBJS=""
   WAYLAND_IDLE_OBJS=""
   WAYLAND_DPMS_OBJS=""
+  WAYLAND_LOCK_OBJS=""
   WAYLAND_GTK_OBJS=""
   if test "$have_wayland" = yes; then
     WAYLAND_DATADIR=`$pkg_config --variable=prefix wayland-client`
@@ -2247,6 +2270,7 @@ if test "$with_wayland" = yes; then
     WAYLAND_DPY_OBJS='$(WAYLAND_DPY_OBJS_1)'
     WAYLAND_IDLE_OBJS='$(WAYLAND_IDLE_OBJS_1)'
     WAYLAND_DPMS_OBJS='$(WAYLAND_DPMS_OBJS_1)'
+    WAYLAND_LOCK_OBJS='$(WAYLAND_LOCK_OBJS_1)'
     WAYLAND_GTK_OBJS='$(WAYLAND_GTK_OBJS_1)'
   fi
 
@@ -3392,7 +3416,8 @@ AC_ARG_WITH(gl,
 [
 Graphics Options:
 
-  --with-gles             Emulate OpenGL 1.3 in terms of OpenGL ES 1.x.],
+  --with-gles             Emulate OpenGL 1.3 in terms of OpenGL ES 1.x.
+                          Do not do this: it doesn't mean what you think.],
   [with_gl="$withval"; with_gl_req="$withval"],[with_gl=yes])
 
 HANDLE_X_PATH_ARG(with_gl, --with-gl, GL)
@@ -3555,7 +3580,7 @@ elif test "$with_gl" = no; then
   # It is the Twenty-First Century, and in This Modern World, every
   # extant microcontroller is more performant than the desktop
   # computers on which I developed most of the OpenGL hacks.
-  exit 1
+  exit 1  # A hearty "fuck you" to my enemies at Debian who keep patching this out.
 
 elif test "$with_gl" != no; then
   echo "error: must be yes or no: --with-gl=$with_gl"
@@ -3573,7 +3598,8 @@ have_glx=no
 have_egl=no
 with_egl_req=unspecified
 AC_ARG_WITH(glx,
-[  --with-glx              Use GLX to interface OpenGL and X11 instead of EGL.],
+[  --with-glx              Use GLX to interface OpenGL and X11 instead of EGL.
+                          Do not do this: it will make GLSL fail.],
   [with_egl="$withval"; with_egl_req="$withval"],
   [with_glx=no])
 
@@ -4528,6 +4554,7 @@ AC_SUBST(WAYLAND_GEN)
 AC_SUBST(WAYLAND_DPY_OBJS)
 AC_SUBST(WAYLAND_IDLE_OBJS)
 AC_SUBST(WAYLAND_DPMS_OBJS)
+AC_SUBST(WAYLAND_LOCK_OBJS)
 AC_SUBST(WAYLAND_GTK_OBJS)
 AC_SUBST(PROG_SETCAP)
 AC_SUBST(SETUID_AUTH)
@@ -4590,6 +4617,7 @@ AC_SUBST(DEPEND)
 AC_SUBST(DEPEND_FLAGS)
 AC_SUBST(DEPEND_DEFINES)
 AC_SUBST(PERL)
+AC_SUBST(TAR)
 
 AC_CONFIG_FILES([Makefile
           utils/Makefile
@@ -4614,10 +4642,11 @@ test -d driver/wayland-protocols || mkdir driver/wayland-protocols
 #
 ###############################################################################
 
-CONF_STATUS=0
+CONF_STATUS=0  # Hello Debian, eat my fuck.
 
 warn_prefix_1="    Warning:"
 warn_prefix_2="       Note:"
+warn_prefix_3="      Error:"
 warn_prefix="$warn_prefix_1"
 
 warning=no
@@ -5075,6 +5104,19 @@ if test "$ac_macosx" = yes -a "$enable_locking" = yes ; then
   warn2 "THIS DOES NOT WORK!  Don't do this!"
 fi
 
+# Fucking Gentoo...
+if test "$have_jwzgles" = yes ; then
+  warn_prefix="$warn_prefix_3"
+  warn "The --with-gles option does not do what you think. Do not use it."
+  exit 1
+fi
+
+if test "$have_egl" = no; then
+  warn_prefix="$warn_prefix_3"
+  warn "Using --with-glx means GLSL won't work. Don't do it!"
+  exit 1
+fi
+
 if test "$have_jwzgles" = yes ; then
   warn  "Do not use --with-gles unless you are sure that you know"
   warn2 "what you are doing!  It is not recommended on normal X11"
@@ -5086,6 +5128,11 @@ if test "$have_jwzgles" = yes ; then
   fi
 fi
 
+if test "$setuid_hacks" = no; then
+  warn  "Using --without-setuid-hacks breaks 'sonar' for no good reason."
+  warn2 "Don't do it."
+fi
+
 
 # You are in a twisty maze of namespaces and syntaxes, all alike.
 # Expand all of these as the Makefile will probably expand them.
diff --git a/debian/README b/debian/README
new file mode 100644 (file)
index 0000000..17172a9
--- /dev/null
@@ -0,0 +1,17 @@
+Here is a build config for Debian that packages XScreenSaver the correct way.
+
+The way Debian packages XScreenSaver is an absolute atrocity: it divides it
+into half a dozen sub-packages, ensuring that some users will accidentally
+end up with a half-installed, nonfunctional installation of XScreenSaver.
+XScreenSaver is a single software package.  That is how I wrote it, how I
+test it, and how it should be distributed.  I have been asking them to
+change this for years and they refuse.
+
+               -- jwz
+
+To build a .deb file, do this in the root of the xscreensaver tree:
+
+       make tar
+       make deb
+
+Files will appear in debian/build/
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..927b6d5
--- /dev/null
@@ -0,0 +1,5 @@
+xscreensaver (6.13-1) unstable; urgency=medium
+
+  * Splitting this into multiple packages is a support nightmare, please don't.
+
+ -- Jamie Zawinski <jwz@jwz.org>  Mon, 11 Aug 2025 16:28:39 -0700
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..860266f
--- /dev/null
@@ -0,0 +1,57 @@
+Source: xscreensaver
+Section: x11
+Priority: optional
+Maintainer: Jamie Zawinski <jwz@jwz.org>
+Build-Depends: debhelper-compat (= 13),
+               autotools-dev,
+               perl,
+               pkg-config,
+               gettext,
+               intltool,
+               libx11-dev,
+               libxext-dev,
+               libxi-dev,
+               libxt-dev,
+               libxft-dev,
+               libxinerama-dev,
+               libxrandr-dev,
+               libxxf86vm-dev,
+               libgl-dev,
+               libglu-dev,
+               libgle-dev,
+               libgtk-3-dev,
+               libgdk-pixbuf2.0-dev,
+               libjpeg-dev,
+               libxml2-dev,
+               libpam-dev,
+               libsystemd-dev,
+               libwayland-dev
+Standards-Version: 4.6.2
+Homepage: https://www.jwz.org/xscreensaver/
+Rules-Requires-Root: no
+
+Package: xscreensaver
+Architecture: any
+Depends: ${misc:Depends},
+         ${shlibs:Depends},
+         attr | xattr,
+         perl
+Recommends: miscfiles | wordlist,
+          fonts-urw-base35 | xfonts-100dpi
+Suggests: gdm3 | kdm-gdmcompat,
+          qcam | streamer,
+          www-browser,
+          xdaliclock
+Breaks:   xscreensaver-gl,
+          xscreensaver-data,
+          xscreensaver-data-extra,
+          xscreensaver-gl-extra,
+          xscreensaver-screensaver-webcollage,
+          xscreensaver-screensaver-bsod
+Replaces: xscreensaver-gl,
+          xscreensaver-data,
+          xscreensaver-data-extra,
+          xscreensaver-gl-extra,
+          xscreensaver-screensaver-webcollage,
+          xscreensaver-screensaver-bsod
+Description: XScreenSaver is screen saver and locker for X11.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..110285d
--- /dev/null
@@ -0,0 +1,15 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: XScreenSaver
+Upstream-Contact: Jamie Zawinski <jwz@jwz.org>
+Source: https://www.jwz.org/xscreensaver/
+
+Files: *
+Copyright: 1991-2025 Jamie Zawinski <jwz@jwz.org>
+License: Other_1
+ 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.
diff --git a/debian/docs b/debian/docs
new file mode 100644 (file)
index 0000000..66c58a8
--- /dev/null
@@ -0,0 +1,2 @@
+README
+README.hacking
diff --git a/debian/postinst b/debian/postinst
new file mode 100755 (executable)
index 0000000..59b2254
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -e
+
+case "$1" in
+    configure)
+      killall -HUP xscreensaver 2>&-
+    ;;
+esac
diff --git a/debian/prerm b/debian/prerm
new file mode 100755 (executable)
index 0000000..be91306
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -e
+
+case "$1" in 
+  remove|purge)
+       killall -q /usr/bin/xscreensaver || true
+       ;;
+esac
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..1ec5bc8
--- /dev/null
@@ -0,0 +1,19 @@
+#!/usr/bin/make -f
+
+DH_VERBOSE = 1
+export DH_OPTIONS=-v
+
+%:
+       dh $@ --without autoreconf
+
+override_dh_auto_configure:
+       ./configure --prefix=/usr
+
+override_dh_installdirs:
+       dh_installdirs
+       mkdir -p debian/xscreensaver/etc/pam.d
+
+override_dh_fixperms-arch:
+       dh_fixperms
+       chmod 4755 debian/xscreensaver/usr/libexec/xscreensaver/xscreensaver-auth
+       chmod 4755 debian/xscreensaver/usr/libexec/xscreensaver/sonar
diff --git a/debian/source/format b/debian/source/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/watch b/debian/watch
new file mode 100644 (file)
index 0000000..a1355c8
--- /dev/null
@@ -0,0 +1,2 @@
+version=4
+https://www.jwz.org/xscreensaver/download.html xscreensaver-(.*)\.tar\.gz
index a013b82dbfa09126c51de1d85663b4b3f5c6939e..dc7e56661035dc3eaaceab909db22ddfda34f754 100644 (file)
@@ -10,7 +10,7 @@ VPATH         = @srcdir@
 top_srcdir     = @top_srcdir@
 top_builddir   = ..
 
-install_prefix =
+DESTDIR                =
 prefix         = @prefix@
 exec_prefix    = @exec_prefix@
 bindir         = @bindir@
@@ -39,23 +39,23 @@ WAYLAND_DATADIR     = @WAYLAND_DATADIR@
 WAYLAND_GEN    = @WAYLAND_GEN@
 
 WAYLAND_PROTO   = wayland-protocols
-WAYLAND_GEN_XML         = $(WAYLAND_PROTO)/xdg-shell.xml \
-                  $(WAYLAND_PROTO)/ext-idle-notify-v1.xml \
+WAYLAND_GEN_XML         = $(WAYLAND_PROTO)/ext-idle-notify-v1.xml \
                   $(WAYLAND_PROTO)/idle.xml \
                   $(WAYLAND_PROTO)/wlr-output-power-management-unstable-v1.xml \
-                  $(WAYLAND_PROTO)/dpms.xml
+                  $(WAYLAND_PROTO)/dpms.xml \
+                  $(WAYLAND_PROTO)/ext-session-lock-v1.xml
 
-WAYLAND_GEN_HDRS = $(WAYLAND_PROTO)/xdg-shell-v1-client-protocol.h \
-                  $(WAYLAND_PROTO)/ext-idle-notify-v1-client-protocol.h \
+WAYLAND_GEN_HDRS = $(WAYLAND_PROTO)/ext-idle-notify-v1-client-protocol.h \
                   $(WAYLAND_PROTO)/idle-client-protocol.h \
                   $(WAYLAND_PROTO)/wlr-output-power-management-unstable-v1-client-protocol.h \
-                  $(WAYLAND_PROTO)/dpms-client-protocol.h
+                  $(WAYLAND_PROTO)/dpms-client-protocol.h \
+                  $(WAYLAND_PROTO)/ext-session-lock-v1-client-protocol.h
 
-WAYLAND_GEN_SRCS = $(WAYLAND_PROTO)/xdg-shell-v1-protocol.c \
-                  $(WAYLAND_PROTO)/ext-idle-notify-v1-protocol.c \
+WAYLAND_GEN_SRCS = $(WAYLAND_PROTO)/ext-idle-notify-v1-protocol.c \
                   $(WAYLAND_PROTO)/idle-protocol.c \
                   $(WAYLAND_PROTO)/wlr-output-power-management-unstable-v1-protocol.c \
-                  $(WAYLAND_PROTO)/dpms-protocol.c
+                  $(WAYLAND_PROTO)/dpms-protocol.c \
+                  $(WAYLAND_PROTO)/ext-session-lock-v1-protocol.c
 
 WAYLAND_DPY_OBJS   = @WAYLAND_DPY_OBJS@
 WAYLAND_DPY_SRCS   = wayland-dpy.c
@@ -73,6 +73,11 @@ WAYLAND_DPMS_OBJS_1 = wayland-dpms.o \
                      $(WAYLAND_PROTO)/wlr-output-power-management-unstable-v1-protocol.o \
                      $(WAYLAND_PROTO)/dpms-protocol.o
 
+WAYLAND_LOCK_OBJS   = @WAYLAND_LOCK_OBJS@
+WAYLAND_LOCK_SRCS   = wayland-lock.c
+WAYLAND_LOCK_OBJS_1 = wayland-lock.o \
+                     $(WAYLAND_PROTO)/ext-session-lock-v1-protocol.o
+
 WAYLAND_GTK_OBJS    = @WAYLAND_GTK_OBJS@
 WAYLAND_GTK_SRCS    = wayland-dpms.c
 WAYLAND_GTK_OBJS_1  = $(WAYLAND_DPY_OBJS) $(WAYLAND_IDLE_OBJS) \
@@ -156,7 +161,7 @@ GFX_DEFS    = @GL_CFLAGS@ -DLOCALEDIR=\"$(localedir)\"
 SUBP_DEFS      = @GL_CFLAGS@
 GFX_SRCS       = xscreensaver-gfx.c screens.c windows.c subprocs.c \
                  exec.c prefsw.c dpms.c fade.c exts.c atomswm.c \
-                 $(WAYLAND_DPY_SRCS) $(WAYLAND_DPMS_SRCS)
+                 $(WAYLAND_DPMS_SRCS)
 GFX_OBJS       = xscreensaver-gfx.o screens.o windows.o subprocs.o \
                  exec.o prefsw.o dpms.o fade.o exts.o atomswm.o \
                  prefs.o blurb.o atoms.o clientmsg.o xinput.o \
@@ -174,6 +179,7 @@ GFX_OBJS    = xscreensaver-gfx.o screens.o windows.o subprocs.o \
                  $(UTILS_BIN)/utf8wc.o \
                  $(UTILS_BIN)/xshm.o \
                  $(UTILS_BIN)/aligned_malloc.o \
+                 $(UTILS_BIN)/doubletime.o \
                  $(GFX_GL_OBJS)
 GFX_GL_OBJS    = @GFX_GL_OBJS@
 GFX_GL_OBJS_1  = $(UTILS_BIN)/visual-gl.o $(UTILS_BIN)/pow2.o
@@ -205,6 +211,7 @@ AUTH_OBJS_1 = dialog.o passwd.o setuid.o \
                  $(UTILS_BIN)/font-retry.o \
                  $(UTILS_BIN)/yarandom.o \
                  $(UTILS_BIN)/usleep.o \
+                 $(UTILS_BIN)/doubletime.o \
                  $(UTILS_BIN)/resources.o \
                  $(UTILS_BIN)/logo.o \
                  $(UTILS_BIN)/minixpm.o
@@ -235,7 +242,8 @@ GTK_OBJS    = demo-Gtk.o demo-Gtk-conf.o demo-Gtk-resources.o \
                  $(UTILS_BIN)/resources.o \
                  $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/screenshot.o \
-                 $(UTILS_BIN)/usleep.o
+                 $(UTILS_BIN)/usleep.o \
+                 $(UTILS_BIN)/doubletime.o
 GTK_LIBS       = $(LIBS_PRE) $(INTL_LIBS) $(XDPMS_LIBS) \
                  $(XINERAMA_LIBS) $(XML_LIBS) @GTK_LIBS@ \
                  -lXt -lX11 -lXext -lXi $(LIBS_POST)
@@ -256,11 +264,11 @@ MOTIF_LIBS        = $(LIBS_PRE) $(XDPMS_LIBS) $(XDPMS_LIBS) @MOTIF_LIBS@ \
 TEST_SRCS      = test-passwd.c test-uid.c      test-xdpms.c    test-grab.c   \
                  test-fade.c   test-xinerama.c test-vp.c       test-randr.c  \
                  xdpyinfo.c    test-screens.c  test-yarandom.c test-xinput.c \
-                 test-xkb.c
+                 test-xkb.c    test-wayland-lock.c
 TEST_EXES      = test-passwd   test-uid        test-xdpms      test-grab     \
                  test-fade     test-xinerama   test-vp         test-randr    \
                  xdpyinfo      test-screens    test-yarandom   test-xinput   \
-                 test-xkb
+                 test-xkb      test-wayland-lock
 
 EXES           = xscreensaver xscreensaver-command xscreensaver-settings
 UTIL_EXES      = xscreensaver-gfx @EXES_SYSTEMD@
@@ -273,7 +281,7 @@ HDRS                = XScreenSaver_ad.h XScreenSaver_Xm_ad.h \
                  xscreensaver.h prefs.h remote.h exec.h \
                  demo-Gtk-conf.h auth.h types.h blurb.h atoms.h clientmsg.h \
                  screens.h xinput.h fade.h wayland-dpy.h wayland-dpyI.h \
-                 wayland-idle.h wayland-dpms.h \
+                 wayland-idle.h wayland-dpms.h wayland-lock.h \
                  $(WAYLAND_GEN_HDRS)
 MENA           = xscreensaver.man xscreensaver-settings.man \
                  xscreensaver-command.man
@@ -315,30 +323,30 @@ install-strip:
        $(MAKE2) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
 
 install-program:: $(EXES)
-       @if [ ! -d $(install_prefix)$(bindir) ]; then                         \
-          $(INSTALL_DIRS) $(install_prefix)$(bindir) ;                       \
+       @if [ ! -d $(DESTDIR)$(bindir) ]; then                                \
+          $(INSTALL_DIRS) $(DESTDIR)$(bindir) ;                              \
         fi ;                                                                 \
-        if [ ! -d $(install_prefix)$(HACKDIR) ]; then                        \
-          $(INSTALL_DIRS) $(install_prefix)$(HACKDIR) ;                      \
+        if [ ! -d $(DESTDIR)$(HACKDIR) ]; then                               \
+          $(INSTALL_DIRS) $(DESTDIR)$(HACKDIR) ;                             \
         fi
 
 install-program:: $(EXES)
        @inst="$(INSTALL_PROGRAM)" ;                                          \
        for exe in $(EXES); do                                                \
-         echo $$inst $$exe $(install_prefix)$(bindir)/$$exe ;                \
-              $$inst $$exe $(install_prefix)$(bindir)/$$exe ;                \
+         echo $$inst $$exe $(DESTDIR)$(bindir)/$$exe ;                       \
+              $$inst $$exe $(DESTDIR)$(bindir)/$$exe ;                       \
        done
 
 install-program:: $(UTIL_EXES)
        @inst="$(INSTALL_PROGRAM)" ;                                          \
         for exe in $(UTIL_EXES); do                                          \
-           echo $$inst $$exe $(install_prefix)$(HACKDIR)/$$exe ;             \
-                $$inst $$exe $(install_prefix)$(HACKDIR)/$$exe ;             \
+           echo $$inst $$exe $(DESTDIR)$(HACKDIR)/$$exe ;                    \
+                $$inst $$exe $(DESTDIR)$(HACKDIR)/$$exe ;                    \
         done
 
 install-program:: $(SETUID_EXES)
        @inst="$(INSTALL_PROGRAM)" ;                                          \
-        idir="$(install_prefix)$(HACKDIR)" ;                                 \
+        idir="$(DESTDIR)$(HACKDIR)" ;                                        \
         if [ @SETUID_AUTH@ = yes ]; then                                     \
           inst="$(INSTALL_SETUID)" ;                                         \
         else                                                                 \
@@ -366,25 +374,25 @@ install-program:: $(SETUID_EXES)
 
 # Symlink from xscreensaver-demo -> xscreensaver-settings in /usr/bin/
 install-program::
-       @D=$(install_prefix)$(bindir) ;                                       \
+       @D=$(DESTDIR)$(bindir) ;                                              \
         echo ln -sf xscreensaver-settings $$D/xscreensaver-demo ;            \
              ln -sf xscreensaver-settings $$D/xscreensaver-demo
 
 install-ad: XScreenSaver.ad
-       @if [ ! -d $(install_prefix)$(AD_DIR) ]; then                         \
-         $(INSTALL_DIRS) $(install_prefix)$(AD_DIR) ;                        \
+       @if [ ! -d $(DESTDIR)$(AD_DIR) ]; then                                \
+         $(INSTALL_DIRS) $(DESTDIR)$(AD_DIR) ;                               \
         fi ;                                                                 \
        echo $(INSTALL_DATA) XScreenSaver.ad                                  \
-         $(install_prefix)$(AD_DIR)/XScreenSaver ;                           \
+         $(DESTDIR)$(AD_DIR)/XScreenSaver ;                                  \
        if $(INSTALL_DATA) XScreenSaver.ad                                    \
-         $(install_prefix)$(AD_DIR)/XScreenSaver ; then                      \
+         $(DESTDIR)$(AD_DIR)/XScreenSaver ; then                             \
          true ;                                                              \
        else                                                                  \
          e=echo ;                                                            \
-         if [ -f $(install_prefix)$(AD_DIR)/XScreenSaver ]; then             \
+         if [ -f $(DESTDIR)$(AD_DIR)/XScreenSaver ]; then                    \
  $$e ""                                                                             ;\
  $$e "  ####################################################################";\
- $$e "  Warning: unable to install $(install_prefix)$(AD_DIR)/XScreenSaver"  ;\
+ $$e "  Warning: unable to install $(DESTDIR)$(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!"                        ;\
@@ -394,7 +402,7 @@ install-ad: XScreenSaver.ad
          else                                                                \
  $$e ""                                                                             ;\
  $$e "  ####################################################################";\
- $$e "  Warning: unable to install $(install_prefix)$(AD_DIR)/XScreenSaver"  ;\
+ $$e "  Warning: unable to install $(DESTDIR)$(AD_DIR)/XScreenSaver"        ;\
  $$e "           This is probably ok; it should work without that file."     ;\
  $$e "  ####################################################################";\
  $$e ""                                                                             ;\
@@ -420,7 +428,7 @@ install-man:: $(MENA) $(MENB)
                                                                        \
        INST() {                                                        \
          TH=".TH XScreenSaver $$SUF \"$$V\" \"X Version 11\"" ;        \
-         DIR="$(install_prefix)$(mandir)/man$$SUF" ;                   \
+         DIR="$(DESTDIR)$(mandir)/man$$SUF" ;                          \
          if [ ! -d $$DIR ]; then                                       \
            echo $(INSTALL_DIRS) $$DIR ;                                \
                 $(INSTALL_DIRS) $$DIR ;                                \
@@ -441,7 +449,7 @@ install-man:: $(MENA) $(MENB)
 
 # Symlink from xscreensaver-demo.1 -> xscreensaver-settings.1 in /usr/man/man1/
 install-man::
-       @D=$(install_prefix)$(mandir)/man$(mansuffixA) ;                \
+       @D=$(DESTDIR)$(mandir)/man$(mansuffixA) ;                       \
         F1=xscreensaver-settings.$(mansuffixA) ;                       \
         F2=xscreensaver-demo.$(mansuffixA) ;                           \
         echo ln -sf $$F1 $$D/$$F2 ;                                    \
@@ -457,32 +465,32 @@ OLD_MEN  = xscreensaver-getimage.man xscreensaver-getimage-file.man \
           xscreensaver-demo.man
 uninstall-program::
        @for program in $(EXES) $(OLD_EXES); do                         \
-         echo rm -f $(install_prefix)$(bindir)/$$program ;             \
-         rm -f $(install_prefix)$(bindir)/$$program ;                  \
+         echo rm -f $(DESTDIR)$(bindir)/$$program ;                    \
+         rm -f $(DESTDIR)$(bindir)/$$program ;                         \
        done
 
 uninstall-program::
        @for program in $(UTIL_EXES) $(SETUID_EXES); do                 \
-         echo rm -f $(install_prefix)$(HACKDIR)/$$program ;            \
-              rm -f $(install_prefix)$(HACKDIR)/$$program ;            \
+         echo rm -f $(DESTDIR)$(HACKDIR)/$$program ;                   \
+              rm -f $(DESTDIR)$(HACKDIR)/$$program ;                   \
        done
 
 uninstall-ad:
-       rm -f $(install_prefix)$(AD_DIR)/XScreenSaver
+       rm -f $(DESTDIR)$(AD_DIR)/XScreenSaver
 
 uninstall-man:
        @men="$(MEN) $(OLD_MEN)" ;                                      \
        for man in $$men; do                                            \
          instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ;     \
-         echo rm -f $(install_prefix)$(manAdir)/$$instname* ;          \
-              rm -f $(install_prefix)$(manAdir)/$$instname* ;          \
+         echo rm -f $(DESTDIR)$(manAdir)/$$instname* ;                 \
+              rm -f $(DESTDIR)$(manAdir)/$$instname* ;                 \
        done
 
 install-pam: xscreensaver.pam
        @src="xscreensaver.pam" ;                                       \
        name=`sed -n 's/.*PAM_SERVICE_NAME[     ]*"\([^"]*\)".*$$/\1/p' \
           < ../config.h` ;                                             \
-       dir="$(install_prefix)$(PAM_DIR)" ;                             \
+       dir="$(DESTDIR)$(PAM_DIR)" ;                                    \
        conf="$(PAM_CONF)" ;                                            \
                                                                        \
        if [ -z "$$name" ]; then                                        \
@@ -490,17 +498,17 @@ install-pam: xscreensaver.pam
          exit 0 ;                                                      \
        fi ;                                                            \
                                                                        \
-       if [ ! -d $(install_prefix)$(PAM_ROOT) ]; then                  \
-         echo $(INSTALL_DIRS) $(install_prefix)$(PAM_ROOT) ;           \
-              $(INSTALL_DIRS) $(install_prefix)$(PAM_ROOT) ;           \
+       if [ ! -d $(DESTDIR)$(PAM_ROOT) ]; then                         \
+         echo $(INSTALL_DIRS) $(DESTDIR)$(PAM_ROOT) ;                  \
+              $(INSTALL_DIRS) $(DESTDIR)$(PAM_ROOT) ;                  \
        fi ;                                                            \
                                                                        \
-       if [ -d $$dir ] ; then                                          \
+       if [ -d $(PAM_DIR) ] ; then                                     \
                                                                        \
-         if [ -f $$dir/xdm ]; then                                     \
-           src2=$$dir/xdm ;                                            \
-         elif [ -f $$dir/login ]; then                                 \
-           src2=$$dir/login ;                                          \
+         if [ -f $(PAM_DIR)/xdm ]; then                                \
+           src2=$(PAM_DIR)/xdm ;                                       \
+         elif [ -f $(PAM_DIR)/login ]; then                            \
+           src2=$(PAM_DIR)/login ;                                     \
          fi ;                                                          \
                                                                        \
          if [ -z "$$src2" ]; then                                      \
@@ -575,20 +583,20 @@ install-pam: xscreensaver.pam
 # into /usr/share/applications/
 install-gnome:: xscreensaver.desktop xscreensaver-settings.desktop
        @if [ "$(GTK_DATADIR)" != "" ]; then                                  \
-          if [ ! -d "$(install_prefix)$(GTK_APPDIR)" ]; then                 \
-            echo $(INSTALL_DIRS) "$(install_prefix)$(GTK_APPDIR)"           ;\
-                 $(INSTALL_DIRS) "$(install_prefix)$(GTK_APPDIR)"           ;\
+          if [ ! -d "$(DESTDIR)$(GTK_APPDIR)" ]; then                        \
+            echo $(INSTALL_DIRS) "$(DESTDIR)$(GTK_APPDIR)"                  ;\
+                 $(INSTALL_DIRS) "$(DESTDIR)$(GTK_APPDIR)"                  ;\
           fi                                                                ;\
           old=xscreensaver-properties.desktop                               ;\
-          if [ -f "$(install_prefix)$(GTK_APPDIR)/$$old" ]; then             \
-            echo rm -f "$(install_prefix)$(GTK_APPDIR)/$$old"               ;\
-                 rm -f "$(install_prefix)$(GTK_APPDIR)/$$old"               ;\
+          if [ -f "$(DESTDIR)$(GTK_APPDIR)/$$old" ]; then                    \
+            echo rm -f "$(DESTDIR)$(GTK_APPDIR)/$$old"                      ;\
+                 rm -f "$(DESTDIR)$(GTK_APPDIR)/$$old"                      ;\
           fi                                                                ;\
           for name in xscreensaver.desktop xscreensaver-settings.desktop ; do\
-           echo $(INSTALL_DATA) $$name $(install_prefix)$(GTK_APPDIR)/$$name;\
-                $(INSTALL_DATA) $$name $(install_prefix)$(GTK_APPDIR)/$$name;\
-           echo chmod a+x $(install_prefix)$(GTK_APPDIR)/$$name             ;\
-                chmod a+x $(install_prefix)$(GTK_APPDIR)/$$name             ;\
+           echo $(INSTALL_DATA) $$name $(DESTDIR)$(GTK_APPDIR)/$$name       ;\
+                $(INSTALL_DATA) $$name $(DESTDIR)$(GTK_APPDIR)/$$name       ;\
+           echo chmod a+x $(DESTDIR)$(GTK_APPDIR)/$$name                    ;\
+                chmod a+x $(DESTDIR)$(GTK_APPDIR)/$$name                    ;\
           done                                                              ;\
         fi
 
@@ -599,27 +607,27 @@ install-gnome:: xscreensaver.desktop xscreensaver-settings.desktop
 # Or would that make it be enabled by default?
 #
 install-gnome:: xscreensaver.service
-       @if [ ! -d "$(install_prefix)$(GTK_SHAREDIR)" ]; then                 \
-          echo $(INSTALL_DIRS) "$(install_prefix)$(GTK_SHAREDIR)"           ;\
-               $(INSTALL_DIRS) "$(install_prefix)$(GTK_SHAREDIR)"           ;\
+       @if [ ! -d "$(DESTDIR)$(GTK_SHAREDIR)" ]; then                        \
+          echo $(INSTALL_DIRS) "$(DESTDIR)$(GTK_SHAREDIR)"                  ;\
+               $(INSTALL_DIRS) "$(DESTDIR)$(GTK_SHAREDIR)"                  ;\
         fi                                                                  ;\
         name=xscreensaver.service                                           ;\
-        echo $(INSTALL_DATA) $$name $(install_prefix)$(GTK_SHAREDIR)/$$name ;\
-             $(INSTALL_DATA) $$name $(install_prefix)$(GTK_SHAREDIR)/$$name
+        echo $(INSTALL_DATA) $$name $(DESTDIR)$(GTK_SHAREDIR)/$$name        ;\
+             $(INSTALL_DATA) $$name $(DESTDIR)$(GTK_SHAREDIR)/$$name
 
 # xscreensaver.png
 # into /usr/share/pixmaps/
 install-gnome:: $(LOGO)
        @if [ "$(GTK_DATADIR)" != "" ]; then                                  \
-           if [ ! -d "$(install_prefix)$(GTK_ICONDIR)" ]; then                \
-             echo $(INSTALL_DIRS) "$(install_prefix)$(GTK_ICONDIR)"          ;\
-                  $(INSTALL_DIRS) "$(install_prefix)$(GTK_ICONDIR)"          ;\
+           if [ ! -d "$(DESTDIR)$(GTK_ICONDIR)" ]; then                              \
+             echo $(INSTALL_DIRS) "$(DESTDIR)$(GTK_ICONDIR)"                ;\
+                  $(INSTALL_DIRS) "$(DESTDIR)$(GTK_ICONDIR)"                ;\
            fi                                                                ;\
           target=xscreensaver.png                                           ;\
           echo $(INSTALL_DATA) $(LOGO)                                       \
-                 $(install_prefix)$(GTK_ICONDIR)/$$target                   ;\
+                 $(DESTDIR)$(GTK_ICONDIR)/$$target                          ;\
                $(INSTALL_DATA) $(LOGO)                                       \
-                 $(install_prefix)$(GTK_ICONDIR)/$$target                   ;\
+                 $(DESTDIR)$(GTK_ICONDIR)/$$target                          ;\
         fi
 
 install-gnome:: uninstall-old-gnome-icons
@@ -645,12 +653,12 @@ uninstall-gnome::
        @if [ "$(GTK_DATADIR)" != "" ]; then                                  \
          old=xscreensaver-properties.desktop                                ;\
          if [ -f "$old" ]; then                                              \
-           echo rm -f $(install_prefix)$(GTK_APPDIR)/$$old                  ;\
-                rm -f $(install_prefix)$(GTK_APPDIR)/$$old                  ;\
+           echo rm -f $(DESTDIR)$(GTK_APPDIR)/$$old                         ;\
+                rm -f $(DESTDIR)$(GTK_APPDIR)/$$old                         ;\
          fi                                                                 ;\
          for f in xscreensaver.desktop xscreensaver-settings.desktop; do     \
-           echo rm -f $(install_prefix)$(GTK_APPDIR)/$$f                    ;\
-                rm -f $(install_prefix)$(GTK_APPDIR)/$$f                    ;\
+           echo rm -f $(DESTDIR)$(GTK_APPDIR)/$$f                           ;\
+                rm -f $(DESTDIR)$(GTK_APPDIR)/$$f                           ;\
          done                                                               ;\
        fi
 
@@ -659,15 +667,15 @@ uninstall-gnome::
 uninstall-gnome::
        @if [ "$(GTK_ICONDIR)" != "" ]; then                                  \
          target=xscreensaver.xpm                                            ;\
-         echo rm -f $(install_prefix)$(GTK_ICONDIR)/$$target                ;\
-              rm -f $(install_prefix)$(GTK_ICONDIR)/$$target                ;\
+         echo rm -f $(DESTDIR)$(GTK_ICONDIR)/$$target                       ;\
+              rm -f $(DESTDIR)$(GTK_ICONDIR)/$$target                       ;\
         fi
 
 # /usr/share/xscreensaver/ui/*.png and *.ui no longer used as of 2022, 6.05.
 uninstall-gnome::
        @if [ "$(GTK_ICONDIR)" != "" ]; then                                  \
-         echo rm -rf $(install_prefix)$(GTK_SHAREDIR)/ui                    ;\
-              rm -rf $(install_prefix)$(GTK_SHAREDIR)/ui                    ;\
+         echo rm -rf $(DESTDIR)$(GTK_SHAREDIR)/ui                           ;\
+              rm -rf $(DESTDIR)$(GTK_SHAREDIR)/ui                           ;\
         fi
 
 # What is all this crap with the wrong logo?
@@ -676,10 +684,10 @@ uninstall-gnome::
 uninstall-gnome:: uninstall-old-gnome-icons
 uninstall-old-gnome-icons::
        @for f in                                                             \
-          "$(install_prefix)$(GTK_DATADIR)/icons"/*/*/apps/xscreensaver.png  \
-          "$(install_prefix)$(GTK_DATADIR)/icons"/*/*/apps/xscreensaver.svg  \
-          "$(install_prefix)$(GTK_ICONDIR)/xscreensaver.xpm"                 \
-          "$(install_prefix)$(GTK_ICONDIR)/xscreensaver.svg"                ;\
+          "$(DESTDIR)$(GTK_DATADIR)/icons"/*/*/apps/xscreensaver.png         \
+          "$(DESTDIR)$(GTK_DATADIR)/icons"/*/*/apps/xscreensaver.svg         \
+          "$(DESTDIR)$(GTK_ICONDIR)/xscreensaver.xpm"                        \
+          "$(DESTDIR)$(GTK_ICONDIR)/xscreensaver.svg"                       ;\
         do                                                                   \
           if [ -f "$$f" ]; then                                              \
             echo rm -f "$$f"                                                ;\
@@ -694,7 +702,7 @@ uninstall-gnome::
 
 # /usr/share/xscreensaver/config/README
 install-xml:
-       @dest=$(install_prefix)$(HACK_CONF_DIR) ;                       \
+       @dest=$(DESTDIR)$(HACK_CONF_DIR) ;                              \
         if [ ! -d $$dest ]; then                                       \
           $(INSTALL_DIRS) $$dest ;                                     \
         fi ;                                                           \
@@ -705,7 +713,7 @@ install-xml:
 
 # /usr/share/xscreensaver/config/README
 uninstall-xml:
-       rm -f $(install_prefix)$(HACK_CONF_DIR)/README
+       rm -f $(DESTDIR)$(HACK_CONF_DIR)/README
 
 
 ##############################################################################
@@ -840,6 +848,7 @@ $(UTILS_BIN)/aligned_malloc.o:      $(UTILS_SRC)/aligned_malloc.c
 $(UTILS_BIN)/screenshot.o:     $(UTILS_SRC)/screenshot.c
 $(UTILS_BIN)/visual-gl.o:      $(UTILS_SRC)/visual-gl.c
 $(UTILS_BIN)/pow2.o:           $(UTILS_SRC)/pow2.c
+$(UTILS_BIN)/doubletime.o:     $(UTILS_SRC)/doubletime.c
 
 
 UTIL_OBJS      = $(UTILS_BIN)/overlay.o \
@@ -862,7 +871,8 @@ UTIL_OBJS   = $(UTILS_BIN)/overlay.o \
                  $(UTILS_BIN)/aligned_malloc.o \
                  $(UTILS_BIN)/screenshot.o \
                  $(UTILS_BIN)/visual-gl.o \
-                 $(UTILS_BIN)/pow2.o
+                 $(UTILS_BIN)/pow2.o \
+                 $(UTILS_BIN)/doubletime.o
 
 $(UTIL_OBJS):
        $(MAKE2CC) -C $(UTILS_BIN) $(@F)
@@ -956,6 +966,7 @@ xscreensaver-settings: @PREFERRED_DEMO_PROGRAM@
               "therefore no xscreensaver-settings!"                  ; \
          rm -f $@@EXEEXT@                                            ; \
        else                                                            \
+              rm -f $@@EXEEXT@                                       ; \
          echo cp -p @PREFERRED_DEMO_PROGRAM@@EXEEXT@ $@@EXEEXT@      ; \
               cp -p @PREFERRED_DEMO_PROGRAM@@EXEEXT@ $@@EXEEXT@      ; \
        fi
@@ -1004,30 +1015,16 @@ XScreenSaver_Xm_ad.h::
 # need to run "wayland-scanner".  But we print a warning if the system's
 # XML files exist and differ from our own.
 
-# "xdg-shell" isn't used yet but probably will be.
-#
-$(srcdir)/$(WAYLAND_PROTO)/xdg-shell.xml::
-       @\
-  F=$(WAYLAND_DATADIR)/wayland-protocols/stable/xdg-shell/xdg-shell.xml ; \
-       if [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                     \
-         echo "WARNING: $$F and $@ differ" >&2 ;                       \
-       fi
-$(srcdir)/$(WAYLAND_PROTO)/xdg-shell-v1-client-protocol.h: \
-$(srcdir)/$(WAYLAND_PROTO)/xdg-shell.xml
-       wayland-scanner client-header < $< > $@
-$(srcdir)/$(WAYLAND_PROTO)/xdg-shell-v1-protocol.c: \
-$(srcdir)/$(WAYLAND_PROTO)/xdg-shell.xml
-       wayland-scanner private-code  < $< > $@
-$(WAYLAND_PROTO)/xdg-shell-v1-protocol.o: \
-$(srcdir)/$(WAYLAND_PROTO)/xdg-shell-v1-protocol.c
-       $(CC) -c $(CC_ALL) $< -o $@
-
 # "idle-notify-v1" for wayland-idle.c
 #
 $(srcdir)/$(WAYLAND_PROTO)/ext-idle-notify-v1.xml::
        @\
   F=$(WAYLAND_DATADIR)/wayland-protocols/staging/ext-idle-notify/ext-idle-notify-v1.xml ; \
-       if [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                     \
+       if ! [ -f "$@" ]; then                                          \
+         echo "ERROR: $@ does not exist" >&2 ;                         \
+         echo "consider: cp -p $$F $@" ;                               \
+         exit 1 ;                                                      \
+       elif [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                   \
          echo "WARNING: $$F and $@ differ" >&2 ;                       \
        fi
 $(srcdir)/$(WAYLAND_PROTO)/ext-idle-notify-v1-client-protocol.h: \
@@ -1046,7 +1043,11 @@ $(srcdir)/$(WAYLAND_PROTO)/ext-idle-notify-v1-protocol.c
 $(srcdir)/$(WAYLAND_PROTO)/idle.xml::
        @\
        F="$(WAYLAND_DATADIR)/plasma-wayland-protocols/idle.xml" ;      \
-       if [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                     \
+       if ! [ -e "$@" ]; then                                          \
+         echo "ERROR: $@ does not exist" >&2 ;                         \
+         echo "consider: cp -p $$F $@" ;                               \
+         exit 1 ;                                                      \
+       elif [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                   \
          echo "WARNING: $$F and $@ differ" >&2 ;                       \
        fi
 $(srcdir)/$(WAYLAND_PROTO)/idle-client-protocol.h: \
@@ -1065,7 +1066,11 @@ $(srcdir)/$(WAYLAND_PROTO)/idle-protocol.c
 $(srcdir)/$(WAYLAND_PROTO)/wlr-output-power-management-unstable-v1.xml::
        @\
   F="$(WAYLAND_DATADIR)/wayland-protocols/staging/wlr-output-power-management-unstable-v1.xml" ; \
-       if [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                     \
+       if ! [ -e "$@" ]; then                                          \
+         echo "ERROR: $@ does not exist" >&2 ;                         \
+         echo "consider: cp -p $$F $@" ;                               \
+         exit 1 ;                                                      \
+       elif [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                   \
          echo "WARNING: $$F and $@ differ" >&2 ;                       \
        fi
 $(srcdir)/$(WAYLAND_PROTO)/wlr-output-power-management-unstable-v1-client-protocol.h: \
@@ -1084,7 +1089,11 @@ $(srcdir)/$(WAYLAND_PROTO)/wlr-output-power-management-unstable-v1-protocol.c
 $(srcdir)/$(WAYLAND_PROTO)/dpms.xml::
        @\
        F="$(WAYLAND_DATADIR)/plasma-wayland-protocols/dpms.xml" ;      \
-       if [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                     \
+       if ! [ -e "$@" ]; then                                          \
+         echo "ERROR: $@ does not exist" >&2 ;                         \
+         echo "consider: cp -p $$F $@" ;                               \
+         exit 1 ;                                                      \
+       elif [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                   \
          echo "WARNING: $$F and $@ differ" >&2 ;                       \
        fi
 $(srcdir)/$(WAYLAND_PROTO)/dpms-client-protocol.h: \
@@ -1097,6 +1106,27 @@ $(WAYLAND_PROTO)/dpms-protocol.o: \
 $(srcdir)/$(WAYLAND_PROTO)/dpms-protocol.c
        $(CC) -c $(CC_ALL) $< -o $@
 
+# "ext-session-lock-v1" for wayland-lock.c
+#
+$(srcdir)/$(WAYLAND_PROTO)/ext-session-lock-v1.xml::
+       @\
+  F="$(WAYLAND_DATADIR)/wayland-protocols/staging/ext-session-lock/ext-session-lock-v1.xml" ; \
+       if ! [ -e "$@" ]; then                                          \
+         echo "ERROR: $@ does not exist" >&2 ;                         \
+         echo "consider: cp -p $$F $@" ;                               \
+         exit 1 ;                                                      \
+       elif [ -e "$$F" ] && ! cmp -s "$$F" $@ ; then                   \
+         echo "WARNING: $$F and $@ differ" >&2 ;                       \
+       fi
+$(srcdir)/$(WAYLAND_PROTO)/ext-session-lock-v1-client-protocol.h: \
+$(srcdir)/$(WAYLAND_PROTO)/ext-session-lock-v1.xml
+       wayland-scanner client-header < $< > $@
+$(srcdir)/$(WAYLAND_PROTO)/ext-session-lock-v1-protocol.c: \
+$(srcdir)/$(WAYLAND_PROTO)/ext-session-lock-v1.xml
+       wayland-scanner private-code  < $< > $@
+$(WAYLAND_PROTO)/ext-session-lock-v1-protocol.o: \
+$(srcdir)/$(WAYLAND_PROTO)/ext-session-lock-v1-protocol.c
+       $(CC) -c $(CC_ALL) $< -o $@
 
 
 ##############################################################################
@@ -1148,7 +1178,7 @@ TEST_FADE_OBJS = test-fade.o fade.o blurb.o atoms.o clientmsg.o xinput.o \
        $(UTILS_BIN)/visual.o $(UTILS_BIN)/resources.o $(UTILS_BIN)/usleep.o \
        $(UTILS_BIN)/logo.o $(UTILS_BIN)/minixpm.o $(UTILS_BIN)/xshm.o \
        $(UTILS_BIN)/xmu.o $(UTILS_BIN)/aligned_malloc.o \
-       $(UTILS_BIN)/screenshot.o $(GFX_GL_OBJS)
+       $(UTILS_BIN)/screenshot.o $(UTILS_BIN)/doubletime.o $(GFX_GL_OBJS)
 test-fade: $(TEST_FADE_OBJS)
        $(CC) $(LDFLAGS) -o $@ $(TEST_FADE_OBJS) $(GFX_LIBS)
 
@@ -1159,6 +1189,13 @@ test-screens: $(TEST_SCREENS_OBJS)
 test-yarandom: test-yarandom.o blurb.o
        $(CC) -DTEST $(LDFLAGS) -o $@ test-yarandom.o blurb.o $(UTILS_BIN)/yarandom.o
 
+TEST_WLOCK_OBJS = test-wayland-lock.o blurb.o atoms.o \
+       $(WAYLAND_DPY_OBJS) $(WAYLAND_LOCK_OBJS) \
+       $(UTILS_BIN)/visual.o $(UTILS_BIN)/resources.o $(UTILS_BIN)/usleep.o \
+       $(UTILS_BIN)/logo.o $(UTILS_BIN)/minixpm.o
+
+test-wayland-lock: $(TEST_WLOCK_OBJS)
+       $(CC) $(LDFLAGS) -o $@ $(TEST_WLOCK_OBJS) $(GFX_LIBS)
 
 XDPY_DEFS = -DHAVE_GLX $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS)
 XDPY_LIBS = $(LIBS_PRE) -lGL -lX11 -lXext $(LIBS_POST)
@@ -1208,6 +1245,7 @@ dialog.o: $(srcdir)/blurb.h
 dialog.o: ../config.h
 dialog.o: $(srcdir)/prefs.h
 dialog.o: $(srcdir)/screens.h
+dialog.o: $(UTILS_SRC)/doubletime.h
 dialog.o: $(UTILS_SRC)/font-retry.h
 dialog.o: $(UTILS_SRC)/resources.h
 dialog.o: $(UTILS_SRC)/usleep.h
@@ -1232,6 +1270,7 @@ fade.o: $(srcdir)/blurb.h
 fade.o: $(srcdir)/clientmsg.h
 fade.o: ../config.h
 fade.o: $(srcdir)/fade.h
+fade.o: $(UTILS_SRC)/doubletime.h
 fade.o: $(UTILS_SRC)/pow2.h
 fade.o: $(UTILS_SRC)/screenshot.h
 fade.o: $(UTILS_SRC)/usleep.h
@@ -1305,6 +1344,15 @@ test-screens.o: $(UTILS_SRC)/visual.h
 test-uid.o: ../config.h
 test-vp.o: $(srcdir)/blurb.h
 test-vp.o: ../config.h
+test-wayland-lock.o: $(srcdir)/atoms.h
+test-wayland-lock.o: $(srcdir)/blurb.h
+test-wayland-lock.o: ../config.h
+test-wayland-lock.o: $(srcdir)/screens.h
+test-wayland-lock.o: $(srcdir)/types.h
+test-wayland-lock.o: $(UTILS_SRC)/resources.h
+test-wayland-lock.o: $(srcdir)/wayland-dpy.h
+test-wayland-lock.o: $(srcdir)/wayland-lock.h
+test-wayland-lock.o: $(srcdir)/xscreensaver.h
 test-xdpms.o: $(srcdir)/blurb.h
 test-xdpms.o: ../config.h
 test-xinerama.o: $(srcdir)/blurb.h
@@ -1325,13 +1373,9 @@ wayland-dpms.o: $(srcdir)/wayland-dpy.h
 wayland-dpms.o: $(srcdir)/wayland-protocols/dpms-client-protocol.h
 wayland-dpms.o: $(srcdir)/wayland-protocols/wlr-output-power-management-unstable-v1-client-protocol.h
 wayland-dpy.o: $(srcdir)/blurb.h
-wayland-dpy.o: $(srcdir)/blurb.h
 wayland-dpy.o: ../config.h
-wayland-dpy.o: ../config.h
-wayland-dpy.o: $(srcdir)/wayland-dpyI.h
 wayland-dpy.o: $(srcdir)/wayland-dpyI.h
 wayland-dpy.o: $(srcdir)/wayland-dpy.h
-wayland-dpy.o: $(srcdir)/wayland-dpy.h
 wayland-idle.o: $(srcdir)/blurb.h
 wayland-idle.o: ../config.h
 wayland-idle.o: $(srcdir)/wayland-dpyI.h
index 6abaef220e20b8dbfa6d2c5e3d1f92253b2e3143..115900d753a6d079984bf3838cec70fcb4797d42 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 6.12
-!                              07-Jul-2025
+!                              version 6.13
+!                              02-Dec-2025
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at https://www.jwz.org/xscreensaver/
 !   non-Gnome systems:
 !
 @NOGNOME@*loadURL: x-www-browser '%s' || firefox '%s' || chromium-browser '%s'
-@NOGNOME@*manualCommand: lxterminal -T '%s manual' \
-@NOGNOME@                  -e /bin/sh -c 'man "%s" ; read foo'
+!@NOGNOME@*manualCommand: lxterminal -T '%s manual' \
+!@NOGNOME@                 -e /bin/sh -c 'man "%s" ; read foo'
+@NOGNOME@*manualCommand: xdg-open man:%s || \
+@NOGNOME@                  x-terminal-emulator -e /bin/sh -c 'man "%s"'
 
 
 ! The strftime(3) format string for printing the time on the password dialog.
index 420a474a489433607ae34f321a4ce8ab22414b31..df1c1698737395fd621149b68f1a150f567efc5e 100644 (file)
@@ -37,8 +37,8 @@
 "*demoCommand: xscreensaver-settings",
 "*helpURL: https://www.jwz.org/xscreensaver/man.html",
 "*loadURL: x-www-browser '%s' || firefox '%s' || chromium-browser '%s'",
-"*manualCommand: lxterminal -T '%s manual' \
-                   -e /bin/sh -c 'man \"%s\" ; read foo'",
+"*manualCommand: xdg-open man:%s || \
+                   x-terminal-emulator -e /bin/sh -c 'man \"%s\"'",
 "*dateFormat:          %I:%M %p, %a %b %e",
 "*newLoginCommand:     no-such-login-manager",
 "XScreenSaver.pointerHysteresis:               10",
index 6f0727da0b19a78b64bd2bdb687dd7cfbac40659..9ab785d1353cca92174fecd5d8b515a4cc707260 100644 (file)
@@ -128,9 +128,8 @@ typedef struct {
   Visual *gl_visual;
 
 # ifdef HAVE_WAYLAND
-  wayland_dpy  *wayland_dpy;
-  wayland_idle *wayland_idle;
-  wayland_dpms *wayland_dpms;
+  Bool have_wayland_p;
+  Bool have_wayland_idle_p;
 # endif
 
   conf_data *cdata;            /* private data for per-hack configuration */
@@ -139,9 +138,11 @@ typedef struct {
   Bool initializing_p;         /* flag for breaking recursion loops */
   Bool flushing_p;             /* flag for breaking recursion loops */
   Bool saving_p;               /* flag for breaking recursion loops */
+  Bool locking_supported_p;    /* Whether locking is possible */
   Bool dpms_supported_p;       /* Whether XDPMS is available */
   Bool dpms_partial_p;         /* Whether DPMS only supports "Off" */
   Bool grabbing_supported_p;   /* Whether "Grab Desktop" and "Fade" work */
+  const char *lock_why, *dpms_why, *grab_why;
 
   char *desired_preview_cmd;   /* subprocess we intend to run */
   char *running_preview_cmd;   /* subprocess we are currently running */
@@ -2184,6 +2185,7 @@ file_chooser (GtkWindow *parent, GtkEntry *entry, char **retP,
             fprintf (stderr, "%s:   chooser: default \"%s\"\n", blurb(), p2);
         }
       free (p2);
+      if (! gf) abort();
       g_object_unref (gf);
     }
 
@@ -2395,7 +2397,7 @@ server_current_hack (state *s)
                           &dataP)
       == Success
       && type == XA_INTEGER
-      && nitems >= 3
+      && nitems >= 4
       && dataP)
     {
       PROP32 *data = (PROP32 *) dataP;
@@ -2472,6 +2474,7 @@ populate_hack_list (state *s)
     {
       model = gtk_list_store_new (COL_LAST, G_TYPE_BOOLEAN, G_TYPE_STRING);
       g_object_set (G_OBJECT (list), "model", model, NULL);
+      if (! model) abort();
       g_object_unref (model);
 
       ren = gtk_cell_renderer_toggle_new ();
@@ -2576,16 +2579,20 @@ populate_prefs_page (state *s)
   XScreenSaverWindow *win = XSCREENSAVER_WINDOW (s->window);
   saver_preferences *p = &s->prefs;
 
-  Bool can_lock_p = TRUE;
   Bool dpms_full_p;
+  char *lock_why = 0;
 
 # ifdef NO_LOCKING
-  can_lock_p = FALSE;
+  s->locking_supported_p = FALSE;
+  lock_why = _("Not compiled with support for locking");
 # endif
 
   if (s->backend == WAYLAND_BACKEND ||
       s->backend == XWAYLAND_BACKEND)
-    can_lock_p = FALSE;
+    {
+      s->locking_supported_p = FALSE;
+      lock_why = _("Locking not supported under Wayland");
+    }
 
   /* If there is only one screen, the mode menu contains
      "random" but not "random-same".
@@ -2750,9 +2757,17 @@ populate_prefs_page (state *s)
 
   /* Blanking and Locking
    */
-  SENSITIZE (lock_button,     can_lock_p);
-  SENSITIZE (lock_spinbutton, can_lock_p && p->lock_p);
-  SENSITIZE (lock_mlabel,     can_lock_p && p->lock_p);
+  SENSITIZE (lock_button,     s->locking_supported_p);
+  SENSITIZE (lock_spinbutton, s->locking_supported_p && p->lock_p);
+  SENSITIZE (lock_mlabel,     s->locking_supported_p && p->lock_p);
+
+  if (!s->locking_supported_p && lock_why)
+    {
+      gtk_widget_set_tooltip_text (win->lock_menuitem,   lock_why);
+      gtk_widget_set_tooltip_text (win->lock_button,     lock_why);
+      gtk_widget_set_tooltip_text (win->lock_spinbutton, lock_why);
+      gtk_widget_set_tooltip_text (win->lock_mlabel,     lock_why);
+    }
 
   /* DPMS
    */
@@ -2777,12 +2792,36 @@ populate_prefs_page (state *s)
                                s->grabbing_supported_p));
   SENSITIZE (fade_spinbutton, ((p->fade_p || p->unfade_p) &&
                                s->grabbing_supported_p));
+  SENSITIZE (grab_desk_button, (s->grabbing_supported_p));
 
 # undef SENSITIZE
 
   if (!s->dpms_supported_p)
-    gtk_frame_set_label (GTK_FRAME (win->dpms_frame),
-      _("Display Power Management (not supported by this display)"));
+    {
+      gtk_frame_set_label (GTK_FRAME (win->dpms_frame),
+        (s->dpms_why ? s->dpms_why :
+         _("Display Power Management (not supported by this display)")));
+    }
+  else if (s->dpms_partial_p)
+    {
+      const char *s1 = _("Wayland doesn't implement \"Standby\"");
+      const char *s2 = _("Wayland doesn't implement \"Suspend\"");
+      gtk_widget_set_tooltip_text (win->dpms_standby_label,      s1);
+      gtk_widget_set_tooltip_text (win->dpms_standby_mlabel,     s1);
+      gtk_widget_set_tooltip_text (win->dpms_standby_spinbutton, s1);
+      gtk_widget_set_tooltip_text (win->dpms_suspend_label,      s2);
+      gtk_widget_set_tooltip_text (win->dpms_suspend_mlabel,     s2);
+      gtk_widget_set_tooltip_text (win->dpms_suspend_spinbutton, s2);
+    }
+
+  if (!s->grabbing_supported_p && s->grab_why)
+    {
+      gtk_widget_set_tooltip_text (win->fade_button, s->grab_why);
+      gtk_widget_set_tooltip_text (win->unfade_button, s->grab_why);
+      gtk_widget_set_tooltip_text (win->fade_label, s->grab_why);
+      gtk_widget_set_tooltip_text (win->fade_spinbutton, s->grab_why);
+      gtk_widget_set_tooltip_text (win->grab_desk_button, s->grab_why);
+    }
 }
 
 
@@ -2937,7 +2976,8 @@ sensitize_menu_items (state *s, Bool force_p)
     }
 
   gtk_widget_set_sensitive (win->activate_menuitem, running_p);
-  gtk_widget_set_sensitive (win->lock_menuitem, running_p);
+  gtk_widget_set_sensitive (win->lock_menuitem, (running_p &&
+                                                 s->locking_supported_p));
   gtk_widget_set_sensitive (win->kill_menuitem, running_p);
 
   gtk_menu_item_set_label (GTK_MENU_ITEM (win->restart_menuitem),
@@ -4303,9 +4343,9 @@ the_network_is_not_the_computer (gpointer data)
       /* If we are in a state where the daemon won't work properly, pop up a
          dialog box explaining why.
        */
-      if (s->wayland_idle)
+      if (s->have_wayland_idle_p)
         ;   /* Connected to Wayland and can detect activity. */
-      else if (s->wayland_dpy)
+      else if (s->have_wayland_p)
         {
           /* Connected but the necessary extensions are missing. */
           warning_dialog (s->window, _("Warning"),
@@ -5045,11 +5085,17 @@ const gchar *accels[][2] = {
 static void
 xscreensaver_window_realize (GtkWidget *self, gpointer user_data)
 {
-  GdkDisplay *gdpy = gdk_display_get_default();
   XScreenSaverWindow *win = XSCREENSAVER_WINDOW (self);
+  GdkDisplay *gdpy = gdk_display_get_default();
   state *s = &win->state;
   saver_preferences *p = &s->prefs;
 
+# ifdef HAVE_WAYLAND
+  wayland_dpy  *wayland_dpy;
+  wayland_idle *wayland_idle;
+  wayland_dpms *wayland_dpms;
+# endif
+
   s->initializing_p = TRUE;
   s->short_version = XSCREENSAVER_VERSION;
   s->window = GTK_WINDOW (win);
@@ -5142,9 +5188,9 @@ xscreensaver_window_realize (GtkWidget *self, gpointer user_data)
   /* Connect to the Wayland server in the same way that xscreensaver
      and xscreensaver-gfx will, to see if blanking and DPMS will work.
   */
-  s->wayland_dpy  = wayland_dpy_connect();
-  s->wayland_idle = wayland_idle_init (s->wayland_dpy, NULL, NULL);
-  s->wayland_dpms = wayland_dpms_init (s->wayland_dpy);
+  wayland_dpy  = wayland_dpy_connect();
+  wayland_idle = wayland_idle_init (wayland_dpy, NULL, NULL);
+  wayland_dpms = wayland_dpms_init (wayland_dpy);
 # endif /* HAVE_WAYLAND */
 
   s->multi_screen_p = multi_screen_p (s->dpy);
@@ -5152,17 +5198,26 @@ xscreensaver_window_realize (GtkWidget *self, gpointer user_data)
   /* Let's see if the server supports DPMS.
    */
   s->dpms_supported_p = FALSE;
-  s->dpms_partial_p   = TRUE;
+  s->dpms_partial_p   = FALSE;
 
 # ifdef HAVE_WAYLAND
-  if (s->wayland_dpms)
+  if (wayland_dpy)  s->have_wayland_p      = TRUE;
+  if (wayland_idle) s->have_wayland_idle_p = TRUE;
+
+  if (wayland_dpms)
     {
       s->dpms_supported_p = TRUE;
       s->dpms_partial_p   = TRUE;
     }
-  else if (s->wayland_dpy)
+  else if (wayland_dpy)
     {
+      char *desk = getenv ("XDG_CURRENT_DESKTOP");
       s->dpms_supported_p = FALSE;
+      if (desk && strcasestr (desk, "GNOME"))
+        s->dpms_why = _("Power management not supported by Wayland GNOME");
+      else
+        s->dpms_why =
+          _("Power management not supported by this Wayland display");
     }
   else
 # endif /* HAVE_WAYLAND */
@@ -5171,18 +5226,48 @@ xscreensaver_window_realize (GtkWidget *self, gpointer user_data)
   {
     int op = 0, event = 0, error = 0;
     if (s->dpy && XQueryExtension (s->dpy, "DPMS", &op, &event, &error))
-      /* Technically this should also check DPMSCapable(), but this is
-         almost certainly close enough. */
-      s->dpms_supported_p = TRUE;
-    else if (s->debug_p)
-      fprintf (stderr, "%s: server does not support power management\n",
-               blurb());
+      {
+        /* Technically this should also check DPMSCapable(), but this is
+           almost certainly close enough. */
+        s->dpms_supported_p = TRUE;
+        s->dpms_partial_p   = FALSE;
+      }
+    else
+      {
+        s->dpms_why = _("Power management not supported by this X11 display");
+        if (s->debug_p)
+          fprintf (stderr, "%s: %s\n", blurb(), s->dpms_why);
+      }
   }
 # else  /* !HAVE_DPMS_EXTENSION */
   if (s->debug_p)
     fprintf (stderr, "%s: DPMS not supported at compile time\n", blurb());
 # endif /* !HAVE_DPMS_EXTENSION */
 
+# ifdef HAVE_WAYLAND
+  /* Disconnect from Wayland to release the wlr DPMS protocol, since,
+     stupidly, only one client can connect at a time and the daemon needs it.
+     It does not release until the Wayland display is fully shut down: merely
+     doing wayland_dpms_free() is insufficient.
+   */
+  if (wayland_dpms)
+    {
+      wayland_dpms_free (wayland_dpms);
+      wayland_dpms = 0;
+    }
+  if (wayland_idle)
+    {
+      wayland_idle_free (wayland_idle);
+      wayland_idle = 0;
+    }
+  if (wayland_dpy)
+    {
+      wayland_dpy_close (wayland_dpy);
+      wayland_dpy = 0;
+    }
+# endif /* !HAVE_WAYLAND */
+
+
 # if defined(__APPLE__) && !defined(HAVE_COCOA) && !defined(__OPTIMIZE__)
   s->dpms_supported_p = TRUE;  /* macOS X11: debugging kludge */
 # endif
@@ -5197,24 +5282,30 @@ xscreensaver_window_realize (GtkWidget *self, gpointer user_data)
     {
       const char *prog = "grim";
       char *desk = getenv ("XDG_CURRENT_DESKTOP");
-      if (desk &&
-          (strcasestr (desk, "GNOME") ||
-           strcasestr (desk, "KDE") ||
-           strcasestr (desk, "plasma")))
+      if (desk && strcasestr (desk, "GNOME"))
         {
           s->grabbing_supported_p = False;
+          s->grab_why =
+            _("Screenshots and fading not supported on Wayland GNOME");
           if (s->debug_p)
-            fprintf (stderr,
-                     "%s: screenshots and fading not supported on Wayland %s\n",
-                     blurb(), desk);
+            fprintf (stderr, "%s:  %s\n", blurb(), s->grab_why);
+        }
+      else if (desk && (strcasestr (desk, "KDE") ||
+                        strcasestr (desk, "plasma")))
+        {
+          s->grabbing_supported_p = False;
+          s->grab_why =
+            _("Screenshots and fading not supported on Wayland KDE");
+          if (s->debug_p)
+            fprintf (stderr, "%s:  %s\n", blurb(), s->grab_why);
         }
       else if (! on_path_p (prog))
         {
           s->grabbing_supported_p = False;
+          s->grab_why =
+            _("Screenshots and fading on Wayland require \"grim\"");
           if (s->debug_p)
-            fprintf (stderr,
-                     "%s: screenshots and fading on Wayland require \"%s\"\n",
-                     blurb(), prog);
+            fprintf (stderr, "%s:  %s\n", blurb(), s->grab_why);
         }
     }
 
@@ -5231,10 +5322,10 @@ xscreensaver_window_realize (GtkWidget *self, gpointer user_data)
 
   gtk_window_set_transient_for (GTK_WINDOW (s->dialog), GTK_WINDOW (win));
 
-  sensitize_menu_items (s, TRUE);
   populate_hack_list (s);
   populate_prefs_page (s);
   sensitize_demo_widgets (s, FALSE);
+  sensitize_menu_items (s, TRUE);
   scroll_to_current_hack (s);
   if (s->dpy && s->backend != WAYLAND_BACKEND)
     fix_preview_visual (s);
index 7b433674192f8c7e7f6a7db11ea16a2386d197a3..d89ebb742fb435de4d3525f42905b277ab8aa109 100644 (file)
@@ -84,6 +84,7 @@
 #include "prefs.h"
 #include "usleep.h"
 #include "utf8wc.h"
+#include "doubletime.h"
 
 #undef countof
 #define countof(x) (sizeof((x))/sizeof((*x)))
@@ -980,21 +981,6 @@ get_keyboard_layout (window_state *ws)
 }
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void
 create_window (window_state *ws, int w, int h)
 {
@@ -1473,7 +1459,7 @@ window_draw (window_state *ws)
 
      Thank you!
 
-     jwz, 2014, 2016, 2018, 2021.
+     jwz, 2014, 2016, 2018, 2021, 2025.
 
      PS: In particular, since Debian refuses to upgrade software on any
      kind of rational timeline, I have asked that they stop shipping
@@ -1513,6 +1499,8 @@ window_draw (window_state *ws)
       lines[i].text  = _("Update available!\nThis version is very old.\n");
       lines[i].font  = ws->error_font;
       lines[i].fg    = ws->xft_error_foreground;
+      /* A special greeting to the Debian assholes who keep patching this out:
+         once again, go fuck yourselves, Debian. https://jwz.org/b/yiYo */
       lines[i].fg2   = lines[i].fg;
       lines[i].bg    = ws->background;
       lines[i].type  = LABEL;
@@ -1525,6 +1513,8 @@ window_draw (window_state *ws)
       lines[i].font  = ws->error_font;
       lines[i].fg    = ws->xft_error_foreground;
       lines[i].fg2   = lines[i].fg;
+      /* Really, get all the way right up in there and fuck yourselves,
+         Debian, you absolute shitweasels.  https://jwz.org/b/yiYo */
       lines[i].bg    = ws->background;
       lines[i].type  = LABEL;
       lines[i].align = CENTER;
index c28989401a9ece577091706fde47c528d84296bb..3674c1f419ed6d68caca126c8046c8f854e844f5 100644 (file)
 #include "clientmsg.h"
 #include "xmu.h"
 #include "pow2.h"
+#include "doubletime.h"
 #include "screenshot.h"
 
 /* Since gamma fading doesn't work on the Raspberry Pi, probably the single
@@ -165,21 +166,6 @@ static int xshm_fade (XtAppContext, Display *,
                       Bool out_p, Bool from_desktop_p, fade_state *);
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 #ifdef HAVE_XINPUT
 static int xi_opcode = -1;
 #endif
diff --git a/driver/test-wayland-lock.c b/driver/test-wayland-lock.c
new file mode 100644 (file)
index 0000000..d7808d6
--- /dev/null
@@ -0,0 +1,160 @@
+/* test-wayland-lock.c --- test harness for ext-session-lock-v1
+ * xscreensaver, Copyright © 2025 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+#include <X11/Xatom.h>
+#include <X11/Intrinsic.h>
+
+#ifndef HAVE_WAYLAND
+# error Wayland is required
+#endif
+
+#include "wayland-dpy.h"
+#include "wayland-lock.h"
+
+#include "xscreensaver.h"
+#include "resources.h"
+#include "screens.h"
+#include "atoms.h"
+
+XrmDatabase db = 0;
+char *progclass = "XScreenSaver";
+Bool debug_p = True;
+
+typedef struct {
+  XtAppContext app;
+  wayland_dpy  *wdpy;
+  wayland_lock *wlock;
+  int duration;
+} wayland_lock_state;
+
+
+static Window
+get_window_cb (const char *name, void *closure)
+{
+  /* wayland_lock_state *state = (wayland_lock_state *) closure; */
+  fprintf (stderr, "%s: get_window_cb unimplemented\n", blurb());
+  return 0;
+}
+
+static void
+reshape_cb (const char *name, unsigned int w, unsigned int h, void *closure)
+{
+  /* wayland_lock_state *state = (wayland_lock_state *) closure; */
+  fprintf (stderr, "%s: reshape_cb unimplemented\n", blurb());
+  abort();
+}
+
+static void
+unlocked_cb (void *closure)
+{
+  /* wayland_lock_state *state = (wayland_lock_state *) closure; */
+  fprintf (stderr, "%s: server unlocked us!\n", blurb());
+  exit (1);
+}
+
+
+
+static void
+wayland_dpy_cb (XtPointer closure, int *source, XtInputId *id)
+{
+  wayland_lock_state *state = (wayland_lock_state *) closure;
+  wayland_dpy_process_events (state->wdpy, False);
+}
+
+
+static void
+unlock_timer (XtPointer closure, XtIntervalId *id)
+{
+  wayland_lock_state *state = (wayland_lock_state *) closure;
+  fprintf (stderr, "%s: unlocking...\n", blurb());
+  wayland_unlock_screen (state->wlock);
+}
+
+
+static void
+lock_timer (XtPointer closure, XtIntervalId *id)
+{
+  wayland_lock_state *state = (wayland_lock_state *) closure;
+
+  fprintf (stderr, "%s: locking...\n", blurb());
+  if (! wayland_lock_screen (state->wlock,
+                             get_window_cb,
+                             reshape_cb,
+                             unlocked_cb,
+                             state->wlock))
+    {
+      fprintf (stderr, "%s: FAILED\n", blurb());
+      exit (1);
+    }
+
+  XtAppAddTimeOut (state->app, 1000 * state->duration, unlock_timer, state);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  XtAppContext app;
+  Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0,
+                                          &argc, argv, 0, 0, 0);
+  Display *dpy = XtDisplay (toplevel_shell);
+  wayland_dpy *wdpy = wayland_dpy_connect();
+  wayland_lock *wlock = wayland_lock_init (wdpy);
+  wayland_lock_state S, *state = &S;
+
+  progname = argv[0];
+  progclass = "XScreenSaver";
+  db = XtDatabase (dpy);
+
+  if (!wdpy)
+    {
+      fprintf (stderr, "%s: wayland: connection failed.\n", blurb());
+      exit (1);
+    }
+  if (!wlock)
+    {
+      fprintf (stderr, "%s: wayland: locking unsupported.\n", blurb());
+      exit (1);
+    }
+
+  verbose_p += 2;
+
+  state->duration = 3;
+  state->app      = app;
+  state->wdpy     = wdpy;
+  state->wlock    = wlock;
+
+  XtAppAddInput (app, wayland_dpy_get_fd (wdpy),
+                 (XtPointer) (XtInputReadMask | XtInputExceptMask),
+                 wayland_dpy_cb, (XtPointer) state);
+
+  XtAppAddTimeOut (app, 1000 * state->duration, lock_timer, state);
+
+  fprintf (stderr, "%s: locking in %d sec...\n", blurb(), state->duration);
+  while (1)
+    {
+      XEvent event;
+      XtAppNextEvent (app, &event);
+      XtDispatchEvent (&event);
+    }
+}
index 536a86b24bddf824cde6be3cb90d92653c4bac9e..61dcdaf16181c864af4410d85d043a3e6c258978 100644 (file)
  * there is user activity.  So if this program crashes with the screens off,
  * good luck getting them to turn back on.  KDE does the right thing.
  *
+ * Also also! Under "wlr", there can be only one listener at a time!
+ * That's right, it's vitally important that two different programs be
+ * unable to interrogate the DPMS state simultaneously!  So if someone
+ * else is already listening to this, we're screwed.  Also also also!
+ * Calling 'destroy' does not release the lock.  The lock is held until
+ * the entire Wayland display connection terminates.  Because reasons?
+ *
  * GNOME does the following crap, because they have never seen a Wayland
  * protocol that they didn't think should be replaced with DBus instead:
  *
@@ -78,11 +85,11 @@ typedef struct dpms_output {
   Bool wl_done;        /* wl_output: all info about this output has been sent */
 
   struct zwlr_output_power_v1   *wlr_out;
-  enum zwlr_output_power_v1_mode wlr_mode;
-  Bool wlr_failed; /* I have no idea what this means */
+  enum zwlr_output_power_v1_mode wlr_mode;  /* On, Off */
+  Bool wlr_failed;
 
   struct org_kde_kwin_dpms   *kde_out;
-  enum org_kde_kwin_dpms_mode kde_mode;
+  enum org_kde_kwin_dpms_mode kde_mode;     /* On, Standby, Suspend, Off */
   Bool kde_done;
 
 } dpms_output;
@@ -154,8 +161,8 @@ wlr_handle_failed (void *data, struct zwlr_output_power_v1 *wlr_output_power)
   dpms_output *out = (dpms_output *) data;
   out->wlr_failed = True;
   if (verbose_p > 2)
-    fprintf (stderr, "%s: wayland: dpms: output %s is FAILED?\n", blurb(),
-             out->name);
+    fprintf (stderr, "%s: wayland: dpms: output %s is in FAILED state\n",
+             blurb(), out->name);
 }
 
 
@@ -218,6 +225,8 @@ handle_global (void *data, struct wl_registry *reg,
       };
 
       dpms_output *out = (dpms_output *) calloc (sizeof (*out), 1);
+      out->wlr_mode = ZWLR_OUTPUT_POWER_V1_MODE_ON;
+      out->kde_mode = ORG_KDE_KWIN_DPMS_MODE_ON;
       wl_list_insert (&state->outputs, &out->link);
 
       if (verbose_p > 2)
@@ -327,13 +336,22 @@ wayland_dpms_free (wayland_dpms *state)
   wl_list_for_each_safe (out, tmp, &state->outputs, link)
     {
       wl_list_remove (&out->link);
-      /* #### out->wl_output ? */
-      /* #### out->zwlr_output_power_v1, etc ? */
+      if (out->wlr_out)
+        zwlr_output_power_v1_destroy (out->wlr_out);
+      if (out->kde_out)
+        org_kde_kwin_dpms_destroy (out->kde_out);
+      if (out->wl_output)
+        wl_output_destroy (out->wl_output);
       free (out);
     }
 
-  /* #### state->reg ? */
-  /* #### state->zwlr_output_power_manager_v1, etc ? */
+  if (state->wlr_mgr)
+    zwlr_output_power_manager_v1_destroy (state->wlr_mgr);
+  if (state->kde_mgr)
+    org_kde_kwin_dpms_manager_destroy (state->kde_mgr);
+  if (state->reg)
+    wl_proxy_destroy ((struct wl_proxy *) state->reg);
+
   free (state);
 }
 
@@ -343,29 +361,43 @@ wayland_dpms_free (wayland_dpms *state)
 Bool
 wayland_monitor_powered_on_p (wayland_dpms *state)
 {
-  Bool on_p = False;
+  Bool off_p = False;
+  Bool failed_p = False;
   dpms_output *out;
 
-  if (!state) return on_p;
+  if (!state) return !off_p;
 
   wayland_dpy_process_events (state->parent, True);
   wl_list_for_each (out, &state->outputs, link)
     {
       if (out->wlr_out)
         {
-          if (out->wlr_mode == ZWLR_OUTPUT_POWER_V1_MODE_ON)
-            on_p = True;
+          if (out->wlr_mode != ZWLR_OUTPUT_POWER_V1_MODE_ON)
+            off_p = True;
+          if (out->wlr_failed)
+            failed_p = True;
         }
       else if (out->kde_out)
         {
-          if (out->kde_mode == ORG_KDE_KWIN_DPMS_MODE_ON)
-            on_p = True;
+          if (out->kde_mode != ORG_KDE_KWIN_DPMS_MODE_ON)
+            off_p = True;
         }
       else
         abort();
     }
 
-  return on_p;
+  if (failed_p)
+    {
+      /* if (verbose_p) */
+        fprintf (stderr, "%s: wayland: dpms: outputs entered 'failed' state\n",
+                 blurb());
+      /* If the outputs are in 'failed' state, assume they are on.  If there
+         was another listener to "wlr", we will always get "failed", because
+         there can be only one listener. */
+      off_p = False;
+    }
+
+  return !off_p;
 }
 
 
index db5c922eca7f2f14fb222ef6b5d05cd6e0cd62ac..fdf7604778597e351d0efe4606615af095a10def 100644 (file)
@@ -83,7 +83,6 @@ wayland_dpy_connect (void)
                             wl_display_get_fd (state->dpy),
                             WL_EVENT_READABLE, handle_event, state);
     wl_event_source_check (source);
-    /* #### Do I need to free 'source'? */
   }
 
   wayland_dpy_process_events (state, 0);
@@ -133,6 +132,7 @@ wayland_dpy_process_events (wayland_dpy *state, int sync_p)
 void
 wayland_dpy_close (wayland_dpy *state)
 {
+  wayland_dpy_process_events (state, 0);
   wl_display_disconnect (state->dpy);
   if (state->event_loop)
     wl_event_loop_destroy (state->event_loop);
index 585dce0729d981c4582d6256d693dccb589dc2c8..9f9cf4eafded2167eb561a14f713de50340837ed 100644 (file)
@@ -15,6 +15,7 @@
 typedef struct wayland_dpy  wayland_dpy;
 typedef struct wayland_idle wayland_idle;
 typedef struct wayland_dpms wayland_dpms;
+typedef struct wayland_lock wayland_lock;
 
 /* Connects to Wayland and returns a state object on success. */
 extern wayland_dpy *wayland_dpy_connect (void);
index 734e35ebc9de94a5bf760d64306ee8ab93a951ff..9c503da7c6dceb5cccbe88e56f55bfc0c25b6f47 100644 (file)
@@ -42,14 +42,11 @@ struct wayland_idle {
   struct wl_display    *dpy;
   struct wl_registry   *reg;
   struct wl_event_loop *event_loop;
+  struct wl_seat       *seat;
 
   void (*activity_cb) (void *closure);
   void *closure;
 
-  struct wl_seat *seat;
-  char           *seat_name;
-  uint32_t        seat_caps;
-
   struct ext_idle_notifier_v1      *ext_idle_notifier;
   struct ext_idle_notification_v1  *ext_idle_notification;
 
@@ -58,26 +55,6 @@ struct wayland_idle {
 };
 
 
-static void
-seat_handle_capabilities (void *data, struct wl_seat *seat, uint32_t caps)
-{
-  wayland_idle *state = (wayland_idle *) data;
-  state->seat_caps = caps;
-  if (verbose_p > 2)
-    fprintf (stderr, "%s: wayland: idle: seat caps: 0x%02lX\n", blurb(),
-             (unsigned long) caps);
-}
-
-static void
-seat_handle_name (void *data, struct wl_seat *seat, const char *name)
-{
-  wayland_idle *state = (wayland_idle *) data;
-  state->seat_name = strdup (name);
-  if (verbose_p > 2)
-    fprintf (stderr, "%s: wayland: idle: seat name: \"%s\"\n", blurb(), name);
-}
-
-
 /* This is an iterator for all of the extensions that Wayland provides,
    so we can find the ones we are interested in.
  */
@@ -89,14 +66,9 @@ handle_global (void *data, struct wl_registry *reg,
 
   if (!strcmp (iface, wl_seat_interface.name))
     {
-      static const struct wl_seat_listener seat_listener = {
-       .name         = seat_handle_name,
-       .capabilities = seat_handle_capabilities,
-      };
       if (verbose_p > 2)
         fprintf (stderr, "%s: wayland: idle: found: %s\n", blurb(), iface);
       state->seat = wl_registry_bind (reg, name, &wl_seat_interface, version);
-      wl_seat_add_listener (state->seat, &seat_listener, state);
     }
   else if (!strcmp (iface, ext_idle_notifier_v1_interface.name))
     {
@@ -250,7 +222,6 @@ wayland_idle_init (wayland_dpy *dpy,
   state->reg = wl_display_get_registry (dpy->dpy);
   wl_registry_add_listener (state->reg, &listener, state);
 
-  /* It takes two round trips: first to register seats, then timers. */
   wayland_dpy_process_events (dpy, true);
 
   if (! state->seat)
@@ -280,10 +251,14 @@ wayland_idle_init (wayland_dpy *dpy,
 void
 wayland_idle_free (wayland_idle *state)
 {
-  if (state->seat_name)
-    free (state->seat_name);
-  /* #### state->reg ? */
-  /* #### state->seat ? */
-  /* #### state->ext_idle_notifier, etc ? */
+  if (state->seat)
+    wl_seat_destroy (state->seat);
+  if (state->ext_idle_notifier)
+    ext_idle_notifier_v1_destroy (state->ext_idle_notifier);
+  if (state->ext_idle_notification)
+    ext_idle_notification_v1_destroy (state->ext_idle_notification);
+  if (state->reg)
+    wl_proxy_destroy ((struct wl_proxy *) state->reg);
+
   free (state);
 }
diff --git a/driver/wayland-lock.h b/driver/wayland-lock.h
new file mode 100644 (file)
index 0000000..9ddb00d
--- /dev/null
@@ -0,0 +1,41 @@
+/* xscreensaver, Copyright © 2025 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.
+ */
+
+#ifndef __XSCREENSAVER_WAYLAND_LOCK_H__
+#define __XSCREENSAVER_WAYLAND_LOCK_H__
+
+/* Binds to Wayland locking protocols and returns an opaque state object
+   on success.
+ */
+extern wayland_lock *wayland_lock_init (wayland_dpy *);
+
+/* Locks the screen.  Returns true on success.
+
+   The 'get_window' callback must return an X11 Window corresponding to the
+   wl_output with the given name (RANDR screen).
+
+   The 'unlocked' callback is run if the server forcibly unlocks us.
+ */
+extern Bool
+wayland_lock_screen (wayland_lock *,
+                     Window (*get_window_cb) (const char *name, void *closure),
+                     void (*reshape_cb) (const char *name,
+                                         unsigned int w, unsigned int h,
+                                         void *closure),
+                     void (*unlocked_cb) (void *closure),
+                     void *closure);
+
+extern void wayland_unlock_screen (wayland_lock *);
+
+/* Shut it all down. If the screen is locked it may remain locked. */
+extern void wayland_lock_free (wayland_lock *);
+
+#endif /* __XSCREENSAVER_WAYLAND_LOCK_H__ */
diff --git a/driver/wayland-protocols/ext-session-lock-v1-client-protocol.h b/driver/wayland-protocols/ext-session-lock-v1-client-protocol.h
new file mode 100644 (file)
index 0000000..994977a
--- /dev/null
@@ -0,0 +1,684 @@
+/* Generated by wayland-scanner 1.23.1 */
+
+#ifndef EXT_SESSION_LOCK_V1_CLIENT_PROTOCOL_H
+#define EXT_SESSION_LOCK_V1_CLIENT_PROTOCOL_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @page page_ext_session_lock_v1 The ext_session_lock_v1 protocol
+ * secure session locking with arbitrary graphics
+ *
+ * @section page_desc_ext_session_lock_v1 Description
+ *
+ * This protocol allows for a privileged Wayland client to lock the session
+ * and display arbitrary graphics while the session is locked.
+ *
+ * The compositor may choose to restrict this protocol to a special client
+ * launched by the compositor itself or expose it to all privileged clients,
+ * this is compositor policy.
+ *
+ * The client is responsible for performing authentication and informing the
+ * compositor when the session should be unlocked. If the client dies while
+ * the session is locked the session remains locked, possibly permanently
+ * depending on compositor policy.
+ *
+ * The key words "must", "must not", "required", "shall", "shall not",
+ * "should", "should not", "recommended",  "may", and "optional" in this
+ * document are to be interpreted as described in IETF RFC 2119.
+ *
+ * Warning! The protocol described in this file is currently in the
+ * testing phase. Backward compatible changes may be added together with
+ * the corresponding interface version bump. Backward incompatible changes
+ * can only be done by creating a new major version of the extension.
+ *
+ * @section page_ifaces_ext_session_lock_v1 Interfaces
+ * - @subpage page_iface_ext_session_lock_manager_v1 - used to lock the session
+ * - @subpage page_iface_ext_session_lock_v1 - manage lock state and create lock surfaces
+ * - @subpage page_iface_ext_session_lock_surface_v1 - a surface displayed while the session is locked
+ * @section page_copyright_ext_session_lock_v1 Copyright
+ * <pre>
+ *
+ * Copyright 2021 Isaac Freund
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * </pre>
+ */
+struct ext_session_lock_manager_v1;
+struct ext_session_lock_surface_v1;
+struct ext_session_lock_v1;
+struct wl_output;
+struct wl_surface;
+
+#ifndef EXT_SESSION_LOCK_MANAGER_V1_INTERFACE
+#define EXT_SESSION_LOCK_MANAGER_V1_INTERFACE
+/**
+ * @page page_iface_ext_session_lock_manager_v1 ext_session_lock_manager_v1
+ * @section page_iface_ext_session_lock_manager_v1_desc Description
+ *
+ * This interface is used to request that the session be locked.
+ * @section page_iface_ext_session_lock_manager_v1_api API
+ * See @ref iface_ext_session_lock_manager_v1.
+ */
+/**
+ * @defgroup iface_ext_session_lock_manager_v1 The ext_session_lock_manager_v1 interface
+ *
+ * This interface is used to request that the session be locked.
+ */
+extern const struct wl_interface ext_session_lock_manager_v1_interface;
+#endif
+#ifndef EXT_SESSION_LOCK_V1_INTERFACE
+#define EXT_SESSION_LOCK_V1_INTERFACE
+/**
+ * @page page_iface_ext_session_lock_v1 ext_session_lock_v1
+ * @section page_iface_ext_session_lock_v1_desc Description
+ *
+ * In response to the creation of this object the compositor must send
+ * either the locked or finished event.
+ *
+ * The locked event indicates that the session is locked. This means
+ * that the compositor must stop rendering and providing input to normal
+ * clients. Instead the compositor must blank all outputs with an opaque
+ * color such that their normal content is fully hidden.
+ *
+ * The only surfaces that should be rendered while the session is locked
+ * are the lock surfaces created through this interface and optionally,
+ * at the compositor's discretion, special privileged surfaces such as
+ * input methods or portions of desktop shell UIs.
+ *
+ * The locked event must not be sent until a new "locked" frame (either
+ * from a session lock surface or the compositor blanking the output) has
+ * been presented on all outputs and no security sensitive normal/unlocked
+ * content is possibly visible.
+ *
+ * The finished event should be sent immediately on creation of this
+ * object if the compositor decides that the locked event will not be sent.
+ *
+ * The compositor may wait for the client to create and render session lock
+ * surfaces before sending the locked event to avoid displaying intermediate
+ * blank frames. However, it must impose a reasonable time limit if
+ * waiting and send the locked event as soon as the hard requirements
+ * described above can be met if the time limit expires. Clients should
+ * immediately create lock surfaces for all outputs on creation of this
+ * object to make this possible.
+ *
+ * This behavior of the locked event is required in order to prevent
+ * possible race conditions with clients that wish to suspend the system
+ * or similar after locking the session. Without these semantics, clients
+ * triggering a suspend after receiving the locked event would race with
+ * the first "locked" frame being presented and normal/unlocked frames
+ * might be briefly visible as the system is resumed if the suspend
+ * operation wins the race.
+ *
+ * If the client dies while the session is locked, the compositor must not
+ * unlock the session in response. It is acceptable for the session to be
+ * permanently locked if this happens. The compositor may choose to continue
+ * to display the lock surfaces the client had mapped before it died or
+ * alternatively fall back to a solid color, this is compositor policy.
+ *
+ * Compositors may also allow a secure way to recover the session, the
+ * details of this are compositor policy. Compositors may allow a new
+ * client to create a ext_session_lock_v1 object and take responsibility
+ * for unlocking the session, they may even start a new lock client
+ * instance automatically.
+ * @section page_iface_ext_session_lock_v1_api API
+ * See @ref iface_ext_session_lock_v1.
+ */
+/**
+ * @defgroup iface_ext_session_lock_v1 The ext_session_lock_v1 interface
+ *
+ * In response to the creation of this object the compositor must send
+ * either the locked or finished event.
+ *
+ * The locked event indicates that the session is locked. This means
+ * that the compositor must stop rendering and providing input to normal
+ * clients. Instead the compositor must blank all outputs with an opaque
+ * color such that their normal content is fully hidden.
+ *
+ * The only surfaces that should be rendered while the session is locked
+ * are the lock surfaces created through this interface and optionally,
+ * at the compositor's discretion, special privileged surfaces such as
+ * input methods or portions of desktop shell UIs.
+ *
+ * The locked event must not be sent until a new "locked" frame (either
+ * from a session lock surface or the compositor blanking the output) has
+ * been presented on all outputs and no security sensitive normal/unlocked
+ * content is possibly visible.
+ *
+ * The finished event should be sent immediately on creation of this
+ * object if the compositor decides that the locked event will not be sent.
+ *
+ * The compositor may wait for the client to create and render session lock
+ * surfaces before sending the locked event to avoid displaying intermediate
+ * blank frames. However, it must impose a reasonable time limit if
+ * waiting and send the locked event as soon as the hard requirements
+ * described above can be met if the time limit expires. Clients should
+ * immediately create lock surfaces for all outputs on creation of this
+ * object to make this possible.
+ *
+ * This behavior of the locked event is required in order to prevent
+ * possible race conditions with clients that wish to suspend the system
+ * or similar after locking the session. Without these semantics, clients
+ * triggering a suspend after receiving the locked event would race with
+ * the first "locked" frame being presented and normal/unlocked frames
+ * might be briefly visible as the system is resumed if the suspend
+ * operation wins the race.
+ *
+ * If the client dies while the session is locked, the compositor must not
+ * unlock the session in response. It is acceptable for the session to be
+ * permanently locked if this happens. The compositor may choose to continue
+ * to display the lock surfaces the client had mapped before it died or
+ * alternatively fall back to a solid color, this is compositor policy.
+ *
+ * Compositors may also allow a secure way to recover the session, the
+ * details of this are compositor policy. Compositors may allow a new
+ * client to create a ext_session_lock_v1 object and take responsibility
+ * for unlocking the session, they may even start a new lock client
+ * instance automatically.
+ */
+extern const struct wl_interface ext_session_lock_v1_interface;
+#endif
+#ifndef EXT_SESSION_LOCK_SURFACE_V1_INTERFACE
+#define EXT_SESSION_LOCK_SURFACE_V1_INTERFACE
+/**
+ * @page page_iface_ext_session_lock_surface_v1 ext_session_lock_surface_v1
+ * @section page_iface_ext_session_lock_surface_v1_desc Description
+ *
+ * The client may use lock surfaces to display a screensaver, render a
+ * dialog to enter a password and unlock the session, or however else it
+ * sees fit.
+ *
+ * On binding this interface the compositor will immediately send the
+ * first configure event. After making the ack_configure request in
+ * response to this event the client should attach and commit the first
+ * buffer. Committing the surface before acking the first configure is a
+ * protocol error. Committing the surface with a null buffer at any time
+ * is a protocol error.
+ *
+ * The compositor is free to handle keyboard/pointer focus for lock
+ * surfaces however it chooses. A reasonable way to do this would be to
+ * give the first lock surface created keyboard focus and change keyboard
+ * focus if the user clicks on other surfaces.
+ * @section page_iface_ext_session_lock_surface_v1_api API
+ * See @ref iface_ext_session_lock_surface_v1.
+ */
+/**
+ * @defgroup iface_ext_session_lock_surface_v1 The ext_session_lock_surface_v1 interface
+ *
+ * The client may use lock surfaces to display a screensaver, render a
+ * dialog to enter a password and unlock the session, or however else it
+ * sees fit.
+ *
+ * On binding this interface the compositor will immediately send the
+ * first configure event. After making the ack_configure request in
+ * response to this event the client should attach and commit the first
+ * buffer. Committing the surface before acking the first configure is a
+ * protocol error. Committing the surface with a null buffer at any time
+ * is a protocol error.
+ *
+ * The compositor is free to handle keyboard/pointer focus for lock
+ * surfaces however it chooses. A reasonable way to do this would be to
+ * give the first lock surface created keyboard focus and change keyboard
+ * focus if the user clicks on other surfaces.
+ */
+extern const struct wl_interface ext_session_lock_surface_v1_interface;
+#endif
+
+#define EXT_SESSION_LOCK_MANAGER_V1_DESTROY 0
+#define EXT_SESSION_LOCK_MANAGER_V1_LOCK 1
+
+
+/**
+ * @ingroup iface_ext_session_lock_manager_v1
+ */
+#define EXT_SESSION_LOCK_MANAGER_V1_DESTROY_SINCE_VERSION 1
+/**
+ * @ingroup iface_ext_session_lock_manager_v1
+ */
+#define EXT_SESSION_LOCK_MANAGER_V1_LOCK_SINCE_VERSION 1
+
+/** @ingroup iface_ext_session_lock_manager_v1 */
+static inline void
+ext_session_lock_manager_v1_set_user_data(struct ext_session_lock_manager_v1 *ext_session_lock_manager_v1, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) ext_session_lock_manager_v1, user_data);
+}
+
+/** @ingroup iface_ext_session_lock_manager_v1 */
+static inline void *
+ext_session_lock_manager_v1_get_user_data(struct ext_session_lock_manager_v1 *ext_session_lock_manager_v1)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) ext_session_lock_manager_v1);
+}
+
+static inline uint32_t
+ext_session_lock_manager_v1_get_version(struct ext_session_lock_manager_v1 *ext_session_lock_manager_v1)
+{
+       return wl_proxy_get_version((struct wl_proxy *) ext_session_lock_manager_v1);
+}
+
+/**
+ * @ingroup iface_ext_session_lock_manager_v1
+ *
+ * This informs the compositor that the session lock manager object will
+ * no longer be used. Existing objects created through this interface
+ * remain valid.
+ */
+static inline void
+ext_session_lock_manager_v1_destroy(struct ext_session_lock_manager_v1 *ext_session_lock_manager_v1)
+{
+       wl_proxy_marshal_flags((struct wl_proxy *) ext_session_lock_manager_v1,
+                        EXT_SESSION_LOCK_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) ext_session_lock_manager_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+/**
+ * @ingroup iface_ext_session_lock_manager_v1
+ *
+ * This request creates a session lock and asks the compositor to lock the
+ * session. The compositor will send either the ext_session_lock_v1.locked
+ * or ext_session_lock_v1.finished event on the created object in
+ * response to this request.
+ */
+static inline struct ext_session_lock_v1 *
+ext_session_lock_manager_v1_lock(struct ext_session_lock_manager_v1 *ext_session_lock_manager_v1)
+{
+       struct wl_proxy *id;
+
+       id = wl_proxy_marshal_flags((struct wl_proxy *) ext_session_lock_manager_v1,
+                        EXT_SESSION_LOCK_MANAGER_V1_LOCK, &ext_session_lock_v1_interface, wl_proxy_get_version((struct wl_proxy *) ext_session_lock_manager_v1), 0, NULL);
+
+       return (struct ext_session_lock_v1 *) id;
+}
+
+#ifndef EXT_SESSION_LOCK_V1_ERROR_ENUM
+#define EXT_SESSION_LOCK_V1_ERROR_ENUM
+enum ext_session_lock_v1_error {
+       /**
+        * attempted to destroy session lock while locked
+        */
+       EXT_SESSION_LOCK_V1_ERROR_INVALID_DESTROY = 0,
+       /**
+        * unlock requested but locked event was never sent
+        */
+       EXT_SESSION_LOCK_V1_ERROR_INVALID_UNLOCK = 1,
+       /**
+        * given wl_surface already has a role
+        */
+       EXT_SESSION_LOCK_V1_ERROR_ROLE = 2,
+       /**
+        * given output already has a lock surface
+        */
+       EXT_SESSION_LOCK_V1_ERROR_DUPLICATE_OUTPUT = 3,
+       /**
+        * given wl_surface has a buffer attached or committed
+        */
+       EXT_SESSION_LOCK_V1_ERROR_ALREADY_CONSTRUCTED = 4,
+};
+#endif /* EXT_SESSION_LOCK_V1_ERROR_ENUM */
+
+/**
+ * @ingroup iface_ext_session_lock_v1
+ * @struct ext_session_lock_v1_listener
+ */
+struct ext_session_lock_v1_listener {
+       /**
+        * session successfully locked
+        *
+        * This client is now responsible for displaying graphics while
+        * the session is locked and deciding when to unlock the session.
+        *
+        * The locked event must not be sent until a new "locked" frame has
+        * been presented on all outputs and no security sensitive
+        * normal/unlocked content is possibly visible.
+        *
+        * If this event is sent, making the destroy request is a protocol
+        * error, the lock object must be destroyed using the
+        * unlock_and_destroy request.
+        */
+       void (*locked)(void *data,
+                      struct ext_session_lock_v1 *ext_session_lock_v1);
+       /**
+        * the session lock object should be destroyed
+        *
+        * The compositor has decided that the session lock should be
+        * destroyed as it will no longer be used by the compositor.
+        * Exactly when this event is sent is compositor policy, but it
+        * must never be sent more than once for a given session lock
+        * object.
+        *
+        * This might be sent because there is already another
+        * ext_session_lock_v1 object held by a client, or the compositor
+        * has decided to deny the request to lock the session for some
+        * other reason. This might also be sent because the compositor
+        * implements some alternative, secure way to authenticate and
+        * unlock the session.
+        *
+        * The finished event should be sent immediately on creation of
+        * this object if the compositor decides that the locked event will
+        * not be sent.
+        *
+        * If the locked event is sent on creation of this object the
+        * finished event may still be sent at some later time in this
+        * object's lifetime. This is compositor policy.
+        *
+        * Upon receiving this event, the client should make either the
+        * destroy request or the unlock_and_destroy request, depending on
+        * whether or not the locked event was received on this object.
+        */
+       void (*finished)(void *data,
+                        struct ext_session_lock_v1 *ext_session_lock_v1);
+};
+
+/**
+ * @ingroup iface_ext_session_lock_v1
+ */
+static inline int
+ext_session_lock_v1_add_listener(struct ext_session_lock_v1 *ext_session_lock_v1,
+                                const struct ext_session_lock_v1_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) ext_session_lock_v1,
+                                    (void (**)(void)) listener, data);
+}
+
+#define EXT_SESSION_LOCK_V1_DESTROY 0
+#define EXT_SESSION_LOCK_V1_GET_LOCK_SURFACE 1
+#define EXT_SESSION_LOCK_V1_UNLOCK_AND_DESTROY 2
+
+/**
+ * @ingroup iface_ext_session_lock_v1
+ */
+#define EXT_SESSION_LOCK_V1_LOCKED_SINCE_VERSION 1
+/**
+ * @ingroup iface_ext_session_lock_v1
+ */
+#define EXT_SESSION_LOCK_V1_FINISHED_SINCE_VERSION 1
+
+/**
+ * @ingroup iface_ext_session_lock_v1
+ */
+#define EXT_SESSION_LOCK_V1_DESTROY_SINCE_VERSION 1
+/**
+ * @ingroup iface_ext_session_lock_v1
+ */
+#define EXT_SESSION_LOCK_V1_GET_LOCK_SURFACE_SINCE_VERSION 1
+/**
+ * @ingroup iface_ext_session_lock_v1
+ */
+#define EXT_SESSION_LOCK_V1_UNLOCK_AND_DESTROY_SINCE_VERSION 1
+
+/** @ingroup iface_ext_session_lock_v1 */
+static inline void
+ext_session_lock_v1_set_user_data(struct ext_session_lock_v1 *ext_session_lock_v1, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) ext_session_lock_v1, user_data);
+}
+
+/** @ingroup iface_ext_session_lock_v1 */
+static inline void *
+ext_session_lock_v1_get_user_data(struct ext_session_lock_v1 *ext_session_lock_v1)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) ext_session_lock_v1);
+}
+
+static inline uint32_t
+ext_session_lock_v1_get_version(struct ext_session_lock_v1 *ext_session_lock_v1)
+{
+       return wl_proxy_get_version((struct wl_proxy *) ext_session_lock_v1);
+}
+
+/**
+ * @ingroup iface_ext_session_lock_v1
+ *
+ * This informs the compositor that the lock object will no longer be
+ * used. Existing objects created through this interface remain valid.
+ *
+ * After this request is made, lock surfaces created through this object
+ * should be destroyed by the client as they will no longer be used by
+ * the compositor.
+ *
+ * It is a protocol error to make this request if the locked event was
+ * sent, the unlock_and_destroy request must be used instead.
+ */
+static inline void
+ext_session_lock_v1_destroy(struct ext_session_lock_v1 *ext_session_lock_v1)
+{
+       wl_proxy_marshal_flags((struct wl_proxy *) ext_session_lock_v1,
+                        EXT_SESSION_LOCK_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) ext_session_lock_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+/**
+ * @ingroup iface_ext_session_lock_v1
+ *
+ * The client is expected to create lock surfaces for all outputs
+ * currently present and any new outputs as they are advertised. These
+ * won't be displayed by the compositor unless the lock is successful
+ * and the locked event is sent.
+ *
+ * Providing a wl_surface which already has a role or already has a buffer
+ * attached or committed is a protocol error, as is attaching/committing
+ * a buffer before the first ext_session_lock_surface_v1.configure event.
+ *
+ * Attempting to create more than one lock surface for a given output
+ * is a duplicate_output protocol error.
+ */
+static inline struct ext_session_lock_surface_v1 *
+ext_session_lock_v1_get_lock_surface(struct ext_session_lock_v1 *ext_session_lock_v1, struct wl_surface *surface, struct wl_output *output)
+{
+       struct wl_proxy *id;
+
+       id = wl_proxy_marshal_flags((struct wl_proxy *) ext_session_lock_v1,
+                        EXT_SESSION_LOCK_V1_GET_LOCK_SURFACE, &ext_session_lock_surface_v1_interface, wl_proxy_get_version((struct wl_proxy *) ext_session_lock_v1), 0, NULL, surface, output);
+
+       return (struct ext_session_lock_surface_v1 *) id;
+}
+
+/**
+ * @ingroup iface_ext_session_lock_v1
+ *
+ * This request indicates that the session should be unlocked, for
+ * example because the user has entered their password and it has been
+ * verified by the client.
+ *
+ * This request also informs the compositor that the lock object will
+ * no longer be used and should be destroyed. Existing objects created
+ * through this interface remain valid.
+ *
+ * After this request is made, lock surfaces created through this object
+ * should be destroyed by the client as they will no longer be used by
+ * the compositor.
+ *
+ * It is a protocol error to make this request if the locked event has
+ * not been sent. In that case, the lock object must be destroyed using
+ * the destroy request.
+ *
+ * Note that a correct client that wishes to exit directly after unlocking
+ * the session must use the wl_display.sync request to ensure the server
+ * receives and processes the unlock_and_destroy request. Otherwise
+ * there is no guarantee that the server has unlocked the session due
+ * to the asynchronous nature of the Wayland protocol. For example,
+ * the server might terminate the client with a protocol error before
+ * it processes the unlock_and_destroy request.
+ */
+static inline void
+ext_session_lock_v1_unlock_and_destroy(struct ext_session_lock_v1 *ext_session_lock_v1)
+{
+       wl_proxy_marshal_flags((struct wl_proxy *) ext_session_lock_v1,
+                        EXT_SESSION_LOCK_V1_UNLOCK_AND_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) ext_session_lock_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+#ifndef EXT_SESSION_LOCK_SURFACE_V1_ERROR_ENUM
+#define EXT_SESSION_LOCK_SURFACE_V1_ERROR_ENUM
+enum ext_session_lock_surface_v1_error {
+       /**
+        * surface committed before first ack_configure request
+        */
+       EXT_SESSION_LOCK_SURFACE_V1_ERROR_COMMIT_BEFORE_FIRST_ACK = 0,
+       /**
+        * surface committed with a null buffer
+        */
+       EXT_SESSION_LOCK_SURFACE_V1_ERROR_NULL_BUFFER = 1,
+       /**
+        * failed to match ack'd width/height
+        */
+       EXT_SESSION_LOCK_SURFACE_V1_ERROR_DIMENSIONS_MISMATCH = 2,
+       /**
+        * serial provided in ack_configure is invalid
+        */
+       EXT_SESSION_LOCK_SURFACE_V1_ERROR_INVALID_SERIAL = 3,
+};
+#endif /* EXT_SESSION_LOCK_SURFACE_V1_ERROR_ENUM */
+
+/**
+ * @ingroup iface_ext_session_lock_surface_v1
+ * @struct ext_session_lock_surface_v1_listener
+ */
+struct ext_session_lock_surface_v1_listener {
+       /**
+        * the client should resize its surface
+        *
+        * This event is sent once on binding the interface and may be
+        * sent again at the compositor's discretion, for example if output
+        * geometry changes.
+        *
+        * The width and height are in surface-local coordinates and are
+        * exact requirements. Failing to match these surface dimensions in
+        * the next commit after acking a configure is a protocol error.
+        * @param serial serial for use in ack_configure
+        */
+       void (*configure)(void *data,
+                         struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1,
+                         uint32_t serial,
+                         uint32_t width,
+                         uint32_t height);
+};
+
+/**
+ * @ingroup iface_ext_session_lock_surface_v1
+ */
+static inline int
+ext_session_lock_surface_v1_add_listener(struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1,
+                                        const struct ext_session_lock_surface_v1_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) ext_session_lock_surface_v1,
+                                    (void (**)(void)) listener, data);
+}
+
+#define EXT_SESSION_LOCK_SURFACE_V1_DESTROY 0
+#define EXT_SESSION_LOCK_SURFACE_V1_ACK_CONFIGURE 1
+
+/**
+ * @ingroup iface_ext_session_lock_surface_v1
+ */
+#define EXT_SESSION_LOCK_SURFACE_V1_CONFIGURE_SINCE_VERSION 1
+
+/**
+ * @ingroup iface_ext_session_lock_surface_v1
+ */
+#define EXT_SESSION_LOCK_SURFACE_V1_DESTROY_SINCE_VERSION 1
+/**
+ * @ingroup iface_ext_session_lock_surface_v1
+ */
+#define EXT_SESSION_LOCK_SURFACE_V1_ACK_CONFIGURE_SINCE_VERSION 1
+
+/** @ingroup iface_ext_session_lock_surface_v1 */
+static inline void
+ext_session_lock_surface_v1_set_user_data(struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) ext_session_lock_surface_v1, user_data);
+}
+
+/** @ingroup iface_ext_session_lock_surface_v1 */
+static inline void *
+ext_session_lock_surface_v1_get_user_data(struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) ext_session_lock_surface_v1);
+}
+
+static inline uint32_t
+ext_session_lock_surface_v1_get_version(struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1)
+{
+       return wl_proxy_get_version((struct wl_proxy *) ext_session_lock_surface_v1);
+}
+
+/**
+ * @ingroup iface_ext_session_lock_surface_v1
+ *
+ * This informs the compositor that the lock surface object will no
+ * longer be used.
+ *
+ * It is recommended for a lock client to destroy lock surfaces if
+ * their corresponding wl_output global is removed.
+ *
+ * If a lock surface on an active output is destroyed before the
+ * ext_session_lock_v1.unlock_and_destroy event is sent, the compositor
+ * must fall back to rendering a solid color.
+ */
+static inline void
+ext_session_lock_surface_v1_destroy(struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1)
+{
+       wl_proxy_marshal_flags((struct wl_proxy *) ext_session_lock_surface_v1,
+                        EXT_SESSION_LOCK_SURFACE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) ext_session_lock_surface_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+/**
+ * @ingroup iface_ext_session_lock_surface_v1
+ *
+ * When a configure event is received, if a client commits the surface
+ * in response to the configure event, then the client must make an
+ * ack_configure request sometime before the commit request, passing
+ * along the serial of the configure event.
+ *
+ * If the client receives multiple configure events before it can
+ * respond to one, it only has to ack the last configure event.
+ *
+ * A client is not required to commit immediately after sending an
+ * ack_configure request - it may even ack_configure several times
+ * before its next surface commit.
+ *
+ * A client may send multiple ack_configure requests before committing,
+ * but only the last request sent before a commit indicates which
+ * configure event the client really is responding to.
+ *
+ * Sending an ack_configure request consumes the configure event
+ * referenced by the given serial, as well as all older configure events
+ * sent on this object.
+ *
+ * It is a protocol error to issue multiple ack_configure requests
+ * referencing the same configure event or to issue an ack_configure
+ * request referencing a configure event older than the last configure
+ * event acked for a given lock surface.
+ */
+static inline void
+ext_session_lock_surface_v1_ack_configure(struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1, uint32_t serial)
+{
+       wl_proxy_marshal_flags((struct wl_proxy *) ext_session_lock_surface_v1,
+                        EXT_SESSION_LOCK_SURFACE_V1_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) ext_session_lock_surface_v1), 0, serial);
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver/wayland-protocols/ext-session-lock-v1-protocol.c b/driver/wayland-protocols/ext-session-lock-v1-protocol.c
new file mode 100644 (file)
index 0000000..b5f80c1
--- /dev/null
@@ -0,0 +1,97 @@
+/* Generated by wayland-scanner 1.23.1 */
+
+/*
+ * Copyright 2021 Isaac Freund
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+#ifndef __has_attribute
+# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
+#endif
+
+#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
+#define WL_PRIVATE __attribute__ ((visibility("hidden")))
+#else
+#define WL_PRIVATE
+#endif
+
+extern const struct wl_interface ext_session_lock_surface_v1_interface;
+extern const struct wl_interface ext_session_lock_v1_interface;
+extern const struct wl_interface wl_output_interface;
+extern const struct wl_interface wl_surface_interface;
+
+static const struct wl_interface *ext_session_lock_v1_types[] = {
+       NULL,
+       NULL,
+       NULL,
+       &ext_session_lock_v1_interface,
+       &ext_session_lock_surface_v1_interface,
+       &wl_surface_interface,
+       &wl_output_interface,
+};
+
+static const struct wl_message ext_session_lock_manager_v1_requests[] = {
+       { "destroy", "", ext_session_lock_v1_types + 0 },
+       { "lock", "n", ext_session_lock_v1_types + 3 },
+};
+
+WL_PRIVATE const struct wl_interface ext_session_lock_manager_v1_interface = {
+       "ext_session_lock_manager_v1", 1,
+       2, ext_session_lock_manager_v1_requests,
+       0, NULL,
+};
+
+static const struct wl_message ext_session_lock_v1_requests[] = {
+       { "destroy", "", ext_session_lock_v1_types + 0 },
+       { "get_lock_surface", "noo", ext_session_lock_v1_types + 4 },
+       { "unlock_and_destroy", "", ext_session_lock_v1_types + 0 },
+};
+
+static const struct wl_message ext_session_lock_v1_events[] = {
+       { "locked", "", ext_session_lock_v1_types + 0 },
+       { "finished", "", ext_session_lock_v1_types + 0 },
+};
+
+WL_PRIVATE const struct wl_interface ext_session_lock_v1_interface = {
+       "ext_session_lock_v1", 1,
+       3, ext_session_lock_v1_requests,
+       2, ext_session_lock_v1_events,
+};
+
+static const struct wl_message ext_session_lock_surface_v1_requests[] = {
+       { "destroy", "", ext_session_lock_v1_types + 0 },
+       { "ack_configure", "u", ext_session_lock_v1_types + 0 },
+};
+
+static const struct wl_message ext_session_lock_surface_v1_events[] = {
+       { "configure", "uuu", ext_session_lock_v1_types + 0 },
+};
+
+WL_PRIVATE const struct wl_interface ext_session_lock_surface_v1_interface = {
+       "ext_session_lock_surface_v1", 1,
+       2, ext_session_lock_surface_v1_requests,
+       1, ext_session_lock_surface_v1_events,
+};
+
diff --git a/driver/wayland-protocols/ext-session-lock-v1.xml b/driver/wayland-protocols/ext-session-lock-v1.xml
new file mode 100644 (file)
index 0000000..19c12d2
--- /dev/null
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="ext_session_lock_v1">
+  <copyright>
+    Copyright 2021 Isaac Freund
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+  </copyright>
+
+  <description summary="secure session locking with arbitrary graphics">
+    This protocol allows for a privileged Wayland client to lock the session
+    and display arbitrary graphics while the session is locked.
+
+    The compositor may choose to restrict this protocol to a special client
+    launched by the compositor itself or expose it to all privileged clients,
+    this is compositor policy.
+
+    The client is responsible for performing authentication and informing the
+    compositor when the session should be unlocked. If the client dies while
+    the session is locked the session remains locked, possibly permanently
+    depending on compositor policy.
+
+    The key words "must", "must not", "required", "shall", "shall not",
+    "should", "should not", "recommended",  "may", and "optional" in this
+    document are to be interpreted as described in IETF RFC 2119.
+
+    Warning! The protocol described in this file is currently in the
+    testing phase. Backward compatible changes may be added together with
+    the corresponding interface version bump. Backward incompatible changes
+    can only be done by creating a new major version of the extension.
+  </description>
+
+  <interface name="ext_session_lock_manager_v1" version="1">
+    <description summary="used to lock the session">
+      This interface is used to request that the session be locked.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy the session lock manager object">
+        This informs the compositor that the session lock manager object will
+        no longer be used. Existing objects created through this interface
+        remain valid.
+      </description>
+    </request>
+
+    <request name="lock">
+      <description summary="attempt to lock the session">
+        This request creates a session lock and asks the compositor to lock the
+        session. The compositor will send either the ext_session_lock_v1.locked
+        or ext_session_lock_v1.finished event on the created object in
+        response to this request.
+      </description>
+      <arg name="id" type="new_id" interface="ext_session_lock_v1"/>
+    </request>
+  </interface>
+
+  <interface name="ext_session_lock_v1" version="1">
+    <description summary="manage lock state and create lock surfaces">
+      In response to the creation of this object the compositor must send
+      either the locked or finished event.
+
+      The locked event indicates that the session is locked. This means
+      that the compositor must stop rendering and providing input to normal
+      clients. Instead the compositor must blank all outputs with an opaque
+      color such that their normal content is fully hidden.
+
+      The only surfaces that should be rendered while the session is locked
+      are the lock surfaces created through this interface and optionally,
+      at the compositor's discretion, special privileged surfaces such as
+      input methods or portions of desktop shell UIs.
+
+      The locked event must not be sent until a new "locked" frame (either
+      from a session lock surface or the compositor blanking the output) has
+      been presented on all outputs and no security sensitive normal/unlocked
+      content is possibly visible.
+
+      The finished event should be sent immediately on creation of this
+      object if the compositor decides that the locked event will not be sent.
+
+      The compositor may wait for the client to create and render session lock
+      surfaces before sending the locked event to avoid displaying intermediate
+      blank frames. However, it must impose a reasonable time limit if
+      waiting and send the locked event as soon as the hard requirements
+      described above can be met if the time limit expires. Clients should
+      immediately create lock surfaces for all outputs on creation of this
+      object to make this possible.
+
+      This behavior of the locked event is required in order to prevent
+      possible race conditions with clients that wish to suspend the system
+      or similar after locking the session. Without these semantics, clients
+      triggering a suspend after receiving the locked event would race with
+      the first "locked" frame being presented and normal/unlocked frames
+      might be briefly visible as the system is resumed if the suspend
+      operation wins the race.
+
+      If the client dies while the session is locked, the compositor must not
+      unlock the session in response. It is acceptable for the session to be
+      permanently locked if this happens. The compositor may choose to continue
+      to display the lock surfaces the client had mapped before it died or
+      alternatively fall back to a solid color, this is compositor policy.
+
+      Compositors may also allow a secure way to recover the session, the
+      details of this are compositor policy. Compositors may allow a new
+      client to create a ext_session_lock_v1 object and take responsibility
+      for unlocking the session, they may even start a new lock client
+      instance automatically.
+    </description>
+
+    <enum name="error">
+      <entry name="invalid_destroy" value="0"
+        summary="attempted to destroy session lock while locked"/>
+      <entry name="invalid_unlock" value="1"
+        summary="unlock requested but locked event was never sent"/>
+      <entry name="role" value="2"
+        summary="given wl_surface already has a role"/>
+      <entry name="duplicate_output" value="3"
+        summary="given output already has a lock surface"/>
+      <entry name="already_constructed" value="4"
+        summary="given wl_surface has a buffer attached or committed"/>
+    </enum>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy the session lock">
+        This informs the compositor that the lock object will no longer be
+        used. Existing objects created through this interface remain valid.
+
+        After this request is made, lock surfaces created through this object
+        should be destroyed by the client as they will no longer be used by
+        the compositor.
+
+        It is a protocol error to make this request if the locked event was
+        sent, the unlock_and_destroy request must be used instead.
+      </description>
+    </request>
+
+    <event name="locked">
+      <description summary="session successfully locked">
+        This client is now responsible for displaying graphics while the
+        session is locked and deciding when to unlock the session.
+
+        The locked event must not be sent until a new "locked" frame has been
+        presented on all outputs and no security sensitive normal/unlocked
+        content is possibly visible.
+
+        If this event is sent, making the destroy request is a protocol error,
+        the lock object must be destroyed using the unlock_and_destroy request.
+      </description>
+    </event>
+
+    <event name="finished">
+      <description summary="the session lock object should be destroyed">
+        The compositor has decided that the session lock should be destroyed
+        as it will no longer be used by the compositor. Exactly when this
+        event is sent is compositor policy, but it must never be sent more
+        than once for a given session lock object.
+
+        This might be sent because there is already another ext_session_lock_v1
+        object held by a client, or the compositor has decided to deny the
+        request to lock the session for some other reason. This might also
+        be sent because the compositor implements some alternative, secure
+        way to authenticate and unlock the session.
+
+        The finished event should be sent immediately on creation of this
+        object if the compositor decides that the locked event will not
+        be sent.
+
+        If the locked event is sent on creation of this object the finished
+        event may still be sent at some later time in this object's
+        lifetime. This is compositor policy.
+
+        Upon receiving this event, the client should make either the destroy
+        request or the unlock_and_destroy request, depending on whether or
+        not the locked event was received on this object.
+      </description>
+    </event>
+
+    <request name="get_lock_surface">
+      <description summary="create a lock surface for a given output">
+        The client is expected to create lock surfaces for all outputs
+        currently present and any new outputs as they are advertised. These
+        won't be displayed by the compositor unless the lock is successful
+        and the locked event is sent.
+
+        Providing a wl_surface which already has a role or already has a buffer
+        attached or committed is a protocol error, as is attaching/committing
+        a buffer before the first ext_session_lock_surface_v1.configure event.
+
+        Attempting to create more than one lock surface for a given output
+        is a duplicate_output protocol error.
+      </description>
+      <arg name="id" type="new_id" interface="ext_session_lock_surface_v1"/>
+      <arg name="surface" type="object" interface="wl_surface"/>
+      <arg name="output" type="object" interface="wl_output"/>
+    </request>
+
+    <request name="unlock_and_destroy" type="destructor">
+      <description summary="unlock the session, destroying the object">
+        This request indicates that the session should be unlocked, for
+        example because the user has entered their password and it has been
+        verified by the client.
+
+        This request also informs the compositor that the lock object will
+        no longer be used and should be destroyed. Existing objects created
+        through this interface remain valid.
+
+        After this request is made, lock surfaces created through this object
+        should be destroyed by the client as they will no longer be used by
+        the compositor.
+
+        It is a protocol error to make this request if the locked event has
+        not been sent. In that case, the lock object must be destroyed using
+        the destroy request.
+
+        Note that a correct client that wishes to exit directly after unlocking
+        the session must use the wl_display.sync request to ensure the server
+        receives and processes the unlock_and_destroy request. Otherwise
+        there is no guarantee that the server has unlocked the session due
+        to the asynchronous nature of the Wayland protocol. For example,
+        the server might terminate the client with a protocol error before
+        it processes the unlock_and_destroy request.
+      </description>
+    </request>
+  </interface>
+
+  <interface name="ext_session_lock_surface_v1" version="1">
+    <description summary="a surface displayed while the session is locked">
+      The client may use lock surfaces to display a screensaver, render a
+      dialog to enter a password and unlock the session, or however else it
+      sees fit.
+
+      On binding this interface the compositor will immediately send the
+      first configure event. After making the ack_configure request in
+      response to this event the client should attach and commit the first
+      buffer. Committing the surface before acking the first configure is a
+      protocol error. Committing the surface with a null buffer at any time
+      is a protocol error.
+
+      The compositor is free to handle keyboard/pointer focus for lock
+      surfaces however it chooses. A reasonable way to do this would be to
+      give the first lock surface created keyboard focus and change keyboard
+      focus if the user clicks on other surfaces.
+    </description>
+
+    <enum name="error">
+      <entry name="commit_before_first_ack" value="0"
+        summary="surface committed before first ack_configure request"/>
+      <entry name="null_buffer" value="1"
+        summary="surface committed with a null buffer"/>
+      <entry name="dimensions_mismatch" value="2"
+        summary="failed to match ack'd width/height"/>
+      <entry name="invalid_serial" value="3"
+        summary="serial provided in ack_configure is invalid"/>
+    </enum>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy the lock surface object">
+        This informs the compositor that the lock surface object will no
+        longer be used.
+
+        It is recommended for a lock client to destroy lock surfaces if
+        their corresponding wl_output global is removed.
+
+        If a lock surface on an active output is destroyed before the
+        ext_session_lock_v1.unlock_and_destroy event is sent, the compositor
+        must fall back to rendering a solid color.
+      </description>
+    </request>
+
+    <request name="ack_configure">
+      <description summary="ack a configure event">
+        When a configure event is received, if a client commits the surface
+        in response to the configure event, then the client must make an
+        ack_configure request sometime before the commit request, passing
+        along the serial of the configure event.
+
+        If the client receives multiple configure events before it can
+        respond to one, it only has to ack the last configure event.
+
+        A client is not required to commit immediately after sending an
+        ack_configure request - it may even ack_configure several times
+        before its next surface commit.
+
+        A client may send multiple ack_configure requests before committing,
+        but only the last request sent before a commit indicates which
+        configure event the client really is responding to.
+
+        Sending an ack_configure request consumes the configure event
+        referenced by the given serial, as well as all older configure events
+        sent on this object.
+
+        It is a protocol error to issue multiple ack_configure requests
+        referencing the same configure event or to issue an ack_configure
+        request referencing a configure event older than the last configure
+        event acked for a given lock surface.
+      </description>
+      <arg name="serial" type="uint" summary="serial from the configure event"/>
+    </request>
+
+    <event name="configure">
+      <description summary="the client should resize its surface">
+        This event is sent once on binding the interface and may be sent again
+        at the compositor's discretion, for example if output geometry changes.
+
+        The width and height are in surface-local coordinates and are exact
+        requirements. Failing to match these surface dimensions in the next
+        commit after acking a configure is a protocol error.
+      </description>
+      <arg name="serial" type="uint" summary="serial for use in ack_configure"/>
+      <arg name="width" type="uint"/>
+      <arg name="height" type="uint"/>
+    </event>
+  </interface>
+</protocol>
diff --git a/driver/wayland-protocols/xdg-shell-v1-client-protocol.h b/driver/wayland-protocols/xdg-shell-v1-client-protocol.h
deleted file mode 100644 (file)
index db57756..0000000
+++ /dev/null
@@ -1,2381 +0,0 @@
-/* Generated by wayland-scanner 1.23.1 */
-
-#ifndef XDG_SHELL_CLIENT_PROTOCOL_H
-#define XDG_SHELL_CLIENT_PROTOCOL_H
-
-#include <stdint.h>
-#include <stddef.h>
-#include "wayland-client.h"
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/**
- * @page page_xdg_shell The xdg_shell protocol
- * @section page_ifaces_xdg_shell Interfaces
- * - @subpage page_iface_xdg_wm_base - create desktop-style surfaces
- * - @subpage page_iface_xdg_positioner - child surface positioner
- * - @subpage page_iface_xdg_surface - desktop user interface surface base interface
- * - @subpage page_iface_xdg_toplevel - toplevel surface
- * - @subpage page_iface_xdg_popup - short-lived, popup surfaces for menus
- * @section page_copyright_xdg_shell Copyright
- * <pre>
- *
- * Copyright © 2008-2013 Kristian Høgsberg
- * Copyright © 2013      Rafael Antognolli
- * Copyright © 2013      Jasper St. Pierre
- * Copyright © 2010-2013 Intel Corporation
- * Copyright © 2015-2017 Samsung Electronics Co., Ltd
- * Copyright © 2015-2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * </pre>
- */
-struct wl_output;
-struct wl_seat;
-struct wl_surface;
-struct xdg_popup;
-struct xdg_positioner;
-struct xdg_surface;
-struct xdg_toplevel;
-struct xdg_wm_base;
-
-#ifndef XDG_WM_BASE_INTERFACE
-#define XDG_WM_BASE_INTERFACE
-/**
- * @page page_iface_xdg_wm_base xdg_wm_base
- * @section page_iface_xdg_wm_base_desc Description
- *
- * The xdg_wm_base interface is exposed as a global object enabling clients
- * to turn their wl_surfaces into windows in a desktop environment. It
- * defines the basic functionality needed for clients and the compositor to
- * create windows that can be dragged, resized, maximized, etc, as well as
- * creating transient windows such as popup menus.
- * @section page_iface_xdg_wm_base_api API
- * See @ref iface_xdg_wm_base.
- */
-/**
- * @defgroup iface_xdg_wm_base The xdg_wm_base interface
- *
- * The xdg_wm_base interface is exposed as a global object enabling clients
- * to turn their wl_surfaces into windows in a desktop environment. It
- * defines the basic functionality needed for clients and the compositor to
- * create windows that can be dragged, resized, maximized, etc, as well as
- * creating transient windows such as popup menus.
- */
-extern const struct wl_interface xdg_wm_base_interface;
-#endif
-#ifndef XDG_POSITIONER_INTERFACE
-#define XDG_POSITIONER_INTERFACE
-/**
- * @page page_iface_xdg_positioner xdg_positioner
- * @section page_iface_xdg_positioner_desc Description
- *
- * The xdg_positioner provides a collection of rules for the placement of a
- * child surface relative to a parent surface. Rules can be defined to ensure
- * the child surface remains within the visible area's borders, and to
- * specify how the child surface changes its position, such as sliding along
- * an axis, or flipping around a rectangle. These positioner-created rules are
- * constrained by the requirement that a child surface must intersect with or
- * be at least partially adjacent to its parent surface.
- *
- * See the various requests for details about possible rules.
- *
- * At the time of the request, the compositor makes a copy of the rules
- * specified by the xdg_positioner. Thus, after the request is complete the
- * xdg_positioner object can be destroyed or reused; further changes to the
- * object will have no effect on previous usages.
- *
- * For an xdg_positioner object to be considered complete, it must have a
- * non-zero size set by set_size, and a non-zero anchor rectangle set by
- * set_anchor_rect. Passing an incomplete xdg_positioner object when
- * positioning a surface raises an invalid_positioner error.
- * @section page_iface_xdg_positioner_api API
- * See @ref iface_xdg_positioner.
- */
-/**
- * @defgroup iface_xdg_positioner The xdg_positioner interface
- *
- * The xdg_positioner provides a collection of rules for the placement of a
- * child surface relative to a parent surface. Rules can be defined to ensure
- * the child surface remains within the visible area's borders, and to
- * specify how the child surface changes its position, such as sliding along
- * an axis, or flipping around a rectangle. These positioner-created rules are
- * constrained by the requirement that a child surface must intersect with or
- * be at least partially adjacent to its parent surface.
- *
- * See the various requests for details about possible rules.
- *
- * At the time of the request, the compositor makes a copy of the rules
- * specified by the xdg_positioner. Thus, after the request is complete the
- * xdg_positioner object can be destroyed or reused; further changes to the
- * object will have no effect on previous usages.
- *
- * For an xdg_positioner object to be considered complete, it must have a
- * non-zero size set by set_size, and a non-zero anchor rectangle set by
- * set_anchor_rect. Passing an incomplete xdg_positioner object when
- * positioning a surface raises an invalid_positioner error.
- */
-extern const struct wl_interface xdg_positioner_interface;
-#endif
-#ifndef XDG_SURFACE_INTERFACE
-#define XDG_SURFACE_INTERFACE
-/**
- * @page page_iface_xdg_surface xdg_surface
- * @section page_iface_xdg_surface_desc Description
- *
- * An interface that may be implemented by a wl_surface, for
- * implementations that provide a desktop-style user interface.
- *
- * It provides a base set of functionality required to construct user
- * interface elements requiring management by the compositor, such as
- * toplevel windows, menus, etc. The types of functionality are split into
- * xdg_surface roles.
- *
- * Creating an xdg_surface does not set the role for a wl_surface. In order
- * to map an xdg_surface, the client must create a role-specific object
- * using, e.g., get_toplevel, get_popup. The wl_surface for any given
- * xdg_surface can have at most one role, and may not be assigned any role
- * not based on xdg_surface.
- *
- * A role must be assigned before any other requests are made to the
- * xdg_surface object.
- *
- * The client must call wl_surface.commit on the corresponding wl_surface
- * for the xdg_surface state to take effect.
- *
- * Creating an xdg_surface from a wl_surface which has a buffer attached or
- * committed is a client error, and any attempts by a client to attach or
- * manipulate a buffer prior to the first xdg_surface.configure call must
- * also be treated as errors.
- *
- * After creating a role-specific object and setting it up (e.g. by sending
- * the title, app ID, size constraints, parent, etc), the client must
- * perform an initial commit without any buffer attached. The compositor
- * will reply with initial wl_surface state such as
- * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
- * event. The client must acknowledge it and is then allowed to attach a
- * buffer to map the surface.
- *
- * Mapping an xdg_surface-based role surface is defined as making it
- * possible for the surface to be shown by the compositor. Note that
- * a mapped surface is not guaranteed to be visible once it is mapped.
- *
- * For an xdg_surface to be mapped by the compositor, the following
- * conditions must be met:
- * (1) the client has assigned an xdg_surface-based role to the surface
- * (2) the client has set and committed the xdg_surface state and the
- * role-dependent state to the surface
- * (3) the client has committed a buffer to the surface
- *
- * A newly-unmapped surface is considered to have met condition (1) out
- * of the 3 required conditions for mapping a surface if its role surface
- * has not been destroyed, i.e. the client must perform the initial commit
- * again before attaching a buffer.
- * @section page_iface_xdg_surface_api API
- * See @ref iface_xdg_surface.
- */
-/**
- * @defgroup iface_xdg_surface The xdg_surface interface
- *
- * An interface that may be implemented by a wl_surface, for
- * implementations that provide a desktop-style user interface.
- *
- * It provides a base set of functionality required to construct user
- * interface elements requiring management by the compositor, such as
- * toplevel windows, menus, etc. The types of functionality are split into
- * xdg_surface roles.
- *
- * Creating an xdg_surface does not set the role for a wl_surface. In order
- * to map an xdg_surface, the client must create a role-specific object
- * using, e.g., get_toplevel, get_popup. The wl_surface for any given
- * xdg_surface can have at most one role, and may not be assigned any role
- * not based on xdg_surface.
- *
- * A role must be assigned before any other requests are made to the
- * xdg_surface object.
- *
- * The client must call wl_surface.commit on the corresponding wl_surface
- * for the xdg_surface state to take effect.
- *
- * Creating an xdg_surface from a wl_surface which has a buffer attached or
- * committed is a client error, and any attempts by a client to attach or
- * manipulate a buffer prior to the first xdg_surface.configure call must
- * also be treated as errors.
- *
- * After creating a role-specific object and setting it up (e.g. by sending
- * the title, app ID, size constraints, parent, etc), the client must
- * perform an initial commit without any buffer attached. The compositor
- * will reply with initial wl_surface state such as
- * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
- * event. The client must acknowledge it and is then allowed to attach a
- * buffer to map the surface.
- *
- * Mapping an xdg_surface-based role surface is defined as making it
- * possible for the surface to be shown by the compositor. Note that
- * a mapped surface is not guaranteed to be visible once it is mapped.
- *
- * For an xdg_surface to be mapped by the compositor, the following
- * conditions must be met:
- * (1) the client has assigned an xdg_surface-based role to the surface
- * (2) the client has set and committed the xdg_surface state and the
- * role-dependent state to the surface
- * (3) the client has committed a buffer to the surface
- *
- * A newly-unmapped surface is considered to have met condition (1) out
- * of the 3 required conditions for mapping a surface if its role surface
- * has not been destroyed, i.e. the client must perform the initial commit
- * again before attaching a buffer.
- */
-extern const struct wl_interface xdg_surface_interface;
-#endif
-#ifndef XDG_TOPLEVEL_INTERFACE
-#define XDG_TOPLEVEL_INTERFACE
-/**
- * @page page_iface_xdg_toplevel xdg_toplevel
- * @section page_iface_xdg_toplevel_desc Description
- *
- * This interface defines an xdg_surface role which allows a surface to,
- * among other things, set window-like properties such as maximize,
- * fullscreen, and minimize, set application-specific metadata like title and
- * id, and well as trigger user interactive operations such as interactive
- * resize and move.
- *
- * A xdg_toplevel by default is responsible for providing the full intended
- * visual representation of the toplevel, which depending on the window
- * state, may mean things like a title bar, window controls and drop shadow.
- *
- * Unmapping an xdg_toplevel means that the surface cannot be shown
- * by the compositor until it is explicitly mapped again.
- * All active operations (e.g., move, resize) are canceled and all
- * attributes (e.g. title, state, stacking, ...) are discarded for
- * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
- * the state it had right after xdg_surface.get_toplevel. The client
- * can re-map the toplevel by performing a commit without any buffer
- * attached, waiting for a configure event and handling it as usual (see
- * xdg_surface description).
- *
- * Attaching a null buffer to a toplevel unmaps the surface.
- * @section page_iface_xdg_toplevel_api API
- * See @ref iface_xdg_toplevel.
- */
-/**
- * @defgroup iface_xdg_toplevel The xdg_toplevel interface
- *
- * This interface defines an xdg_surface role which allows a surface to,
- * among other things, set window-like properties such as maximize,
- * fullscreen, and minimize, set application-specific metadata like title and
- * id, and well as trigger user interactive operations such as interactive
- * resize and move.
- *
- * A xdg_toplevel by default is responsible for providing the full intended
- * visual representation of the toplevel, which depending on the window
- * state, may mean things like a title bar, window controls and drop shadow.
- *
- * Unmapping an xdg_toplevel means that the surface cannot be shown
- * by the compositor until it is explicitly mapped again.
- * All active operations (e.g., move, resize) are canceled and all
- * attributes (e.g. title, state, stacking, ...) are discarded for
- * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
- * the state it had right after xdg_surface.get_toplevel. The client
- * can re-map the toplevel by performing a commit without any buffer
- * attached, waiting for a configure event and handling it as usual (see
- * xdg_surface description).
- *
- * Attaching a null buffer to a toplevel unmaps the surface.
- */
-extern const struct wl_interface xdg_toplevel_interface;
-#endif
-#ifndef XDG_POPUP_INTERFACE
-#define XDG_POPUP_INTERFACE
-/**
- * @page page_iface_xdg_popup xdg_popup
- * @section page_iface_xdg_popup_desc Description
- *
- * A popup surface is a short-lived, temporary surface. It can be used to
- * implement for example menus, popovers, tooltips and other similar user
- * interface concepts.
- *
- * A popup can be made to take an explicit grab. See xdg_popup.grab for
- * details.
- *
- * When the popup is dismissed, a popup_done event will be sent out, and at
- * the same time the surface will be unmapped. See the xdg_popup.popup_done
- * event for details.
- *
- * Explicitly destroying the xdg_popup object will also dismiss the popup and
- * unmap the surface. Clients that want to dismiss the popup when another
- * surface of their own is clicked should dismiss the popup using the destroy
- * request.
- *
- * A newly created xdg_popup will be stacked on top of all previously created
- * xdg_popup surfaces associated with the same xdg_toplevel.
- *
- * The parent of an xdg_popup must be mapped (see the xdg_surface
- * description) before the xdg_popup itself.
- *
- * The client must call wl_surface.commit on the corresponding wl_surface
- * for the xdg_popup state to take effect.
- * @section page_iface_xdg_popup_api API
- * See @ref iface_xdg_popup.
- */
-/**
- * @defgroup iface_xdg_popup The xdg_popup interface
- *
- * A popup surface is a short-lived, temporary surface. It can be used to
- * implement for example menus, popovers, tooltips and other similar user
- * interface concepts.
- *
- * A popup can be made to take an explicit grab. See xdg_popup.grab for
- * details.
- *
- * When the popup is dismissed, a popup_done event will be sent out, and at
- * the same time the surface will be unmapped. See the xdg_popup.popup_done
- * event for details.
- *
- * Explicitly destroying the xdg_popup object will also dismiss the popup and
- * unmap the surface. Clients that want to dismiss the popup when another
- * surface of their own is clicked should dismiss the popup using the destroy
- * request.
- *
- * A newly created xdg_popup will be stacked on top of all previously created
- * xdg_popup surfaces associated with the same xdg_toplevel.
- *
- * The parent of an xdg_popup must be mapped (see the xdg_surface
- * description) before the xdg_popup itself.
- *
- * The client must call wl_surface.commit on the corresponding wl_surface
- * for the xdg_popup state to take effect.
- */
-extern const struct wl_interface xdg_popup_interface;
-#endif
-
-#ifndef XDG_WM_BASE_ERROR_ENUM
-#define XDG_WM_BASE_ERROR_ENUM
-enum xdg_wm_base_error {
-       /**
-        * given wl_surface has another role
-        */
-       XDG_WM_BASE_ERROR_ROLE = 0,
-       /**
-        * xdg_wm_base was destroyed before children
-        */
-       XDG_WM_BASE_ERROR_DEFUNCT_SURFACES = 1,
-       /**
-        * the client tried to map or destroy a non-topmost popup
-        */
-       XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP = 2,
-       /**
-        * the client specified an invalid popup parent surface
-        */
-       XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT = 3,
-       /**
-        * the client provided an invalid surface state
-        */
-       XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE = 4,
-       /**
-        * the client provided an invalid positioner
-        */
-       XDG_WM_BASE_ERROR_INVALID_POSITIONER = 5,
-       /**
-        * the client didn’t respond to a ping event in time
-        */
-       XDG_WM_BASE_ERROR_UNRESPONSIVE = 6,
-};
-#endif /* XDG_WM_BASE_ERROR_ENUM */
-
-/**
- * @ingroup iface_xdg_wm_base
- * @struct xdg_wm_base_listener
- */
-struct xdg_wm_base_listener {
-       /**
-        * check if the client is alive
-        *
-        * The ping event asks the client if it's still alive. Pass the
-        * serial specified in the event back to the compositor by sending
-        * a "pong" request back with the specified serial. See
-        * xdg_wm_base.pong.
-        *
-        * Compositors can use this to determine if the client is still
-        * alive. It's unspecified what will happen if the client doesn't
-        * respond to the ping request, or in what timeframe. Clients
-        * should try to respond in a reasonable amount of time. The
-        * “unresponsive” error is provided for compositors that wish
-        * to disconnect unresponsive clients.
-        *
-        * A compositor is free to ping in any way it wants, but a client
-        * must always respond to any xdg_wm_base object it created.
-        * @param serial pass this to the pong request
-        */
-       void (*ping)(void *data,
-                    struct xdg_wm_base *xdg_wm_base,
-                    uint32_t serial);
-};
-
-/**
- * @ingroup iface_xdg_wm_base
- */
-static inline int
-xdg_wm_base_add_listener(struct xdg_wm_base *xdg_wm_base,
-                        const struct xdg_wm_base_listener *listener, void *data)
-{
-       return wl_proxy_add_listener((struct wl_proxy *) xdg_wm_base,
-                                    (void (**)(void)) listener, data);
-}
-
-#define XDG_WM_BASE_DESTROY 0
-#define XDG_WM_BASE_CREATE_POSITIONER 1
-#define XDG_WM_BASE_GET_XDG_SURFACE 2
-#define XDG_WM_BASE_PONG 3
-
-/**
- * @ingroup iface_xdg_wm_base
- */
-#define XDG_WM_BASE_PING_SINCE_VERSION 1
-
-/**
- * @ingroup iface_xdg_wm_base
- */
-#define XDG_WM_BASE_DESTROY_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_wm_base
- */
-#define XDG_WM_BASE_CREATE_POSITIONER_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_wm_base
- */
-#define XDG_WM_BASE_GET_XDG_SURFACE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_wm_base
- */
-#define XDG_WM_BASE_PONG_SINCE_VERSION 1
-
-/** @ingroup iface_xdg_wm_base */
-static inline void
-xdg_wm_base_set_user_data(struct xdg_wm_base *xdg_wm_base, void *user_data)
-{
-       wl_proxy_set_user_data((struct wl_proxy *) xdg_wm_base, user_data);
-}
-
-/** @ingroup iface_xdg_wm_base */
-static inline void *
-xdg_wm_base_get_user_data(struct xdg_wm_base *xdg_wm_base)
-{
-       return wl_proxy_get_user_data((struct wl_proxy *) xdg_wm_base);
-}
-
-static inline uint32_t
-xdg_wm_base_get_version(struct xdg_wm_base *xdg_wm_base)
-{
-       return wl_proxy_get_version((struct wl_proxy *) xdg_wm_base);
-}
-
-/**
- * @ingroup iface_xdg_wm_base
- *
- * Destroy this xdg_wm_base object.
- *
- * Destroying a bound xdg_wm_base object while there are surfaces
- * still alive created by this xdg_wm_base object instance is illegal
- * and will result in a defunct_surfaces error.
- */
-static inline void
-xdg_wm_base_destroy(struct xdg_wm_base *xdg_wm_base)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
-                        XDG_WM_BASE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_xdg_wm_base
- *
- * Create a positioner object. A positioner object is used to position
- * surfaces relative to some parent surface. See the interface description
- * and xdg_surface.get_popup for details.
- */
-static inline struct xdg_positioner *
-xdg_wm_base_create_positioner(struct xdg_wm_base *xdg_wm_base)
-{
-       struct wl_proxy *id;
-
-       id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
-                        XDG_WM_BASE_CREATE_POSITIONER, &xdg_positioner_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL);
-
-       return (struct xdg_positioner *) id;
-}
-
-/**
- * @ingroup iface_xdg_wm_base
- *
- * This creates an xdg_surface for the given surface. While xdg_surface
- * itself is not a role, the corresponding surface may only be assigned
- * a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is
- * illegal to create an xdg_surface for a wl_surface which already has an
- * assigned role and this will result in a role error.
- *
- * This creates an xdg_surface for the given surface. An xdg_surface is
- * used as basis to define a role to a given surface, such as xdg_toplevel
- * or xdg_popup. It also manages functionality shared between xdg_surface
- * based surface roles.
- *
- * See the documentation of xdg_surface for more details about what an
- * xdg_surface is and how it is used.
- */
-static inline struct xdg_surface *
-xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface)
-{
-       struct wl_proxy *id;
-
-       id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
-                        XDG_WM_BASE_GET_XDG_SURFACE, &xdg_surface_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL, surface);
-
-       return (struct xdg_surface *) id;
-}
-
-/**
- * @ingroup iface_xdg_wm_base
- *
- * A client must respond to a ping event with a pong request or
- * the client may be deemed unresponsive. See xdg_wm_base.ping
- * and xdg_wm_base.error.unresponsive.
- */
-static inline void
-xdg_wm_base_pong(struct xdg_wm_base *xdg_wm_base, uint32_t serial)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
-                        XDG_WM_BASE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, serial);
-}
-
-#ifndef XDG_POSITIONER_ERROR_ENUM
-#define XDG_POSITIONER_ERROR_ENUM
-enum xdg_positioner_error {
-       /**
-        * invalid input provided
-        */
-       XDG_POSITIONER_ERROR_INVALID_INPUT = 0,
-};
-#endif /* XDG_POSITIONER_ERROR_ENUM */
-
-#ifndef XDG_POSITIONER_ANCHOR_ENUM
-#define XDG_POSITIONER_ANCHOR_ENUM
-enum xdg_positioner_anchor {
-       XDG_POSITIONER_ANCHOR_NONE = 0,
-       XDG_POSITIONER_ANCHOR_TOP = 1,
-       XDG_POSITIONER_ANCHOR_BOTTOM = 2,
-       XDG_POSITIONER_ANCHOR_LEFT = 3,
-       XDG_POSITIONER_ANCHOR_RIGHT = 4,
-       XDG_POSITIONER_ANCHOR_TOP_LEFT = 5,
-       XDG_POSITIONER_ANCHOR_BOTTOM_LEFT = 6,
-       XDG_POSITIONER_ANCHOR_TOP_RIGHT = 7,
-       XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT = 8,
-};
-#endif /* XDG_POSITIONER_ANCHOR_ENUM */
-
-#ifndef XDG_POSITIONER_GRAVITY_ENUM
-#define XDG_POSITIONER_GRAVITY_ENUM
-enum xdg_positioner_gravity {
-       XDG_POSITIONER_GRAVITY_NONE = 0,
-       XDG_POSITIONER_GRAVITY_TOP = 1,
-       XDG_POSITIONER_GRAVITY_BOTTOM = 2,
-       XDG_POSITIONER_GRAVITY_LEFT = 3,
-       XDG_POSITIONER_GRAVITY_RIGHT = 4,
-       XDG_POSITIONER_GRAVITY_TOP_LEFT = 5,
-       XDG_POSITIONER_GRAVITY_BOTTOM_LEFT = 6,
-       XDG_POSITIONER_GRAVITY_TOP_RIGHT = 7,
-       XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT = 8,
-};
-#endif /* XDG_POSITIONER_GRAVITY_ENUM */
-
-#ifndef XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM
-#define XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM
-/**
- * @ingroup iface_xdg_positioner
- * constraint adjustments
- *
- * The constraint adjustment value define ways the compositor will adjust
- * the position of the surface, if the unadjusted position would result
- * in the surface being partly constrained.
- *
- * Whether a surface is considered 'constrained' is left to the compositor
- * to determine. For example, the surface may be partly outside the
- * compositor's defined 'work area', thus necessitating the child surface's
- * position be adjusted until it is entirely inside the work area.
- *
- * The adjustments can be combined, according to a defined precedence: 1)
- * Flip, 2) Slide, 3) Resize.
- */
-enum xdg_positioner_constraint_adjustment {
-       /**
-        * don't move the child surface when constrained
-        *
-        * Don't alter the surface position even if it is constrained on
-        * some axis, for example partially outside the edge of an output.
-        */
-       XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE = 0,
-       /**
-        * move along the x axis until unconstrained
-        *
-        * Slide the surface along the x axis until it is no longer
-        * constrained.
-        *
-        * First try to slide towards the direction of the gravity on the x
-        * axis until either the edge in the opposite direction of the
-        * gravity is unconstrained or the edge in the direction of the
-        * gravity is constrained.
-        *
-        * Then try to slide towards the opposite direction of the gravity
-        * on the x axis until either the edge in the direction of the
-        * gravity is unconstrained or the edge in the opposite direction
-        * of the gravity is constrained.
-        */
-       XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1,
-       /**
-        * move along the y axis until unconstrained
-        *
-        * Slide the surface along the y axis until it is no longer
-        * constrained.
-        *
-        * First try to slide towards the direction of the gravity on the y
-        * axis until either the edge in the opposite direction of the
-        * gravity is unconstrained or the edge in the direction of the
-        * gravity is constrained.
-        *
-        * Then try to slide towards the opposite direction of the gravity
-        * on the y axis until either the edge in the direction of the
-        * gravity is unconstrained or the edge in the opposite direction
-        * of the gravity is constrained.
-        */
-       XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2,
-       /**
-        * invert the anchor and gravity on the x axis
-        *
-        * Invert the anchor and gravity on the x axis if the surface is
-        * constrained on the x axis. For example, if the left edge of the
-        * surface is constrained, the gravity is 'left' and the anchor is
-        * 'left', change the gravity to 'right' and the anchor to 'right'.
-        *
-        * If the adjusted position also ends up being constrained, the
-        * resulting position of the flip_x adjustment will be the one
-        * before the adjustment.
-        */
-       XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X = 4,
-       /**
-        * invert the anchor and gravity on the y axis
-        *
-        * Invert the anchor and gravity on the y axis if the surface is
-        * constrained on the y axis. For example, if the bottom edge of
-        * the surface is constrained, the gravity is 'bottom' and the
-        * anchor is 'bottom', change the gravity to 'top' and the anchor
-        * to 'top'.
-        *
-        * The adjusted position is calculated given the original anchor
-        * rectangle and offset, but with the new flipped anchor and
-        * gravity values.
-        *
-        * If the adjusted position also ends up being constrained, the
-        * resulting position of the flip_y adjustment will be the one
-        * before the adjustment.
-        */
-       XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8,
-       /**
-        * horizontally resize the surface
-        *
-        * Resize the surface horizontally so that it is completely
-        * unconstrained.
-        */
-       XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16,
-       /**
-        * vertically resize the surface
-        *
-        * Resize the surface vertically so that it is completely
-        * unconstrained.
-        */
-       XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32,
-};
-#endif /* XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM */
-
-#define XDG_POSITIONER_DESTROY 0
-#define XDG_POSITIONER_SET_SIZE 1
-#define XDG_POSITIONER_SET_ANCHOR_RECT 2
-#define XDG_POSITIONER_SET_ANCHOR 3
-#define XDG_POSITIONER_SET_GRAVITY 4
-#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT 5
-#define XDG_POSITIONER_SET_OFFSET 6
-#define XDG_POSITIONER_SET_REACTIVE 7
-#define XDG_POSITIONER_SET_PARENT_SIZE 8
-#define XDG_POSITIONER_SET_PARENT_CONFIGURE 9
-
-
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_DESTROY_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_SIZE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_ANCHOR_RECT_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_ANCHOR_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_GRAVITY_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_OFFSET_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_REACTIVE_SINCE_VERSION 3
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_PARENT_SIZE_SINCE_VERSION 3
-/**
- * @ingroup iface_xdg_positioner
- */
-#define XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION 3
-
-/** @ingroup iface_xdg_positioner */
-static inline void
-xdg_positioner_set_user_data(struct xdg_positioner *xdg_positioner, void *user_data)
-{
-       wl_proxy_set_user_data((struct wl_proxy *) xdg_positioner, user_data);
-}
-
-/** @ingroup iface_xdg_positioner */
-static inline void *
-xdg_positioner_get_user_data(struct xdg_positioner *xdg_positioner)
-{
-       return wl_proxy_get_user_data((struct wl_proxy *) xdg_positioner);
-}
-
-static inline uint32_t
-xdg_positioner_get_version(struct xdg_positioner *xdg_positioner)
-{
-       return wl_proxy_get_version((struct wl_proxy *) xdg_positioner);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Notify the compositor that the xdg_positioner will no longer be used.
- */
-static inline void
-xdg_positioner_destroy(struct xdg_positioner *xdg_positioner)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Set the size of the surface that is to be positioned with the positioner
- * object. The size is in surface-local coordinates and corresponds to the
- * window geometry. See xdg_surface.set_window_geometry.
- *
- * If a zero or negative size is set the invalid_input error is raised.
- */
-static inline void
-xdg_positioner_set_size(struct xdg_positioner *xdg_positioner, int32_t width, int32_t height)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, width, height);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Specify the anchor rectangle within the parent surface that the child
- * surface will be placed relative to. The rectangle is relative to the
- * window geometry as defined by xdg_surface.set_window_geometry of the
- * parent surface.
- *
- * When the xdg_positioner object is used to position a child surface, the
- * anchor rectangle may not extend outside the window geometry of the
- * positioned child's parent surface.
- *
- * If a negative size is set the invalid_input error is raised.
- */
-static inline void
-xdg_positioner_set_anchor_rect(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y, int32_t width, int32_t height)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_ANCHOR_RECT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y, width, height);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Defines the anchor point for the anchor rectangle. The specified anchor
- * is used derive an anchor point that the child surface will be
- * positioned relative to. If a corner anchor is set (e.g. 'top_left' or
- * 'bottom_right'), the anchor point will be at the specified corner;
- * otherwise, the derived anchor point will be centered on the specified
- * edge, or in the center of the anchor rectangle if no edge is specified.
- */
-static inline void
-xdg_positioner_set_anchor(struct xdg_positioner *xdg_positioner, uint32_t anchor)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, anchor);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Defines in what direction a surface should be positioned, relative to
- * the anchor point of the parent surface. If a corner gravity is
- * specified (e.g. 'bottom_right' or 'top_left'), then the child surface
- * will be placed towards the specified gravity; otherwise, the child
- * surface will be centered over the anchor point on any axis that had no
- * gravity specified. If the gravity is not in the ‘gravity’ enum, an
- * invalid_input error is raised.
- */
-static inline void
-xdg_positioner_set_gravity(struct xdg_positioner *xdg_positioner, uint32_t gravity)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_GRAVITY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, gravity);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Specify how the window should be positioned if the originally intended
- * position caused the surface to be constrained, meaning at least
- * partially outside positioning boundaries set by the compositor. The
- * adjustment is set by constructing a bitmask describing the adjustment to
- * be made when the surface is constrained on that axis.
- *
- * If no bit for one axis is set, the compositor will assume that the child
- * surface should not change its position on that axis when constrained.
- *
- * If more than one bit for one axis is set, the order of how adjustments
- * are applied is specified in the corresponding adjustment descriptions.
- *
- * The default adjustment is none.
- */
-static inline void
-xdg_positioner_set_constraint_adjustment(struct xdg_positioner *xdg_positioner, uint32_t constraint_adjustment)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, constraint_adjustment);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Specify the surface position offset relative to the position of the
- * anchor on the anchor rectangle and the anchor on the surface. For
- * example if the anchor of the anchor rectangle is at (x, y), the surface
- * has the gravity bottom|right, and the offset is (ox, oy), the calculated
- * surface position will be (x + ox, y + oy). The offset position of the
- * surface is the one used for constraint testing. See
- * set_constraint_adjustment.
- *
- * An example use case is placing a popup menu on top of a user interface
- * element, while aligning the user interface element of the parent surface
- * with some user interface element placed somewhere in the popup surface.
- */
-static inline void
-xdg_positioner_set_offset(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * When set reactive, the surface is reconstrained if the conditions used
- * for constraining changed, e.g. the parent window moved.
- *
- * If the conditions changed and the popup was reconstrained, an
- * xdg_popup.configure event is sent with updated geometry, followed by an
- * xdg_surface.configure event.
- */
-static inline void
-xdg_positioner_set_reactive(struct xdg_positioner *xdg_positioner)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_REACTIVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Set the parent window geometry the compositor should use when
- * positioning the popup. The compositor may use this information to
- * determine the future state the popup should be constrained using. If
- * this doesn't match the dimension of the parent the popup is eventually
- * positioned against, the behavior is undefined.
- *
- * The arguments are given in the surface-local coordinate space.
- */
-static inline void
-xdg_positioner_set_parent_size(struct xdg_positioner *xdg_positioner, int32_t parent_width, int32_t parent_height)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_PARENT_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, parent_width, parent_height);
-}
-
-/**
- * @ingroup iface_xdg_positioner
- *
- * Set the serial of an xdg_surface.configure event this positioner will be
- * used in response to. The compositor may use this information together
- * with set_parent_size to determine what future state the popup should be
- * constrained using.
- */
-static inline void
-xdg_positioner_set_parent_configure(struct xdg_positioner *xdg_positioner, uint32_t serial)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
-                        XDG_POSITIONER_SET_PARENT_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, serial);
-}
-
-#ifndef XDG_SURFACE_ERROR_ENUM
-#define XDG_SURFACE_ERROR_ENUM
-enum xdg_surface_error {
-       /**
-        * Surface was not fully constructed
-        */
-       XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1,
-       /**
-        * Surface was already constructed
-        */
-       XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2,
-       /**
-        * Attaching a buffer to an unconfigured surface
-        */
-       XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3,
-       /**
-        * Invalid serial number when acking a configure event
-        */
-       XDG_SURFACE_ERROR_INVALID_SERIAL = 4,
-       /**
-        * Width or height was zero or negative
-        */
-       XDG_SURFACE_ERROR_INVALID_SIZE = 5,
-       /**
-        * Surface was destroyed before its role object
-        */
-       XDG_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 6,
-};
-#endif /* XDG_SURFACE_ERROR_ENUM */
-
-/**
- * @ingroup iface_xdg_surface
- * @struct xdg_surface_listener
- */
-struct xdg_surface_listener {
-       /**
-        * suggest a surface change
-        *
-        * The configure event marks the end of a configure sequence. A
-        * configure sequence is a set of one or more events configuring
-        * the state of the xdg_surface, including the final
-        * xdg_surface.configure event.
-        *
-        * Where applicable, xdg_surface surface roles will during a
-        * configure sequence extend this event as a latched state sent as
-        * events before the xdg_surface.configure event. Such events
-        * should be considered to make up a set of atomically applied
-        * configuration states, where the xdg_surface.configure commits
-        * the accumulated state.
-        *
-        * Clients should arrange their surface for the new states, and
-        * then send an ack_configure request with the serial sent in this
-        * configure event at some point before committing the new surface.
-        *
-        * If the client receives multiple configure events before it can
-        * respond to one, it is free to discard all but the last event it
-        * received.
-        * @param serial serial of the configure event
-        */
-       void (*configure)(void *data,
-                         struct xdg_surface *xdg_surface,
-                         uint32_t serial);
-};
-
-/**
- * @ingroup iface_xdg_surface
- */
-static inline int
-xdg_surface_add_listener(struct xdg_surface *xdg_surface,
-                        const struct xdg_surface_listener *listener, void *data)
-{
-       return wl_proxy_add_listener((struct wl_proxy *) xdg_surface,
-                                    (void (**)(void)) listener, data);
-}
-
-#define XDG_SURFACE_DESTROY 0
-#define XDG_SURFACE_GET_TOPLEVEL 1
-#define XDG_SURFACE_GET_POPUP 2
-#define XDG_SURFACE_SET_WINDOW_GEOMETRY 3
-#define XDG_SURFACE_ACK_CONFIGURE 4
-
-/**
- * @ingroup iface_xdg_surface
- */
-#define XDG_SURFACE_CONFIGURE_SINCE_VERSION 1
-
-/**
- * @ingroup iface_xdg_surface
- */
-#define XDG_SURFACE_DESTROY_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_surface
- */
-#define XDG_SURFACE_GET_TOPLEVEL_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_surface
- */
-#define XDG_SURFACE_GET_POPUP_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_surface
- */
-#define XDG_SURFACE_SET_WINDOW_GEOMETRY_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_surface
- */
-#define XDG_SURFACE_ACK_CONFIGURE_SINCE_VERSION 1
-
-/** @ingroup iface_xdg_surface */
-static inline void
-xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data)
-{
-       wl_proxy_set_user_data((struct wl_proxy *) xdg_surface, user_data);
-}
-
-/** @ingroup iface_xdg_surface */
-static inline void *
-xdg_surface_get_user_data(struct xdg_surface *xdg_surface)
-{
-       return wl_proxy_get_user_data((struct wl_proxy *) xdg_surface);
-}
-
-static inline uint32_t
-xdg_surface_get_version(struct xdg_surface *xdg_surface)
-{
-       return wl_proxy_get_version((struct wl_proxy *) xdg_surface);
-}
-
-/**
- * @ingroup iface_xdg_surface
- *
- * Destroy the xdg_surface object. An xdg_surface must only be destroyed
- * after its role object has been destroyed, otherwise
- * a defunct_role_object error is raised.
- */
-static inline void
-xdg_surface_destroy(struct xdg_surface *xdg_surface)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
-                        XDG_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_xdg_surface
- *
- * This creates an xdg_toplevel object for the given xdg_surface and gives
- * the associated wl_surface the xdg_toplevel role.
- *
- * See the documentation of xdg_toplevel for more details about what an
- * xdg_toplevel is and how it is used.
- */
-static inline struct xdg_toplevel *
-xdg_surface_get_toplevel(struct xdg_surface *xdg_surface)
-{
-       struct wl_proxy *id;
-
-       id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
-                        XDG_SURFACE_GET_TOPLEVEL, &xdg_toplevel_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL);
-
-       return (struct xdg_toplevel *) id;
-}
-
-/**
- * @ingroup iface_xdg_surface
- *
- * This creates an xdg_popup object for the given xdg_surface and gives
- * the associated wl_surface the xdg_popup role.
- *
- * If null is passed as a parent, a parent surface must be specified using
- * some other protocol, before committing the initial state.
- *
- * See the documentation of xdg_popup for more details about what an
- * xdg_popup is and how it is used.
- */
-static inline struct xdg_popup *
-xdg_surface_get_popup(struct xdg_surface *xdg_surface, struct xdg_surface *parent, struct xdg_positioner *positioner)
-{
-       struct wl_proxy *id;
-
-       id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
-                        XDG_SURFACE_GET_POPUP, &xdg_popup_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL, parent, positioner);
-
-       return (struct xdg_popup *) id;
-}
-
-/**
- * @ingroup iface_xdg_surface
- *
- * The window geometry of a surface is its "visible bounds" from the
- * user's perspective. Client-side decorations often have invisible
- * portions like drop-shadows which should be ignored for the
- * purposes of aligning, placing and constraining windows.
- *
- * The window geometry is double-buffered state, see wl_surface.commit.
- *
- * When maintaining a position, the compositor should treat the (x, y)
- * coordinate of the window geometry as the top left corner of the window.
- * A client changing the (x, y) window geometry coordinate should in
- * general not alter the position of the window.
- *
- * Once the window geometry of the surface is set, it is not possible to
- * unset it, and it will remain the same until set_window_geometry is
- * called again, even if a new subsurface or buffer is attached.
- *
- * If never set, the value is the full bounds of the surface,
- * including any subsurfaces. This updates dynamically on every
- * commit. This unset is meant for extremely simple clients.
- *
- * The arguments are given in the surface-local coordinate space of
- * the wl_surface associated with this xdg_surface, and may extend outside
- * of the wl_surface itself to mark parts of the subsurface tree as part of
- * the window geometry.
- *
- * When applied, the effective window geometry will be the set window
- * geometry clamped to the bounding rectangle of the combined
- * geometry of the surface of the xdg_surface and the associated
- * subsurfaces.
- *
- * The effective geometry will not be recalculated unless a new call to
- * set_window_geometry is done and the new pending surface state is
- * subsequently applied.
- *
- * The width and height of the effective window geometry must be
- * greater than zero. Setting an invalid size will raise an
- * invalid_size error.
- */
-static inline void
-xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
-                        XDG_SURFACE_SET_WINDOW_GEOMETRY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, x, y, width, height);
-}
-
-/**
- * @ingroup iface_xdg_surface
- *
- * When a configure event is received, if a client commits the
- * surface in response to the configure event, then the client
- * must make an ack_configure request sometime before the commit
- * request, passing along the serial of the configure event.
- *
- * For instance, for toplevel surfaces the compositor might use this
- * information to move a surface to the top left only when the client has
- * drawn itself for the maximized or fullscreen state.
- *
- * If the client receives multiple configure events before it
- * can respond to one, it only has to ack the last configure event.
- * Acking a configure event that was never sent raises an invalid_serial
- * error.
- *
- * A client is not required to commit immediately after sending
- * an ack_configure request - it may even ack_configure several times
- * before its next surface commit.
- *
- * A client may send multiple ack_configure requests before committing, but
- * only the last request sent before a commit indicates which configure
- * event the client really is responding to.
- *
- * Sending an ack_configure request consumes the serial number sent with
- * the request, as well as serial numbers sent by all configure events
- * sent on this xdg_surface prior to the configure event referenced by
- * the committed serial.
- *
- * It is an error to issue multiple ack_configure requests referencing a
- * serial from the same configure event, or to issue an ack_configure
- * request referencing a serial from a configure event issued before the
- * event identified by the last ack_configure request for the same
- * xdg_surface. Doing so will raise an invalid_serial error.
- */
-static inline void
-xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
-                        XDG_SURFACE_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, serial);
-}
-
-#ifndef XDG_TOPLEVEL_ERROR_ENUM
-#define XDG_TOPLEVEL_ERROR_ENUM
-enum xdg_toplevel_error {
-       /**
-        * provided value is         not a valid variant of the resize_edge enum
-        */
-       XDG_TOPLEVEL_ERROR_INVALID_RESIZE_EDGE = 0,
-       /**
-        * invalid parent toplevel
-        */
-       XDG_TOPLEVEL_ERROR_INVALID_PARENT = 1,
-       /**
-        * client provided an invalid min or max size
-        */
-       XDG_TOPLEVEL_ERROR_INVALID_SIZE = 2,
-};
-#endif /* XDG_TOPLEVEL_ERROR_ENUM */
-
-#ifndef XDG_TOPLEVEL_RESIZE_EDGE_ENUM
-#define XDG_TOPLEVEL_RESIZE_EDGE_ENUM
-/**
- * @ingroup iface_xdg_toplevel
- * edge values for resizing
- *
- * These values are used to indicate which edge of a surface
- * is being dragged in a resize operation.
- */
-enum xdg_toplevel_resize_edge {
-       XDG_TOPLEVEL_RESIZE_EDGE_NONE = 0,
-       XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1,
-       XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2,
-       XDG_TOPLEVEL_RESIZE_EDGE_LEFT = 4,
-       XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT = 5,
-       XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT = 6,
-       XDG_TOPLEVEL_RESIZE_EDGE_RIGHT = 8,
-       XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT = 9,
-       XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT = 10,
-};
-#endif /* XDG_TOPLEVEL_RESIZE_EDGE_ENUM */
-
-#ifndef XDG_TOPLEVEL_STATE_ENUM
-#define XDG_TOPLEVEL_STATE_ENUM
-/**
- * @ingroup iface_xdg_toplevel
- * types of state on the surface
- *
- * The different state values used on the surface. This is designed for
- * state values like maximized, fullscreen. It is paired with the
- * configure event to ensure that both the client and the compositor
- * setting the state can be synchronized.
- *
- * States set in this way are double-buffered, see wl_surface.commit.
- */
-enum xdg_toplevel_state {
-       /**
-        * the surface is maximized
-        * the surface is maximized
-        *
-        * The surface is maximized. The window geometry specified in the
-        * configure event must be obeyed by the client, or the
-        * xdg_wm_base.invalid_surface_state error is raised.
-        *
-        * The client should draw without shadow or other decoration
-        * outside of the window geometry.
-        */
-       XDG_TOPLEVEL_STATE_MAXIMIZED = 1,
-       /**
-        * the surface is fullscreen
-        * the surface is fullscreen
-        *
-        * The surface is fullscreen. The window geometry specified in
-        * the configure event is a maximum; the client cannot resize
-        * beyond it. For a surface to cover the whole fullscreened area,
-        * the geometry dimensions must be obeyed by the client. For more
-        * details, see xdg_toplevel.set_fullscreen.
-        */
-       XDG_TOPLEVEL_STATE_FULLSCREEN = 2,
-       /**
-        * the surface is being resized
-        * the surface is being resized
-        *
-        * The surface is being resized. The window geometry specified in
-        * the configure event is a maximum; the client cannot resize
-        * beyond it. Clients that have aspect ratio or cell sizing
-        * configuration can use a smaller size, however.
-        */
-       XDG_TOPLEVEL_STATE_RESIZING = 3,
-       /**
-        * the surface is now activated
-        * the surface is now activated
-        *
-        * Client window decorations should be painted as if the window
-        * is active. Do not assume this means that the window actually has
-        * keyboard or pointer focus.
-        */
-       XDG_TOPLEVEL_STATE_ACTIVATED = 4,
-       /**
-        * the surface’s left edge is tiled
-        *
-        * The window is currently in a tiled layout and the left edge is
-        * considered to be adjacent to another part of the tiling grid.
-        *
-        * The client should draw without shadow or other decoration
-        * outside of the window geometry on the left edge.
-        * @since 2
-        */
-       XDG_TOPLEVEL_STATE_TILED_LEFT = 5,
-       /**
-        * the surface’s right edge is tiled
-        *
-        * The window is currently in a tiled layout and the right edge
-        * is considered to be adjacent to another part of the tiling grid.
-        *
-        * The client should draw without shadow or other decoration
-        * outside of the window geometry on the right edge.
-        * @since 2
-        */
-       XDG_TOPLEVEL_STATE_TILED_RIGHT = 6,
-       /**
-        * the surface’s top edge is tiled
-        *
-        * The window is currently in a tiled layout and the top edge is
-        * considered to be adjacent to another part of the tiling grid.
-        *
-        * The client should draw without shadow or other decoration
-        * outside of the window geometry on the top edge.
-        * @since 2
-        */
-       XDG_TOPLEVEL_STATE_TILED_TOP = 7,
-       /**
-        * the surface’s bottom edge is tiled
-        *
-        * The window is currently in a tiled layout and the bottom edge
-        * is considered to be adjacent to another part of the tiling grid.
-        *
-        * The client should draw without shadow or other decoration
-        * outside of the window geometry on the bottom edge.
-        * @since 2
-        */
-       XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8,
-       /**
-        * surface repaint is suspended
-        *
-        * The surface is currently not ordinarily being repainted; for
-        * example because its content is occluded by another window, or
-        * its outputs are switched off due to screen locking.
-        * @since 6
-        */
-       XDG_TOPLEVEL_STATE_SUSPENDED = 9,
-       /**
-        * the surface’s left edge is constrained
-        *
-        * The left edge of the window is currently constrained, meaning
-        * it shouldn't attempt to resize from that edge. It can for
-        * example mean it's tiled next to a monitor edge on the
-        * constrained side of the window.
-        * @since 7
-        */
-       XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT = 10,
-       /**
-        * the surface’s right edge is constrained
-        *
-        * The right edge of the window is currently constrained, meaning
-        * it shouldn't attempt to resize from that edge. It can for
-        * example mean it's tiled next to a monitor edge on the
-        * constrained side of the window.
-        * @since 7
-        */
-       XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT = 11,
-       /**
-        * the surface’s top edge is constrained
-        *
-        * The top edge of the window is currently constrained, meaning
-        * it shouldn't attempt to resize from that edge. It can for
-        * example mean it's tiled next to a monitor edge on the
-        * constrained side of the window.
-        * @since 7
-        */
-       XDG_TOPLEVEL_STATE_CONSTRAINED_TOP = 12,
-       /**
-        * the surface’s bottom edge is tiled
-        *
-        * The bottom edge of the window is currently constrained,
-        * meaning it shouldn't attempt to resize from that edge. It can
-        * for example mean it's tiled next to a monitor edge on the
-        * constrained side of the window.
-        * @since 7
-        */
-       XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM = 13,
-};
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION 2
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION 2
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_TILED_TOP_SINCE_VERSION 2
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_TILED_BOTTOM_SINCE_VERSION 2
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION 6
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT_SINCE_VERSION 7
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT_SINCE_VERSION 7
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_CONSTRAINED_TOP_SINCE_VERSION 7
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM_SINCE_VERSION 7
-#endif /* XDG_TOPLEVEL_STATE_ENUM */
-
-#ifndef XDG_TOPLEVEL_WM_CAPABILITIES_ENUM
-#define XDG_TOPLEVEL_WM_CAPABILITIES_ENUM
-enum xdg_toplevel_wm_capabilities {
-       /**
-        * show_window_menu is available
-        */
-       XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU = 1,
-       /**
-        * set_maximized and unset_maximized are available
-        */
-       XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE = 2,
-       /**
-        * set_fullscreen and unset_fullscreen are available
-        */
-       XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN = 3,
-       /**
-        * set_minimized is available
-        */
-       XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE = 4,
-};
-#endif /* XDG_TOPLEVEL_WM_CAPABILITIES_ENUM */
-
-/**
- * @ingroup iface_xdg_toplevel
- * @struct xdg_toplevel_listener
- */
-struct xdg_toplevel_listener {
-       /**
-        * suggest a surface change
-        *
-        * This configure event asks the client to resize its toplevel
-        * surface or to change its state. The configured state should not
-        * be applied immediately. See xdg_surface.configure for details.
-        *
-        * The width and height arguments specify a hint to the window
-        * about how its surface should be resized in window geometry
-        * coordinates. See set_window_geometry.
-        *
-        * If the width or height arguments are zero, it means the client
-        * should decide its own window dimension. This may happen when the
-        * compositor needs to configure the state of the surface but
-        * doesn't have any information about any previous or expected
-        * dimension.
-        *
-        * The states listed in the event specify how the width/height
-        * arguments should be interpreted, and possibly how it should be
-        * drawn.
-        *
-        * Clients must send an ack_configure in response to this event.
-        * See xdg_surface.configure and xdg_surface.ack_configure for
-        * details.
-        */
-       void (*configure)(void *data,
-                         struct xdg_toplevel *xdg_toplevel,
-                         int32_t width,
-                         int32_t height,
-                         struct wl_array *states);
-       /**
-        * surface wants to be closed
-        *
-        * The close event is sent by the compositor when the user wants
-        * the surface to be closed. This should be equivalent to the user
-        * clicking the close button in client-side decorations, if your
-        * application has any.
-        *
-        * This is only a request that the user intends to close the
-        * window. The client may choose to ignore this request, or show a
-        * dialog to ask the user to save their data, etc.
-        */
-       void (*close)(void *data,
-                     struct xdg_toplevel *xdg_toplevel);
-       /**
-        * recommended window geometry bounds
-        *
-        * The configure_bounds event may be sent prior to a
-        * xdg_toplevel.configure event to communicate the bounds a window
-        * geometry size is recommended to constrain to.
-        *
-        * The passed width and height are in surface coordinate space. If
-        * width and height are 0, it means bounds is unknown and
-        * equivalent to as if no configure_bounds event was ever sent for
-        * this surface.
-        *
-        * The bounds can for example correspond to the size of a monitor
-        * excluding any panels or other shell components, so that a
-        * surface isn't created in a way that it cannot fit.
-        *
-        * The bounds may change at any point, and in such a case, a new
-        * xdg_toplevel.configure_bounds will be sent, followed by
-        * xdg_toplevel.configure and xdg_surface.configure.
-        * @since 4
-        */
-       void (*configure_bounds)(void *data,
-                                struct xdg_toplevel *xdg_toplevel,
-                                int32_t width,
-                                int32_t height);
-       /**
-        * compositor capabilities
-        *
-        * This event advertises the capabilities supported by the
-        * compositor. If a capability isn't supported, clients should hide
-        * or disable the UI elements that expose this functionality. For
-        * instance, if the compositor doesn't advertise support for
-        * minimized toplevels, a button triggering the set_minimized
-        * request should not be displayed.
-        *
-        * The compositor will ignore requests it doesn't support. For
-        * instance, a compositor which doesn't advertise support for
-        * minimized will ignore set_minimized requests.
-        *
-        * Compositors must send this event once before the first
-        * xdg_surface.configure event. When the capabilities change,
-        * compositors must send this event again and then send an
-        * xdg_surface.configure event.
-        *
-        * The configured state should not be applied immediately. See
-        * xdg_surface.configure for details.
-        *
-        * The capabilities are sent as an array of 32-bit unsigned
-        * integers in native endianness.
-        * @param capabilities array of 32-bit capabilities
-        * @since 5
-        */
-       void (*wm_capabilities)(void *data,
-                               struct xdg_toplevel *xdg_toplevel,
-                               struct wl_array *capabilities);
-};
-
-/**
- * @ingroup iface_xdg_toplevel
- */
-static inline int
-xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel,
-                         const struct xdg_toplevel_listener *listener, void *data)
-{
-       return wl_proxy_add_listener((struct wl_proxy *) xdg_toplevel,
-                                    (void (**)(void)) listener, data);
-}
-
-#define XDG_TOPLEVEL_DESTROY 0
-#define XDG_TOPLEVEL_SET_PARENT 1
-#define XDG_TOPLEVEL_SET_TITLE 2
-#define XDG_TOPLEVEL_SET_APP_ID 3
-#define XDG_TOPLEVEL_SHOW_WINDOW_MENU 4
-#define XDG_TOPLEVEL_MOVE 5
-#define XDG_TOPLEVEL_RESIZE 6
-#define XDG_TOPLEVEL_SET_MAX_SIZE 7
-#define XDG_TOPLEVEL_SET_MIN_SIZE 8
-#define XDG_TOPLEVEL_SET_MAXIMIZED 9
-#define XDG_TOPLEVEL_UNSET_MAXIMIZED 10
-#define XDG_TOPLEVEL_SET_FULLSCREEN 11
-#define XDG_TOPLEVEL_UNSET_FULLSCREEN 12
-#define XDG_TOPLEVEL_SET_MINIMIZED 13
-
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_CONFIGURE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_CLOSE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION 4
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION 5
-
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_DESTROY_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_PARENT_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_TITLE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_APP_ID_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SHOW_WINDOW_MENU_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_MOVE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_RESIZE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_MAX_SIZE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_MIN_SIZE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_MAXIMIZED_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_UNSET_MAXIMIZED_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_FULLSCREEN_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_UNSET_FULLSCREEN_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_toplevel
- */
-#define XDG_TOPLEVEL_SET_MINIMIZED_SINCE_VERSION 1
-
-/** @ingroup iface_xdg_toplevel */
-static inline void
-xdg_toplevel_set_user_data(struct xdg_toplevel *xdg_toplevel, void *user_data)
-{
-       wl_proxy_set_user_data((struct wl_proxy *) xdg_toplevel, user_data);
-}
-
-/** @ingroup iface_xdg_toplevel */
-static inline void *
-xdg_toplevel_get_user_data(struct xdg_toplevel *xdg_toplevel)
-{
-       return wl_proxy_get_user_data((struct wl_proxy *) xdg_toplevel);
-}
-
-static inline uint32_t
-xdg_toplevel_get_version(struct xdg_toplevel *xdg_toplevel)
-{
-       return wl_proxy_get_version((struct wl_proxy *) xdg_toplevel);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * This request destroys the role surface and unmaps the surface;
- * see "Unmapping" behavior in interface section for details.
- */
-static inline void
-xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Set the "parent" of this surface. This surface should be stacked
- * above the parent surface and all other ancestor surfaces.
- *
- * Parent surfaces should be set on dialogs, toolboxes, or other
- * "auxiliary" surfaces, so that the parent is raised when the dialog
- * is raised.
- *
- * Setting a null parent for a child surface unsets its parent. Setting
- * a null parent for a surface which currently has no parent is a no-op.
- *
- * Only mapped surfaces can have child surfaces. Setting a parent which
- * is not mapped is equivalent to setting a null parent. If a surface
- * becomes unmapped, its children's parent is set to the parent of
- * the now-unmapped surface. If the now-unmapped surface has no parent,
- * its children's parent is unset. If the now-unmapped surface becomes
- * mapped again, its parent-child relationship is not restored.
- *
- * The parent toplevel must not be one of the child toplevel's
- * descendants, and the parent must be different from the child toplevel,
- * otherwise the invalid_parent protocol error is raised.
- */
-static inline void
-xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_PARENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, parent);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Set a short title for the surface.
- *
- * This string may be used to identify the surface in a task bar,
- * window list, or other user interface elements provided by the
- * compositor.
- *
- * The string must be encoded in UTF-8.
- */
-static inline void
-xdg_toplevel_set_title(struct xdg_toplevel *xdg_toplevel, const char *title)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, title);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Set an application identifier for the surface.
- *
- * The app ID identifies the general class of applications to which
- * the surface belongs. The compositor can use this to group multiple
- * surfaces together, or to determine how to launch a new application.
- *
- * For D-Bus activatable applications, the app ID is used as the D-Bus
- * service name.
- *
- * The compositor shell will try to group application surfaces together
- * by their app ID. As a best practice, it is suggested to select app
- * ID's that match the basename of the application's .desktop file.
- * For example, "org.freedesktop.FooViewer" where the .desktop file is
- * "org.freedesktop.FooViewer.desktop".
- *
- * Like other properties, a set_app_id request can be sent after the
- * xdg_toplevel has been mapped to update the property.
- *
- * See the desktop-entry specification [0] for more details on
- * application identifiers and how they relate to well-known D-Bus
- * names and .desktop files.
- *
- * [0] https://standards.freedesktop.org/desktop-entry-spec/
- */
-static inline void
-xdg_toplevel_set_app_id(struct xdg_toplevel *xdg_toplevel, const char *app_id)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_APP_ID, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, app_id);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Clients implementing client-side decorations might want to show
- * a context menu when right-clicking on the decorations, giving the
- * user a menu that they can use to maximize or minimize the window.
- *
- * This request asks the compositor to pop up such a window menu at
- * the given position, relative to the local surface coordinates of
- * the parent surface. There are no guarantees as to what menu items
- * the window menu contains, or even if a window menu will be drawn
- * at all.
- *
- * This request must be used in response to some sort of user action
- * like a button press, key press, or touch down event.
- */
-static inline void
-xdg_toplevel_show_window_menu(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SHOW_WINDOW_MENU, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, x, y);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Start an interactive, user-driven move of the surface.
- *
- * This request must be used in response to some sort of user action
- * like a button press, key press, or touch down event. The passed
- * serial is used to determine the type of interactive move (touch,
- * pointer, etc).
- *
- * The server may ignore move requests depending on the state of
- * the surface (e.g. fullscreen or maximized), or if the passed serial
- * is no longer valid.
- *
- * If triggered, the surface will lose the focus of the device
- * (wl_pointer, wl_touch, etc) used for the move. It is up to the
- * compositor to visually indicate that the move is taking place, such as
- * updating a pointer cursor, during the move. There is no guarantee
- * that the device focus will return when the move is completed.
- */
-static inline void
-xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Start a user-driven, interactive resize of the surface.
- *
- * This request must be used in response to some sort of user action
- * like a button press, key press, or touch down event. The passed
- * serial is used to determine the type of interactive resize (touch,
- * pointer, etc).
- *
- * The server may ignore resize requests depending on the state of
- * the surface (e.g. fullscreen or maximized).
- *
- * If triggered, the client will receive configure events with the
- * "resize" state enum value and the expected sizes. See the "resize"
- * enum value for more details about what is required. The client
- * must also acknowledge configure events using "ack_configure". After
- * the resize is completed, the client will receive another "configure"
- * event without the resize state.
- *
- * If triggered, the surface also will lose the focus of the device
- * (wl_pointer, wl_touch, etc) used for the resize. It is up to the
- * compositor to visually indicate that the resize is taking place,
- * such as updating a pointer cursor, during the resize. There is no
- * guarantee that the device focus will return when the resize is
- * completed.
- *
- * The edges parameter specifies how the surface should be resized, and
- * is one of the values of the resize_edge enum. Values not matching
- * a variant of the enum will cause the invalid_resize_edge protocol error.
- * The compositor may use this information to update the surface position
- * for example when dragging the top left corner. The compositor may also
- * use this information to adapt its behavior, e.g. choose an appropriate
- * cursor image.
- */
-static inline void
-xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, edges);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Set a maximum size for the window.
- *
- * The client can specify a maximum size so that the compositor does
- * not try to configure the window beyond this size.
- *
- * The width and height arguments are in window geometry coordinates.
- * See xdg_surface.set_window_geometry.
- *
- * Values set in this way are double-buffered, see wl_surface.commit.
- *
- * The compositor can use this information to allow or disallow
- * different states like maximize or fullscreen and draw accurate
- * animations.
- *
- * Similarly, a tiling window manager may use this information to
- * place and resize client windows in a more effective way.
- *
- * The client should not rely on the compositor to obey the maximum
- * size. The compositor may decide to ignore the values set by the
- * client and request a larger size.
- *
- * If never set, or a value of zero in the request, means that the
- * client has no expected maximum size in the given dimension.
- * As a result, a client wishing to reset the maximum size
- * to an unspecified state can use zero for width and height in the
- * request.
- *
- * Requesting a maximum size to be smaller than the minimum size of
- * a surface is illegal and will result in an invalid_size error.
- *
- * The width and height must be greater than or equal to zero. Using
- * strictly negative values for width or height will result in a
- * invalid_size error.
- */
-static inline void
-xdg_toplevel_set_max_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_MAX_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Set a minimum size for the window.
- *
- * The client can specify a minimum size so that the compositor does
- * not try to configure the window below this size.
- *
- * The width and height arguments are in window geometry coordinates.
- * See xdg_surface.set_window_geometry.
- *
- * Values set in this way are double-buffered, see wl_surface.commit.
- *
- * The compositor can use this information to allow or disallow
- * different states like maximize or fullscreen and draw accurate
- * animations.
- *
- * Similarly, a tiling window manager may use this information to
- * place and resize client windows in a more effective way.
- *
- * The client should not rely on the compositor to obey the minimum
- * size. The compositor may decide to ignore the values set by the
- * client and request a smaller size.
- *
- * If never set, or a value of zero in the request, means that the
- * client has no expected minimum size in the given dimension.
- * As a result, a client wishing to reset the minimum size
- * to an unspecified state can use zero for width and height in the
- * request.
- *
- * Requesting a minimum size to be larger than the maximum size of
- * a surface is illegal and will result in an invalid_size error.
- *
- * The width and height must be greater than or equal to zero. Using
- * strictly negative values for width and height will result in a
- * invalid_size error.
- */
-static inline void
-xdg_toplevel_set_min_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_MIN_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Maximize the surface.
- *
- * After requesting that the surface should be maximized, the compositor
- * will respond by emitting a configure event. Whether this configure
- * actually sets the window maximized is subject to compositor policies.
- * The client must then update its content, drawing in the configured
- * state. The client must also acknowledge the configure when committing
- * the new content (see ack_configure).
- *
- * It is up to the compositor to decide how and where to maximize the
- * surface, for example which output and what region of the screen should
- * be used.
- *
- * If the surface was already maximized, the compositor will still emit
- * a configure event with the "maximized" state.
- *
- * If the surface is in a fullscreen state, this request has no direct
- * effect. It may alter the state the surface is returned to when
- * unmaximized unless overridden by the compositor.
- */
-static inline void
-xdg_toplevel_set_maximized(struct xdg_toplevel *xdg_toplevel)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Unmaximize the surface.
- *
- * After requesting that the surface should be unmaximized, the compositor
- * will respond by emitting a configure event. Whether this actually
- * un-maximizes the window is subject to compositor policies.
- * If available and applicable, the compositor will include the window
- * geometry dimensions the window had prior to being maximized in the
- * configure event. The client must then update its content, drawing it in
- * the configured state. The client must also acknowledge the configure
- * when committing the new content (see ack_configure).
- *
- * It is up to the compositor to position the surface after it was
- * unmaximized; usually the position the surface had before maximizing, if
- * applicable.
- *
- * If the surface was already not maximized, the compositor will still
- * emit a configure event without the "maximized" state.
- *
- * If the surface is in a fullscreen state, this request has no direct
- * effect. It may alter the state the surface is returned to when
- * unmaximized unless overridden by the compositor.
- */
-static inline void
-xdg_toplevel_unset_maximized(struct xdg_toplevel *xdg_toplevel)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_UNSET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Make the surface fullscreen.
- *
- * After requesting that the surface should be fullscreened, the
- * compositor will respond by emitting a configure event. Whether the
- * client is actually put into a fullscreen state is subject to compositor
- * policies. The client must also acknowledge the configure when
- * committing the new content (see ack_configure).
- *
- * The output passed by the request indicates the client's preference as
- * to which display it should be set fullscreen on. If this value is NULL,
- * it's up to the compositor to choose which display will be used to map
- * this surface.
- *
- * If the surface doesn't cover the whole output, the compositor will
- * position the surface in the center of the output and compensate with
- * with border fill covering the rest of the output. The content of the
- * border fill is undefined, but should be assumed to be in some way that
- * attempts to blend into the surrounding area (e.g. solid black).
- *
- * If the fullscreened surface is not opaque, the compositor must make
- * sure that other screen content not part of the same surface tree (made
- * up of subsurfaces, popups or similarly coupled surfaces) are not
- * visible below the fullscreened surface.
- */
-static inline void
-xdg_toplevel_set_fullscreen(struct xdg_toplevel *xdg_toplevel, struct wl_output *output)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, output);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Make the surface no longer fullscreen.
- *
- * After requesting that the surface should be unfullscreened, the
- * compositor will respond by emitting a configure event.
- * Whether this actually removes the fullscreen state of the client is
- * subject to compositor policies.
- *
- * Making a surface unfullscreen sets states for the surface based on the following:
- * * the state(s) it may have had before becoming fullscreen
- * * any state(s) decided by the compositor
- * * any state(s) requested by the client while the surface was fullscreen
- *
- * The compositor may include the previous window geometry dimensions in
- * the configure event, if applicable.
- *
- * The client must also acknowledge the configure when committing the new
- * content (see ack_configure).
- */
-static inline void
-xdg_toplevel_unset_fullscreen(struct xdg_toplevel *xdg_toplevel)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_UNSET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
-}
-
-/**
- * @ingroup iface_xdg_toplevel
- *
- * Request that the compositor minimize your surface. There is no
- * way to know if the surface is currently minimized, nor is there
- * any way to unset minimization on this surface.
- *
- * If you are looking to throttle redrawing when minimized, please
- * instead use the wl_surface.frame event for this, as this will
- * also work with live previews on windows in Alt-Tab, Expose or
- * similar compositor features.
- */
-static inline void
-xdg_toplevel_set_minimized(struct xdg_toplevel *xdg_toplevel)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
-                        XDG_TOPLEVEL_SET_MINIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
-}
-
-#ifndef XDG_POPUP_ERROR_ENUM
-#define XDG_POPUP_ERROR_ENUM
-enum xdg_popup_error {
-       /**
-        * tried to grab after being mapped
-        */
-       XDG_POPUP_ERROR_INVALID_GRAB = 0,
-};
-#endif /* XDG_POPUP_ERROR_ENUM */
-
-/**
- * @ingroup iface_xdg_popup
- * @struct xdg_popup_listener
- */
-struct xdg_popup_listener {
-       /**
-        * configure the popup surface
-        *
-        * This event asks the popup surface to configure itself given
-        * the configuration. The configured state should not be applied
-        * immediately. See xdg_surface.configure for details.
-        *
-        * The x and y arguments represent the position the popup was
-        * placed at given the xdg_positioner rule, relative to the upper
-        * left corner of the window geometry of the parent surface.
-        *
-        * For version 2 or older, the configure event for an xdg_popup is
-        * only ever sent once for the initial configuration. Starting with
-        * version 3, it may be sent again if the popup is setup with an
-        * xdg_positioner with set_reactive requested, or in response to
-        * xdg_popup.reposition requests.
-        * @param x x position relative to parent surface window geometry
-        * @param y y position relative to parent surface window geometry
-        * @param width window geometry width
-        * @param height window geometry height
-        */
-       void (*configure)(void *data,
-                         struct xdg_popup *xdg_popup,
-                         int32_t x,
-                         int32_t y,
-                         int32_t width,
-                         int32_t height);
-       /**
-        * popup interaction is done
-        *
-        * The popup_done event is sent out when a popup is dismissed by
-        * the compositor. The client should destroy the xdg_popup object
-        * at this point.
-        */
-       void (*popup_done)(void *data,
-                          struct xdg_popup *xdg_popup);
-       /**
-        * signal the completion of a repositioned request
-        *
-        * The repositioned event is sent as part of a popup
-        * configuration sequence, together with xdg_popup.configure and
-        * lastly xdg_surface.configure to notify the completion of a
-        * reposition request.
-        *
-        * The repositioned event is to notify about the completion of a
-        * xdg_popup.reposition request. The token argument is the token
-        * passed in the xdg_popup.reposition request.
-        *
-        * Immediately after this event is emitted, xdg_popup.configure and
-        * xdg_surface.configure will be sent with the updated size and
-        * position, as well as a new configure serial.
-        *
-        * The client should optionally update the content of the popup,
-        * but must acknowledge the new popup configuration for the new
-        * position to take effect. See xdg_surface.ack_configure for
-        * details.
-        * @param token reposition request token
-        * @since 3
-        */
-       void (*repositioned)(void *data,
-                            struct xdg_popup *xdg_popup,
-                            uint32_t token);
-};
-
-/**
- * @ingroup iface_xdg_popup
- */
-static inline int
-xdg_popup_add_listener(struct xdg_popup *xdg_popup,
-                      const struct xdg_popup_listener *listener, void *data)
-{
-       return wl_proxy_add_listener((struct wl_proxy *) xdg_popup,
-                                    (void (**)(void)) listener, data);
-}
-
-#define XDG_POPUP_DESTROY 0
-#define XDG_POPUP_GRAB 1
-#define XDG_POPUP_REPOSITION 2
-
-/**
- * @ingroup iface_xdg_popup
- */
-#define XDG_POPUP_CONFIGURE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_popup
- */
-#define XDG_POPUP_POPUP_DONE_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_popup
- */
-#define XDG_POPUP_REPOSITIONED_SINCE_VERSION 3
-
-/**
- * @ingroup iface_xdg_popup
- */
-#define XDG_POPUP_DESTROY_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_popup
- */
-#define XDG_POPUP_GRAB_SINCE_VERSION 1
-/**
- * @ingroup iface_xdg_popup
- */
-#define XDG_POPUP_REPOSITION_SINCE_VERSION 3
-
-/** @ingroup iface_xdg_popup */
-static inline void
-xdg_popup_set_user_data(struct xdg_popup *xdg_popup, void *user_data)
-{
-       wl_proxy_set_user_data((struct wl_proxy *) xdg_popup, user_data);
-}
-
-/** @ingroup iface_xdg_popup */
-static inline void *
-xdg_popup_get_user_data(struct xdg_popup *xdg_popup)
-{
-       return wl_proxy_get_user_data((struct wl_proxy *) xdg_popup);
-}
-
-static inline uint32_t
-xdg_popup_get_version(struct xdg_popup *xdg_popup)
-{
-       return wl_proxy_get_version((struct wl_proxy *) xdg_popup);
-}
-
-/**
- * @ingroup iface_xdg_popup
- *
- * This destroys the popup. Explicitly destroying the xdg_popup
- * object will also dismiss the popup, and unmap the surface.
- *
- * If this xdg_popup is not the "topmost" popup, the
- * xdg_wm_base.not_the_topmost_popup protocol error will be sent.
- */
-static inline void
-xdg_popup_destroy(struct xdg_popup *xdg_popup)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup,
-                        XDG_POPUP_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_xdg_popup
- *
- * This request makes the created popup take an explicit grab. An explicit
- * grab will be dismissed when the user dismisses the popup, or when the
- * client destroys the xdg_popup. This can be done by the user clicking
- * outside the surface, using the keyboard, or even locking the screen
- * through closing the lid or a timeout.
- *
- * If the compositor denies the grab, the popup will be immediately
- * dismissed.
- *
- * This request must be used in response to some sort of user action like a
- * button press, key press, or touch down event. The serial number of the
- * event should be passed as 'serial'.
- *
- * The parent of a grabbing popup must either be an xdg_toplevel surface or
- * another xdg_popup with an explicit grab. If the parent is another
- * xdg_popup it means that the popups are nested, with this popup now being
- * the topmost popup.
- *
- * Nested popups must be destroyed in the reverse order they were created
- * in, e.g. the only popup you are allowed to destroy at all times is the
- * topmost one.
- *
- * When compositors choose to dismiss a popup, they may dismiss every
- * nested grabbing popup as well. When a compositor dismisses popups, it
- * will follow the same dismissing order as required from the client.
- *
- * If the topmost grabbing popup is destroyed, the grab will be returned to
- * the parent of the popup, if that parent previously had an explicit grab.
- *
- * If the parent is a grabbing popup which has already been dismissed, this
- * popup will be immediately dismissed. If the parent is a popup that did
- * not take an explicit grab, an error will be raised.
- *
- * During a popup grab, the client owning the grab will receive pointer
- * and touch events for all their surfaces as normal (similar to an
- * "owner-events" grab in X11 parlance), while the top most grabbing popup
- * will always have keyboard focus.
- */
-static inline void
-xdg_popup_grab(struct xdg_popup *xdg_popup, struct wl_seat *seat, uint32_t serial)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup,
-                        XDG_POPUP_GRAB, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, seat, serial);
-}
-
-/**
- * @ingroup iface_xdg_popup
- *
- * Reposition an already-mapped popup. The popup will be placed given the
- * details in the passed xdg_positioner object, and a
- * xdg_popup.repositioned followed by xdg_popup.configure and
- * xdg_surface.configure will be emitted in response. Any parameters set
- * by the previous positioner will be discarded.
- *
- * The passed token will be sent in the corresponding
- * xdg_popup.repositioned event. The new popup position will not take
- * effect until the corresponding configure event is acknowledged by the
- * client. See xdg_popup.repositioned for details. The token itself is
- * opaque, and has no other special meaning.
- *
- * If multiple reposition requests are sent, the compositor may skip all
- * but the last one.
- *
- * If the popup is repositioned in response to a configure event for its
- * parent, the client should send an xdg_positioner.set_parent_configure
- * and possibly an xdg_positioner.set_parent_size request to allow the
- * compositor to properly constrain the popup.
- *
- * If the popup is repositioned together with a parent that is being
- * resized, but not in response to a configure event, the client should
- * send an xdg_positioner.set_parent_size request.
- */
-static inline void
-xdg_popup_reposition(struct xdg_popup *xdg_popup, struct xdg_positioner *positioner, uint32_t token)
-{
-       wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup,
-                        XDG_POPUP_REPOSITION, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, positioner, token);
-}
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
diff --git a/driver/wayland-protocols/xdg-shell-v1-protocol.c b/driver/wayland-protocols/xdg-shell-v1-protocol.c
deleted file mode 100644 (file)
index 4faed8d..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Generated by wayland-scanner 1.23.1 */
-
-/*
- * Copyright © 2008-2013 Kristian Høgsberg
- * Copyright © 2013      Rafael Antognolli
- * Copyright © 2013      Jasper St. Pierre
- * Copyright © 2010-2013 Intel Corporation
- * Copyright © 2015-2017 Samsung Electronics Co., Ltd
- * Copyright © 2015-2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include "wayland-util.h"
-
-#ifndef __has_attribute
-# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
-#endif
-
-#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
-#define WL_PRIVATE __attribute__ ((visibility("hidden")))
-#else
-#define WL_PRIVATE
-#endif
-
-extern const struct wl_interface wl_output_interface;
-extern const struct wl_interface wl_seat_interface;
-extern const struct wl_interface wl_surface_interface;
-extern const struct wl_interface xdg_popup_interface;
-extern const struct wl_interface xdg_positioner_interface;
-extern const struct wl_interface xdg_surface_interface;
-extern const struct wl_interface xdg_toplevel_interface;
-
-static const struct wl_interface *xdg_shell_types[] = {
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       &xdg_positioner_interface,
-       &xdg_surface_interface,
-       &wl_surface_interface,
-       &xdg_toplevel_interface,
-       &xdg_popup_interface,
-       &xdg_surface_interface,
-       &xdg_positioner_interface,
-       &xdg_toplevel_interface,
-       &wl_seat_interface,
-       NULL,
-       NULL,
-       NULL,
-       &wl_seat_interface,
-       NULL,
-       &wl_seat_interface,
-       NULL,
-       NULL,
-       &wl_output_interface,
-       &wl_seat_interface,
-       NULL,
-       &xdg_positioner_interface,
-       NULL,
-};
-
-static const struct wl_message xdg_wm_base_requests[] = {
-       { "destroy", "", xdg_shell_types + 0 },
-       { "create_positioner", "n", xdg_shell_types + 4 },
-       { "get_xdg_surface", "no", xdg_shell_types + 5 },
-       { "pong", "u", xdg_shell_types + 0 },
-};
-
-static const struct wl_message xdg_wm_base_events[] = {
-       { "ping", "u", xdg_shell_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
-       "xdg_wm_base", 7,
-       4, xdg_wm_base_requests,
-       1, xdg_wm_base_events,
-};
-
-static const struct wl_message xdg_positioner_requests[] = {
-       { "destroy", "", xdg_shell_types + 0 },
-       { "set_size", "ii", xdg_shell_types + 0 },
-       { "set_anchor_rect", "iiii", xdg_shell_types + 0 },
-       { "set_anchor", "u", xdg_shell_types + 0 },
-       { "set_gravity", "u", xdg_shell_types + 0 },
-       { "set_constraint_adjustment", "u", xdg_shell_types + 0 },
-       { "set_offset", "ii", xdg_shell_types + 0 },
-       { "set_reactive", "3", xdg_shell_types + 0 },
-       { "set_parent_size", "3ii", xdg_shell_types + 0 },
-       { "set_parent_configure", "3u", xdg_shell_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
-       "xdg_positioner", 7,
-       10, xdg_positioner_requests,
-       0, NULL,
-};
-
-static const struct wl_message xdg_surface_requests[] = {
-       { "destroy", "", xdg_shell_types + 0 },
-       { "get_toplevel", "n", xdg_shell_types + 7 },
-       { "get_popup", "n?oo", xdg_shell_types + 8 },
-       { "set_window_geometry", "iiii", xdg_shell_types + 0 },
-       { "ack_configure", "u", xdg_shell_types + 0 },
-};
-
-static const struct wl_message xdg_surface_events[] = {
-       { "configure", "u", xdg_shell_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_surface_interface = {
-       "xdg_surface", 7,
-       5, xdg_surface_requests,
-       1, xdg_surface_events,
-};
-
-static const struct wl_message xdg_toplevel_requests[] = {
-       { "destroy", "", xdg_shell_types + 0 },
-       { "set_parent", "?o", xdg_shell_types + 11 },
-       { "set_title", "s", xdg_shell_types + 0 },
-       { "set_app_id", "s", xdg_shell_types + 0 },
-       { "show_window_menu", "ouii", xdg_shell_types + 12 },
-       { "move", "ou", xdg_shell_types + 16 },
-       { "resize", "ouu", xdg_shell_types + 18 },
-       { "set_max_size", "ii", xdg_shell_types + 0 },
-       { "set_min_size", "ii", xdg_shell_types + 0 },
-       { "set_maximized", "", xdg_shell_types + 0 },
-       { "unset_maximized", "", xdg_shell_types + 0 },
-       { "set_fullscreen", "?o", xdg_shell_types + 21 },
-       { "unset_fullscreen", "", xdg_shell_types + 0 },
-       { "set_minimized", "", xdg_shell_types + 0 },
-};
-
-static const struct wl_message xdg_toplevel_events[] = {
-       { "configure", "iia", xdg_shell_types + 0 },
-       { "close", "", xdg_shell_types + 0 },
-       { "configure_bounds", "4ii", xdg_shell_types + 0 },
-       { "wm_capabilities", "5a", xdg_shell_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
-       "xdg_toplevel", 7,
-       14, xdg_toplevel_requests,
-       4, xdg_toplevel_events,
-};
-
-static const struct wl_message xdg_popup_requests[] = {
-       { "destroy", "", xdg_shell_types + 0 },
-       { "grab", "ou", xdg_shell_types + 22 },
-       { "reposition", "3ou", xdg_shell_types + 24 },
-};
-
-static const struct wl_message xdg_popup_events[] = {
-       { "configure", "iiii", xdg_shell_types + 0 },
-       { "popup_done", "", xdg_shell_types + 0 },
-       { "repositioned", "3u", xdg_shell_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_popup_interface = {
-       "xdg_popup", 7,
-       3, xdg_popup_requests,
-       3, xdg_popup_events,
-};
-
diff --git a/driver/wayland-protocols/xdg-shell.xml b/driver/wayland-protocols/xdg-shell.xml
deleted file mode 100644 (file)
index c4d4685..0000000
+++ /dev/null
@@ -1,1415 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="xdg_shell">
-
-  <copyright>
-    Copyright © 2008-2013 Kristian Høgsberg
-    Copyright © 2013      Rafael Antognolli
-    Copyright © 2013      Jasper St. Pierre
-    Copyright © 2010-2013 Intel Corporation
-    Copyright © 2015-2017 Samsung Electronics Co., Ltd
-    Copyright © 2015-2017 Red Hat Inc.
-
-    Permission is hereby granted, free of charge, to any person obtaining a
-    copy of this software and associated documentation files (the "Software"),
-    to deal in the Software without restriction, including without limitation
-    the rights to use, copy, modify, merge, publish, distribute, sublicense,
-    and/or sell copies of the Software, and to permit persons to whom the
-    Software is furnished to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice (including the next
-    paragraph) shall be included in all copies or substantial portions of the
-    Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-    DEALINGS IN THE SOFTWARE.
-  </copyright>
-
-  <interface name="xdg_wm_base" version="7">
-    <description summary="create desktop-style surfaces">
-      The xdg_wm_base interface is exposed as a global object enabling clients
-      to turn their wl_surfaces into windows in a desktop environment. It
-      defines the basic functionality needed for clients and the compositor to
-      create windows that can be dragged, resized, maximized, etc, as well as
-      creating transient windows such as popup menus.
-    </description>
-
-    <enum name="error">
-      <entry name="role" value="0" summary="given wl_surface has another role"/>
-      <entry name="defunct_surfaces" value="1"
-            summary="xdg_wm_base was destroyed before children"/>
-      <entry name="not_the_topmost_popup" value="2"
-            summary="the client tried to map or destroy a non-topmost popup"/>
-      <entry name="invalid_popup_parent" value="3"
-            summary="the client specified an invalid popup parent surface"/>
-      <entry name="invalid_surface_state" value="4"
-            summary="the client provided an invalid surface state"/>
-      <entry name="invalid_positioner" value="5"
-            summary="the client provided an invalid positioner"/>
-      <entry name="unresponsive" value="6"
-            summary="the client didn’t respond to a ping event in time"/>
-    </enum>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy xdg_wm_base">
-       Destroy this xdg_wm_base object.
-
-       Destroying a bound xdg_wm_base object while there are surfaces
-       still alive created by this xdg_wm_base object instance is illegal
-       and will result in a defunct_surfaces error.
-      </description>
-    </request>
-
-    <request name="create_positioner">
-      <description summary="create a positioner object">
-       Create a positioner object. A positioner object is used to position
-       surfaces relative to some parent surface. See the interface description
-       and xdg_surface.get_popup for details.
-      </description>
-      <arg name="id" type="new_id" interface="xdg_positioner"/>
-    </request>
-
-    <request name="get_xdg_surface">
-      <description summary="create a shell surface from a surface">
-       This creates an xdg_surface for the given surface. While xdg_surface
-       itself is not a role, the corresponding surface may only be assigned
-       a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is
-       illegal to create an xdg_surface for a wl_surface which already has an
-       assigned role and this will result in a role error.
-
-       This creates an xdg_surface for the given surface. An xdg_surface is
-       used as basis to define a role to a given surface, such as xdg_toplevel
-       or xdg_popup. It also manages functionality shared between xdg_surface
-       based surface roles.
-
-       See the documentation of xdg_surface for more details about what an
-       xdg_surface is and how it is used.
-      </description>
-      <arg name="id" type="new_id" interface="xdg_surface"/>
-      <arg name="surface" type="object" interface="wl_surface"/>
-    </request>
-
-    <request name="pong">
-      <description summary="respond to a ping event">
-       A client must respond to a ping event with a pong request or
-       the client may be deemed unresponsive. See xdg_wm_base.ping
-       and xdg_wm_base.error.unresponsive.
-      </description>
-      <arg name="serial" type="uint" summary="serial of the ping event"/>
-    </request>
-
-    <event name="ping">
-      <description summary="check if the client is alive">
-       The ping event asks the client if it's still alive. Pass the
-       serial specified in the event back to the compositor by sending
-       a "pong" request back with the specified serial. See xdg_wm_base.pong.
-
-       Compositors can use this to determine if the client is still
-       alive. It's unspecified what will happen if the client doesn't
-       respond to the ping request, or in what timeframe. Clients should
-       try to respond in a reasonable amount of time. The “unresponsive”
-       error is provided for compositors that wish to disconnect unresponsive
-       clients.
-
-       A compositor is free to ping in any way it wants, but a client must
-       always respond to any xdg_wm_base object it created.
-      </description>
-      <arg name="serial" type="uint" summary="pass this to the pong request"/>
-    </event>
-  </interface>
-
-  <interface name="xdg_positioner" version="7">
-    <description summary="child surface positioner">
-      The xdg_positioner provides a collection of rules for the placement of a
-      child surface relative to a parent surface. Rules can be defined to ensure
-      the child surface remains within the visible area's borders, and to
-      specify how the child surface changes its position, such as sliding along
-      an axis, or flipping around a rectangle. These positioner-created rules are
-      constrained by the requirement that a child surface must intersect with or
-      be at least partially adjacent to its parent surface.
-
-      See the various requests for details about possible rules.
-
-      At the time of the request, the compositor makes a copy of the rules
-      specified by the xdg_positioner. Thus, after the request is complete the
-      xdg_positioner object can be destroyed or reused; further changes to the
-      object will have no effect on previous usages.
-
-      For an xdg_positioner object to be considered complete, it must have a
-      non-zero size set by set_size, and a non-zero anchor rectangle set by
-      set_anchor_rect. Passing an incomplete xdg_positioner object when
-      positioning a surface raises an invalid_positioner error.
-    </description>
-
-    <enum name="error">
-      <entry name="invalid_input" value="0" summary="invalid input provided"/>
-    </enum>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the xdg_positioner object">
-       Notify the compositor that the xdg_positioner will no longer be used.
-      </description>
-    </request>
-
-    <request name="set_size">
-      <description summary="set the size of the to-be positioned rectangle">
-       Set the size of the surface that is to be positioned with the positioner
-       object. The size is in surface-local coordinates and corresponds to the
-       window geometry. See xdg_surface.set_window_geometry.
-
-       If a zero or negative size is set the invalid_input error is raised.
-      </description>
-      <arg name="width" type="int" summary="width of positioned rectangle"/>
-      <arg name="height" type="int" summary="height of positioned rectangle"/>
-    </request>
-
-    <request name="set_anchor_rect">
-      <description summary="set the anchor rectangle within the parent surface">
-       Specify the anchor rectangle within the parent surface that the child
-       surface will be placed relative to. The rectangle is relative to the
-       window geometry as defined by xdg_surface.set_window_geometry of the
-       parent surface.
-
-       When the xdg_positioner object is used to position a child surface, the
-       anchor rectangle may not extend outside the window geometry of the
-       positioned child's parent surface.
-
-       If a negative size is set the invalid_input error is raised.
-      </description>
-      <arg name="x" type="int" summary="x position of anchor rectangle"/>
-      <arg name="y" type="int" summary="y position of anchor rectangle"/>
-      <arg name="width" type="int" summary="width of anchor rectangle"/>
-      <arg name="height" type="int" summary="height of anchor rectangle"/>
-    </request>
-
-    <enum name="anchor">
-      <entry name="none" value="0"/>
-      <entry name="top" value="1"/>
-      <entry name="bottom" value="2"/>
-      <entry name="left" value="3"/>
-      <entry name="right" value="4"/>
-      <entry name="top_left" value="5"/>
-      <entry name="bottom_left" value="6"/>
-      <entry name="top_right" value="7"/>
-      <entry name="bottom_right" value="8"/>
-    </enum>
-
-    <request name="set_anchor">
-      <description summary="set anchor rectangle anchor">
-       Defines the anchor point for the anchor rectangle. The specified anchor
-       is used derive an anchor point that the child surface will be
-       positioned relative to. If a corner anchor is set (e.g. 'top_left' or
-       'bottom_right'), the anchor point will be at the specified corner;
-       otherwise, the derived anchor point will be centered on the specified
-       edge, or in the center of the anchor rectangle if no edge is specified.
-      </description>
-      <arg name="anchor" type="uint" enum="anchor"
-          summary="anchor"/>
-    </request>
-
-    <enum name="gravity">
-      <entry name="none" value="0"/>
-      <entry name="top" value="1"/>
-      <entry name="bottom" value="2"/>
-      <entry name="left" value="3"/>
-      <entry name="right" value="4"/>
-      <entry name="top_left" value="5"/>
-      <entry name="bottom_left" value="6"/>
-      <entry name="top_right" value="7"/>
-      <entry name="bottom_right" value="8"/>
-    </enum>
-
-    <request name="set_gravity">
-      <description summary="set child surface gravity">
-       Defines in what direction a surface should be positioned, relative to
-       the anchor point of the parent surface. If a corner gravity is
-       specified (e.g. 'bottom_right' or 'top_left'), then the child surface
-       will be placed towards the specified gravity; otherwise, the child
-       surface will be centered over the anchor point on any axis that had no
-       gravity specified. If the gravity is not in the ‘gravity’ enum, an
-       invalid_input error is raised.
-      </description>
-      <arg name="gravity" type="uint" enum="gravity"
-          summary="gravity direction"/>
-    </request>
-
-    <enum name="constraint_adjustment" bitfield="true">
-      <description summary="constraint adjustments">
-       The constraint adjustment value define ways the compositor will adjust
-       the position of the surface, if the unadjusted position would result
-       in the surface being partly constrained.
-
-       Whether a surface is considered 'constrained' is left to the compositor
-       to determine. For example, the surface may be partly outside the
-       compositor's defined 'work area', thus necessitating the child surface's
-       position be adjusted until it is entirely inside the work area.
-
-       The adjustments can be combined, according to a defined precedence: 1)
-       Flip, 2) Slide, 3) Resize.
-      </description>
-      <entry name="none" value="0">
-       <description summary="don't move the child surface when constrained">
-         Don't alter the surface position even if it is constrained on some
-         axis, for example partially outside the edge of an output.
-       </description>
-      </entry>
-      <entry name="slide_x" value="1">
-       <description summary="move along the x axis until unconstrained">
-         Slide the surface along the x axis until it is no longer constrained.
-
-         First try to slide towards the direction of the gravity on the x axis
-         until either the edge in the opposite direction of the gravity is
-         unconstrained or the edge in the direction of the gravity is
-         constrained.
-
-         Then try to slide towards the opposite direction of the gravity on the
-         x axis until either the edge in the direction of the gravity is
-         unconstrained or the edge in the opposite direction of the gravity is
-         constrained.
-       </description>
-      </entry>
-      <entry name="slide_y" value="2">
-       <description summary="move along the y axis until unconstrained">
-         Slide the surface along the y axis until it is no longer constrained.
-
-         First try to slide towards the direction of the gravity on the y axis
-         until either the edge in the opposite direction of the gravity is
-         unconstrained or the edge in the direction of the gravity is
-         constrained.
-
-         Then try to slide towards the opposite direction of the gravity on the
-         y axis until either the edge in the direction of the gravity is
-         unconstrained or the edge in the opposite direction of the gravity is
-         constrained.
-       </description>
-      </entry>
-      <entry name="flip_x" value="4">
-       <description summary="invert the anchor and gravity on the x axis">
-         Invert the anchor and gravity on the x axis if the surface is
-         constrained on the x axis. For example, if the left edge of the
-         surface is constrained, the gravity is 'left' and the anchor is
-         'left', change the gravity to 'right' and the anchor to 'right'.
-
-         If the adjusted position also ends up being constrained, the resulting
-         position of the flip_x adjustment will be the one before the
-         adjustment.
-       </description>
-      </entry>
-      <entry name="flip_y" value="8">
-       <description summary="invert the anchor and gravity on the y axis">
-         Invert the anchor and gravity on the y axis if the surface is
-         constrained on the y axis. For example, if the bottom edge of the
-         surface is constrained, the gravity is 'bottom' and the anchor is
-         'bottom', change the gravity to 'top' and the anchor to 'top'.
-
-         The adjusted position is calculated given the original anchor
-         rectangle and offset, but with the new flipped anchor and gravity
-         values.
-
-         If the adjusted position also ends up being constrained, the resulting
-         position of the flip_y adjustment will be the one before the
-         adjustment.
-       </description>
-      </entry>
-      <entry name="resize_x" value="16">
-       <description summary="horizontally resize the surface">
-         Resize the surface horizontally so that it is completely
-         unconstrained.
-       </description>
-      </entry>
-      <entry name="resize_y" value="32">
-       <description summary="vertically resize the surface">
-         Resize the surface vertically so that it is completely unconstrained.
-       </description>
-      </entry>
-    </enum>
-
-    <request name="set_constraint_adjustment">
-      <description summary="set the adjustment to be done when constrained">
-       Specify how the window should be positioned if the originally intended
-       position caused the surface to be constrained, meaning at least
-       partially outside positioning boundaries set by the compositor. The
-       adjustment is set by constructing a bitmask describing the adjustment to
-       be made when the surface is constrained on that axis.
-
-       If no bit for one axis is set, the compositor will assume that the child
-       surface should not change its position on that axis when constrained.
-
-       If more than one bit for one axis is set, the order of how adjustments
-       are applied is specified in the corresponding adjustment descriptions.
-
-       The default adjustment is none.
-      </description>
-      <arg name="constraint_adjustment" type="uint" enum="constraint_adjustment"
-          summary="bit mask of constraint adjustments"/>
-    </request>
-
-    <request name="set_offset">
-      <description summary="set surface position offset">
-       Specify the surface position offset relative to the position of the
-       anchor on the anchor rectangle and the anchor on the surface. For
-       example if the anchor of the anchor rectangle is at (x, y), the surface
-       has the gravity bottom|right, and the offset is (ox, oy), the calculated
-       surface position will be (x + ox, y + oy). The offset position of the
-       surface is the one used for constraint testing. See
-       set_constraint_adjustment.
-
-       An example use case is placing a popup menu on top of a user interface
-       element, while aligning the user interface element of the parent surface
-       with some user interface element placed somewhere in the popup surface.
-      </description>
-      <arg name="x" type="int" summary="surface position x offset"/>
-      <arg name="y" type="int" summary="surface position y offset"/>
-    </request>
-
-    <!-- Version 3 additions -->
-
-    <request name="set_reactive" since="3">
-      <description summary="continuously reconstrain the surface">
-       When set reactive, the surface is reconstrained if the conditions used
-       for constraining changed, e.g. the parent window moved.
-
-       If the conditions changed and the popup was reconstrained, an
-       xdg_popup.configure event is sent with updated geometry, followed by an
-       xdg_surface.configure event.
-      </description>
-    </request>
-
-    <request name="set_parent_size" since="3">
-      <description summary="">
-       Set the parent window geometry the compositor should use when
-       positioning the popup. The compositor may use this information to
-       determine the future state the popup should be constrained using. If
-       this doesn't match the dimension of the parent the popup is eventually
-       positioned against, the behavior is undefined.
-
-       The arguments are given in the surface-local coordinate space.
-      </description>
-      <arg name="parent_width" type="int"
-          summary="future window geometry width of parent"/>
-      <arg name="parent_height" type="int"
-          summary="future window geometry height of parent"/>
-    </request>
-
-    <request name="set_parent_configure" since="3">
-      <description summary="set parent configure this is a response to">
-       Set the serial of an xdg_surface.configure event this positioner will be
-       used in response to. The compositor may use this information together
-       with set_parent_size to determine what future state the popup should be
-       constrained using.
-      </description>
-      <arg name="serial" type="uint"
-          summary="serial of parent configure event"/>
-    </request>
-  </interface>
-
-  <interface name="xdg_surface" version="7">
-    <description summary="desktop user interface surface base interface">
-      An interface that may be implemented by a wl_surface, for
-      implementations that provide a desktop-style user interface.
-
-      It provides a base set of functionality required to construct user
-      interface elements requiring management by the compositor, such as
-      toplevel windows, menus, etc. The types of functionality are split into
-      xdg_surface roles.
-
-      Creating an xdg_surface does not set the role for a wl_surface. In order
-      to map an xdg_surface, the client must create a role-specific object
-      using, e.g., get_toplevel, get_popup. The wl_surface for any given
-      xdg_surface can have at most one role, and may not be assigned any role
-      not based on xdg_surface.
-
-      A role must be assigned before any other requests are made to the
-      xdg_surface object.
-
-      The client must call wl_surface.commit on the corresponding wl_surface
-      for the xdg_surface state to take effect.
-
-      Creating an xdg_surface from a wl_surface which has a buffer attached or
-      committed is a client error, and any attempts by a client to attach or
-      manipulate a buffer prior to the first xdg_surface.configure call must
-      also be treated as errors.
-
-      After creating a role-specific object and setting it up (e.g. by sending
-      the title, app ID, size constraints, parent, etc), the client must
-      perform an initial commit without any buffer attached. The compositor
-      will reply with initial wl_surface state such as
-      wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
-      event. The client must acknowledge it and is then allowed to attach a
-      buffer to map the surface.
-
-      Mapping an xdg_surface-based role surface is defined as making it
-      possible for the surface to be shown by the compositor. Note that
-      a mapped surface is not guaranteed to be visible once it is mapped.
-
-      For an xdg_surface to be mapped by the compositor, the following
-      conditions must be met:
-      (1) the client has assigned an xdg_surface-based role to the surface
-      (2) the client has set and committed the xdg_surface state and the
-         role-dependent state to the surface
-      (3) the client has committed a buffer to the surface
-
-      A newly-unmapped surface is considered to have met condition (1) out
-      of the 3 required conditions for mapping a surface if its role surface
-      has not been destroyed, i.e. the client must perform the initial commit
-      again before attaching a buffer.
-    </description>
-
-    <enum name="error">
-      <entry name="not_constructed" value="1"
-            summary="Surface was not fully constructed"/>
-      <entry name="already_constructed" value="2"
-            summary="Surface was already constructed"/>
-      <entry name="unconfigured_buffer" value="3"
-            summary="Attaching a buffer to an unconfigured surface"/>
-      <entry name="invalid_serial" value="4"
-            summary="Invalid serial number when acking a configure event"/>
-      <entry name="invalid_size" value="5"
-            summary="Width or height was zero or negative"/>
-      <entry name="defunct_role_object" value="6"
-            summary="Surface was destroyed before its role object"/>
-    </enum>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the xdg_surface">
-       Destroy the xdg_surface object. An xdg_surface must only be destroyed
-       after its role object has been destroyed, otherwise
-       a defunct_role_object error is raised.
-      </description>
-    </request>
-
-    <request name="get_toplevel">
-      <description summary="assign the xdg_toplevel surface role">
-       This creates an xdg_toplevel object for the given xdg_surface and gives
-       the associated wl_surface the xdg_toplevel role.
-
-       See the documentation of xdg_toplevel for more details about what an
-       xdg_toplevel is and how it is used.
-      </description>
-      <arg name="id" type="new_id" interface="xdg_toplevel"/>
-    </request>
-
-    <request name="get_popup">
-      <description summary="assign the xdg_popup surface role">
-       This creates an xdg_popup object for the given xdg_surface and gives
-       the associated wl_surface the xdg_popup role.
-
-       If null is passed as a parent, a parent surface must be specified using
-       some other protocol, before committing the initial state.
-
-       See the documentation of xdg_popup for more details about what an
-       xdg_popup is and how it is used.
-      </description>
-      <arg name="id" type="new_id" interface="xdg_popup"/>
-      <arg name="parent" type="object" interface="xdg_surface" allow-null="true"/>
-      <arg name="positioner" type="object" interface="xdg_positioner"/>
-    </request>
-
-    <request name="set_window_geometry">
-      <description summary="set the new window geometry">
-       The window geometry of a surface is its "visible bounds" from the
-       user's perspective. Client-side decorations often have invisible
-       portions like drop-shadows which should be ignored for the
-       purposes of aligning, placing and constraining windows.
-
-       The window geometry is double-buffered state, see wl_surface.commit.
-
-       When maintaining a position, the compositor should treat the (x, y)
-       coordinate of the window geometry as the top left corner of the window.
-       A client changing the (x, y) window geometry coordinate should in
-       general not alter the position of the window.
-
-       Once the window geometry of the surface is set, it is not possible to
-       unset it, and it will remain the same until set_window_geometry is
-       called again, even if a new subsurface or buffer is attached.
-
-       If never set, the value is the full bounds of the surface,
-       including any subsurfaces. This updates dynamically on every
-       commit. This unset is meant for extremely simple clients.
-
-       The arguments are given in the surface-local coordinate space of
-       the wl_surface associated with this xdg_surface, and may extend outside
-       of the wl_surface itself to mark parts of the subsurface tree as part of
-       the window geometry.
-
-       When applied, the effective window geometry will be the set window
-       geometry clamped to the bounding rectangle of the combined
-       geometry of the surface of the xdg_surface and the associated
-       subsurfaces.
-
-       The effective geometry will not be recalculated unless a new call to
-       set_window_geometry is done and the new pending surface state is
-       subsequently applied.
-
-       The width and height of the effective window geometry must be
-       greater than zero. Setting an invalid size will raise an
-       invalid_size error.
-      </description>
-      <arg name="x" type="int"/>
-      <arg name="y" type="int"/>
-      <arg name="width" type="int"/>
-      <arg name="height" type="int"/>
-    </request>
-
-    <request name="ack_configure">
-      <description summary="ack a configure event">
-       When a configure event is received, if a client commits the
-       surface in response to the configure event, then the client
-       must make an ack_configure request sometime before the commit
-       request, passing along the serial of the configure event.
-
-       For instance, for toplevel surfaces the compositor might use this
-       information to move a surface to the top left only when the client has
-       drawn itself for the maximized or fullscreen state.
-
-       If the client receives multiple configure events before it
-       can respond to one, it only has to ack the last configure event.
-       Acking a configure event that was never sent raises an invalid_serial
-       error.
-
-       A client is not required to commit immediately after sending
-       an ack_configure request - it may even ack_configure several times
-       before its next surface commit.
-
-       A client may send multiple ack_configure requests before committing, but
-       only the last request sent before a commit indicates which configure
-       event the client really is responding to.
-
-       Sending an ack_configure request consumes the serial number sent with
-       the request, as well as serial numbers sent by all configure events
-       sent on this xdg_surface prior to the configure event referenced by
-       the committed serial.
-
-       It is an error to issue multiple ack_configure requests referencing a
-       serial from the same configure event, or to issue an ack_configure
-       request referencing a serial from a configure event issued before the
-       event identified by the last ack_configure request for the same
-       xdg_surface. Doing so will raise an invalid_serial error.
-      </description>
-      <arg name="serial" type="uint" summary="the serial from the configure event"/>
-    </request>
-
-    <event name="configure">
-      <description summary="suggest a surface change">
-       The configure event marks the end of a configure sequence. A configure
-       sequence is a set of one or more events configuring the state of the
-       xdg_surface, including the final xdg_surface.configure event.
-
-       Where applicable, xdg_surface surface roles will during a configure
-       sequence extend this event as a latched state sent as events before the
-       xdg_surface.configure event. Such events should be considered to make up
-       a set of atomically applied configuration states, where the
-       xdg_surface.configure commits the accumulated state.
-
-       Clients should arrange their surface for the new states, and then send
-       an ack_configure request with the serial sent in this configure event at
-       some point before committing the new surface.
-
-       If the client receives multiple configure events before it can respond
-       to one, it is free to discard all but the last event it received.
-      </description>
-      <arg name="serial" type="uint" summary="serial of the configure event"/>
-    </event>
-
-  </interface>
-
-  <interface name="xdg_toplevel" version="7">
-    <description summary="toplevel surface">
-      This interface defines an xdg_surface role which allows a surface to,
-      among other things, set window-like properties such as maximize,
-      fullscreen, and minimize, set application-specific metadata like title and
-      id, and well as trigger user interactive operations such as interactive
-      resize and move.
-
-      A xdg_toplevel by default is responsible for providing the full intended
-      visual representation of the toplevel, which depending on the window
-      state, may mean things like a title bar, window controls and drop shadow.
-
-      Unmapping an xdg_toplevel means that the surface cannot be shown
-      by the compositor until it is explicitly mapped again.
-      All active operations (e.g., move, resize) are canceled and all
-      attributes (e.g. title, state, stacking, ...) are discarded for
-      an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
-      the state it had right after xdg_surface.get_toplevel. The client
-      can re-map the toplevel by performing a commit without any buffer
-      attached, waiting for a configure event and handling it as usual (see
-      xdg_surface description).
-
-      Attaching a null buffer to a toplevel unmaps the surface.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the xdg_toplevel">
-       This request destroys the role surface and unmaps the surface;
-       see "Unmapping" behavior in interface section for details.
-      </description>
-    </request>
-
-    <enum name="error">
-      <entry name="invalid_resize_edge" value="0" summary="provided value is
-        not a valid variant of the resize_edge enum"/>
-      <entry name="invalid_parent" value="1"
-        summary="invalid parent toplevel"/>
-      <entry name="invalid_size" value="2"
-       summary="client provided an invalid min or max size"/>
-    </enum>
-
-    <request name="set_parent">
-      <description summary="set the parent of this surface">
-       Set the "parent" of this surface. This surface should be stacked
-       above the parent surface and all other ancestor surfaces.
-
-       Parent surfaces should be set on dialogs, toolboxes, or other
-       "auxiliary" surfaces, so that the parent is raised when the dialog
-       is raised.
-
-       Setting a null parent for a child surface unsets its parent. Setting
-       a null parent for a surface which currently has no parent is a no-op.
-
-       Only mapped surfaces can have child surfaces. Setting a parent which
-       is not mapped is equivalent to setting a null parent. If a surface
-       becomes unmapped, its children's parent is set to the parent of
-       the now-unmapped surface. If the now-unmapped surface has no parent,
-       its children's parent is unset. If the now-unmapped surface becomes
-       mapped again, its parent-child relationship is not restored.
-
-       The parent toplevel must not be one of the child toplevel's
-       descendants, and the parent must be different from the child toplevel,
-       otherwise the invalid_parent protocol error is raised.
-      </description>
-      <arg name="parent" type="object" interface="xdg_toplevel" allow-null="true"/>
-    </request>
-
-    <request name="set_title">
-      <description summary="set surface title">
-       Set a short title for the surface.
-
-       This string may be used to identify the surface in a task bar,
-       window list, or other user interface elements provided by the
-       compositor.
-
-       The string must be encoded in UTF-8.
-      </description>
-      <arg name="title" type="string"/>
-    </request>
-
-    <request name="set_app_id">
-      <description summary="set application ID">
-       Set an application identifier for the surface.
-
-       The app ID identifies the general class of applications to which
-       the surface belongs. The compositor can use this to group multiple
-       surfaces together, or to determine how to launch a new application.
-
-       For D-Bus activatable applications, the app ID is used as the D-Bus
-       service name.
-
-       The compositor shell will try to group application surfaces together
-       by their app ID. As a best practice, it is suggested to select app
-       ID's that match the basename of the application's .desktop file.
-       For example, "org.freedesktop.FooViewer" where the .desktop file is
-       "org.freedesktop.FooViewer.desktop".
-
-       Like other properties, a set_app_id request can be sent after the
-       xdg_toplevel has been mapped to update the property.
-
-       See the desktop-entry specification [0] for more details on
-       application identifiers and how they relate to well-known D-Bus
-       names and .desktop files.
-
-       [0] https://standards.freedesktop.org/desktop-entry-spec/
-      </description>
-      <arg name="app_id" type="string"/>
-    </request>
-
-    <request name="show_window_menu">
-      <description summary="show the window menu">
-       Clients implementing client-side decorations might want to show
-       a context menu when right-clicking on the decorations, giving the
-       user a menu that they can use to maximize or minimize the window.
-
-       This request asks the compositor to pop up such a window menu at
-       the given position, relative to the local surface coordinates of
-       the parent surface. There are no guarantees as to what menu items
-       the window menu contains, or even if a window menu will be drawn
-       at all.
-
-       This request must be used in response to some sort of user action
-       like a button press, key press, or touch down event.
-      </description>
-      <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
-      <arg name="serial" type="uint" summary="the serial of the user event"/>
-      <arg name="x" type="int" summary="the x position to pop up the window menu at"/>
-      <arg name="y" type="int" summary="the y position to pop up the window menu at"/>
-    </request>
-
-    <request name="move">
-      <description summary="start an interactive move">
-       Start an interactive, user-driven move of the surface.
-
-       This request must be used in response to some sort of user action
-       like a button press, key press, or touch down event. The passed
-       serial is used to determine the type of interactive move (touch,
-       pointer, etc).
-
-       The server may ignore move requests depending on the state of
-       the surface (e.g. fullscreen or maximized), or if the passed serial
-       is no longer valid.
-
-       If triggered, the surface will lose the focus of the device
-       (wl_pointer, wl_touch, etc) used for the move. It is up to the
-       compositor to visually indicate that the move is taking place, such as
-       updating a pointer cursor, during the move. There is no guarantee
-       that the device focus will return when the move is completed.
-      </description>
-      <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
-      <arg name="serial" type="uint" summary="the serial of the user event"/>
-    </request>
-
-    <enum name="resize_edge">
-      <description summary="edge values for resizing">
-       These values are used to indicate which edge of a surface
-       is being dragged in a resize operation.
-      </description>
-      <entry name="none" value="0"/>
-      <entry name="top" value="1"/>
-      <entry name="bottom" value="2"/>
-      <entry name="left" value="4"/>
-      <entry name="top_left" value="5"/>
-      <entry name="bottom_left" value="6"/>
-      <entry name="right" value="8"/>
-      <entry name="top_right" value="9"/>
-      <entry name="bottom_right" value="10"/>
-    </enum>
-
-    <request name="resize">
-      <description summary="start an interactive resize">
-       Start a user-driven, interactive resize of the surface.
-
-       This request must be used in response to some sort of user action
-       like a button press, key press, or touch down event. The passed
-       serial is used to determine the type of interactive resize (touch,
-       pointer, etc).
-
-       The server may ignore resize requests depending on the state of
-       the surface (e.g. fullscreen or maximized).
-
-       If triggered, the client will receive configure events with the
-       "resize" state enum value and the expected sizes. See the "resize"
-       enum value for more details about what is required. The client
-       must also acknowledge configure events using "ack_configure". After
-       the resize is completed, the client will receive another "configure"
-       event without the resize state.
-
-       If triggered, the surface also will lose the focus of the device
-       (wl_pointer, wl_touch, etc) used for the resize. It is up to the
-       compositor to visually indicate that the resize is taking place,
-       such as updating a pointer cursor, during the resize. There is no
-       guarantee that the device focus will return when the resize is
-       completed.
-
-       The edges parameter specifies how the surface should be resized, and
-       is one of the values of the resize_edge enum. Values not matching
-       a variant of the enum will cause the invalid_resize_edge protocol error.
-       The compositor may use this information to update the surface position
-       for example when dragging the top left corner. The compositor may also
-       use this information to adapt its behavior, e.g. choose an appropriate
-       cursor image.
-      </description>
-      <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
-      <arg name="serial" type="uint" summary="the serial of the user event"/>
-      <arg name="edges" type="uint" enum="resize_edge" summary="which edge or corner is being dragged"/>
-    </request>
-
-    <enum name="state">
-      <description summary="types of state on the surface">
-       The different state values used on the surface. This is designed for
-       state values like maximized, fullscreen. It is paired with the
-       configure event to ensure that both the client and the compositor
-       setting the state can be synchronized.
-
-       States set in this way are double-buffered, see wl_surface.commit.
-      </description>
-      <entry name="maximized" value="1" summary="the surface is maximized">
-       <description summary="the surface is maximized">
-         The surface is maximized. The window geometry specified in the configure
-         event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state
-         error is raised.
-
-         The client should draw without shadow or other
-         decoration outside of the window geometry.
-       </description>
-      </entry>
-      <entry name="fullscreen" value="2" summary="the surface is fullscreen">
-       <description summary="the surface is fullscreen">
-         The surface is fullscreen. The window geometry specified in the
-         configure event is a maximum; the client cannot resize beyond it. For
-         a surface to cover the whole fullscreened area, the geometry
-         dimensions must be obeyed by the client. For more details, see
-         xdg_toplevel.set_fullscreen.
-       </description>
-      </entry>
-      <entry name="resizing" value="3" summary="the surface is being resized">
-       <description summary="the surface is being resized">
-         The surface is being resized. The window geometry specified in the
-         configure event is a maximum; the client cannot resize beyond it.
-         Clients that have aspect ratio or cell sizing configuration can use
-         a smaller size, however.
-       </description>
-      </entry>
-      <entry name="activated" value="4" summary="the surface is now activated">
-       <description summary="the surface is now activated">
-         Client window decorations should be painted as if the window is
-         active. Do not assume this means that the window actually has
-         keyboard or pointer focus.
-       </description>
-      </entry>
-      <entry name="tiled_left" value="5" since="2">
-       <description summary="the surface’s left edge is tiled">
-         The window is currently in a tiled layout and the left edge is
-         considered to be adjacent to another part of the tiling grid.
-
-         The client should draw without shadow or other decoration outside of
-         the window geometry on the left edge.
-       </description>
-      </entry>
-      <entry name="tiled_right" value="6" since="2">
-       <description summary="the surface’s right edge is tiled">
-         The window is currently in a tiled layout and the right edge is
-         considered to be adjacent to another part of the tiling grid.
-
-         The client should draw without shadow or other decoration outside of
-         the window geometry on the right edge.
-       </description>
-      </entry>
-      <entry name="tiled_top" value="7" since="2">
-       <description summary="the surface’s top edge is tiled">
-         The window is currently in a tiled layout and the top edge is
-         considered to be adjacent to another part of the tiling grid.
-
-         The client should draw without shadow or other decoration outside of
-         the window geometry on the top edge.
-       </description>
-      </entry>
-      <entry name="tiled_bottom" value="8" since="2">
-       <description summary="the surface’s bottom edge is tiled">
-         The window is currently in a tiled layout and the bottom edge is
-         considered to be adjacent to another part of the tiling grid.
-
-         The client should draw without shadow or other decoration outside of
-         the window geometry on the bottom edge.
-       </description>
-      </entry>
-      <entry name="suspended" value="9" since="6">
-        <description summary="surface repaint is suspended">
-         The surface is currently not ordinarily being repainted; for
-         example because its content is occluded by another window, or its
-         outputs are switched off due to screen locking.
-       </description>
-      </entry>
-      <entry name="constrained_left" value="10" since="7">
-       <description summary="the surface’s left edge is constrained">
-          The left edge of the window is currently constrained, meaning it
-          shouldn't attempt to resize from that edge. It can for example mean
-          it's tiled next to a monitor edge on the constrained side of the
-          window.
-       </description>
-      </entry>
-      <entry name="constrained_right" value="11" since="7">
-       <description summary="the surface’s right edge is constrained">
-          The right edge of the window is currently constrained, meaning it
-          shouldn't attempt to resize from that edge. It can for example mean
-          it's tiled next to a monitor edge on the constrained side of the
-          window.
-       </description>
-      </entry>
-      <entry name="constrained_top" value="12" since="7">
-       <description summary="the surface’s top edge is constrained">
-          The top edge of the window is currently constrained, meaning it
-          shouldn't attempt to resize from that edge. It can for example mean
-          it's tiled next to a monitor edge on the constrained side of the
-          window.
-       </description>
-      </entry>
-      <entry name="constrained_bottom" value="13" since="7">
-       <description summary="the surface’s bottom edge is tiled">
-          The bottom edge of the window is currently constrained, meaning it
-          shouldn't attempt to resize from that edge. It can for example mean
-          it's tiled next to a monitor edge on the constrained side of the
-          window.
-       </description>
-      </entry>
-    </enum>
-
-    <request name="set_max_size">
-      <description summary="set the maximum size">
-       Set a maximum size for the window.
-
-       The client can specify a maximum size so that the compositor does
-       not try to configure the window beyond this size.
-
-       The width and height arguments are in window geometry coordinates.
-       See xdg_surface.set_window_geometry.
-
-       Values set in this way are double-buffered, see wl_surface.commit.
-
-       The compositor can use this information to allow or disallow
-       different states like maximize or fullscreen and draw accurate
-       animations.
-
-       Similarly, a tiling window manager may use this information to
-       place and resize client windows in a more effective way.
-
-       The client should not rely on the compositor to obey the maximum
-       size. The compositor may decide to ignore the values set by the
-       client and request a larger size.
-
-       If never set, or a value of zero in the request, means that the
-       client has no expected maximum size in the given dimension.
-       As a result, a client wishing to reset the maximum size
-       to an unspecified state can use zero for width and height in the
-       request.
-
-       Requesting a maximum size to be smaller than the minimum size of
-       a surface is illegal and will result in an invalid_size error.
-
-       The width and height must be greater than or equal to zero. Using
-       strictly negative values for width or height will result in a
-       invalid_size error.
-      </description>
-      <arg name="width" type="int"/>
-      <arg name="height" type="int"/>
-    </request>
-
-    <request name="set_min_size">
-      <description summary="set the minimum size">
-       Set a minimum size for the window.
-
-       The client can specify a minimum size so that the compositor does
-       not try to configure the window below this size.
-
-       The width and height arguments are in window geometry coordinates.
-       See xdg_surface.set_window_geometry.
-
-       Values set in this way are double-buffered, see wl_surface.commit.
-
-       The compositor can use this information to allow or disallow
-       different states like maximize or fullscreen and draw accurate
-       animations.
-
-       Similarly, a tiling window manager may use this information to
-       place and resize client windows in a more effective way.
-
-       The client should not rely on the compositor to obey the minimum
-       size. The compositor may decide to ignore the values set by the
-       client and request a smaller size.
-
-       If never set, or a value of zero in the request, means that the
-       client has no expected minimum size in the given dimension.
-       As a result, a client wishing to reset the minimum size
-       to an unspecified state can use zero for width and height in the
-       request.
-
-       Requesting a minimum size to be larger than the maximum size of
-       a surface is illegal and will result in an invalid_size error.
-
-       The width and height must be greater than or equal to zero. Using
-       strictly negative values for width and height will result in a
-       invalid_size error.
-      </description>
-      <arg name="width" type="int"/>
-      <arg name="height" type="int"/>
-    </request>
-
-    <request name="set_maximized">
-      <description summary="maximize the window">
-       Maximize the surface.
-
-       After requesting that the surface should be maximized, the compositor
-       will respond by emitting a configure event. Whether this configure
-       actually sets the window maximized is subject to compositor policies.
-       The client must then update its content, drawing in the configured
-       state. The client must also acknowledge the configure when committing
-       the new content (see ack_configure).
-
-       It is up to the compositor to decide how and where to maximize the
-       surface, for example which output and what region of the screen should
-       be used.
-
-       If the surface was already maximized, the compositor will still emit
-       a configure event with the "maximized" state.
-
-       If the surface is in a fullscreen state, this request has no direct
-       effect. It may alter the state the surface is returned to when
-       unmaximized unless overridden by the compositor.
-      </description>
-    </request>
-
-    <request name="unset_maximized">
-      <description summary="unmaximize the window">
-       Unmaximize the surface.
-
-       After requesting that the surface should be unmaximized, the compositor
-       will respond by emitting a configure event. Whether this actually
-       un-maximizes the window is subject to compositor policies.
-       If available and applicable, the compositor will include the window
-       geometry dimensions the window had prior to being maximized in the
-       configure event. The client must then update its content, drawing it in
-       the configured state. The client must also acknowledge the configure
-       when committing the new content (see ack_configure).
-
-       It is up to the compositor to position the surface after it was
-       unmaximized; usually the position the surface had before maximizing, if
-       applicable.
-
-       If the surface was already not maximized, the compositor will still
-       emit a configure event without the "maximized" state.
-
-       If the surface is in a fullscreen state, this request has no direct
-       effect. It may alter the state the surface is returned to when
-       unmaximized unless overridden by the compositor.
-      </description>
-    </request>
-
-    <request name="set_fullscreen">
-      <description summary="set the window as fullscreen on an output">
-       Make the surface fullscreen.
-
-       After requesting that the surface should be fullscreened, the
-       compositor will respond by emitting a configure event. Whether the
-       client is actually put into a fullscreen state is subject to compositor
-       policies. The client must also acknowledge the configure when
-       committing the new content (see ack_configure).
-
-       The output passed by the request indicates the client's preference as
-       to which display it should be set fullscreen on. If this value is NULL,
-       it's up to the compositor to choose which display will be used to map
-       this surface.
-
-       If the surface doesn't cover the whole output, the compositor will
-       position the surface in the center of the output and compensate with
-       with border fill covering the rest of the output. The content of the
-       border fill is undefined, but should be assumed to be in some way that
-       attempts to blend into the surrounding area (e.g. solid black).
-
-       If the fullscreened surface is not opaque, the compositor must make
-       sure that other screen content not part of the same surface tree (made
-       up of subsurfaces, popups or similarly coupled surfaces) are not
-       visible below the fullscreened surface.
-      </description>
-      <arg name="output" type="object" interface="wl_output" allow-null="true"/>
-    </request>
-
-    <request name="unset_fullscreen">
-      <description summary="unset the window as fullscreen">
-       Make the surface no longer fullscreen.
-
-       After requesting that the surface should be unfullscreened, the
-       compositor will respond by emitting a configure event.
-       Whether this actually removes the fullscreen state of the client is
-       subject to compositor policies.
-
-       Making a surface unfullscreen sets states for the surface based on the following:
-       * the state(s) it may have had before becoming fullscreen
-       * any state(s) decided by the compositor
-       * any state(s) requested by the client while the surface was fullscreen
-
-       The compositor may include the previous window geometry dimensions in
-       the configure event, if applicable.
-
-       The client must also acknowledge the configure when committing the new
-       content (see ack_configure).
-      </description>
-    </request>
-
-    <request name="set_minimized">
-      <description summary="set the window as minimized">
-       Request that the compositor minimize your surface. There is no
-       way to know if the surface is currently minimized, nor is there
-       any way to unset minimization on this surface.
-
-       If you are looking to throttle redrawing when minimized, please
-       instead use the wl_surface.frame event for this, as this will
-       also work with live previews on windows in Alt-Tab, Expose or
-       similar compositor features.
-      </description>
-    </request>
-
-    <event name="configure">
-      <description summary="suggest a surface change">
-       This configure event asks the client to resize its toplevel surface or
-       to change its state. The configured state should not be applied
-       immediately. See xdg_surface.configure for details.
-
-       The width and height arguments specify a hint to the window
-       about how its surface should be resized in window geometry
-       coordinates. See set_window_geometry.
-
-       If the width or height arguments are zero, it means the client
-       should decide its own window dimension. This may happen when the
-       compositor needs to configure the state of the surface but doesn't
-       have any information about any previous or expected dimension.
-
-       The states listed in the event specify how the width/height
-       arguments should be interpreted, and possibly how it should be
-       drawn.
-
-       Clients must send an ack_configure in response to this event. See
-       xdg_surface.configure and xdg_surface.ack_configure for details.
-      </description>
-      <arg name="width" type="int"/>
-      <arg name="height" type="int"/>
-      <arg name="states" type="array"/>
-    </event>
-
-    <event name="close">
-      <description summary="surface wants to be closed">
-       The close event is sent by the compositor when the user
-       wants the surface to be closed. This should be equivalent to
-       the user clicking the close button in client-side decorations,
-       if your application has any.
-
-       This is only a request that the user intends to close the
-       window. The client may choose to ignore this request, or show
-       a dialog to ask the user to save their data, etc.
-      </description>
-    </event>
-
-    <!-- Version 4 additions -->
-
-    <event name="configure_bounds" since="4">
-      <description summary="recommended window geometry bounds">
-       The configure_bounds event may be sent prior to a xdg_toplevel.configure
-       event to communicate the bounds a window geometry size is recommended
-       to constrain to.
-
-       The passed width and height are in surface coordinate space. If width
-       and height are 0, it means bounds is unknown and equivalent to as if no
-       configure_bounds event was ever sent for this surface.
-
-       The bounds can for example correspond to the size of a monitor excluding
-       any panels or other shell components, so that a surface isn't created in
-       a way that it cannot fit.
-
-       The bounds may change at any point, and in such a case, a new
-       xdg_toplevel.configure_bounds will be sent, followed by
-       xdg_toplevel.configure and xdg_surface.configure.
-      </description>
-      <arg name="width" type="int"/>
-      <arg name="height" type="int"/>
-    </event>
-
-    <!-- Version 5 additions -->
-
-    <enum name="wm_capabilities" since="5">
-      <entry name="window_menu" value="1" summary="show_window_menu is available"/>
-      <entry name="maximize" value="2" summary="set_maximized and unset_maximized are available"/>
-      <entry name="fullscreen" value="3" summary="set_fullscreen and unset_fullscreen are available"/>
-      <entry name="minimize" value="4" summary="set_minimized is available"/>
-    </enum>
-
-    <event name="wm_capabilities" since="5">
-      <description summary="compositor capabilities">
-       This event advertises the capabilities supported by the compositor. If
-       a capability isn't supported, clients should hide or disable the UI
-       elements that expose this functionality. For instance, if the
-       compositor doesn't advertise support for minimized toplevels, a button
-       triggering the set_minimized request should not be displayed.
-
-       The compositor will ignore requests it doesn't support. For instance,
-       a compositor which doesn't advertise support for minimized will ignore
-       set_minimized requests.
-
-       Compositors must send this event once before the first
-       xdg_surface.configure event. When the capabilities change, compositors
-       must send this event again and then send an xdg_surface.configure
-       event.
-
-       The configured state should not be applied immediately. See
-       xdg_surface.configure for details.
-
-       The capabilities are sent as an array of 32-bit unsigned integers in
-       native endianness.
-      </description>
-      <arg name="capabilities" type="array" summary="array of 32-bit capabilities"/>
-    </event>
-  </interface>
-
-  <interface name="xdg_popup" version="7">
-    <description summary="short-lived, popup surfaces for menus">
-      A popup surface is a short-lived, temporary surface. It can be used to
-      implement for example menus, popovers, tooltips and other similar user
-      interface concepts.
-
-      A popup can be made to take an explicit grab. See xdg_popup.grab for
-      details.
-
-      When the popup is dismissed, a popup_done event will be sent out, and at
-      the same time the surface will be unmapped. See the xdg_popup.popup_done
-      event for details.
-
-      Explicitly destroying the xdg_popup object will also dismiss the popup and
-      unmap the surface. Clients that want to dismiss the popup when another
-      surface of their own is clicked should dismiss the popup using the destroy
-      request.
-
-      A newly created xdg_popup will be stacked on top of all previously created
-      xdg_popup surfaces associated with the same xdg_toplevel.
-
-      The parent of an xdg_popup must be mapped (see the xdg_surface
-      description) before the xdg_popup itself.
-
-      The client must call wl_surface.commit on the corresponding wl_surface
-      for the xdg_popup state to take effect.
-    </description>
-
-    <enum name="error">
-      <entry name="invalid_grab" value="0"
-            summary="tried to grab after being mapped"/>
-    </enum>
-
-    <request name="destroy" type="destructor">
-      <description summary="remove xdg_popup interface">
-       This destroys the popup. Explicitly destroying the xdg_popup
-       object will also dismiss the popup, and unmap the surface.
-
-       If this xdg_popup is not the "topmost" popup, the
-       xdg_wm_base.not_the_topmost_popup protocol error will be sent.
-      </description>
-    </request>
-
-    <request name="grab">
-      <description summary="make the popup take an explicit grab">
-       This request makes the created popup take an explicit grab. An explicit
-       grab will be dismissed when the user dismisses the popup, or when the
-       client destroys the xdg_popup. This can be done by the user clicking
-       outside the surface, using the keyboard, or even locking the screen
-       through closing the lid or a timeout.
-
-       If the compositor denies the grab, the popup will be immediately
-       dismissed.
-
-       This request must be used in response to some sort of user action like a
-       button press, key press, or touch down event. The serial number of the
-       event should be passed as 'serial'.
-
-       The parent of a grabbing popup must either be an xdg_toplevel surface or
-       another xdg_popup with an explicit grab. If the parent is another
-       xdg_popup it means that the popups are nested, with this popup now being
-       the topmost popup.
-
-       Nested popups must be destroyed in the reverse order they were created
-       in, e.g. the only popup you are allowed to destroy at all times is the
-       topmost one.
-
-       When compositors choose to dismiss a popup, they may dismiss every
-       nested grabbing popup as well. When a compositor dismisses popups, it
-       will follow the same dismissing order as required from the client.
-
-       If the topmost grabbing popup is destroyed, the grab will be returned to
-       the parent of the popup, if that parent previously had an explicit grab.
-
-       If the parent is a grabbing popup which has already been dismissed, this
-       popup will be immediately dismissed. If the parent is a popup that did
-       not take an explicit grab, an error will be raised.
-
-       During a popup grab, the client owning the grab will receive pointer
-       and touch events for all their surfaces as normal (similar to an
-       "owner-events" grab in X11 parlance), while the top most grabbing popup
-       will always have keyboard focus.
-      </description>
-      <arg name="seat" type="object" interface="wl_seat"
-          summary="the wl_seat of the user event"/>
-      <arg name="serial" type="uint" summary="the serial of the user event"/>
-    </request>
-
-    <event name="configure">
-      <description summary="configure the popup surface">
-       This event asks the popup surface to configure itself given the
-       configuration. The configured state should not be applied immediately.
-       See xdg_surface.configure for details.
-
-       The x and y arguments represent the position the popup was placed at
-       given the xdg_positioner rule, relative to the upper left corner of the
-       window geometry of the parent surface.
-
-       For version 2 or older, the configure event for an xdg_popup is only
-       ever sent once for the initial configuration. Starting with version 3,
-       it may be sent again if the popup is setup with an xdg_positioner with
-       set_reactive requested, or in response to xdg_popup.reposition requests.
-      </description>
-      <arg name="x" type="int"
-          summary="x position relative to parent surface window geometry"/>
-      <arg name="y" type="int"
-          summary="y position relative to parent surface window geometry"/>
-      <arg name="width" type="int" summary="window geometry width"/>
-      <arg name="height" type="int" summary="window geometry height"/>
-    </event>
-
-    <event name="popup_done">
-      <description summary="popup interaction is done">
-       The popup_done event is sent out when a popup is dismissed by the
-       compositor. The client should destroy the xdg_popup object at this
-       point.
-      </description>
-    </event>
-
-    <!-- Version 3 additions -->
-
-    <request name="reposition" since="3">
-      <description summary="recalculate the popup's location">
-       Reposition an already-mapped popup. The popup will be placed given the
-       details in the passed xdg_positioner object, and a
-       xdg_popup.repositioned followed by xdg_popup.configure and
-       xdg_surface.configure will be emitted in response. Any parameters set
-       by the previous positioner will be discarded.
-
-       The passed token will be sent in the corresponding
-       xdg_popup.repositioned event. The new popup position will not take
-       effect until the corresponding configure event is acknowledged by the
-       client. See xdg_popup.repositioned for details. The token itself is
-       opaque, and has no other special meaning.
-
-       If multiple reposition requests are sent, the compositor may skip all
-       but the last one.
-
-       If the popup is repositioned in response to a configure event for its
-       parent, the client should send an xdg_positioner.set_parent_configure
-       and possibly an xdg_positioner.set_parent_size request to allow the
-       compositor to properly constrain the popup.
-
-       If the popup is repositioned together with a parent that is being
-       resized, but not in response to a configure event, the client should
-       send an xdg_positioner.set_parent_size request.
-      </description>
-      <arg name="positioner" type="object" interface="xdg_positioner"/>
-      <arg name="token" type="uint" summary="reposition request token"/>
-    </request>
-
-    <event name="repositioned" since="3">
-      <description summary="signal the completion of a repositioned request">
-       The repositioned event is sent as part of a popup configuration
-       sequence, together with xdg_popup.configure and lastly
-       xdg_surface.configure to notify the completion of a reposition request.
-
-       The repositioned event is to notify about the completion of a
-       xdg_popup.reposition request. The token argument is the token passed
-       in the xdg_popup.reposition request.
-
-       Immediately after this event is emitted, xdg_popup.configure and
-       xdg_surface.configure will be sent with the updated size and position,
-       as well as a new configure serial.
-
-       The client should optionally update the content of the popup, but must
-       acknowledge the new popup configuration for the new position to take
-       effect. See xdg_surface.ack_configure for details.
-      </description>
-      <arg name="token" type="uint" summary="reposition request token"/>
-    </event>
-
-  </interface>
-</protocol>
index b0c637e3a5792bbf2d427dccf4961a9330169864..d60b5d0e3c6f8699cba6a80ea0f7d8c40a3de100 100644 (file)
@@ -1699,7 +1699,7 @@ main_loop (Display *dpy)
           
         if (verbose_p > 3)
           {
-            if (!tv.tv_sec && tv.tv_usec)
+            if (!tv.tv_sec && !tv.tv_usec)
               fprintf (stderr, "%s: block until input\n", blurb());
             else
               {
index 38aebd07ad30f1ff91a9ecac435d8b602a6dba7a..b0825b1c381534b52dab98c9859205a6028bb0a8 100644 (file)
@@ -10,7 +10,7 @@ VPATH         = @srcdir@
 top_srcdir     = @top_srcdir@
 top_builddir   = ..
 
-install_prefix =
+DESTDIR                =
 prefix         = @prefix@
 exec_prefix    = @exec_prefix@
 bindir         = @bindir@
@@ -82,7 +82,8 @@ UTIL_SRCS     = $(UTILS_SRC)/alpha.c $(UTILS_SRC)/colors.c \
                  $(UTILS_SRC)/xshm.c $(UTILS_SRC)/xdbe.c \
                  $(UTILS_SRC)/textclient.c $(UTILS_SRC)/aligned_malloc.c \
                  $(UTILS_SRC)/thread_util.c $(UTILS_SRC)/pow2.c \
-                 $(UTILS_SRC)/font-retry.c
+                 $(UTILS_SRC)/font-retry.c $(UTILS_SRC)/easing.c \
+                 $(UTILS_SRC)/doubletime.c
 UTIL_OBJS      = $(UTILS_BIN)/alpha.o $(UTILS_BIN)/colors.o \
                  $(UTILS_BIN)/grabclient.o \
                  $(UTILS_BIN)/hsv.o $(UTILS_BIN)/resources.o \
@@ -94,7 +95,8 @@ UTIL_OBJS     = $(UTILS_BIN)/alpha.o $(UTILS_BIN)/colors.o \
                  $(UTILS_BIN)/textclient.o $(UTILS_BIN)/aligned_malloc.o \
                  $(UTILS_BIN)/thread_util.o $(UTILS_BIN)/pow2.o \
                  $(UTILS_BIN)/xft.o $(UTILS_BIN)/xftwrap.o \
-                 $(UTILS_BIN)/utf8wc.o $(UTILS_BIN)/font-retry.o
+                 $(UTILS_BIN)/utf8wc.o $(UTILS_BIN)/font-retry.o \
+                 $(UTILS_BIN)/easing.o $(UTILS_BIN)/doubletime.o
 
 SRCS           = xscreensaver-getimage.c \
                  attraction.c blitspin.c bouboule.c braid.c bubbles.c \
@@ -202,7 +204,7 @@ RETIRED_EXES        = ant bubbles critical flag forest hyperball hypercube laser \
 HACK_OBJS_1    = fps.o $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o \
                  $(UTILS_BIN)/utf8wc.o $(UTILS_BIN)/font-retry.o \
-                 $(UTILS_BIN)/xmu.o @XFT_OBJS@ @ANIM_OBJS@
+                 $(UTILS_BIN)/xmu.o $(DT) @XFT_OBJS@ @ANIM_OBJS@
 HACK_OBJS      = screenhack.o $(HACK_OBJS_1)
 XLOCK_OBJS     = screenhack.o xlockmore.o $(COLOR_OBJS) $(HACK_OBJS_1) \
                  $(ERASE)
@@ -286,19 +288,19 @@ install-strip:
 
 # the hacks, in $HACKDIR
 install-program:: $(EXES)
-       @if [ ! -d $(install_prefix)$(HACKDIR) ]; then                  \
-         $(INSTALL_DIRS) $(install_prefix)$(HACKDIR) ;                 \
+       @if [ ! -d $(DESTDIR)$(HACKDIR) ]; then                         \
+         $(INSTALL_DIRS) $(DESTDIR)$(HACKDIR) ;                        \
         fi ;                                                           \
        for program in $(EXES); do                                      \
          echo $(INSTALL_PROGRAM) $$program                             \
-           $(install_prefix)$(HACKDIR)/$$program ;                     \
+           $(DESTDIR)$(HACKDIR)/$$program ;                            \
          $(INSTALL_PROGRAM) $$program                                  \
-           $(install_prefix)$(HACKDIR)/$$program ;                     \
+           $(DESTDIR)$(HACKDIR)/$$program ;                            \
        done
 
 install-scripts: $(SCRIPTS) munge-scripts
-       @if [ ! -d $(install_prefix)$(HACKDIR) ]; then                  \
-         $(INSTALL_DIRS) $(install_prefix)$(HACKDIR) ;                 \
+       @if [ ! -d $(DESTDIR)$(HACKDIR) ]; then                         \
+         $(INSTALL_DIRS) $(DESTDIR)$(HACKDIR) ;                        \
         fi ;                                                           \
        for program in $(SCRIPTS); do                                   \
          if [ -r $$program ] ; then                                    \
@@ -307,9 +309,9 @@ install-scripts: $(SCRIPTS) munge-scripts
            p=$(srcdir)/$$program ;                                     \
          fi ;                                                          \
          echo $(INSTALL_SCRIPT) $$p                                    \
-           $(install_prefix)$(HACKDIR)/$$program ;                     \
+           $(DESTDIR)$(HACKDIR)/$$program ;                            \
          $(INSTALL_SCRIPT) $$p                                         \
-           $(install_prefix)$(HACKDIR)/$$program ;                     \
+           $(DESTDIR)$(HACKDIR)/$$program ;                            \
        done
 
 munge-scripts: $(SCRIPTS)
@@ -342,8 +344,8 @@ install-man: $(MEN)
        TH=".TH XScreenSaver $(mansuffix) \"$$V\" \"X Version 11\"" ;   \
        echo "installing man pages: $$TH" ;                             \
                                                                        \
-       if [ ! -d $(install_prefix)$(manNdir) ]; then                   \
-         $(INSTALL_DIRS) $(install_prefix)$(manNdir) ;                 \
+       if [ ! -d $(DESTDIR)$(manNdir) ]; then                          \
+         $(INSTALL_DIRS) $(DESTDIR)$(manNdir) ;                        \
         fi ;                                                           \
                                                                        \
        for man in $$men; do                                            \
@@ -354,14 +356,14 @@ install-man: $(MEN)
              -e 's@(MANSUFFIX)@($(mansuffix))@g'                       \
            < $(srcdir)/$$man > $$T ;                                   \
          echo $(INSTALL_DATA) $(srcdir)/$$man                          \
-          $(install_prefix)$(manNdir)/$$instname ;                     \
+          $(DESTDIR)$(manNdir)/$$instname ;                            \
          $(INSTALL_DATA) $$T                                           \
-           $(install_prefix)$(manNdir)/$$instname ;                    \
+           $(DESTDIR)$(manNdir)/$$instname ;                           \
        done ;                                                          \
        rm -f $$T
 
 install-xml:
-       @dest=$(install_prefix)$(HACK_CONF_DIR) ;                       \
+       @dest=$(DESTDIR)$(HACK_CONF_DIR) ;                              \
         if [ ! -d $$dest ]; then                                       \
           $(INSTALL_DIRS) $$dest ;                                     \
         fi ;                                                           \
@@ -375,20 +377,20 @@ install-xml:
 
 uninstall-program:
        @for program in $(EXES) $(RETIRED_EXES) $(SCRIPTS); do          \
-         echo rm -f $(install_prefix)$(HACKDIR)/$$program ;            \
-         rm -f $(install_prefix)$(HACKDIR)/$$program ;                 \
+         echo rm -f $(DESTDIR)$(HACKDIR)/$$program ;                   \
+         rm -f $(DESTDIR)$(HACKDIR)/$$program ;                        \
        done
 
 uninstall-man:
        @men="$(MEN) $(RETIRED_MEN)" ;                                  \
        for man in $$men; do                                            \
          instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ;     \
-         echo rm -f $(install_prefix)$(manNdir)/$$instname* ;          \
-         rm -f $(install_prefix)$(manNdir)/$$instname* ;               \
+         echo rm -f $(DESTDIR)$(manNdir)/$$instname* ;                 \
+         rm -f $(DESTDIR)$(manNdir)/$$instname* ;                      \
        done
 
 uninstall-xml:
-       @dest=$(install_prefix)$(HACK_CONF_DIR) ;                       \
+       @dest=$(DESTDIR)$(HACK_CONF_DIR) ;                              \
         for file in $(EXES) $(RETIRED_EXES) $(SCRIPTS) ; do            \
             echo rm -f $$dest/$$file.xml ;                             \
                  rm -f $$dest/$$file.xml ;                             \
@@ -491,6 +493,7 @@ $(UTILS_BIN)/aligned_malloc.o:      $(UTILS_SRC)/aligned_malloc.c
 $(UTILS_BIN)/thread_util.o:    $(UTILS_SRC)/thread_util.c
 $(UTILS_BIN)/pow2.o:           $(UTILS_SRC)/pow2.c
 $(UTILS_BIN)/font-retry.o:     $(UTILS_SRC)/font-retry.c
+$(UTILS_BIN)/easing.o:         $(UTILS_SRC)/easing.c
 
 
 
@@ -519,6 +522,7 @@ ALP         = $(UTILS_BIN)/alpha.o
 HSV            = $(UTILS_BIN)/hsv.o
 SPL            = $(UTILS_BIN)/spline.o
 GRAB           = $(GRAB_OBJS)
+DT             = $(UTILS_BIN)/doubletime.o
 ERASE          = $(UTILS_BIN)/erase.o
 COL            = $(COLOR_OBJS)
 SHM             = $(XSHM_OBJS)
@@ -551,7 +555,7 @@ GETIMG_OBJS = xscreensaver-getimage.o \
                  $(UTILS_BIN)/colors.o \
                  $(UTILS_BIN)/logo.o $(UTILS_BIN)/minixpm.o \
                  $(UTILS_BIN)/screenshot.o $(UTILS_BIN)/xmu.o \
-                 $(DRIVER_BIN)/prefs.o
+                 $(DRIVER_BIN)/prefs.o $(DT)
 GETIMG_LIBS    = $(LIBS) $(X_LIBS) $(PNG_LIBS) $(JPEG_LIBS) \
                  $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS)
 
@@ -885,8 +889,9 @@ glitchpeg:  glitchpeg.o     $(HACK_OBJS) $(PNG)
 filmleader:    filmleader.o    $(HACK_OBJS) $(ATV) $(GRAB) $(PNG)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(ATV) $(GRAB) $(PNG) $(PNG_LIBS) $(HACK_LIBS) $(THRL)
 
-vfeedback:     vfeedback.o     $(HACK_OBJS) $(ATV) $(GRAB) $(PNG)
-       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(ATV) $(GRAB) $(PNG) $(PNG_LIBS) $(HACK_LIBS) $(THRL)
+EASE = $(UTILS_BIN)/easing.o
+vfeedback:     vfeedback.o     $(HACK_OBJS) $(ATV) $(GRAB) $(PNG) $(EASE)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(ATV) $(GRAB) $(PNG) $(EASE) $(PNG_LIBS) $(HACK_LIBS) $(THRL)
 
 MARBLING_OBJS=$(COLOR_OBJS) $(THRO) $(XSHM_OBJS) $(HACK_OBJS)
 marbling:      marbling.o      $(MARBLING_OBJS)
@@ -1713,6 +1718,7 @@ droste.o: $(srcdir)/screenhackI.h
 droste.o: $(srcdir)/screenhack.h
 droste.o: $(UTILS_SRC)/aligned_malloc.h
 droste.o: $(UTILS_SRC)/colors.h
+droste.o: $(UTILS_SRC)/doubletime.h
 droste.o: $(UTILS_SRC)/font-retry.h
 droste.o: $(UTILS_SRC)/grabclient.h
 droste.o: $(UTILS_SRC)/hsv.h
@@ -1825,6 +1831,7 @@ filmleader.o: $(srcdir)/screenhackI.h
 filmleader.o: $(srcdir)/screenhack.h
 filmleader.o: $(UTILS_SRC)/aligned_malloc.h
 filmleader.o: $(UTILS_SRC)/colors.h
+filmleader.o: $(UTILS_SRC)/doubletime.h
 filmleader.o: $(UTILS_SRC)/font-retry.h
 filmleader.o: $(UTILS_SRC)/grabclient.h
 filmleader.o: $(UTILS_SRC)/hsv.h
@@ -2406,6 +2413,7 @@ m6502.o: $(srcdir)/screenhackI.h
 m6502.o: $(srcdir)/screenhack.h
 m6502.o: $(UTILS_SRC)/aligned_malloc.h
 m6502.o: $(UTILS_SRC)/colors.h
+m6502.o: $(UTILS_SRC)/doubletime.h
 m6502.o: $(UTILS_SRC)/font-retry.h
 m6502.o: $(UTILS_SRC)/grabclient.h
 m6502.o: $(UTILS_SRC)/hsv.h
@@ -2752,6 +2760,7 @@ pong.o: $(srcdir)/screenhackI.h
 pong.o: $(srcdir)/screenhack.h
 pong.o: $(UTILS_SRC)/aligned_malloc.h
 pong.o: $(UTILS_SRC)/colors.h
+pong.o: $(UTILS_SRC)/doubletime.h
 pong.o: $(UTILS_SRC)/font-retry.h
 pong.o: $(UTILS_SRC)/grabclient.h
 pong.o: $(UTILS_SRC)/hsv.h
@@ -2827,6 +2836,7 @@ recanim.o: $(srcdir)/fps.h
 recanim.o: $(srcdir)/recanim.h
 recanim.o: $(srcdir)/screenhackI.h
 recanim.o: $(UTILS_SRC)/colors.h
+recanim.o: $(UTILS_SRC)/doubletime.h
 recanim.o: $(UTILS_SRC)/font-retry.h
 recanim.o: $(UTILS_SRC)/grabclient.h
 recanim.o: $(UTILS_SRC)/hsv.h
@@ -3165,6 +3175,7 @@ tessellimage.o: $(srcdir)/recanim.h
 tessellimage.o: $(srcdir)/screenhackI.h
 tessellimage.o: $(srcdir)/screenhack.h
 tessellimage.o: $(UTILS_SRC)/colors.h
+tessellimage.o: $(UTILS_SRC)/doubletime.h
 tessellimage.o: $(UTILS_SRC)/font-retry.h
 tessellimage.o: $(UTILS_SRC)/grabclient.h
 tessellimage.o: $(UTILS_SRC)/hsv.h
@@ -3275,6 +3286,8 @@ vfeedback.o: $(srcdir)/screenhackI.h
 vfeedback.o: $(srcdir)/screenhack.h
 vfeedback.o: $(UTILS_SRC)/aligned_malloc.h
 vfeedback.o: $(UTILS_SRC)/colors.h
+vfeedback.o: $(UTILS_SRC)/doubletime.h
+vfeedback.o: $(UTILS_SRC)/easing.h
 vfeedback.o: $(UTILS_SRC)/font-retry.h
 vfeedback.o: $(UTILS_SRC)/grabclient.h
 vfeedback.o: $(UTILS_SRC)/hsv.h
index 5e506ab38d5d01acacf0050d8d9b402cdd4802c0..231251d67be1d541347dc35f0c3e7dfa042c10b7 100644 (file)
@@ -51,7 +51,7 @@ struct tty_state {
 
      However, this only applies to cursor coordinates caused by text insertion.
      Inserting "X" at column 80 lets cursor.x go to 81; but if at column 70
-     and you do "move right by 20", the cursot ends up at 80, not 81.  Fun!
+     and you do "move right by 20", the cursor ends up at 80, not 81.  Fun!
 
      Details: https://github.com/mattiase/wraptest
    */
index b909925d79d9aaea175cb3d0d69a8d9d09cf6d84..0ef51b00ab77cbb6ff9f039f37dd5c9bfb226377 100644 (file)
@@ -1,6 +1,6 @@
 .TH "Binary Horizon" 1 "23-Mar-20" "X Version 11"
 .SH NAME
-binaryhorizon - A system of path tracing particles evolves continuously. 
+binaryhorizon \- A system of path tracing particles evolves continuously. 
 .SH SYNOPSIS
 .B binaryhorizon
 [\-\-fps]
index c46cd8d1bdd32e8ede2ba08d5878ee0f2d25f8e5..3b25d5636911da89315edbb82db49caf4fa8404e 100644 (file)
@@ -1971,38 +1971,36 @@ windows_10_recovery (Display *dpy, Window window)
 }
 
 
+static int qr_size = 41;
+static const unsigned char qr_bits[] = {
+  0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,
+  0x03,0x9A,0x70,0xEE,0x80,0x01,0xFB,0x22,0xAA,0xA6,0xBE,0x01,
+  0x8B,0x8E,0x74,0xE7,0xA2,0x01,0x8B,0xEE,0x42,0xC4,0xA2,0x01,
+  0x8B,0x42,0x6E,0xED,0xA2,0x01,0xFB,0xDA,0x63,0xA6,0xBE,0x01,
+  0x03,0xAA,0xAA,0xAA,0x80,0x01,0xFF,0x8B,0xD8,0x9D,0xFF,0x01,
+  0x63,0x62,0xDA,0x1B,0x98,0x01,0x6F,0x67,0x98,0x9F,0xBC,0x01,
+  0x4F,0xCC,0x55,0x81,0x83,0x01,0xB7,0x6D,0xFF,0x68,0xB2,0x01,
+  0xC3,0x10,0x87,0x8B,0x96,0x01,0x6F,0xB1,0x91,0x58,0x94,0x01,
+  0xE3,0x36,0x88,0x84,0xB8,0x01,0x83,0x9B,0xFE,0x59,0xD7,0x01,
+  0x3B,0x74,0x98,0x5C,0xB4,0x01,0x37,0x75,0xDC,0x91,0xA6,0x01,
+  0x77,0xDE,0x01,0x54,0xBA,0x01,0xBB,0x6D,0x8B,0xB9,0xB5,0x01,
+  0x1F,0x06,0xBD,0x9B,0xB4,0x01,0xD3,0xBD,0x91,0x19,0x84,0x01,
+  0x0B,0x20,0xD8,0x91,0xB4,0x01,0x33,0x95,0xBC,0x0A,0xD5,0x01,
+  0xB3,0x60,0xDC,0xD9,0xB6,0x01,0xEF,0x77,0x18,0x09,0xA4,0x01,
+  0xA3,0xC2,0x95,0x51,0xB2,0x01,0xDF,0x63,0xDB,0xBE,0xB3,0x01,
+  0x03,0x08,0xC9,0x09,0xF0,0x01,0xFF,0xA3,0x19,0xBD,0xFB,0x01,
+  0x03,0x2E,0x84,0xA5,0xAA,0x01,0xFB,0x9A,0xFC,0x9B,0xBB,0x01,
+  0x8B,0x7E,0x9C,0x1D,0xB0,0x01,0x8B,0x6E,0x58,0xA1,0xDB,0x01,
+  0x8B,0xDA,0xD5,0x65,0xA2,0x01,0xFB,0x72,0xFB,0xE9,0xF0,0x01,
+  0x03,0x02,0x99,0x3B,0xB3,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,
+  0xFF,0xFF,0xFF,0xFF,0xFF,0x01};
+
 static struct bsod_state *
 windows_10 (Display *dpy, Window window)
 {
   struct bsod_state *bst =
     make_bsod_state (dpy, window, "win10", "Win10");
-
-  int qr_width  = 41;
-  int qr_height = 41;
-  static const unsigned char qr_bits[] = {
-    0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,
-    0x03,0x9A,0x70,0xEE,0x80,0x01,0xFB,0x22,0xAA,0xA6,0xBE,0x01,
-    0x8B,0x8E,0x74,0xE7,0xA2,0x01,0x8B,0xEE,0x42,0xC4,0xA2,0x01,
-    0x8B,0x42,0x6E,0xED,0xA2,0x01,0xFB,0xDA,0x63,0xA6,0xBE,0x01,
-    0x03,0xAA,0xAA,0xAA,0x80,0x01,0xFF,0x8B,0xD8,0x9D,0xFF,0x01,
-    0x63,0x62,0xDA,0x1B,0x98,0x01,0x6F,0x67,0x98,0x9F,0xBC,0x01,
-    0x4F,0xCC,0x55,0x81,0x83,0x01,0xB7,0x6D,0xFF,0x68,0xB2,0x01,
-    0xC3,0x10,0x87,0x8B,0x96,0x01,0x6F,0xB1,0x91,0x58,0x94,0x01,
-    0xE3,0x36,0x88,0x84,0xB8,0x01,0x83,0x9B,0xFE,0x59,0xD7,0x01,
-    0x3B,0x74,0x98,0x5C,0xB4,0x01,0x37,0x75,0xDC,0x91,0xA6,0x01,
-    0x77,0xDE,0x01,0x54,0xBA,0x01,0xBB,0x6D,0x8B,0xB9,0xB5,0x01,
-    0x1F,0x06,0xBD,0x9B,0xB4,0x01,0xD3,0xBD,0x91,0x19,0x84,0x01,
-    0x0B,0x20,0xD8,0x91,0xB4,0x01,0x33,0x95,0xBC,0x0A,0xD5,0x01,
-    0xB3,0x60,0xDC,0xD9,0xB6,0x01,0xEF,0x77,0x18,0x09,0xA4,0x01,
-    0xA3,0xC2,0x95,0x51,0xB2,0x01,0xDF,0x63,0xDB,0xBE,0xB3,0x01,
-    0x03,0x08,0xC9,0x09,0xF0,0x01,0xFF,0xA3,0x19,0xBD,0xFB,0x01,
-    0x03,0x2E,0x84,0xA5,0xAA,0x01,0xFB,0x9A,0xFC,0x9B,0xBB,0x01,
-    0x8B,0x7E,0x9C,0x1D,0xB0,0x01,0x8B,0x6E,0x58,0xA1,0xDB,0x01,
-    0x8B,0xDA,0xD5,0x65,0xA2,0x01,0xFB,0x72,0xFB,0xE9,0xF0,0x01,
-    0x03,0x02,0x99,0x3B,0xB3,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,
-    0xFF,0xFF,0xFF,0xFF,0xFF,0x01};
   Pixmap pixmap;
-
   const char * const lines1[] = {
     ":(",
 
@@ -2068,6 +2066,7 @@ windows_10 (Display *dpy, Window window)
   Bool honorp = !clownp && !(random() % 20);
   const char * const * lines = (clownp ? lines2 : honorp ? lines3 : lines1);
   int stop = 60 + (random() % 39) + (clownp ? 1300 : 0);
+  int qs = qr_size;
 
   if (!(random() % 4))
     return windows_10_recovery (dpy, window);
@@ -2088,7 +2087,7 @@ windows_10 (Display *dpy, Window window)
   }
 
   pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) qr_bits,
-                                        qr_width, qr_height,
+                                        qs, qs,
                                         bst->fg, bst->bg, bst->xgwa.depth);
   {
     int n = 2;
@@ -2097,9 +2096,8 @@ windows_10 (Display *dpy, Window window)
     for (i = 0; i < n; i++)
       {
         pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth,
-                                pixmap, qr_width, qr_height);
-        qr_width *= 2;
-        qr_height *= 2;
+                                pixmap, qs, qs);
+        qs *= 2;
       }
   }
   bst->pixmap = pixmap;
@@ -2140,14 +2138,14 @@ windows_10 (Display *dpy, Window window)
         }
       else if (i == 2)
         {
-          left  += qr_width + font->ascent / 2;
+          left  += qs + font->ascent / 2;
           if (bst->xgwa.width > bst->xgwa.height)
-            right += qr_width * 1.8;
+            right += qs * 1.8;
           BSOD_MARGINS (bst, left, right);
         }
       else if (i == 3)
         {
-          BSOD_PIXMAP (bst, 0, 0, qr_width, qr_height, left0, oy);
+          BSOD_PIXMAP (bst, 0, 0, qs, qs, left0, oy);
         }
     }
 
@@ -7035,6 +7033,26 @@ systemd (Display *dpy, Window window)
 {
   struct bsod_state *bst = make_bsod_state (dpy, window, "systemd", "Systemd");
   int lh = (bst->font->ascent + bst->font->descent);
+  int qs = qr_size;
+  Pixmap pixmap;
+  int i, y = 0;
+
+  pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) qr_bits,
+                                        qs, qs,
+                                        bst->fg, bst->bg, bst->xgwa.depth);
+  {
+    int n = 3;
+    if (bst->xgwa.width > 2560 || bst->xgwa.height > 2560)
+      n++;  /* Retina displays */
+    for (i = 0; i < n; i++)
+      {
+        pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth,
+                                pixmap, qs, qs);
+        qs *= 2;
+      }
+  }
+  bst->pixmap = pixmap;
+
   BSOD_MOVETO (bst, 0, lh);
   BSOD_TEXT (bst, LEFT,
              "     .--.        _\n"
@@ -7044,11 +7062,15 @@ systemd (Display *dpy, Window window)
              "  (|     | )     _\n"
              " /'\\_   _/`\\    (_)\n"
              " \\___)=(___/\n");
-  BSOD_MOVETO (bst, 0, (bst->xgwa.height / 2) - lh);
-  BSOD_TEXT (bst, CENTER,
-             "KERNEL PANIC !\n"
-             "\n"
-             "Please reboot your computer.");
+
+  y = (bst->xgwa.height - qs) / 2;
+  if (y < lh * 8) y = lh * 8;
+  BSOD_PIXMAP (bst, 0, 0, qs, qs, (bst->xgwa.width - qs) / 2, y);
+  y += qs + lh * 3;
+  BSOD_MOVETO (bst, 0, y);
+  BSOD_TEXT (bst, CENTER, "KERNEL PANIC !\n\n");
+  BSOD_TEXT (bst, CENTER, "Please reboot your computer.\n\n");
+  BSOD_TEXT (bst, CENTER, "Fatal exception in interrupt");
   XClearWindow (dpy, window);
   return bst;
 }
index a0218c1afbd55bd8031b45843f00acdfe17740f7..02ce3f5d8aa31a54d750c7afb67c3a5a37000995 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 celtic \- draws celtic cross-stich patterns
 .SH SYNOPSIS
-.B ifs
+.B celtic
 [\-\-display \fIhost:display.screen\fP]
 [\-\-visual \fIvisual\fP]
 [\-\-window]
index 1177e6c400b4a99100e8196cca2986ad639983b7..b6591e9381c4536d9d7883f3a6a47a2801c5152f 100644 (file)
@@ -4,8 +4,8 @@
             a screen saver and locker for the X window system
                             by Jamie Zawinski
 
-                              version 6.12
-                               07-Jul-2025
+                              version 6.13
+                               02-Dec-2025
 
                      https://www.jwz.org/xscreensaver/
 
index a5cdc53ec7c766b74f56981539e846be8ecee841..11709465945d08f05a227be84aa1f1db7a813d7b 100644 (file)
 
   <boolean id="classic" _label="Low resolution chess pieces" arg-set="--classic"/>
   <boolean id="showfps" _label="Show frame rate" arg-set="--fps"/>
+  <boolean id="hidelabels" _label="Hide game and moves description" arg-set="--no-labels"/>
 
   <xscreensaver-updater />
 
   <_description>
 Black slips out of three mating nets, but the fourth one holds him tight!
-A brilliant composition! 
+A brilliant composition!
 
 See also the "Queens" screen saver.
 
index ae615e8b95843f0ac4e79cc652a44a6d54aad792..b061b03184562ea407cececca0286108adc5d1c7 100644 (file)
@@ -8,36 +8,44 @@
 
   <hgroup>
    <vgroup>
-   <number id="delay" type="slider" arg="--delay %"
-           _label="Frame rate" _low-label="Low" _high-label="High"
-           low="0" high="100000" default="20000"
-           convert="invert"/>
-
-   <number id="duration" type="slider" arg="--duration %"
-           _label="Time until loading a new image"
-           _low-label="10 seconds" _high-label="5 minutes"
-           low="10" high="300" default="30"/>
-
-   <number id="zoom" type="slider" arg="--zoom %"
-           _label="Always show at least this much of the image"
-           _low-label="50%" _high-label="100%"
-           low="50" high="100" default="75"/>
-
-   <number id="pan" type="slider" arg="--pan %"
-           _label="Pan/zoom duration"
-           _low-label="1 second" _high-label="30 seconds"
-           low="1" high="30" default="6"/>
-
-   <number id="fade" type="slider" arg="--fade %"
-           _label="Crossfade duration"
-           _low-label="None" _high-label="30 seconds"
-           low="0" high="30" default="2"/>
+    <number id="delay" type="slider" arg="--delay %"
+            _label="Frame rate" _low-label="Low" _high-label="High"
+            low="0" high="100000" default="20000"
+            convert="invert"/>
+    <number id="duration" type="slider" arg="--duration %"
+            _label="Time until loading a new image"
+            _low-label="10 seconds" _high-label="5 minutes"
+            low="10" high="300" default="30"/>
+
+    <number id="pan" type="slider" arg="--transition %"
+            _label="Image loading animation duration"
+            _low-label="1 second" _high-label="30 seconds"
+            low="1" high="30" default="3"/>
+   </vgroup>
+   <vgroup>
+    <number id="zoom" type="slider" arg="--zoom %"
+            _label="Always show at least this much of the image"
+            _low-label="50%" _high-label="100%"
+            low="50" high="100" default="75"/>
+    <number id="pan" type="slider" arg="--pan %"
+            _label="Pan / zoom duration"
+            _low-label="1 second" _high-label="30 seconds"
+            low="1" high="30" default="6"/>
+    <number id="fade" type="slider" arg="--fade %"
+            _label="Crossfade duration"
+            _low-label="None" _high-label="30 seconds"
+            low="0" high="30" default="2"/>
    </vgroup>
    <vgroup>
 
-    <boolean id="letterbox" _label="Letterbox" arg-unset="--no-letterbox"/>
-    <boolean id="titles" _label="Show file names" arg-set="--titles"/>
-    <boolean id="showfps" _label="Show frame rate" arg-set="--fps"/>
+    <hgroup>
+     <boolean id="letterbox" _label="Letterbox" arg-unset="--no-letterbox"/>
+     <boolean id="titles" _label="Show file names" arg-set="--titles"/>
+     <boolean id="showfps" _label="Show frame rate" arg-set="--fps"/>
+    </hgroup>
 
     <xscreensaver-image />
 
   </hgroup>
 
   <_description>
-Loads a random sequence of images and smoothly scans and zooms around
-in each, fading from pan to pan.  
+Displays a slideshow of images, with panning, zooming and crossfading
+effects.
+
+When a new image is loaded, it transitions onto the screen by sliding
+in from the edges, spinning or flipping.  Turn off "Image Loading Animation"
+to disable those effects.
+
+Once an image has been loaded, it is panned, zoomed and cross-faded against
+itself.  Turn off "Crossfade" to disable those effects.
 
-Written by Jamie Zawinski and Mike Oliphant; 2003.
+Written by Jamie Zawinski; 2003.
   </_description>
 </screensaver>
index 0a5631a747ae9e34ccf93e8079847782dd7e0bae..08478fdc4b48e921511fd75389120c499bd97d38 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright © 2023 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 2023-2025 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
@@ -13,6 +13,7 @@
 #include "pow2.h"
 #include "thread_util.h"
 #include "xshm.h"
+#include "doubletime.h"
 
 #define DO_LOG_TABLES /* Dave's hairier and faster version */
 
@@ -122,21 +123,6 @@ struct thread {
 };
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 /* Called for each thread, once at startup. */
 static int
 droste_thread_create (void *t_raw,
index 598269baa92296b52447a95a6c1e1086b255372e..553c2e7837dac8188d4d3b941230eba10ad5260c 100644 (file)
@@ -1,8 +1,8 @@
 .TH XScreenSaver 1 "" "X Version 11"
 .SH NAME
-Eruption \- eruption of pieces of hot volcanic rock
+eruption \- eruption of pieces of hot volcanic rock
 .SH SYNOPSIS
-.B Eruption
+.B eruption
 [\-\-display \fIhost:display.screen\fP]
 [\-\-visual \fIvisual\fP]
 [\-\-window]
index c3e94153a309233141e3b8e05105d6b995e0e332..e894e9b079fb695bf076228d14cb4edaceb45090 100644 (file)
 # define HAVE_AVCODEC_GET_SUPPORTED_CONFIG
 #endif
 
+#ifndef  AV_PROFILE_H264_BASELINE /* ffmpeg < 8.0 */
+# define AV_PROFILE_H264_BASELINE FF_PROFILE_H264_BASELINE
+# define AV_PROFILE_H264_MAIN     FF_PROFILE_H264_MAIN
+# define AV_PROFILE_H264_HIGH     FF_PROFILE_H264_HIGH
+#endif
+
 struct av_stream {
   const AVCodec *codec;
   AVStream *st;
@@ -403,7 +409,7 @@ ffmpeg_out_init (const char *outfile, const char *audiofile,
   ffst->video_ost.ctx->time_base    = ffst->video_ost.st->time_base;
   ffst->video_ost.ctx->gop_size     = 250;
   ffst->video_ost.ctx->pix_fmt      = pix_fmt;
-  ffst->video_ost.ctx->profile      = FF_PROFILE_H264_HIGH;
+  ffst->video_ost.ctx->profile      = AV_PROFILE_H264_HIGH;
 
   av_log_set_level (AV_LOG_ERROR);  /* Before open_stream */
 
index 454b91d0e72e06db65bdf5a7c4a8e2622910268f..3250d3b1ac7b341acddfe98e5cfc10479979a776 100644 (file)
@@ -1,4 +1,4 @@
-/* filmleader, Copyright (c) 2018-2019 Jamie Zawinski <jwz@jwz.org>
+/* filmleader, Copyright © 2018-2025 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
@@ -13,6 +13,7 @@
 
 #include "screenhack.h"
 #include "analogtv.h"
+#include "doubletime.h"
 
 #include <time.h>
 
@@ -132,21 +133,6 @@ filmleader_init (Display *dpy, Window window)
 }
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static unsigned long
 filmleader_draw (Display *dpy, Window window, void *closure)
 {
index 7e272c856b2effd80f035136ea039966a6f23fe2..2ba4b90f75308060e8126528dce5b184e9a0c302 100644 (file)
@@ -1,4 +1,4 @@
-# hacks/fonts/Makefile.in --- xscreensaver, Copyright © 2021-2023 Jamie Zawinski.
+# hacks/fonts/Makefile.in --- xscreensaver, Copyright © 2021-2025 Jamie Zawinski.
 # the `../configure' script generates `hacks/fonts/Makefile' from this file.
 
 @SET_MAKE@
@@ -7,7 +7,7 @@ VPATH           = ${srcdir}
 top_srcdir     = @top_srcdir@
 top_builddir   = ..
 
-install_prefix =
+DESTDIR                =
 prefix         = @prefix@
 datarootdir    = @datarootdir@
 datadir                = @datadir@
@@ -15,10 +15,9 @@ FONT_DIR     = @FONT_DIR@
 
 RM             = rm -f
 
-STAR           = *
 TARFILES       = Makefile.in \
-                 $(STAR).ttf \
-                 $(STAR).otf
+                 $(FONTS) \
+                 gallant12x22-bsd.c
 
 INSTALL                = @INSTALL@
 INSTALL_DATA   = @INSTALL_DATA@
@@ -66,7 +65,7 @@ install-fonts:
        @if [ -z "$(FONT_DIR)" ]; then                                  \
           echo "not installing fonts" ;                                \
         else                                                           \
-          dest="$(install_prefix)$(FONT_DIR)" ;                        \
+          dest="$(DESTDIR)$(FONT_DIR)" ;                               \
           if [ ! -d "$$dest" ]; then                                   \
             echo $(INSTALL_DIRS) "$$dest" ;                            \
                  $(INSTALL_DIRS) "$$dest" ;                            \
@@ -80,12 +79,12 @@ install-fonts:
 uninstall:: uninstall-fonts
 uninstall-fonts:
        @if ! [ -z "$(FONT_DIR)" ]; then                                \
-          dest="$(install_prefix)$(FONT_DIR)" ;                        \
+          dest="$(DESTDIR)$(FONT_DIR)" ;                               \
           for f in $(FONTS) ; do                                       \
             echo $(RM) $$dest/$$f ;                                    \
                  $(RM) $$dest/$$f ;                                    \
           done ;                                                       \
-          rmdir "$(install_prefix)$(FONT_DIR)" ;                       \
+          rmdir "$(DESTDIR)$(FONT_DIR)" ;                              \
           exit 0 ;                                                     \
         fi
 
diff --git a/hacks/fonts/OCRAStd.otf b/hacks/fonts/OCRAStd.otf
deleted file mode 100644 (file)
index aee7c35..0000000
Binary files a/hacks/fonts/OCRAStd.otf and /dev/null differ
diff --git a/hacks/fonts/gallant12x22-bsd.c b/hacks/fonts/gallant12x22-bsd.c
new file mode 100644 (file)
index 0000000..1af343c
--- /dev/null
@@ -0,0 +1,6198 @@
+/* http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/dev/wsfont/gallant12x22.h */
+/*     $NetBSD: gallant12x22.h,v 1.11 2005/12/11 12:24:12 christos Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory and to the University
+ * of California at Berkeley by Jef Poskanzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Derived from: @(#)gallant19.h       8.1 (Berkeley) 6/11/93
+ */
+
+static u_char gallant12x22_data[];
+
+static struct wsdisplay_font gallant12x22 = {
+       "Gallant",                      /* typeface name */
+       0,                              /* firstchar */
+       255 - 0 + 1,                    /* numchar */
+       WSDISPLAY_FONTENC_ISO,          /* encoding */
+       12,                             /* width */
+       22,                             /* height */
+       2,                              /* stride */
+       WSDISPLAY_FONTORDER_L2R,        /* bit order */
+       WSDISPLAY_FONTORDER_L2R,        /* byte order */
+       gallant12x22_data               /* data */
+};
+
+static u_char gallant12x22_data[] = {
+       /* 0 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 1 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1f, 0x80,     /* ...******... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x1f, 0x80,     /* ...******... */
+       0x0f, 0x00,     /* ....****.... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 2 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x55, 0x40,     /* .*.*.*.*.*.. */
+       0x2a, 0xa0,     /* ..*.*.*.*.*. */
+       0x55, 0x40,     /* .*.*.*.*.*.. */
+       0x2a, 0xa0,     /* ..*.*.*.*.*. */
+       0x55, 0x40,     /* .*.*.*.*.*.. */
+       0x2a, 0xa0,     /* ..*.*.*.*.*. */
+       0x55, 0x40,     /* .*.*.*.*.*.. */
+       0x2a, 0xa0,     /* ..*.*.*.*.*. */
+       0x55, 0x40,     /* .*.*.*.*.*.. */
+       0x2a, 0xa0,     /* ..*.*.*.*.*. */
+       0x55, 0x40,     /* .*.*.*.*.*.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 3 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x44, 0x00,     /* .*...*...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x7c, 0x00,     /* .*****...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x03, 0xe0,     /* ......*****. */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 4 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7c, 0x00,     /* .*****...... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x78, 0x00,     /* .****....... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x03, 0xe0,     /* ......*****. */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x03, 0xc0,     /* ......****.. */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 5 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x38, 0x00,     /* ..***....... */
+       0x44, 0x00,     /* .*...*...... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x44, 0x00,     /* .*...*...... */
+       0x38, 0x00,     /* ..***....... */
+       0x03, 0xc0,     /* ......****.. */
+       0x02, 0x20,     /* ......*...*. */
+       0x02, 0x20,     /* ......*...*. */
+       0x03, 0xc0,     /* ......****.. */
+       0x02, 0x80,     /* ......*.*... */
+       0x02, 0x40,     /* ......*..*.. */
+       0x02, 0x20,     /* ......*...*. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 6 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x40, 0x00,     /* .*.......... */
+       0x7c, 0x00,     /* .*****...... */
+       0x03, 0xe0,     /* ......*****. */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x03, 0xc0,     /* ......****.. */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 7 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0e, 0x00,     /* ....***..... */
+       0x17, 0x00,     /* ...*.***.... */
+       0x23, 0x80,     /* ..*...***... */
+       0x61, 0x80,     /* .**....**... */
+       0x61, 0x80,     /* .**....**... */
+       0x71, 0x00,     /* .***...*.... */
+       0x3a, 0x00,     /* ..***.*..... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 8 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 9 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x44, 0x00,     /* .*...*...... */
+       0x64, 0x00,     /* .**..*...... */
+       0x64, 0x00,     /* .**..*...... */
+       0x54, 0x00,     /* .*.*.*...... */
+       0x4c, 0x00,     /* .*..**...... */
+       0x4c, 0x00,     /* .*..**...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x03, 0xe0,     /* ......*****. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 10 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x44, 0x00,     /* .*...*...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x44, 0x00,     /* .*...*...... */
+       0x28, 0x00,     /* ..*.*....... */
+       0x28, 0x00,     /* ..*.*....... */
+       0x10, 0x00,     /* ...*........ */
+       0x10, 0x00,     /* ...*........ */
+       0x03, 0xe0,     /* ......*****. */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 11 */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0xfe, 0x00,     /* *******..... */
+       0xfe, 0x00,     /* *******..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 12 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xfe, 0x00,     /* *******..... */
+       0xfe, 0x00,     /* *******..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 13 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x07, 0xf0,     /* .....******* */
+       0x07, 0xf0,     /* .....******* */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 14 */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x07, 0xf0,     /* .....******* */
+       0x07, 0xf0,     /* .....******* */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 15 */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 16 */
+       0x00, 0x00,     /* ............ */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 17 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 18 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 19 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 20 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x00, 0x00,     /* ............ */
+
+       /* 21 */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x07, 0xf0,     /* .....******* */
+       0x07, 0xf0,     /* .....******* */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 22 */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0xfe, 0x00,     /* *******..... */
+       0xfe, 0x00,     /* *******..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 23 */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 24 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0xf0,     /* ************ */
+       0xff, 0xf0,     /* ************ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 25 */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 26 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0xe0,     /* ........***. */
+       0x07, 0x80,     /* .....****... */
+       0x1e, 0x00,     /* ...****..... */
+       0x78, 0x00,     /* .****....... */
+       0x78, 0x00,     /* .****....... */
+       0x1e, 0x00,     /* ...****..... */
+       0x07, 0x80,     /* .....****... */
+       0x00, 0xe0,     /* ........***. */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 27 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x70, 0x00,     /* .***........ */
+       0x1e, 0x00,     /* ...****..... */
+       0x07, 0x80,     /* .....****... */
+       0x01, 0xe0,     /* .......****. */
+       0x01, 0xe0,     /* .......****. */
+       0x07, 0x80,     /* .....****... */
+       0x1e, 0x00,     /* ...****..... */
+       0x70, 0x00,     /* .***........ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 28 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x3f, 0xe0,     /* ..*********. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x31, 0x80,     /* ..**...**... */
+       0x31, 0x80,     /* ..**...**... */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 29 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x40,     /* .........*.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x01, 0x80,     /* .......**... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x30, 0x00,     /* ..**........ */
+       0x60, 0x00,     /* .**......... */
+       0x40, 0x00,     /* .*.......... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 30 */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x10, 0x00,     /* ...*........ */
+       0x10, 0x00,     /* ...*........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x3e, 0x00,     /* ..*****..... */
+       0x7c, 0x00,     /* .*****...... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x3f, 0x20,     /* ..******..*. */
+       0x3f, 0xe0,     /* ..*********. */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 31 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 32 ( ) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 33 (!) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 34 (") */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 35 (#) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x30,     /* ......**..** */
+       0x03, 0x30,     /* ......**..** */
+       0x03, 0x30,     /* ......**..** */
+       0x06, 0x60,     /* .....**..**. */
+       0x1f, 0xf0,     /* ...********* */
+       0x1f, 0xf0,     /* ...********* */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x33, 0x00,     /* ..**..**.... */
+       0x66, 0x00,     /* .**..**..... */
+       0x66, 0x00,     /* .**..**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 36 ($) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x66, 0xe0,     /* .**..**.***. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x00,     /* .**..**..... */
+       0x3e, 0x00,     /* ..*****..... */
+       0x1f, 0x80,     /* ...******... */
+       0x07, 0xc0,     /* .....*****.. */
+       0x06, 0x60,     /* .....**..**. */
+       0x06, 0x60,     /* .....**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x3f, 0x80,     /* ..*******... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 37 (%) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x38, 0x60,     /* ..***....**. */
+       0x44, 0xc0,     /* .*...*..**.. */
+       0x44, 0xc0,     /* .*...*..**.. */
+       0x45, 0x80,     /* .*...*.**... */
+       0x39, 0x80,     /* ..***..**... */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x19, 0xc0,     /* ...**..***.. */
+       0x1a, 0x20,     /* ...**.*...*. */
+       0x32, 0x20,     /* ..**..*...*. */
+       0x32, 0x20,     /* ..**..*...*. */
+       0x61, 0xc0,     /* .**....***.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 38 (&) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x07, 0x00,     /* .....***.... */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x0f, 0x80,     /* ....*****... */
+       0x1e, 0x00,     /* ...****..... */
+       0x3e, 0x00,     /* ..*****..... */
+       0x77, 0x00,     /* .***.***.... */
+       0x63, 0x60,     /* .**...**.**. */
+       0x61, 0xe0,     /* .**....****. */
+       0x61, 0xc0,     /* .**....***.. */
+       0x61, 0x80,     /* .**....**... */
+       0x3f, 0xe0,     /* ..*********. */
+       0x1e, 0x60,     /* ...****..**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 39 (') */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x10, 0x00,     /* ...*........ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 40 (() */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0xc0,     /* ........**.. */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x80,     /* ......***... */
+       0x03, 0x00,     /* ......**.... */
+       0x07, 0x00,     /* .....***.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x07, 0x00,     /* .....***.... */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x80,     /* ......***... */
+       0x01, 0x80,     /* .......**... */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 41 ()) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x30, 0x00,     /* ..**........ */
+       0x18, 0x00,     /* ...**....... */
+       0x1c, 0x00,     /* ...***...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0e, 0x00,     /* ....***..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0e, 0x00,     /* ....***..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x1c, 0x00,     /* ...***...... */
+       0x18, 0x00,     /* ...**....... */
+       0x30, 0x00,     /* ..**........ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 42 (*) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x06, 0x00,     /* .....**..... */
+       0x66, 0x60,     /* .**..**..**. */
+       0x76, 0xe0,     /* .***.**.***. */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x76, 0xe0,     /* .***.**.***. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 43 (+) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 44 (,) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x10, 0x00,     /* ...*........ */
+
+       /* 45 (-) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 46 (.) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 47 (/) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x60, 0x00,     /* .**......... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 48 (0) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x07, 0x00,     /* .....***.... */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0x80,     /* ..**....*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x0e, 0x00,     /* ....***..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 49 (1) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x02, 0x00,     /* ......*..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0e, 0x00,     /* ....***..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x36, 0x00,     /* ..**.**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 50 (2) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x00,     /* ...*****.... */
+       0x3f, 0x80,     /* ..*******... */
+       0x61, 0xc0,     /* .**....***.. */
+       0x40, 0xc0,     /* .*......**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x30, 0x20,     /* ..**......*. */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 51 (3) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x1f, 0xc0,     /* ...*******.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x40, 0x60,     /* .*.......**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0xe0,     /* ........***. */
+       0x07, 0xc0,     /* .....*****.. */
+       0x0f, 0xc0,     /* ....******.. */
+       0x00, 0xe0,     /* ........***. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x40, 0x60,     /* .*.......**. */
+       0x60, 0x40,     /* .**......*.. */
+       0x3f, 0x80,     /* ..*******... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 52 (4) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x80,     /* ......***... */
+       0x03, 0x80,     /* ......***... */
+       0x05, 0x80,     /* .....*.**... */
+       0x05, 0x80,     /* .....*.**... */
+       0x09, 0x80,     /* ....*..**... */
+       0x09, 0x80,     /* ....*..**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x21, 0x80,     /* ..*....**... */
+       0x3f, 0xe0,     /* ..*********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 53 (5) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0xc0,     /* ....******.. */
+       0x0f, 0xc0,     /* ....******.. */
+       0x10, 0x00,     /* ...*........ */
+       0x10, 0x00,     /* ...*........ */
+       0x20, 0x00,     /* ..*......... */
+       0x3f, 0x80,     /* ..*******... */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x00, 0xe0,     /* ........***. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x40, 0x60,     /* .*.......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 54 (6) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x07, 0x00,     /* .....***.... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x60, 0x00,     /* .**......... */
+       0x67, 0x80,     /* .**..****... */
+       0x6f, 0xc0,     /* .**.******.. */
+       0x70, 0xe0,     /* .***....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x3f, 0x80,     /* ..*******... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 55 (7) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0xe0,     /* ...********. */
+       0x3f, 0xe0,     /* ..*********. */
+       0x60, 0x40,     /* .**......*.. */
+       0x00, 0x40,     /* .........*.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0x80,     /* ........*... */
+       0x00, 0x80,     /* ........*... */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x00,     /* .......*.... */
+       0x01, 0x00,     /* .......*.... */
+       0x03, 0x00,     /* ......**.... */
+       0x02, 0x00,     /* ......*..... */
+       0x02, 0x00,     /* ......*..... */
+       0x06, 0x00,     /* .....**..... */
+       0x04, 0x00,     /* .....*...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 56 (8) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 57 (9) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0xe0,     /* .***....***. */
+       0x3f, 0x60,     /* ..******.**. */
+       0x1e, 0x60,     /* ...****..**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x01, 0x80,     /* .......**... */
+       0x07, 0x00,     /* .....***.... */
+       0x3c, 0x00,     /* ..****...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 58 (:) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 59 (;) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x10, 0x00,     /* ...*........ */
+
+       /* 60 (<) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x60,     /* .........**. */
+       0x01, 0xc0,     /* .......***.. */
+       0x07, 0x00,     /* .....***.... */
+       0x1e, 0x00,     /* ...****..... */
+       0x78, 0x00,     /* .****....... */
+       0x78, 0x00,     /* .****....... */
+       0x1e, 0x00,     /* ...****..... */
+       0x07, 0x00,     /* .....***.... */
+       0x01, 0xc0,     /* .......***.. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 61 (=) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xc0,     /* .*********.. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xc0,     /* .*********.. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 62 (>) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x60, 0x00,     /* .**......... */
+       0x38, 0x00,     /* ..***....... */
+       0x1e, 0x00,     /* ...****..... */
+       0x07, 0x80,     /* .....****... */
+       0x01, 0xe0,     /* .......****. */
+       0x01, 0xe0,     /* .......****. */
+       0x07, 0x80,     /* .....****... */
+       0x1e, 0x00,     /* ...****..... */
+       0x38, 0x00,     /* ..***....... */
+       0x60, 0x00,     /* .**......... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 63 (?) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x1f, 0x80,     /* ...******... */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 64 (@) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x60, 0x60,     /* .**......**. */
+       0x67, 0x20,     /* .**..***..*. */
+       0x6f, 0xa0,     /* .**.*****.*. */
+       0x6c, 0xa0,     /* .**.**..*.*. */
+       0x6c, 0xa0,     /* .**.**..*.*. */
+       0x67, 0xe0,     /* .**..******. */
+       0x60, 0x00,     /* .**......... */
+       0x30, 0x00,     /* ..**........ */
+       0x3f, 0xe0,     /* ..*********. */
+       0x0f, 0xe0,     /* ....*******. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 65 (A) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x09, 0x00,     /* ....*..*.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0x80,     /* ...*....*... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 66 (B) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0x00,     /* ********.... */
+       0x60, 0x80,     /* .**.....*... */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x61, 0x80,     /* .**....**... */
+       0x7f, 0x80,     /* .********... */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0xff, 0x80,     /* *********... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 67 (C) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0xc0,     /* ....******.. */
+       0x10, 0x60,     /* ...*.....**. */
+       0x20, 0x20,     /* ..*.......*. */
+       0x20, 0x00,     /* ..*......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x20, 0x00,     /* ..*......... */
+       0x30, 0x20,     /* ..**......*. */
+       0x18, 0x40,     /* ...**....*.. */
+       0x0f, 0x80,     /* ....*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 68 (D) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0x00,     /* ********.... */
+       0x61, 0xc0,     /* .**....***.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x40,     /* .**......*.. */
+       0x61, 0x80,     /* .**....**... */
+       0xfe, 0x00,     /* *******..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 69 (E) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xc0,     /* .*********.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x80,     /* ..**....*... */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x20,     /* ..**......*. */
+       0x30, 0x20,     /* ..**......*. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 70 (F) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xc0,     /* .*********.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x80,     /* ..**....*... */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x78, 0x00,     /* .****....... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 71 (G) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0xc0,     /* ....******.. */
+       0x10, 0x60,     /* ...*.....**. */
+       0x20, 0x20,     /* ..*.......*. */
+       0x20, 0x00,     /* ..*......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x61, 0xf0,     /* .**....***** */
+       0x60, 0x60,     /* .**......**. */
+       0x20, 0x60,     /* ..*......**. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x18, 0x60,     /* ...**....**. */
+       0x0f, 0x80,     /* ....*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 72 (H) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0xf0,     /* ****....**** */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x7f, 0xe0,     /* .**********. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0xf0, 0xf0,     /* ****....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 73 (I) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x80,     /* ...******... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 74 (J) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x80,     /* ...******... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x04, 0x00,     /* .....*...... */
+       0x38, 0x00,     /* ..***....... */
+       0x30, 0x00,     /* ..**........ */
+
+       /* 75 (K) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0xe0,     /* ****....***. */
+       0x61, 0x80,     /* .**....**... */
+       0x63, 0x00,     /* .**...**.... */
+       0x66, 0x00,     /* .**..**..... */
+       0x6c, 0x00,     /* .**.**...... */
+       0x78, 0x00,     /* .****....... */
+       0x78, 0x00,     /* .****....... */
+       0x7c, 0x00,     /* .*****...... */
+       0x6e, 0x00,     /* .**.***..... */
+       0x67, 0x00,     /* .**..***.... */
+       0x63, 0x80,     /* .**...***... */
+       0x61, 0xc0,     /* .**....***.. */
+       0x60, 0xe0,     /* .**.....***. */
+       0xf0, 0x70,     /* ****.....*** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 76 (L) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x78, 0x00,     /* .****....... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x20,     /* ..**......*. */
+       0x30, 0x20,     /* ..**......*. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 77 (M) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xe0, 0x70,     /* ***......*** */
+       0x60, 0xe0,     /* .**.....***. */
+       0x70, 0xe0,     /* .***....***. */
+       0x70, 0xe0,     /* .***....***. */
+       0x70, 0xe0,     /* .***....***. */
+       0x59, 0x60,     /* .*.**..*.**. */
+       0x59, 0x60,     /* .*.**..*.**. */
+       0x59, 0x60,     /* .*.**..*.**. */
+       0x4d, 0x60,     /* .*..**.*.**. */
+       0x4e, 0x60,     /* .*..***..**. */
+       0x4e, 0x60,     /* .*..***..**. */
+       0x44, 0x60,     /* .*...*...**. */
+       0x44, 0x60,     /* .*...*...**. */
+       0xe4, 0xf0,     /* ***..*..**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 78 (N) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xc0, 0x70,     /* **.......*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x20,     /* .***......*. */
+       0x78, 0x20,     /* .****.....*. */
+       0x58, 0x20,     /* .*.**.....*. */
+       0x4c, 0x20,     /* .*..**....*. */
+       0x46, 0x20,     /* .*...**...*. */
+       0x47, 0x20,     /* .*...***..*. */
+       0x43, 0x20,     /* .*....**..*. */
+       0x41, 0xa0,     /* .*.....**.*. */
+       0x40, 0xe0,     /* .*......***. */
+       0x40, 0xe0,     /* .*......***. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0x30,     /* ***.......** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 79 (O) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x60,     /* ..*......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 80 (P) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0x80,     /* .********... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x37, 0x80,     /* ..**.****... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x78, 0x00,     /* .****....... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 81 (Q) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x60,     /* ..*......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x38, 0x40,     /* ..***....*.. */
+       0x1f, 0x80,     /* ...******... */
+       0x0e, 0x00,     /* ....***..... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x23, 0x90,     /* ..*...***..* */
+       0x01, 0xe0,     /* .......****. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 82 (R) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0x00,     /* ********.... */
+       0x61, 0x80,     /* .**....**... */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0x80,     /* .**.....*... */
+       0x7f, 0x00,     /* .*******.... */
+       0x7c, 0x00,     /* .*****...... */
+       0x6e, 0x00,     /* .**.***..... */
+       0x67, 0x00,     /* .**..***.... */
+       0x63, 0x80,     /* .**...***... */
+       0x61, 0xc0,     /* .**....***.. */
+       0x60, 0xe0,     /* .**.....***. */
+       0xf0, 0x70,     /* ****.....*** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 83 (S) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0xe0,     /* ...********. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x00,     /* .***........ */
+       0x3c, 0x00,     /* ..****...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x07, 0x80,     /* .....****... */
+       0x01, 0xc0,     /* .......***.. */
+       0x00, 0xe0,     /* ........***. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x7f, 0x80,     /* .********... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 84 (T) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x46, 0x20,     /* .*...**...*. */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 85 (U) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 86 (V) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xe0, 0xe0,     /* ***.....***. */
+       0x60, 0x40,     /* .**......*.. */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x80,     /* ..**....*... */
+       0x19, 0x00,     /* ...**..*.... */
+       0x19, 0x00,     /* ...**..*.... */
+       0x19, 0x00,     /* ...**..*.... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0e, 0x00,     /* ....***..... */
+       0x0e, 0x00,     /* ....***..... */
+       0x04, 0x00,     /* .....*...... */
+       0x04, 0x00,     /* .....*...... */
+       0x04, 0x00,     /* .....*...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 87 (W) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xfe, 0xf0,     /* *******.**** */
+       0x66, 0x20,     /* .**..**...*. */
+       0x66, 0x20,     /* .**..**...*. */
+       0x66, 0x20,     /* .**..**...*. */
+       0x76, 0x20,     /* .***.**...*. */
+       0x77, 0x40,     /* .***.***.*.. */
+       0x33, 0x40,     /* ..**..**.*.. */
+       0x37, 0x40,     /* ..**.***.*.. */
+       0x3b, 0xc0,     /* ..***.****.. */
+       0x3b, 0x80,     /* ..***.***... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 88 (X) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 89 (Y) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 90 (Z) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x3f, 0xe0,     /* ..*********. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x20,     /* ...**.....*. */
+       0x3f, 0xe0,     /* ..*********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 91 ([) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x07, 0xc0,     /* .....*****.. */
+       0x07, 0xc0,     /* .....*****.. */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x07, 0xc0,     /* .....*****.. */
+       0x07, 0xc0,     /* .....*****.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 92 (\) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x06, 0x00,     /* .....**..... */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 93 (]) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7c, 0x00,     /* .*****...... */
+       0x7c, 0x00,     /* .*****...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x7c, 0x00,     /* .*****...... */
+       0x7c, 0x00,     /* .*****...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 94 (^) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x04, 0x00,     /* .....*...... */
+       0x0e, 0x00,     /* ....***..... */
+       0x1b, 0x00,     /* ...**.**.... */
+       0x31, 0x80,     /* ..**...**... */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 95 (_) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0xe0,     /* ***********. */
+       0xff, 0xe0,     /* ***********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 96 (`) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x01, 0x00,     /* .......*.... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x07, 0x80,     /* .....****... */
+       0x07, 0x80,     /* .....****... */
+       0x03, 0x00,     /* ......**.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 97 (a) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x03, 0xc0,     /* ......****.. */
+       0x1c, 0xc0,     /* ...***..**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0xe0,     /* ...****.***. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 98 (b) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x20, 0x00,     /* ..*......... */
+       0x60, 0x00,     /* .**......... */
+       0xe0, 0x00,     /* ***......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x67, 0x80,     /* .**..****... */
+       0x6f, 0xc0,     /* .**.******.. */
+       0x70, 0xe0,     /* .***....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x60,     /* .***.....**. */
+       0x78, 0xc0,     /* .****...**.. */
+       0x4f, 0x80,     /* .*..*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 99 (c) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x80,     /* ...******... */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x70, 0x40,     /* .***.....*.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 100 (d) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0xe0,     /* ........***. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x0f, 0x60,     /* ....****.**. */
+       0x31, 0xe0,     /* ..**...****. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0xe0,     /* .***....***. */
+       0x39, 0x60,     /* ..***..*.**. */
+       0x1e, 0x70,     /* ...****..*** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 101 (e) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x7f, 0xe0,     /* .**********. */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x30, 0x00,     /* ..**........ */
+       0x18, 0x60,     /* ...**....**. */
+       0x0f, 0x80,     /* ....*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 102 (f) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x80,     /* ......***... */
+       0x04, 0xc0,     /* .....*..**.. */
+       0x04, 0xc0,     /* .....*..**.. */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x1f, 0x80,     /* ...******... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x1e, 0x00,     /* ...****..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 103 (g) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x20,     /* ...*****..*. */
+       0x31, 0xe0,     /* ..**...****. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x31, 0x80,     /* ..**...**... */
+       0x3f, 0x00,     /* ..******.... */
+       0x60, 0x00,     /* .**......... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x3f, 0xe0,     /* ..*********. */
+       0x20, 0x60,     /* ..*......**. */
+       0x40, 0x20,     /* .*........*. */
+       0x40, 0x20,     /* .*........*. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x3f, 0x80,     /* ..*******... */
+
+       /* 104 (h) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x10, 0x00,     /* ...*........ */
+       0x30, 0x00,     /* ..**........ */
+       0x70, 0x00,     /* .***........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x37, 0x80,     /* ..**.****... */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x79, 0xe0,     /* .****..****. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 105 (i) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 106 (j) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0xc0,     /* ......****.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x0e, 0x00,     /* ....***..... */
+
+       /* 107 (k) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x60, 0x00,     /* .**......... */
+       0xe0, 0x00,     /* ***......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x61, 0xc0,     /* .**....***.. */
+       0x63, 0x00,     /* .**...**.... */
+       0x66, 0x00,     /* .**..**..... */
+       0x7c, 0x00,     /* .*****...... */
+       0x78, 0x00,     /* .****....... */
+       0x7c, 0x00,     /* .*****...... */
+       0x6e, 0x00,     /* .**.***..... */
+       0x67, 0x00,     /* .**..***.... */
+       0x63, 0x80,     /* .**...***... */
+       0xf1, 0xe0,     /* ****...****. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 108 (l) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 109 (m) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xdd, 0xc0,     /* **.***.***.. */
+       0x6e, 0xe0,     /* .**.***.***. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0xef, 0x70,     /* ***.****.*** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 110 (n) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x27, 0x80,     /* ..*..****... */
+       0x79, 0xc0,     /* .****..***.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x79, 0xe0,     /* .****..****. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 111 (o) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 112 (p) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xef, 0x80,     /* ***.*****... */
+       0x71, 0xc0,     /* .***...***.. */
+       0x60, 0xe0,     /* .**.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x40,     /* .**......*.. */
+       0x70, 0x80,     /* .***....*... */
+       0x7f, 0x00,     /* .*******.... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0xf0, 0x00,     /* ****........ */
+
+       /* 113 (q) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x20,     /* ....****..*. */
+       0x11, 0xe0,     /* ...*...****. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x60,     /* .***.....**. */
+       0x38, 0xe0,     /* ..***...***. */
+       0x1f, 0xe0,     /* ...********. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0xf0,     /* ........**** */
+
+       /* 114 (r) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x73, 0x80,     /* .***..***... */
+       0x34, 0xc0,     /* ..**.*..**.. */
+       0x38, 0xc0,     /* ..***...**.. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x78, 0x00,     /* .****....... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 115 (s) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0xc0,     /* ...*******.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x38, 0x00,     /* ..***....... */
+       0x1e, 0x00,     /* ...****..... */
+       0x07, 0x80,     /* .....****... */
+       0x01, 0xc0,     /* .......***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x3f, 0x80,     /* ..*******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 116 (t) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x04, 0x00,     /* .....*...... */
+       0x04, 0x00,     /* .....*...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x20,     /* ....**....*. */
+       0x0e, 0x40,     /* ....***..*.. */
+       0x07, 0x80,     /* .....****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 117 (u) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x79, 0xe0,     /* .****..****. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0x60,     /* ...****..**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 118 (v) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 119 (w) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0x70,     /* ********.*** */
+       0x66, 0x20,     /* .**..**...*. */
+       0x66, 0x20,     /* .**..**...*. */
+       0x66, 0x20,     /* .**..**...*. */
+       0x37, 0x40,     /* ..**.***.*.. */
+       0x3b, 0x40,     /* ..***.**.*.. */
+       0x3b, 0x40,     /* ..***.**.*.. */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 120 (x) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf8, 0xf0,     /* *****...**** */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1d, 0x00,     /* ...***.*.... */
+       0x0e, 0x00,     /* ....***..... */
+       0x07, 0x00,     /* .....***.... */
+       0x0b, 0x80,     /* ....*.***... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0xf1, 0xf0,     /* ****...***** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 121 (y) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0xf0,     /* ****....**** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x04, 0x00,     /* .....*...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x08, 0x00,     /* ....*....... */
+       0x78, 0x00,     /* .****....... */
+       0x70, 0x00,     /* .***........ */
+
+       /* 122 (z) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x60, 0xe0,     /* .**.....***. */
+       0x41, 0xc0,     /* .*.....***.. */
+       0x03, 0x80,     /* ......***... */
+       0x07, 0x00,     /* .....***.... */
+       0x0e, 0x00,     /* ....***..... */
+       0x1c, 0x00,     /* ...***...... */
+       0x38, 0x20,     /* ..***.....*. */
+       0x70, 0x60,     /* .***.....**. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 123 ({) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x01, 0xc0,     /* .......***.. */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x00,     /* ......**.... */
+       0x07, 0x00,     /* .....***.... */
+       0x03, 0x00,     /* ......**.... */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x01, 0x80,     /* .......**... */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x01, 0xc0,     /* .......***.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 124 (|) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 125 (}) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x38, 0x00,     /* ..***....... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0e, 0x00,     /* ....***..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x0c, 0x00,     /* ....**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x38, 0x00,     /* ..***....... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 126 (~) */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1c, 0x20,     /* ...***....*. */
+       0x3e, 0x60,     /* ..*****..**. */
+       0x36, 0xc0,     /* ..**.**.**.. */
+       0x67, 0xc0,     /* .**..*****.. */
+       0x43, 0x80,     /* .*....***... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 127 */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+       0xaa, 0xa0,     /* *.*.*.*.*.*. */
+       0x55, 0x50,     /* .*.*.*.*.*.* */
+
+       /* 128 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 129 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 130 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 131 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 132 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 133 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 134 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 135 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 136 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 137 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 138 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 139 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 140 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 141 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 142 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 143 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 144 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 145 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 146 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 147 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 148 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 149 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 150 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 151 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 152 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 153 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 154 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 155 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 156 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 157 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 158 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 159 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 160 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 161 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 162 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x01, 0x00,     /* .......*.... */
+       0x01, 0x00,     /* .......*.... */
+       0x03, 0x00,     /* ......**.... */
+       0x02, 0x00,     /* ......*..... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x37, 0x80,     /* ..**.****... */
+       0x25, 0x80,     /* ..*..*.**... */
+       0x64, 0x00,     /* .**..*...... */
+       0x6c, 0x00,     /* .**.**...... */
+       0x68, 0x00,     /* .**.*....... */
+       0x78, 0x80,     /* .****...*... */
+       0x39, 0x80,     /* ..***..**... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x10, 0x00,     /* ...*........ */
+       0x30, 0x00,     /* ..**........ */
+       0x20, 0x00,     /* ..*......... */
+       0x20, 0x00,     /* ..*......... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 163 */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x10, 0x00,     /* ...*........ */
+       0x10, 0x00,     /* ...*........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x3e, 0x00,     /* ..*****..... */
+       0x7c, 0x00,     /* .*****...... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x00,     /* ...**....... */
+       0x3f, 0x20,     /* ..******..*. */
+       0x3f, 0xe0,     /* ..*********. */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 164 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x60, 0x20,     /* .**.......*. */
+       0x77, 0x40,     /* .***.***.*.. */
+       0x3b, 0x80,     /* ..***.***... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1d, 0xc0,     /* ...***.***.. */
+       0x2e, 0xe0,     /* ..*.***.***. */
+       0x40, 0x60,     /* .*.......**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 165 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x06, 0x00,     /* .....**..... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 166 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+
+       /* 167 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0xe0,     /* ....*******. */
+       0x18, 0x60,     /* ...**....**. */
+       0x30, 0x20,     /* ..**......*. */
+       0x38, 0x20,     /* ..***.....*. */
+       0x1e, 0x00,     /* ...****..... */
+       0x1f, 0x80,     /* ...******... */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x60, 0xe0,     /* .**.....***. */
+       0x70, 0x60,     /* .***.....**. */
+       0x38, 0xc0,     /* ..***...**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x07, 0x80,     /* .....****... */
+       0x41, 0xc0,     /* .*.....***.. */
+       0x40, 0xc0,     /* .*......**.. */
+       0x61, 0x80,     /* .**....**... */
+       0x7f, 0x00,     /* .*******.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 168 */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 169 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x10, 0x80,     /* ...*....*... */
+       0x20, 0x40,     /* ..*......*.. */
+       0x2f, 0x40,     /* ..*.****.*.. */
+       0x59, 0xa0,     /* .*.**..**.*. */
+       0x59, 0xa0,     /* .*.**..**.*. */
+       0x58, 0x20,     /* .*.**.....*. */
+       0x58, 0x20,     /* .*.**.....*. */
+       0x59, 0xa0,     /* .*.**..**.*. */
+       0x59, 0xa0,     /* .*.**..**.*. */
+       0x2f, 0x40,     /* ..*.****.*.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x10, 0x80,     /* ...*....*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 170 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0e, 0x00,     /* ....***..... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x13, 0x80,     /* ...*..***... */
+       0x0f, 0x80,     /* ....*****... */
+       0x19, 0x80,     /* ...**..**... */
+       0x31, 0x80,     /* ..**...**... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x1e, 0xc0,     /* ...****.**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x3f, 0xe0,     /* ..*********. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 171 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x02, 0x20,     /* ......*...*. */
+       0x04, 0x40,     /* .....*...*.. */
+       0x08, 0x80,     /* ....*...*... */
+       0x11, 0x00,     /* ...*...*.... */
+       0x33, 0x00,     /* ..**..**.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x06, 0x60,     /* .....**..**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 172 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x60,     /* .........**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 173 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x80,     /* ...******... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 174 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x10, 0x80,     /* ...*....*... */
+       0x20, 0x40,     /* ..*......*.. */
+       0x3f, 0x40,     /* ..******.*.. */
+       0x59, 0xa0,     /* .*.**..**.*. */
+       0x59, 0xa0,     /* .*.**..**.*. */
+       0x5f, 0xa0,     /* .*.******.*. */
+       0x5b, 0x20,     /* .*.**.**..*. */
+       0x5b, 0x20,     /* .*.**.**..*. */
+       0x59, 0xa0,     /* .*.**..**.*. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x10, 0x80,     /* ...*....*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 175 */
+       0x3f, 0xc0,     /* ..********.. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 176 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0e, 0x00,     /* ....***..... */
+       0x17, 0x00,     /* ...*.***.... */
+       0x23, 0x80,     /* ..*...***... */
+       0x61, 0x80,     /* .**....**... */
+       0x61, 0x80,     /* .**....**... */
+       0x71, 0x00,     /* .***...*.... */
+       0x3a, 0x00,     /* ..***.*..... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 177 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 178 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0e, 0x00,     /* ....***..... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x13, 0x00,     /* ...*..**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 179 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0e, 0x00,     /* ....***..... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x13, 0x00,     /* ...*..**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x03, 0x00,     /* ......**.... */
+       0x13, 0x00,     /* ...*..**.... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x0e, 0x00,     /* ....***..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 180 */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 181 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x79, 0xe0,     /* .****..****. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x3e, 0x60,     /* ..*****..**. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x60, 0x00,     /* .**......... */
+
+       /* 182 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0xc0,     /* ...*******.. */
+       0x3e, 0xc0,     /* ..*****.**.. */
+       0x7e, 0xc0,     /* .******.**.. */
+       0x7e, 0xc0,     /* .******.**.. */
+       0x7e, 0xc0,     /* .******.**.. */
+       0x3e, 0xc0,     /* ..*****.**.. */
+       0x1e, 0xc0,     /* ...****.**.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 183 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x0f, 0x00,     /* ....****.... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 184 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x02, 0x00,     /* ......*..... */
+       0x03, 0x00,     /* ......**.... */
+       0x01, 0x80,     /* .......**... */
+       0x09, 0x80,     /* ....*..**... */
+       0x07, 0x00,     /* .....***.... */
+
+       /* 185 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0e, 0x00,     /* ....***..... */
+       0x0e, 0x00,     /* ....***..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 186 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x07, 0x00,     /* .....***.... */
+       0x0b, 0x80,     /* ....*.***... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1d, 0x00,     /* ...***.*.... */
+       0x0e, 0x00,     /* ....***..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x3f, 0xe0,     /* ..*********. */
+       0x7f, 0xc0,     /* .*********.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 187 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x66, 0x00,     /* .**..**..... */
+       0x33, 0x00,     /* ..**..**.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x08, 0x80,     /* ....*...*... */
+       0x11, 0x00,     /* ...*...*.... */
+       0x22, 0x00,     /* ..*...*..... */
+       0x44, 0x00,     /* .*...*...... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 188 */
+       0x00, 0x00,     /* ............ */
+       0x18, 0x00,     /* ...**....... */
+       0x38, 0x00,     /* ..***....... */
+       0x38, 0x00,     /* ..***....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x20,     /* ...**.....*. */
+       0x18, 0x60,     /* ...**....**. */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x19, 0x80,     /* ...**..**... */
+       0x3f, 0x40,     /* ..******.*.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x0d, 0xc0,     /* ....**.***.. */
+       0x19, 0xc0,     /* ...**..***.. */
+       0x32, 0xc0,     /* ..**..*.**.. */
+       0x64, 0xc0,     /* .**..*..**.. */
+       0x47, 0xe0,     /* .*...******. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 189 */
+       0x00, 0x00,     /* ............ */
+       0x18, 0x00,     /* ...**....... */
+       0x38, 0x00,     /* ..***....... */
+       0x38, 0x00,     /* ..***....... */
+       0x18, 0x00,     /* ...**....... */
+       0x18, 0x20,     /* ...**.....*. */
+       0x18, 0x60,     /* ...**....**. */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x19, 0x80,     /* ...**..**... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x07, 0xe0,     /* .....******. */
+       0x0f, 0x60,     /* ....****.**. */
+       0x1a, 0x60,     /* ...**.*..**. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x61, 0x80,     /* .**....**... */
+       0x43, 0x00,     /* .*....**.... */
+       0x03, 0xe0,     /* ......*****. */
+       0x03, 0xe0,     /* ......*****. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 190 */
+       0x00, 0x00,     /* ............ */
+       0x38, 0x00,     /* ..***....... */
+       0x7c, 0x00,     /* .*****...... */
+       0x4c, 0x00,     /* .*..**...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x20,     /* ...**.....*. */
+       0x0c, 0x60,     /* ....**...**. */
+       0x4c, 0xc0,     /* .*..**..**.. */
+       0x7d, 0x80,     /* .*****.**... */
+       0x3b, 0x40,     /* ..***.**.*.. */
+       0x06, 0xc0,     /* .....**.**.. */
+       0x0d, 0xc0,     /* ....**.***.. */
+       0x19, 0xc0,     /* ...**..***.. */
+       0x32, 0xc0,     /* ..**..*.**.. */
+       0x64, 0xc0,     /* .**..*..**.. */
+       0x47, 0xe0,     /* .*...******. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0xc0,     /* ........**.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 191 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x00,     /* ......**.... */
+       0x03, 0x00,     /* ......**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0c, 0x00,     /* ....**...... */
+       0x18, 0x00,     /* ...**....... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1f, 0x80,     /* ...******... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 192 */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x09, 0x00,     /* ....*..*.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0x80,     /* ...*....*... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 193 */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x09, 0x00,     /* ....*..*.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0x80,     /* ...*....*... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 194 */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x09, 0x00,     /* ....*..*.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0x80,     /* ...*....*... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 195 */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x33, 0x00,     /* ..**..**.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x09, 0x00,     /* ....*..*.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0x80,     /* ...*....*... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 196 */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x09, 0x00,     /* ....*..*.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0x80,     /* ...*....*... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 197 */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x0f, 0x00,     /* ....****.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x0b, 0x00,     /* ....*.**.... */
+       0x09, 0x00,     /* ....*..*.... */
+       0x11, 0x80,     /* ...*...**... */
+       0x11, 0x80,     /* ...*...**... */
+       0x10, 0x80,     /* ...*....*... */
+       0x3f, 0xc0,     /* ..********.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x40, 0x60,     /* .*.......**. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0xf0,     /* ***.....**** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 198 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0xe0,     /* ....*******. */
+       0x0e, 0x20,     /* ....***...*. */
+       0x16, 0x20,     /* ...*.**...*. */
+       0x16, 0x00,     /* ...*.**..... */
+       0x16, 0x00,     /* ...*.**..... */
+       0x16, 0x40,     /* ...*.**..*.. */
+       0x27, 0xc0,     /* ..*..*****.. */
+       0x26, 0x40,     /* ..*..**..*.. */
+       0x3e, 0x00,     /* ..*****..... */
+       0x26, 0x00,     /* ..*..**..... */
+       0x46, 0x00,     /* .*...**..... */
+       0x46, 0x10,     /* .*...**....* */
+       0x46, 0x10,     /* .*...**....* */
+       0xe7, 0xf0,     /* ***..******* */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 199 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0xc0,     /* ....******.. */
+       0x10, 0x60,     /* ...*.....**. */
+       0x20, 0x20,     /* ..*.......*. */
+       0x20, 0x00,     /* ..*......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x20, 0x00,     /* ..*......... */
+       0x30, 0x20,     /* ..**......*. */
+       0x18, 0x40,     /* ...**....*.. */
+       0x0f, 0x80,     /* ....*****... */
+       0x02, 0x00,     /* ......*..... */
+       0x03, 0x00,     /* ......**.... */
+       0x01, 0x80,     /* .......**... */
+       0x09, 0x80,     /* ....*..**... */
+       0x07, 0x00,     /* .....***.... */
+
+       /* 200 */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x80,     /* ..**....*... */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x20,     /* ..**......*. */
+       0x30, 0x20,     /* ..**......*. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 201 */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x80,     /* ..**....*... */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x20,     /* ..**......*. */
+       0x30, 0x20,     /* ..**......*. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 202 */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x7f, 0xc0,     /* .*********.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x80,     /* ..**....*... */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x20,     /* ..**......*. */
+       0x30, 0x20,     /* ..**......*. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 203 */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xc0,     /* .*********.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x80,     /* ..**....*... */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0x80,     /* ..**....*... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x20,     /* ..**......*. */
+       0x30, 0x20,     /* ..**......*. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 204 */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x1f, 0x80,     /* ...******... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 205 */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x1f, 0x80,     /* ...******... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 206 */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x1f, 0x80,     /* ...******... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 207 */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x80,     /* ...******... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 208 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xff, 0x00,     /* ********.... */
+       0x61, 0xc0,     /* .**....***.. */
+       0x60, 0xc0,     /* .**.....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0xf8, 0x60,     /* *****....**. */
+       0xf8, 0x60,     /* *****....**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x40,     /* .**......*.. */
+       0x61, 0x80,     /* .**....**... */
+       0xfe, 0x00,     /* *******..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 209 */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x33, 0x00,     /* ..**..**.... */
+       0xc0, 0x70,     /* **.......*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x20,     /* .***......*. */
+       0x78, 0x20,     /* .****.....*. */
+       0x58, 0x20,     /* .*.**.....*. */
+       0x4c, 0x20,     /* .*..**....*. */
+       0x46, 0x20,     /* .*...**...*. */
+       0x47, 0x20,     /* .*...***..*. */
+       0x43, 0x20,     /* .*....**..*. */
+       0x41, 0xa0,     /* .*.....**.*. */
+       0x40, 0xe0,     /* .*......***. */
+       0x40, 0xe0,     /* .*......***. */
+       0x40, 0x60,     /* .*.......**. */
+       0xe0, 0x30,     /* ***.......** */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 210 */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x60,     /* ..*......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 211 */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x60,     /* ..*......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 212 */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x60,     /* ..*......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 213 */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x33, 0x00,     /* ..**..**.... */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x60,     /* ..*......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 214 */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x20, 0x60,     /* ..*......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x20, 0x40,     /* ..*......*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 215 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x60, 0x60,     /* .**......**. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x19, 0x80,     /* ...**..**... */
+       0x0f, 0x00,     /* ....****.... */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 216 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x60,     /* .........**. */
+       0x0f, 0xc0,     /* ....******.. */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x21, 0xc0,     /* ..*....***.. */
+       0x21, 0xe0,     /* ..*....****. */
+       0x63, 0x60,     /* .**...**.**. */
+       0x63, 0x60,     /* .**...**.**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x6c, 0x60,     /* .**.**...**. */
+       0x6c, 0x60,     /* .**.**...**. */
+       0x78, 0x60,     /* .****....**. */
+       0x38, 0x40,     /* ..***....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x6f, 0x00,     /* .**.****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 217 */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 218 */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 219 */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 220 */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x60, 0x20,     /* .**.......*. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 221 */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0xf0, 0x70,     /* ****.....*** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 222 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x78, 0x00,     /* .****....... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x30, 0x60,     /* ..**.....**. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x3f, 0x80,     /* ..*******... */
+       0x30, 0x00,     /* ..**........ */
+       0x30, 0x00,     /* ..**........ */
+       0x78, 0x00,     /* .****....... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 223 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x31, 0x80,     /* ..**...**... */
+       0x31, 0x80,     /* ..**...**... */
+       0x33, 0x80,     /* ..**..***... */
+       0x36, 0x00,     /* ..**.**..... */
+       0x36, 0x00,     /* ..**.**..... */
+       0x36, 0x00,     /* ..**.**..... */
+       0x33, 0x80,     /* ..**..***... */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x30, 0xe0,     /* ..**....***. */
+       0x34, 0x60,     /* ..**.*...**. */
+       0x36, 0x60,     /* ..**.**..**. */
+       0x77, 0xc0,     /* .***.*****.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 224 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x03, 0xc0,     /* ......****.. */
+       0x1c, 0xc0,     /* ...***..**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0xe0,     /* ...****.***. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 225 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x03, 0xc0,     /* ......****.. */
+       0x1c, 0xc0,     /* ...***..**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0xe0,     /* ...****.***. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 226 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x03, 0xc0,     /* ......****.. */
+       0x1c, 0xc0,     /* ...***..**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0xe0,     /* ...****.***. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 227 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x33, 0x00,     /* ..**..**.... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x03, 0xc0,     /* ......****.. */
+       0x1c, 0xc0,     /* ...***..**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0xe0,     /* ...****.***. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 228 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x03, 0xc0,     /* ......****.. */
+       0x1c, 0xc0,     /* ...***..**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0xe0,     /* ...****.***. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 229 */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x0f, 0x00,     /* ....****.... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x18, 0xc0,     /* ...**...**.. */
+       0x10, 0xc0,     /* ...*....**.. */
+       0x03, 0xc0,     /* ......****.. */
+       0x1c, 0xc0,     /* ...***..**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0xe0,     /* ...****.***. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 230 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x80,     /* ...******... */
+       0x36, 0x40,     /* ..**.**..*.. */
+       0x26, 0x60,     /* ..*..**..**. */
+       0x0e, 0x60,     /* ....***..**. */
+       0x3f, 0xe0,     /* ..*********. */
+       0x66, 0x00,     /* .**..**..... */
+       0x66, 0x00,     /* .**..**..... */
+       0x66, 0x00,     /* .**..**..... */
+       0x67, 0x60,     /* .**..***.**. */
+       0x3f, 0xc0,     /* ..********.. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 231 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1f, 0x80,     /* ...******... */
+       0x31, 0xc0,     /* ..**...***.. */
+       0x20, 0xc0,     /* ..*.....**.. */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x70, 0x40,     /* .***.....*.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x02, 0x00,     /* ......*..... */
+       0x03, 0x00,     /* ......**.... */
+       0x01, 0x80,     /* .......**... */
+       0x09, 0x80,     /* ....*..**... */
+       0x07, 0x00,     /* .....***.... */
+
+       /* 232 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x7f, 0xe0,     /* .**********. */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x30, 0x00,     /* ..**........ */
+       0x18, 0x60,     /* ...**....**. */
+       0x0f, 0x80,     /* ....*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 233 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x7f, 0xe0,     /* .**********. */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x30, 0x00,     /* ..**........ */
+       0x18, 0x60,     /* ...**....**. */
+       0x0f, 0x80,     /* ....*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 234 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x7f, 0xe0,     /* .**********. */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x30, 0x00,     /* ..**........ */
+       0x18, 0x60,     /* ...**....**. */
+       0x0f, 0x80,     /* ....*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 235 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x00,     /* ....****.... */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x7f, 0xe0,     /* .**********. */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x30, 0x00,     /* ..**........ */
+       0x18, 0x60,     /* ...**....**. */
+       0x0f, 0x80,     /* ....*****... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 236 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x00, 0x00,     /* ............ */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 237 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 238 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 239 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1e, 0x00,     /* ...****..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x80,     /* ...******... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 240 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x06, 0x00,     /* .....**..... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x31, 0x80,     /* ..**...**... */
+       0x01, 0xc0,     /* .......***.. */
+       0x0f, 0xc0,     /* ....******.. */
+       0x10, 0xe0,     /* ...*....***. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 241 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x33, 0x00,     /* ..**..**.... */
+       0x00, 0x00,     /* ............ */
+       0x27, 0x80,     /* ..*..****... */
+       0x79, 0xc0,     /* .****..***.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x79, 0xe0,     /* .****..****. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 242 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 243 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 244 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 245 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0c, 0xc0,     /* ....**..**.. */
+       0x1f, 0x80,     /* ...******... */
+       0x33, 0x00,     /* ..**..**.... */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 246 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0x80,     /* ....*****... */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x20, 0xe0,     /* ..*.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x70, 0x40,     /* .***.....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x1f, 0x00,     /* ...*****.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 247 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x7f, 0xe0,     /* .**********. */
+       0x7f, 0xe0,     /* .**********. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 248 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x0f, 0xe0,     /* ....*******. */
+       0x11, 0xc0,     /* ...*...***.. */
+       0x21, 0xe0,     /* ..*....****. */
+       0x63, 0x60,     /* .**...**.**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x66, 0x60,     /* .**..**..**. */
+       0x6c, 0x60,     /* .**.**...**. */
+       0x78, 0x40,     /* .****....*.. */
+       0x38, 0x80,     /* ..***...*... */
+       0x7f, 0x00,     /* .*******.... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 249 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x1c, 0x00,     /* ...***...... */
+       0x0f, 0x00,     /* ....****.... */
+       0x03, 0x80,     /* ......***... */
+       0x00, 0x00,     /* ............ */
+       0x79, 0xe0,     /* .****..****. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0x60,     /* ...****..**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 250 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0x79, 0xe0,     /* .****..****. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0x60,     /* ...****..**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 251 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x06, 0x00,     /* .....**..... */
+       0x0f, 0x00,     /* ....****.... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x79, 0xe0,     /* .****..****. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0x60,     /* ...****..**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 252 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x79, 0xe0,     /* .****..****. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x30, 0xc0,     /* ..**....**.. */
+       0x39, 0xc0,     /* ..***..***.. */
+       0x1e, 0x60,     /* ...****..**. */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+
+       /* 253 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x03, 0x80,     /* ......***... */
+       0x0f, 0x00,     /* ....****.... */
+       0x1c, 0x00,     /* ...***...... */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0xf0,     /* ****....**** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x04, 0x00,     /* .....*...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x08, 0x00,     /* ....*....... */
+       0x78, 0x00,     /* .****....... */
+       0x70, 0x00,     /* .***........ */
+
+       /* 254 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xe0, 0x00,     /* ***......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x6f, 0x80,     /* .**.*****... */
+       0x71, 0xc0,     /* .***...***.. */
+       0x60, 0xe0,     /* .**.....***. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x60,     /* .**......**. */
+       0x60, 0x40,     /* .**......*.. */
+       0x70, 0x80,     /* .***....*... */
+       0x7f, 0x00,     /* .*******.... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0x60, 0x00,     /* .**......... */
+       0xf0, 0x00,     /* ****........ */
+
+       /* 255 */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0x19, 0x80,     /* ...**..**... */
+       0x19, 0x80,     /* ...**..**... */
+       0x00, 0x00,     /* ............ */
+       0x00, 0x00,     /* ............ */
+       0xf0, 0xf0,     /* ****....**** */
+       0x60, 0x20,     /* .**.......*. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x30, 0x40,     /* ..**.....*.. */
+       0x18, 0x80,     /* ...**...*... */
+       0x18, 0x80,     /* ...**...*... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x0d, 0x00,     /* ....**.*.... */
+       0x06, 0x00,     /* .....**..... */
+       0x06, 0x00,     /* .....**..... */
+       0x04, 0x00,     /* .....*...... */
+       0x0c, 0x00,     /* ....**...... */
+       0x08, 0x00,     /* ....*....... */
+       0x78, 0x00,     /* .****....... */
+       0x70, 0x00,     /* .***........ */
+};
index d6b7dc939b54b4c27a5049c238cada2837c6c00d..08e0f0711f860edbd5db6786a2befc50ba5de178 100644 (file)
@@ -10,7 +10,7 @@ VPATH         = @srcdir@
 top_srcdir     = @top_srcdir@
 top_builddir   = ..
 
-install_prefix =
+DESTDIR                =
 prefix         = @prefix@
 exec_prefix    = @exec_prefix@
 bindir         = @bindir@
@@ -88,7 +88,7 @@ UTILDIR_OBJS  = $(UTILS_BIN)/colors.o $(UTILS_BIN)/grabclient.o \
                  $(UTILS_BIN)/textclient.o $(UTILS_BIN)/async_netdb.o \
                  $(UTILS_BIN)/aligned_malloc.o $(UTILS_BIN)/thread_util.o \
                  $(UTILS_BIN)/spline.o $(UTILS_BIN)/pow2.o \
-                 $(UTILS_BIN)/font-retry.o
+                 $(UTILS_BIN)/font-retry.o $(UTILS_BIN)/easing.o
 JWXYZ_OBJS     = $(JWXYZ_BIN)/jwzgles.o
 HACKDIR_OBJS   = $(HACK_BIN)/screenhack.o $(HACK_BIN)/xlockmore.o \
                  $(HACK_BIN)/fps.o $(HACK_BIN)/ximage-loader.o \
@@ -242,8 +242,10 @@ JWZGLES_OBJS       = @JWZGLES_OBJS@
 HACK_EXES_1    = @GL_EXES@ @GLE_EXES@
 HACK_EXES      = $(HACK_EXES_1) @SUID_EXES@
 XSHM_OBJS      = $(UTILS_BIN)/xshm.o $(UTILS_BIN)/aligned_malloc.o
+DT             = $(UTILS_BIN)/doubletime.o
 GRAB_OBJS      = $(UTILS_BIN)/grabclient.o grab-ximage.o $(XSHM_OBJS)
 ANIM_OBJS      = recanim-gl.o $(HACK_BIN)/ffmpeg-out.o
+
 EXES           = @GL_UTIL_EXES@ $(HACK_EXES)
 
 RETIRED_EXES   = @RETIRED_GL_EXES@
@@ -265,6 +267,7 @@ HACK_OBJS   = $(HACK_BIN)/screenhack.o $(HACK_BIN)/xlockmore.o \
                  $(UTILS_BIN)/usleep.o \
                  $(UTILS_BIN)/xmu.o \
                  $(UTILS_BIN)/yarandom.o \
+                 $(UTILS_BIN)/doubletime.o \
                  $(FPS_OBJS) $(JWZGLES_OBJS) $(HACK_GLSL_OBJS) @ANIM_OBJS@
 
 HDRS           = atlantis.h bubble3d.h buildlwo.h e_textures.h \
@@ -339,7 +342,7 @@ install-strip:
 # the hacks, in $HACKDIR
 install-program:: $(EXES)
        @exes="$(HACK_EXES_1) @GL_UTIL_EXES@" ;                         \
-        idir="$(install_prefix)$(HACKDIR)" ;                           \
+        idir="$(DESTDIR)$(HACKDIR)" ;                                  \
         if ( echo $$exes | grep -q . ); then                           \
           if [ ! -d $$idir ]; then                                     \
             $(INSTALL_DIRS) $$idir ;                                   \
@@ -393,8 +396,8 @@ install-program:: $(EXES)
 install-scripts: $(SCRIPTS) munge-scripts
        @                                                               \
        if ! ( echo $(HACK_EXES_1) | grep -q . ); then exit 0 ; fi ;    \
-       if [ ! -d $(install_prefix)$(HACKDIR) ]; then                   \
-         $(INSTALL_DIRS) $(install_prefix)$(HACKDIR) ;                 \
+       if [ ! -d $(DESTDIR)$(HACKDIR) ]; then                          \
+         $(INSTALL_DIRS) $(DESTDIR)$(HACKDIR) ;                        \
         fi ;                                                           \
        for program in $(SCRIPTS); do                                   \
          if [ -r $$program ] ; then                                    \
@@ -403,9 +406,9 @@ install-scripts: $(SCRIPTS) munge-scripts
            p=$(srcdir)/$$program ;                                     \
          fi ;                                                          \
          echo $(INSTALL_SCRIPT) $$p                                    \
-           $(install_prefix)$(HACKDIR)/$$program ;                     \
+           $(DESTDIR)$(HACKDIR)/$$program ;                            \
          $(INSTALL_SCRIPT) $$p                                         \
-           $(install_prefix)$(HACKDIR)/$$program ;                     \
+           $(DESTDIR)$(HACKDIR)/$$program ;                            \
        done
 
 munge-scripts: $(SCRIPTS)
@@ -439,8 +442,8 @@ install-man: $(MEN)
        if ! ( echo $(HACK_EXES_1) | grep -q . ); then exit 0 ; fi ;    \
        echo "installing man pages: $$TH" ;                             \
                                                                        \
-       if [ ! -d $(install_prefix)$(manNdir) ]; then                   \
-         $(INSTALL_DIRS) $(install_prefix)$(manNdir) ;                 \
+       if [ ! -d $(DESTDIR)$(manNdir) ]; then                          \
+         $(INSTALL_DIRS) $(DESTDIR)$(manNdir) ;                        \
         fi ;                                                           \
                                                                        \
        for man in $$men; do                                            \
@@ -451,14 +454,14 @@ install-man: $(MEN)
              -e 's@(MANSUFFIX)@($(mansuffix))@g'                       \
            < $(srcdir)/$$man > $$T ;                                   \
          echo $(INSTALL_DATA) $(srcdir)/$$man                          \
-          $(install_prefix)$(manNdir)/$$instname ;                     \
+          $(DESTDIR)$(manNdir)/$$instname ;                            \
          $(INSTALL_DATA) $$T                                           \
-           $(install_prefix)$(manNdir)/$$instname ;                    \
+           $(DESTDIR)$(manNdir)/$$instname ;                           \
        done ;                                                          \
        rm -f $$T
 
 install-xml:
-       @dest=$(install_prefix)$(HACK_CONF_DIR) ;                       \
+       @dest=$(DESTDIR)$(HACK_CONF_DIR) ;                              \
         if [ ! -d $$dest ]; then                                       \
           $(INSTALL_DIRS) $$dest ;                                     \
         fi ;                                                           \
@@ -473,7 +476,7 @@ install-xml:
 # the hacks, in $HACKDIR
 uninstall-program::
        @exes="$(HACK_EXES) $(RETIRED_EXES) $(SCRIPTS) @GL_UTIL_EXES@" ;\
-        idir="$(install_prefix)$(HACKDIR)" ;                           \
+        idir="$(DESTDIR)$(HACKDIR)" ;                                  \
         for program in $$exes; do                                      \
           echo rm -f $$idir/$$program ;                                \
                rm -f $$idir/$$program ;                                \
@@ -481,18 +484,18 @@ uninstall-program::
 
 # $HACKDIR/xscreensaver-gl-visual used to be $bindir/xscreensaver-gl-helper
 uninstall-program::
-       rm -f $(install_prefix)$(bindir)/xscreensaver-gl-helper
+       rm -f $(DESTDIR)$(bindir)/xscreensaver-gl-helper
 
 uninstall-man:
        @men="$(MEN) $(RETIRED_MEN)" ;                                  \
        for man in $$men; do                                            \
          instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ;     \
-         echo rm -f $(install_prefix)$(manNdir)/$$instname* ;          \
-              rm -f $(install_prefix)$(manNdir)/$$instname* ;          \
+         echo rm -f $(DESTDIR)$(manNdir)/$$instname* ;                 \
+              rm -f $(DESTDIR)$(manNdir)/$$instname* ;                 \
        done
 
 uninstall-xml:
-       @dest=$(install_prefix)$(HACK_CONF_DIR) ;                       \
+       @dest=$(DESTDIR)$(HACK_CONF_DIR) ;                              \
         for file in $(EXES) $(RETIRED_EXES) $(SCRIPTS) ; do            \
             echo rm -f $$dest/$$file.xml ;                             \
                  rm -f $$dest/$$file.xml ;                             \
@@ -595,6 +598,7 @@ $(UTILS_BIN)/thread_util.o: $(UTILS_SRC)/thread_util.c
 $(UTILS_BIN)/spline.o:         $(UTILS_SRC)/spline.c
 $(UTILS_BIN)/pow2.o:           $(UTILS_SRC)/pow2.c
 $(UTILS_BIN)/font-retry.o:     $(UTILS_SRC)/font-retry.c
+$(UTILS_BIN)/easing.o:         $(UTILS_SRC)/easing.c
 $(HACK_BIN)/screenhack.o:      $(HACK_SRC)/screenhack.c
 $(HACK_BIN)/xlockmore.o:       $(HACK_SRC)/xlockmore.c
 $(HACK_BIN)/fps.o:             $(HACK_SRC)/fps.c
@@ -713,7 +717,7 @@ PLANET_OBJS=sphere.o gllist.o timezones.o $(PNG) $(HACK_TRACK_OBJS)
 glplanet:      glplanet.o      $(PLANET_OBJS)
        $(CC_HACK) -o $@ $@.o   $(PLANET_OBJS) $(PNG_LIBS)
 
-DYMAXIOBJS=dymaxionmap-coords.o normals.o $(PLANET_OBJS)
+DYMAXIOBJS=dymaxionmap-coords.o normals.o $(EASE) $(PLANET_OBJS)
 dymaxionmap:   dymaxionmap.o   $(DYMAXIOBJS)
        $(CC_HACK) -o $@ $@.o   $(DYMAXIOBJS) $(PNG_LIBS)
 
@@ -782,8 +786,8 @@ lavalite:   lavalite.o      $(LL_OBJS)
 queens:                queens.o        chessmodels.o $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   chessmodels.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-endgame:       endgame.o       chessmodels.o $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o   chessmodels.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
+endgame:       endgame.o       chessmodels.o $(EASE) $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   chessmodels.o $(EASE) $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
 glblur:        glblur.o                $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
@@ -833,8 +837,10 @@ vigilance:                 $(CAM_OBJS)
 seccam_dxf::
        ./dxf2gl.pl --smooth --layers seccam.dxf seccam.c
 
-glslideshow:   glslideshow.o   $(HACK_GRAB_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(HACK_GRAB_OBJS) $(HACK_LIBS)
+EASE = $(UTILS_BIN)/easing.o
+SLIDE_OBJS = $(HACK_GRAB_OBJS) $(EASE)
+glslideshow:   glslideshow.o   $(SLIDE_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(SLIDE_OBJS) $(HACK_LIBS)
 
 jigglypuff:    jigglypuff.o    $(PNG) $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(PNG) $(HACK_TRACK_OBJS) $(PNG_LIBS)
@@ -928,8 +934,8 @@ moebiusgears:       moebiusgears.o  $(GEARS_OBJS)
 boing:         boing.o         normals.o $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   normals.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-carousel:      carousel.o      $(HACK_TRACK_GRAB_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_GRAB_OBJS) $(HACK_LIBS)
+carousel:      carousel.o      $(EASE) $(HACK_TRACK_GRAB_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(EASE) $(HACK_TRACK_GRAB_OBJS) $(HACK_LIBS)
 
 fliptext:      fliptext.o      $(TEXT) $(HACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(TEXT) $(HACK_OBJS) $(HACK_LIBS) $(TEXT_LIBS)
@@ -1018,10 +1024,10 @@ CCUBE2=gllist.o $(HACK_TRACK_OBJS)
 companioncube:                 $(CCUBE1) $(CCUBE2)
        $(CC_HACK) -o $@        $(CCUBE1) $(CCUBE2) $(HACK_LIBS)
 
-TBIT1=tronbit.o tronbit_idle1.o tronbit_idle2.o tronbit_no.o tronbit_yes.o
-TBIT2=gllist.o $(HACK_TRACK_OBJS)
-tronbit:                       $(TBIT1) $(TBIT2)
-       $(CC_HACK) -o $@        $(TBIT1) $(TBIT2) $(HACK_LIBS)
+TBIT = tronbit.o tronbit_idle1.o tronbit_idle2.o tronbit_no.o tronbit_yes.o \
+       gllist.o $(HACK_TRACK_OBJS)
+tronbit:                       $(TBIT)
+       $(CC_HACK) -o $@        $(TBIT) $(HACK_LIBS)
 
 KALEIDOCYCLE_OBJS=kaleidocycle.o normals.o $(HACK_TRACK_OBJS)
 kaleidocycle:                  $(KALEIDOCYCLE_OBJS)
@@ -1030,8 +1036,9 @@ kaleidocycle:                     $(KALEIDOCYCLE_OBJS)
 quasicrystal:  quasicrystal.o  $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-unknownpleasures: unknownpleasures.o   $(PNG) $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o $(PNG) $(HACK_TRACK_OBJS) $(HACK_LIBS) $(PNG_LIBS)
+UNKOBJS = $(PNG) $(EASE) $(HACK_TRACK_OBJS)
+unknownpleasures: unknownpleasures.o $(UNKOBJS)
+       $(CC_HACK) -o $@ $@.o $(UNKOBJS) $(HACK_LIBS) $(PNG_LIBS)
 
 geodesic: geodesic.o            normals.o $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o    normals.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
@@ -1056,21 +1063,21 @@ ES_OBJS=$(PNG) $(HACK_TRACK_OBJS)
 energystream:  energystream.o  $(ES_OBJS)
        $(CC_HACK) -o $@ $@.o   $(ES_OBJS) $(PNG_LIBS) $(HACK_LIBS)
 
-raverhoop:     raverhoop.o     $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+raverhoop:     raverhoop.o     $(EASE) $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(EASE) $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-HSTAT_OBJS=sphere.o normals.o $(HACK_TRACK_OBJS)
+HSTAT_OBJS=sphere.o normals.o $(EASE) $(HACK_TRACK_OBJS)
 hydrostat:     hydrostat.o     $(HSTAT_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HSTAT_OBJS) $(HACK_LIBS)
 
 discoball:     discoball.o     $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-cubetwist:     cubetwist.o     $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+cubetwist:     cubetwist.o     $(HACK_TRACK_OBJS) $(EASE)
+       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(EASE) $(HACK_LIBS)
 
-cubestack:     cubestack.o     $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+cubestack:     cubestack.o     $(HACK_TRACK_OBJS) $(EASE)
+       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(EASE) $(HACK_LIBS)
 
 splodesic:     splodesic.o     $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
@@ -1091,8 +1098,8 @@ razzledazzle:     razzledazzle.o  $(DAZ_OBJS)
 peepers:       peepers.o        normals.o $(PNG) $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o    normals.o $(PNG) $(PNG_LIBS) $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-crumbler:      crumbler.o      quickhull.o $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o   quickhull.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
+crumbler:      crumbler.o      quickhull.o $(HACK_TRACK_OBJS) $(EASE)
+       $(CC_HACK) -o $@ $@.o   quickhull.o $(HACK_TRACK_OBJS) $(EASE) $(HACK_LIBS)
 
 maze3d:        maze3d.o                 $(PNG) $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o    $(PNG) $(PNG_LIBS) $(HACK_TRACK_OBJS) $(HACK_LIBS)
@@ -1110,8 +1117,8 @@ gravitywell:      gravitywell.o   $(HACK_TRACK_OBJS)
 deepstars:     deepstars.o     $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-gibson:                gibson.o        $(PNG) $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(PNG) $(HACK_TRACK_OBJS) $(PNG_LIBS)
+gibson:                gibson.o        $(PNG) $(EASE) $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(PNG) $(EASE) $(HACK_TRACK_OBJS) $(PNG_LIBS)
 
 covid19:       covid19.o       $(DB_OBJS)
        $(CC_HACK) -o $@ $@.o   $(DB_OBJS) $(HACK_LIBS)
@@ -1128,17 +1135,18 @@ headroom_dxf::
 beats:         beats.o         sphere.o $(HACK_OBJS)
        $(CC_HACK) -o $@ $@.o   sphere.o $(HACK_OBJS) $(HACK_LIBS)
 
-mapscroller:   mapscroller.o   $(PNG) $(HACK_GRAB_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(PNG) $(HACK_GRAB_OBJS) $(PNG_LIBS)
+mapscroller:   mapscroller.o   $(PNG) $(EASE) $(HACK_GRAB_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(PNG) $(EASE) $(HACK_GRAB_OBJS) $(PNG_LIBS)
 
-SQOBJ = normals.o $(UTILS_BIN)/spline.o
+SQOBJ = normals.o $(UTILS_BIN)/spline.o $(EASE)
 squirtorus:    squirtorus.o    $(SQOBJ) $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(SQOBJ) $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-nakagin:       nakagin.o       $(HACK_TRACK_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+nakagin:       nakagin.o       $(EASE) $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(EASE) $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-CHOBJS = gllist.o teeth_model.o normals.o sphere.o $(UTILS_BIN)/spline.o
+CHOBJS = gllist.o teeth_model.o normals.o sphere.o $(UTILS_BIN)/spline.o \
+        $(EASE)
 chompytower:   chompytower.o   $(CHOBJS) $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(CHOBJS) $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
@@ -1155,7 +1163,7 @@ CUBOCT_OBJS=$(PNG) $(HACK_TRACK_OBJS)
 cubocteversion:        cubocteversion.o $(CUBOCT_OBJS)
        $(CC_HACK) -o $@ $@.o    $(CUBOCT_OBJS) $(HACK_LIBS) $(PNG_LIBS)
 
-SKULLOOP_OBJS=gllist.o skull_model.o normals.o $(HACK_TRACK_OBJS)
+SKULLOOP_OBJS=gllist.o skull_model.o normals.o $(EASE) $(HACK_TRACK_OBJS)
 skulloop:      skulloop.o       $(SKULLOOP_OBJS)
        $(CC_HACK) -o $@ $@.o    $(SKULLOOP_OBJS) $(HACK_LIBS)
 
@@ -1200,7 +1208,7 @@ klondike: klondike.o $(KLONDIKE_OBJS)
 
 dumpster_dxf::
        ./dxf2gl.pl --smooth --layers --normalize dumpster.dxf dumpster_model.c
-DUMPSTERFIRE=dumpsterfire.o dumpster_model.o gllist.o $(HACK_TRACK_OBJS)
+DUMPSTERFIRE=dumpsterfire.o dumpster_model.o gllist.o $(EASE) $(HACK_TRACK_OBJS)
 dumpsterfire:                  $(DUMPSTERFIRE)
        $(CC_HACK) -o $@        $(DUMPSTERFIRE) $(HACK_LIBS)
 
@@ -1519,6 +1527,7 @@ carousel.o: $(srcdir)/rotator.h
 carousel.o: $(HACK_SRC)/screenhackI.h
 carousel.o: $(srcdir)/texfont.h
 carousel.o: $(UTILS_SRC)/colors.h
+carousel.o: $(UTILS_SRC)/easing.h
 carousel.o: $(UTILS_SRC)/erase.h
 carousel.o: $(UTILS_SRC)/font-retry.h
 carousel.o: $(UTILS_SRC)/grabclient.h
@@ -1554,6 +1563,8 @@ chompytower.o: $(srcdir)/rotator.h
 chompytower.o: $(HACK_SRC)/screenhackI.h
 chompytower.o: $(srcdir)/sphere.h
 chompytower.o: $(UTILS_SRC)/colors.h
+chompytower.o: $(UTILS_SRC)/doubletime.h
+chompytower.o: $(UTILS_SRC)/easing.h
 chompytower.o: $(UTILS_SRC)/erase.h
 chompytower.o: $(UTILS_SRC)/font-retry.h
 chompytower.o: $(UTILS_SRC)/grabclient.h
@@ -1828,6 +1839,7 @@ crumbler.o: $(HACK_SRC)/recanim.h
 crumbler.o: $(srcdir)/rotator.h
 crumbler.o: $(HACK_SRC)/screenhackI.h
 crumbler.o: $(UTILS_SRC)/colors.h
+crumbler.o: $(UTILS_SRC)/easing.h
 crumbler.o: $(UTILS_SRC)/erase.h
 crumbler.o: $(UTILS_SRC)/font-retry.h
 crumbler.o: $(UTILS_SRC)/grabclient.h
@@ -1881,6 +1893,7 @@ cubestack.o: $(HACK_SRC)/recanim.h
 cubestack.o: $(srcdir)/rotator.h
 cubestack.o: $(HACK_SRC)/screenhackI.h
 cubestack.o: $(UTILS_SRC)/colors.h
+cubestack.o: $(UTILS_SRC)/easing.h
 cubestack.o: $(UTILS_SRC)/erase.h
 cubestack.o: $(UTILS_SRC)/font-retry.h
 cubestack.o: $(UTILS_SRC)/grabclient.h
@@ -1918,6 +1931,7 @@ cubetwist.o: $(HACK_SRC)/recanim.h
 cubetwist.o: $(srcdir)/rotator.h
 cubetwist.o: $(HACK_SRC)/screenhackI.h
 cubetwist.o: $(UTILS_SRC)/colors.h
+cubetwist.o: $(UTILS_SRC)/easing.h
 cubetwist.o: $(UTILS_SRC)/erase.h
 cubetwist.o: $(UTILS_SRC)/font-retry.h
 cubetwist.o: $(UTILS_SRC)/grabclient.h
@@ -2087,6 +2101,7 @@ dumpsterfire.o: $(HACK_SRC)/recanim.h
 dumpsterfire.o: $(srcdir)/rotator.h
 dumpsterfire.o: $(HACK_SRC)/screenhackI.h
 dumpsterfire.o: $(UTILS_SRC)/colors.h
+dumpsterfire.o: $(UTILS_SRC)/easing.h
 dumpsterfire.o: $(UTILS_SRC)/erase.h
 dumpsterfire.o: $(UTILS_SRC)/font-retry.h
 dumpsterfire.o: $(UTILS_SRC)/grabclient.h
@@ -2131,6 +2146,8 @@ dymaxionmap.o: $(HACK_SRC)/screenhackI.h
 dymaxionmap.o: $(srcdir)/sphere.h
 dymaxionmap.o: $(srcdir)/texfont.h
 dymaxionmap.o: $(UTILS_SRC)/colors.h
+dymaxionmap.o: $(UTILS_SRC)/doubletime.h
+dymaxionmap.o: $(UTILS_SRC)/easing.h
 dymaxionmap.o: $(UTILS_SRC)/erase.h
 dymaxionmap.o: $(UTILS_SRC)/font-retry.h
 dymaxionmap.o: $(UTILS_SRC)/grabclient.h
@@ -2150,7 +2167,9 @@ endgame.o: $(HACK_SRC)/fps.h
 endgame.o: $(srcdir)/gltrackball.h
 endgame.o: $(HACK_SRC)/recanim.h
 endgame.o: $(HACK_SRC)/screenhackI.h
+endgame.o: $(srcdir)/texfont.h
 endgame.o: $(UTILS_SRC)/colors.h
+endgame.o: $(UTILS_SRC)/easing.h
 endgame.o: $(UTILS_SRC)/erase.h
 endgame.o: $(UTILS_SRC)/font-retry.h
 endgame.o: $(UTILS_SRC)/grabclient.h
@@ -2209,6 +2228,7 @@ esper.o: $(HACK_SRC)/recanim.h
 esper.o: $(HACK_SRC)/screenhackI.h
 esper.o: $(srcdir)/texfont.h
 esper.o: $(UTILS_SRC)/colors.h
+esper.o: $(UTILS_SRC)/doubletime.h
 esper.o: $(UTILS_SRC)/erase.h
 esper.o: $(UTILS_SRC)/font-retry.h
 esper.o: $(UTILS_SRC)/grabclient.h
@@ -2643,6 +2663,7 @@ gibson.o: $(srcdir)/rotator.h
 gibson.o: $(HACK_SRC)/screenhackI.h
 gibson.o: $(srcdir)/texfont.h
 gibson.o: $(UTILS_SRC)/colors.h
+gibson.o: $(UTILS_SRC)/easing.h
 gibson.o: $(UTILS_SRC)/erase.h
 gibson.o: $(UTILS_SRC)/font-retry.h
 gibson.o: $(UTILS_SRC)/grabclient.h
@@ -2732,6 +2753,7 @@ glhanoi.o: $(HACK_SRC)/recanim.h
 glhanoi.o: $(srcdir)/rotator.h
 glhanoi.o: $(HACK_SRC)/screenhackI.h
 glhanoi.o: $(UTILS_SRC)/colors.h
+glhanoi.o: $(UTILS_SRC)/doubletime.h
 glhanoi.o: $(UTILS_SRC)/erase.h
 glhanoi.o: $(UTILS_SRC)/font-retry.h
 glhanoi.o: $(UTILS_SRC)/grabclient.h
@@ -2867,6 +2889,8 @@ glslideshow.o: $(HACK_SRC)/recanim.h
 glslideshow.o: $(HACK_SRC)/screenhackI.h
 glslideshow.o: $(srcdir)/texfont.h
 glslideshow.o: $(UTILS_SRC)/colors.h
+glslideshow.o: $(UTILS_SRC)/doubletime.h
+glslideshow.o: $(UTILS_SRC)/easing.h
 glslideshow.o: $(UTILS_SRC)/erase.h
 glslideshow.o: $(UTILS_SRC)/font-retry.h
 glslideshow.o: $(UTILS_SRC)/grabclient.h
@@ -2983,6 +3007,7 @@ grab-ximage.o: $(srcdir)/grab-ximage.h
 grab-ximage.o: $(HACK_SRC)/recanim.h
 grab-ximage.o: $(HACK_SRC)/screenhackI.h
 grab-ximage.o: $(UTILS_SRC)/colors.h
+grab-ximage.o: $(UTILS_SRC)/doubletime.h
 grab-ximage.o: $(UTILS_SRC)/erase.h
 grab-ximage.o: $(UTILS_SRC)/font-retry.h
 grab-ximage.o: $(UTILS_SRC)/grabclient.h
@@ -3039,6 +3064,7 @@ handsy.o: $(HACK_SRC)/screenhackI.h
 handsy.o: $(srcdir)/sphere.h
 handsy.o: $(srcdir)/tube.h
 handsy.o: $(UTILS_SRC)/colors.h
+handsy.o: $(UTILS_SRC)/doubletime.h
 handsy.o: $(UTILS_SRC)/erase.h
 handsy.o: $(UTILS_SRC)/font-retry.h
 handsy.o: $(UTILS_SRC)/grabclient.h
@@ -3207,6 +3233,7 @@ hydrostat.o: $(HACK_SRC)/recanim.h
 hydrostat.o: $(HACK_SRC)/screenhackI.h
 hydrostat.o: $(srcdir)/sphere.h
 hydrostat.o: $(UTILS_SRC)/colors.h
+hydrostat.o: $(UTILS_SRC)/easing.h
 hydrostat.o: $(UTILS_SRC)/erase.h
 hydrostat.o: $(UTILS_SRC)/font-retry.h
 hydrostat.o: $(UTILS_SRC)/grabclient.h
@@ -3575,6 +3602,7 @@ mapscroller.o: $(HACK_SRC)/recanim.h
 mapscroller.o: $(HACK_SRC)/screenhackI.h
 mapscroller.o: $(srcdir)/texfont.h
 mapscroller.o: $(UTILS_SRC)/colors.h
+mapscroller.o: $(UTILS_SRC)/easing.h
 mapscroller.o: $(UTILS_SRC)/erase.h
 mapscroller.o: $(UTILS_SRC)/font-retry.h
 mapscroller.o: $(UTILS_SRC)/grabclient.h
@@ -3650,6 +3678,7 @@ mirrorblob.o: $(srcdir)/grab-ximage.h
 mirrorblob.o: $(HACK_SRC)/recanim.h
 mirrorblob.o: $(HACK_SRC)/screenhackI.h
 mirrorblob.o: $(UTILS_SRC)/colors.h
+mirrorblob.o: $(UTILS_SRC)/doubletime.h
 mirrorblob.o: $(UTILS_SRC)/erase.h
 mirrorblob.o: $(UTILS_SRC)/font-retry.h
 mirrorblob.o: $(UTILS_SRC)/grabclient.h
@@ -3747,6 +3776,8 @@ nakagin.o: $(HACK_SRC)/recanim.h
 nakagin.o: $(srcdir)/rotator.h
 nakagin.o: $(HACK_SRC)/screenhackI.h
 nakagin.o: $(UTILS_SRC)/colors.h
+nakagin.o: $(UTILS_SRC)/doubletime.h
+nakagin.o: $(UTILS_SRC)/easing.h
 nakagin.o: $(UTILS_SRC)/erase.h
 nakagin.o: $(UTILS_SRC)/font-retry.h
 nakagin.o: $(UTILS_SRC)/grabclient.h
@@ -4074,6 +4105,7 @@ raverhoop.o: $(HACK_SRC)/recanim.h
 raverhoop.o: $(srcdir)/rotator.h
 raverhoop.o: $(HACK_SRC)/screenhackI.h
 raverhoop.o: $(UTILS_SRC)/colors.h
+raverhoop.o: $(UTILS_SRC)/easing.h
 raverhoop.o: $(UTILS_SRC)/erase.h
 raverhoop.o: $(UTILS_SRC)/font-retry.h
 raverhoop.o: $(UTILS_SRC)/grabclient.h
@@ -4415,6 +4447,7 @@ skulloop.o: $(HACK_SRC)/recanim.h
 skulloop.o: $(HACK_SRC)/screenhackI.h
 skulloop.o: $(srcdir)/texfont.h
 skulloop.o: $(UTILS_SRC)/colors.h
+skulloop.o: $(UTILS_SRC)/easing.h
 skulloop.o: $(UTILS_SRC)/erase.h
 skulloop.o: $(UTILS_SRC)/font-retry.h
 skulloop.o: $(UTILS_SRC)/grabclient.h
@@ -4455,6 +4488,7 @@ sonar-icmp.o: $(srcdir)/sonar.h
 sonar-icmp.o: $(UTILS_SRC)/aligned_malloc.h
 sonar-icmp.o: $(UTILS_SRC)/async_netdb.h
 sonar-icmp.o: $(UTILS_SRC)/colors.h
+sonar-icmp.o: $(UTILS_SRC)/doubletime.h
 sonar-icmp.o: $(UTILS_SRC)/font-retry.h
 sonar-icmp.o: $(UTILS_SRC)/grabclient.h
 sonar-icmp.o: $(UTILS_SRC)/hsv.h
@@ -4475,6 +4509,7 @@ sonar.o: $(srcdir)/sonar.h
 sonar.o: $(srcdir)/texfont.h
 sonar.o: $(UTILS_SRC)/aligned_malloc.h
 sonar.o: $(UTILS_SRC)/colors.h
+sonar.o: $(UTILS_SRC)/doubletime.h
 sonar.o: $(UTILS_SRC)/erase.h
 sonar.o: $(UTILS_SRC)/font-retry.h
 sonar.o: $(UTILS_SRC)/grabclient.h
@@ -4695,6 +4730,7 @@ squirtorus.o: $(srcdir)/normals.h
 squirtorus.o: $(HACK_SRC)/recanim.h
 squirtorus.o: $(HACK_SRC)/screenhackI.h
 squirtorus.o: $(UTILS_SRC)/colors.h
+squirtorus.o: $(UTILS_SRC)/easing.h
 squirtorus.o: $(UTILS_SRC)/erase.h
 squirtorus.o: $(UTILS_SRC)/font-retry.h
 squirtorus.o: $(UTILS_SRC)/grabclient.h
@@ -5204,6 +5240,7 @@ tronbit.o: $(srcdir)/rotator.h
 tronbit.o: $(HACK_SRC)/screenhackI.h
 tronbit.o: $(srcdir)/sphere.h
 tronbit.o: $(UTILS_SRC)/colors.h
+tronbit.o: $(UTILS_SRC)/doubletime.h
 tronbit.o: $(UTILS_SRC)/erase.h
 tronbit.o: $(UTILS_SRC)/font-retry.h
 tronbit.o: $(UTILS_SRC)/grabclient.h
@@ -5286,6 +5323,8 @@ unknownpleasures.o: $(srcdir)/grab-ximage.h
 unknownpleasures.o: $(HACK_SRC)/recanim.h
 unknownpleasures.o: $(HACK_SRC)/screenhackI.h
 unknownpleasures.o: $(UTILS_SRC)/colors.h
+unknownpleasures.o: $(UTILS_SRC)/doubletime.h
+unknownpleasures.o: $(UTILS_SRC)/easing.h
 unknownpleasures.o: $(UTILS_SRC)/erase.h
 unknownpleasures.o: $(UTILS_SRC)/font-retry.h
 unknownpleasures.o: $(UTILS_SRC)/grabclient.h
@@ -5323,6 +5362,7 @@ voronoi.o: $(HACK_SRC)/fps.h
 voronoi.o: $(HACK_SRC)/recanim.h
 voronoi.o: $(HACK_SRC)/screenhackI.h
 voronoi.o: $(UTILS_SRC)/colors.h
+voronoi.o: $(UTILS_SRC)/doubletime.h
 voronoi.o: $(UTILS_SRC)/erase.h
 voronoi.o: $(UTILS_SRC)/font-retry.h
 voronoi.o: $(UTILS_SRC)/grabclient.h
index 43b8da4b1b83d5d98ea461052fad8e26054f9c19..785260ae84b3ca871d6dded8eca15219a3f4cd23 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 atunnel \- hypnotic GL tunnel journey
 .SH SYNOPSIS
-.B sballs
+.B atunnel
 [\-\-display \fIhost:display.screen\fP] [\-\-window] [\-\-root]
 [\-\-window\-id \fInumber\fP]
 [\-\-visual \fIvisual\fP] [\-\-delay \fImicroseconds\fP]
index 5543403b5c272040d8217602819cd2b702a80845..147b3fadaf17787bc0ab1b5e37d94e9de3f81969 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "2020-Feb-04" "X Version 11"
 .SH NAME
-beats - create offset beating figures
+beats \- create offset beating figures
 .SH SYNOPSIS
 .B beats
 [\-\-display \fIhost:display.screen\fP]
index d265e6f8042ed842aa7c172744e2fd8cce455e45..901cda2f1df25de623a9c5fc1e08f410ec29ed08 100644 (file)
@@ -1,4 +1,4 @@
-/* carousel, Copyright © 2005-2023 Jamie Zawinski <jwz@jwz.org>
+/* carousel, Copyright © 2005-2025 Jamie Zawinski <jwz@jwz.org>
  * Loads a sequence of images and rotates them around.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -30,6 +30,7 @@
 
 # define release_carousel 0
 # include "xlockmore.h"
+# include "easing.h"
 
 #ifdef USE_GL
 
@@ -63,7 +64,7 @@ typedef struct {
 } rect;
 
 typedef enum { EARLY, NORMAL, LOADING, OUT, IN, DEAD } fade_mode;
-static int fade_ticks = 60;
+static int fade_ticks = 30 * 5;
 
 typedef struct {
   char *title;                 /* the filename of this image */
@@ -758,8 +759,10 @@ draw_frame (ModeInfo *mi, image_frame *frame, time_t now, Bool body_p)
                    ? frame->mode_tick / (fade_ticks / speed)
                    : (((fade_ticks / speed) - frame->mode_tick + 1) /
                       (fade_ticks / speed)));
-      t = 5 * (1 - t);
+      t = 1-t;
+      t = ease (EASE_IN_OUT_BACK, t);
       if (frame->from_top_p) t = -t;
+      t *= 5;
       glTranslatef (0, t, 0);
     }
 
index 28f5c57070eda9fdf6ed71545183c587e76447ef..a93015e53161985d84626f927a1119e888d3f4e3 100644 (file)
 #ifndef __CHESSGAMES_H__
 #define __CHESSGAMES_H__
 
+#define DESC_STR_LEN 64 /* Length of the game description. */
+#define SAN_STR_LEN 8   /* Length of the move description */
+
 /** structure for a chess game */
 typedef struct {
-
-  /** original board configuration */
-  int board[BOARDSIZE][BOARDSIZE];
-
-  /** total moves */
-  int movecount;
-
-  /** 
-      moves in game.  this is a slight hack: moves are encoded in
-      integer pairs (x,y).  the first pair, _from_, determines the 
-      piece to move.  the second pair, _to_, determines where to move.
-      
-      in case _to_ is held by another piece, that piece is taken.
-      (see drawTakePiece(), draw_chess())
-
-      in case the move promotes a pawn, we assume a queening.
-      (see drawMovingPiece())
-
-      what's lacking? 
-      castling, en passant, under-promotions.
-  */
-  int moves[40][4];
+    char desc[DESC_STR_LEN + SAN_STR_LEN + 1]; /* game + move description */
+    char fen[80];  /* Original board configuration / FEN format */
+    int movecount; /* total moves */
+    struct {       /* moves in game - as uci and san strings */
+        char uci[8];
+        char san[8];
+    } moves[128];
 } ChessGame;
 
-#define GAMES 7
-static ChessGame games[GAMES] = {
-  
-  /** 
-      game 1:
-      
-      E. N. Somov-Nasimovitsch
-      White to play and win.
-      
-      "Zadachi I Etiudi"
-      1928
-  */
-  {
-    {
-      {   0,     0,     0,    0,     0, BKING,    0,    0},
-      {   BPAWN, 0, BPAWN,    0, BPAWN,     0,    0,    0},
-      {   0,     0, BPAWN,    0, BPAWN,     0,    0,    KNIGHT},
-      {   PAWN,  0,  ROOK,    0,     0,     0,    0,    0},
-      {   PAWN,  0,     0,    0,  KING,  PAWN,    0,    0},
-      {   0,     0,     0,    0,     0,     0,    0,    0},
-      {   BPAWN, 0,     0,    0,     0,     0,    0,    PAWN},
-      {  BBISHOP,0,     0,    0,     0,     0,    0,    0},
-    },
-    
-    24,
-    
-    { 
-      {3, 2, 6, 2},
-      {7, 0, 6, 1},
-      {6, 2, 6, 6},
-      {0, 5, 0, 4},
-      {6, 6, 0, 6},
-      {0, 4, 1, 3},
-      {2, 7, 1, 5},
-      {2, 2, 3, 2},
-      {0, 6, 0, 3},
-      {1, 3, 2, 2},
-      {0, 3, 6, 3},
-      {3, 2, 4, 2}, /* pawn to bishop 5 */
-      {1, 5, 0, 3}, /* check */
-      {2, 2, 3, 2},
-      {0, 3, 2, 4}, /* takes pawn */
-      {3, 2, 2, 2},
-      {2, 4, 0, 3},
-      {2, 2, 3, 2},
-      {6, 3, 6, 1}, /* rook takes bishop */
-      {6, 0, 7, 0},
-      {6, 1, 3, 1},
-      {3, 2, 2, 3},
-      {3, 1, 3, 3},
-      {0, 0, 2, 3},
-    }
-  },
-
-  /** 
-      game 2: 
-      
-      K. A. L. Kubbel
-      White to play and win.
-      
-      "Chess in the USSR"
-      1936
-  */
-  {
-    {
-      {   0,     0,     0,    0,     0,     0,    0,    0},
-      {   0,     0,     0,    0,     0,     0,    0,    BPAWN},
-      {   0,     0,     0,    0, BPAWN,  KING,    0,    BKING},
-      {   0,     0,     0,    0,     0,  ROOK,    0,    0},
-      {   0,     0,     0,    0,     0,     0,    0,    0},
-      {  0,BBISHOP,     0,    0, BROOK,     0, PAWN,    0},
-      {   0,     0,     0,    0,     0,     0,    0,    0},
-      {   0,     0,     0,    0,     0,BISHOP,    0,    0},
-    },
-    
-    10,
-    
-    { 
-      {3, 5, 6, 5},
-      {5, 1, 7, 3},
-      {6, 5, 6, 7}, /* check */
-      {7, 3, 3, 7}, 
-      {7, 5, 6, 4}, 
-      {5, 4, 6, 4},
-      {5, 6, 4, 6}, /* ! */
-      {6, 4, 6, 7},
-      {4, 6, 3, 6},
-      {0, 0, 2, 7}
-    }
-  },
-
-  /** 
-      game 3: 
-      
-      J. Hasek
-      White to play and win.
-      
-      "Le Strategie"
-      1929
-  */
-  {
-    {
-      {     0,      0,      0, KNIGHT,      0,      0,      0, KNIGHT},
-      {     0,   KING,  BPAWN,  BPAWN,      0,      0,      0,      0},
-      {     0,      0,      0,      0,      0,      0,      0,      0},
-      {     0,  BKING,      0,      0,      0,      0,      0,      0},
-      {     0,   PAWN,      0,      0,      0,  BPAWN,      0,      0},
-      {  PAWN,      0,   PAWN,      0,      0,      0,      0,      0},
-      {     0,      0,      0,      0,      0,      0,      0,      0},
-      {     0,      0,      0,      0,      0,      0,      0,      0},
-    },
-    
-    11,
-
-    { 
-      {0, 3, 2, 2},
-      {1, 3, 2, 2},
-      {0, 7, 2, 6},
-      {4, 5, 5, 5}, 
-      {2, 6, 3, 4}, 
-      {5, 5, 6, 5},
-      {3, 4, 5, 3}, /* ! */
-      {6, 5, 7, 5},
-      {5, 3, 6, 1},
-      {0, 0, 0, 0}, /* mull it over... */
-      {0, 0, 3, 1}
-    }    
-  },
-
-  /** 
-      game 4: 
-
-      M.B. Newman
-      White to play and win.
-      
-      "Chess Amateur"
-      1913
-  */
-  {
-    {
-      {      0,      0,      0,      0,  BQUEEN,      0,      0,      0},
-      {BKNIGHT,      0,      0,      0,       0,      0,      0,      0},
-      {      0,      0,      0,      0,       0,      0,      0,      0},
-      {      0,      0,      0,      0,       0,      0,      0,   PAWN},
-      {  BKING,      0, BISHOP,      0,  KNIGHT,      0,      0,      0},
-      {  PAWN,       0,      0,      0,  KNIGHT,      0,      0,      0},
-      {     0,       0,      0,      0,       0,      0,      0,      0},
-      {  KING,       0,      0,      0,       0,      0,      0,      0},
-    },
-    
-    15,
-
-    { 
-      {4, 2, 3, 1},
-      {0, 4, 3, 1}, /* queen wins bishop */
-      {4, 4, 5, 2},
-      {4, 0, 5, 0}, /* king takes pawn */
-      {5, 2, 3, 1}, /* knight takes queen, check */
-      {1, 0, 3, 1}, /* knight takes knight */
-      {3, 7, 2, 7}, /* pawn advances */
-      {3, 1, 2, 3},
-      {5, 4, 4, 2},
-      {2, 3, 4, 2},
-      {2, 7, 1, 7}, /* pawn advances */
-      {4, 2, 2, 3},
-      {1, 7, 0, 7},
-      {0, 0, 0, 0},
-      {0, 0, 5, 0}
-    }    
-  },
-
-  /** 
-      game 5:
-
-      V.A. Korolikov
-      White to play and win
-      
-      First Prize - "Truda"
-      1935
-  */
-  {
-    {
-      {      0,      0, BISHOP,      0,       0,      0,      0,       0},
-      {  BPAWN,   ROOK,      0,      0,       0,      0,      0,       0},
-      {      0,      0,  BPAWN,   PAWN,       0,  BKING,      0,       0},
-      {      0,      0,      0,      0,       0,      0,      0,       0},
-      {      0,      0,      0,      0,       0,      0,   KING, BBISHOP},
-      {      0,      0,      0,      0,   BPAWN,      0,   PAWN,      0},
-      {      0,      0,      0,      0,       0,  BPAWN,      0,      0},
-      {      0,      0,      0,      0,       0,      0,      0,      0},
-    },
-    
-    21,
-
-    { 
-      {2, 3, 1, 3}, /* pawn to q7 */
-      {2, 5, 1, 4}, /* cover with king */
-      {1, 1, 0, 1},
-      {4, 7, 5, 6}, /* bishop takes pawn */
-      {0, 1, 0, 0}, /* r - r8 */
-      {6, 5, 7, 5}, /* queened */
-      {1, 3, 0, 3}, /* white pawn promoted */
-      {1, 4, 0, 3}, /* king takes queen */
-      {0, 2, 2, 0}, /* discovered check */
-      {5, 6, 0, 1}, /* pull back bishop */
-      {2, 0, 7, 5}, /* bishop takes queen */
-      {0, 3, 1, 2},
-      {7, 5, 2, 0}, /* save rook */
-      {5, 4, 6, 4},
-      {2, 0, 6, 4}, /* bishop takes pawn */
-      {1, 2, 1, 1}, /* king moves in */
-      {6, 4, 5, 5},
-      {1, 1, 0, 0},
-      {5, 5, 2, 2},
-      {0, 0, 0, 0},
-      {0, 0, 0, 0}
-    }    
-  },
-
-  /** 
-      game 6:
-
-      T.B. Gorgiev
-      White to play and win
-      
-      First Prize - "64"
-      1929
-  */
-  {
-    {
-      {      0,      0,      0,      0,       0,      0, KNIGHT,       0},
-      {  BKNIGHT,    0,      0,      0,       0,      0,      0,       0},
-      {      0,      0,      0,  BKING, BKNIGHT,      0,      0,       0},
-      {   KING,      0,      0,      0,       0,      0,      0,       0},
-      {      0,      0,      0,      0,       0,      0, KNIGHT,       0},
-      {      0,      0,      0,      0,       0,      0,      0,      0},
-      {      0,      0,      0,      0,       0,      0,      0,      0},
-      {      0,      0,      0,      0,  BISHOP,      0,      0,      0},
-    },
-    
-    13,
-
-    { 
-      {3, 0, 2, 1}, /* king on move */
-      {1, 0, 0, 2}, /* check */
-      {2, 1, 1, 1},
-      {0, 2, 1, 4}, /* knight moves on */
-      {7, 4, 5, 6}, /* bishop puts king in check */
-      {2, 3, 1, 3}, /* king moves back */
-      {0, 6, 2, 5}, /* knight moves in, check */
-      {1, 3, 0, 3}, /* king moves back queen */
-      {5, 6, 1, 2}, /* bishop - b7 ch!! */
-      {2, 4, 1, 2}, /* black knight takes bishop */
-      {4, 6, 3, 4}, /* knight to k5 */
-      {0, 0, 0, 0}, /* mate */
-      {0, 0, 0, 0}
-    }    
-  },
-
-  /** 
-      game 7:
-
-      K. A. L. Kubbel
-      White to play and win
-      
-      "Schachmatny Listok"
-      1922
-  */
-  {
-    {
-      {      0, KNIGHT,      0,      0,       0,      0,       0,      0},
-      {      0,      0,      0,      0,       0,      0,      0,      0},
-      {   KING,      0,      0,      0,       0,      0,      0,      0},
-      {      0,      0,      0,  BKING,       0,      0,      0,      0},
-      {      0,      0,      0,  BPAWN,       0,      0,      0, BISHOP},
-      {  BPAWN,      0,      0,      0,       0,      0,      0,      0},
-      {      0,      0,   PAWN,   PAWN,       0,      0,      0,      0},
-      {      0,      0,      0,      0,       0,      0,      0,      0},
-    },
-    
-    12,
-
-    { 
-      {0, 1, 2, 2}, /* kt-b6 */
-      {3, 3, 2, 2}, /* k x kt */
-      {4, 7, 2, 5}, /* b-b6 */
-      {2, 2, 3, 3}, /* king back to original position */
-      {6, 3, 5, 3}, /* p-q3! */
-      {5, 0, 6, 0}, /* p-r7 */
-      {6, 2, 4, 2}, /* p-b4ch */
-      {3, 3, 3, 2}, /* king moves, black cannot capture in passing */
-      {2, 0, 1, 1}, /* k-kt7! */
-      {6, 0, 7, 0}, /* promo */
-      {2, 5, 1, 4}, /* mate */
-      {0, 0, 3, 2},
-    }    
-  },
+#define GAMES_NUMBER 34
+static ChessGame games[GAMES_NUMBER] = {
+    {.desc = "A. Anderssen / L. Kieseritzky / 1851\n\"The immortal game\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 45,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},    {.uci = "e7e5", .san = "e5"},
+             {.uci = "f2f4", .san = "f4"},    {.uci = "e5f4", .san = "exf4"},
+             {.uci = "f1c4", .san = "Bc4"},   {.uci = "d8h4", .san = "Qh4+"},
+             {.uci = "e1f1", .san = "Kf1"},   {.uci = "b7b5", .san = "b5"},
+             {.uci = "c4b5", .san = "Bxb5"},  {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "h4h6", .san = "Qh6"},
+             {.uci = "d2d3", .san = "d3"},    {.uci = "f6h5", .san = "Nh5"},
+             {.uci = "f3h4", .san = "Nh4"},   {.uci = "h6g5", .san = "Qg5"},
+             {.uci = "h4f5", .san = "Nf5"},   {.uci = "c7c6", .san = "c6"},
+             {.uci = "g2g4", .san = "g4"},    {.uci = "h5f6", .san = "Nf6"},
+             {.uci = "h1g1", .san = "Rg1"},   {.uci = "c6b5", .san = "cxb5"},
+             {.uci = "h2h4", .san = "h4"},    {.uci = "g5g6", .san = "Qg6"},
+             {.uci = "h4h5", .san = "h5"},    {.uci = "g6g5", .san = "Qg5"},
+             {.uci = "d1f3", .san = "Qf3"},   {.uci = "f6g8", .san = "Ng8"},
+             {.uci = "c1f4", .san = "Bxf4"},  {.uci = "g5f6", .san = "Qf6"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "f8c5", .san = "Bc5"},
+             {.uci = "c3d5", .san = "Nd5"},   {.uci = "f6b2", .san = "Qxb2"},
+             {.uci = "f4d6", .san = "Bd6"},   {.uci = "c5g1", .san = "Bxg1"},
+             {.uci = "e4e5", .san = "e5"},    {.uci = "b2a1", .san = "Qxa1+"},
+             {.uci = "f1e2", .san = "Ke2"},   {.uci = "b8a6", .san = "Na6"},
+             {.uci = "f5g7", .san = "Nxg7+"}, {.uci = "e8d8", .san = "Kd8"},
+             {.uci = "f3f6", .san = "Qf6+"},  {.uci = "g8f6", .san = "Nxf6"},
+             {.uci = "d6e7", .san = "Be7#"},
+         }},
+    {.desc = "A. Hoffmann / A. Petrov / 1844\n\"Petrov's immortal\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 40,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},   {.uci = "e7e5", .san = "e5"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "f1c4", .san = "Bc4"},  {.uci = "f8c5", .san = "Bc5"},
+             {.uci = "c2c3", .san = "c3"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "d2d4", .san = "d4"},   {.uci = "e5d4", .san = "exd4"},
+             {.uci = "e4e5", .san = "e5"},   {.uci = "f6e4", .san = "Ne4"},
+             {.uci = "c4d5", .san = "Bd5"},  {.uci = "e4f2", .san = "Nxf2"},
+             {.uci = "e1f2", .san = "Kxf2"}, {.uci = "d4c3", .san = "dxc3+"},
+             {.uci = "f2g3", .san = "Kg3"},  {.uci = "c3b2", .san = "cxb2"},
+             {.uci = "c1b2", .san = "Bxb2"}, {.uci = "c6e7", .san = "Ne7"},
+             {.uci = "f3g5", .san = "Ng5"},  {.uci = "e7d5", .san = "Nxd5"},
+             {.uci = "g5f7", .san = "Nxf7"}, {.uci = "e8g8", .san = "O-O"},
+             {.uci = "f7d8", .san = "Nxd8"}, {.uci = "c5f2", .san = "Bf2+"},
+             {.uci = "g3h3", .san = "Kh3"},  {.uci = "d7d6", .san = "d6+"},
+             {.uci = "e5e6", .san = "e6"},   {.uci = "d5f4", .san = "Nf4+"},
+             {.uci = "h3g4", .san = "Kg4"},  {.uci = "f4e6", .san = "Nxe6"},
+             {.uci = "d8e6", .san = "Nxe6"}, {.uci = "c8e6", .san = "Bxe6+"},
+             {.uci = "g4g5", .san = "Kg5"},  {.uci = "f8f5", .san = "Rf5+"},
+             {.uci = "g5g4", .san = "Kg4"},  {.uci = "h7h5", .san = "h5+"},
+             {.uci = "g4h3", .san = "Kh3"},  {.uci = "f5f3", .san = "Rf3#"},
+         }},
+    {.desc = "A. Anderssen / J. Dufresne / 1852\n\"The evergreen game\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 47,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},    {.uci = "e7e5", .san = "e5"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "f1c4", .san = "Bc4"},   {.uci = "f8c5", .san = "Bc5"},
+             {.uci = "b2b4", .san = "b4"},    {.uci = "c5b4", .san = "Bxb4"},
+             {.uci = "c2c3", .san = "c3"},    {.uci = "b4a5", .san = "Ba5"},
+             {.uci = "d2d4", .san = "d4"},    {.uci = "e5d4", .san = "exd4"},
+             {.uci = "e1g1", .san = "O-O"},   {.uci = "d4d3", .san = "d3"},
+             {.uci = "d1b3", .san = "Qb3"},   {.uci = "d8f6", .san = "Qf6"},
+             {.uci = "e4e5", .san = "e5"},    {.uci = "f6g6", .san = "Qg6"},
+             {.uci = "f1e1", .san = "Re1"},   {.uci = "g8e7", .san = "Nge7"},
+             {.uci = "c1a3", .san = "Ba3"},   {.uci = "b7b5", .san = "b5"},
+             {.uci = "b3b5", .san = "Qxb5"},  {.uci = "a8b8", .san = "Rb8"},
+             {.uci = "b5a4", .san = "Qa4"},   {.uci = "a5b6", .san = "Bb6"},
+             {.uci = "b1d2", .san = "Nbd2"},  {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "d2e4", .san = "Ne4"},   {.uci = "g6f5", .san = "Qf5"},
+             {.uci = "c4d3", .san = "Bxd3"},  {.uci = "f5h5", .san = "Qh5"},
+             {.uci = "e4f6", .san = "Nf6+"},  {.uci = "g7f6", .san = "gxf6"},
+             {.uci = "e5f6", .san = "exf6"},  {.uci = "h8g8", .san = "Rg8"},
+             {.uci = "a1d1", .san = "Rad1"},  {.uci = "h5f3", .san = "Qxf3"},
+             {.uci = "e1e7", .san = "Rxe7+"}, {.uci = "c6e7", .san = "Nxe7"},
+             {.uci = "a4d7", .san = "Qxd7+"}, {.uci = "e8d7", .san = "Kxd7"},
+             {.uci = "d3f5", .san = "Bf5+"},  {.uci = "d7e8", .san = "Ke8"},
+             {.uci = "f5d7", .san = "Bd7+"},  {.uci = "e8f8", .san = "Kf8"},
+             {.uci = "a3e7", .san = "Bxe7#"},
+         }},
+    {.desc = "P. Morphy / D. Karl / 1858\n\"The opera game\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 33,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},    {.uci = "e7e5", .san = "e5"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "d7d6", .san = "d6"},
+             {.uci = "d2d4", .san = "d4"},    {.uci = "c8g4", .san = "Bg4"},
+             {.uci = "d4e5", .san = "dxe5"},  {.uci = "g4f3", .san = "Bxf3"},
+             {.uci = "d1f3", .san = "Qxf3"},  {.uci = "d6e5", .san = "dxe5"},
+             {.uci = "f1c4", .san = "Bc4"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "f3b3", .san = "Qb3"},   {.uci = "d8e7", .san = "Qe7"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "c7c6", .san = "c6"},
+             {.uci = "c1g5", .san = "Bg5"},   {.uci = "b7b5", .san = "b5"},
+             {.uci = "c3b5", .san = "Nxb5"},  {.uci = "c6b5", .san = "cxb5"},
+             {.uci = "c4b5", .san = "Bxb5+"}, {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "e1c1", .san = "O-O-O"}, {.uci = "a8d8", .san = "Rd8"},
+             {.uci = "d1d7", .san = "Rxd7"},  {.uci = "d8d7", .san = "Rxd7"},
+             {.uci = "h1d1", .san = "Rd1"},   {.uci = "e7e6", .san = "Qe6"},
+             {.uci = "b5d7", .san = "Bxd7+"}, {.uci = "f6d7", .san = "Nxd7"},
+             {.uci = "b3b8", .san = "Qb8+"},  {.uci = "d7b8", .san = "Nxb8"},
+             {.uci = "d1d8", .san = "Rd8#"},
+         }},
+    {.desc = "G. Rotlewi / A. Rubinstein / 1907\n\"Rotlewi's immortal game\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 50,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},   {.uci = "d7d5", .san = "d5"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "e7e6", .san = "e6"},
+             {.uci = "e2e3", .san = "e3"},   {.uci = "c7c5", .san = "c5"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "d4c5", .san = "dxc5"}, {.uci = "f8c5", .san = "Bxc5"},
+             {.uci = "a2a3", .san = "a3"},   {.uci = "a7a6", .san = "a6"},
+             {.uci = "b2b4", .san = "b4"},   {.uci = "c5d6", .san = "Bd6"},
+             {.uci = "c1b2", .san = "Bb2"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "d1d2", .san = "Qd2"},  {.uci = "d8e7", .san = "Qe7"},
+             {.uci = "f1d3", .san = "Bd3"},  {.uci = "d5c4", .san = "dxc4"},
+             {.uci = "d3c4", .san = "Bxc4"}, {.uci = "b7b5", .san = "b5"},
+             {.uci = "c4d3", .san = "Bd3"},  {.uci = "f8d8", .san = "Rd8"},
+             {.uci = "d2e2", .san = "Qe2"},  {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "e1g1", .san = "O-O"},  {.uci = "c6e5", .san = "Ne5"},
+             {.uci = "f3e5", .san = "Nxe5"}, {.uci = "d6e5", .san = "Bxe5"},
+             {.uci = "f2f4", .san = "f4"},   {.uci = "e5c7", .san = "Bc7"},
+             {.uci = "e3e4", .san = "e4"},   {.uci = "a8c8", .san = "Rac8"},
+             {.uci = "e4e5", .san = "e5"},   {.uci = "c7b6", .san = "Bb6+"},
+             {.uci = "g1h1", .san = "Kh1"},  {.uci = "f6g4", .san = "Ng4"},
+             {.uci = "d3e4", .san = "Be4"},  {.uci = "e7h4", .san = "Qh4"},
+             {.uci = "g2g3", .san = "g3"},   {.uci = "c8c3", .san = "Rxc3"},
+             {.uci = "g3h4", .san = "gxh4"}, {.uci = "d8d2", .san = "Rd2"},
+             {.uci = "e2d2", .san = "Qxd2"}, {.uci = "b7e4", .san = "Bxe4+"},
+             {.uci = "d2g2", .san = "Qg2"},  {.uci = "c3h3", .san = "Rh3"},
+         }},
+    {.desc = "E. Bogoljubov / A. Alekhine / 1922.09.21 / Hastings",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 106,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},
+             {.uci = "f7f5", .san = "f5"},
+             {.uci = "c2c4", .san = "c4"},
+             {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "g2g3", .san = "g3"},
+             {.uci = "e7e6", .san = "e6"},
+             {.uci = "f1g2", .san = "Bg2"},
+             {.uci = "f8b4", .san = "Bb4+"},
+             {.uci = "c1d2", .san = "Bd2"},
+             {.uci = "b4d2", .san = "Bxd2+"},
+             {.uci = "b1d2", .san = "Nxd2"},
+             {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "g1f3", .san = "Ngf3"},
+             {.uci = "e8g8", .san = "O-O"},
+             {.uci = "e1g1", .san = "O-O"},
+             {.uci = "d7d6", .san = "d6"},
+             {.uci = "d1b3", .san = "Qb3"},
+             {.uci = "g8h8", .san = "Kh8"},
+             {.uci = "b3c3", .san = "Qc3"},
+             {.uci = "e6e5", .san = "e5"},
+             {.uci = "e2e3", .san = "e3"},
+             {.uci = "a7a5", .san = "a5"},
+             {.uci = "b2b3", .san = "b3"},
+             {.uci = "d8e8", .san = "Qe8"},
+             {.uci = "a2a3", .san = "a3"},
+             {.uci = "e8h5", .san = "Qh5"},
+             {.uci = "h2h4", .san = "h4"},
+             {.uci = "f6g4", .san = "Ng4"},
+             {.uci = "f3g5", .san = "Ng5"},
+             {.uci = "c8d7", .san = "Bd7"},
+             {.uci = "f2f3", .san = "f3"},
+             {.uci = "g4f6", .san = "Nf6"},
+             {.uci = "f3f4", .san = "f4"},
+             {.uci = "e5e4", .san = "e4"},
+             {.uci = "f1d1", .san = "Rfd1"},
+             {.uci = "h7h6", .san = "h6"},
+             {.uci = "g5h3", .san = "Nh3"},
+             {.uci = "d6d5", .san = "d5"},
+             {.uci = "d2f1", .san = "Nf1"},
+             {.uci = "c6e7", .san = "Ne7"},
+             {.uci = "a3a4", .san = "a4"},
+             {.uci = "e7c6", .san = "Nc6"},
+             {.uci = "d1d2", .san = "Rd2"},
+             {.uci = "c6b4", .san = "Nb4"},
+             {.uci = "g2h1", .san = "Bh1"},
+             {.uci = "h5e8", .san = "Qe8"},
+             {.uci = "d2g2", .san = "Rg2"},
+             {.uci = "d5c4", .san = "dxc4"},
+             {.uci = "b3c4", .san = "bxc4"},
+             {.uci = "d7a4", .san = "Bxa4"},
+             {.uci = "h3f2", .san = "Nf2"},
+             {.uci = "a4d7", .san = "Bd7"},
+             {.uci = "f1d2", .san = "Nd2"},
+             {.uci = "b7b5", .san = "b5"},
+             {.uci = "f2d1", .san = "Nd1"},
+             {.uci = "b4d3", .san = "Nd3"},
+             {.uci = "a1a5", .san = "Rxa5"},
+             {.uci = "b5b4", .san = "b4"},
+             {.uci = "a5a8", .san = "Rxa8"},
+             {.uci = "b4c3", .san = "bxc3"},
+             {.uci = "a8e8", .san = "Rxe8"},
+             {.uci = "c3c2", .san = "c2"},
+             {.uci = "e8f8", .san = "Rxf8+"},
+             {.uci = "h8h7", .san = "Kh7"},
+             {.uci = "d1f2", .san = "Nf2"},
+             {.uci = "c2c1q", .san = "c1=Q+"},
+             {.uci = "d2f1", .san = "Nf1"},
+             {.uci = "d3e1", .san = "Ne1"},
+             {.uci = "g2h2", .san = "Rh2"},
+             {.uci = "c1c4", .san = "Qxc4"},
+             {.uci = "f8b8", .san = "Rb8"},
+             {.uci = "d7b5", .san = "Bb5"},
+             {.uci = "b8b5", .san = "Rxb5"},
+             {.uci = "c4b5", .san = "Qxb5"},
+             {.uci = "g3g4", .san = "g4"},
+             {.uci = "e1f3", .san = "Nf3+"},
+             {.uci = "h1f3", .san = "Bxf3"},
+             {.uci = "e4f3", .san = "exf3"},
+             {.uci = "g4f5", .san = "gxf5"},
+             {.uci = "b5e2", .san = "Qe2"},
+             {.uci = "d4d5", .san = "d5"},
+             {.uci = "h7g8", .san = "Kg8"},
+             {.uci = "h4h5", .san = "h5"},
+             {.uci = "g8h7", .san = "Kh7"},
+             {.uci = "e3e4", .san = "e4"},
+             {.uci = "f6e4", .san = "Nxe4"},
+             {.uci = "f2e4", .san = "Nxe4"},
+             {.uci = "e2e4", .san = "Qxe4"},
+             {.uci = "d5d6", .san = "d6"},
+             {.uci = "c7d6", .san = "cxd6"},
+             {.uci = "f5f6", .san = "f6"},
+             {.uci = "g7f6", .san = "gxf6"},
+             {.uci = "h2d2", .san = "Rd2"},
+             {.uci = "e4e2", .san = "Qe2"},
+             {.uci = "d2e2", .san = "Rxe2"},
+             {.uci = "f3e2", .san = "fxe2"},
+             {.uci = "g1f2", .san = "Kf2"},
+             {.uci = "e2f1q", .san = "exf1=Q+"},
+             {.uci = "f2f1", .san = "Kxf1"},
+             {.uci = "h7g7", .san = "Kg7"},
+             {.uci = "f1e2", .san = "Ke2"},
+             {.uci = "g7f7", .san = "Kf7"},
+             {.uci = "e2e3", .san = "Ke3"},
+             {.uci = "f7e6", .san = "Ke6"},
+             {.uci = "e3e4", .san = "Ke4"},
+             {.uci = "d6d5", .san = "d5+"},
+         }},
+    {.desc = "Glucksberg / M. Najdorf / 1929\n\"The Polish immortal\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 44,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},   {.uci = "f7f5", .san = "f5"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "e7e6", .san = "e6"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "d7d5", .san = "d5"},
+             {.uci = "e2e3", .san = "e3"},   {.uci = "c7c6", .san = "c6"},
+             {.uci = "f1d3", .san = "Bd3"},  {.uci = "f8d6", .san = "Bd6"},
+             {.uci = "e1g1", .san = "O-O"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "c3e2", .san = "Ne2"},  {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "f3g5", .san = "Ng5"},  {.uci = "d6h2", .san = "Bxh2+"},
+             {.uci = "g1h1", .san = "Kh1"},  {.uci = "f6g4", .san = "Ng4"},
+             {.uci = "f2f4", .san = "f4"},   {.uci = "d8e8", .san = "Qe8"},
+             {.uci = "g2g3", .san = "g3"},   {.uci = "e8h5", .san = "Qh5"},
+             {.uci = "h1g2", .san = "Kg2"},  {.uci = "h2g1", .san = "Bg1"},
+             {.uci = "e2g1", .san = "Nxg1"}, {.uci = "h5h2", .san = "Qh2+"},
+             {.uci = "g2f3", .san = "Kf3"},  {.uci = "e6e5", .san = "e5"},
+             {.uci = "d4e5", .san = "dxe5"}, {.uci = "d7e5", .san = "Ndxe5+"},
+             {.uci = "f4e5", .san = "fxe5"}, {.uci = "g4e5", .san = "Nxe5+"},
+             {.uci = "f3f4", .san = "Kf4"},  {.uci = "e5g6", .san = "Ng6+"},
+             {.uci = "f4f3", .san = "Kf3"},  {.uci = "f5f4", .san = "f4"},
+             {.uci = "e3f4", .san = "exf4"}, {.uci = "c8g4", .san = "Bg4+"},
+             {.uci = "f3g4", .san = "Kxg4"}, {.uci = "g6e5", .san = "Ne5+"},
+             {.uci = "f4e5", .san = "fxe5"}, {.uci = "h7h5", .san = "h5#"},
+         }},
+    {.desc = "D. Byrne / R. J. Fischer / 1956\n\"The game of the century\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 82,
+     .moves =
+         {
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "g7g6", .san = "g6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "f8g7", .san = "Bg7"},
+             {.uci = "d2d4", .san = "d4"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "c1f4", .san = "Bf4"},  {.uci = "d7d5", .san = "d5"},
+             {.uci = "d1b3", .san = "Qb3"},  {.uci = "d5c4", .san = "dxc4"},
+             {.uci = "b3c4", .san = "Qxc4"}, {.uci = "c7c6", .san = "c6"},
+             {.uci = "e2e4", .san = "e4"},   {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "a1d1", .san = "Rd1"},  {.uci = "d7b6", .san = "Nb6"},
+             {.uci = "c4c5", .san = "Qc5"},  {.uci = "c8g4", .san = "Bg4"},
+             {.uci = "f4g5", .san = "Bg5"},  {.uci = "b6a4", .san = "Na4"},
+             {.uci = "c5a3", .san = "Qa3"},  {.uci = "a4c3", .san = "Nxc3"},
+             {.uci = "b2c3", .san = "bxc3"}, {.uci = "f6e4", .san = "Nxe4"},
+             {.uci = "g5e7", .san = "Bxe7"}, {.uci = "d8b6", .san = "Qb6"},
+             {.uci = "f1c4", .san = "Bc4"},  {.uci = "e4c3", .san = "Nxc3"},
+             {.uci = "e7c5", .san = "Bc5"},  {.uci = "f8e8", .san = "Rfe8+"},
+             {.uci = "e1f1", .san = "Kf1"},  {.uci = "g4e6", .san = "Be6"},
+             {.uci = "c5b6", .san = "Bxb6"}, {.uci = "e6c4", .san = "Bxc4+"},
+             {.uci = "f1g1", .san = "Kg1"},  {.uci = "c3e2", .san = "Ne2+"},
+             {.uci = "g1f1", .san = "Kf1"},  {.uci = "e2d4", .san = "Nxd4+"},
+             {.uci = "f1g1", .san = "Kg1"},  {.uci = "d4e2", .san = "Ne2+"},
+             {.uci = "g1f1", .san = "Kf1"},  {.uci = "e2c3", .san = "Nc3+"},
+             {.uci = "f1g1", .san = "Kg1"},  {.uci = "a7b6", .san = "axb6"},
+             {.uci = "a3b4", .san = "Qb4"},  {.uci = "a8a4", .san = "Ra4"},
+             {.uci = "b4b6", .san = "Qxb6"}, {.uci = "c3d1", .san = "Nxd1"},
+             {.uci = "h2h3", .san = "h3"},   {.uci = "a4a2", .san = "Rxa2"},
+             {.uci = "g1h2", .san = "Kh2"},  {.uci = "d1f2", .san = "Nxf2"},
+             {.uci = "h1e1", .san = "Re1"},  {.uci = "e8e1", .san = "Rxe1"},
+             {.uci = "b6d8", .san = "Qd8+"}, {.uci = "g7f8", .san = "Bf8"},
+             {.uci = "f3e1", .san = "Nxe1"}, {.uci = "c4d5", .san = "Bd5"},
+             {.uci = "e1f3", .san = "Nf3"},  {.uci = "f2e4", .san = "Ne4"},
+             {.uci = "d8b8", .san = "Qb8"},  {.uci = "b7b5", .san = "b5"},
+             {.uci = "h3h4", .san = "h4"},   {.uci = "h7h5", .san = "h5"},
+             {.uci = "f3e5", .san = "Ne5"},  {.uci = "g8g7", .san = "Kg7"},
+             {.uci = "h2g1", .san = "Kg1"},  {.uci = "f8c5", .san = "Bc5+"},
+             {.uci = "g1f1", .san = "Kf1"},  {.uci = "e4g3", .san = "Ng3+"},
+             {.uci = "f1e1", .san = "Ke1"},  {.uci = "c5b4", .san = "Bb4+"},
+             {.uci = "e1d1", .san = "Kd1"},  {.uci = "d5b3", .san = "Bb3+"},
+             {.uci = "d1c1", .san = "Kc1"},  {.uci = "g3e2", .san = "Ne2+"},
+             {.uci = "c1b1", .san = "Kb1"},  {.uci = "e2c3", .san = "Nc3+"},
+             {.uci = "b1c1", .san = "Kc1"},  {.uci = "a2c2", .san = "Rc2#"},
+         }},
+    {.desc = "G. Kasparov / V. Topalov / 1999\n\"Kasparov's immortal\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 87,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},    {.uci = "d7d6", .san = "d6"},
+             {.uci = "d2d4", .san = "d4"},    {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "g7g6", .san = "g6"},
+             {.uci = "c1e3", .san = "Be3"},   {.uci = "f8g7", .san = "Bg7"},
+             {.uci = "d1d2", .san = "Qd2"},   {.uci = "c7c6", .san = "c6"},
+             {.uci = "f2f3", .san = "f3"},    {.uci = "b7b5", .san = "b5"},
+             {.uci = "g1e2", .san = "Nge2"},  {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "e3h6", .san = "Bh6"},   {.uci = "g7h6", .san = "Bxh6"},
+             {.uci = "d2h6", .san = "Qxh6"},  {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "a2a3", .san = "a3"},    {.uci = "e7e5", .san = "e5"},
+             {.uci = "e1c1", .san = "O-O-O"}, {.uci = "d8e7", .san = "Qe7"},
+             {.uci = "c1b1", .san = "Kb1"},   {.uci = "a7a6", .san = "a6"},
+             {.uci = "e2c1", .san = "Nc1"},   {.uci = "e8c8", .san = "O-O-O"},
+             {.uci = "c1b3", .san = "Nb3"},   {.uci = "e5d4", .san = "exd4"},
+             {.uci = "d1d4", .san = "Rxd4"},  {.uci = "c6c5", .san = "c5"},
+             {.uci = "d4d1", .san = "Rd1"},   {.uci = "d7b6", .san = "Nb6"},
+             {.uci = "g2g3", .san = "g3"},    {.uci = "c8b8", .san = "Kb8"},
+             {.uci = "b3a5", .san = "Na5"},   {.uci = "b7a8", .san = "Ba8"},
+             {.uci = "f1h3", .san = "Bh3"},   {.uci = "d6d5", .san = "d5"},
+             {.uci = "h6f4", .san = "Qf4+"},  {.uci = "b8a7", .san = "Ka7"},
+             {.uci = "h1e1", .san = "Rhe1"},  {.uci = "d5d4", .san = "d4"},
+             {.uci = "c3d5", .san = "Nd5"},   {.uci = "b6d5", .san = "Nbxd5"},
+             {.uci = "e4d5", .san = "exd5"},  {.uci = "e7d6", .san = "Qd6"},
+             {.uci = "d1d4", .san = "Rxd4"},  {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "e1e7", .san = "Re7+"},  {.uci = "a7b6", .san = "Kb6"},
+             {.uci = "f4d4", .san = "Qxd4+"}, {.uci = "b6a5", .san = "Kxa5"},
+             {.uci = "b2b4", .san = "b4+"},   {.uci = "a5a4", .san = "Ka4"},
+             {.uci = "d4c3", .san = "Qc3"},   {.uci = "d6d5", .san = "Qxd5"},
+             {.uci = "e7a7", .san = "Ra7"},   {.uci = "a8b7", .san = "Bb7"},
+             {.uci = "a7b7", .san = "Rxb7"},  {.uci = "d5c4", .san = "Qc4"},
+             {.uci = "c3f6", .san = "Qxf6"},  {.uci = "a4a3", .san = "Kxa3"},
+             {.uci = "f6a6", .san = "Qxa6+"}, {.uci = "a3b4", .san = "Kxb4"},
+             {.uci = "c2c3", .san = "c3+"},   {.uci = "b4c3", .san = "Kxc3"},
+             {.uci = "a6a1", .san = "Qa1+"},  {.uci = "c3d2", .san = "Kd2"},
+             {.uci = "a1b2", .san = "Qb2+"},  {.uci = "d2d1", .san = "Kd1"},
+             {.uci = "h3f1", .san = "Bf1"},   {.uci = "d8d2", .san = "Rd2"},
+             {.uci = "b7d7", .san = "Rd7"},   {.uci = "d2d7", .san = "Rxd7"},
+             {.uci = "f1c4", .san = "Bxc4"},  {.uci = "b5c4", .san = "bxc4"},
+             {.uci = "b2h8", .san = "Qxh8"},  {.uci = "d7d3", .san = "Rd3"},
+             {.uci = "h8a8", .san = "Qa8"},   {.uci = "c4c3", .san = "c3"},
+             {.uci = "a8a4", .san = "Qa4+"},  {.uci = "d1e1", .san = "Ke1"},
+             {.uci = "f3f4", .san = "f4"},    {.uci = "f7f5", .san = "f5"},
+             {.uci = "b1c1", .san = "Kc1"},   {.uci = "d3d2", .san = "Rd2"},
+             {.uci = "a4a7", .san = "Qa7"},
+         }},
+    {.desc = "W. Yi / L. B. Bruzon / 2015.07.03\n6th Hainan Danzhou",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 71,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},    {.uci = "c7c5", .san = "c5"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "e7e6", .san = "e6"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "a7a6", .san = "a6"},
+             {.uci = "f1e2", .san = "Be2"},   {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "d2d4", .san = "d4"},    {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "f3d4", .san = "Nxd4"},  {.uci = "d8c7", .san = "Qc7"},
+             {.uci = "e1g1", .san = "O-O"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c1e3", .san = "Be3"},   {.uci = "f8e7", .san = "Be7"},
+             {.uci = "f2f4", .san = "f4"},    {.uci = "d7d6", .san = "d6"},
+             {.uci = "g1h1", .san = "Kh1"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "d1e1", .san = "Qe1"},   {.uci = "c6d4", .san = "Nxd4"},
+             {.uci = "e3d4", .san = "Bxd4"},  {.uci = "b7b5", .san = "b5"},
+             {.uci = "e1g3", .san = "Qg3"},   {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "a2a3", .san = "a3"},    {.uci = "a8d8", .san = "Rad8"},
+             {.uci = "a1e1", .san = "Rae1"},  {.uci = "d8d7", .san = "Rd7"},
+             {.uci = "e2d3", .san = "Bd3"},   {.uci = "c7d8", .san = "Qd8"},
+             {.uci = "g3h3", .san = "Qh3"},   {.uci = "g7g6", .san = "g6"},
+             {.uci = "f4f5", .san = "f5"},    {.uci = "e6e5", .san = "e5"},
+             {.uci = "d4e3", .san = "Be3"},   {.uci = "f8e8", .san = "Re8"},
+             {.uci = "f5g6", .san = "fxg6"},  {.uci = "h7g6", .san = "hxg6"},
+             {.uci = "c3d5", .san = "Nd5"},   {.uci = "f6d5", .san = "Nxd5"},
+             {.uci = "f1f7", .san = "Rxf7"},  {.uci = "g8f7", .san = "Kxf7"},
+             {.uci = "h3h7", .san = "Qh7+"},  {.uci = "f7e6", .san = "Ke6"},
+             {.uci = "e4d5", .san = "exd5+"}, {.uci = "e6d5", .san = "Kxd5"},
+             {.uci = "d3e4", .san = "Be4+"},  {.uci = "d5e4", .san = "Kxe4"},
+             {.uci = "h7f7", .san = "Qf7"},   {.uci = "e7f6", .san = "Bf6"},
+             {.uci = "e3d2", .san = "Bd2+"},  {.uci = "e4d4", .san = "Kd4"},
+             {.uci = "d2e3", .san = "Be3+"},  {.uci = "d4e4", .san = "Ke4"},
+             {.uci = "f7b3", .san = "Qb3"},   {.uci = "e4f5", .san = "Kf5"},
+             {.uci = "e1f1", .san = "Rf1+"},  {.uci = "f5g4", .san = "Kg4"},
+             {.uci = "b3d3", .san = "Qd3"},   {.uci = "b7g2", .san = "Bxg2+"},
+             {.uci = "h1g2", .san = "Kxg2"},  {.uci = "d8a8", .san = "Qa8+"},
+             {.uci = "g2g1", .san = "Kg1"},   {.uci = "f6g5", .san = "Bg5"},
+             {.uci = "d3e2", .san = "Qe2+"},  {.uci = "g4h4", .san = "Kh4"},
+             {.uci = "e3f2", .san = "Bf2+"},  {.uci = "h4h3", .san = "Kh3"},
+             {.uci = "f2e1", .san = "Be1"},
+         }},
+    {.desc = "L. Polugaevsky / R. G. Nezhmetdinov / 1958 / Sochi",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 66,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},     {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},     {.uci = "d7d6", .san = "d6"},
+             {.uci = "b1c3", .san = "Nc3"},    {.uci = "e7e5", .san = "e5"},
+             {.uci = "e2e4", .san = "e4"},     {.uci = "e5d4", .san = "exd4"},
+             {.uci = "d1d4", .san = "Qxd4"},   {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "d4d2", .san = "Qd2"},    {.uci = "g7g6", .san = "g6"},
+             {.uci = "b2b3", .san = "b3"},     {.uci = "f8g7", .san = "Bg7"},
+             {.uci = "c1b2", .san = "Bb2"},    {.uci = "e8g8", .san = "O-O"},
+             {.uci = "f1d3", .san = "Bd3"},    {.uci = "f6g4", .san = "Ng4"},
+             {.uci = "g1e2", .san = "Nge2"},   {.uci = "d8h4", .san = "Qh4"},
+             {.uci = "e2g3", .san = "Ng3"},    {.uci = "g4e5", .san = "Nge5"},
+             {.uci = "e1g1", .san = "O-O"},    {.uci = "f7f5", .san = "f5"},
+             {.uci = "f2f3", .san = "f3"},     {.uci = "g7h6", .san = "Bh6"},
+             {.uci = "d2d1", .san = "Qd1"},    {.uci = "f5f4", .san = "f4"},
+             {.uci = "g3e2", .san = "Nge2"},   {.uci = "g6g5", .san = "g5"},
+             {.uci = "c3d5", .san = "Nd5"},    {.uci = "g5g4", .san = "g4"},
+             {.uci = "g2g3", .san = "g3"},     {.uci = "f4g3", .san = "fxg3"},
+             {.uci = "h2g3", .san = "hxg3"},   {.uci = "h4h3", .san = "Qh3"},
+             {.uci = "f3f4", .san = "f4"},     {.uci = "c8e6", .san = "Be6"},
+             {.uci = "d3c2", .san = "Bc2"},    {.uci = "f8f7", .san = "Rf7"},
+             {.uci = "g1f2", .san = "Kf2"},    {.uci = "h3h2", .san = "Qh2+"},
+             {.uci = "f2e3", .san = "Ke3"},    {.uci = "e6d5", .san = "Bxd5"},
+             {.uci = "c4d5", .san = "cxd5"},   {.uci = "c6b4", .san = "Nb4"},
+             {.uci = "f1h1", .san = "Rh1"},    {.uci = "f7f4", .san = "Rxf4"},
+             {.uci = "h1h2", .san = "Rxh2"},   {.uci = "f4f3", .san = "Rf3+"},
+             {.uci = "e3d4", .san = "Kd4"},    {.uci = "h6g7", .san = "Bg7"},
+             {.uci = "a2a4", .san = "a4"},     {.uci = "c7c5", .san = "c5+"},
+             {.uci = "d5c6", .san = "dxc6"}, /* e.p. */
+             {.uci = "b7c6", .san = "bxc6"},   {.uci = "c2d3", .san = "Bd3"},
+             {.uci = "e5d3", .san = "Nexd3+"}, {.uci = "d4c4", .san = "Kc4"},
+             {.uci = "d6d5", .san = "d5+"},    {.uci = "e4d5", .san = "exd5"},
+             {.uci = "c6d5", .san = "cxd5+"},  {.uci = "c4b5", .san = "Kb5"},
+             {.uci = "a8b8", .san = "Rb8+"},   {.uci = "b5a5", .san = "Ka5"},
+             {.uci = "b4c6", .san = "Nc6+"},
+         }},
+    {.desc = "M. Botvinnik / J. R. Capablanca / 1938.11.22 / Rotterdam",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 81,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "e7e6", .san = "e6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "f8b4", .san = "Bb4"},
+             {.uci = "e2e3", .san = "e3"},   {.uci = "d7d5", .san = "d5"},
+             {.uci = "a2a3", .san = "a3"},   {.uci = "b4c3", .san = "Bxc3+"},
+             {.uci = "b2c3", .san = "bxc3"}, {.uci = "c7c5", .san = "c5"},
+             {.uci = "c4d5", .san = "cxd5"}, {.uci = "e6d5", .san = "exd5"},
+             {.uci = "f1d3", .san = "Bd3"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "g1e2", .san = "Ne2"},  {.uci = "b7b6", .san = "b6"},
+             {.uci = "e1g1", .san = "O-O"},  {.uci = "c8a6", .san = "Ba6"},
+             {.uci = "d3a6", .san = "Bxa6"}, {.uci = "b8a6", .san = "Nxa6"},
+             {.uci = "c1b2", .san = "Bb2"},  {.uci = "d8d7", .san = "Qd7"},
+             {.uci = "a3a4", .san = "a4"},   {.uci = "f8e8", .san = "Rfe8"},
+             {.uci = "d1d3", .san = "Qd3"},  {.uci = "c5c4", .san = "c4"},
+             {.uci = "d3c2", .san = "Qc2"},  {.uci = "a6b8", .san = "Nb8"},
+             {.uci = "a1e1", .san = "Rae1"}, {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "e2g3", .san = "Ng3"},  {.uci = "c6a5", .san = "Na5"},
+             {.uci = "f2f3", .san = "f3"},   {.uci = "a5b3", .san = "Nb3"},
+             {.uci = "e3e4", .san = "e4"},   {.uci = "d7a4", .san = "Qxa4"},
+             {.uci = "e4e5", .san = "e5"},   {.uci = "f6d7", .san = "Nd7"},
+             {.uci = "c2f2", .san = "Qf2"},  {.uci = "g7g6", .san = "g6"},
+             {.uci = "f3f4", .san = "f4"},   {.uci = "f7f5", .san = "f5"},
+             {.uci = "e5f6", .san = "exf6"}, /* e.p. */
+             {.uci = "d7f6", .san = "Nxf6"}, {.uci = "f4f5", .san = "f5"},
+             {.uci = "e8e1", .san = "Rxe1"}, {.uci = "f1e1", .san = "Rxe1"},
+             {.uci = "a8e8", .san = "Re8"},  {.uci = "e1e6", .san = "Re6"},
+             {.uci = "e8e6", .san = "Rxe6"}, {.uci = "f5e6", .san = "fxe6"},
+             {.uci = "g8g7", .san = "Kg7"},  {.uci = "f2f4", .san = "Qf4"},
+             {.uci = "a4e8", .san = "Qe8"},  {.uci = "f4e5", .san = "Qe5"},
+             {.uci = "e8e7", .san = "Qe7"},  {.uci = "b2a3", .san = "Ba3"},
+             {.uci = "e7a3", .san = "Qxa3"}, {.uci = "g3h5", .san = "Nh5+"},
+             {.uci = "g6h5", .san = "gxh5"}, {.uci = "e5g5", .san = "Qg5+"},
+             {.uci = "g7f8", .san = "Kf8"},  {.uci = "g5f6", .san = "Qxf6+"},
+             {.uci = "f8g8", .san = "Kg8"},  {.uci = "e6e7", .san = "e7"},
+             {.uci = "a3c1", .san = "Qc1+"}, {.uci = "g1f2", .san = "Kf2"},
+             {.uci = "c1c2", .san = "Qc2+"}, {.uci = "f2g3", .san = "Kg3"},
+             {.uci = "c2d3", .san = "Qd3+"}, {.uci = "g3h4", .san = "Kh4"},
+             {.uci = "d3e4", .san = "Qe4+"}, {.uci = "h4h5", .san = "Kxh5"},
+             {.uci = "e4e2", .san = "Qe2+"}, {.uci = "h5h4", .san = "Kh4"},
+             {.uci = "e2e4", .san = "Qe4+"}, {.uci = "g2g4", .san = "g4"},
+             {.uci = "e4e1", .san = "Qe1+"}, {.uci = "h4h5", .san = "Kh5"},
+         }},
+    {.desc = "V. Bagirov / E. Gufeld / 1973\n\"Mona Lisa\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 64,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},    {.uci = "g7g6", .san = "g6"},
+             {.uci = "c2c4", .san = "c4"},    {.uci = "f8g7", .san = "Bg7"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "d7d6", .san = "d6"},
+             {.uci = "e2e4", .san = "e4"},    {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "f2f3", .san = "f3"},    {.uci = "e8g8", .san = "O-O"},
+             {.uci = "c1e3", .san = "Be3"},   {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "g1e2", .san = "Nge2"},  {.uci = "a8b8", .san = "Rb8"},
+             {.uci = "d1d2", .san = "Qd2"},   {.uci = "a7a6", .san = "a6"},
+             {.uci = "e3h6", .san = "Bh6"},   {.uci = "b7b5", .san = "b5"},
+             {.uci = "h2h4", .san = "h4"},    {.uci = "e7e5", .san = "e5"},
+             {.uci = "h6g7", .san = "Bxg7"},  {.uci = "g8g7", .san = "Kxg7"},
+             {.uci = "h4h5", .san = "h5"},    {.uci = "g7h8", .san = "Kh8"},
+             {.uci = "c3d5", .san = "Nd5"},   {.uci = "b5c4", .san = "bxc4"},
+             {.uci = "h5g6", .san = "hxg6"},  {.uci = "f7g6", .san = "fxg6"},
+             {.uci = "d2h6", .san = "Qh6"},   {.uci = "f6h5", .san = "Nh5"},
+             {.uci = "g2g4", .san = "g4"},    {.uci = "b8b2", .san = "Rxb2"},
+             {.uci = "g4h5", .san = "gxh5"},  {.uci = "g6g5", .san = "g5"},
+             {.uci = "h1g1", .san = "Rg1"},   {.uci = "g5g4", .san = "g4"},
+             {.uci = "e1c1", .san = "O-O-O"}, {.uci = "b2a2", .san = "Rxa2"},
+             {.uci = "e2f4", .san = "Nef4"},  {.uci = "e5f4", .san = "exf4"},
+             {.uci = "d5f4", .san = "Nxf4"},  {.uci = "f8f4", .san = "Rxf4"},
+             {.uci = "h6f4", .san = "Qxf4"},  {.uci = "c4c3", .san = "c3"},
+             {.uci = "f1c4", .san = "Bc4"},   {.uci = "a2a3", .san = "Ra3"},
+             {.uci = "f3g4", .san = "fxg4"},  {.uci = "c6b4", .san = "Nb4"},
+             {.uci = "c1b1", .san = "Kb1"},   {.uci = "c8e6", .san = "Be6"},
+             {.uci = "c4e6", .san = "Bxe6"},  {.uci = "b4d3", .san = "Nd3"},
+             {.uci = "f4f7", .san = "Qf7"},   {.uci = "d8b8", .san = "Qb8+"},
+             {.uci = "e6b3", .san = "Bb3"},   {.uci = "a3b3", .san = "Rxb3+"},
+             {.uci = "b1c2", .san = "Kc2"},   {.uci = "d3b4", .san = "Nb4+"},
+             {.uci = "c2b3", .san = "Kxb3"},  {.uci = "b4d5", .san = "Nd5+"},
+             {.uci = "b3c2", .san = "Kc2"},   {.uci = "b8b2", .san = "Qb2+"},
+             {.uci = "c2d3", .san = "Kd3"},   {.uci = "b2b5", .san = "Qb5+"},
+         }},
+    {.desc = "A. Beliavsky / J. Nunn / 1985",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 54,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "g7g6", .san = "g6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "f8g7", .san = "Bg7"},
+             {.uci = "e2e4", .san = "e4"},   {.uci = "d7d6", .san = "d6"},
+             {.uci = "f2f3", .san = "f3"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "c1e3", .san = "Be3"},  {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "d1d2", .san = "Qd2"},  {.uci = "c7c5", .san = "c5"},
+             {.uci = "d4d5", .san = "d5"},   {.uci = "d7e5", .san = "Ne5"},
+             {.uci = "h2h3", .san = "h3"},   {.uci = "f6h5", .san = "Nh5"},
+             {.uci = "e3f2", .san = "Bf2"},  {.uci = "f7f5", .san = "f5"},
+             {.uci = "e4f5", .san = "exf5"}, {.uci = "f8f5", .san = "Rxf5"},
+             {.uci = "g2g4", .san = "g4"},   {.uci = "f5f3", .san = "Rxf3"},
+             {.uci = "g4h5", .san = "gxh5"}, {.uci = "d8f8", .san = "Qf8"},
+             {.uci = "c3e4", .san = "Ne4"},  {.uci = "g7h6", .san = "Bh6"},
+             {.uci = "d2c2", .san = "Qc2"},  {.uci = "f8f4", .san = "Qf4"},
+             {.uci = "g1e2", .san = "Ne2"},  {.uci = "f3f2", .san = "Rxf2"},
+             {.uci = "e4f2", .san = "Nxf2"}, {.uci = "e5f3", .san = "Nf3+"},
+             {.uci = "e1d1", .san = "Kd1"},  {.uci = "f4h4", .san = "Qh4"},
+             {.uci = "f2d3", .san = "Nd3"},  {.uci = "c8f5", .san = "Bf5"},
+             {.uci = "e2c1", .san = "Nec1"}, {.uci = "f3d2", .san = "Nd2"},
+             {.uci = "h5g6", .san = "hxg6"}, {.uci = "h7g6", .san = "hxg6"},
+             {.uci = "f1g2", .san = "Bg2"},  {.uci = "d2c4", .san = "Nxc4"},
+             {.uci = "c2f2", .san = "Qf2"},  {.uci = "c4e3", .san = "Ne3+"},
+             {.uci = "d1e2", .san = "Ke2"},  {.uci = "h4c4", .san = "Qc4"},
+             {.uci = "g2f3", .san = "Bf3"},  {.uci = "a8f8", .san = "Rf8"},
+             {.uci = "h1g1", .san = "Rg1"},  {.uci = "e3c2", .san = "Nc2"},
+             {.uci = "e2d1", .san = "Kd1"},  {.uci = "f5d3", .san = "Bxd3"},
+         }},
+    {.desc = "A. Shirov / J. Polgar / 1994 / Buenos Aires",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 58,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},   {.uci = "c7c5", .san = "c5"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "e7e6", .san = "e6"},
+             {.uci = "d2d4", .san = "d4"},   {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "f3d4", .san = "Nxd4"}, {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "d7d6", .san = "d6"},
+             {.uci = "g2g4", .san = "g4"},   {.uci = "a7a6", .san = "a6"},
+             {.uci = "c1e3", .san = "Be3"},  {.uci = "g8e7", .san = "Nge7"},
+             {.uci = "d4b3", .san = "Nb3"},  {.uci = "b7b5", .san = "b5"},
+             {.uci = "f2f4", .san = "f4"},   {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "d1f3", .san = "Qf3"},  {.uci = "g7g5", .san = "g5"},
+             {.uci = "f4g5", .san = "fxg5"}, {.uci = "c6e5", .san = "Ne5"},
+             {.uci = "f3g2", .san = "Qg2"},  {.uci = "b5b4", .san = "b4"},
+             {.uci = "c3e2", .san = "Ne2"},  {.uci = "h7h5", .san = "h5"},
+             {.uci = "g4h5", .san = "gxh5"}, {.uci = "e7f5", .san = "Nf5"},
+             {.uci = "e3f2", .san = "Bf2"},  {.uci = "d8g5", .san = "Qxg5"},
+             {.uci = "b3a5", .san = "Na5"},  {.uci = "f5e3", .san = "Ne3"},
+             {.uci = "g2g3", .san = "Qg3"},  {.uci = "g5g3", .san = "Qxg3"},
+             {.uci = "e2g3", .san = "Nxg3"}, {.uci = "e3c2", .san = "Nxc2+"},
+             {.uci = "e1d1", .san = "Kd1"},  {.uci = "c2a1", .san = "Nxa1"},
+             {.uci = "a5b7", .san = "Nxb7"}, {.uci = "b4b3", .san = "b3"},
+             {.uci = "a2b3", .san = "axb3"}, {.uci = "a1b3", .san = "Nxb3"},
+             {.uci = "d1c2", .san = "Kc2"},  {.uci = "b3c5", .san = "Nc5"},
+             {.uci = "b7c5", .san = "Nxc5"}, {.uci = "d6c5", .san = "dxc5"},
+             {.uci = "f2e1", .san = "Be1"},  {.uci = "e5f3", .san = "Nf3"},
+             {.uci = "e1c3", .san = "Bc3"},  {.uci = "f3d4", .san = "Nd4+"},
+             {.uci = "c2d3", .san = "Kd3"},  {.uci = "f8d6", .san = "Bd6"},
+             {.uci = "f1g2", .san = "Bg2"},  {.uci = "d6e5", .san = "Be5"},
+             {.uci = "d3c4", .san = "Kc4"},  {.uci = "e8e7", .san = "Ke7"},
+             {.uci = "h1a1", .san = "Ra1"},  {.uci = "d4c6", .san = "Nc6"},
+         }},
+    {.desc = "V. Ivanchuk / A. Yusupov / 1991\n\"Ivanchuck's immortal\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 78,
+     .moves =
+         {
+             {.uci = "c2c4", .san = "c4"},    {.uci = "e7e5", .san = "e5"},
+             {.uci = "g2g3", .san = "g3"},    {.uci = "d7d6", .san = "d6"},
+             {.uci = "f1g2", .san = "Bg2"},   {.uci = "g7g6", .san = "g6"},
+             {.uci = "d2d4", .san = "d4"},    {.uci = "b8d7", .san = "Nd7"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "f8g7", .san = "Bg7"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "g8f6", .san = "Ngf6"},
+             {.uci = "e1g1", .san = "O-O"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "d1c2", .san = "Qc2"},   {.uci = "f8e8", .san = "Re8"},
+             {.uci = "f1d1", .san = "Rd1"},   {.uci = "c7c6", .san = "c6"},
+             {.uci = "b2b3", .san = "b3"},    {.uci = "d8e7", .san = "Qe7"},
+             {.uci = "c1a3", .san = "Ba3"},   {.uci = "e5e4", .san = "e4"},
+             {.uci = "f3g5", .san = "Ng5"},   {.uci = "e4e3", .san = "e3"},
+             {.uci = "f2f4", .san = "f4"},    {.uci = "d7f8", .san = "Nf8"},
+             {.uci = "b3b4", .san = "b4"},    {.uci = "c8f5", .san = "Bf5"},
+             {.uci = "c2b3", .san = "Qb3"},   {.uci = "h7h6", .san = "h6"},
+             {.uci = "g5f3", .san = "Nf3"},   {.uci = "f6g4", .san = "Ng4"},
+             {.uci = "b4b5", .san = "b5"},    {.uci = "g6g5", .san = "g5"},
+             {.uci = "b5c6", .san = "bxc6"},  {.uci = "b7c6", .san = "bxc6"},
+             {.uci = "f3e5", .san = "Ne5"},   {.uci = "g5f4", .san = "gxf4"},
+             {.uci = "e5c6", .san = "Nxc6"},  {.uci = "e7g5", .san = "Qg5"},
+             {.uci = "a3d6", .san = "Bxd6"},  {.uci = "f8g6", .san = "Ng6"},
+             {.uci = "c3d5", .san = "Nd5"},   {.uci = "g5h5", .san = "Qh5"},
+             {.uci = "h2h4", .san = "h4"},    {.uci = "g6h4", .san = "Nxh4"},
+             {.uci = "g3h4", .san = "gxh4"},  {.uci = "h5h4", .san = "Qxh4"},
+             {.uci = "d5e7", .san = "Nde7+"}, {.uci = "g8h8", .san = "Kh8"},
+             {.uci = "e7f5", .san = "Nxf5"},  {.uci = "h4h2", .san = "Qh2+"},
+             {.uci = "g1f1", .san = "Kf1"},   {.uci = "e8e6", .san = "Re6"},
+             {.uci = "b3b7", .san = "Qb7"},   {.uci = "e6g6", .san = "Rg6"},
+             {.uci = "b7a8", .san = "Qxa8+"}, {.uci = "h8h7", .san = "Kh7"},
+             {.uci = "a8g8", .san = "Qg8+"},  {.uci = "h7g8", .san = "Kxg8"},
+             {.uci = "c6e7", .san = "Nce7+"}, {.uci = "g8h7", .san = "Kh7"},
+             {.uci = "e7g6", .san = "Nxg6"},  {.uci = "f7g6", .san = "fxg6"},
+             {.uci = "f5g7", .san = "Nxg7"},  {.uci = "g4f2", .san = "Nf2"},
+             {.uci = "d6f4", .san = "Bxf4"},  {.uci = "h2f4", .san = "Qxf4"},
+             {.uci = "g7e6", .san = "Ne6"},   {.uci = "f4h2", .san = "Qh2"},
+             {.uci = "d1b1", .san = "Rdb1"},  {.uci = "f2h3", .san = "Nh3"},
+             {.uci = "b1b7", .san = "Rb7+"},  {.uci = "h7h8", .san = "Kh8"},
+             {.uci = "b7b8", .san = "Rb8+"},  {.uci = "h2b8", .san = "Qxb8"},
+             {.uci = "g2h3", .san = "Bxh3"},  {.uci = "b8g3", .san = "Qg3"},
+         }},
+    {.desc = "M. Krasenkow / H. Nakamura / 2007 / Barcelona",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 56,
+     .moves =
+         {
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "e7e6", .san = "e6"},
+             {.uci = "g2g3", .san = "g3"},   {.uci = "d7d5", .san = "d5"},
+             {.uci = "f1g2", .san = "Bg2"},  {.uci = "f8e7", .san = "Be7"},
+             {.uci = "e1g1", .san = "O-O"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "b2b3", .san = "b3"},   {.uci = "a7a5", .san = "a5"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "c7c6", .san = "c6"},
+             {.uci = "d2d4", .san = "d4"},   {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "d1c2", .san = "Qc2"},  {.uci = "b7b6", .san = "b6"},
+             {.uci = "e2e4", .san = "e4"},   {.uci = "c8a6", .san = "Ba6"},
+             {.uci = "f3d2", .san = "Nd2"},  {.uci = "c6c5", .san = "c5"},
+             {.uci = "e4d5", .san = "exd5"}, {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "c3b5", .san = "Nb5"},  {.uci = "e6d5", .san = "exd5"},
+             {.uci = "b5d4", .san = "Nxd4"}, {.uci = "a8c8", .san = "Rc8"},
+             {.uci = "f1e1", .san = "Re1"},  {.uci = "b6b5", .san = "b5"},
+             {.uci = "c1b2", .san = "Bb2"},  {.uci = "f8e8", .san = "Re8"},
+             {.uci = "c2d1", .san = "Qd1"},  {.uci = "b5c4", .san = "bxc4"},
+             {.uci = "b3c4", .san = "bxc4"}, {.uci = "d8b6", .san = "Qb6"},
+             {.uci = "a1b1", .san = "Rb1"},  {.uci = "d5c4", .san = "dxc4"},
+             {.uci = "d4c6", .san = "Nc6"},  {.uci = "c8c6", .san = "Rxc6"},
+             {.uci = "b2f6", .san = "Bxf6"}, {.uci = "b6f2", .san = "Qxf2+"},
+             {.uci = "g1f2", .san = "Kxf2"}, {.uci = "e7c5", .san = "Bc5+"},
+             {.uci = "f2f3", .san = "Kf3"},  {.uci = "c6f6", .san = "Rxf6+"},
+             {.uci = "f3g4", .san = "Kg4"},  {.uci = "d7e5", .san = "Ne5+"},
+             {.uci = "g4g5", .san = "Kg5"},  {.uci = "f6g6", .san = "Rg6+"},
+             {.uci = "g5h5", .san = "Kh5"},  {.uci = "f7f6", .san = "f6"},
+             {.uci = "e1e5", .san = "Rxe5"}, {.uci = "e8e5", .san = "Rxe5+"},
+             {.uci = "h5h4", .san = "Kh4"},  {.uci = "a6c8", .san = "Bc8"},
+         }},
+    {.desc = "A. Karpov / V. Topalov / 1994\n\"Karpov's immortal\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 77,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},    {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},    {.uci = "c7c5", .san = "c5"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "f3d4", .san = "Nxd4"},  {.uci = "e7e6", .san = "e6"},
+             {.uci = "g2g3", .san = "g3"},    {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "f1g2", .san = "Bg2"},   {.uci = "f8c5", .san = "Bc5"},
+             {.uci = "d4b3", .san = "Nb3"},   {.uci = "c5e7", .san = "Be7"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "e1g1", .san = "O-O"},   {.uci = "d7d6", .san = "d6"},
+             {.uci = "c1f4", .san = "Bf4"},   {.uci = "f6h5", .san = "Nh5"},
+             {.uci = "e2e3", .san = "e3"},    {.uci = "h5f4", .san = "Nxf4"},
+             {.uci = "e3f4", .san = "exf4"},  {.uci = "c8d7", .san = "Bd7"},
+             {.uci = "d1d2", .san = "Qd2"},   {.uci = "d8b8", .san = "Qb8"},
+             {.uci = "f1e1", .san = "Rfe1"},  {.uci = "g7g6", .san = "g6"},
+             {.uci = "h2h4", .san = "h4"},    {.uci = "a7a6", .san = "a6"},
+             {.uci = "h4h5", .san = "h5"},    {.uci = "b7b5", .san = "b5"},
+             {.uci = "h5g6", .san = "hxg6"},  {.uci = "h7g6", .san = "hxg6"},
+             {.uci = "b3c5", .san = "Nc5"},   {.uci = "d6c5", .san = "dxc5"},
+             {.uci = "d2d7", .san = "Qxd7"},  {.uci = "f8c8", .san = "Rc8"},
+             {.uci = "e1e6", .san = "Rxe6"},  {.uci = "a8a7", .san = "Ra7"},
+             {.uci = "e6g6", .san = "Rxg6+"}, {.uci = "f7g6", .san = "fxg6"},
+             {.uci = "d7e6", .san = "Qe6+"},  {.uci = "g8g7", .san = "Kg7"},
+             {.uci = "g2c6", .san = "Bxc6"},  {.uci = "c8d8", .san = "Rd8"},
+             {.uci = "c4b5", .san = "cxb5"},  {.uci = "e7f6", .san = "Bf6"},
+             {.uci = "c3e4", .san = "Ne4"},   {.uci = "f6d4", .san = "Bd4"},
+             {.uci = "b5a6", .san = "bxa6"},  {.uci = "b8b6", .san = "Qb6"},
+             {.uci = "a1d1", .san = "Rd1"},   {.uci = "b6a6", .san = "Qxa6"},
+             {.uci = "d1d4", .san = "Rxd4"},  {.uci = "d8d4", .san = "Rxd4"},
+             {.uci = "e6f6", .san = "Qf6+"},  {.uci = "g7g8", .san = "Kg8"},
+             {.uci = "f6g6", .san = "Qxg6+"}, {.uci = "g8f8", .san = "Kf8"},
+             {.uci = "g6e8", .san = "Qe8+"},  {.uci = "f8g7", .san = "Kg7"},
+             {.uci = "e8e5", .san = "Qe5+"},  {.uci = "g7g8", .san = "Kg8"},
+             {.uci = "e4f6", .san = "Nf6+"},  {.uci = "g8f7", .san = "Kf7"},
+             {.uci = "c6e8", .san = "Be8+"},  {.uci = "f7f8", .san = "Kf8"},
+             {.uci = "e5c5", .san = "Qxc5+"}, {.uci = "a6d6", .san = "Qd6"},
+             {.uci = "c5a7", .san = "Qxa7"},  {.uci = "d6f6", .san = "Qxf6"},
+             {.uci = "e8h5", .san = "Bh5"},   {.uci = "d4d2", .san = "Rd2"},
+             {.uci = "b2b3", .san = "b3"},    {.uci = "d2b2", .san = "Rb2"},
+             {.uci = "g1g2", .san = "Kg2"},
+         }},
+    {.desc = "M. Carlsen / S. Ernst / 2004\n\"The Magnus effect\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 57,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},    {.uci = "c7c6", .san = "c6"},
+             {.uci = "d2d4", .san = "d4"},    {.uci = "d7d5", .san = "d5"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "d5e4", .san = "dxe4"},
+             {.uci = "c3e4", .san = "Nxe4"},  {.uci = "c8f5", .san = "Bf5"},
+             {.uci = "e4g3", .san = "Ng3"},   {.uci = "f5g6", .san = "Bg6"},
+             {.uci = "h2h4", .san = "h4"},    {.uci = "h7h6", .san = "h6"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "b8d7", .san = "Nd7"},
+             {.uci = "h4h5", .san = "h5"},    {.uci = "g6h7", .san = "Bh7"},
+             {.uci = "f1d3", .san = "Bd3"},   {.uci = "h7d3", .san = "Bxd3"},
+             {.uci = "d1d3", .san = "Qxd3"},  {.uci = "e7e6", .san = "e6"},
+             {.uci = "c1f4", .san = "Bf4"},   {.uci = "g8f6", .san = "Ngf6"},
+             {.uci = "e1c1", .san = "O-O-O"}, {.uci = "f8e7", .san = "Be7"},
+             {.uci = "g3e4", .san = "Ne4"},   {.uci = "d8a5", .san = "Qa5"},
+             {.uci = "c1b1", .san = "Kb1"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "e4f6", .san = "Nxf6+"}, {.uci = "d7f6", .san = "Nxf6"},
+             {.uci = "f3e5", .san = "Ne5"},   {.uci = "a8d8", .san = "Rad8"},
+             {.uci = "d3e2", .san = "Qe2"},   {.uci = "c6c5", .san = "c5"},
+             {.uci = "e5g6", .san = "Ng6"},   {.uci = "f7g6", .san = "fxg6"},
+             {.uci = "e2e6", .san = "Qxe6+"}, {.uci = "g8h8", .san = "Kh8"},
+             {.uci = "h5g6", .san = "hxg6"},  {.uci = "f6g8", .san = "Ng8"},
+             {.uci = "f4h6", .san = "Bxh6"},  {.uci = "g7h6", .san = "gxh6"},
+             {.uci = "h1h6", .san = "Rxh6+"}, {.uci = "g8h6", .san = "Nxh6"},
+             {.uci = "e6e7", .san = "Qxe7"},  {.uci = "h6f7", .san = "Nf7"},
+             {.uci = "g6f7", .san = "gxf7"},  {.uci = "h8g7", .san = "Kg7"},
+             {.uci = "d1d3", .san = "Rd3"},   {.uci = "d8d6", .san = "Rd6"},
+             {.uci = "d3g3", .san = "Rg3+"},  {.uci = "d6g6", .san = "Rg6"},
+             {.uci = "e7e5", .san = "Qe5+"},  {.uci = "g7f7", .san = "Kxf7"},
+             {.uci = "e5f5", .san = "Qf5+"},  {.uci = "g6f6", .san = "Rf6"},
+             {.uci = "f5d7", .san = "Qd7#"},
+         }},
+    {.desc = "N. Short / J. Timman / 1991\n\"The king's walk\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 67,
+     .moves =
+         {
+             {.uci = "e2e4", .san = "e4"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "e4e5", .san = "e5"},   {.uci = "f6d5", .san = "Nd5"},
+             {.uci = "d2d4", .san = "d4"},   {.uci = "d7d6", .san = "d6"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "g7g6", .san = "g6"},
+             {.uci = "f1c4", .san = "Bc4"},  {.uci = "d5b6", .san = "Nb6"},
+             {.uci = "c4b3", .san = "Bb3"},  {.uci = "f8g7", .san = "Bg7"},
+             {.uci = "d1e2", .san = "Qe2"},  {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "e1g1", .san = "O-O"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "h2h3", .san = "h3"},   {.uci = "a7a5", .san = "a5"},
+             {.uci = "a2a4", .san = "a4"},   {.uci = "d6e5", .san = "dxe5"},
+             {.uci = "d4e5", .san = "dxe5"}, {.uci = "c6d4", .san = "Nd4"},
+             {.uci = "f3d4", .san = "Nxd4"}, {.uci = "d8d4", .san = "Qxd4"},
+             {.uci = "f1e1", .san = "Re1"},  {.uci = "e7e6", .san = "e6"},
+             {.uci = "b1d2", .san = "Nd2"},  {.uci = "b6d5", .san = "Nd5"},
+             {.uci = "d2f3", .san = "Nf3"},  {.uci = "d4c5", .san = "Qc5"},
+             {.uci = "e2e4", .san = "Qe4"},  {.uci = "c5b4", .san = "Qb4"},
+             {.uci = "b3c4", .san = "Bc4"},  {.uci = "d5b6", .san = "Nb6"},
+             {.uci = "b2b3", .san = "b3"},   {.uci = "b6c4", .san = "Nxc4"},
+             {.uci = "b3c4", .san = "bxc4"}, {.uci = "f8e8", .san = "Re8"},
+             {.uci = "e1d1", .san = "Rd1"},  {.uci = "b4c5", .san = "Qc5"},
+             {.uci = "e4h4", .san = "Qh4"},  {.uci = "b7b6", .san = "b6"},
+             {.uci = "c1e3", .san = "Be3"},  {.uci = "c5c6", .san = "Qc6"},
+             {.uci = "e3h6", .san = "Bh6"},  {.uci = "g7h8", .san = "Bh8"},
+             {.uci = "d1d8", .san = "Rd8"},  {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "a1d1", .san = "Rad1"}, {.uci = "h8g7", .san = "Bg7"},
+             {.uci = "d8d7", .san = "R8d7"}, {.uci = "e8f8", .san = "Rf8"},
+             {.uci = "h6g7", .san = "Bxg7"}, {.uci = "g8g7", .san = "Kxg7"},
+             {.uci = "d1d4", .san = "R1d4"}, {.uci = "a8e8", .san = "Rae8"},
+             {.uci = "h4f6", .san = "Qf6+"}, {.uci = "g7g8", .san = "Kg8"},
+             {.uci = "h3h4", .san = "h4"},   {.uci = "h7h5", .san = "h5"},
+             {.uci = "g1h2", .san = "Kh2"},  {.uci = "e8c8", .san = "Rc8"},
+             {.uci = "h2g3", .san = "Kg3"},  {.uci = "c8e8", .san = "Rce8"},
+             {.uci = "g3f4", .san = "Kf4"},  {.uci = "b7c8", .san = "Bc8"},
+             {.uci = "f4g5", .san = "Kg5"},
+         }},
+    {.desc = "L. Aronian / V. Anand / 2013\n\"Nerves of steel\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 46,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},   {.uci = "d7d5", .san = "d5"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "c7c6", .san = "c6"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "e7e6", .san = "e6"},
+             {.uci = "e2e3", .san = "e3"},   {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "f1d3", .san = "Bd3"},  {.uci = "d5c4", .san = "dxc4"},
+             {.uci = "d3c4", .san = "Bxc4"}, {.uci = "b7b5", .san = "b5"},
+             {.uci = "c4d3", .san = "Bd3"},  {.uci = "f8d6", .san = "Bd6"},
+             {.uci = "e1g1", .san = "O-O"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "d1c2", .san = "Qc2"},  {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "a2a3", .san = "a3"},   {.uci = "a8c8", .san = "Rc8"},
+             {.uci = "f3g5", .san = "Ng5"},  {.uci = "c6c5", .san = "c5"},
+             {.uci = "g5h7", .san = "Nxh7"}, {.uci = "f6g4", .san = "Ng4"},
+             {.uci = "f2f4", .san = "f4"},   {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "e3d4", .san = "exd4"}, {.uci = "d6c5", .san = "Bc5"},
+             {.uci = "d3e2", .san = "Be2"},  {.uci = "d7e5", .san = "Nde5"},
+             {.uci = "e2g4", .san = "Bxg4"}, {.uci = "c5d4", .san = "Bxd4+"},
+             {.uci = "g1h1", .san = "Kh1"},  {.uci = "e5g4", .san = "Nxg4"},
+             {.uci = "h7f8", .san = "Nxf8"}, {.uci = "f7f5", .san = "f5"},
+             {.uci = "f8g6", .san = "Ng6"},  {.uci = "d8f6", .san = "Qf6"},
+             {.uci = "h2h3", .san = "h3"},   {.uci = "f6g6", .san = "Qxg6"},
+             {.uci = "c2e2", .san = "Qe2"},  {.uci = "g6h5", .san = "Qh5"},
+             {.uci = "e2d3", .san = "Qd3"},  {.uci = "d4e3", .san = "Be3"},
+         }},
+    {.desc = "Jinshi Bai / Ding Liren / 2017.11.04\nChinese Chess League",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 64,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},   {.uci = "e7e6", .san = "e6"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "f8b4", .san = "Bb4"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "c1g5", .san = "Bg5"},  {.uci = "c7c5", .san = "c5"},
+             {.uci = "e2e3", .san = "e3"},   {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "d1d4", .san = "Qxd4"}, {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "d4d3", .san = "Qd3"},  {.uci = "h7h6", .san = "h6"},
+             {.uci = "g5h4", .san = "Bh4"},  {.uci = "d7d5", .san = "d5"},
+             {.uci = "a1d1", .san = "Rd1"},  {.uci = "g7g5", .san = "g5"},
+             {.uci = "h4g3", .san = "Bg3"},  {.uci = "f6e4", .san = "Ne4"},
+             {.uci = "f3d2", .san = "Nd2"},  {.uci = "e4c5", .san = "Nc5"},
+             {.uci = "d3c2", .san = "Qc2"},  {.uci = "d5d4", .san = "d4"},
+             {.uci = "d2f3", .san = "Nf3"},  {.uci = "e6e5", .san = "e5"},
+             {.uci = "f3e5", .san = "Nxe5"}, {.uci = "d4c3", .san = "dxc3"},
+             {.uci = "d1d8", .san = "Rxd8"}, {.uci = "c3b2", .san = "cxb2+"},
+             {.uci = "e1e2", .san = "Ke2"},  {.uci = "f8d8", .san = "Rxd8"},
+             {.uci = "c2b2", .san = "Qxb2"}, {.uci = "c5a4", .san = "Na4"},
+             {.uci = "b2c2", .san = "Qc2"},  {.uci = "a4c3", .san = "Nc3+"},
+             {.uci = "e2f3", .san = "Kf3"},  {.uci = "d8d4", .san = "Rd4"},
+             {.uci = "h2h3", .san = "h3"},   {.uci = "h6h5", .san = "h5"},
+             {.uci = "g3h2", .san = "Bh2"},  {.uci = "g5g4", .san = "g4+"},
+             {.uci = "f3g3", .san = "Kg3"},  {.uci = "d4d2", .san = "Rd2"},
+             {.uci = "c2b3", .san = "Qb3"},  {.uci = "c3e4", .san = "Ne4+"},
+             {.uci = "g3h4", .san = "Kh4"},  {.uci = "b4e7", .san = "Be7+"},
+             {.uci = "h4h5", .san = "Kxh5"}, {.uci = "g8g7", .san = "Kg7"},
+             {.uci = "h2f4", .san = "Bf4"},  {.uci = "c8f5", .san = "Bf5"},
+             {.uci = "f4h6", .san = "Bh6+"}, {.uci = "g7h7", .san = "Kh7"},
+             {.uci = "b3b7", .san = "Qxb7"}, {.uci = "d2f2", .san = "Rxf2"},
+             {.uci = "h6g5", .san = "Bg5"},  {.uci = "a8h8", .san = "Rh8"},
+             {.uci = "e5f7", .san = "Nxf7"}, {.uci = "f5g6", .san = "Bg6+"},
+             {.uci = "h5g4", .san = "Kxg4"}, {.uci = "c6e5", .san = "Ne5+"},
+         }},
+    {.desc = "E. Geller / M. Euwe / 1953.08.31",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 52,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},    {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c2c4", .san = "c4"},    {.uci = "e7e6", .san = "e6"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "f8b4", .san = "Bb4"},
+             {.uci = "e2e3", .san = "e3"},    {.uci = "c7c5", .san = "c5"},
+             {.uci = "a2a3", .san = "a3"},    {.uci = "b4c3", .san = "Bxc3+"},
+             {.uci = "b2c3", .san = "bxc3"},  {.uci = "b7b6", .san = "b6"},
+             {.uci = "f1d3", .san = "Bd3"},   {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "f2f3", .san = "f3"},    {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "g1e2", .san = "Ne2"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "e1g1", .san = "O-O"},   {.uci = "c6a5", .san = "Na5"},
+             {.uci = "e3e4", .san = "e4"},    {.uci = "f6e8", .san = "Ne8"},
+             {.uci = "e2g3", .san = "Ng3"},   {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "c3d4", .san = "cxd4"},  {.uci = "a8c8", .san = "Rc8"},
+             {.uci = "f3f4", .san = "f4"},    {.uci = "a5c4", .san = "Nxc4"},
+             {.uci = "f4f5", .san = "f5"},    {.uci = "f7f6", .san = "f6"},
+             {.uci = "f1f4", .san = "Rf4"},   {.uci = "b6b5", .san = "b5"},
+             {.uci = "f4h4", .san = "Rh4"},   {.uci = "d8b6", .san = "Qb6"},
+             {.uci = "e4e5", .san = "e5"},    {.uci = "c4e5", .san = "Nxe5"},
+             {.uci = "f5e6", .san = "fxe6"},  {.uci = "e5d3", .san = "Nxd3"},
+             {.uci = "d1d3", .san = "Qxd3"},  {.uci = "b6e6", .san = "Qxe6"},
+             {.uci = "d3h7", .san = "Qxh7+"}, {.uci = "g8f7", .san = "Kf7"},
+             {.uci = "c1h6", .san = "Bh6"},   {.uci = "f8h8", .san = "Rh8"},
+             {.uci = "h7h8", .san = "Qxh8"},  {.uci = "c8c2", .san = "Rc2"},
+             {.uci = "a1c1", .san = "Rc1"},   {.uci = "c2g2", .san = "Rxg2+"},
+             {.uci = "g1f1", .san = "Kf1"},   {.uci = "e6b3", .san = "Qb3"},
+             {.uci = "f1e1", .san = "Ke1"},   {.uci = "b3f3", .san = "Qf3"},
+         }},
+    {.desc = "S. Levitsky / F. J. Marshall / 1912\n\"The Gold coin game\"",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 46,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},   {.uci = "e7e6", .san = "e6"},
+             {.uci = "e2e4", .san = "e4"},   {.uci = "d7d5", .san = "d5"},
+             {.uci = "b1c3", .san = "Nc3"},  {.uci = "c7c5", .san = "c5"},
+             {.uci = "g1f3", .san = "Nf3"},  {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "e4d5", .san = "exd5"}, {.uci = "e6d5", .san = "exd5"},
+             {.uci = "f1e2", .san = "Be2"},  {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "e1g1", .san = "O-O"},  {.uci = "f8e7", .san = "Be7"},
+             {.uci = "c1g5", .san = "Bg5"},  {.uci = "e8g8", .san = "O-O"},
+             {.uci = "d4c5", .san = "dxc5"}, {.uci = "c8e6", .san = "Be6"},
+             {.uci = "f3d4", .san = "Nd4"},  {.uci = "e7c5", .san = "Bxc5"},
+             {.uci = "d4e6", .san = "Nxe6"}, {.uci = "f7e6", .san = "fxe6"},
+             {.uci = "e2g4", .san = "Bg4"},  {.uci = "d8d6", .san = "Qd6"},
+             {.uci = "g4h3", .san = "Bh3"},  {.uci = "a8e8", .san = "Rae8"},
+             {.uci = "d1d2", .san = "Qd2"},  {.uci = "c5b4", .san = "Bb4"},
+             {.uci = "g5f6", .san = "Bxf6"}, {.uci = "f8f6", .san = "Rxf6"},
+             {.uci = "a1d1", .san = "Rad1"}, {.uci = "d6c5", .san = "Qc5"},
+             {.uci = "d2e2", .san = "Qe2"},  {.uci = "b4c3", .san = "Bxc3"},
+             {.uci = "b2c3", .san = "bxc3"}, {.uci = "c5c3", .san = "Qxc3"},
+             {.uci = "d1d5", .san = "Rxd5"}, {.uci = "c6d4", .san = "Nd4"},
+             {.uci = "e2h5", .san = "Qh5"},  {.uci = "e8f8", .san = "Ref8"},
+             {.uci = "d5e5", .san = "Re5"},  {.uci = "f6h6", .san = "Rh6"},
+             {.uci = "h5g5", .san = "Qg5"},  {.uci = "h6h3", .san = "Rxh3"},
+             {.uci = "e5c5", .san = "Rc5"},  {.uci = "c3g3", .san = "Qg3"},
+         }},
+    {.desc = "E. N. Somov-Nasimovitsch / 1928 / Zadachi I Etiudi",
+     .fen = "5k2/p1p1p3/2p1p2N/P1R5/P3KP2/8/p6P/b7",
+     .movecount = 19,
+     .moves =
+         {
+             {.uci = "c5c2", .san = "Rc2"},   {.uci = "a1b2", .san = "Bb2"},
+             {.uci = "c2g2", .san = "Rg2"},   {.uci = "f8e8", .san = "Ke8"},
+             {.uci = "g2g8", .san = "Rg8+"},  {.uci = "e8d7", .san = "Kd7"},
+             {.uci = "h6f7", .san = "Nf7"},   {.uci = "c6c5", .san = "c5"},
+             {.uci = "g8d8", .san = "Rd8+"},  {.uci = "d7c6", .san = "Kc6"},
+             {.uci = "d8d2", .san = "Rd2"},   {.uci = "c5c4", .san = "c4"},
+             {.uci = "f7d8", .san = "Nd8+"},  {.uci = "c6c5", .san = "Kc5"},
+             {.uci = "d8e6", .san = "Nxe6+"}, {.uci = "c5c6", .san = "Kc6"},
+             {.uci = "e6d8", .san = "Nd8+"},  {.uci = "c6c5", .san = "Kc5"},
+             {.uci = "d2b2", .san = "Rxb2"},
+         }},
+    {.desc = "J. Hendel / 1859\nPayne's family journal",
+     .fen = "8/K1N1p3/2k1N3/4P3/8/8/1P6/8",
+     .movecount = 9,
+     .moves =
+         {
+             {.uci = "b2b4", .san = "b4"},
+             {.uci = "c6d7", .san = "Kd7"},
+             {.uci = "b4b5", .san = "b5"},
+             {.uci = "d7c8", .san = "Kc8"},
+             {.uci = "b5b6", .san = "b6"},
+             {.uci = "c8d7", .san = "Kd7"},
+             {.uci = "b6b7", .san = "b7"},
+             {.uci = "d7c6", .san = "Kc6"},
+             {.uci = "b7b8n", .san = "b8=N#"},
+         }},
+    {.desc = "J. Hasek / 1929\nLa strategie",
+     .fen = "3N3N/1Kpp4/8/1k6/1P3p2/P1P5/8/8",
+     .movecount = 9,
+     .moves =
+         {
+             {.uci = "d8c6", .san = "Nc6"},
+             {.uci = "d7c6", .san = "dxc6"},
+             {.uci = "h8g6", .san = "Ng6"},
+             {.uci = "f4f3", .san = "f3"},
+             {.uci = "g6e5", .san = "Ne5"},
+             {.uci = "f3f2", .san = "f2"},
+             {.uci = "e5d3", .san = "Nd3"},
+             {.uci = "f2f1q", .san = "f1=Q"},
+             {.uci = "d3b2", .san = "Nb2"},
+         }},
+    {.desc = "K. A. L. Kubbel / 1936\nChess in the USSR",
+     .fen = "8/7p/4pK1k/5R2/8/1b2r1P1/8/5B2",
+     .movecount = 9,
+     .moves =
+         {
+             {.uci = "f5f2", .san = "Rf2"},
+             {.uci = "b3d1", .san = "Bd1"},
+             {.uci = "f2h2", .san = "Rh2"},
+             {.uci = "d1h5", .san = "Bh5"},
+             {.uci = "f1e2", .san = "Be2"},
+             {.uci = "e3e2", .san = "Rxe2"},
+             {.uci = "g3g4", .san = "g4"},
+             {.uci = "e2h2", .san = "Rxh2"},
+             {.uci = "g4g5", .san = "g5"},
+         }},
+    {.desc = "M. B. Newman / 1913\nChess amateur",
+     .fen = "4q3/n7/8/7P/k1B1N3/P3N3/8/K7",
+     .movecount = 11,
+     .moves =
+         {
+             {.uci = "c4b5", .san = "Bb5+"},
+             {.uci = "e8b5", .san = "Qxb5"},
+             {.uci = "e4c3", .san = "Nc3+"},
+             {.uci = "a4a3", .san = "Kxa3"},
+             {.uci = "c3b5", .san = "Nxb5+"},
+             {.uci = "a7b5", .san = "Nxb5"},
+             {.uci = "h5h6", .san = "h6"},
+             {.uci = "b5d6", .san = "Nd6"},
+             {.uci = "e3c4", .san = "Nc4+"},
+             {.uci = "d6c4", .san = "Nxc4"},
+             {.uci = "h6h7", .san = "h7"},
+         }},
+    {.desc = "V. A. Korolikov / 1935 / Truda",
+     .fen = "2B5/pR6/2pP1k2/8/6Kb/4p1P1/5p2/8",
+     .movecount = 19,
+     .moves =
+         {
+             {.uci = "d6d7", .san = "d7"},     {.uci = "f6e7", .san = "Ke7"},
+             {.uci = "b7b8", .san = "Rb8"},    {.uci = "h4g3", .san = "Bxg3"},
+             {.uci = "b8a8", .san = "Ra8"},    {.uci = "f2f1q", .san = "f1=Q"},
+             {.uci = "d7d8q", .san = "d8=Q+"}, {.uci = "e7d8", .san = "Kxd8"},
+             {.uci = "c8a6", .san = "Ba6+"},   {.uci = "g3b8", .san = "Bb8"},
+             {.uci = "a6f1", .san = "Bxf1"},   {.uci = "d8c7", .san = "Kc7"},
+             {.uci = "f1a6", .san = "Ba6"},    {.uci = "e3e2", .san = "e2"},
+             {.uci = "a6e2", .san = "Bxe2"},   {.uci = "c7b7", .san = "Kb7"},
+             {.uci = "e2f3", .san = "Bf3"},    {.uci = "b7a8", .san = "Kxa8"},
+             {.uci = "f3c6", .san = "Bxc6#"},
+         }},
+    {.desc = "Gorgiev / 1929 / 64",
+     .fen = "6N1/n7/3kn3/K7/6N1/8/8/4B3",
+     .movecount = 11,
+     .moves =
+         {
+             {.uci = "a5b6", .san = "Kb6"},
+             {.uci = "a7c8", .san = "Nc8+"},
+             {.uci = "b6b7", .san = "Kb7"},
+             {.uci = "c8e7", .san = "Ne7"},
+             {.uci = "e1g3", .san = "Bg3+"},
+             {.uci = "d6d7", .san = "Kd7"},
+             {.uci = "g8f6", .san = "N8f6+"},
+             {.uci = "d7d8", .san = "Kd8"},
+             {.uci = "g3c7", .san = "Bc7+"},
+             {.uci = "e6c7", .san = "Nxc7"},
+             {.uci = "g4e5", .san = "Ne5"},
+         }},
+    {.desc = "K. A. L. Kubbel / 1922\nSchachmatny Listok",
+     .fen = "1N6/8/K7/3k4/3p3B/p7/2PP4/8",
+     .movecount = 11,
+     .moves =
+         {
+             {.uci = "b8c6", .san = "Nc6"},
+             {.uci = "d5c6", .san = "Kxc6"},
+             {.uci = "h4f6", .san = "Bf6"},
+             {.uci = "c6d5", .san = "Kd5"},
+             {.uci = "d2d3", .san = "d3"},
+             {.uci = "a3a2", .san = "a2"},
+             {.uci = "c2c4", .san = "c4+"},
+             {.uci = "d5c5", .san = "Kc5"},
+             {.uci = "a6b7", .san = "Kb7"},
+             {.uci = "a2a1q", .san = "a1=Q"},
+             {.uci = "f6e7", .san = "Be7#"},
+         }},
+    {.desc = "M. Carlsen / G. Kasparov / 2004 / Reykjavik",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 103,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},    {.uci = "d7d5", .san = "d5"},
+             {.uci = "c2c4", .san = "c4"},    {.uci = "c7c6", .san = "c6"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "e7e6", .san = "e6"},
+             {.uci = "c1g5", .san = "Bg5"},   {.uci = "b8d7", .san = "Nbd7"},
+             {.uci = "e2e3", .san = "e3"},    {.uci = "d8a5", .san = "Qa5"},
+             {.uci = "f3d2", .san = "Nd2"},   {.uci = "f8b4", .san = "Bb4"},
+             {.uci = "d1c2", .san = "Qc2"},   {.uci = "e8g8", .san = "O-O"},
+             {.uci = "f1e2", .san = "Be2"},   {.uci = "e6e5", .san = "e5"},
+             {.uci = "e1g1", .san = "O-O"},   {.uci = "e5d4", .san = "exd4"},
+             {.uci = "d2b3", .san = "Nb3"},   {.uci = "a5b6", .san = "Qb6"},
+             {.uci = "e3d4", .san = "exd4"},  {.uci = "d5c4", .san = "dxc4"},
+             {.uci = "e2c4", .san = "Bxc4"},  {.uci = "a7a5", .san = "a5"},
+             {.uci = "a2a4", .san = "a4"},    {.uci = "b6c7", .san = "Qc7"},
+             {.uci = "a1e1", .san = "Rae1"},  {.uci = "h7h6", .san = "h6"},
+             {.uci = "g5h4", .san = "Bh4"},   {.uci = "b4d6", .san = "Bd6"},
+             {.uci = "h2h3", .san = "h3"},    {.uci = "d7b6", .san = "Nb6"},
+             {.uci = "h4f6", .san = "Bxf6"},  {.uci = "b6c4", .san = "Nxc4"},
+             {.uci = "c3e4", .san = "Ne4"},   {.uci = "d6h2", .san = "Bh2+"},
+             {.uci = "g1h1", .san = "Kh1"},   {.uci = "c4d6", .san = "Nd6"},
+             {.uci = "h1h2", .san = "Kxh2"},  {.uci = "d6e4", .san = "Nxe4+"},
+             {.uci = "f6e5", .san = "Be5"},   {.uci = "e4d6", .san = "Nd6"},
+             {.uci = "c2c5", .san = "Qc5"},   {.uci = "f8d8", .san = "Rd8"},
+             {.uci = "d4d5", .san = "d5"},    {.uci = "c7d7", .san = "Qd7"},
+             {.uci = "b3d4", .san = "Nd4"},   {.uci = "d6f5", .san = "Nf5"},
+             {.uci = "d5c6", .san = "dxc6"},  {.uci = "b7c6", .san = "bxc6"},
+             {.uci = "d4c6", .san = "Nxc6"},  {.uci = "d8e8", .san = "Re8"},
+             {.uci = "e1d1", .san = "Rd1"},   {.uci = "d7e6", .san = "Qe6"},
+             {.uci = "f1e1", .san = "Rfe1"},  {.uci = "c8b7", .san = "Bb7"},
+             {.uci = "c6d4", .san = "Nd4"},   {.uci = "f5d4", .san = "Nxd4"},
+             {.uci = "c5d4", .san = "Qxd4"},  {.uci = "e6g6", .san = "Qg6"},
+             {.uci = "d4g4", .san = "Qg4"},   {.uci = "g6g4", .san = "Qxg4"},
+             {.uci = "h3g4", .san = "hxg4"},  {.uci = "b7c6", .san = "Bc6"},
+             {.uci = "b2b3", .san = "b3"},    {.uci = "f7f6", .san = "f6"},
+             {.uci = "e5c3", .san = "Bc3"},   {.uci = "e8e1", .san = "Rxe1"},
+             {.uci = "d1e1", .san = "Rxe1"},  {.uci = "c6d5", .san = "Bd5"},
+             {.uci = "e1b1", .san = "Rb1"},   {.uci = "g8f7", .san = "Kf7"},
+             {.uci = "h2g3", .san = "Kg3"},   {.uci = "a8b8", .san = "Rb8"},
+             {.uci = "b3b4", .san = "b4"},    {.uci = "a5b4", .san = "axb4"},
+             {.uci = "c3b4", .san = "Bxb4"},  {.uci = "d5c4", .san = "Bc4"},
+             {.uci = "a4a5", .san = "a5"},    {.uci = "c4a6", .san = "Ba6"},
+             {.uci = "f2f3", .san = "f3"},    {.uci = "f7g6", .san = "Kg6"},
+             {.uci = "g3f4", .san = "Kf4"},   {.uci = "h6h5", .san = "h5"},
+             {.uci = "g4h5", .san = "gxh5+"}, {.uci = "g6h5", .san = "Kxh5"},
+             {.uci = "b1h1", .san = "Rh1+"},  {.uci = "h5g6", .san = "Kg6"},
+             {.uci = "b4c5", .san = "Bc5"},   {.uci = "b8b2", .san = "Rb2"},
+             {.uci = "f4g3", .san = "Kg3"},   {.uci = "b2a2", .san = "Ra2"},
+             {.uci = "c5b6", .san = "Bb6"},   {.uci = "g6f7", .san = "Kf7"},
+             {.uci = "h1c1", .san = "Rc1"},   {.uci = "g7g5", .san = "g5"},
+             {.uci = "c1c7", .san = "Rc7+"},  {.uci = "f7g6", .san = "Kg6"},
+             {.uci = "c7c6", .san = "Rc6"},   {.uci = "a6f1", .san = "Bf1"},
+             {.uci = "b6f2", .san = "Bf2"},
+         }},
+    {.desc = "M. Carlsen / V. Kramnik / 2016 / Norway",
+     .fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
+     .movecount = 99,
+     .moves =
+         {
+             {.uci = "d2d4", .san = "d4"},    {.uci = "d7d5", .san = "d5"},
+             {.uci = "c2c4", .san = "c4"},    {.uci = "e7e6", .san = "e6"},
+             {.uci = "b1c3", .san = "Nc3"},   {.uci = "g8f6", .san = "Nf6"},
+             {.uci = "c4d5", .san = "cxd5"},  {.uci = "e6d5", .san = "exd5"},
+             {.uci = "c1g5", .san = "Bg5"},   {.uci = "c7c6", .san = "c6"},
+             {.uci = "e2e3", .san = "e3"},    {.uci = "c8f5", .san = "Bf5"},
+             {.uci = "d1f3", .san = "Qf3"},   {.uci = "f5g6", .san = "Bg6"},
+             {.uci = "g5f6", .san = "Bxf6"},  {.uci = "d8f6", .san = "Qxf6"},
+             {.uci = "f3f6", .san = "Qxf6"},  {.uci = "g7f6", .san = "gxf6"},
+             {.uci = "g1f3", .san = "Nf3"},   {.uci = "b8d7", .san = "Nd7"},
+             {.uci = "f3h4", .san = "Nh4"},   {.uci = "f8e7", .san = "Be7"},
+             {.uci = "c3e2", .san = "Ne2"},   {.uci = "d7b6", .san = "Nb6"},
+             {.uci = "e2g3", .san = "Ng3"},   {.uci = "e7b4", .san = "Bb4+"},
+             {.uci = "e1d1", .san = "Kd1"},   {.uci = "b6a4", .san = "Na4"},
+             {.uci = "g3f5", .san = "Ngf5"},  {.uci = "e8d7", .san = "Kd7"},
+             {.uci = "a1b1", .san = "Rb1"},   {.uci = "d7e6", .san = "Ke6"},
+             {.uci = "f1d3", .san = "Bd3"},   {.uci = "h8c8", .san = "Rhc8"},
+             {.uci = "d1e2", .san = "Ke2"},   {.uci = "b4f8", .san = "Bf8"},
+             {.uci = "g2g4", .san = "g4"},    {.uci = "c6c5", .san = "c5"},
+             {.uci = "h4g2", .san = "Ng2"},   {.uci = "c5d4", .san = "cxd4"},
+             {.uci = "e3d4", .san = "exd4"},  {.uci = "f8d6", .san = "Bd6"},
+             {.uci = "h2h4", .san = "h4"},    {.uci = "h7h5", .san = "h5"},
+             {.uci = "f5g7", .san = "Ng7+"},  {.uci = "e6e7", .san = "Ke7"},
+             {.uci = "g4h5", .san = "gxh5"},  {.uci = "g6d3", .san = "Bxd3+"},
+             {.uci = "e2d3", .san = "Kxd3"},  {.uci = "e7d7", .san = "Kd7"},
+             {.uci = "g2e3", .san = "Ne3"},   {.uci = "a4b6", .san = "Nb6"},
+             {.uci = "e3g4", .san = "Ng4"},   {.uci = "c8h8", .san = "Rh8"},
+             {.uci = "h1e1", .san = "Rhe1"},  {.uci = "d6e7", .san = "Be7"},
+             {.uci = "g7f5", .san = "Nf5"},   {.uci = "e7d8", .san = "Bd8"},
+             {.uci = "h5h6", .san = "h6"},    {.uci = "a8c8", .san = "Rc8"},
+             {.uci = "b2b3", .san = "b3"},    {.uci = "c8c6", .san = "Rc6"},
+             {.uci = "g4e3", .san = "Nge3"},  {.uci = "d8c7", .san = "Bc7"},
+             {.uci = "b1c1", .san = "Rbc1"},  {.uci = "c6c1", .san = "Rxc1"},
+             {.uci = "e1c1", .san = "Rxc1"},  {.uci = "c7f4", .san = "Bf4"},
+             {.uci = "c1c5", .san = "Rc5"},   {.uci = "d7e6", .san = "Ke6"},
+             {.uci = "f5g7", .san = "Ng7+"},  {.uci = "e6d6", .san = "Kd6"},
+             {.uci = "e3g4", .san = "Ng4"},   {.uci = "b6d7", .san = "Nd7"},
+             {.uci = "c5c2", .san = "Rc2"},   {.uci = "f6f5", .san = "f5"},
+             {.uci = "g7f5", .san = "Nxf5+"}, {.uci = "d6e6", .san = "Ke6"},
+             {.uci = "f5g7", .san = "Ng7+"},  {.uci = "e6d6", .san = "Kd6"},
+             {.uci = "c2e2", .san = "Re2"},   {.uci = "d6c6", .san = "Kc6"},
+             {.uci = "e2e8", .san = "Re8"},   {.uci = "h8e8", .san = "Rxe8"},
+             {.uci = "g7e8", .san = "Nxe8"},  {.uci = "d7f8", .san = "Nf8"},
+             {.uci = "g4e5", .san = "Ne5+"},  {.uci = "f4e5", .san = "Bxe5"},
+             {.uci = "d4e5", .san = "dxe5"},  {.uci = "c6d7", .san = "Kd7"},
+             {.uci = "e8f6", .san = "Nf6+"},  {.uci = "d7e6", .san = "Ke6"},
+             {.uci = "h4h5", .san = "h5"},    {.uci = "e6e5", .san = "Kxe5"},
+             {.uci = "f6d7", .san = "Nd7+"},  {.uci = "f8d7", .san = "Nxd7"},
+             {.uci = "h6h7", .san = "h7"},    {.uci = "d7c5", .san = "Nc5+"},
+             {.uci = "d3e2", .san = "Ke2"},
+         }},
 };
 
 #endif /* __CHESSGAMES_H__ */
index 057f0948038f0fa2709f782671157fed7f2e70ec..73da06f0902f8c9f128bea60f2a6f2f2a407d36b 100644 (file)
@@ -1,4 +1,4 @@
-/* chompytower, Copyright © 2022 Jamie Zawinski <jwz@jwz.org>
+/* chompytower, Copyright © 2022-2025 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
@@ -43,6 +43,8 @@
 #include "spline.h"
 #include "gltrackball.h"
 #include "gllist.h"
+#include "easing.h"
+#include "doubletime.h"
 #include <ctype.h>
 
 extern const struct gllist
@@ -152,21 +154,6 @@ ENTRYPOINT ModeSpecOpt chompytower_opts = {
 #define SPLINE_SCALE 1000
 #define FUNHOLE_HEIGHT 0.2
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void
 parse_color (ModeInfo *mi, char *key, GLfloat color[4])
 {
@@ -896,25 +883,6 @@ draw_component (ModeInfo *mi, int i)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static int
 draw_funhole (ModeInfo *mi, slice *s, Bool shadow_p)
 {
@@ -944,10 +912,10 @@ draw_funhole (ModeInfo *mi, slice *s, Bool shadow_p)
 
   switch (s->funhole.state) {
   case HIDDEN:     dist  = 0; break;
-  case EXTENDING:  dist *= ease_ratio (s->funhole.ratio);     break;
-  case RETRACTING: dist *= ease_ratio (1 - s->funhole.ratio); break;
-  case OPENING:    tilt  = ease_ratio (s->funhole.ratio);     break;
-  case CLOSING:    tilt  = ease_ratio (1 - s->funhole.ratio); break;
+  case EXTENDING:  dist *= ease(EASE_IN_OUT_SINE,   s->funhole.ratio); break;
+  case RETRACTING: dist *= ease(EASE_IN_OUT_SINE, 1-s->funhole.ratio); break;
+  case OPENING:    tilt  = ease(EASE_IN_OUT_SINE,   s->funhole.ratio); break;
+  case CLOSING:    tilt  = ease(EASE_IN_OUT_SINE, 1-s->funhole.ratio); break;
   case OPEN:       tilt  = 1; break;
   case CLOSED:     tilt  = 0; break;
   default: abort(); break;
index fccee8de6d4457cd059b20ad1d85aac0bef4d49a..132ecb673a85967dde2dfc4c778427382266560f 100644 (file)
@@ -1,4 +1,4 @@
-/* crumbler, Copyright (c) 2018 Jamie Zawinski <jwz@jwz.org>
+/* crumbler, Copyright © 2018-2025 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
@@ -21,6 +21,7 @@
 #include "rotator.h"
 #include "quickhull.h"
 #include "gltrackball.h"
+#include "easing.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -563,25 +564,6 @@ tick_crumbler (ModeInfo *mi)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.35;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 /* Window management, etc
  */
 ENTRYPOINT void
@@ -840,7 +822,7 @@ draw_crumbler (ModeInfo *mi)
       switch (bp->state) {
         case FLEE:
           {
-            GLfloat r = ease_ratio (bp->tick);
+            GLfloat r = ease (EASE_IN_OUT_SINE, bp->tick);
             /* Move everybody toward the origin, so that chunk #0 ends up
                centered there. */
             glTranslatef (-r * c->mid.x,
@@ -865,7 +847,7 @@ draw_crumbler (ModeInfo *mi)
           GLfloat Z = (c->max.z - c->min.z);
           GLfloat size0 = MAX(X, MAX(Y, Z));
           GLfloat size1 = 1.0;
-          GLfloat r = 1 - ease_ratio (bp->tick);
+          GLfloat r = 1 - ease (EASE_IN_OUT_SINE, bp->tick);
           GLfloat s = 1 / (size0 + r * (size1 - size0));
           glScalef (s, s, s);
         }
@@ -885,8 +867,8 @@ draw_crumbler (ModeInfo *mi)
       GLfloat s;
       /* alpha = 1 - bp->tick; */
       alpha = 1;
-      /* s = 0.7 + (0.3 * ease_ratio (1-bp->tick)); */
-      s = 2 * ease_ratio ((1-bp->tick) / 2);
+      /* s = 0.7 + (0.3 * ease (EASE_IN_OUT_SINE, 1-bp->tick)); */
+      s = 2 * ease (EASE_IN_OUT_SINE, (1-bp->tick) / 2);
       s *= 1.01;
       glScalef (s, s, s);
       draw_chunk (mi, bp->ghost, alpha);
index ef62ab414a164a51fc2c7bbdf79d2695acc2457a..e387413746183caa520dd0bf59be2b5bdc349feb 100644 (file)
@@ -1,4 +1,4 @@
-/* cubestack, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+/* cubestack, Copyright © 2016-2025 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
@@ -20,6 +20,7 @@
 #include "colors.h"
 #include "rotator.h"
 #include "gltrackball.h"
+#include "easing.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -120,25 +121,6 @@ draw_face (ModeInfo *mi)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static int
 draw_cube_1 (ModeInfo *mi, GLfloat state, GLfloat color[4], Bool bottom_p)
 {
@@ -147,7 +129,7 @@ draw_cube_1 (ModeInfo *mi, GLfloat state, GLfloat color[4], Bool bottom_p)
   GLfloat r = state - istate;
   GLfloat a = color[3];
 
-  r = ease_ratio (r);
+  r = ease (EASE_IN_OUT_SINE, r);
 
 # define COLORIZE(R) \
       color[3] = a * R; \
index eed1901c7e3a387a3f2277b3cdfe320cdfdeb0cf..fdaea8ad0e9a9bc38f5c66e0038d5c0d7e2afbb0 100644 (file)
@@ -1,4 +1,4 @@
-/* cubetwist, Copyright (c) 2016-2017 Jamie Zawinski <jwz@jwz.org>
+/* cubetwist, Copyright © 2016-2025 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
@@ -20,6 +20,7 @@
 #include "normals.h"
 #include "rotator.h"
 #include "gltrackball.h"
+#include "easing.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -211,25 +212,6 @@ make_cubes (ModeInfo *mi)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static void
 tick_oscillators (ModeInfo *mi)
 {
@@ -245,7 +227,7 @@ tick_oscillators (ModeInfo *mi)
       if (a->ratio > 1)
         a->ratio = 1;
 
-      *a->var = a->from + (a->to - a->from) * ease_ratio (a->ratio);
+      *a->var = a->from + (a->to - a->from) * ease(EASE_IN_OUT_SINE, a->ratio);
 
       if (a->ratio < 1)                        /* mid cycle */
         prev = a;
index ab65d3895061c6c40f18521e9416c2d1b2dd77e7..f25ce17395f1e7d59582fd4d926bb83083338347 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "" "X Version 11"
 .SH NAME
-cubocteversion - Displays a cuboctahedron eversion.
+cubocteversion \- Displays a cuboctahedron eversion.
 .SH SYNOPSIS
 .B cubocteversion
 [\-\-display \fIhost:display.screen\fP]
index c0392f4d06f0306ac70f5a1e9fe6c41417267c04..39edc722c94e0be190b2abaa98a177a9a669d724 100644 (file)
@@ -34,6 +34,7 @@
 #include "rotator.h"
 #include "gltrackball.h"
 #include "gllist.h"
+#include "easing.h"
 #include <ctype.h>
 
 #define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
@@ -638,26 +639,6 @@ draw_component (ModeInfo *mi, int i, Bool half_p)
 }
 
 
-static double
-easeOutBounce (double i)
-{
-  double n1 = 7.5625;
-  double d1 = 2.75;
-  if (i < 1 / d1) {
-    return n1 * i * i;
-  } else if (i < 2 / d1) {
-    i -= (1.5 / d1);
-    return n1 * i * i + 0.75;
-  } else if (i < 2.5 / d1) {
-    i -= (2.25 / d1);
-    return n1 * i * i + 0.9375;
-  } else {
-    i -= (2.625 / d1);
-    return n1 * i * i + 0.984375;
-  }
-}
-
-
 static void
 tick_dumpster (ModeInfo *mi)
 {
@@ -735,7 +716,7 @@ draw_box (ModeInfo *mi)
   switch (bp->state) {
   case DROP:
     bp->pos.x = bp->pos.y = 0;
-    bp->pos.z = (1 - easeOutBounce (bp->tick)) * 3;
+    bp->pos.z = (1 - ease (EASE_OUT_BOUNCE, (bp->tick))) * 3;
     break;
   case OPEN:
     bp->lid_angle[(bp->lid_angle[0] == 0.0 ? 1 : 0)] = bp->tick     + 0.0001;
@@ -767,8 +748,8 @@ draw_box (ModeInfo *mi)
       const GLfloat deg = 115;
       const XYZ off = { 0, 0.63, -0.25 };
       double a2 = (bp->state == CLOSE
-                   ? 1 - easeOutBounce (1 - bp->lid_angle[i])
-                   :     easeOutBounce (    bp->lid_angle[i]));
+                   ? 1 - ease (EASE_OUT_BOUNCE, (1 - bp->lid_angle[i]))
+                   :     ease (EASE_OUT_BOUNCE, (    bp->lid_angle[i])));
 
       glPushMatrix();
       glTranslatef (off.x, off.y, off.z);
@@ -818,6 +799,8 @@ draw_dumpster (ModeInfo *mi)
  /* glRotatef (z * 360, 0.0, 0.0, 1.0); */
   }
 
+  glRotatef (current_device_rotation(), 0, 0, 1);
+
   mi->polygon_count = 0;
 
   glTranslatef (0, -6, 0);
index 35e1c1504e9d80a971b2350452e100f3723922e6..37816b146c2fbd437551eca1ea86ccde87c06274 100644 (file)
@@ -1,5 +1,5 @@
 /* dymaxionmap --- Buckminster Fuller's unwrapped icosahedral globe.
- * Copyright © 2016-2022 Jamie Zawinski.
+ * Copyright © 2016-2025 Jamie Zawinski.
  *
  * Permission to use, copy, modify, and distribute this software and its
  * documentation for any purpose and without fee is hereby granted,
@@ -31,6 +31,8 @@
 
 #include "sphere.h"
 #include "normals.h"
+#include "easing.h"
+#include "doubletime.h"
 #include "texfont.h"
 #include "dymaxionmap-coords.h"
 
@@ -156,21 +158,6 @@ typedef struct {
 static planetstruct *planets = NULL;
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 /* Draw faint latitude and longitude lines into the RGBA XImage.
  */
 static void
@@ -1494,25 +1481,6 @@ init_planet (ModeInfo * mi)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.35;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 ENTRYPOINT void
 draw_planet (ModeInfo * mi)
 {
@@ -1696,7 +1664,7 @@ draw_planet (ModeInfo * mi)
     case STEL_IN:  fold_ratio = 1; stel_ratio = gp->ratio; break;
     case STEL_OUT: fold_ratio = 1; stel_ratio = 1 - gp->ratio; break;
     case STARTUP:      /* Tilt in from flat */
-      glRotatef (-90 * ease_ratio (1 - gp->ratio), 1, 0, 0);
+      glRotatef (-90 * ease (EASE_IN_OUT_SINE, 1 - gp->ratio), 1, 0, 0);
       break;
 
     default: break;
@@ -1704,7 +1672,7 @@ draw_planet (ModeInfo * mi)
 
 # ifdef HAVE_MOBILE  /* Enlarge the icosahedron a bit to make it more visible */
     {
-      GLfloat s = 1 + 1.3 * ease_ratio (fold_ratio);
+      GLfloat s = 1 + 1.3 * ease (EASE_IN_OUT_SINE, fold_ratio);
       glScalef (s, s, s);
     }
 # endif
@@ -1712,11 +1680,13 @@ draw_planet (ModeInfo * mi)
     if (gp->state == SPIN)
       {
         align_axis (mi, 0);
-        glRotatef (ease_ratio (gp->ratio) * 360 * 3, 0, 0, 1);
+        glRotatef (ease (EASE_IN_OUT_SINE, gp->ratio) * 360 * 3, 0, 0, 1);
         align_axis (mi, 1);
       }
 
-    draw_triangles (mi, ease_ratio (fold_ratio), ease_ratio (stel_ratio));
+    draw_triangles (mi,
+                    ease (EASE_IN_OUT_SINE, fold_ratio),
+                    ease (EASE_IN_OUT_SINE, stel_ratio));
 
     if (gp->state == AXIS)
       draw_axis(mi);
index 724af959b1aa2d6636c5f1b2d9227d1a515a98c6..2c1b7f4a1c73488e5afcdda6d4e064d94b5a76c2 100644 (file)
  * implied warranty.
  */
 
+/* TODO: correct castling moves */
 #ifdef STANDALONE
-#define DEFAULTS       "*delay:     20000 \n" \
-                       "*showFPS:   False \n" \
-                      "*wireframe: False \n" \
+#define DEFAULTS                                                               \
+    "*delay:      20000 \n"                                                    \
+    "*showFPS:    False \n"                                                    \
+    "*wireframe:  False \n"                                                    \
+    "*titleFont:  sans-serif 18\n"                                             \
+    "*titleFont2: sans-serif 12\n"                                             \
+    "*titleFont3: sans-serif 8\n"
 
-# define release_chess 0
-# include "xlockmore.h"
+#define release_chess 0
+#include "xlockmore.h"
 
 #else
-# include "xlock.h"
+#include "xlock.h"
 #endif
 
 #ifdef USE_GL
 #include "gltrackball.h"
 #include "chessmodels.h"
 #include "chessgames.h"
+#include "texfont.h"
+#include "easing.h"
 
-#define DEF_ROTATE      "True"
+#define DEF_ROTATE "True"
 #define DEF_REFLECTIONS "True"
-#define DEF_SHADOWS     "True"
-#define DEF_SMOOTH      "True"
-#define DEF_CLASSIC     "False"
-
+#define DEF_SHADOWS "True"
+#define DEF_SMOOTH "True"
+#define DEF_CLASSIC "False"
+#define DEF_LABELS "True"
 
 static XrmOptionDescRec opts[] = {
-  {"+rotate", ".chess.rotate", XrmoptionNoArg, "false" },
-  {"-rotate", ".chess.rotate", XrmoptionNoArg, "true" },
-  {"+reflections", ".chess.reflections", XrmoptionNoArg, "false" },
-  {"-reflections", ".chess.reflections", XrmoptionNoArg, "true" },
-  {"+shadows", ".chess.shadows", XrmoptionNoArg, "false" },
-  {"-shadows", ".chess.shadows", XrmoptionNoArg, "true" },
-  {"+smooth", ".chess.smooth", XrmoptionNoArg, "false" },
-  {"-smooth", ".chess.smooth", XrmoptionNoArg, "true" },
-  {"+classic", ".chess.classic", XrmoptionNoArg, "false" },
-  {"-classic", ".chess.classic", XrmoptionNoArg, "true" },
+    {"+rotate", ".chess.rotate", XrmoptionNoArg, "false"},
+    {"-rotate", ".chess.rotate", XrmoptionNoArg, "true"},
+    {"+reflections", ".chess.reflections", XrmoptionNoArg, "false"},
+    {"-reflections", ".chess.reflections", XrmoptionNoArg, "true"},
+    {"+shadows", ".chess.shadows", XrmoptionNoArg, "false"},
+    {"-shadows", ".chess.shadows", XrmoptionNoArg, "true"},
+    {"+smooth", ".chess.smooth", XrmoptionNoArg, "false"},
+    {"-smooth", ".chess.smooth", XrmoptionNoArg, "true"},
+    {"+classic", ".chess.classic", XrmoptionNoArg, "false"},
+    {"-classic", ".chess.classic", XrmoptionNoArg, "true"},
+    {"+labels", ".chess.labels", XrmoptionNoArg, "false"},
+    {"-labels", ".chess.labels", XrmoptionNoArg, "true"},
 };
 
-static int rotate, reflections, smooth, shadows, classic;
+static int rotate, reflections, smooth, shadows, classic, labels;
 
 static argtype vars[] = {
-  {&rotate,      "rotate",      "Rotate",      DEF_ROTATE, t_Bool},
-  {&reflections, "reflections", "Reflections", DEF_REFLECTIONS, t_Bool},
-  {&shadows,    "shadows",      "Shadows",    DEF_SHADOWS, t_Bool},
-  {&smooth,      "smooth",      "Smooth",      DEF_SMOOTH, t_Bool},
-  {&classic,     "classic",     "Classic",     DEF_CLASSIC, t_Bool},
+    {&rotate, "rotate", "Rotate", DEF_ROTATE, t_Bool},
+    {&reflections, "reflections", "Reflections", DEF_REFLECTIONS, t_Bool},
+    {&shadows, "shadows", "Shadows", DEF_SHADOWS, t_Bool},
+    {&smooth, "smooth", "Smooth", DEF_SMOOTH, t_Bool},
+    {&classic, "classic", "Classic", DEF_CLASSIC, t_Bool},
+    {&labels, "labels", "Labels", DEF_LABELS, t_Bool},
 };
 
-ENTRYPOINT ModeSpecOpt chess_opts = {countof(opts), opts, countof(vars), vars, NULL};
+ENTRYPOINT ModeSpecOpt chess_opts = {countof(opts), opts, countof(vars), vars,
+                                     NULL};
 
 #ifdef USE_MODULES
-ModStruct   chess_description =
-{"chess", "init_chess", "draw_chess", NULL,
- "draw_chess", "init_chess", NULL, &chess_opts,
- 1000, 1, 2, 1, 4, 1.0, "",
- "Chess", 0, NULL};
+ModStruct chess_description = {"chess",
+                               "init_chess",
+                               "draw_chess",
+                               NULL,
+                               "draw_chess",
+                               "init_chess",
+                               NULL,
+                               &chess_opts,
+                               1000,
+                               1,
+                               2,
+                               1,
+                               4,
+                               1.0,
+                               "",
+                               "Chess",
+                               0,
+                               NULL};
 
 #endif
 
 #define checkImageWidth 16
 #define checkImageHeight 16
+#define CONCURRENT_MOVES 2
+#define TICKS_BET_MOVES 50
+#define FADE_FACTOR 2
+#define END_FACTOR 5
+#define NUM_STEPS 80
+
+const double num_steps_f = (double)NUM_STEPS;
+
+enum app_stage {
+    CHOSE_GAME = 0,
+    FADE_IN,
+    DO_MOVE,
+    WAIT_FOR_NEXT_MOVE,
+    WAIT_FOR_NEXT_GAME,
+    FADE_OUT
+};
 
-typedef struct {
-  GLXContext *glx_context;
-  Window window;
-  trackball_state *trackball;
-  Bool button_down_p;
+enum color { WHITE = 0, BLACK };
 
-  ChessGame game;
-  int oldwhite;
+typedef struct {
+    int active;        /* Is a piece moving */
+    int mpiece;        /* The moving piece */
+    int tpiece;        /* Piece taken by this move, if any */
+    int promotion;     /* Promotion piece */
+    int from[2];       /* Origin case */
+    int to[2];         /* destination case */
+    int en_passant[2]; /* Is this an en passant capture */
+    enum color color;  /* White or black move */
+    double dx;         /* Delta x */
+    double dz;         /* Delta z */
+    int castling;      /* Are we castling */
+} Chessmovestate;
 
-  /** definition of white/black (orange/gray) colors */
-  GLfloat colors[2][3];
+typedef struct {
+    GLXContext *glx_context;
+    Window window;
+    trackball_state *trackball;
+    Bool button_down_p;
 
-  GLubyte checkImage[checkImageWidth][checkImageHeight][3];
-  GLuint piecetexture, boardtexture;
+    ChessGame game;
+    char game_desc[DESC_STR_LEN + SAN_STR_LEN + 1];
+    int move_desc_index;
+    int oldwhite;
 
-  int mpiece, tpiece, steps, done;
-  double from[2], to[2];
-  double dx, dz;
-  int moving, take, mc, count, wire;
-  double theta;
+    /** definition of white/black (orange/gray) colors */
+    GLfloat colors[2][3];
 
-  GLfloat position[4];
-  GLfloat position2[4];
+    GLubyte checkImage[checkImageWidth][checkImageHeight][3];
+    GLuint piecetexture, boardtexture;
 
-  GLfloat mod;
+    int board[BOARDSIZE][BOARDSIZE];
+    Chessmovestate moves[CONCURRENT_MOVES]; /* If castling, two pieces can move
+                                               at the same time */
+    int steps;
+    enum app_stage stage;
+    int mc, ticks, wire, abort;
+    double theta;
 
-  GLfloat ground[4];
+    GLfloat position[4];
+    GLfloat position2[4];
 
-  int oldgame;
+    GLfloat mod;
 
-  int poly_counts[PIECES];  /* polygon count of each type of piece */
+    GLfloat ground[4];
 
+    int cur_game_idx;
 
+    texture_font_data *font1_data, *font2_data, *font3_data;
+    int poly_counts[PIECES]; /* polygon count of each type of piece */
 } Chesscreen;
 
 static Chesscreen *qs = NULL;
 
-static const GLfloat MaterialShadow[] =   {0.0, 0.0, 0.0, 0.3};
-
+static const GLfloat MaterialShadow[] = {0.0, 0.0, 0.0, 0.3};
 
 /* i prefer silvertip */
-static const GLfloat whites[WHITES][3] = 
-  {
-    {1.0, 0.55, 0.1},
-    {0.8, 0.52, 0.8},
-    {0.43, 0.54, 0.76},
-    {0.2, 0.2, 0.2},
-    {0.35, 0.60, 0.35},
-  };
-
-static void build_colors(Chesscreen *cs) 
-{
+static const GLfloat whites[WHITES][3] = {
+    {1.0, 0.55, 0.1}, {0.8, 0.52, 0.8},   {0.43, 0.54, 0.76},
+    {0.7, 0.7, 0.7},  {0.35, 0.60, 0.35},
+};
+
+static void build_colors(Chesscreen *cs) {
 
-  /* find new white */
-  int newwhite = cs->oldwhite;
-  while(newwhite == cs->oldwhite)
-    newwhite = random()%WHITES;
-  cs->oldwhite = newwhite;
+    /* find new white */
+    int newwhite = cs->oldwhite;
+    while (newwhite == cs->oldwhite)
+        newwhite = random() % WHITES;
+    cs->oldwhite = newwhite;
 
-  cs->colors[0][0] = whites[cs->oldwhite][0];
-  cs->colors[0][1] = whites[cs->oldwhite][1];
-  cs->colors[0][2] = whites[cs->oldwhite][2];
+    cs->colors[0][0] = whites[cs->oldwhite][0];
+    cs->colors[0][1] = whites[cs->oldwhite][1];
+    cs->colors[0][2] = whites[cs->oldwhite][2];
 }
 
 /* build piece texture */
-static void make_piece_texture(Chesscreen *cs) 
-{
-  int i, j, c;
-
-  for (i = 0; i < checkImageWidth; i++) {
-    for (j = 0; j < checkImageHeight; j++) {
-      c = ((j%2) == 0 || i%2 == 0) ? 240 : 180+random()%16;
-      cs->checkImage[i][j][0] = (GLubyte) c;
-      cs->checkImage[i][j][1] = (GLubyte) c;
-      cs->checkImage[i][j][2] = (GLubyte) c;
+static void make_piece_texture(Chesscreen *cs) {
+    int i, j, c;
+
+    for (i = 0; i < checkImageWidth; i++) {
+        for (j = 0; j < checkImageHeight; j++) {
+            c = ((j % 2) == 0 || i % 2 == 0) ? 240 : 180 + random() % 16;
+            cs->checkImage[i][j][0] = (GLubyte)c;
+            cs->checkImage[i][j][1] = (GLubyte)c;
+            cs->checkImage[i][j][2] = (GLubyte)c;
+        }
     }
-  }
 
-  glGenTextures(1, &cs->piecetexture);
-  glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
+    glGenTextures(1, &cs->piecetexture);
+    glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
 
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
-  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, 
-              checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 
-              &cs->checkImage[0][0]);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, checkImageHeight, 0,
+                 GL_RGB, GL_UNSIGNED_BYTE, &cs->checkImage[0][0]);
 }
 
 /* build board texture (uniform noise in [180,180+50]) */
-static void make_board_texture(Chesscreen *cs) 
-{
-  int i, j, c;
-
-  for (i = 0; i < checkImageWidth; i++) {
-    for (j = 0; j < checkImageHeight; j++) {
-      c = 180 + random()%51;
-      cs->checkImage[i][j][0] = (GLubyte) c;
-      cs->checkImage[i][j][1] = (GLubyte) c;
-      cs->checkImage[i][j][2] = (GLubyte) c;
+static void make_board_texture(Chesscreen *cs) {
+    int i, j, c;
+
+    for (i = 0; i < checkImageWidth; i++) {
+        for (j = 0; j < checkImageHeight; j++) {
+            c = 180 + random() % 51;
+            cs->checkImage[i][j][0] = (GLubyte)c;
+            cs->checkImage[i][j][1] = (GLubyte)c;
+            cs->checkImage[i][j][2] = (GLubyte)c;
+        }
     }
-  }
 
-  glGenTextures(1, &cs->boardtexture);
-  glBindTexture(GL_TEXTURE_2D, cs->boardtexture);
+    glGenTextures(1, &cs->boardtexture);
+    glBindTexture(GL_TEXTURE_2D, cs->boardtexture);
 
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
-  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, 
-              checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 
-              &cs->checkImage[0][0]);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, checkImageHeight, 0,
+                 GL_RGB, GL_UNSIGNED_BYTE, &cs->checkImage[0][0]);
 }
 
 /** handle X event (trackball) */
-ENTRYPOINT Bool chess_handle_event (ModeInfo *mi, XEvent *event) 
-{
-  Chesscreen *cs = &qs[MI_SCREEN(mi)];
-
-  if (gltrackball_event_handler (event, cs->trackball,
-                                 MI_WIDTH (mi), MI_HEIGHT (mi),
-                                 &cs->button_down_p))
-    return True;
-  else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
-    {
-      cs->done = 1;
-      return True;
+ENTRYPOINT Bool chess_handle_event(ModeInfo *mi, XEvent *event) {
+    Chesscreen *cs = &qs[MI_SCREEN(mi)];
+
+    if (gltrackball_event_handler(event, cs->trackball, MI_WIDTH(mi),
+                                  MI_HEIGHT(mi), &cs->button_down_p))
+        return True;
+    else if (screenhack_event_helper(MI_DISPLAY(mi), MI_WINDOW(mi), event)) {
+        cs->abort = 1;
+        return True;
     }
-  return False;
+
+    return False;
 }
 
 static const GLfloat diffuse2[] = {1.0, 1.0, 1.0, 1.0};
@@ -220,764 +266,1185 @@ static const GLfloat shininess[] = {60.0};
 static const GLfloat specular[] = {0.4, 0.4, 0.4, 1.0};
 
 /* configure lighting */
-static void setup_lights(Chesscreen *cs) 
-{
-  glEnable(GL_LIGHTING);
-  glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
-  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse2);
-  glEnable(GL_LIGHT0);
+static void setup_lights(Chesscreen *cs) {
+    glEnable(GL_LIGHTING);
+    glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse2);
+    glEnable(GL_LIGHT0);
 
-/*   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient2); */
+    /*   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient2); */
 
-  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
-  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
 
-  glLightfv(GL_LIGHT1, GL_SPECULAR, diffuse2);
-  glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse2);
-  glEnable(GL_LIGHT1);
+    glLightfv(GL_LIGHT1, GL_SPECULAR, diffuse2);
+    glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse2);
+    glEnable(GL_LIGHT1);
+}
+
+static enum color get_piece_color(int piece) {
+    if (piece < BKING)
+        return WHITE;
+    return BLACK;
 }
 
 /* draw pieces */
-static void drawPieces(ModeInfo *mi, Chesscreen *cs) 
-{
-  int i, j;
-
-  for(i = 0; i < BOARDSIZE; ++i) {
-    for(j = 0; j < BOARDSIZE; ++j) {
-      if(cs->game.board[i][j]) {       
-       int c = cs->game.board[i][j]/PIECES;
-       glColor3fv(cs->colors[c]);
-       glCallList(cs->game.board[i][j]%PIECES);
-        mi->polygon_count += cs->poly_counts[cs->game.board[i][j]%PIECES];
-      }
-      
-      glTranslatef(1.0, 0.0, 0.0);
-    }
-    
-    glTranslatef(-1.0*BOARDSIZE, 0.0, 1.0);
-  }
+static void drawPieces(ModeInfo *mi, Chesscreen *cs) {
+    int i, j;
 
-  glTranslatef(0.0, 0.0, -1.0*BOARDSIZE);
+    for (i = 0; i < BOARDSIZE; ++i) {
+        for (j = 0; j < BOARDSIZE; ++j) {
+            if (cs->board[i][j]) {
+                int c = cs->board[i][j] / PIECES;
+                int piece = cs->board[i][j] % PIECES;
+                int side = (cs->board[i][j] == piece ? 1 : -1);
+                glColor3fv(cs->colors[c]);
+                if (cs->board[i][j] == KNIGHT)
+                    glRotatef(180.0, 0.0, 1.0, 0.0);
+                else if (piece == BISHOP)
+                    glRotatef(90.0 * side, 0.0, 1.0, 0.0);
+                glCallList(piece);
+                if (cs->board[i][j] == KNIGHT)
+                    glRotatef(180.0, 0.0, 1.0, 0.0);
+                else if (piece == BISHOP)
+                    glRotatef(-90.0 * side, 0.0, 1.0, 0.0);
+                mi->polygon_count += cs->poly_counts[cs->board[i][j] % PIECES];
+            }
+            glTranslatef(1.0, 0.0, 0.0);
+        }
+        glTranslatef(-1.0 * BOARDSIZE, 0.0, 1.0);
+    }
+    glTranslatef(0.0, 0.0, -1.0 * BOARDSIZE);
 }
 
 /* draw pieces */
-static void drawPiecesShadow(ModeInfo *mi, Chesscreen *cs) 
-{
-  int i, j;
-
-  for(i = 0; i < BOARDSIZE; ++i) {
-    for(j = 0; j < BOARDSIZE; ++j) {
-      if(cs->game.board[i][j]) {       
-       glColor4f(0.0, 0.0, 0.0, 0.4);
-       glCallList(cs->game.board[i][j]%PIECES);
-        mi->polygon_count += cs->poly_counts[cs->game.board[i][j]%PIECES];
-      }
-      
-      glTranslatef(1.0, 0.0, 0.0);
-    }
-    
-    glTranslatef(-1.0*BOARDSIZE, 0.0, 1.0);
-  }
+static void drawPiecesShadow(ModeInfo *mi, Chesscreen *cs) {
+    int i, j;
 
-  glTranslatef(0.0, 0.0, -1.0*BOARDSIZE);
+    for (i = 0; i < BOARDSIZE; ++i) {
+        for (j = 0; j < BOARDSIZE; ++j) {
+            if (cs->board[i][j]) {
+                glColor4f(0.0, 0.0, 0.0, 0.4);
+                glCallList(cs->board[i][j] % PIECES);
+                mi->polygon_count += cs->poly_counts[cs->board[i][j] % PIECES];
+            }
+            glTranslatef(1.0, 0.0, 0.0);
+        }
+        glTranslatef(-1.0 * BOARDSIZE, 0.0, 1.0);
+    }
+    glTranslatef(0.0, 0.0, -1.0 * BOARDSIZE);
 }
 
-/* draw a moving piece */
-static void drawMovingPiece(ModeInfo *mi, Chesscreen *cs, int shadow) 
-{
-  int piece = cs->mpiece % PIECES;
-
-  if (piece == NONE) return;
+/** Helpers */
+static int char_to_piece(char piece_char) {
+    switch (piece_char) {
+    case 'p':
+        return BPAWN;
+    case 'P':
+        return PAWN;
+    case 'q':
+        return BQUEEN;
+    case 'Q':
+        return QUEEN;
+    case 'k':
+        return BKING;
+    case 'K':
+        return KING;
+    case 'b':
+        return BBISHOP;
+    case 'B':
+        return BISHOP;
+    case 'n':
+        return BKNIGHT;
+    case 'N':
+        return KNIGHT;
+    case 'r':
+        return BROOK;
+    case 'R':
+        return ROOK;
+    default:
+        return NONE;
+    }
+    return NONE;
+}
 
-  glPushMatrix();
+static int get_digit(char c) {
+    switch (c) {
+    case '1':
+        return 1;
+    case '2':
+        return 2;
+    case '3':
+        return 3;
+    case '4':
+        return 4;
+    case '5':
+        return 5;
+    case '6':
+        return 6;
+    case '7':
+        return 7;
+    case '8':
+        return 8;
+    default:
+        return 0;
+    }
+    return 0;
+}
 
-  if(shadow) glColor4fv(MaterialShadow);
-  else glColor3fv(cs->colors[cs->mpiece/PIECES]);
+static int char_to_rowcol(char c) {
+    switch (c) {
+    case 'a':
+    case '8':
+        return 0;
+    case 'b':
+    case '7':
+        return 1;
+    case 'c':
+    case '6':
+        return 2;
+    case 'd':
+    case '5':
+        return 3;
+    case 'e':
+    case '4':
+        return 4;
+    case 'f':
+    case '3':
+        return 5;
+    case 'g':
+    case '2':
+        return 6;
+    case 'h':
+    case '1':
+        return 7;
+    default:
+        return -1;
+    }
+    return -1;
+}
 
-  /** assume a queening.  should be more general */
-  if((cs->mpiece == PAWN  && fabs(cs->to[0]) < 0.01) || 
-     (cs->mpiece == BPAWN && fabs(cs->to[0]-7.0) < 0.01)) {
-    glTranslatef(cs->from[1]+cs->steps*cs->dx, 0.0, cs->from[0]+cs->steps*cs->dz);
+static void apply_fen(Chesscreen *cs) {
+    char *row, *saveptr;
+    char *fen = cs->game.fen;
+
+    row = strtok_r(fen, "/", &saveptr);
+    for (int row_num = 0; row_num < 8; row_num++) {
+        int col_num = 0;
+        for (int char_num = 0; char_num < strlen(row); char_num++) {
+            char c = row[char_num];
+            int d = get_digit(c);
+            for (int i = 0; i < d; i++) {
+                cs->board[row_num][col_num++] = NONE;
+            }
+            int p = char_to_piece(c);
+            if (p != NONE) {
+                cs->board[row_num][col_num++] = p;
+            }
+        }
+        row = strtok_r(NULL, "/", &saveptr);
+    }
+}
 
-    glColor4f(shadow ? MaterialShadow[0] : cs->colors[cs->mpiece/7][0], 
-             shadow ? MaterialShadow[1] : cs->colors[cs->mpiece/7][1], 
-             shadow ? MaterialShadow[2] : cs->colors[cs->mpiece/7][2],
-             (fabs(50.0-cs->steps))/50.0);
+static void coord_to_case(char *uci, int chess_case[2]) {
+    chess_case[0] = char_to_rowcol(uci[1]);
+    chess_case[1] = char_to_rowcol(uci[0]);
+}
 
-    piece = cs->steps < 50 ? PAWN : QUEEN;
+static int color_piece(int piece, enum color color) {
+    if (piece == NONE)
+        return piece;
+    if (color == WHITE)
+        return piece % PIECES;
+    return (piece % PIECES) + PIECES;
+}
 
-    /* what a kludge */
-    if(cs->steps == 99)
-      cs->mpiece = cs->mpiece == PAWN ? QUEEN : BQUEEN;
-  }
-  else if(cs->mpiece % PIECES == KNIGHT) {
-    /* If there is nothing in the path of a knight, move it by sliding,
-       just like the other pieces.  But if there are any pieces on the
-       middle two squares in its path, the knight would intersect them,
-       so in that case, move it in an airborne arc. */
-    GLfloat y;
-    int i, j;
-    Bool blocked_p = False;
-    int fromx = MIN(cs->from[1], cs->to[1]);
-    int fromy = MIN(cs->from[0], cs->to[0]);
-    int tox   = MAX(cs->from[1], cs->to[1]);
-    int toy   = MAX(cs->from[0], cs->to[0]);
-    if (fromx == tox-2) fromx = tox = fromx+1;
-    if (fromy == toy-2) fromy = toy = fromy+1;
-    for (i = fromy; i <= toy; i++) {
-      for (j = fromx; j <= tox; j++) {
-        if (cs->game.board[i][j]) {
-          blocked_p = True;
-          break;
+static void setup_move(Chesscreen *cs, char *uci, int move_index) {
+    Chessmovestate *movestate = &(cs->moves[move_index]);
+    coord_to_case(uci, movestate->from);
+    coord_to_case(uci + 2, movestate->to);
+    movestate->mpiece = cs->board[movestate->from[0]][movestate->from[1]];
+    movestate->color = get_piece_color(movestate->mpiece);
+    if (strlen(uci) == 5)
+        movestate->promotion =
+            color_piece(char_to_piece(uci[4]), movestate->color);
+    movestate->dz = (movestate->to[0] - movestate->from[0]) / num_steps_f;
+    movestate->dx = (movestate->to[1] - movestate->from[1]) / num_steps_f;
+    cs->board[movestate->from[0]][movestate->from[1]] =
+        NONE; /* Remove moving piece from board */
+
+    movestate->tpiece = cs->board[movestate->to[0]][movestate->to[1]];
+    /* Capture ? */
+    if (movestate->tpiece != NONE) {
+        cs->board[movestate->to[0]][movestate->to[1]] =
+            NONE; /* Remove captured piece from board */
+        movestate->en_passant[0] = movestate->en_passant[1] =
+            -1; /* Not en passant */
+    } else {    /* Destination case is empty. Is this an en passant capture ? */
+        /* White en passant ? */
+        if ((movestate->mpiece == PAWN) && (movestate->from[0] == 3) &&
+            (movestate->from[1] != movestate->to[1])) {
+            movestate->tpiece = BPAWN;
+            movestate->en_passant[0] = 3;
+            movestate->en_passant[1] = movestate->to[1];
+            cs->board[movestate->en_passant[0]][movestate->en_passant[1]] =
+                NONE; /* Remove captured piece */
+        }
+        /* Black en passant ? */
+        else if ((movestate->mpiece == BPAWN) && (movestate->from[0] == 4) &&
+                 (movestate->from[1] != movestate->to[1])) {
+            movestate->tpiece = PAWN;
+            movestate->en_passant[0] = 4;
+            movestate->en_passant[1] = movestate->to[1];
+            cs->board[movestate->en_passant[0]][movestate->en_passant[1]] =
+                NONE; /* Remove captured piece */
         }
-      }
     }
+    movestate->active = 1;
+}
 
-    if (!blocked_p)
-      goto SLIDE;
+static void setup_moves(Chesscreen *cs, char *uci) {
+    setup_move(cs, uci, 0);         /* General case */
+    if (!strncmp(uci, "e1g1", 4)) { /* White king castling */
+        setup_move(cs, "h1f1", 1);  /* rook will move at the same time */
+        cs->moves[1].castling = 1;
+        return;
+    }
+    if (!strncmp(uci, "e1c1", 4)) { /* White queen castling */
+        setup_move(cs, "a1d1", 1);  /* rook will move at the same time */
+        cs->moves[1].castling = 1;
+        return;
+    }
+    if (!strncmp(uci, "e8g8", 4)) { /* Black king castling */
+        setup_move(cs, "h8f8", 1);  /* rook will move at the same time */
+        cs->moves[1].castling = 1;
+        return;
+    }
+    if (!strncmp(uci, "e8c8", 4)) { /* Black queen castling */
+        setup_move(cs, "a8d8", 1);  /* rook will move at the same time */
+        cs->moves[1].castling = 1;
+        return;
+    }
+}
 
-    /* Move by hopping. */
-    y = 1.5 * sin (M_PI * cs->steps / 100.0);
-    glTranslatef(cs->from[1]+cs->steps*cs->dx, y,
-                 cs->from[0]+cs->steps*cs->dz);
+static int are_moves_active(Chesscreen *cs) {
+    for (int i = 0; i < CONCURRENT_MOVES; i++) {
+        if (cs->moves[i].active)
+            return 1;
+    }
+    return 0;
+}
 
-  } else {
-  SLIDE:
-    /* Move by sliding. */
-    glTranslatef(cs->from[1]+cs->steps*cs->dx, 0.0, cs->from[0]+cs->steps*cs->dz);
-  }
+static int is_a_piece_taken(Chesscreen *cs) {
+    for (int i = 0; i < CONCURRENT_MOVES; i++) {
+        if (cs->moves[i].tpiece != NONE)
+            return 1;
+    }
+    return 0;
+}
 
+static void init_moves(Chesscreen *cs) {
+    for (int i = 0; i < CONCURRENT_MOVES; i++) {
+        cs->moves[i].active = 0;
+        cs->moves[i].tpiece = cs->moves[i].mpiece = NONE;
+        cs->moves[i].promotion = NONE;
+        cs->moves[i].en_passant[0] = cs->moves[i].en_passant[1] = -1;
+        cs->moves[i].color = WHITE;
+        cs->moves[i].dx = cs->moves[i].dz = 0;
+        cs->moves[i].castling = 0;
+    }
+}
 
-  if(!cs->wire)
-    glEnable(GL_BLEND);
-  
-  glCallList(piece);
-  mi->polygon_count += cs->poly_counts[cs->mpiece % PIECES];
+static double
+ease_move (double x, double max)
+{
+  if (max == 0) return x;
+  if (max < 0) max = -max;
+  if (x > 0)
+    return max * ease (EASE_IN_OUT_CUBIC, x / max);
+  else
+    return max * -ease (EASE_IN_OUT_CUBIC, -x / max);
+}
 
-  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
-  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
 
-  glPopMatrix();
+/* draw a moving piece */
+static void drawMovingPiece(ModeInfo *mi, Chesscreen *cs, int shadow) {
+    int piece, side, promotion_piece;
+
+    for (int i = 0; i < CONCURRENT_MOVES; i++) {
+        Chessmovestate *movestate = &(cs->moves[i]);
+        if (!movestate->active)
+            continue;
+        piece = movestate->mpiece % PIECES;
+        side = (movestate->color == WHITE ? 1 : -1);
+        if (piece == NONE)
+            continue;
+        promotion_piece = movestate->promotion;
+
+        glPushMatrix();
+
+        if (shadow)
+            glColor4fv(MaterialShadow);
+        else
+            glColor3fv(cs->colors[movestate->mpiece / PIECES]);
+
+        if ((movestate->mpiece == PAWN && abs(movestate->to[0]) < 0.01) ||
+            (movestate->mpiece == BPAWN &&
+             fabs(movestate->to[0] - 7.0) < 0.01)) {
+            glTranslatef(movestate->from[1] + cs->steps * movestate->dx, 0.0,
+                         movestate->from[0] + cs->steps * movestate->dz);
+            glColor4f(shadow ? MaterialShadow[0]
+                             : cs->colors[movestate->mpiece / 7][0],
+                      shadow ? MaterialShadow[1]
+                             : cs->colors[movestate->mpiece / 7][1],
+                      shadow ? MaterialShadow[2]
+                             : cs->colors[movestate->mpiece / 7][2],
+                      fabs((num_steps_f / 2.0) - cs->steps) /
+                          (num_steps_f / 2.0));
+
+            piece = cs->steps < NUM_STEPS / 2 ? PAWN : promotion_piece % PIECES;
+
+            /* what a kludge */
+            if (cs->steps == NUM_STEPS - 1)
+                movestate->mpiece = promotion_piece;
+        } else if (movestate->mpiece % PIECES == KNIGHT) {
+            /* If there is nothing in the path of a knight, move it by sliding,
+               just like the other pieces.  But if there are any pieces on the
+               middle two squares in its path, the knight would intersect them,
+               so in that case, move it in an airborne arc. */
+            GLfloat y;
+            int i, j;
+            Bool blocked_p = False;
+            int fromx = MIN(movestate->from[1], movestate->to[1]);
+            int fromy = MIN(movestate->from[0], movestate->to[0]);
+            int tox = MAX(movestate->from[1], movestate->to[1]);
+            int toy = MAX(movestate->from[0], movestate->to[0]);
+            if (fromx == tox - 2)
+                fromx = tox = fromx + 1;
+            if (fromy == toy - 2)
+                fromy = toy = fromy + 1;
+            for (i = fromy; i <= toy; i++) {
+                for (j = fromx; j <= tox; j++) {
+                    if (cs->board[i][j]) {
+                        blocked_p = True;
+                        break;
+                    }
+                }
+            }
+
+            if (!blocked_p)
+                goto SLIDE;
+
+            /* Move by hopping. */
+            y = 1.5 * sin(M_PI * cs->steps / num_steps_f);
+            glTranslatef(movestate->from[1] +
+                         ease_move (cs->steps * movestate->dx,
+                                    movestate->to[1] - movestate->from[1]),
+                         y,
+                         movestate->from[0] +
+                         ease_move (cs->steps * movestate->dz,
+                                    movestate->to[0] - movestate->from[0]));
+
+        } else if ((movestate->mpiece % PIECES == ROOK) &&
+                   movestate->castling) {
+            /* Move z in an arc */
+            GLfloat offset = 1.5 * sin(M_PI * cs->steps / num_steps_f);
+            glTranslatef(movestate->from[1] +
+                         ease_move (cs->steps * movestate->dx,
+                                    movestate->to[1] - movestate->from[1]),
+                         0.0,
+                         movestate->from[0] + 
+                         ease_move (cs->steps * movestate->dz +
+                                    (movestate->color == WHITE
+                                     ? offset : -offset),
+                                    movestate->to[0] - movestate->from[0]));
+        } else {
+        SLIDE:
+            /* Move by sliding. */
+            glTranslatef(movestate->from[1] +
+                         ease_move (cs->steps * movestate->dx,
+                                    movestate->to[1] - movestate->from[1]),
+                         0.0,
+                         movestate->from[0] + 
+                         ease_move (cs->steps * movestate->dz,
+                                    movestate->to[0] - movestate->from[0]));
+        }
 
-  if(!cs->wire)
-    glDisable(GL_BLEND);
+        if (!cs->wire)
+            glEnable(GL_BLEND);
+
+        if ((movestate->mpiece == KNIGHT) ||
+            ((promotion_piece == KNIGHT) && (cs->steps >= NUM_STEPS / 2)))
+            glRotatef(180.0, 0.0, 1.0, 0.0);
+        if ((piece == BISHOP) ||
+            ((promotion_piece == BISHOP) && (cs->steps >= NUM_STEPS / 2)))
+            glRotatef(90.0 * side, 0.0, 1.0, 0.0);
+        glCallList(piece);
+        if ((movestate->mpiece == KNIGHT) ||
+            ((promotion_piece == KNIGHT) && (cs->steps >= NUM_STEPS / 2)))
+            glRotatef(180.0, 0.0, 1.0, 0.0);
+        if ((piece == BISHOP) ||
+            ((promotion_piece == BISHOP) && (cs->steps >= NUM_STEPS / 2)))
+            glRotatef(-90.0 * side, 0.0, 1.0, 0.0);
+        mi->polygon_count += cs->poly_counts[movestate->mpiece % PIECES];
+
+        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
+        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
+
+        glPopMatrix();
+
+        if (!cs->wire)
+            glDisable(GL_BLEND);
+    }
 }
 
 /** code to squish a taken piece */
-static void drawTakePiece(ModeInfo *mi, Chesscreen *cs, int shadow) 
-{
-  if(!cs->wire)
-    glEnable(GL_BLEND);
-
-  glColor4f(shadow ? MaterialShadow[0] : cs->colors[cs->tpiece/7][0], 
-           shadow ? MaterialShadow[1] : cs->colors[cs->tpiece/7][1], 
-           shadow ? MaterialShadow[2] : cs->colors[cs->tpiece/7][2],
-            (100-1.6*cs->steps)/100.0);
-
-  glTranslatef(cs->to[1], 0.0, cs->to[0]);
-  
-  if(cs->mpiece % PIECES == KNIGHT)
-    glScalef(1.0+cs->steps/100.0, 1.0, 1.0+cs->steps/100.0);
-  else
-    glScalef(1.0, 1 - cs->steps/50.0 > 0.01 ? 1 - cs->steps/50.0 : 0.01, 1.0);
-  glCallList(cs->tpiece % 7);
-  mi->polygon_count += cs->poly_counts[cs->tpiece % PIECES];
-  
-  if(!cs->wire)
-    glDisable(GL_BLEND);
-}
+static void drawTakePiece(ModeInfo *mi, Chesscreen *cs, int shadow) {
+    if (!cs->wire)
+        glEnable(GL_BLEND);
+
+    /* Only the first move can take a piece in case of multiple
+     * concurrent moves (castling). So we could only consider the first move
+     * for capture... but let's loop anyway over all concurrent moves since it
+     * costs almost nothing */
+    for (int i = 0; i < CONCURRENT_MOVES; i++) {
+        Chessmovestate *movestate = &(cs->moves[i]);
+        int side = (movestate->color == BLACK ? 1 : -1);
+        if (!movestate->active)
+            continue;
+
+        glColor4f(
+            shadow ? MaterialShadow[0] : cs->colors[movestate->tpiece / 7][0],
+            shadow ? MaterialShadow[1] : cs->colors[movestate->tpiece / 7][1],
+            shadow ? MaterialShadow[2] : cs->colors[movestate->tpiece / 7][2],
+            (num_steps_f - 1.6 * cs->steps) / num_steps_f);
+
+        if (movestate->en_passant[0] != -1) {
+            glTranslatef(movestate->en_passant[1], 0.0,
+                         movestate->en_passant[0]);
+        } else {
+            glTranslatef(movestate->to[1], 0.0, movestate->to[0]);
+        }
 
-/** draw board */
-static void drawBoard(ModeInfo *mi, Chesscreen *cs) 
-{
-  int i, j;
-
-  glBegin(GL_QUADS);
-
-  for(i = 0; i < BOARDSIZE; ++i)
-    for(j = 0; j < BOARDSIZE; ++j) {
-      double ma1 = (i+j)%2 == 0 ? cs->mod*i : 0.0;
-      double mb1 = (i+j)%2 == 0 ? cs->mod*j : 0.0;
-      double ma2 = (i+j)%2 == 0 ? cs->mod*(i+1.0) : 0.01;
-      double mb2 = (i+j)%2 == 0 ? cs->mod*(j+1.0) : 0.01;
-
-      /*glColor3fv(colors[(i+j)%2]);*/
-      glColor4f(cs->colors[(i+j)%2][0], cs->colors[(i+j)%2][1],
-               cs->colors[(i+j)%2][2], 0.65);
-      
-      glNormal3f(0.0, 1.0, 0.0);
-/*       glTexCoord2f(mod*i, mod*(j+1.0)); */
-      glTexCoord2f(ma1, mb2);
-      glVertex3f(i, 0.0, j + 1.0);
-/*       glTexCoord2f(mod*(i+1.0), mod*(j+1.0)); */
-      glTexCoord2f(ma2, mb2);
-      glVertex3f(i + 1.0, 0.0, j + 1.0);
-      glTexCoord2f(ma2, mb1);
-/*       glTexCoord2f(mod*(i+1.0), mod*j); */
-      glVertex3f(i + 1.0, 0.0, j);
-      glTexCoord2f(ma1, mb1);
-/*       glTexCoord2f(mod*i, mod*j); */
-      glVertex3f(i, 0.0, j);
-
-      mi->polygon_count++;
+        if (movestate->tpiece % PIECES == KNIGHT)
+            glScalef(1.0 + cs->steps / num_steps_f, 1.0,
+                     1.0 + cs->steps / num_steps_f);
+        else
+            glScalef(1.0,
+                     1.0 - cs->steps / num_steps_f / 2 > 0.01
+                         ? 1.0 - cs->steps / num_steps_f
+                         : 0.01,
+                     1.0);
+
+        if (movestate->tpiece == KNIGHT)
+            glRotatef(180.0, 0.0, 1.0, 0.0);
+        else if ((movestate->tpiece % PIECES) == BISHOP)
+            glRotatef(90.0 * side, 0.0, 1.0, 0.0);
+        glCallList(movestate->tpiece % 7);
+        if (movestate->tpiece == KNIGHT)
+            glRotatef(180.0, 0.0, 1.0, 0.0);
+        else if ((movestate->tpiece % PIECES) == BISHOP)
+            glRotatef(-90.0 * side, 0.0, 1.0, 0.0);
+        mi->polygon_count += cs->poly_counts[movestate->tpiece % PIECES];
     }
-  glEnd();
-
-  {
-    GLfloat off = 0.01;
-    GLfloat w = BOARDSIZE;
-    GLfloat h = 0.1;
-
-    /* Give the board a slight lip. */
-    /* #### oops, normals are wrong here, but you can't tell */
-
-    glColor3f(0.3, 0.3, 0.3);
-    glBegin (GL_QUADS);
-    glVertex3f (0,  0, 0);
-    glVertex3f (0, -h, 0);
-    glVertex3f (0, -h, w);
-    glVertex3f (0,  0, w);
-
-    glVertex3f (0,  0, w);
-    glVertex3f (0, -h, w);
-    glVertex3f (w, -h, w);
-    glVertex3f (w,  0, w);
-
-    glVertex3f (w,  0, w);
-    glVertex3f (w, -h, w);
-    glVertex3f (w, -h, 0);
-    glVertex3f (w,  0, 0);
-
-    glVertex3f (w,  0, 0);
-    glVertex3f (w, -h, 0);
-    glVertex3f (0, -h, 0);
-    glVertex3f (0,  0, 0);
-
-    glVertex3f (0, -h, 0);
-    glVertex3f (w, -h, 0);
-    glVertex3f (w, -h, w);
-    glVertex3f (0, -h, w);
-    glEnd();
-    mi->polygon_count += 4;
-
-    /* Fill in the underside of the board with an invisible black box
-       to hide the reflections that are not on tiles.  Probably there's
-       a way to do this with stencils instead.
-     */
-    w -= off*2;
-    h = 5;
 
-    glPushMatrix();
-    glTranslatef (off, 0, off);
-    glDisable(GL_LIGHTING);
-    glColor3f(0,0,0);
-    glBegin (GL_QUADS);
-    glVertex3f (0,  0, 0);
-    glVertex3f (0, -h, 0);
-    glVertex3f (0, -h, w);
-    glVertex3f (0,  0, w);
-
-    glVertex3f (0,  0, w);
-    glVertex3f (0, -h, w);
-    glVertex3f (w, -h, w);
-    glVertex3f (w,  0, w);
-
-    glVertex3f (w,  0, w);
-    glVertex3f (w, -h, w);
-    glVertex3f (w, -h, 0);
-    glVertex3f (w,  0, 0);
-
-    glVertex3f (w,  0, 0);
-    glVertex3f (w, -h, 0);
-    glVertex3f (0, -h, 0);
-    glVertex3f (0,  0, 0);
-
-    glVertex3f (0, -h, 0);
-    glVertex3f (w, -h, 0);
-    glVertex3f (w, -h, w);
-    glVertex3f (0, -h, w);
-    glEnd();
-    mi->polygon_count += 4;
-    glPopMatrix();
     if (!cs->wire)
-      glEnable(GL_LIGHTING);
-  }
+        glDisable(GL_BLEND);
 }
 
-static void draw_pieces(ModeInfo *mi, Chesscreen *cs, int wire) 
-{
-  if (!cs->wire) {
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+/** draw board */
+static void drawBoard(ModeInfo *mi, Chesscreen *cs) {
+    int i, j;
 
-    glColor4f(0.5, 0.5, 0.5, 1.0);
-    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
-  }
+    glBegin(GL_QUADS);
+
+    for (i = 0; i < BOARDSIZE; ++i)
+        for (j = 0; j < BOARDSIZE; ++j) {
+            double ma1 = (i + j) % 2 == 0 ? cs->mod * i : 0.0;
+            double mb1 = (i + j) % 2 == 0 ? cs->mod * j : 0.0;
+            double ma2 = (i + j) % 2 == 0 ? cs->mod * (i + 1.0) : 0.01;
+            double mb2 = (i + j) % 2 == 0 ? cs->mod * (j + 1.0) : 0.01;
+
+            /*glColor3fv(colors[(i+j)%2]);*/
+            glColor4f(cs->colors[(i + j) % 2][0], cs->colors[(i + j) % 2][1],
+                      cs->colors[(i + j) % 2][2], 0.65);
+
+            glNormal3f(0.0, 1.0, 0.0);
+            /*       glTexCoord2f(mod*i, mod*(j+1.0)); */
+            glTexCoord2f(ma1, mb2);
+            glVertex3f(i, 0.0, j + 1.0);
+            /*       glTexCoord2f(mod*(i+1.0), mod*(j+1.0)); */
+            glTexCoord2f(ma2, mb2);
+            glVertex3f(i + 1.0, 0.0, j + 1.0);
+            glTexCoord2f(ma2, mb1);
+            /*       glTexCoord2f(mod*(i+1.0), mod*j); */
+            glVertex3f(i + 1.0, 0.0, j);
+            glTexCoord2f(ma1, mb1);
+            /*       glTexCoord2f(mod*i, mod*j); */
+            glVertex3f(i, 0.0, j);
+
+            mi->polygon_count++;
+        }
+    glEnd();
 
-  drawPieces(mi, cs);
-  if(cs->moving) drawMovingPiece(mi, cs, 0);
-  if(cs->take) drawTakePiece(mi, cs, 0);
-  glDisable(GL_TEXTURE_2D);
+    {
+        GLfloat off = 0.01;
+        GLfloat w = BOARDSIZE;
+        GLfloat h = 0.1;
+
+        /* Give the board a slight lip. */
+        /* #### oops, normals are wrong here, but you can't tell */
+
+        glColor3f(0.3, 0.3, 0.3);
+        glBegin(GL_QUADS);
+        glVertex3f(0, 0, 0);
+        glVertex3f(0, -h, 0);
+        glVertex3f(0, -h, w);
+        glVertex3f(0, 0, w);
+
+        glVertex3f(0, 0, w);
+        glVertex3f(0, -h, w);
+        glVertex3f(w, -h, w);
+        glVertex3f(w, 0, w);
+
+        glVertex3f(w, 0, w);
+        glVertex3f(w, -h, w);
+        glVertex3f(w, -h, 0);
+        glVertex3f(w, 0, 0);
+
+        glVertex3f(w, 0, 0);
+        glVertex3f(w, -h, 0);
+        glVertex3f(0, -h, 0);
+        glVertex3f(0, 0, 0);
+
+        glVertex3f(0, -h, 0);
+        glVertex3f(w, -h, 0);
+        glVertex3f(w, -h, w);
+        glVertex3f(0, -h, w);
+        glEnd();
+        mi->polygon_count += 4;
+
+        /* Fill in the underside of the board with an invisible black box
+           to hide the reflections that are not on tiles.  Probably there's
+           a way to do this with stencils instead.
+         */
+        w -= off * 2;
+        h = 5;
+
+        glPushMatrix();
+        glTranslatef(off, 0, off);
+        glDisable(GL_LIGHTING);
+        glColor3f(0, 0, 0);
+        glBegin(GL_QUADS);
+        glVertex3f(0, 0, 0);
+        glVertex3f(0, -h, 0);
+        glVertex3f(0, -h, w);
+        glVertex3f(0, 0, w);
+
+        glVertex3f(0, 0, w);
+        glVertex3f(0, -h, w);
+        glVertex3f(w, -h, w);
+        glVertex3f(w, 0, w);
+
+        glVertex3f(w, 0, w);
+        glVertex3f(w, -h, w);
+        glVertex3f(w, -h, 0);
+        glVertex3f(w, 0, 0);
+
+        glVertex3f(w, 0, 0);
+        glVertex3f(w, -h, 0);
+        glVertex3f(0, -h, 0);
+        glVertex3f(0, 0, 0);
+
+        glVertex3f(0, -h, 0);
+        glVertex3f(w, -h, 0);
+        glVertex3f(w, -h, w);
+        glVertex3f(0, -h, w);
+        glEnd();
+        mi->polygon_count += 4;
+        glPopMatrix();
+        if (!cs->wire)
+            glEnable(GL_LIGHTING);
+    }
 }
 
-static void draw_shadow_pieces(ModeInfo *mi, Chesscreen *cs, int wire) 
-{
-  if (!cs->wire) {
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-  }
-
-  /* use the stencil */
-  glDisable(GL_LIGHTING);
-  glDisable(GL_COLOR_MATERIAL);
-  glDisable(GL_DEPTH_TEST);
-  glDisable(GL_TEXTURE_2D);
-  glDisable(GL_BLEND);
+static void draw_pieces(ModeInfo *mi, Chesscreen *cs, int wire) {
+    if (!cs->wire) {
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
+        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
-  glClear(GL_STENCIL_BUFFER_BIT);
-  glColorMask(0,0,0,0);
-  glEnable(GL_STENCIL_TEST);
+        glColor4f(0.5, 0.5, 0.5, 1.0);
+        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
+    }
 
-  glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFFL);
-  glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
-  
+    drawPieces(mi, cs);
+    if (are_moves_active(cs))
+        drawMovingPiece(mi, cs, 0);
+    if (is_a_piece_taken(cs))
+        drawTakePiece(mi, cs, 0);
+    glDisable(GL_TEXTURE_2D);
+}
 
-  glPushMatrix();
-  glTranslatef(0.0, 0.001, 0.0);
+static void draw_shadow_pieces(ModeInfo *mi, Chesscreen *cs, int wire) {
+    if (!cs->wire) {
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
+        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    }
 
-  /* draw the pieces */
-  drawPiecesShadow(mi, cs);
-  if(cs->moving) drawMovingPiece(mi, cs, shadows);
-  if(cs->take) drawTakePiece(mi, cs, shadows);
+    /* use the stencil */
+    glDisable(GL_LIGHTING);
+    glDisable(GL_COLOR_MATERIAL);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
 
-  glPopMatrix();
+    glClear(GL_STENCIL_BUFFER_BIT);
+    glColorMask(0, 0, 0, 0);
+    glEnable(GL_STENCIL_TEST);
 
+    glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFFL);
+    glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
 
-  /* turn on drawing into colour buffer */
-  glColorMask(1,1,1,1);
+    glPushMatrix();
+    glTranslatef(0.0, 0.001, 0.0);
 
-  /* programming with effect */
-  glDisable(GL_LIGHTING);
-  glDisable(GL_COLOR_MATERIAL);
-  glDisable(GL_TEXTURE_2D);
+    /* draw the pieces */
+    drawPiecesShadow(mi, cs);
+    if (are_moves_active(cs))
+        drawMovingPiece(mi, cs, shadows);
+    if (is_a_piece_taken(cs))
+        drawTakePiece(mi, cs, shadows);
 
-  /* now draw the union of the shadows */
+    glPopMatrix();
 
-  /* 
-     <todo>
-     want to keep alpha values (alpha is involved in transition
-     effects of the active pieces).
-     </todo>
-  */
-  glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFFL);
-  glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+    /* turn on drawing into colour buffer */
+    glColorMask(1, 1, 1, 1);
 
-  glEnable(GL_BLEND);
+    /* programming with effect */
+    glDisable(GL_LIGHTING);
+    glDisable(GL_COLOR_MATERIAL);
+    glDisable(GL_TEXTURE_2D);
 
-  glColor4fv(MaterialShadow);
+    /* now draw the union of the shadows */
 
-  /* draw the board generously to fill the shadows */
-  glBegin(GL_QUADS);
+    /*
+       <todo>
+       want to keep alpha values (alpha is involved in transition
+       effects of the active pieces).
+       </todo>
+    */
+    glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFFL);
+    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
 
-  glVertex3f(-1.0, 0.0, -1.0);
-  glVertex3f(-1.0, 0.0, BOARDSIZE + 1.0);
-  glVertex3f(1.0 + BOARDSIZE, 0.0, BOARDSIZE + 1.0);
-  glVertex3f(1.0 + BOARDSIZE, 0.0, -1.0);
+    glEnable(GL_BLEND);
 
-  glEnd();
+    glColor4fv(MaterialShadow);
 
-  glDisable(GL_STENCIL_TEST);
+    /* draw the board generously to fill the shadows */
+    glBegin(GL_QUADS);
 
-  /* "pop" attributes */
-  glEnable(GL_TEXTURE_2D);
-  glEnable(GL_COLOR_MATERIAL);
-  glEnable(GL_LIGHTING);
-  glEnable(GL_CULL_FACE);
+    glVertex3f(-1.0, 0.0, -1.0);
+    glVertex3f(-1.0, 0.0, BOARDSIZE + 1.0);
+    glVertex3f(1.0 + BOARDSIZE, 0.0, BOARDSIZE + 1.0);
+    glVertex3f(1.0 + BOARDSIZE, 0.0, -1.0);
 
+    glEnd();
 
+    glDisable(GL_STENCIL_TEST);
 
+    /* "pop" attributes */
+    glEnable(GL_TEXTURE_2D);
+    glEnable(GL_COLOR_MATERIAL);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_CULL_FACE);
 }
 
-enum {X, Y, Z, W};
-enum {A, B, C, D};
+enum { X, Y, Z, W };
+enum { A, B, C, D };
 
 /* create a matrix that will project the desired shadow */
-static void shadowmatrix(GLfloat shadowMat[4][4],
-                 GLfloat groundplane[4],
-                 GLfloat lightpos[4]) 
-{
-  GLfloat dot;
-
-  /* find dot product between light position vector and ground plane normal */
-  dot = groundplane[X] * lightpos[X] +
-        groundplane[Y] * lightpos[Y] +
-        groundplane[Z] * lightpos[Z] +
-        groundplane[W] * lightpos[W];
-
-  shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
-  shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
-  shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
-  shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
-
-  shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
-  shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
-  shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
-  shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
-
-  shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
-  shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
-  shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
-  shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
-
-  shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
-  shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
-  shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
-  shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
+static void shadowmatrix(GLfloat shadowMat[4][4], GLfloat groundplane[4],
+                         GLfloat lightpos[4]) {
+    GLfloat dot;
+
+    /* find dot product between light position vector and ground plane normal */
+    dot = groundplane[X] * lightpos[X] + groundplane[Y] * lightpos[Y] +
+          groundplane[Z] * lightpos[Z] + groundplane[W] * lightpos[W];
+
+    shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
+    shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
+    shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
+    shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
+
+    shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
+    shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
+    shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
+    shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
+
+    shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
+    shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
+    shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
+    shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
+
+    shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
+    shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
+    shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
+    shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
 }
 
 /** reflectionboard */
-static void draw_reflections(ModeInfo *mi, Chesscreen *cs) 
-{
-  int i, j;
-
-  glEnable(GL_STENCIL_TEST);
-  glStencilFunc(GL_ALWAYS, 1, 1);
-  glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-  glColorMask(0,0,0,0);
-  glDisable(GL_CULL_FACE);
-
-  glDisable(GL_DEPTH_TEST);
-  glBegin(GL_QUADS);
-
-  /* only draw white squares */
-  for(i = 0; i < BOARDSIZE; ++i) {
-    for(j = (BOARDSIZE+i) % 2; j < BOARDSIZE; j += 2) {
-      glVertex3f(i, 0.0, j + 1.0);
-      glVertex3f(i + 1.0, 0.0, j + 1.0);
-      glVertex3f(i + 1.0, 0.0, j);
-      glVertex3f(i, 0.0, j);
-      mi->polygon_count++;
-    }
-  }
-  glEnd();
-  glEnable(GL_DEPTH_TEST);
-
-  glColorMask(1, 1, 1, 1);
-  glStencilFunc(GL_EQUAL, 1, 1);
-  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-  
-  glPushMatrix(); 
-  glScalef(1.0, -1.0, 1.0);
-  glTranslatef(0.5, 0.0, 0.5);
-
-  glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
-  draw_pieces(mi, cs, cs->wire);
-  glPopMatrix();
-  
-  glDisable(GL_STENCIL_TEST);
-  glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
-
-  glEnable(GL_CULL_FACE);
-  glCullFace(GL_BACK);
-  glColorMask(1,1,1,1);
-}
-
-/** draws the scene */
-static void display(ModeInfo *mi, Chesscreen *cs) 
-{
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
-  mi->polygon_count = 0;
-
-  glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity();
-  glRotatef(current_device_rotation(), 0, 0, 1);
-
-  /** setup perspectiv */
-  glTranslatef(0.0, 0.0, -1.5*BOARDSIZE);
-  glRotatef(30.0, 1.0, 0.0, 0.0);
-  gltrackball_rotate (cs->trackball);
+static void draw_reflections(ModeInfo *mi, Chesscreen *cs) {
+    int i, j;
 
-  if (rotate)
-    glRotatef(cs->theta*100, 0.0, 1.0, 0.0);
-  glTranslatef(-0.5*BOARDSIZE, 0.0, -0.5*BOARDSIZE);
+    glEnable(GL_STENCIL_TEST);
+    glStencilFunc(GL_ALWAYS, 1, 1);
+    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+    glColorMask(0, 0, 0, 0);
+    glDisable(GL_CULL_FACE);
+
+    glDisable(GL_DEPTH_TEST);
+    glBegin(GL_QUADS);
+
+    /* only draw white squares */
+    for (i = 0; i < BOARDSIZE; ++i) {
+        for (j = (BOARDSIZE + i) % 2; j < BOARDSIZE; j += 2) {
+            glVertex3f(i, 0.0, j + 1.0);
+            glVertex3f(i + 1.0, 0.0, j + 1.0);
+            glVertex3f(i + 1.0, 0.0, j);
+            glVertex3f(i, 0.0, j);
+            mi->polygon_count++;
+        }
+    }
+    glEnd();
+    glEnable(GL_DEPTH_TEST);
 
-/*   cs->position[0] = 4.0 + 1.0*-sin(cs->theta*100*M_PI/180.0); */
-/*   cs->position[2] = 4.0 + 1.0* cos(cs->theta*100*M_PI/180.0); */
-/*   cs->position[1] = 5.0; */
+    glColorMask(1, 1, 1, 1);
+    glStencilFunc(GL_EQUAL, 1, 1);
+    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 
-  /* this is the lone light that the shadow matrix is generated from */
-  cs->position[0] = 1.0;
-  cs->position[2] = 1.0;
-  cs->position[1] = 16.0;
+    glPushMatrix();
+    glScalef(1.0, -1.0, 1.0);
+    glTranslatef(0.5, 0.0, 0.5);
 
-  cs->position2[0] = 4.0 + 8.0*-sin(cs->theta*100*M_PI/180.0);
-  cs->position2[2] = 4.0 + 8.0* cos(cs->theta*100*M_PI/180.0);
+    glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
+    draw_pieces(mi, cs, cs->wire);
+    glPopMatrix();
 
-  if (!cs->wire) {
-    glEnable(GL_LIGHTING);
+    glDisable(GL_STENCIL_TEST);
     glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
-    glLightfv(GL_LIGHT1, GL_POSITION, cs->position2);
-    glEnable(GL_LIGHT0);
-  }
 
-  /** draw board, pieces */
-  if(!cs->wire) {
-    glEnable(GL_LIGHTING);
-    glEnable(GL_COLOR_MATERIAL);
+    glEnable(GL_CULL_FACE);
+    glCullFace(GL_BACK);
+    glColorMask(1, 1, 1, 1);
+}
 
-    if(reflections && !cs->wire) {
-      draw_reflections(mi, cs);
-      glEnable(GL_BLEND);
-    }
+/** draws the scene */
+static void display(ModeInfo *mi, Chesscreen *cs) {
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, cs->boardtexture);
-    drawBoard(mi, cs);
-    glDisable(GL_TEXTURE_2D);
+    mi->polygon_count = 0;
 
-    if(shadows) {
-      /* render shadows */
-      GLfloat m[4][4];
-      shadowmatrix(m, cs->ground, cs->position);
-
-      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
-      glEnable(GL_BLEND);
-      glDisable(GL_LIGHTING);
-      glDisable(GL_DEPTH_TEST);
-      
-      /* display ant shadow */
-      glPushMatrix();
-      glTranslatef(0.0, 0.001, 0.0);
-      glMultMatrixf(m[0]);
-      glTranslatef(0.5, 0.01, 0.5);
-      draw_shadow_pieces(mi, cs, cs->wire);
-      glPopMatrix();      
-
-      glEnable(GL_LIGHTING);
-      glDisable(GL_BLEND);
-      glEnable(GL_DEPTH_TEST);
-    }
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glRotatef(current_device_rotation(), 0, 0, 1);
 
-    if(reflections)
-      glDisable(GL_BLEND);
-  }
-  else
-    drawBoard(mi, cs);
-  glTranslatef(0.5, 0.0, 0.5);
-  draw_pieces(mi, cs, cs->wire);
+    /** setup perspectiv */
+    glTranslatef(0.0, 0.0, -1.5 * BOARDSIZE);
+    glRotatef(30.0, 1.0, 0.0, 0.0);
+    gltrackball_rotate(cs->trackball);
 
-  if(!cs->wire) {
-    glDisable(GL_COLOR_MATERIAL);
-    glDisable(GL_LIGHTING);
-  }
+    if (rotate)
+        glRotatef(cs->theta * 100, 0.0, 1.0, 0.0);
+    glTranslatef(-0.5 * BOARDSIZE, 0.0, -0.5 * BOARDSIZE);
 
-  if (!cs->button_down_p)
-    cs->theta += .002;
-}
+    /*   cs->position[0] = 4.0 + 1.0*-sin(cs->theta*100*M_PI/180.0); */
+    /*   cs->position[2] = 4.0 + 1.0* cos(cs->theta*100*M_PI/180.0); */
+    /*   cs->position[1] = 5.0; */
 
-/** reshape handler */
-ENTRYPOINT void reshape_chess(ModeInfo *mi, int width, int height) 
-{
-  GLfloat h = (GLfloat) height / (GLfloat) width;
-  int y = 0;
+    /* this is the lone light that the shadow matrix is generated from */
+    cs->position[0] = 1.0;
+    cs->position[2] = 1.0;
+    cs->position[1] = 16.0;
 
-  if (width > height * 5) {   /* tiny window: show middle */
-    height = width * 9/16;
-    y = -height/2;
-    h = height / (GLfloat) width;
-  }
+    cs->position2[0] = 4.0 + 8.0 * -sin(cs->theta * 100 * M_PI / 180.0);
+    cs->position2[2] = 4.0 + 8.0 * cos(cs->theta * 100 * M_PI / 180.0);
 
-  glViewport(0,y, width, height);
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-  gluPerspective(45, 1/h, 2.0, 30.0);
-  glMatrixMode(GL_MODELVIEW);
-}
+    if (!cs->wire) {
+        glEnable(GL_LIGHTING);
+        glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
+        glLightfv(GL_LIGHT1, GL_POSITION, cs->position2);
+        glEnable(GL_LIGHT0);
+    }
 
-/** initialization handler */
-ENTRYPOINT void init_chess(ModeInfo *mi) 
-{
-  Chesscreen *cs;
-  int screen = MI_SCREEN(mi);
+    /** draw board, pieces */
+    if (!cs->wire) {
+        glEnable(GL_LIGHTING);
+        glEnable(GL_COLOR_MATERIAL);
 
-  MI_INIT(mi, qs);
-  
-  cs = &qs[screen];
-  cs->window = MI_WINDOW(mi);
-  cs->wire = MI_IS_WIREFRAME(mi);
-  cs->trackball = gltrackball_init (False);
-  
-  cs->oldwhite = -1;
+        if (reflections && !cs->wire) {
+            draw_reflections(mi, cs);
+            glEnable(GL_BLEND);
+        }
 
-  cs->colors[0][0] = 1.0;
-  cs->colors[0][1] = 0.5;
-  cs->colors[0][2] = 0.0;
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, cs->boardtexture);
+        drawBoard(mi, cs);
+        glDisable(GL_TEXTURE_2D);
+
+        if (shadows) {
+            /* render shadows */
+            GLfloat m[4][4];
+            shadowmatrix(m, cs->ground, cs->position);
+
+            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
+            glEnable(GL_BLEND);
+            glDisable(GL_LIGHTING);
+            glDisable(GL_DEPTH_TEST);
+
+            /* display shadow */
+            glPushMatrix();
+            glTranslatef(0.0, 0.001, 0.0);
+            glMultMatrixf(m[0]);
+            glTranslatef(0.5, 0.01, 0.5);
+            draw_shadow_pieces(mi, cs, cs->wire);
+            glPopMatrix();
+
+            glEnable(GL_LIGHTING);
+            glDisable(GL_BLEND);
+            glEnable(GL_DEPTH_TEST);
+        }
 
-  cs->colors[1][0] = 0.6;
-  cs->colors[1][1] = 0.6;
-  cs->colors[1][2] = 0.6;
+        if (reflections)
+            glDisable(GL_BLEND);
+    } else
+        drawBoard(mi, cs);
 
-  cs->done = 1;
-  cs->count = 99;
-  cs->mod = 1.4;
+    glTranslatef(0.5, 0.0, 0.5);
+    draw_pieces(mi, cs, cs->wire);
 
-/*   cs->position[0] = 0.0; */
-/*   cs->position[1] = 5.0; */
-/*   cs->position[2] = 5.0; */
-/*   cs->position[3] = 1.0; */
+    if (!cs->wire) {
+        glDisable(GL_COLOR_MATERIAL);
+        glDisable(GL_LIGHTING);
+    }
 
-  cs->position[0] = 0.0;
-  cs->position[1] = 24.0;
-  cs->position[2] = 2.0;
-  cs->position[3] = 1.0;
+    if (!cs->button_down_p)
+        cs->theta += .002;
+}
 
+static void load_fonts(ModeInfo *mi) {
+    Chesscreen *cs = &qs[MI_SCREEN(mi)];
+    cs->font1_data = load_texture_font(mi->dpy, "titleFont");
+    cs->font2_data = load_texture_font(mi->dpy, "titleFont2");
+    cs->font3_data = load_texture_font(mi->dpy, "titleFont3");
+}
 
-  cs->position2[0] = 5.0;
-  cs->position2[1] = 5.0;
-  cs->position2[2] = 5.0;
-  cs->position2[3] = 1.0;
+static void set_description(Chesscreen *cs) {
+    int move_index;
 
-  cs->ground[0] = 0.0;
-  cs->ground[1] = 1.0;
-  cs->ground[2] = 0.0;
-  cs->ground[3] = -0.00001;
+    if (!labels)
+        return;
 
-  cs->oldgame = -1;
+    for (int i = 0; i < DESC_STR_LEN + SAN_STR_LEN + 1; i++)
+        cs->game_desc[i] = cs->game.desc[i];
+    for (move_index = 0; move_index <= DESC_STR_LEN; move_index++) {
+        if (cs->game_desc[move_index] == '\0')
+            break;
+    }
+    cs->game_desc[move_index++] = '\n';
+    cs->move_desc_index = move_index;
+}
 
+static void manage_labels(ModeInfo *mi) {
+    Chesscreen *cs = &qs[MI_SCREEN(mi)];
+
+    if ((cs->stage == DO_MOVE) || (cs->stage == FADE_IN) ||
+        (cs->stage == WAIT_FOR_NEXT_MOVE) ||
+        (cs->stage == WAIT_FOR_NEXT_GAME)) {
+        if (labels) {
+            int move_num = (cs->stage == DO_MOVE) ? cs->mc : cs->mc - 1;
+            texture_font_data *f;
+            int san_index;
+
+            if (cs->stage != FADE_IN) {
+                for (san_index = 0; san_index < SAN_STR_LEN; san_index++) {
+                    char c = cs->game.moves[move_num].san[san_index];
+                    cs->game_desc[cs->move_desc_index + san_index] = c;
+                    if (c == '\0')
+                        break;
+                }
+                cs->game_desc[cs->move_desc_index + san_index] = '\0';
+            }
+            if (MI_WIDTH(mi) >= 500 && MI_HEIGHT(mi) >= 375)
+                f = cs->font1_data;
+            else if (MI_WIDTH(mi) >= 350 && MI_HEIGHT(mi) >= 260)
+                f = cs->font2_data;
+            else
+                f = cs->font3_data;
+            glColor3f(0.8, 0.8, 0);
+            print_texture_label(mi->dpy, f, mi->xgwa.width, mi->xgwa.height, 1,
+                                cs->game_desc);
+        }
+    }
+}
 
-  if((cs->glx_context = init_GL(mi)))
-    reshape_chess(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
-  else
-    MI_CLEARWINDOW(mi);
+/** reshape handler */
+ENTRYPOINT void reshape_chess(ModeInfo *mi, int width, int height) {
+    GLfloat h = (GLfloat)height / (GLfloat)width;
+    int y = 0;
+
+    if (width > height * 5) { /* tiny window: show middle */
+        height = width * 9 / 16;
+        y = -height / 2;
+        h = height / (GLfloat)width;
+    }
 
-  if (!cs->wire) {
-    glDepthFunc(GL_LEQUAL);
-    glClearStencil(0);
-    glEnable(GL_CULL_FACE);
-    glCullFace(GL_BACK);
+    glViewport(0, y, width, height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45, 1 / h, 2.0, 30.0);
+    glMatrixMode(GL_MODELVIEW);
+}
 
-    make_piece_texture(cs);
-    make_board_texture(cs);
-  }
-  chessmodels_gen_lists( classic, cs->poly_counts);
+/** initialization handler */
+ENTRYPOINT void init_chess(ModeInfo *mi) {
+    Chesscreen *cs;
+
+    MI_INIT(mi, qs);
+    cs = &qs[MI_SCREEN(mi)];
+
+    cs->window = MI_WINDOW(mi);
+    cs->wire = MI_IS_WIREFRAME(mi);
+    cs->trackball = gltrackball_init(False);
+
+    cs->oldwhite = -1;
+
+    cs->colors[0][0] = 1.0;
+    cs->colors[0][1] = 0.5;
+    cs->colors[0][2] = 0.0;
+
+    cs->colors[1][0] = 0.3;
+    cs->colors[1][1] = 0.3;
+    cs->colors[1][2] = 0.3;
+
+    cs->stage = CHOSE_GAME;
+    cs->ticks = 0;
+    cs->mod = 1.4;
+    cs->abort = 0;
+    init_moves(cs);
+
+    /*   cs->position[0] = 0.0; */
+    /*   cs->position[1] = 5.0; */
+    /*   cs->position[2] = 5.0; */
+    /*   cs->position[3] = 1.0; */
+
+    cs->position[0] = 0.0;
+    cs->position[1] = 24.0;
+    cs->position[2] = 2.0;
+    cs->position[3] = 1.0;
+
+    cs->position2[0] = 5.0;
+    cs->position2[1] = 5.0;
+    cs->position2[2] = 5.0;
+    cs->position2[3] = 1.0;
+
+    cs->ground[0] = 0.0;
+    cs->ground[1] = 1.0;
+    cs->ground[2] = 0.0;
+    cs->ground[3] = -0.00001;
+
+    cs->cur_game_idx = -1;
+
+    if ((cs->glx_context = init_GL(mi)))
+        reshape_chess(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+    else
+        MI_CLEARWINDOW(mi);
+
+    if (!cs->wire) {
+        glDepthFunc(GL_LEQUAL);
+        glClearStencil(0);
+        glEnable(GL_CULL_FACE);
+        glCullFace(GL_BACK);
+
+        make_piece_texture(cs);
+        make_board_texture(cs);
+    }
+    chessmodels_gen_lists(classic, cs->poly_counts);
 
-# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
+#ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
     cs->wire = 0;
-# endif
+#endif
 
-  if(!cs->wire) {
-    setup_lights(cs);
-    glColorMaterial(GL_FRONT, GL_DIFFUSE);
-    glShadeModel(smooth ? GL_SMOOTH : GL_FLAT);
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    glEnable(GL_DEPTH_TEST);
-  }
-  else
-    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    if (!cs->wire) {
+        setup_lights(cs);
+        glColorMaterial(GL_FRONT, GL_DIFFUSE);
+        glShadeModel(smooth ? GL_SMOOTH : GL_FLAT);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        glEnable(GL_DEPTH_TEST);
+    } else
+        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+    load_fonts(mi);
 }
 
 /** does dirty work drawing scene, moving pieces */
-ENTRYPOINT void draw_chess(ModeInfo *mi) 
-{
-  Chesscreen *cs = &qs[MI_SCREEN(mi)];
-  Window w = MI_WINDOW(mi);
-  Display *disp = MI_DISPLAY(mi);
-
-  if(!cs->glx_context)
-    return;
-
-  glXMakeCurrent(disp, w, *cs->glx_context);
-
-  /** code for moving a piece */
-  if(cs->moving && ++cs->steps == 100) {
-    cs->moving = cs->count = cs->steps = cs->take = 0;
-    cs->game.board[cs->game.moves[cs->mc][2]][cs->game.moves[cs->mc][3]] = cs->mpiece;
-    ++cs->mc;
-    
-    if(cs->mc == cs->game.movecount) {
-      cs->done = 1;
-      cs->mc = 0;
-    }
-  }
-
-  if(++cs->count == 100) {
-    if(!cs->done) {
-      cs->mpiece = cs->game.board[cs->game.moves[cs->mc][0]][cs->game.moves[cs->mc][1]];
-      cs->game.board[cs->game.moves[cs->mc][0]][cs->game.moves[cs->mc][1]] = NONE;
-      
-      if((cs->tpiece = cs->game.board[cs->game.moves[cs->mc][2]][cs->game.moves[cs->mc][3]])) {
-       cs->game.board[cs->game.moves[cs->mc][2]][cs->game.moves[cs->mc][3]] = NONE;
-       cs->take = 1;
-      }
-      
-      cs->from[0] = cs->game.moves[cs->mc][0];
-      cs->from[1] = cs->game.moves[cs->mc][1];
-      cs->to[0] = cs->game.moves[cs->mc][2];
-      cs->to[1] = cs->game.moves[cs->mc][3];
-      
-      cs->dz = (cs->to[0] - cs->from[0]) / 100;
-      cs->dx = (cs->to[1] - cs->from[1]) / 100;
-      cs->steps = 0;
-      cs->moving = 1;
-    }
-    else if(cs->done == 1) {
-      int newgame = cs->oldgame;
-      while(newgame == cs->oldgame)
-       newgame = random()%GAMES;
-
-      /* mod the mod */
-      cs->mod = 0.6 + (random()%20)/10.0;
-
-      /* same old game */
-      cs->oldgame = newgame;
-      cs->game = games[cs->oldgame];
-      build_colors(cs);
-      cs->done = 2;
-      cs->count = 0;
-    }
-    else {
-      cs->done = 0;
-      cs->count = 0;
+ENTRYPOINT void draw_chess(ModeInfo *mi) {
+    Chesscreen *cs = &qs[MI_SCREEN(mi)];
+    Chessmovestate *movestate;
+    Window w = MI_WINDOW(mi);
+    Display *disp = MI_DISPLAY(mi);
+    int new_game_idx;
+
+    if (!cs->glx_context)
+        return;
+
+    glXMakeCurrent(disp, w, *cs->glx_context);
+
+    switch (cs->stage) {
+    case CHOSE_GAME:
+        new_game_idx = cs->cur_game_idx;
+        while (new_game_idx == cs->cur_game_idx)
+            new_game_idx = random() % GAMES_NUMBER;
+
+        /* mod the mod */
+        cs->mod = 0.6 + (random() % 20) / 10.0;
+
+        cs->cur_game_idx = new_game_idx;
+        cs->game = games[cs->cur_game_idx];
+
+        cs->stage = FADE_IN;
+        cs->ticks = 1;
+        cs->mc = 0;
+        build_colors(cs);
+        apply_fen(cs);
+        set_description(cs);
+        init_moves(cs);
+        glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,
+                 (double)FADE_FACTOR * TICKS_BET_MOVES);
+        glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION,
+                 (double)FADE_FACTOR * TICKS_BET_MOVES);
+        if (cs->abort)
+            cs->abort = 0;
+        break;
+    case FADE_IN:
+        glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,
+                 (double)FADE_FACTOR * TICKS_BET_MOVES / cs->ticks);
+        glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION,
+                 (double)FADE_FACTOR * TICKS_BET_MOVES / cs->ticks);
+        if (cs->abort) {
+            cs->abort = 0;
+            cs->stage = FADE_OUT;
+        } else if (cs->ticks++ == FADE_FACTOR * TICKS_BET_MOVES) {
+            cs->stage = WAIT_FOR_NEXT_MOVE;
+        }
+        break;
+    case FADE_OUT:
+        glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,
+                 (double)FADE_FACTOR * TICKS_BET_MOVES / cs->ticks);
+        glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION,
+                 (double)FADE_FACTOR * TICKS_BET_MOVES / cs->ticks);
+        if (cs->ticks-- == 0) {
+            cs->stage = CHOSE_GAME;
+        }
+        if (cs->abort)
+            cs->abort = 0;
+        break;
+    case DO_MOVE:
+        if (cs->abort) {
+            cs->abort = 0;
+            cs->ticks = FADE_FACTOR * TICKS_BET_MOVES;
+            cs->stage = FADE_OUT;
+            break;
+        }
+        /* End of current move(s) */
+        if (are_moves_active(cs) && ++cs->steps == NUM_STEPS) {
+            for (int i = 0; i < CONCURRENT_MOVES;
+                 i++) { /* Update board with moved piece(s) */
+                movestate = &(cs->moves[i]);
+                if (movestate->active) {
+                    cs->board[movestate->to[0]][movestate->to[1]] =
+                        movestate->mpiece;
+                }
+            }
+            /* Reinit stuff for next move */
+            cs->ticks = cs->steps = 0;
+            init_moves(cs);
+            ++cs->mc;
+            if (cs->mc == cs->game.movecount) {
+                cs->ticks = 0;
+                cs->stage = WAIT_FOR_NEXT_GAME;
+                cs->mc = 0;
+            } else {
+                cs->stage = WAIT_FOR_NEXT_MOVE;
+            }
+        }
+        break;
+    case WAIT_FOR_NEXT_MOVE:
+        if (cs->abort) {
+            cs->abort = 0;
+            cs->ticks = FADE_FACTOR * TICKS_BET_MOVES;
+            cs->stage = FADE_OUT;
+            break;
+        }
+        if (cs->ticks++ >=
+            TICKS_BET_MOVES) { /* Wait before processing next move */
+            char *uci = cs->game.moves[cs->mc].uci;
+            setup_moves(cs, uci);
+            cs->steps = 0;
+            cs->ticks = 0;
+            cs->stage = DO_MOVE;
+        }
+        break;
+    case WAIT_FOR_NEXT_GAME: /* Wait before moving on */
+        if (cs->abort) {
+            cs->abort = 0;
+            cs->ticks = FADE_FACTOR * TICKS_BET_MOVES;
+            cs->stage = FADE_OUT;
+            break;
+        }
+        if (cs->ticks++ >= END_FACTOR * TICKS_BET_MOVES) {
+            cs->ticks = FADE_FACTOR * TICKS_BET_MOVES;
+            cs->stage = FADE_OUT;
+        }
+        break;
+    default:
+        break;
     }
-  }
-
-  /* set lighting */
-  if(cs->done) {
-    glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 
-            cs->done == 1 ? 1.0+0.1*cs->count : 100.0/cs->count);
-    glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 
-            cs->done == 1 ? 1.0+0.1*cs->count : 100.0/cs->count);
     glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.14);
     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.14);
-  }
-
-  display(mi, cs);
 
-  if(mi->fps_p) do_fps(mi);
-  glFinish(); 
-  glXSwapBuffers(disp, w);
+    display(mi, cs);
+    manage_labels(mi);
+    if (mi->fps_p)
+        do_fps(mi);
+    glFinish();
+    glXSwapBuffers(disp, w);
 }
 
-
-ENTRYPOINT void free_chess(ModeInfo *mi) 
-{
-  Chesscreen *cs = &qs[MI_SCREEN(mi)];
-  int i;
-  if (!cs->glx_context) return;
-  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *cs->glx_context);
-  gltrackball_free (cs->trackball);
-  if (cs->piecetexture) glDeleteTextures (1, &cs->piecetexture);
-  if (cs->boardtexture) glDeleteTextures (1, &cs->boardtexture);
-
-  /* this is horrible! List numbers are hardcoded! */
-  for (i = 1; i <= 20; i++)
-    if (glIsList(i)) glDeleteLists(i, 1);
+ENTRYPOINT void free_chess(ModeInfo *mi) {
+    Chesscreen *cs = &qs[MI_SCREEN(mi)];
+    int i;
+    if (!cs->glx_context)
+        return;
+    glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *cs->glx_context);
+    gltrackball_free(cs->trackball);
+    if (cs->piecetexture)
+        glDeleteTextures(1, &cs->piecetexture);
+    if (cs->boardtexture)
+        glDeleteTextures(1, &cs->boardtexture);
+    /* this is horrible! List numbers are hardcoded! */
+    for (i = 1; i <= 20; i++)
+        if (glIsList(i))
+            glDeleteLists(i, 1);
+    if (cs->font1_data)
+        free_texture_font(cs->font1_data);
+    if (cs->font2_data)
+        free_texture_font(cs->font2_data);
+    if (cs->font3_data)
+        free_texture_font(cs->font3_data);
 }
 
-XSCREENSAVER_MODULE_2 ("Endgame", endgame, chess)
+XSCREENSAVER_MODULE_2("Endgame", endgame, chess)
 
 #endif
index 4b20d460c2ac95128af59818e39cb5e2fab7c3c5..02a72dbe0a1e3421f6f4380c808df7f4d73666cc 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "5-May-2004"
 .SH NAME
-endgame \- endgame chess screensaver
+endgame \- re-play classic chess games
 .SH SYNOPSIS
 .B endgame
 [\-\-display \fIhost:display.screen\fP]
@@ -39,6 +39,9 @@ Reflect pieces in light board squares.
 .B \-\-classic
 Use the original low-polygon piece models.
 .TP 8
+.B \-\-labels
+Display information about the current game and move.
+.TP 8
 .B \-\-visual \fIvisual\fP\fP
 Specify which visual to use.  Legal values are the name of a visual class,
 or the id number (decimal or hex) of a specific visual.
@@ -59,8 +62,6 @@ stored in the RESOURCE_MANAGER property.
 .TP 8
 .B XSCREENSAVER_WINDOW
 The window ID to use with \fI\-\-root\fP.
-.SH BUGS
-It's not unknown for this and other OpenGL hacks to fail under hardware accelaration (UtahGLX) and take the X server with them.  Texture images must be 16x16 or 32x32 or 64x64 etc.
 .SH SEE ALSO
 .BR X (1),
 .BR xscreensaver (1)
index 1302cac493d20bbe9396e88223ff7107d5825b2f..b557908c460efa45351c0d42ad1d30266339bbdb 100644 (file)
@@ -1,4 +1,4 @@
-/* esper, Copyright © 2017-2021 Jamie Zawinski <jwz@jwz.org>
+/* esper, Copyright © 2017-2025 Jamie Zawinski <jwz@jwz.org>
  * Enhance 224 to 176. Pull out track right. Center in pull back.
  * Pull back. Wait a minute. Go right. Stop. Enhance 57 19. Track 45 left.
  * Gimme a hardcopy right there.
 
 #include "grab-ximage.h"
 #include "texfont.h"
+#include "doubletime.h"
 
 #ifdef HAVE_XSHM_EXTENSION
 # include "xshm.h"  /* to get <sys/shm.h> */
@@ -291,22 +292,6 @@ static argtype vars[] = {
 ENTRYPOINT ModeSpecOpt esper_opts = {countof(opts), opts, countof(vars), vars, NULL};
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
 static const char *
 state_name (anim_state s)
 {
index e90d8d25f6d0fba562cb6090cce6bc4964fa0fc1..77ce9adc68e45d084e3c2a7c7aed7494c758cab7 100644 (file)
@@ -1,4 +1,4 @@
-/* gibson, Copyright (c) 2020-2021 Jamie Zawinski <jwz@jwz.org>
+/* gibson, Copyright © 2020-2025 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
@@ -31,6 +31,7 @@
 #include "colors.h"
 #include "rotator.h"
 #include "texfont.h"
+#include "easing.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -408,25 +409,6 @@ cmp_towers (const void *aa, const void *bb)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 /* Draws the text quads on the face.
    First pass is for the small background text, second is for the big block.
  */
@@ -1253,7 +1235,8 @@ draw_gibson (ModeInfo *mi)
     {
       tower *t = &bp->towers[i];
       glPushMatrix();
-      glTranslatef (t->x, t->y-1, -grid_height * ease_ratio (1 - t->h));
+      glTranslatef (t->x, t->y-1,
+                    -grid_height * ease (EASE_IN_OUT_SINE, 1 - t->h));
 
       glCallList (bp->tower_dlist);
       mi->polygon_count += bp->tower_polys;
index b544283987b54824bdfcfd2d9374b58293c83a8b..415723ae33ea7f736e3c4a3376718192b3bb0e07 100644 (file)
@@ -15,6 +15,7 @@
 #include <assert.h>
 
 #include "rotator.h"
+#include "doubletime.h"
 
 #define DEF_LIGHT     "True"
 #define DEF_FOG       "False"
@@ -67,17 +68,6 @@ enum {
 
 typedef struct timeval glhtime;
 
-static double getTime(void)
-{
-       struct timeval t;
-#ifdef GETTIMEOFDAY_TWO_ARGS
-       gettimeofday(&t, NULL);
-#else                                                  /* !GETTIMEOFDAY_TWO_ARGS */
-       gettimeofday(&t);
-#endif                                                 /* !GETTIMEOFDAY_TWO_ARGS */
-       return t.tv_sec + t.tv_usec / 1000000.0;
-}
-
 typedef enum {
        START,
        MOVE_DISK,
@@ -614,7 +604,7 @@ static void enQTrail(glhcfg *glhanoi, GLfloat *posn)
 {      
        if (glhanoi->trailQSize && glhanoi->state != MONEY_SHOT)  {
                TrailPoint *tp = &(glhanoi->trailQ[glhanoi->trailQBack]);
-               double t = getTime();
+               double t = double_time();
                
                tp->position[0] = posn[0];
                tp->position[1] = posn[1] + glhanoi->diskHeight;
@@ -702,7 +692,7 @@ static void updateView(glhcfg *glhanoi)
 static void changeState(glhcfg *glhanoi, State state)
 {
        glhanoi->state = state;
-       glhanoi->startTime = getTime();
+       glhanoi->startTime = double_time();
 }
 
 static Bool finishedHanoi(glhcfg *glhanoi) {
@@ -714,7 +704,7 @@ static Bool finishedHanoi(glhcfg *glhanoi) {
 
 static void update_glhanoi(glhcfg *glhanoi)
 {
-       double t = getTime() - glhanoi->startTime;
+       double t = double_time() - glhanoi->startTime;
        int i;
        Bool done;
 
@@ -1824,7 +1814,7 @@ static int drawTrails1(glhcfg *glhanoi, double t, double thickness, double alpha
 
 static int drawTrails(glhcfg *glhanoi) {
        int lines = 0;
-       double t = getTime();
+       double t = double_time();
 
        glEnable (GL_BLEND);
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
index 24930c8f9c92081f4c59fb821a6b31b558c9af21..2ee1c6505621eefbb0920cc1c1f3e430ceb85b07 100644 (file)
@@ -1,4 +1,4 @@
-/* glslideshow, Copyright © 2003-2022 Jamie Zawinski <jwz@jwz.org>
+/* glslideshow, Copyright © 2003-2025 Jamie Zawinski <jwz@jwz.org>
  * Loads a sequence of images and smoothly pans around them; crossfades
  * when loading new images.
  *
@@ -6,6 +6,7 @@
  * Rewritten by jwz, 21-Jun-2003.
  * Rewritten by jwz again, 6-Feb-2005.
  * Modified by Richard Weeks <rtweeks21@gmail.com> Copyright (c) 2020
+ * Rewritten by jwz again, 27-Nov-2025.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
 #ifdef USE_GL
 
 
-# define DEF_FADE_DURATION  "2"
-# define DEF_PAN_DURATION   "6"
-# define DEF_IMAGE_DURATION "30"
-# define DEF_ZOOM           "75"
-# define DEF_FPS_CUTOFF     "5"
-# define DEF_TITLES         "False"
-# define DEF_LETTERBOX      "True"
-# define DEF_DEBUG          "False"
-# define DEF_VERBOSE        "False"
-# define DEF_MIPMAP         "True"
+# define DEF_TRANSITION_DURATION "3"
+# define DEF_FADE_DURATION       "2"
+# define DEF_PAN_DURATION        "6"
+# define DEF_IMAGE_DURATION      "30"
+# define DEF_ZOOM                "75"
+# define DEF_TITLES              "False"
+# define DEF_LETTERBOX           "True"
+# define DEF_DEBUG               "False"
+# define DEF_VERBOSE             "False"
+# define DEF_MIPMAP              "True"
 
 #include "grab-ximage.h"
 #include "texfont.h"
+#include "easing.h"
+#include "doubletime.h"
 
 # ifndef HAVE_JWXYZ
 #  include <X11/Intrinsic.h>     /* for XrmDatabase in -verbose mode */
@@ -84,6 +87,7 @@
 
 typedef struct {
   double x, y, w, h;
+  struct { double x, y, z; } r;
 } rect;
 
 typedef struct {
@@ -104,12 +108,23 @@ typedef struct {
 
 
 typedef enum { NEW, IN, FULL, OUT, DEAD } sprite_state;
+typedef enum { NONE, PANZOOM, FADE,
+               LEFT, RIGHT, TOP, BOTTOM,
+               ZOOM, FLIP, SPIN }
+  transition_mode;
+
+typedef enum { LOADING, FIRST_IN, IN_PANZOOM, MID_PANZOOM, RECENTER,
+               TRANSITION_OUT, TRANSITION_PANZOOM } anim_state;
 
 typedef struct {
   int id;                         /* unique number for debugging */
   image *img;                     /* which image this animation displays */
   GLfloat opacity;                /* how to render it */
   double start_time;              /* when this animation began */
+  double duration;                /* How long for all 3 sprite_states */
+  transition_mode transition;      /* how to render it */
+  easing_function easing;
+  GLfloat zoom;                           /* randomized version of --zoom arg */
   rect from, to, current;         /* the journey this image is taking */
   sprite_state state;             /* the state we're in right now */
   sprite_state prev_state;        /* the state we were in previously */
@@ -120,18 +135,20 @@ typedef struct {
 
 typedef struct {
   GLXContext *glx_context;
+
   int nimages;                 /* how many images are loaded or loading now */
   image *images[10];           /* pointers to the images */
 
   int nsprites;                        /* how many sprites are animating right now */
   sprite *sprites[10];         /* pointers to the live sprites */
 
+  anim_state state;
+
   double now;                  /* current time in seconds */
   double dawn_of_time;         /* when the program launched */
-  double image_load_time;      /* time when we last loaded a new image */
-  double prev_frame_time;      /* time when we last drew a frame */
+  double start_time;           /* when we began displaying this image */
+  double prev_frame_time;      /* when we last drew a frame */
 
-  Bool awaiting_first_image_p;  /* Early in startup: nothing to display yet */
   Bool redisplay_needed_p;     /* Sometimes we can get away with not
                                    re-painting.  Tick this if a redisplay
                                    is required. */
@@ -157,32 +174,33 @@ static slideshow_state *sss = NULL;
 
 /* Command-line arguments
  */
-static int fade_seconds;    /* Duration in seconds of fade transitions.
-                               If 0, jump-cut instead of fading. */
-static int pan_seconds;     /* Duration of each pan through an image. */
-static int image_seconds;   /* How many seconds until loading a new image. */
-static int zoom;            /* How far in to zoom when panning, in percent of
-                               image size: that is, 75 means "when zoomed all
-                               the way in, 75% of the image will be visible."
-                             */
-static int fps_cutoff;      /* If the frame-rate falls below this, turn off
-                               zooming.*/
-static Bool letterbox_p;    /* When a loaded image is not the same aspect
-                               ratio as the window, whether to display black
-                               bars.
-                             */
-static Bool mipmap_p;      /* Use mipmaps instead of single textures. */
-static Bool do_titles;     /* Display image titles. */
-static Bool verbose_p;     /* Print to stderr. */
-static Bool debug_p;       /* Show image extents with boxes. */
+static int transition_seconds; /* Duration in seconds of in/out transitions.
+                                  If 0, jump-cut instead of fading. */
+static int fade_seconds;       /* Duration in seconds of pan-zoom transitions.
+                                  If 0, jump-cut instead of fading. */
+static int pan_seconds;                /* Duration of each pan-zoom. */
+static int image_seconds;      /* How long until loading a new image. */
+static int zoom;               /* How far in to zoom, in percent of image
+                                  size: that is, 75 means "when zoomed all
+                                  the way in, 75% of the image will be
+                                  visible."
+                                 */
+static Bool letterbox_p;       /* When a loaded image is not the same aspect
+                                  ratio as the window, whether to display
+                                  black bars.
+                                */
+static Bool mipmap_p;          /* Use mipmaps instead of single textures. */
+static Bool do_titles;         /* Display image titles. */
+static Bool verbose_p;         /* Print to stderr. */
+static Bool debug_p;           /* Show image extents with boxes. */
 
 
 static XrmOptionDescRec opts[] = {
+  {"-transition",   ".transitionDuration", XrmoptionSepArg, 0 },
   {"-fade",         ".fadeDuration",  XrmoptionSepArg, 0      },
   {"-pan",          ".panDuration",   XrmoptionSepArg, 0      },
   {"-duration",     ".imageDuration", XrmoptionSepArg, 0      },
   {"-zoom",         ".zoom",          XrmoptionSepArg, 0      },
-  {"-cutoff",       ".FPScutoff",     XrmoptionSepArg, 0      },
   {"-titles",       ".titles",        XrmoptionNoArg, "True"  },
   {"-letterbox",    ".letterbox",     XrmoptionNoArg, "True"  },
   {"-no-letterbox", ".letterbox",     XrmoptionNoArg, "False" },
@@ -195,19 +213,21 @@ static XrmOptionDescRec opts[] = {
 };
 
 static argtype vars[] = {
+  { &transition_seconds, "transitionDuration", "TransitionDuration",
+                                              DEF_TRANSITION_DURATION,  t_Int},
   { &fade_seconds,  "fadeDuration", "FadeDuration", DEF_FADE_DURATION,  t_Int},
   { &pan_seconds,   "panDuration",  "PanDuration",  DEF_PAN_DURATION,   t_Int},
   { &image_seconds, "imageDuration","ImageDuration",DEF_IMAGE_DURATION, t_Int},
   { &zoom,          "zoom",         "Zoom",         DEF_ZOOM,           t_Int},
   { &mipmap_p,      "mipmap",       "Mipmap",       DEF_MIPMAP,        t_Bool},
   { &letterbox_p,   "letterbox",    "Letterbox",    DEF_LETTERBOX,     t_Bool},
-  { &fps_cutoff,    "FPScutoff",    "FPSCutoff",    DEF_FPS_CUTOFF,     t_Int},
   { &verbose_p,     "verbose",      "Verbose",      DEF_VERBOSE,       t_Bool},
   { &debug_p,       "debug",        "Debug",        DEF_DEBUG,         t_Bool},
   { &do_titles,     "titles",       "Titles",       DEF_TITLES,        t_Bool},
 };
 
-ENTRYPOINT ModeSpecOpt slideshow_opts = {countof(opts), opts, countof(vars), vars, NULL};
+ENTRYPOINT ModeSpecOpt slideshow_opts = {
+  countof(opts), opts, countof(vars), vars, NULL};
 
 
 static const char *
@@ -231,61 +251,12 @@ blurb (void)
 }
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void image_loaded_cb (const char *filename, XRectangle *geom,
                              int image_width, int image_height,
                              int texture_width, int texture_height,
                              void *closure);
 
 
-/* Allocate an image structure and start a file loading in the background.
- */
-static image *
-alloc_image (ModeInfo *mi)
-{
-  slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  int wire = MI_IS_WIREFRAME(mi);
-  image *img = (image *) calloc (1, sizeof (*img));
-
-  img->id = ++ss->image_id;
-  img->loaded_p = False;
-  img->used_p = False;
-  img->mi = mi;
-
-  glGenTextures (1, &img->texid);
-  if (img->texid <= 0) abort();
-
-  ss->image_load_time = ss->now;
-
-  if (wire)
-    image_loaded_cb (0, 0, 0, 0, 0, 0, img);
-  else
-    load_texture_async (mi->xgwa.screen, mi->window, *ss->glx_context,
-                        0, 0, mipmap_p, img->texid, image_loaded_cb, img);
-
-  ss->images[ss->nimages++] = img;
-  if (ss->nimages >= countof(ss->images)) abort();
-
-  return img;
-}
-
-
 /* Allocate an image structure and start asynchronous file loading in the
    background.
 
@@ -309,8 +280,6 @@ alloc_image_incremental (ModeInfo *mi)
   glGenTextures (1, &img->texid);
   if (img->texid <= 0) abort();
 
-  ss->image_load_time = ss->now;
-
   if (wire)
     image_loaded_cb (0, 0, 0, 0, 0, 0, img);
   else
@@ -325,6 +294,31 @@ alloc_image_incremental (ModeInfo *mi)
 }
 
 
+/* Step the incremental image loader.
+ */
+static void
+slideshow_idle (ModeInfo *mi)
+{
+  slideshow_state *ss = &sss[MI_SCREEN(mi)];
+  double allowed_time = ((double) mi->pause) / 2000000; /* 0.01 sec */
+  int i;
+
+  for (i = 0; i < ss->nimages; i++)
+    {
+      image *img = ss->images[i];
+      if (img->loader)
+        {
+          if (texture_loader_failed (img->loader))
+            abort();
+          step_texture_loader (img->loader, allowed_time,
+                               image_loaded_cb, img);
+          img->steps++;
+          break; /* only do the first one! */
+        }
+    }
+}
+
+
 /* Callback that tells us that the texture has been loaded.
  */
 static void
@@ -445,6 +439,13 @@ destroy_image (ModeInfo *mi, image *img)
     fprintf (stderr, "%s: unloaded img %2d: \"%s\"\n",
              blurb(), img->id, (img->title ? img->title : "(null)"));
 
+  if (img->loader)
+    {
+      texture_loader_t *loader = img->loader;
+      img->loader = 0;
+      free_texture_loader (loader);
+    }
+
   if (img->title) free (img->title);
   glDeleteTextures (1, &img->texid);
   free (img);
@@ -452,18 +453,14 @@ destroy_image (ModeInfo *mi, image *img)
 
 
 /* Return an image to use for a sprite.
-   If it's time for a new one, get a new one.
-   Otherwise, use an old one.
-   Might return 0 if the machine is really slow.
+   Might return 0 if a new image is unavailable because
+   the machine is being really slow.
  */
 static image *
-get_image (ModeInfo *mi)
+get_image (ModeInfo *mi, Bool want_new_p)
 {
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  image *img = 0;
-  double now = ss->now;
-  Bool want_new_p = (ss->change_now_p ||
-                     ss->image_load_time + image_seconds <= now);
+  image *ret = 0;
   image *new_img = 0;
   image *old_img = 0;
   image *loading_img = 0;
@@ -481,121 +478,25 @@ get_image (ModeInfo *mi)
         old_img = img2;
     }
 
-  if (want_new_p && new_img)
-    img = new_img, new_img = 0, ss->change_now_p = False;
-  else if (old_img)
-    img = old_img, old_img = 0;
-  else if (new_img)
-    img = new_img, new_img = 0, ss->change_now_p = False;
+  /* If a new image was requested but unavailable, return NULL. */
+  ret = want_new_p ? new_img : old_img;
 
-  /* Make sure that there is always one unused image in the pipe.
-   */
+  /* Make sure that there is always one unused image in the pipe. */
   if (!new_img && !loading_img)
     alloc_image_incremental (mi);
 
-  return img;
-}
-
-
-/* Pick random starting and ending positions for the given sprite.
- */
-static void
-randomize_sprite (ModeInfo *mi, sprite *sp)
-{
-  int vp_w = MI_WIDTH(mi);
-  int vp_h = MI_HEIGHT(mi);
-  int img_w = sp->img->geom.width;
-  int img_h = sp->img->geom.height;
-  int min_w, max_w;
-  double ratio = (double) img_h / img_w;
-
-  if (letterbox_p)
-    {
-      min_w = img_w;
-    }
-  else
-    {
-      if (img_w < vp_w)
-        min_w = vp_w;
-      else
-        min_w = img_w * (float) vp_h / img_h;
-    }
-
-  max_w = min_w * 100 / zoom;
-
-  sp->from.w = min_w + frand ((max_w - min_w) * 0.4);
-  sp->to.w   = max_w - frand ((max_w - min_w) * 0.4);
-  sp->from.h = sp->from.w * ratio;
-  sp->to.h   = sp->to.w   * ratio;
-
-  if (zoom == 100)     /* only one box, and it is centered */
-    {
-      sp->from.x = (sp->from.w > vp_w
-                    ? -(sp->from.w - vp_w) / 2
-                    :  (vp_w - sp->from.w) / 2);
-      sp->from.y = (sp->from.h > vp_h
-                    ? -(sp->from.h - vp_h) / 2
-                    :  (vp_h - sp->from.h) / 2);
-      sp->to = sp->from;
-    }
-  else                 /* position both boxes randomly */
-    {
-      sp->from.x = (sp->from.w > vp_w
-                    ? -frand (sp->from.w - vp_w)
-                    :  frand (vp_w - sp->from.w));
-      sp->from.y = (sp->from.h > vp_h
-                    ? -frand (sp->from.h - vp_h)
-                    :  frand (vp_h - sp->from.h));
-      sp->to.x   = (sp->to.w > vp_w
-                    ? -frand (sp->to.w - vp_w)
-                    :  frand (vp_w - sp->to.w));
-      sp->to.y   = (sp->to.h > vp_h
-                    ? -frand (sp->to.h - vp_h)
-                    :  frand (vp_h - sp->to.h));
-    }
-
-  if (random() & 1)
-    {
-      rect swap = sp->to;
-      sp->to = sp->from;
-      sp->from = swap;
-    }
-
-  /* Make sure the aspect ratios are within 0.001 of each other.
-   */
-  {
-    int r1 = 0.5 + (sp->from.w * 1000 / sp->from.h);
-    int r2 = 0.5 + (sp->to.w   * 1000 / sp->to.h);
-    if (r1 < r2-1 || r1 > r2+1)
-      {
-        fprintf (stderr,
-                 "%s: botched aspect: %f x %f (%d) vs  %f x %f (%d): %s\n",
-                 progname, 
-                 sp->from.w, sp->from.h, r1,
-                 sp->to.w, sp->to.h, r2,
-                 (sp->img->title ? sp->img->title : "[null]"));
-        abort();
-      }
-  }
-
-  sp->from.x /= vp_w;
-  sp->from.y /= vp_h;
-  sp->from.w /= vp_w;
-  sp->from.h /= vp_h;
-  sp->to.x   /= vp_w;
-  sp->to.y   /= vp_h;
-  sp->to.w   /= vp_w;
-  sp->to.h   /= vp_h;
+  return ret;
 }
 
 
 /* Allocate a new sprite and start its animation going.
+   Returns 0 if no images available yet.
  */
 static sprite *
-new_sprite (ModeInfo *mi)
+new_sprite (ModeInfo *mi, Bool want_new_p)
 {
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  image *img = get_image (mi);
+  image *img = get_image (mi, want_new_p);
   sprite *sp;
 
   if (!img)
@@ -606,20 +507,30 @@ new_sprite (ModeInfo *mi)
       return 0;
     }
 
+  if (!img->loaded_p) abort();
+
   sp = (sprite *) calloc (1, sizeof (*sp));
   sp->id = ++ss->sprite_id;
   sp->start_time = ss->now;
   sp->state_time = sp->start_time;
   sp->state = sp->prev_state = NEW;
+  sp->zoom = (zoom
+              ? 1 + frand ((100.0 / zoom) - 1)  /* 75% => [1.0 - 1.33] */
+              : 1);
   sp->img = img;
 
   sp->img->refcount++;
   sp->img->used_p = True;
 
+  if (want_new_p)
+    ss->start_time = ss->now;
+
   ss->sprites[ss->nsprites++] = sp;
   if (ss->nsprites >= countof(ss->sprites)) abort();
 
-  randomize_sprite (mi, sp);
+  if (verbose_p)
+    fprintf (stderr, "%s: new sprite %d, img %d\n", blurb(), sp->id,
+             sp->img->id);
 
   return sp;
 }
@@ -638,10 +549,13 @@ destroy_sprite (ModeInfo *mi, sprite *sp)
   if (!sp) abort();
   if (sp->state != DEAD) abort();
   img = sp->img;
-  if (!img) abort();
-  if (!img->loaded_p) abort();
-  if (!img->used_p) abort();
-  if (img->refcount <= 0) abort();
+  /* if (!img) abort(); */
+  if (img)
+    {
+      if (!img->loaded_p) abort();
+      if (!img->used_p) abort();
+      if (img->refcount <= 0) abort();
+    }
 
   for (i = 0; i < ss->nsprites; i++)           /* unlink it from the list */
     if (ss->sprites[i] == sp)
@@ -656,114 +570,412 @@ destroy_sprite (ModeInfo *mi, sprite *sp)
       }
 
   if (!freed_p) abort();
+
+  if (verbose_p)
+    fprintf (stderr, "%s: free sprite %d\n", blurb(), sp->id);
+
   free (sp);
   sp = 0;
 
-  img->refcount--;
-  if (img->refcount < 0) abort();
-  if (img->refcount == 0)
-    destroy_image (mi, img);
+  if (img)
+    {
+      img->refcount--;
+      if (img->refcount < 0) abort();
+      if (img->refcount == 0)
+        destroy_image (mi, img);
+    }
 }
 
 
-/* Updates the sprite for the current frame of the animation based on
-   its creation time compared to the current wall clock.
- */
 static void
-tick_sprite (ModeInfo *mi, sprite *sp)
+launch_sprite (ModeInfo *mi)
 {
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  image *img = sp->img;
-  double now = ss->now;
-  double secs;
-  double ratio;
-  rect prev_rect = sp->current;
-  GLfloat prev_opacity = sp->opacity;
-
-  if (! sp->img) abort();
-  if (! img->loaded_p) abort();
-
-  secs = now - sp->start_time;
-  ratio = secs / (pan_seconds + fade_seconds);
-  if (ratio > 1) ratio = 1;
-
-  sp->current.x = sp->from.x + ratio * (sp->to.x - sp->from.x);
-  sp->current.y = sp->from.y + ratio * (sp->to.y - sp->from.y);
-  sp->current.w = sp->from.w + ratio * (sp->to.w - sp->from.w);
-  sp->current.h = sp->from.h + ratio * (sp->to.h - sp->from.h);
+  int vp_w = MI_WIDTH(mi);
+  int vp_h = MI_HEIGHT(mi);
+  sprite *out, *in;
+  sprite *sprites[2];
+  int sprite_w[countof(sprites)];
+  int sprite_max_w = 0;
+  int sprite_max_h = 0;
+  int i;
 
-  sp->prev_state = sp->state;
+  if (ss->state == LOADING)
+    return;
 
-  if (secs < fade_seconds)
-    {
-      sp->state = IN;
-      sp->opacity = secs / (GLfloat) fade_seconds;
-    }
-  else if (secs < pan_seconds)
+  if (ss->state == FIRST_IN)
+    out = NULL;
+  else if (ss->nsprites > 0)
+    out = ss->sprites[ss->nsprites-1];
+  else
     {
-      sp->state = FULL;
-      sp->opacity = 1;
+      fprintf (stderr, "%s: no out sprite\n", blurb());
+      abort();
     }
-  else if (secs < pan_seconds + fade_seconds)
+
+  in = new_sprite (mi, (ss->state == FIRST_IN ||
+                        ss->state == TRANSITION_OUT ||
+                        ss->state == TRANSITION_PANZOOM));
+  if (!in)
     {
-      sp->state = OUT;
-      sp->opacity = 1 - ((secs - pan_seconds) / (GLfloat) fade_seconds);
+      fprintf (stderr, "%s: no in sprite\n", blurb());
+      abort();
     }
-  else
+
+  sprites[0] = out;
+  sprites[1] = in;
+
+  switch (ss->state) {
+  case FIRST_IN:
+  case TRANSITION_OUT:
+
+    /* Compute the maximal extents of the pair, including letterboxing.
+       For the overlapping horizontal/vertical transitions to look right,
+       the two sprites have to transit the same distance, not just 100%.
+     */
+    sprite_max_w = vp_w;
+    sprite_max_h = vp_h;
+
+    for (i = 0; i < countof(sprites); i++)
+      {
+        sprite *sp = sprites[i];
+        int w, h;
+        double ratio;
+        if (!sp) continue;
+        ratio = (double) sp->img->geom.height / sp->img->geom.width;
+
+        if (letterbox_p)
+          {
+            if (vp_w * ratio < vp_h)
+              w = vp_w;                        /* full width, smaller height */
+            else
+              w = vp_h / ratio;                /* full height, smaller width */
+          }
+        else
+          {
+            if (vp_w * ratio < vp_h)
+              w = vp_h / ratio;                /* full height, crop width */
+            else
+              w = vp_w;                        /* full width, crop height */
+          }
+
+        w *= sp->zoom;
+
+        sprite_w[i] = w;
+        h = w * ratio;
+        if (w > sprite_max_w) sprite_max_w = w;
+        if (h > sprite_max_h) sprite_max_h = h;
+      }
+
     {
-      sp->state = DEAD;
-      sp->opacity = 0;
+      const transition_mode mm[] = {
+        FADE, LEFT, RIGHT, TOP, BOTTOM, FLIP, SPIN
+      };
+      const easing_function ee[] = {
+        EASE_IN_OUT_QUAD, EASE_IN_OUT_QUAD, EASE_IN_OUT_QUAD, EASE_IN_OUT_QUAD,
+        EASE_IN_OUT_QUINT, EASE_IN_OUT_QUINT,
+        EASE_IN_OUT_BACK, EASE_IN_OUT_BACK,
+        EASE_IN_CUBIC, EASE_IN_CUBIC,
+      };
+      transition_mode t;
+      easing_function e;
+      t = mm[random() % countof(mm)];
+      e = ee[random() % countof(ee)];
+
+      if (ss->state == FIRST_IN && out) abort();
+      if (ss->state == TRANSITION_OUT && !out) abort();
+
+      for (i = 0; i < countof(sprites); i++)
+        {
+          Bool out_p = (i == 0);
+          sprite *sp = sprites[i];
+          double ratio;
+          if (!sp) continue;
+
+          sp->state      = out_p ? OUT : IN;
+          sp->start_time = ss->now;
+          sp->duration   = transition_seconds;
+
+          if (!out_p && pan_seconds <= 0)
+            /* If we are not doing PANZOOM, then this image will
+               linger on screen for the full image duration. */
+            sp->duration += image_seconds;
+
+          ratio = (double) sp->img->geom.height / sp->img->geom.width;
+
+          /* Default coordinates are centered. */
+          sp->to.w   = sprite_w[i];
+          sp->to.h   = sp->to.w * ratio;
+          sp->to.x   = (sp->to.w > vp_w
+                        ? -(sp->to.w - vp_w) / 2
+                        :  (vp_w - sp->to.w) / 2);
+          sp->to.y   = (sp->to.h > vp_h
+                        ? -(sp->to.h - vp_h) / 2
+                        :  (vp_h - sp->to.h) / 2);
+          sp->to.r.x = 0;
+          sp->to.r.y = 0;
+          sp->to.r.z = 0;
+          sp->from   = sp->to;
+
+          sp->transition = t;
+          sp->easing = e;
+
+          switch (t) {
+          case FADE:
+            /* No motion, only alpha */
+            break;
+
+          case LEFT:
+            if (out_p)
+              sp->to.x   = sp->to.x + sprite_max_w;
+            else
+              sp->from.x = sp->to.x - sprite_max_w;
+            break;
+
+          case RIGHT:
+            if (out_p)
+              sp->to.x   = sp->to.x - sprite_max_w;
+            else
+              sp->from.x = sp->to.x + sprite_max_w;
+            break;
+    
+          case TOP:
+            if (out_p)
+              sp->to.y   = sp->to.y - sprite_max_h;
+            else
+              sp->from.y = sp->to.y + sprite_max_h;
+            break;
+    
+          case BOTTOM:
+            if (out_p)
+              sp->to.y   = sp->to.y + sprite_max_h;
+            else
+              sp->from.y = sp->to.y - sprite_max_h;
+            break;
+    
+          case ZOOM:
+            if (out_p)
+              {
+                sp->to.x   = vp_w / 2;
+                sp->to.y   = vp_h / 2;
+                sp->to.w   = 1;
+                sp->to.h   = sp->to.w * ratio;
+              }
+            else
+              {
+                sp->from.x = vp_w / 2;
+                sp->from.y = vp_h / 2;
+                sp->from.w = 1;
+                sp->from.h = sp->from.w * ratio;
+              }
+            break;
+    
+          case SPIN:
+            {
+              int quads = 2 + (random() % 6);
+              GLfloat spin = (!out_p && out
+                              ? -out->to.r.z
+                              : (90 * quads *
+                                  (random() & 1 ? 1 : -1)));
+              GLfloat scale = 0.0001;
+              if (out_p)
+                {
+                  sp->to.r.z  = spin;
+                  sp->to.w   *= scale;
+                  sp->to.h   *= scale;
+                  sp->to.x    = (vp_w - sp->to.w) / 2;
+                  sp->to.y    = (vp_h - sp->to.h) / 2;
+                }
+              else
+                {
+                  sp->from.r.z = spin;
+                  sp->from.w  *= scale;
+                  sp->from.h  *= scale;
+                  sp->from.x   = (vp_w - sp->from.w) / 2;
+                  sp->from.y   = (vp_h - sp->from.h) / 2;
+                }
+            }
+            break;
+    
+          case FLIP:
+            {
+              Bool horiz_p = random() & 1;
+              Bool sign = (random() & 1 ? 1 : -1);
+              GLfloat flipx = (!out_p && out
+                               ? -out->to.r.x
+                               : horiz_p ? 180 * sign : 0);
+              GLfloat flipy = (!out_p && out
+                               ? -out->to.r.y
+                               : horiz_p ? 0 : 180 * sign);
+              if (out_p)
+                {
+                  sp->to.r.x   = flipx;
+                  sp->to.r.y   = flipy;
+                }
+              else
+                {
+                  sp->from.r.x = flipx;
+                  sp->from.r.y = flipy;
+                }
+            }
+            break;
+    
+          default:
+            abort();
+            break;
+          }
+        }
+
+      if (out && verbose_p)
+        fprintf (stderr, "%s: adjust TR sprite %d dur %.1f start %.1f\n",
+                 blurb(), out->id, out->duration,
+                 out->start_time - ss->now);
     }
+    break;
+
+  case IN_PANZOOM:
+    /* Adjust the just-transitioned-in image to fade out, as the 
+       second sprite starts fading in.
+     */
+    if (!out) abort();
+    out->duration   = pan_seconds;
+    out->duration   = fade_seconds + pan_seconds;
+    out->start_time = ss->now - pan_seconds;
+    out->transition = PANZOOM;
+    out->state      = FULL;
+    out->prev_state = OUT;
+    out->to         = out->current;
+    out->from       = out->current;
+
+    if (verbose_p)
+      fprintf (stderr, "%s: adjust PZ sprite %d dur %.1f start %.1f\n",
+               blurb(), out->id, out->duration,
+               out->start_time - ss->now);
+
+    /* fallthrough */
+
+  case MID_PANZOOM:
+  case RECENTER:
+  case TRANSITION_PANZOOM:
+    if (!in) abort();
+    in->duration   = fade_seconds + pan_seconds;
+    in->start_time = ss->now;
+    in->transition = PANZOOM;
+    in->state      = IN;
 
-  if (sp->state != sp->prev_state &&
-      (sp->prev_state == IN ||
-       sp->prev_state == FULL))
     {
-      double secs = now - sp->state_time;
+      int w;
+      double ratio = (double) in->img->geom.height / in->img->geom.width;
+      double in_zoom[2];
+
+      if (letterbox_p)
+        {
+          if (vp_w * ratio < vp_h)
+            w = vp_w;                  /* full width, smaller height */
+          else
+            w = vp_h / ratio;          /* full height, smaller width */
+        }
+      else
+        {
+          if (vp_w * ratio < vp_h)
+            w = vp_h / ratio;          /* full height, crop width */
+          else
+            w = vp_w;                  /* full width, crop height */
+        }
+
+      in_zoom[0] = (zoom
+                    ? 1 + frand ((100.0 / zoom) - 1)  /* 75% => [1.0 - 1.33] */
+                    : 1);
+      in_zoom[1] = (zoom
+                    ? 1 + frand ((100.0 / zoom) - 1)
+                    : 1);
+
+      if (ss->state == RECENTER)
+        in_zoom[1] = in->zoom;
+
+      in->from.w   = w * in_zoom[0];
+      in->from.h   = in->from.w * ratio;
+      in->from.r.x = 0;
+      in->from.r.y = 0;
+      in->from.r.z = 0;
+
+      in->from.x = (in->from.w > vp_w
+                    ? -frand (in->from.w - vp_w)
+                    :  frand (vp_w - in->from.w));
+      in->from.y = (in->from.h > vp_h
+                    ? -frand (in->from.h - vp_h)
+                    :  frand (vp_h - in->from.h));
+
+      in->to.w   = w * in_zoom[1];
+      in->to.h   = in->to.w * ratio;
+      in->to.r.x = 0;
+      in->to.r.y = 0;
+      in->to.r.z = 0;
+
+      if (ss->state == RECENTER)
+        {
+          in->to.x   = (in->to.w > vp_w
+                        ? -(in->to.w - vp_w) / 2
+                        :  (vp_w - in->to.w) / 2);
+          in->to.y   = (in->to.h > vp_h
+                        ? -(in->to.h - vp_h) / 2
+                        :  (vp_h - in->to.h) / 2);
+        }
+      else
+        {
+          in->to.x = (in->to.w > vp_w
+                      ? -frand (in->to.w - vp_w)
+                      :  frand (vp_w - in->to.w));
+          in->to.y = (in->to.h > vp_h
+                      ? -frand (in->to.h - vp_h)
+                      :  frand (vp_h - in->to.h));
+        }
 
-      if (verbose_p)
-        fprintf (stderr,
-                 "%s: %s %3d frames %2.0f sec %5.1f fps (max %.1f fps?)\n",
-                 blurb(),
-                 (sp->prev_state == IN ? "fade" : "pan "),
-                 sp->frame_count,
-                 secs,
-                 sp->frame_count / secs,
-                 ss->theoretical_fps);
-
-      sp->state_time = now;
-      sp->frame_count = 0;
     }
+    break;
 
-  sp->frame_count++;
+  default:
+    abort();
+    break;
+  }
 
-  if (sp->state != DEAD &&
-      (prev_rect.x != sp->current.x ||
-       prev_rect.y != sp->current.y ||
-       prev_rect.w != sp->current.w ||
-       prev_rect.h != sp->current.h ||
-       prev_opacity != sp->opacity))
-    ss->redisplay_needed_p = True;
+  if (verbose_p)
+    fprintf (stderr, "%s: launch sprite %d dur %.1f\n",
+             blurb(), in->id, in->duration);
 }
 
 
+
 /* Draw the given sprite at the phase of its animation dictated by
    its creation time compared to the current wall clock.
  */
 static void
-draw_sprite (ModeInfo *mi, sprite *sp, Bool keep_title_p)
+draw_sprite (ModeInfo *mi, sprite *sp)
 {
-  slideshow_state *ss = &sss[MI_SCREEN(mi)];
+  /* slideshow_state *ss = &sss[MI_SCREEN(mi)]; */
   int wire = MI_IS_WIREFRAME(mi);
   image *img = sp->img;
+  int vp_w = MI_WIDTH(mi);
+  int vp_h = MI_HEIGHT(mi);
 
   if (! sp->img) abort();
   if (! img->loaded_p) abort();
 
   glPushMatrix();
   {
-    glTranslatef (sp->current.x, sp->current.y, 0);
-    glScalef (sp->current.w, sp->current.h, 1);
+    GLfloat aspect = vp_w / (GLfloat) vp_h;
+    glScalef (1, aspect, 1);
+    glRotatef (sp->current.r.x, 1, 0, 0);
+    glRotatef (sp->current.r.y, 0, 1, 0);
+    glRotatef (sp->current.r.z, 0, 0, 1);
+    glScalef (1, 1/aspect, 1);
+
+    glTranslatef (sp->current.x / vp_w - 0.5,
+                  sp->current.y / vp_h - 0.5,
+                  0);
+    glScalef (sp->current.w / vp_w,
+              sp->current.h / vp_h,
+              1);
 
     if (wire)                  /* Draw a grid inside the box */
       {
@@ -837,20 +1049,11 @@ draw_sprite (ModeInfo *mi, sprite *sp, Bool keep_title_p)
             if (!wire) glEnable (GL_TEXTURE_2D);
           }
       }
-
-
-    if (do_titles && img->title && *img->title)
-      {
-        glColor4f (1, 1, 1, keep_title_p ? 1 : sp->opacity);
-        print_texture_label (mi->dpy, ss->font_data,
-                             mi->xgwa.width, mi->xgwa.height,
-                             1, img->title);
-      }
   }
-  glPopMatrix();
 
   if (debug_p)
     {
+#if 1
       if (!wire) glDisable (GL_TEXTURE_2D);
 
       if (sp->id & 1)
@@ -875,7 +1078,10 @@ draw_sprite (ModeInfo *mi, sprite *sp, Bool keep_title_p)
       glEnd();
 
       if (!wire) glEnable (GL_TEXTURE_2D);
+#endif
     }
+
+  glPopMatrix();
 }
 
 
@@ -883,9 +1089,312 @@ static void
 tick_sprites (ModeInfo *mi)
 {
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
+  anim_state ostate = ss->state;
+  double total_secs = ss->now - ss->start_time;
+  sprite *sp = ss->nsprites > 0 ? ss->sprites[ss->nsprites-1] : NULL;
+  double sp_secs = sp ? ss->now - sp->start_time : 0;
+  Bool launch_p = FALSE;
+  Bool image_p;
   int i;
+
+  /* Make sure that there is always one unused image in the pipe. */
+  get_image (mi, TRUE);
+
+  image_p = (ss->nimages > 0 &&
+             ss->images[ss->nimages-1]->loaded_p &&
+             !ss->images[ss->nimages-1]->used_p);
+
+  switch (ss->state) {
+
+  case LOADING:
+    if (image_p)
+      ss->state = FIRST_IN;
+    ss->redisplay_needed_p = TRUE;
+    break;
+
+  case FIRST_IN:
+  case TRANSITION_OUT:
+    if (!sp && ss->state == TRANSITION_OUT)
+      {
+        fprintf (stderr, "%s: no TRANSITION_OUT sprite\n", blurb());
+        abort();
+      }
+    else if (ss->change_now_p && image_p)
+      {
+        ss->state = TRANSITION_OUT;
+        launch_p = TRUE;
+      }
+    else if (total_secs >= transition_seconds && pan_seconds)
+      ss->state = IN_PANZOOM;
+    else if (total_secs >= image_seconds && image_p)
+      {
+        ss->state = TRANSITION_OUT;
+        launch_p = TRUE;       /* do TRANSITION_OUT again */
+      }
+    break;
+
+  case IN_PANZOOM:
+    if (!sp)
+      {
+        fprintf (stderr, "%s: no IN_PANZOOM sprite\n", blurb());
+        abort();
+      }
+    else if (ss->change_now_p && image_p)
+      {
+        if (transition_seconds <= 0)
+          ss->state = TRANSITION_PANZOOM;
+        else
+          ss->state = RECENTER;
+      }
+    else if (sp_secs >= pan_seconds)
+      ss->state = MID_PANZOOM;
+    break;
+
+  case MID_PANZOOM:
+  case TRANSITION_PANZOOM:
+    if (!sp)
+      {
+        fprintf (stderr, "%s: no MID_PANZOOM sprite\n", blurb());
+        abort();
+      }
+    else if (image_p &&
+             (ss->change_now_p ||
+              sp_secs >= pan_seconds))
+      {
+        if ((ss->change_now_p && image_p) ||
+            total_secs >= image_seconds - (fade_seconds + pan_seconds))
+          {
+            if (transition_seconds <= 0)
+              {
+                /* TRANSITION_PANZOOM is just like MID_PANZOOM but loads
+                   a new image instead of reusing an old one. */
+                ss->state = TRANSITION_PANZOOM;
+                launch_p = TRUE;
+              }
+            else
+              {
+                ss->state = RECENTER;
+              }
+          }
+        else
+          {
+            ss->state = MID_PANZOOM;
+            launch_p = TRUE;
+          }
+      }
+    break;
+
+  case RECENTER:
+    if (!sp)
+      {
+        fprintf (stderr, "%s: no RECENTER sprite\n", blurb());
+        abort();
+      }
+    else if (sp_secs >= pan_seconds + fade_seconds &&
+             total_secs >= image_seconds)
+      ss->state = TRANSITION_OUT;
+    break;
+
+  default:
+    abort();
+    break;
+  }
+
+  ss->change_now_p = FALSE;
+
   for (i = 0; i < ss->nsprites; i++)
-      tick_sprite (mi, ss->sprites[i]);
+    {
+      sprite *sp = ss->sprites[i];
+      sp_secs = ss->now - sp->start_time;
+    }
+
+  if (ostate != ss->state) launch_p = TRUE;
+
+  if (launch_p)
+    {
+      if (verbose_p)
+        fprintf (stderr, "%s: %s => %s\n", blurb(),
+                 (ostate == LOADING        ? "LOADING" :
+                  ostate == FIRST_IN       ? "FIRST_IN" :
+                  ostate == IN_PANZOOM     ? "IN_PANZOOM" :
+                  ostate == MID_PANZOOM    ? "MID_PANZOOM" :
+                  ostate == RECENTER       ? "RECENTER" :
+                  ostate == TRANSITION_OUT ? "TRANSITION_OUT" : "???"),
+                 (ss->state == LOADING        ? "LOADING" :
+                  ss->state == FIRST_IN       ? "FIRST_IN" :
+                  ss->state == IN_PANZOOM     ? "IN_PANZOOM" :
+                  ss->state == MID_PANZOOM    ? "MID_PANZOOM" :
+                  ss->state == RECENTER       ? "RECENTER" :
+                  ss->state == TRANSITION_OUT ? "TRANSITION_OUT" :
+                  ss->state == TRANSITION_PANZOOM ? "TRANSITION_PANZOOM" :
+                  "???"));
+
+      launch_sprite (mi);
+      return;
+    }
+
+  for (i = 0; i < countof(ss->sprites); i++)
+    {
+      sprite *sp = ss->sprites[i];
+      double ratio;
+      double secs;
+      double prev_opacity;
+      rect prev_rect;
+      if (!sp) continue;
+
+      secs = ss->now - sp->start_time;
+
+      sp->prev_state  = sp->state;
+      prev_rect       = sp->current;
+      prev_opacity    = sp->opacity;
+
+      switch (sp->transition) {
+      case PANZOOM:
+        ratio = secs / (fade_seconds + pan_seconds);
+
+        if (secs <= fade_seconds)      /* PANZOOM is 3 transitions in one */
+          {
+            sp->opacity = secs / fade_seconds;
+            if (sp->opacity > 1) sp->opacity = 1;
+            sp->state = IN;
+          }
+        else if (secs <= pan_seconds)
+          {
+            sp->state = FULL;
+            sp->opacity = 1;
+          }
+        else if (secs <= fade_seconds + pan_seconds)
+          {
+            sp->opacity = 1 - ((secs - pan_seconds) / fade_seconds);
+            sp->state = OUT;
+            if (ss->state == RECENTER &&
+                i == ss->nsprites-1)
+              sp->opacity = 1;
+          }
+        else
+          {
+            sp->state = DEAD;
+            sp->opacity = 0;
+          }
+        break;
+
+      case LEFT:
+      case RIGHT:
+      case TOP:
+      case BOTTOM:
+      case FLIP:
+      case FADE:
+      case ZOOM:
+      case SPIN:
+        ratio = secs / transition_seconds;
+        if (ratio <= 1)
+          {
+            if (sp->transition == FADE ||
+                sp->transition == ZOOM ||
+                sp->transition == SPIN)
+              sp->opacity = (sp->state == IN ? ratio : 1-ratio);
+            else
+              sp->opacity = 1;
+          }
+        else if (secs <= sp->duration)
+          {
+            ratio = 1;         /* Linger */
+            sp->opacity = 1;
+          }
+        else
+          {
+            sp->state = DEAD;
+            ratio = 1;
+            sp->opacity = 0;
+          }
+        break;
+      default:
+        abort();
+        break;
+      }
+
+      ratio = ease (sp->easing, ratio);
+      sp->current.x   = sp->from.x +   ratio * (sp->to.x   - sp->from.x);
+      sp->current.y   = sp->from.y +   ratio * (sp->to.y   - sp->from.y);
+      sp->current.w   = sp->from.w +   ratio * (sp->to.w   - sp->from.w);
+      sp->current.h   = sp->from.h +   ratio * (sp->to.h   - sp->from.h);
+      sp->current.r.x = sp->from.r.x + ratio * (sp->to.r.x - sp->from.r.x);
+      sp->current.r.y = sp->from.r.y + ratio * (sp->to.r.y - sp->from.r.y);
+      sp->current.r.z = sp->from.r.z + ratio * (sp->to.r.z - sp->from.r.z);
+
+      sp->frame_count++;
+    
+      if (sp->state != DEAD &&
+          (prev_rect.x   != sp->current.x ||
+           prev_rect.y   != sp->current.y ||
+           prev_rect.w   != sp->current.w ||
+           prev_rect.h   != sp->current.h ||
+           prev_rect.r.x != sp->current.r.x ||
+           prev_rect.r.y != sp->current.r.y ||
+           prev_rect.r.z != sp->current.r.z ||
+           prev_opacity != sp->opacity))
+        ss->redisplay_needed_p = True;
+
+      if (0 && verbose_p && debug_p && ss->redisplay_needed_p)
+        fprintf (stderr, "%s: %d: %5.0f %-5.0f  %5.0f %-5.0f  %.1f\n", blurb(),
+                 sp->id, 
+                 sp->current.x, sp->current.y, 
+                 sp->current.w, sp->current.h, 
+                 sp->opacity);
+
+      if (sp->state != sp->prev_state)
+        {
+          if (verbose_p)
+            fprintf (stderr,
+                     "%s: %d: %-4s %-5s %3d frames %2.0f sec %5.1f fps"
+                     " (max %.0f fps?)\n",
+                     blurb(),
+                     sp->id,
+                     (sp->prev_state == NEW  ? "NEW"  :
+                      sp->prev_state == IN   ? "IN"   :
+                      sp->prev_state == FULL ? "FULL" :
+                      sp->prev_state == OUT  ? "FULL" :
+                      sp->prev_state == DEAD ? "DEAD" : "???"),
+                     (sp->transition == NONE    ? "NONE"  :
+                      sp->transition == PANZOOM ? "PZ"    :
+                      sp->transition == FADE    ? "FADE"  :
+                      sp->transition == LEFT    ? "LEFT"  :
+                      sp->transition == RIGHT   ? "RIGHT" :
+                      sp->transition == TOP     ? "TOP"   :
+                      sp->transition == BOTTOM  ? "BOT"   :
+                      sp->transition == ZOOM    ? "ZOOM"  :
+                      sp->transition == FLIP    ? "FLIP"  :
+                      sp->transition == SPIN    ? "SPIN"  : "???"),
+                     sp->frame_count,
+                     secs,
+                     sp->frame_count / secs,
+                     ss->theoretical_fps);
+          sp->state_time = ss->now;
+          sp->frame_count = 0;
+        }
+    }
+
+  for (i = 0; i < ss->nsprites; i++)
+    {
+      sprite *sp = ss->sprites[i];
+      if (sp->state == DEAD)
+        {
+          /* Don't unload the last sprite if we are stalled waiting for an
+             image to load. */
+          if (ss->nsprites < 2 && !image_p)
+            continue;
+          destroy_sprite (mi, sp);
+          i--;
+        }
+    }
+
+  if (ss->nsprites > 3 ||
+      ss->nsprites > countof (ss->sprites) ||
+      ss->nsprites < (!image_p ? 0 : 1))
+    {
+      fprintf (stderr, "%s: %d sprites\n", blurb(), ss->nsprites);
+      abort();
+    }
 }
 
 
@@ -893,40 +1402,58 @@ static void
 draw_sprites (ModeInfo *mi)
 {
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  char *last_title = 0;
   int i;
 
   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
   glPushMatrix();
 
-/*
-  {
-    GLfloat rot = current_device_rotation();
-    glTranslatef (0.5, 0.5, 0);
-    glRotatef(rot, 0, 0, 1);
-    if ((rot >  45 && rot <  135) ||
-        (rot < -45 && rot > -135))
-      {
-        GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi);
-        glScalef (s, 1/s, 1);
-      }
-    glTranslatef (-0.5, -0.5, 0);
-  }
-*/
+  if (debug_p)
+    {
+      GLfloat s = 0.75;
+      glScalef (s, s, s);
+    }
+
+  if (ss->state == LOADING)
+    {
+      double secs = ss->now - ss->dawn_of_time;
+      double opacity = secs / 6;
+      if (opacity > 1) opacity = 1;
+      glColor4f (1, 1, 0, opacity);
+      print_texture_label (mi->dpy, ss->font_data,
+                           mi->xgwa.width, mi->xgwa.height,
+                           0, "Loading...");
+    }
 
   for (i = 0; i < ss->nsprites; i++)
+    draw_sprite (mi, ss->sprites[i]);
+
+  if (do_titles)
     {
-      sprite *s = ss->sprites[i];
-      /* If the two sprites have the same title, draw the second title at
-         full intensity to avoid a weird blooming effect when crossfading
-         an image with itself. */
-      Bool keep_title_p = (do_titles && last_title && s->img->title &&
-                           !strcmp (last_title, s->img->title));
-      draw_sprite (mi, s, keep_title_p);
-      last_title = s->img->title;
+      sprite *sp = (ss->nsprites > 0
+                    ? ss->sprites[ss->nsprites-1]
+                    : 0);
+      if (sp && sp->img && sp->img->loaded_p &&
+          sp->img->title && *sp->img->title)
+        {
+          double start = (transition_seconds
+                          ? transition_seconds : fade_seconds);
+          double end   = (image_seconds -
+                          (transition_seconds ? 0 : pan_seconds));
+          double secs = ss->now - ss->start_time;
+          double sec_fade = 3;
+          GLfloat alpha = 1;
+          if (secs - start <= sec_fade)
+            alpha = (secs - start) / sec_fade;
+          else if (secs + sec_fade >= end)
+            alpha = (end - secs) / sec_fade;
+          if (alpha < 0) alpha = 0;
+          if (alpha > 1) alpha = 1;
+          glColor4f (1, 1, 1, alpha);
+          print_texture_label (mi->dpy, ss->font_data,
+                               mi->xgwa.width, mi->xgwa.height,
+                               1, sp->img->title);
+        }
     }
-  glPopMatrix();
 
   if (debug_p)                         /* draw a white box (the "screen") */
     {
@@ -936,14 +1463,23 @@ draw_sprites (ModeInfo *mi)
 
       glColor4f (1, 1, 1, 1);
       glBegin (GL_LINE_LOOP);
-      glVertex3f (0, 0, 0);
-      glVertex3f (0, 1, 0);
-      glVertex3f (1, 1, 0);
-      glVertex3f (1, 0, 0);
+      glVertex3f (-0.5, -0.5, 0);
+      glVertex3f (-0.5,  0.5, 0);
+      glVertex3f ( 0.5,  0.5, 0);
+      glVertex3f ( 0.5, -0.5, 0);
+      glEnd();
+
+      glBegin (GL_LINES);
+      glVertex3f (-0.05, 0, 0);
+      glVertex3f ( 0.05, 0, 0);
+      glVertex3f (0, -0.05, 0);
+      glVertex3f (0,  0.05, 0);
       glEnd();
 
       if (!wire) glEnable (GL_TEXTURE_2D);
     }
+
+  glPopMatrix();
 }
 
 
@@ -951,27 +1487,31 @@ ENTRYPOINT void
 reshape_slideshow (ModeInfo *mi, int width, int height)
 {
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  GLfloat s;
+
+  /* Empirically, these numbers give us a projection where a 1x1 quad
+     centered at 0,0,0 fills the viewport 100%, while still having a
+     non-ortho projection.  All 3 numbers are interdependent.
+     Presumably 'scale' could be computed from the others, somehow...
+   */
+  GLfloat fov   = 30;
+  GLfloat cam   = 15;
+  GLfloat scale = 8.03845;
+
   glViewport (0, 0, width, height);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity();
+  gluPerspective (fov, 1, 0.01, 100);
+
   glRotatef (current_device_rotation(), 0, 0, 1);
   glMatrixMode (GL_MODELVIEW);
   glLoadIdentity();
 
-  s = 2;
-
-  if (debug_p)
-    {
-      s *= (zoom / 100.0) * 0.75;
-      if (s < 0.1) s = 0.1;
-    }
-
-  glScalef (s, s, s);
-  glTranslatef (-0.5, -0.5, 0);
+  gluLookAt (0, 0, cam,
+             0, 0, 0,
+             0, 1, 0);
+  glScalef (scale, scale, scale);
 
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
   ss->redisplay_needed_p = True;
 }
 
@@ -990,11 +1530,14 @@ slideshow_handle_event (ModeInfo *mi, XEvent *event)
         fprintf (stderr, "%s: exposure\n", blurb());
       return False;
     }
+#if 0   /* This tends to trigger "no sprites" aborts, and I don't care
+           enough to debug it. */
   else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
     {
       ss->change_now_p = True;
       return True;
     }
+#endif
 
   return False;
 }
@@ -1006,42 +1549,73 @@ slideshow_handle_event (ModeInfo *mi, XEvent *event)
 static void
 sanity_check (ModeInfo *mi)
 {
+  /* When transitioning one image out and another in (e.g.,
+     one image slides out to the right while a new one slides
+     in from the left) the two sprites run simultaneously over
+     'transition' seconds.
+
+     After an image has transitioned in and is centered on screen,
+     we begin the PANZOOM phase, in which each sprite has three
+     states: fading in, full, fading out.  The in/out states
+     overlap like this:
+
+     iiiiiiFFFFFFFFFFFFoooooo  . . . . . . . . . . . . . . . . . 
+     . . . . . . . . . iiiiiiFFFFFFFFFFFFoooooo  . . . . . . . .
+     . . . . . . . . . . . . . . . . . . iiiiiiFFFFFFFFFFFFooooo
+
+     In PANZOOM, we create a new sprite in the IN state as soon
+     as the old sprite enters the OUT state.
+
+     The "fade in + pan" phase lasts 'pan' seconds: 'fade' is
+     inclusive of 'pan'.  So the non-overlapped part takes 'pan'
+     seconds but the whole animation takes 'fade + pan' seconds
+     (not 'pan + fade + pan' seconds).
+
+     To avoid necessitating a jump-cut or blank screen, when
+     entering the PANZOOM phase, there is a single IN_PANZOOM
+     state that smoothly turns the just-landed centered image
+     into a panner.  And when exiting PANZOOM for transition-out,
+     the final RECENTER state does a PANZOOM that lands the image
+     centered on the screen in preparation for TRANSITION_OUT.
+
+     To do PANZOOM only, set 'transition' to 0.
+
+     To do TRANSITION only, set 'pan' to 0.
+
+     The full cycle (before loading a new image) takes 'image'
+     seconds (and is inclusive of the 'transition' seconds).
+   */
+
   if (zoom < 1) zoom = 1;           /* zoom is a positive percentage */
   else if (zoom > 100) zoom = 100;
 
-  if (zoom == 100)                 /* with no zooming, there is no panning */
-    pan_seconds = 0;
+  if (transition_seconds < 0)
+    transition_seconds = 0;
 
-  if (pan_seconds < fade_seconds)   /* pan is inclusive of fade */
-    pan_seconds = fade_seconds;
+  if (image_seconds < transition_seconds) /* img is inclusive of transition. */
+    image_seconds = transition_seconds;
 
-  if (pan_seconds == 0)             /* no zero-length cycles, please... */
-    pan_seconds = 1;
+  if (image_seconds <= 0)           /* no zero-length cycles, please... */
+    image_seconds = 1;
 
-  if (image_seconds < pan_seconds)  /* we only change images at fade-time */
-    image_seconds = pan_seconds;
+  if (pan_seconds < fade_seconds)   /* pan is inclusive of fade */
+    pan_seconds = fade_seconds;
 
-  /* If we're not panning/zooming within the image, then there's no point
-     in crossfading the image with itself -- only do crossfades when changing
-     to a new image. */
-  if (zoom == 100 && pan_seconds < image_seconds)
-    pan_seconds = image_seconds;
+  if (fade_seconds == 0)           /* Panning without fading looks terrible */
+    pan_seconds = 0;
 
   /* No need to use mipmaps if we're not changing the image size much */
   if (zoom >= 80) mipmap_p = False;
-
-  if      (fps_cutoff < 0)  fps_cutoff = 0;
-  else if (fps_cutoff > 30) fps_cutoff = 30;
 }
 
 
+#if 0 /* This if flaky and probably not necessary any more */
 static void
 check_fps (ModeInfo *mi)
 {
-#ifndef HAVE_JWXYZ  /* always assume Cocoa and mobile are fast enough */
+# ifndef HAVE_JWXYZ  /* always assume Cocoa and mobile are fast enough */
 
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
-
   double start_time, end_time, wall_elapsed, frame_duration, fps;
   int i;
 
@@ -1056,6 +1630,7 @@ check_fps (ModeInfo *mi)
   ss->theoretical_fps = fps;
 
   if (ss->checked_fps_p) return;
+  if (debug_p) return;
 
   if (wall_elapsed <= 8)    /* too early to be sure */
     return;
@@ -1074,24 +1649,51 @@ check_fps (ModeInfo *mi)
   fprintf (stderr,
            "%s: only %.1f fps!  Turning off pan/fade to compensate...\n",
            blurb(), fps);
+
   zoom = 100;
+  transition_seconds = 0;
   fade_seconds = 0;
+  pan_seconds = 0;
 
   sanity_check (mi);
 
+  if (verbose_p)
+    fprintf (stderr,
+             "%s: tr: %d, pan: %d; fade: %d; img: %d; zoom: %d%%\n",
+             blurb(), transition_seconds, pan_seconds, fade_seconds,
+             image_seconds, zoom);
+
+  ss->state = LOADING;
+  ss->redisplay_needed_p = True;
+
   for (i = 0; i < ss->nsprites; i++)
     {
       sprite *sp = ss->sprites[i];
-      randomize_sprite (mi, sp);
-      sp->state = FULL;
+      if (!sp) continue;
+      sp->state = DEAD;
+      if (!sp->img->used_p) abort();
+      if (!sp->img->loaded_p) abort();
+      if (sp->img->refcount <= 0) abort();
+      sp->img->used_p = FALSE;
+      sp->img->refcount--;
+      if (verbose_p)
+        fprintf (stderr, "%s: %d: deref img %d\n",
+                 blurb(), sp->id, sp->img->id);
+      sp->img = NULL;
+      destroy_sprite (mi, sp);
+      i--;
     }
 
-  ss->redisplay_needed_p = True;
+  for (i = 0; i < ss->nimages; i++)
+    {
+      image *img = ss->images[i];
+      if (!img) continue;
+      img->used_p = FALSE;
+    }
 
-  /* Need this in case zoom changed. */
-  reshape_slideshow (mi, mi->xgwa.width, mi->xgwa.height);
 #endif /* HAVE_JWXYZ */
 }
+#endif /* 0 */
 
 
 /* Add "-v" to invocation of "xscreensaver-getimage" in -debug mode.
@@ -1135,14 +1737,18 @@ init_slideshow (ModeInfo *mi)
   if (debug_p) verbose_p = True;
 
   if (verbose_p)
-    fprintf (stderr, "%s: pan: %d; fade: %d; img: %d; zoom: %d%%\n",
-             blurb(), pan_seconds, fade_seconds, image_seconds, zoom);
+    fprintf (stderr,
+             "%s: tr: %d, pan: %d; fade: %d; img: %d; zoom: %d%%\n",
+             blurb(), transition_seconds, pan_seconds, fade_seconds,
+             image_seconds, zoom);
 
   sanity_check(mi);
 
   if (verbose_p)
-    fprintf (stderr, "%s: pan: %d; fade: %d; img: %d; zoom: %d%%\n\n",
-             blurb(), pan_seconds, fade_seconds, image_seconds, zoom);
+    fprintf (stderr,
+             "%s: tr: %d, pan: %d; fade: %d; img: %d; zoom: %d%%\n",
+             blurb(), transition_seconds, pan_seconds, fade_seconds,
+             image_seconds, zoom);
 
   glDisable (GL_LIGHTING);
   glDisable (GL_DEPTH_TEST);
@@ -1165,98 +1771,38 @@ init_slideshow (ModeInfo *mi)
   if (debug_p)
     hack_resources (MI_DISPLAY(mi));
 
+  ss->state = LOADING;
+
   ss->now = double_time();
   ss->dawn_of_time = ss->now;
   ss->prev_frame_time = ss->now;
 
-  ss->awaiting_first_image_p = True;
-  alloc_image (mi);
+  get_image (mi, TRUE);
 }
 
 
-static void slideshow_idle (ModeInfo *mi);
-
-
 ENTRYPOINT void
 draw_slideshow (ModeInfo *mi)
 {
   slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  int i;
 
   if (!ss->glx_context)
     return;
 
   glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *ss->glx_context);
-
-  if (ss->awaiting_first_image_p)
-    {
-      image *img = ss->images[0];
-      if (!img) abort();
-      if (!img->loaded_p)
-        return;
-
-      ss->awaiting_first_image_p = False;
-      ss->dawn_of_time = double_time();
-
-      /* start the very first sprite fading in */
-      new_sprite (mi);
-    }
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
   ss->now = double_time();
 
-  /* Each sprite has three states: fading in, full, fading out.
-     The in/out states overlap like this:
-
-     iiiiiiFFFFFFFFFFFFoooooo  . . . . . . . . . . . . . . . . . 
-     . . . . . . . . . iiiiiiFFFFFFFFFFFFoooooo  . . . . . . . .
-     . . . . . . . . . . . . . . . . . . iiiiiiFFFFFFFFFFFFooooo
-
-     So as soon as a sprite goes into the "out" state, we create
-     a new sprite (in the "in" state.)
-   */
-
-  if (ss->nsprites > 2) abort();
-
-  /* If a sprite is just entering the fade-out state,
-     then add a new sprite in the fade-in state.
-   */
-  for (i = 0; i < ss->nsprites; i++)
-    {
-      sprite *sp = ss->sprites[i];
-      if (sp->state != sp->prev_state &&
-          sp->state == (fade_seconds == 0 ? DEAD : OUT))
-        new_sprite (mi);
-    }
-
+  slideshow_idle (mi);
   tick_sprites (mi);
 
-  /* Now garbage collect the dead sprites.
-   */
-  for (i = 0; i < ss->nsprites; i++)
-    {
-      sprite *sp = ss->sprites[i];
-      if (sp->state == DEAD)
-        {
-          destroy_sprite (mi, sp);
-          i--;
-        }
-    }
-
-  /* We can only ever end up with no sprites at all if the machine is
-     being really slow and we hopped states directly from FULL to DEAD
-     without passing OUT... */
-  if (ss->nsprites == 0)
-    new_sprite (mi);
-
   if (!ss->redisplay_needed_p)
     /* Nothing to do! Don't bother drawing a texture or even swapping the
        frame buffers. Note that this means that the FPS display will be
        wrong: "Load" will be frozen on whatever it last was, when in
        reality it will be close to 0. */
-    {
-      slideshow_idle (mi);
-      return;
-    }
+    return;
 
   if (verbose_p && ss->now - ss->prev_frame_time > 1)
     fprintf (stderr, "%s: static screen for %.1f secs\n",
@@ -1271,9 +1817,7 @@ draw_slideshow (ModeInfo *mi)
   ss->prev_frame_time = ss->now;
   ss->redisplay_needed_p = False;
 
-  slideshow_idle (mi);
-
-  check_fps (mi);
+  /* check_fps (mi); */
 }
 
 
@@ -1289,44 +1833,27 @@ free_slideshow (ModeInfo *mi)
   ss->font_data = 0;
 
 # if 0
-  /* The lifetime of these objects is incomprehensible.
-     Doing this causes free pointers to be run from the XtInput.
-   */
-  for (i = ss->nimages-1; i >= 0; i--) {
-    if (ss->images[i] && ss->images[i]->refcount == 0)
-      destroy_image (mi, ss->images[i]);
-  }
-
-  for (i = countof(ss->sprites)-1; i >= 0; i--) {
-    if (ss->sprites[i])
-      destroy_sprite (mi, ss->sprites[i]);
-  }
-# endif
-}
-
-
-static void
-slideshow_idle (ModeInfo *mi)
-{
-  slideshow_state *ss = &sss[MI_SCREEN(mi)];
-  double allowed_time = ((double) mi->pause) / 2000000; /* 0.01 sec */
-  int i;
+  /* Doing this causes free pointers to be run from the XtInput.
+     I don't know how to shut that down properly. */
+  for (i = countof(ss->sprites)-1; i >= 0; i--)
+    {
+      sprite *sp = ss->sprites[i];
+      if (!sp) continue;
+      sp->state = DEAD;
+      destroy_sprite (mi, sp);
+    }
 
-  for (i = 0; i < ss->nimages; i++)
+  for (i = ss->nimages-1; i >= 0; i--)
     {
       image *img = ss->images[i];
-      if (img->loader)
-        {
-          if (texture_loader_failed (img->loader))
-            abort();
-          step_texture_loader (img->loader, allowed_time,
-                               image_loaded_cb, img);
-          img->steps++;
-          break; /* only do the first one! */
-        }
+      if (!img) continue;
+      if (img->refcount == 0)
+        destroy_image (mi, img);
     }
+# endif
 }
 
+
 XSCREENSAVER_MODULE_2 ("GLSlideshow", glslideshow, slideshow)
 
 #endif /* USE_GL */
index d1ab1abc2b01b7681fff2155e712bc60d0c37fc3..c226982725c937ed624bf896277210c0e702c27e 100644 (file)
@@ -9,22 +9,20 @@ glslideshow \- slideshow of images using smooth zooming and fades
 [\-\-root]
 [\-\-window\-id \fInumber\fP]
 [\-\-duration \fIseconds\fP]
-[\-\-zoom \fIpercent\fP]
+[\-\-transition \fIseconds\fP]
 [\-\-pan \fIseconds\fP]
 [\-\-fade \fIseconds\fP]
-[\-\-titles]
 [\-\-letterbox | \-\-clip]
+[\-\-zoom \fIpercent\fP]
+[\-\-titles]
 [\-\-delay \fIusecs\fP]
 [\-\-fps]
+[\-\-verbose]
 [\-\-debug]
 [\-\-wireframe]
-[\-\-cutoff \fIint\fP]
 .SH DESCRIPTION
-Loads a random sequence of images and smoothly scans and zooms around
-in each, fading from pan to pan.  
-
-This program requires a good video card capable of supporting large
-textures.
+Displays a slideshow of images, with panning, zooming and crossfading
+effects.
 
 To specify the directory that images are loaded from, run
 .BR xscreensaver\-settings (1)
@@ -48,58 +46,50 @@ Draw on the specified window.
 How long each image will be displayed before loading a new one.
 Default 30 seconds.
 .TP 8
+.B \-\-transition \fIseconds\fP
+When a new image is loaded, it transitions onto the screen by sliding
+in from the edges, spinning or flipping.  This is how long that transition
+takes.  Set it to 0 to disable the transition effects.  Default 3 seconds.
+.TP 8
 .B \-\-pan \fIseconds\fP
-How long each pan-and-zoom should last.  Default 6 seconds.
-
-With the default settings of \fI\-\-pan 6 \-\-duration 30\fP, each image
-will be displayed five times (30/6), and then a new image will be loaded.
-If you want a new image to be loaded at each fade, then set \fI\-\-pan\fP
-and \fI\-\-duration\fP to the same value.
+Once an image has been loaded, it is panned, zoomed and cross-faded against
+itself.  This is how fast those pans are.  Set this to 0 to disable the
+panning-and-crossfading effect.  Default 6 seconds.
 .TP 8
 .B \-\-fade \fIseconds\fP
-How long each cross-fade between images should last.  Default 2 seconds.
-If set to 0, then no cross-fading will be done (all transitions
-will be jump-cuts.)
-
-Note that fades are included in the pan time, so \fI\-\-fade\fP cannot
-be larger than \fI\-\-pan\fP.
-.TP 8
-.B \-\-zoom \fInumber\fP
-Amount to zoom and pan as a percentage. Default: 75, meaning that
-75% or more of each image will always be visible.  If set to 100%,
-then the images will always fill the screen, and no panning or 
-zooming will occur.  (Images will still smoothly fade from one
-to another if \fI\-\-fade\fP is non-zero.)
-.TP 8
-.B \-\-titles
-Whether to print the file name of the current image in the upper left corner.
+When zooming and cross-fading, this is how long the "fade" portion takes.
+This value must be less than the "pan" option (it is inclusive).
+Set this to 0 to disable the panning-and-crossfading effect.
+Default 2 seconds.
 .TP 8
 .B \-\-letterbox
-In "letterbox" mode, when an image is not the same aspect ratio as the screen,
-black bars will appear at the top/bottom or left/right so that the whole
-image can be displayed.  This is the default.
+Whether to fit the image on the screen (adding horizontal or vertical
+black bars) or to fill the screen (cropping the image).  This is
+the default.
 .TP 8
 .B \-\-clip
-In "clip" mode, when an image is not the same aspect ratio as the screen,
-we will zoom in further until the image takes up the whole screen.
-This is the opposite of \fI\-\-letterbox\fP.
+The opposite of \fB\-\-letterbox\fP.
+.TP 8
+.B \-\-zoom \fInumber\fP
+Zoom in on the image a little bit.  This applies both to "transitions" and to
+"panning-and-crossfading". Default: 75, meaning that 75% or more of each image
+will always be visible.  If you always want to see 100% of every image, then
+use "letterbox" and set "zoom" to 100%.
+.TP 8
+.B \-\-titles
+Whether to show the file name of the current image in the upper left corner.
 .TP 8
 .B \-\-delay \fInumber\fP
-Per-frame delay, in microseconds.  Default: 20000 (0.02 seconds.).
+Per-frame delay, in microseconds.  Default: 20000 (0.02 seconds).
 .TP 8
 .B \-\-fps
 Display the current frame rate, CPU load, and polygon count.
 .TP 8
-.B \-\-cutoff \fInumber\fP
-If the frame rate we are achieving is lower than this, then panning,
-fading, and zooming will be disabled.  Default 5 FPS.
-
-The idea here is that if your machine can't maintain a decent frame
-rate, then it must not have fast 3D hardware, so we might as well
-behave in a simpler manner.  Set this to 0 to disable this check.
+.B \-\-verbose
+Prints debugging info to stderr.
 .TP 8
 .B \-\-debug
-Prints debugging info to stderr.
+Draw some diagnostic rectangles.
 .TP 8
 .B \-\-wireframe
 Another debug mode.
@@ -123,16 +113,12 @@ The window ID to use with \fI\-\-root\fP.
 .BR carousel (MANSUFFIX)
 .BR photopile (MANSUFFIX)
 .SH COPYRIGHT
-Copyright \(co 2003-2005 by Jamie Zawinski, based on an earlier version
-that was
-Copyright \(co 2002 by Mike Oliphant.
-
-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.
+Copyright \(co 2003-2025 by Jamie Zawinski.  Permission to use, copy, modify, 
+distribute, and sell this software and its documentation for any purpose is 
+hereby granted without fee, provided that the above copyright notice appear 
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation.  No representations are made about the 
+suitability of this software for any purpose.  It is provided "as is" without
+express or implied warranty.
 .SH AUTHOR
-Jamie Zawinski and Mike Oliphant.
+Jamie Zawinski.
index defefda8d0bc73fe978f1eb21673d2f0179b3737..a63b7333cefe5dbfc4670b0643773f5e75dfff09 100644 (file)
@@ -1,5 +1,5 @@
 /* grab-ximage.c --- grab the screen to an XImage for use with OpenGL.
- * xscreensaver, Copyright © 2001-2022 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright © 2001-2025 Jamie Zawinski <jwz@jwz.org>
  *
  * Modified by Richard Weeks <rtweeks21@gmail.com> Copyright (c) 2020
  *
@@ -18,6 +18,7 @@
 #include "pow2.h"
 #include "visual.h"
 #include "xshm.h"
+#include "doubletime.h"
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -486,23 +487,6 @@ struct texture_loader_t {
 };
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 /* Loads the given XImage into GL's texture memory.
    The image may be of any size.
    If mipmap_p is true, then make mipmaps instead of just a single texture.
index f03c7084302b3a40a7f0e8790eaac317e1190ead..2cf1b8e53e28c61bda37600a0846220f94dfe511 100644 (file)
@@ -1,4 +1,4 @@
-/* handsy, Copyright © 2018-2023 Jamie Zawinski <jwz@jwz.org>
+/* handsy, Copyright © 2018-2025 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
@@ -24,6 +24,7 @@
 #include "rotator.h"
 #include "gltrackball.h"
 #include "gllist.h"
+#include "doubletime.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -195,23 +196,6 @@ static argtype vars[] = {
 ENTRYPOINT ModeSpecOpt hands_opts = {countof(opts), opts, countof(vars), vars, NULL};
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static double
 constrain_joint (double v, double min, double max)
 {
index 6ff00e843f49728400f7ce4c723e5cd4e15d8bf4..836d22a94062409c544cc5188138c1bf4af72bab 100644 (file)
@@ -1,5 +1,4 @@
-/* hydrostat, Copyright (C) 2012 by Justin Windle
- * Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+/* hydrostat, Copyright © 2012-2025 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -39,6 +38,7 @@
 #include "colors.h"
 #include "sphere.h"
 #include "normals.h"
+#include "easing.h"
 #include "gltrackball.h"
 #include <ctype.h>
 
@@ -217,27 +217,6 @@ move_tentacle (squid *sq, tentacle *t)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-/* Squirty motion: fast acceleration, then fade. */
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.05;
-  GLfloat ease2 = 1-ease;
-  if      (r <= 0)     r = 0;
-  else if (r >= 1)     r = 1;
-  else if (r <= ease)  r =     ease  * ease_fn (r / ease);
-  else                 r = 1 - ease2 * ease_fn ((1 - r) / ease2);
-  return r;
-}
-
-
 static void
 move_squid (ModeInfo *mi, squid *sq)
 {
@@ -263,7 +242,7 @@ move_squid (ModeInfo *mi, squid *sq)
           sq->to.z = 250 - frand(500);
         }
 
-      r = sq->ratio > 0 ? ease_ratio (sq->ratio) : 0;
+      r = sq->ratio > 0 ? ease (EASE_IN_OUT_SINE, sq->ratio) : 0;
       sq->pos.x = sq->from.x + r * (sq->to.x - sq->from.x);
       sq->pos.y = sq->from.y + r * (sq->to.y - sq->from.y);
       sq->pos.z = sq->from.z + r * (sq->to.z - sq->from.z);
index 659ae14a9251f97739a7c093f08544c8a047f58b..781b9ef9f40d8105e3f1d558c1f92ea661ca225e 100644 (file)
@@ -38,6 +38,7 @@
 #include "xlockmore.h"
 #include "ximage-loader.h"
 #include "texfont.h"
+#include "easing.h"
 #include "../images/gen/oceantiles_12_png.h"
 
 #ifdef USE_GL /* whole file */
@@ -1165,25 +1166,6 @@ init_map (ModeInfo *mi)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 ENTRYPOINT void
 draw_map (ModeInfo *mi)
 {
@@ -1334,7 +1316,7 @@ draw_map (ModeInfo *mi)
                 th0 += M_PI*2;
             }
 
-          th2 = th0 + (th1 - th0) * ease_ratio (bp->heading_ratio);
+          th2 = th0 + (th1 - th0) * ease (EASE_IN_OUT_SINE, bp->heading_ratio);
           bp->heading[2].x = sin (th2);
           bp->heading[2].y = cos (th2);
         }
index ee9717b0b8fad4fe9cbaf9b8aba90f8bdb7cad0c..909637c395c24f5fb3aedec74e388668934ee57a 100644 (file)
@@ -52,6 +52,7 @@
 
 #ifdef USE_GL /* whole file */
 
+#include "doubletime.h"
 
 #define DEF_DELAY            "10000"
 #define DEF_FPS              "False"
@@ -311,26 +312,6 @@ typedef struct {
 
 static mirrorblobstruct *Mirrorblob = NULL;
 
-/******************************************************************************
- *
- * Returns the current time in seconds as a double.  Shamelessly borrowed from
- * glslideshow.
- *
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
 /******************************************************************************
  *
  * Change to the projection matrix and set our viewing volume.
index afb20a7b4f8a0ce0d7a4908e927adeeecf5f820a..2a81d6c55c482253baf8bf9724f7f8d475462535 100644 (file)
@@ -1,4 +1,4 @@
-/* nakagin, Copyright © 2022 Jamie Zawinski <jwz@jwz.org>
+/* nakagin, Copyright © 2022-2025 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
@@ -23,7 +23,9 @@
 #include "colors.h"
 #include "rotator.h"
 #include "normals.h"
+#include "easing.h"
 #include "gltrackball.h"
+#include "doubletime.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -115,21 +117,6 @@ ENTRYPOINT ModeSpecOpt nakagin_opts = {
   countof(opts), opts, countof(vars), vars, NULL };
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void
 make_floorplan (floorplan *fp, floorplan *prev)
 {
@@ -933,25 +920,6 @@ draw_capsule (ModeInfo *mi, capsule *c, GLfloat y)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static GLfloat
 max_stack_height (ModeInfo *mi)
 {
@@ -1089,7 +1057,7 @@ move_capsules (ModeInfo *mi)
                   moving++;
                 c->ratio += slide_speed * c->speed;
                 if (bp->ffwd) c->ratio = 1;
-                r = ease_ratio (c->ratio);
+                r = ease (EASE_IN_OUT_SINE, c->ratio);
                 c->pos.x = c->start_pos.x + r * (c->end_pos.x - c->start_pos.x);
                 c->pos.y = c->start_pos.y + r * (c->end_pos.y - c->start_pos.y);
                 c->pos.z = c->start_pos.z + r * (c->end_pos.z - c->start_pos.z);
@@ -1254,7 +1222,7 @@ move_capsules (ModeInfo *mi)
           GLfloat r;
           t->ratio += slide_speed * t->speed;
           if (bp->ffwd) t->ratio = 1;
-          r = ease_ratio (t->ratio);
+          r = ease (EASE_IN_OUT_SINE, t->ratio);
           t->pos.x = t->start_pos.x + r * (t->end_pos.x - t->start_pos.x);
           t->pos.y = t->start_pos.y + r * (t->end_pos.y - t->start_pos.y);
           t->pos.z = t->start_pos.z + r * (t->end_pos.z - t->start_pos.z);
index fbbc2c5e8ad4e40160ee5ebee85c1ba4bda095dc..d021c7597a6b0640e0e6de481f44c1f7837a3134 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 noof \- draw rotatey patterns
 .SH SYNOPSIS
-.B dangerball
+.B noof
 [\-\-display \fIhost:display.screen\fP]
 [\-\-visual \fIvisual\fP]
 [\-\-window]
index 0408760f3389a7818ba620093a4e584c697086d4..9ecb85d82815fc4d263aab55a9e72ba5cae96280 100644 (file)
@@ -92,7 +92,7 @@ Select a new polyhedron at random.
 .B + \fIor\fP >
 Select the next-higher-numbered polyhedron.
 .TP 12
-.B - \fIor\fP <
+.B \- \fIor\fP <
 Select the next-lower-numbered polyhedron.
 .TP 12
 .B ESC \fIor\fP ^C
index 4a5a26a52bd9e44a67211fd11e7c0e7342a462be..8d4b7adf0e9af19685ab2c6229cba66d194c35f5 100644 (file)
@@ -1,4 +1,4 @@
-/* raverhoop, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+/* raverhoop, Copyright © 2016-2025 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
@@ -22,6 +22,7 @@
 #include "colors.h"
 #include "rotator.h"
 #include "gltrackball.h"
+#include "easing.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -311,25 +312,6 @@ draw_lights (ModeInfo *mi)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.35;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static void
 tick_oscillators (ModeInfo *mi)
 {
@@ -345,7 +327,7 @@ tick_oscillators (ModeInfo *mi)
       if (a->ratio > 1)
         a->ratio = 1;
 
-      *a->var = a->from + (a->to - a->from) * ease_ratio (a->ratio);
+      *a->var = a->from + (a->to - a->from) * ease (EASE_IN_OUT_SINE, a->ratio);
 
       if (a->ratio < 1)                        /* mid cycle */
         prev = a;
index bf81bcd56664190cd4b5dce140e0e19c568e98a8..2cfa761924beec5c982c765e0ef71bfffb013cca 100644 (file)
@@ -1,4 +1,4 @@
-/* skulloop, Copyright © 2023-2024 Jamie Zawinski <jwz@jwz.org>
+/* skulloop, Copyright © 2023-2025 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
@@ -30,6 +30,7 @@
 #include "gltrackball.h"
 #include "gllist.h"
 #include "texfont.h"
+#include "easing.h"
 
 #ifdef USE_GL /* whole file */
 
@@ -215,25 +216,6 @@ draw_obj (ModeInfo *mi, obj *o)
 }
 
 
-static double
-ease_fn (double r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static double
-ease_ratio (double r)
-{
-  double ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static void
 draw_objs (ModeInfo *mi)
 {
@@ -242,7 +224,7 @@ draw_objs (ModeInfo *mi)
   obj cur;
   GLfloat s;
   int i;
-  GLfloat r = ease_ratio (bp->ratio);
+  GLfloat r = ease (EASE_IN_OUT_SINE, bp->ratio);
 
   cur.id = -1;
 # undef R
index 2328472801b4c59aa30fb082961b16ae86f4d74e..bb3e4b03271a6851fd56b02cead8479587d405b7 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "screenhackI.h"
 #include "sonar.h"
+#include "doubletime.h"
 #include "version.h"
 #include "async_netdb.h"
 
@@ -1319,23 +1320,6 @@ ping_free_bogie_data (sonar_sensor_data *sd, void *closure)
 }
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void
 free_bogie_after_lookup(sonar_sensor_data *ssd, sonar_bogie **sbp,
                         sonar_bogie **sb)
index 80f3fc686f182b2fbe15dbb9295edcd250485ca0..0dd78e04bde91a470ae0f22ee075a209ff6076ff 100644 (file)
@@ -1,4 +1,4 @@
-/* sonar, Copyright (c) 1998-2020 Jamie Zawinski and Stephen Martin
+/* sonar, Copyright © 1998-2025 Jamie Zawinski and Stephen Martin
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -87,6 +87,7 @@
 #include "gltrackball.h"
 #include "rotator.h"
 #include "texfont.h"
+#include "doubletime.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -658,23 +659,6 @@ point_in_wedge (GLfloat th, GLfloat low, GLfloat high)
 }
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void
 sweep (sonar_configuration *sp)
 {
index 9d78149450b05fdc2e8cd900e173f91baca84f9c..a290289ca48c27071c1c8a7a1142d02facaec65d 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "" "X Version 11"
 .SH NAME
-sphereeversion - Displays a sphere eversion.
+sphereeversion \- Displays a sphere eversion.
 .SH SYNOPSIS
 .B sphereeversion
 [\-\-display \fIhost:display.screen\fP]
index e5a3b4e97775805a85be9f7200214821cfb6a9b4..0a1776d4361f5d82926eabfbe41d8e2ada7653fd 100644 (file)
@@ -1,4 +1,4 @@
-/* squirtorus, Copyright (c) 2022 Jamie Zawinski <jwz@jwz.org>
+/* squirtorus, Copyright © 2022-2025 Jamie Zawinski <jwz@jwz.org>
  * Eat stars, shit rainbows.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -36,6 +36,7 @@
 #include "hsv.h"
 #include "spline.h"
 #include "normals.h"
+#include "easing.h"
 
 #include <ctype.h>
 
@@ -182,25 +183,6 @@ new_sphincter (ModeInfo *mi, sphincter *s, Bool early_p)
 }
 
 
-static GLfloat
-ease_fn (GLfloat r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
-  GLfloat ease = 0.35;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static void
 compute_unit_torus (ModeInfo *mi, double ratio, int slices1, int slices2)
 {
@@ -362,7 +344,7 @@ render_sphincter (ModeInfo *mi, spline *sp, int rez, int frame)
   int i, j;
 
   GLfloat sc = frame / (GLfloat) SPHINCTER_FRAMES;
-  sc = ease_ratio (sc);
+  sc = ease (EASE_IN_OUT_SINE, sc);
   sc *= SPHINCTER_OPEN;
 
   /* Compute each vertex */
index 8a957f191507978bdc3ae0397648109bfaa81686..43a4d64aacd73bb4cc1ea94045f3e1b155f853ad 100644 (file)
@@ -147,8 +147,10 @@ bitmap_to_texture (const texture_font_data *tfdata, Pixmap p,
   XImage *image = 0;
   unsigned char *data = (unsigned char *) calloc (w2 * 2, (h2 + 1));
   unsigned char *out = data;
+# ifndef HAVE_IPHONE
   GLint rowpack = 0;
   GLint alignment = 0;
+# endif /* HAVE_IPHONE */
 
   /* OpenGLES doesn't support GL_INTENSITY, so instead of using a
      texture with 1 byte per pixel, the intensity value, we have
@@ -260,11 +262,14 @@ bitmap_to_texture (const texture_font_data *tfdata, Pixmap p,
 
   image = 0;
 
+# ifndef HAVE_IPHONE
+  /* iOS gives us "invalid enum" when trying to read or write these. */
   glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowpack);
   glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
 
   glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
   glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+# endif /* HAVE_IPHONE */
 
   {
 # ifdef GL_INTENSITY
@@ -295,8 +300,10 @@ bitmap_to_texture (const texture_font_data *tfdata, Pixmap p,
       }
   }
 
+# ifndef HAVE_IPHONE
   glPixelStorei (GL_UNPACK_ROW_LENGTH, rowpack);
   glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
+# endif /* HAVE_IPHONE */
 
   {
     char msg[100];
index 966ccf0f68b1fd1ad39b259f88cb5b0d7dec9794..0ae98ab1f40d119fc76c0417a11b23a64c69f0e1 100644 (file)
@@ -1,4 +1,4 @@
-/* tronbit, Copyright (c) 2011-2014 Jamie Zawinski <jwz@jwz.org>
+/* tronbit, Copyright © 2011-2025 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
@@ -21,6 +21,7 @@
 #include "sphere.h"
 #include "rotator.h"
 #include "gltrackball.h"
+#include "doubletime.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -92,23 +93,6 @@ static argtype vars[] = {
 ENTRYPOINT ModeSpecOpt bit_opts = {countof(opts), opts, countof(vars), vars, NULL};
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static int
 make_bit (ModeInfo *mi, bit_state which)
 {
index 00a6052e3946c8a1ce54b8d077d8e5eaaf19181a..edca09597a8b4b167ca6e6dc8b326fc0e4d986f7 100644 (file)
@@ -1,4 +1,4 @@
-/* unknownpleasures, Copyright © 2013-2019 Jamie Zawinski <jwz@jwz.org>
+/* unknownpleasures, Copyright © 2013-2025 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
@@ -54,6 +54,8 @@
 #include "gltrackball.h"
 #include "ximage-loader.h"
 #include "grab-ximage.h"
+#include "easing.h"
+#include "doubletime.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
@@ -121,23 +123,6 @@ ENTRYPOINT ModeSpecOpt unk_opts = {countof(opts), opts, countof(vars), vars, NUL
 
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void
 parse_color (ModeInfo *mi, char *res, char *class, GLfloat *a)
 {
@@ -623,25 +608,6 @@ init_unk (ModeInfo *mi)
 }
 
 
-static double
-ease_fn (double r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static double
-ease_ratio (double r)
-{
-  double ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 ENTRYPOINT void
 draw_unk (ModeInfo *mi)
 {
@@ -703,8 +669,8 @@ draw_unk (ModeInfo *mi)
   for (i = 0; i < bp->count; i++)
     {
       int j = i * bp->frames * 2 + frame * 2;
-      GLfloat s  = ease_ratio (bp->heights[i]);
-      GLfloat s2 = ease_ratio (bp->heights[i] * 1.5);
+      GLfloat s  = ease (EASE_IN_OUT_SINE, bp->heights[i]);
+      GLfloat s2 = ease (EASE_IN_OUT_SINE, bp->heights[i] * 1.5);
 
       glPushMatrix();
       glScalef (1, 1, s);
index d2c3bb704f8e89da1f5717ef780f38ac0205d793..4f8e1e517c8fe0238b658f134229a99aee9e161f 100644 (file)
@@ -1,4 +1,4 @@
-/* voronoi, Copyright (c) 2007-2018 Jamie Zawinski <jwz@jwz.org>
+/* voronoi, Copyright © 2007-2025 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
@@ -23,6 +23,8 @@
 
 #ifdef USE_GL /* whole file */
 
+#include "doubletime.h"
+
 #define DEF_POINTS      "25"
 #define DEF_POINT_SIZE  "9"
 #define DEF_POINT_SPEED "1.0"
@@ -86,23 +88,6 @@ ENTRYPOINT ModeSpecOpt voronoi_opts =
   {countof(opts), opts, countof(vars), vars, NULL};
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static node *
 add_node (voronoi_configuration *vp, GLfloat x, GLfloat y)
 {
index 1d349206c703b85817b6c4ab43e4d38af15931c2..57c7f7b9caf18c370e56c1fb76bc186e0d93dd78 100644 (file)
@@ -206,7 +206,7 @@ void
 glXSwapBuffers (Display *dpy, GLXDrawable win)
 {
   egl_data *d = global_egl_kludge;
-  if (!d) abort();
+  if (!d) return; /* Called glXSwapBuffers before glXMakeCurrent? */
   if (! eglSwapBuffers (d->egl_display, d->egl_surface))
     abort();
 }
index ca82ea43400f61e2cdc22f7b944877a486b4e0e5..e070434643a142176f59e3570fa6e76e0d6cd5c2 100644 (file)
@@ -56,6 +56,7 @@ The minimum speed of each mass point. Default: 0.001
 .TP 8
 .B \-\-maxspeed \fInumber\fP
 The maximum speed of each mass point. Default: 0.02
+.TP 8
 .B \-\-delay \fInumber\fP
 Per-frame delay, in microseconds.  Default: 10000
 .TP 8
index fb9f9c202c4b9c663656911485a41d12ca576542..018d53f6256413e35412ea5506e7d73861b24c54 100644 (file)
@@ -15,6 +15,7 @@
 #include "screenhack.h"
 #include "analogtv.h"
 #include "asm6502.h"
+#include "doubletime.h"
 
 #include <string.h>
 
@@ -88,24 +89,6 @@ start_rand_bin_prog(machine_6502 *machine, struct state *st){
   m6502_start_eval_string(machine, demo_files[st->which], plot6502, st);
 }
 
-\f
-/*
- * double_time ()
- *
- * returns the current time as a floating-point value
- */
-static double double_time(void) {
-  struct timeval t;
-  double f;
-#if GETTIMEOFDAY_TWO_ARGS
-  gettimeofday(&t, NULL);
-#else
-  gettimeofday(&t);
-#endif
-  f = ((double)t.tv_sec) + t.tv_usec*1e-6;
-  return f;
-}
-
 static void *
 m6502_init (Display *dpy, Window window)
 {
index 67e75ffef8ec85a2e20a6f77727c4b3bf059d31d..21694309cb2e77e026049462a0def83392d35a39 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "5-May-2004" "X Version 11"
 .SH NAME
-m6502 - 6502 Microprocessor Emulator
+m6502 \- 6502 Microprocessor Emulator
 .SH SYNOPSIS
 .B m6502
 [\-\-display \fIhost:display.screen\fP] [\-\-foreground \fIcolor\fP]
index d9afcbbd1e1959099f9e71963cce06b4ae11e906..85b3016eaddb26da1b6fa9247ab18aebcd010f66 100644 (file)
@@ -1,8 +1,8 @@
 .TH XScreenSaver 1 "" "X Version 11"
 .SH NAME
-MetaBalls \- draws 2D metaballs
+metaballs \- draws 2D metaballs
 .SH SYNOPSIS
-.B MetaBalls
+.B metaballs
 [\-\-display \fIhost:display.screen\fP]
 [\-\-visual \fIvisual\fP]
 [\-\-window]
@@ -37,7 +37,7 @@ Draw on the specified window.
 Number of Colors.  Default: 256.
 .TP 8
 .B \-\-count \fInumber\fP
-Number of MetaBalls.   2 - 255.  Default: 10.
+Number of metaballs.   2 - 255.  Default: 10.
 .TP 8
 .B \-\-delay \fInumber\fP
 Per-frame delay, in microseconds.  Default: 5000 (0.005 seconds.).
@@ -46,10 +46,10 @@ Per-frame delay, in microseconds.  Default: 5000 (0.005 seconds.).
 Duration.  100 - 3000.  Default: 1000.
 .TP 8
 .B \-\-radius \fInumber\fP
-MetaBall Radius.  2 - 100.  Default: 100.
+metaball Radius.  2 - 100.  Default: 100.
 .TP 8
 .B \-\-delta \fInumber\fP
-MetaBall Movement.  1 - 20.  Default: 3.
+metaball Movement.  1 - 20.  Default: 3.
 .TP 8
 .B \-\-fps
 Display the current frame rate and CPU load.
index 2415b168b99b6d9a37f3f4fa9758163458656546..ceeedbbd720e7c2d92f43ae4778f5e155e6d952d 100644 (file)
@@ -57,6 +57,8 @@
 
 #include "screenhack.h"
 #include "analogtv.h"
+#include "doubletime.h"
+
 #include <time.h>
 #ifndef HAVE_JWXYZ
 # include <X11/keysym.h>
@@ -890,20 +892,6 @@ paint_net(struct state *st)
   }
 }
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
 static unsigned long
 pong_draw (Display *dpy, Window window, void *closure)
 {
index e307edde3c3b9ff49084ad255589f2960d2f39a1..c9106187f47f3b05a288e4da7740eb17524d3806 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "" "X Version 11"
 .SH NAME
-popsquares - pop artish pulsing color grid.
+popsquares \- pop artish pulsing color grid.
 .SH SYNOPSIS
 .B popsquares
 [\-\-display \fIhost:display.screen\fP]
index 7800b5d48b0675f95b34334eae341c5ee6145aa9..303d90b0fbf4e389402fc3dce77d0054fa365b7e 100644 (file)
@@ -1,4 +1,4 @@
-/* recanim, Copyright © 2014-2023 Jamie Zawinski <jwz@jwz.org>
+/* recanim, Copyright © 2014-2025 Jamie Zawinski <jwz@jwz.org>
  * Record animation frames of the running screenhack.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -12,6 +12,7 @@
 
 #include "screenhackI.h"
 #include "recanim.h"
+#include "doubletime.h"
 
 #ifndef HAVE_FFMPEG
 # error HAVE_FFMPEG is required
@@ -74,21 +75,6 @@ struct record_anim_state {
 };
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 /* Some of the hacks set their timing based on the real-world wall clock,
    so to make the animations record at a sensible speed, we need to slow
    down that clock by discounting the time taken up by snapshotting and
index f16c2d87a676cf842d11f38d76d9ccfa977be31b..53b184cc56b3e71f3326ce156383427c3e3f8aca 100644 (file)
@@ -1,4 +1,4 @@
-/* tessellimage, Copyright (c) 2014-2018 Jamie Zawinski <jwz@jwz.org>
+/* tessellimage, Copyright © 2014-2025 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
@@ -11,6 +11,7 @@
 
 #include "screenhack.h"
 #include "delaunay.h"
+#include "doubletime.h"
 
 #ifndef HAVE_JWXYZ
 # define XK_MISCELLANY
@@ -52,23 +53,6 @@ typedef struct {
 } voronoi_pa;
 
 
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void *
 tessellimage_init (Display *dpy, Window window)
 {
index 107bfe54d46411d9f40b36b14bd5a019e56c64dc..07a2a64d4b5d7db596e1f90b8cdf976491ad5d48 100644 (file)
@@ -1,4 +1,4 @@
-/* vfeedback, Copyright (c) 2018 Jamie Zawinski <jwz@jwz.org>
+/* vfeedback, Copyright © 2018-2025 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
@@ -25,6 +25,8 @@
 
 #include "screenhack.h"
 #include "analogtv.h"
+#include "easing.h"
+#include "doubletime.h"
 
 #include <time.h>
 
@@ -150,25 +152,6 @@ vfeedback_init (Display *dpy, Window window)
 }
 
 
-static double
-ease_fn (double r)
-{
-  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static double
-ease_ratio (double r)
-{
-  double ease = 0.5;
-  if      (r <= 0)     return 0;
-  else if (r >= 1)     return 1;
-  else if (r <= ease)  return     ease * ease_fn (r / ease);
-  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
-  else                 return r;
-}
-
-
 static XImage *
 grab_rectangle (struct state *st)
 {
@@ -190,7 +173,7 @@ grab_rectangle (struct state *st)
       double r = (st->svalue <    p ? st->svalue/p :
                   st->svalue >= 1-p ? (1-st->svalue)/p :
                   1);
-      double s = st->specular.s * ease_ratio (r * 2);
+      double s = st->specular.s * ease (EASE_IN_OUT_SINE, r * 2);
       XFillArc (st->dpy, st->pix, st->gc,
                 st->specular.x - s/2,
                 st->specular.y - s/2,
@@ -286,21 +269,6 @@ grab_rectangle (struct state *st)
 }
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static unsigned long
 vfeedback_draw (Display *dpy, Window window, void *closure)
 {
@@ -312,11 +280,14 @@ vfeedback_draw (Display *dpy, Window window, void *closure)
   switch (st->state) {
   case POWERUP: case IDLE: break;
   case MOVE:
-    st->rect.x  = st->orect.x  + st->dx  * ease_ratio (st->value);
-    st->rect.y  = st->orect.y  + st->dy  * ease_ratio (st->value);
-    st->rect.th = st->orect.th + st->dth * ease_ratio (st->value);
-    st->rect.w  = st->orect.w * (1 + (st->ds * ease_ratio (st->value)));
-    st->rect.h  = st->orect.h * (1 + (st->ds * ease_ratio (st->value)));
+    {
+      double v = ease (EASE_IN_OUT_SINE, st->value);
+      st->rect.x  = st->orect.x  + st->dx  * v;
+      st->rect.y  = st->orect.y  + st->dy  * v;
+      st->rect.th = st->orect.th + st->dth * v;
+      st->rect.w  = st->orect.w * (1 + (st->ds * v));
+      st->rect.h  = st->orect.h * (1 + (st->ds * v));
+    }
     break;
   default:
     abort();
index 7172247b2d76b5677a0c635d18da572b5fb1cd08..5f693447a24906f32eb0eb477d0b01af8b011864 100755 (executable)
@@ -53,7 +53,7 @@ BEGIN { eval 'use LWP::Simple; use LWP::UserAgent;' }
 
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.70 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.71 $' =~ m/\s(\d[.\d]+)\s/s);
 
 my $verbose = 0;
 
@@ -102,6 +102,7 @@ my $min_image_height = 500;
 
 my @all_files = ();         # list of "good" files we've collected
 my %seen_inodes;            # for breaking recursive symlink loops
+my $setfattr = 'setfattr';
 
 # For diagnostic messages:
 #
@@ -113,6 +114,17 @@ my $skip_count_stat = 0;    # number of files skipped after stat
 my $config_file = $ENV{HOME} . "/.xscreensaver";
 my $image_directory = undef;
 
+sub which($) {
+  my ($cmd) = @_;
+  if ($cmd =~ m@^\./|^/@) {
+    return undef unless (-x $cmd);
+  }
+  foreach my $dir (split (/:/, $ENV{PATH})) {
+    my $cmd2 = "$dir/$cmd";
+    return $cmd2 if (-x "$cmd2");
+  }
+  return undef;
+}
 
 sub find_all_files($);
 sub find_all_files($) {
@@ -532,9 +544,17 @@ sub parse_feed($) {
 
   foreach my $item (@items) {
     my $iurl = undef;
+    my $title = undef;
     my $id = undef;
     my $kind = '?';
 
+    ($title) = ($item =~ m@<TITLE\b[^<>]*>(.*?)</TITLE>@si);
+    if ($title) {
+      $title =~ s/<.*?>//gs;
+      $title = html_unquote ($title);
+      $title =~ s/^\s+|\s+$//gs;
+    }
+
     # The <media:group> container groups the same content in different
     # representations.  So first, edit each of those to contain only the
     # highest resolution child.
@@ -668,7 +688,7 @@ sub parse_feed($) {
       my $o = $ids{$id};
       if (! $o) {
         $ids{$id} = $iurl;
-        my @P = ($iurl, $id);
+        my @P = ($iurl, $id, $title);
         push @imgs, \@P;
         print STDERR "$progname:   $kind: $iurl\n" if ($verbose > 4);
       } elsif ($iurl ne $o) {
@@ -1059,6 +1079,47 @@ sub download_image($$$) {
 }
 
 
+# Write some xattrs on the file saying where we downloaded it from:
+# "user.xdg.origin.url" and "user.dublincore.title".
+#
+sub store_xattrs($$$) {
+  my ($file, $url, $title) = @_;
+
+  # Sometimes we have 'setfattr', sometimes 'xattr', sometimes neither.
+  # And they take different command-line options. Yay!
+  #
+  # Also, the macOS and Linux versions of 'xattr' have similar but not
+  # identical options (but close enough for our purposes).  The macOS
+  # version is a binary while the Linux version is a Python script.
+  # Mac weirdness is due to resource forks.
+  #
+  # What about BSD? Solaris? Who knows!
+  #
+  # There's also the File::ExtAttr perl module, but it is not installed
+  # by default, so using that would not improve matters in any way.
+
+  return unless $setfattr;
+
+  if ($url) {
+    my $key = 'user.xdg.origin.url';
+    my @cmd = ($setfattr =~ m/setfattr/
+               ? ($setfattr, '-n', $key, '-v', $url, $file)    # setfattr
+               : ($setfattr, '-w', $key,       $url, $file));  # xattr
+    print STDERR "$progname: exec: @cmd\n" if ($verbose);
+    system (@cmd);  # Ignore errors
+  }
+
+  if ($title) {
+    my $key = 'user.dublincore.title';
+    my @cmd = ($setfattr =~ m/setfattr/
+               ? ($setfattr, '-n', $key, '-v', $title, $file)  # setfattr
+               : ($setfattr, '-w', $key,       $title, $file));        # xattr
+    print STDERR "$progname: exec: @cmd\n" if ($verbose);
+    system (@cmd);  # Ignore errors
+  }
+}
+
+
 sub mirror_feed($) {
   my ($url) = @_;
 
@@ -1144,9 +1205,12 @@ sub mirror_feed($) {
     my @urls = parse_feed ($url);
     print STDERR "$progname: " . ($#urls + 1) . " images\n"
       if ($verbose > 1);
+
+    $setfattr = which ('setfattr') || which ('xattr');
+
     my %seen_src_urls;
     foreach my $p (@urls) {
-      my ($furl, $id) = @$p;
+      my ($furl, $id, $title) = @$p;
       $furl = expand_url ($furl, $url);
 
       # No need to download the same image twice, even if it was in the feed
@@ -1158,6 +1222,8 @@ sub mirror_feed($) {
       next unless $f;
       $files{$f} = 1;    # Got it, don't delete
       $count++;
+
+      store_xattrs ("$dir/$f", $furl, $title);
     }
 
     my $empty_p = ($count <= 0);
index 754e6b116e090437ffc1f9fa9a3d686a71fd9961..ebf1d531be739cf761c8140694495e86b47e66ad 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "20-Mar-2005 (4.21)" "X Version 11"
 .SH NAME
-xscreensaver-getimage-file - select a random image file for use by screen savers
+xscreensaver-getimage-file \- select a random image file for use by screen savers
 .SH SYNOPSIS
 .B xscreensaver-getimage-file
 [\--verbose]
index 8edf5184a894781f90c17b96ec79365430ffd077..f2aff607964912b822fda4da2702a7e16b535870 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "20-Mar-2005 (4.21)" "X Version 11"
 .SH NAME
-xscreensaver-getimage-video - grab a video still frame for use by screen savers
+xscreensaver-getimage-video \- grab a video still frame for use by screen savers
 .SH SYNOPSIS
 .B xscreensaver-getimage-video
 [\--verbose]
index 39eb8722ac85601a9f5cd83c78be78249710e0f0..29a2cb925b4986512c0f328141d689a34f88b964 100644 (file)
 # include <sys/wait.h>         /* for waitpid() and associated macros */
 #endif
 
+#ifdef HAVE_GETXATTR
+# include <sys/xattr.h>
+#endif
+
 #include "version.h"
 #include "../driver/blurb.h"
 #include "yarandom.h"
@@ -1902,6 +1906,40 @@ drawable_miniscule_p (Display *dpy, Drawable drawable)
 }
 
 
+/* Returns the URL and title of the given file, if present in xattrs.
+   Duplicated in grabclient.c.
+ */
+static void
+get_file_xattrs (const char *file, char **urlP, char **titleP)
+{
+# ifdef HAVE_GETXATTR
+
+#  ifdef XATTR_ADDITIONAL_OPTIONS
+#   define GETXATTR(F,K,B,S) getxattr (F, K, B, S, 0, 0)
+#  else
+#   define GETXATTR(F,K,B,S) getxattr (F, K, B, S)
+#  endif
+
+  char url[1024], title[1024];
+  ssize_t s;
+
+  s = GETXATTR (file, "user.xdg.origin.url", url, sizeof(url)-1);
+  if (s > 0)
+    {
+      url[s] = 0;
+      *urlP = strdup (url);
+    }
+
+  s = GETXATTR (file, "user.dublincore.title", title, sizeof(title)-1);
+  if (s > 0)
+    {
+      title[s] = 0;
+      *titleP = strdup (title);
+    }
+# endif /* HAVE_GETXATTR */
+}
+
+
 /* Grabs an image (from a file, video, or the desktop) and renders it on
    the Drawable.  If 'file' is specified, always use that file.  Otherwise,
    select randomly, based on the other arguments.
@@ -1921,6 +1959,8 @@ get_image (Screen *screen,
   grab_type which = GRAB_BARS;
   struct stat st;
   const char *file_prop = 0;
+  char *xattr_url   = 0;
+  char *xattr_title = 0;
   char *absfile = 0;
   XRectangle geom = { 0, 0, 0, 0 };
 
@@ -2081,6 +2121,7 @@ get_image (Screen *screen,
                           verbose_p, &geom))
         goto COLORBARS;
       file_prop = file;
+      get_file_xattrs (file, &xattr_url, &xattr_title);
       break;
 
     case GRAB_VIDEO:
@@ -2096,7 +2137,10 @@ get_image (Screen *screen,
 
   {
     Atom a = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_FILENAME, False);
-    if (file_prop && *file_prop)
+    if (xattr_url)
+      XChangeProperty (dpy, window, a, XA_STRING, 8, PropModeReplace, 
+                       (unsigned char *) xattr_url, strlen(xattr_url));
+    else if (file_prop && *file_prop)
       {
         char *f2 = strdup (file_prop);
 
@@ -2105,11 +2149,6 @@ get_image (Screen *screen,
         char *slash = strrchr (f2, '/');
         char *dot = strrchr ((slash ? slash : f2), '.');
         if (dot) *dot = 0;
-        /* Replace slashes with newlines */
-        /* while ((dot = strchr(f2, '/'))) *dot = '\n'; */
-        /* Replace slashes with spaces */
-        /* while ((dot = strchr(f2, '/'))) *dot = ' '; */
-
         XChangeProperty (dpy, window, a, XA_STRING, 8, PropModeReplace, 
                          (unsigned char *) f2, strlen(f2));
         free (f2);
@@ -2117,6 +2156,13 @@ get_image (Screen *screen,
     else
       XDeleteProperty (dpy, window, a);
 
+    a = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_TITLE, False);
+    if (xattr_title)
+      XChangeProperty (dpy, window, a, XA_STRING, 8, PropModeReplace, 
+                       (unsigned char *) xattr_title, strlen(xattr_title));
+    else
+      XDeleteProperty (dpy, window, a);
+
     a = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_GEOMETRY, False);
     if (geom.width > 0)
       {
@@ -2132,6 +2178,9 @@ get_image (Screen *screen,
   if (absfile) free (absfile);
 
   XSync (dpy, False);
+
+  if (xattr_url)   free (xattr_url);
+  if (xattr_title) free (xattr_title);
 }
 
 
index 155c45c8046a894bf1d68c0516f3edb417f759f5..62f019055a0d48ba1399ebac4ad494bac5190227 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "20-Mar-2005 (4.21)" "X Version 11"
 .SH NAME
-xscreensaver-getimage - loads a randomly-selected image onto an X11 Drawable
+xscreensaver-getimage \- loads a randomly-selected image onto an X11 Drawable
 for use by screen savers
 .SH SYNOPSIS
 .B xscreensaver-getimage
index a56387915e8299fe960f57206f2f24d3b34a6cd3..b20f918fd53c4191de298ea22ef8476d1cd9282f 100644 (file)
@@ -1,6 +1,6 @@
 .TH XScreenSaver 1 "20-Mar-2005 (4.21)" "X Version 11"
 .SH NAME
-xscreensaver\-text - prints some text to stdout, for use by screen savers.
+xscreensaver\-text \- prints some text to stdout, for use by screen savers.
 .SH SYNOPSIS
 .B xscreensaver\-text
 [\--verbose]
index ad7ec554f8f1a09da438d166fd9ae990dd27e3a7..8523bf62b3e420c68172cd6333af0b537bd2f5b8 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright © 2016-2021 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 2016-2025 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
@@ -51,6 +51,7 @@
 #include "textclient.h"
 #include "grabclient.h"
 #include "pow2.h"
+#include "doubletime.h"
 
 
 #undef countof
@@ -715,24 +716,6 @@ doinit (jobject jwxyz_obj, struct running_hack *rh, JNIEnv *env,
 
 #undef DEBUG_FPS
 
-#ifdef DEBUG_FPS
-
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-#endif
-
 // Animates a single frame of the current hack.
 //
 static jlong
index 1e81ab86a2ee5bb9f62adfa99c6e4cdedce8f568..bec5f70a8e51205e899313cc442aff11bf49ea0c 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2006-2017 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 2006-2025 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
@@ -29,6 +29,7 @@
 #include <sys/select.h>
 #include "jwxyz.h"
 #include "jwxyz-timers.h"
+#include "doubletime.h"
 
 #ifdef HAVE_ANDROID
 extern void Log(const char *format, ...);
@@ -102,21 +103,6 @@ struct jwxyz_XtInputId {
 };
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 jwxyz_sources_data *
 jwxyz_sources_init (XtAppContext app)
 {
index 03e816f6dce55651e1081a1f96cc32b34ccccde0..123a28a3685b69ba907142f6f8d6d7a094fc5e06 100644 (file)
@@ -61,8 +61,6 @@
 #       The install-data-yes rule made no provision for this, and would
 #       just error out when the .gmo files were not there.
 #
-#     - $(DESTDIR) was being used where $(install_prefix) should have been.
-#
 #     - For xscreensaver, $(prefix) is generally /usr/X11R6/, but some files
 #      need to go under /usr/ instead of under /usr/X11R6/ -- for those, we
 #      use @PO_DATADIR@ instead of @prefix@.  So I changed $(datadir) and
@@ -111,7 +109,7 @@ localedir = $(datadir)/locale
 gnulocaledir = $(localedir)
 #gettextsrcdir = $(prefix)/share/glib-2.0/gettext/po
 subdir = po
-DESTDIR = $(install_prefix)
+DESTDIR = 
 
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -225,7 +223,7 @@ install-data-yes: all
            *)     destdir=$(localedir);; \
          esac; \
          lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
-         dir=$(install_prefix)$$destdir/$$lang/LC_MESSAGES; \
+         dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \
          dest=$$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \
          if test -r $$cat -o -r $$cat.m; then \
            echo $(MKINSTALLDIRS) $$dir; \
@@ -256,10 +254,10 @@ uninstall:
          cat=`basename $$cat`; \
          lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
          suffix="$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \
-         for f in $(install_prefix)$(localedir)/$$suffix \
-                  $(install_prefix)$(localedir)/$$suffix.m \
-                  $(install_prefix)$(gnulocaledir)/$$suffix \
-                  $(install_prefix)$(gnulocaledir)/$$suffix.m; do \
+         for f in $(DESTDIR)$(localedir)/$$suffix \
+                  $(DESTDIR)$(localedir)/$$suffix.m \
+                  $(DESTDIR)$(gnulocaledir)/$$suffix \
+                  $(DESTDIR)$(gnulocaledir)/$$suffix.m; do \
            if [ -f $$f ]; then \
              echo rm -f $$f; \
                   rm -f $$f; \
index d3ea9ee684b939ceb21f3395b7c2edb4751767a9..f7fd69903e9dc22f2e7d8bd12a2c0539e2b065e9 100644 (file)
@@ -1,4 +1,4 @@
-# Auto-generated: Mon Jul  7 12:46:55 PDT 2025
+# Auto-generated: Tue Dec  2 17:18:02 PST 2025
 driver/demo-Gtk-conf.c
 driver/demo-Gtk.c
 driver/demo.ui
diff --git a/po/ka.po b/po/ka.po
new file mode 100644 (file)
index 0000000..e1a4d14
--- /dev/null
+++ b/po/ka.po
@@ -0,0 +1,10495 @@
+# Georgian translation for xscreensaver.
+# Copyright (C) 2025 xscreensaver's authors
+# This file is distributed under the same license as the xscreensaver package.
+# Ekaterine Papava <papava.e@gtu.ge>, 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: xscreensaver\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-02-21 14:05+0100\n"
+"PO-Revision-Date: 2025-09-26 12:56+0200\n"
+"Last-Translator: Ekaterine Papava <papava.e@gtu.ge>\n"
+"Language-Team: Georgian <(nothing)>\n"
+"Language: ka\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 3.7\n"
+
+#: ../driver/demo-Gtk-conf.c:931
+msgid "Browse..."
+msgstr "ამორჩევა..."
+
+#: ../driver/demo-Gtk-conf.c:1117
+msgid "Select file."
+msgstr "აირჩიეთ ფაილი."
+
+#: ../driver/demo-Gtk.c:612 ../driver/demo-Gtk.c:619
+msgid "_OK"
+msgstr "_დიახ"
+
+#: ../driver/demo-Gtk.c:616
+msgid "Launch"
+msgstr "გაშვება"
+
+#: ../driver/demo-Gtk.c:617 ../driver/demo-Gtk.c:618
+msgid "Kill"
+msgstr "მოკვლა"
+
+#: ../driver/demo-Gtk.c:621 ../driver/demo-Gtk.c:1894 ../driver/demo-Gtk.c:2128
+msgid "_Cancel"
+msgstr "გაუქმება"
+
+#: ../driver/demo-Gtk.c:686 ../driver/demo-Gtk.c:726
+msgid "Unknown error!"
+msgstr "უცნობი შეცდომა!"
+
+#: ../driver/demo-Gtk.c:687 ../driver/demo-Gtk.c:727 ../driver/demo-Gtk.c:850
+#: ../driver/demo-Gtk.c:981 ../driver/demo-Gtk.c:1010 ../driver/demo-Gtk.c:1016
+#: ../driver/demo-Gtk.c:1217 ../driver/demo-Gtk.c:2176
+#: ../driver/demo-Gtk.c:2183 ../driver/demo-Gtk.c:4346
+msgid "Error"
+msgstr "შეცდომა"
+
+#: ../driver/demo-Gtk.c:738 ../driver/demo-Gtk.c:4132
+#, c-format
+msgid ""
+"The XScreenSaver daemon doesn't seem to be running\n"
+"on display \"%.25s\".  Launch it now?"
+msgstr ""
+"როგორც ჩანს, ეკრანზე \"%.25s\" XScreenSaver-ის დემონი\n"
+"გაშვებული არაა.  გავუშვა ის ახლა?"
+
+#: ../driver/demo-Gtk.c:741 ../driver/demo-Gtk.c:1840 ../driver/demo-Gtk.c:2066
+#: ../driver/demo-Gtk.c:3154 ../driver/demo-Gtk.c:4200
+#: ../driver/demo-Gtk.c:4222 ../driver/demo-Gtk.c:4226
+#: ../driver/demo-Gtk.c:4234
+msgid "Warning"
+msgstr "შეტყობინება"
+
+#: ../driver/demo-Gtk.c:851
+msgid "No Help URL has been specified.\n"
+msgstr "დახმარების ბმული მითითებული არაა.\n"
+
+#: ../driver/demo-Gtk.c:970
+msgid ""
+"The xscreensaver daemon did not start up properly.\n"
+"\n"
+msgstr ""
+"XScreenSaver-ის დემონი სწორად არ გაეშვა.\n"
+"\n"
+
+#: ../driver/demo-Gtk.c:975
+msgid ""
+"You are running as root.  Don't do that.  Instead, you should\n"
+"log in as a normal user and use `sudo' as necessary."
+msgstr ""
+"შესული ბრძანდებით, როგორც root.  ნუ შვრებით ამას.  ამის მაგიერ,\n"
+"შედით ჩვეულებრივი მომხმარებლით და გამოიყენეთ 'sudo', როცა ეს დაგჭირდებათ."
+
+#: ../driver/demo-Gtk.c:979
+msgid "Please check your $PATH and permissions."
+msgstr "შეამოწმეთ თქვენი $PATH და თქვენი წვდომები."
+
+#: ../driver/demo-Gtk.c:1011
+msgid "Couldn't determine init file name!\n"
+msgstr "შეუძლებელია init ფაილის სახელის დადგენა!\n"
+
+#: ../driver/demo-Gtk.c:1015
+#, c-format
+msgid "Couldn't write %s\n"
+msgstr "%s-ის ჩაწერა შეუძლებელია\n"
+
+#: ../driver/demo-Gtk.c:1215
+#, c-format
+msgid "Unparsable time format: \"%.100s\"\n"
+msgstr "არასამუშავებადი დროის ფორმატი: \"%.100s\"\n"
+
+#: ../driver/demo-Gtk.c:1822
+msgid "Image directory is unset"
+msgstr "გამოსახულებების საქაღალდე დაყენებული არაა"
+
+#: ../driver/demo-Gtk.c:1827
+msgid "Image directory does not exist"
+msgstr "გამოსახულებების საქაღალდე არ არსებობს"
+
+#: ../driver/demo-Gtk.c:1829
+msgid "Image directory is empty"
+msgstr "გამოსახულებების საქაღალდე ცარიელია"
+
+#: ../driver/demo-Gtk.c:1834
+#, c-format
+msgid ""
+"%.100s:\n"
+"\n"
+"        %.100s\n"
+"\n"
+"Select the 'Advanced' tab and choose a directory with some\n"
+"pictures in it, or you're going to see a lot of boring colorbars!"
+msgstr ""
+"%.100s:\n"
+"\n"
+"        %.100s\n"
+"\n"
+"აირჩიეთ 'დამატებით' და აირჩიეთ საქაღალდე, რომლებშიც\n"
+"სურათებია და მოსაბეზრებელ პანელებს აღარ დაინახავთ!"
+
+#: ../driver/demo-Gtk.c:1891
+msgid "XScreenSaver Image Cache"
+msgstr "XScreenSaver-ის გამოსახულებების კეში"
+
+#: ../driver/demo-Gtk.c:1897
+#, c-format
+msgid "Populating image cache for \"%.100s\"..."
+msgstr "გამოსახულებების კეშის შევსება \"%.100s\"-სთვის..."
+
+#: ../driver/demo-Gtk.c:2129
+msgid "_Select"
+msgstr "_აირჩიეთ"
+
+#: ../driver/demo-Gtk.c:2175
+#, c-format
+msgid "Directory does not exist: \"%.100s\"\n"
+msgstr "საქაღალდე არ არსებობს: \"%.100s\"\n"
+
+#: ../driver/demo-Gtk.c:2182
+#, c-format
+msgid "File does not exist: \"%.100s\"\n"
+msgstr "ფაილი არ არსებობს: \"%.100s\"\n"
+
+#: ../driver/demo-Gtk.c:2218
+msgid "Please select the image directory."
+msgstr "აირჩიეთ გამოსახულებების საქაღალდე."
+
+#: ../driver/demo-Gtk.c:2248
+msgid "Please select a text file."
+msgstr "აირჩიეთ ტექსტური ფაილი."
+
+#: ../driver/demo-Gtk.c:2266
+msgid "Please select a text-generating program."
+msgstr "აირჩიეთ ტექსტის დამაგენერირებელი პროგრამა."
+
+#: ../driver/demo-Gtk.c:2445
+msgid "Use"
+msgstr "გამოყენება"
+
+#: ../driver/demo-Gtk.c:2455
+msgid "Screen Saver"
+msgstr "ეკრანის დაცვა"
+
+#: ../driver/demo-Gtk.c:2750
+msgid "Display Power Management (not supported by this display)"
+msgstr "ეკრანის კვების მართვა (ამ ეკრანს მიერ მხარდაჭერილი არა)"
+
+#: ../driver/demo-Gtk.c:2910
+msgid "Restart Daemon"
+msgstr "დემონის გადატვირთვა"
+
+#: ../driver/demo-Gtk.c:2911
+msgid "Launch Daemon"
+msgstr "დემონის გაშვება"
+
+#: ../driver/demo-Gtk.c:2954
+msgid "Blank Screen"
+msgstr "ეკრანის გასუფთავება"
+
+#: ../driver/demo-Gtk.c:2960
+msgid "Screen Saver Disabled"
+msgstr "ეკრანის შემნახველის გამორთულია"
+
+#: ../driver/demo-Gtk.c:2983
+msgid "Preview"
+msgstr "მინიატურა"
+
+#: ../driver/demo-Gtk.c:2996
+#, c-format
+msgid "%s: %.100s Settings"
+msgstr "%s: %.100s-ის მორგება"
+
+#: ../driver/demo-Gtk.c:3009
+msgid "Any"
+msgstr "ნებისმიერი"
+
+#: ../driver/demo-Gtk.c:3153
+#, c-format
+msgid "file \"%s\" has changed, reloading.\n"
+msgstr "ფაილი \"%s\" შეიცვალა. თავიდან ჩატვირთვა.\n"
+
+#: ../driver/demo-Gtk.c:4142
+#, c-format
+msgid ""
+"%s is running as user \"%s\" on host \"%s\".\n"
+"But the xscreensaver managing display \"%.25s\"\n"
+"is running as user \"%s\" on host \"%s\".\n"
+"\n"
+"Since they are different users, they won't be reading/writing\n"
+"the same ~/.xscreensaver file, so %s isn't\n"
+"going to work right.\n"
+"\n"
+"You should either re-run %s as \"%s\", or re-run\n"
+"xscreensaver as \"%s\".\n"
+"\n"
+"Restart the xscreensaver daemon now?\n"
+msgstr ""
+
+#: ../driver/demo-Gtk.c:4166
+#, c-format
+msgid ""
+"%s is running as user \"%s\" on host \"%s\".\n"
+"But the xscreensaver managing display \"%s\"\n"
+"is running as user \"%s\" on host \"%s\".\n"
+"\n"
+"If those two machines don't share a file system (that is,\n"
+"if they don't see the same ~%s/.xscreensaver file) then\n"
+"%s won't work right.\n"
+"\n"
+"Restart the daemon on \"%s\" as \"%s\" now?\n"
+msgstr ""
+
+#: ../driver/demo-Gtk.c:4187
+#, c-format
+msgid ""
+"This is %s version %s.\n"
+"But the xscreensaver managing display \"%s\"\n"
+"is version %s.  This could cause problems.\n"
+"\n"
+"Restart the xscreensaver daemon now?\n"
+msgstr ""
+
+#: ../driver/demo-Gtk.c:4217
+#, c-format
+msgid ""
+"The GNOME screen saver daemon (%s) appears to be running.\n"
+"It must be stopped for XScreenSaver to work properly.\n"
+"\n"
+"Stop the \"%s\" daemon now?\n"
+msgstr ""
+
+#: ../driver/demo-Gtk.c:4227
+msgid ""
+"The KDE screen saver daemon appears to be running.\n"
+"It must be stopped for XScreenSaver to work properly.\n"
+"\n"
+"Stop the KDE screen saver daemon now?\n"
+msgstr ""
+
+#: ../driver/demo-Gtk.c:4235
+msgid ""
+"You are running Wayland rather than the X Window System.\n"
+"\n"
+"Under Wayland, idle-detection fails when non-X11 programs\n"
+"are selected, meaning the screen may blank prematurely.\n"
+"Also, locking is impossible.\n"
+"\n"
+"See the XScreenSaver manual for instructions on\n"
+"configuring your system to use X11 instead of Wayland.\n"
+msgstr ""
+
+#: ../driver/demo-Gtk.c:4347
+msgid "no `manualCommand' resource set."
+msgstr "რესურსი 'manualCommand' დაყენებული არაა."
+
+#: ../driver/demo-Gtk.c:4589 ../driver/demo-Gtk.c:4623
+msgid "No description available."
+msgstr "აღწერის გარეშე."
+
+#: ../driver/dialog.c:1056
+#, c-format
+msgid ""
+"Copyright © 1991-%.4s by\n"
+"Jamie Zawinski <jwz@jwz.org>"
+msgstr ""
+"Copyright © 1991-%.4s by\n"
+"Jamie Zawinski <jwz@jwz.org>"
+
+#: ../driver/dialog.c:1377
+msgid ""
+"Update available!\n"
+"This version is very old.\n"
+msgstr ""
+"ხელმისაწვდომია განახლება!\n"
+"ეს ვერსია ძალიან ძველია.\n"
+
+#: ../driver/dialog.c:1389
+msgid "PRE-RELEASE VERSION"
+msgstr "წინასწარი რელიზი"
+
+#: ../driver/dialog.c:1426
+msgid ""
+"DEBUG MODE:\n"
+"All keystrokes are being logged to stderr.\n"
+msgstr ""
+"გამართვის რეჟიმი:\n"
+"ყველა ღილაკის დაწოლა stderr-ზე გამოჩნდება.\n"
+
+#: ../driver/dialog.c:1475
+msgid "Username:"
+msgstr "მომხმარებელი:"
+
+#: ../driver/dialog.c:1506
+msgid "Checking..."
+msgstr "შემოწმება…"
+
+#: ../driver/dialog.c:1586
+msgid "Settings"
+msgstr "მორგება"
+
+#: ../driver/dialog.c:1601
+msgid "Help"
+msgstr "დახმარება"
+
+#: ../driver/dialog.c:1615
+msgid "New Login"
+msgstr "ახალი შესვლის დეტალები"
+
+#: ../driver/dialog.c:1627
+msgid "OK"
+msgstr "დიახ"
+
+#: ../driver/dialog.c:2597
+msgid "Password initialization failed"
+msgstr "პაროლის ინიციალიზაცია ჩავარდა"
+
+#: ../driver/dialog.c:2599
+msgid "Authentication failed (Caps Lock?)"
+msgstr "ავთენტკაცია ჩავარდა (Caps Lock?)"
+
+#: ../driver/dialog.c:2601
+msgid "Authentication failed!"
+msgstr "ავთენტიკაციის შეცდომა!"
+
+#: ../driver/dialog.c:2621
+#, c-format
+msgid "%d days ago"
+msgstr "%d დღის წინ"
+
+#: ../driver/dialog.c:2622
+#, c-format
+msgid "%d hours ago"
+msgstr "%d საათის წინ"
+
+#: ../driver/dialog.c:2623
+#, c-format
+msgid "%d minutes ago"
+msgstr "%d წუთის წინ"
+
+#: ../driver/dialog.c:2624
+#, c-format
+msgid "just now"
+msgstr "ახლახანს"
+
+#: ../driver/dialog.c:2627
+#, c-format
+msgid "There has been 1 failed login attempt, %s."
+msgstr "1 ჩავარდნილი შესვლის მცდელობა. %s."
+
+#: ../driver/dialog.c:2630
+#, c-format
+msgid "There have been %d failed login attempts, oldest %s."
+msgstr "%d ჩავარდნილი შესვლის შეცდომა. უძველესი: %s."
+
+#: ../driver/subprocs.c:587
+msgid "is not installed"
+msgstr "დაყენებული არაა"
+
+#: ../driver/subprocs.c:589
+#, c-format
+msgid "crashed with status %d"
+msgstr "დასრულდა ავარიულად, სტატუსით %d"
+
+#. Expected notification after we killed it.
+#: ../driver/subprocs.c:606
+#, c-format
+msgid "exited normally with %.100s"
+msgstr "გამოვიდა ნორმალურად, სტატუსით %.100s"
+
+#. Unexpected signal.
+#: ../driver/subprocs.c:615
+#, c-format
+msgid "crashed with %.100s"
+msgstr "ავარიულად დასრულდა, %.100s-ით"
+
+#. Didn't exit, signal or stop; is this even possible?
+#: ../driver/subprocs.c:636
+#, c-format
+msgid "crashed mysteriously"
+msgstr "ავარიულად დასრულდა, მიზეზების გარეშე"
+
+#: ../driver/xscreensaver-settings.desktop.in.h:1
+msgid "XScreenSaver Settings"
+msgstr "XScreenSaver-ის მორგება"
+
+#: ../driver/xscreensaver-settings.desktop.in.h:2
+msgid "Change screensaver properties"
+msgstr "ეკრანის დამცველის მორგება"
+
+#: ../driver/xscreensaver.desktop.in.h:1
+msgid "XScreenSaver"
+msgstr "XScreenSaver"
+
+#: ../driver/xscreensaver.desktop.in.h:2
+msgid "XScreenSaver daemon: screen saver and locker"
+msgstr "დემონი XScreenSaver: ეკრანის შემნახველი და დამბლოკველი"
+
+#: ../hacks/config/abstractile.xml.h:1
+msgid "Abstractile"
+msgstr "აბსტრაქტული"
+
+#: ../hacks/config/abstractile.xml.h:2 ../hacks/config/anemone.xml.h:2
+#: ../hacks/config/apollonian.xml.h:10 ../hacks/config/atlantis.xml.h:5
+#: ../hacks/config/attraction.xml.h:24 ../hacks/config/blitspin.xml.h:2
+#: ../hacks/config/boing.xml.h:5 ../hacks/config/bouncingcow.xml.h:5
+#: ../hacks/config/boxed.xml.h:5 ../hacks/config/carousel.xml.h:5
+#: ../hacks/config/ccurve.xml.h:5 ../hacks/config/chompytower.xml.h:5
+#: ../hacks/config/circuit.xml.h:8 ../hacks/config/cityflow.xml.h:9
+#: ../hacks/config/companioncube.xml.h:5 ../hacks/config/covid19.xml.h:5
+#: ../hacks/config/crumbler.xml.h:5 ../hacks/config/cube21.xml.h:8
+#: ../hacks/config/cubenetic.xml.h:17 ../hacks/config/cubestack.xml.h:5
+#: ../hacks/config/cubestorm.xml.h:5 ../hacks/config/cubetwist.xml.h:5
+#: ../hacks/config/cubicgrid.xml.h:5 ../hacks/config/dangerball.xml.h:5
+#: ../hacks/config/deepstars.xml.h:5 ../hacks/config/discoball.xml.h:5
+#: ../hacks/config/dymaxionmap.xml.h:5 ../hacks/config/energystream.xml.h:2
+#: ../hacks/config/eruption.xml.h:10 ../hacks/config/esper.xml.h:5
+#: ../hacks/config/fliptext.xml.h:5 ../hacks/config/flyingtoasters.xml.h:5
+#: ../hacks/config/fontglide.xml.h:5 ../hacks/config/fuzzyflakes.xml.h:5
+#: ../hacks/config/gears.xml.h:5 ../hacks/config/geodesic.xml.h:14
+#: ../hacks/config/gflux.xml.h:5 ../hacks/config/gibson.xml.h:5
+#: ../hacks/config/glcells.xml.h:25 ../hacks/config/glknots.xml.h:5
+#: ../hacks/config/glmatrix.xml.h:8 ../hacks/config/glsnake.xml.h:11
+#: ../hacks/config/goop.xml.h:5 ../hacks/config/gravitywell.xml.h:5
+#: ../hacks/config/handsy.xml.h:5 ../hacks/config/headroom.xml.h:5
+#: ../hacks/config/hexadrop.xml.h:5 ../hacks/config/hexstrut.xml.h:5
+#: ../hacks/config/hilbert.xml.h:8 ../hacks/config/hydrostat.xml.h:5
+#: ../hacks/config/hyperball.xml.h:9 ../hacks/config/hypercube.xml.h:9
+#: ../hacks/config/hypnowheel.xml.h:2 ../hacks/config/interference.xml.h:5
+#: ../hacks/config/jigglypuff.xml.h:14 ../hacks/config/jigsaw.xml.h:5
+#: ../hacks/config/juggle.xml.h:5 ../hacks/config/juggler3d.xml.h:5
+#: ../hacks/config/kaleidocycle.xml.h:8 ../hacks/config/mapscroller.xml.h:5
+#: ../hacks/config/maze3d.xml.h:2 ../hacks/config/moebiusgears.xml.h:5
+#: ../hacks/config/nakagin.xml.h:5 ../hacks/config/peepers.xml.h:5
+#: ../hacks/config/penetrate.xml.h:2 ../hacks/config/petri.xml.h:16
+#: ../hacks/config/phosphor.xml.h:6 ../hacks/config/photopile.xml.h:12
+#: ../hacks/config/piecewise.xml.h:8 ../hacks/config/pinion.xml.h:5
+#: ../hacks/config/polyhedra.xml.h:5 ../hacks/config/pong.xml.h:2
+#: ../hacks/config/pyro.xml.h:2 ../hacks/config/quasicrystal.xml.h:5
+#: ../hacks/config/raverhoop.xml.h:11 ../hacks/config/razzledazzle.xml.h:5
+#: ../hacks/config/rocks.xml.h:8 ../hacks/config/rubik.xml.h:6
+#: ../hacks/config/rubikblocks.xml.h:8 ../hacks/config/skytentacles.xml.h:15
+#: ../hacks/config/slidescreen.xml.h:11 ../hacks/config/sonar.xml.h:5
+#: ../hacks/config/speedmine.xml.h:5 ../hacks/config/splitflap.xml.h:5
+#: ../hacks/config/squirtorus.xml.h:5 ../hacks/config/superquadrics.xml.h:5
+#: ../hacks/config/tangram.xml.h:8 ../hacks/config/topblock.xml.h:5
+#: ../hacks/config/tronbit.xml.h:5 ../hacks/config/twang.xml.h:8
+#: ../hacks/config/unicrud.xml.h:5 ../hacks/config/unknownpleasures.xml.h:8
+#: ../hacks/config/vigilance.xml.h:5 ../hacks/config/voronoi.xml.h:2
+#: ../hacks/config/winduprobot.xml.h:5 ../hacks/config/wormhole.xml.h:5
+#: ../hacks/config/xjack.xml.h:2
+msgid "Slow"
+msgstr "ნელი"
+
+#: ../hacks/config/abstractile.xml.h:3 ../hacks/config/anemone.xml.h:3
+#: ../hacks/config/apollonian.xml.h:11 ../hacks/config/attraction.xml.h:25
+#: ../hacks/config/boing.xml.h:6 ../hacks/config/boxed.xml.h:6
+#: ../hacks/config/covid19.xml.h:6 ../hacks/config/crumbler.xml.h:6
+#: ../hacks/config/cubestorm.xml.h:6 ../hacks/config/cubicgrid.xml.h:6
+#: ../hacks/config/deepstars.xml.h:6 ../hacks/config/discoball.xml.h:6
+#: ../hacks/config/energystream.xml.h:3 ../hacks/config/esper.xml.h:6
+#: ../hacks/config/fliptext.xml.h:6 ../hacks/config/fontglide.xml.h:6
+#: ../hacks/config/fuzzyflakes.xml.h:6 ../hacks/config/gears.xml.h:6
+#: ../hacks/config/glknots.xml.h:6 ../hacks/config/goop.xml.h:6
+#: ../hacks/config/gravitywell.xml.h:6 ../hacks/config/handsy.xml.h:6
+#: ../hacks/config/hexadrop.xml.h:6 ../hacks/config/hexstrut.xml.h:6
+#: ../hacks/config/hilbert.xml.h:11 ../hacks/config/hypnowheel.xml.h:5
+#: ../hacks/config/jigsaw.xml.h:6 ../hacks/config/juggle.xml.h:6
+#: ../hacks/config/juggler3d.xml.h:6 ../hacks/config/kaleidocycle.xml.h:9
+#: ../hacks/config/maze3d.xml.h:3 ../hacks/config/moebiusgears.xml.h:6
+#: ../hacks/config/peepers.xml.h:6 ../hacks/config/polyhedra.xml.h:6
+#: ../hacks/config/quasicrystal.xml.h:6 ../hacks/config/razzledazzle.xml.h:6
+#: ../hacks/config/skytentacles.xml.h:18 ../hacks/config/sonar.xml.h:6
+#: ../hacks/config/splitflap.xml.h:6 ../hacks/config/tessellimage.xml.h:6
+#: ../hacks/config/unknownpleasures.xml.h:9 ../hacks/config/vigilance.xml.h:6
+#: ../hacks/config/xjack.xml.h:3
+msgid "Speed"
+msgstr "სიჩქარე"
+
+#: ../hacks/config/abstractile.xml.h:4 ../hacks/config/anemone.xml.h:4
+#: ../hacks/config/apollonian.xml.h:12 ../hacks/config/atlantis.xml.h:7
+#: ../hacks/config/attraction.xml.h:26 ../hacks/config/blitspin.xml.h:4
+#: ../hacks/config/boing.xml.h:7 ../hacks/config/bouncingcow.xml.h:7
+#: ../hacks/config/boxed.xml.h:7 ../hacks/config/carousel.xml.h:7
+#: ../hacks/config/ccurve.xml.h:7 ../hacks/config/chompytower.xml.h:7
+#: ../hacks/config/circuit.xml.h:10 ../hacks/config/cityflow.xml.h:11
+#: ../hacks/config/companioncube.xml.h:7 ../hacks/config/covid19.xml.h:7
+#: ../hacks/config/crumbler.xml.h:7 ../hacks/config/cube21.xml.h:10
+#: ../hacks/config/cubenetic.xml.h:19 ../hacks/config/cubestack.xml.h:7
+#: ../hacks/config/cubestorm.xml.h:7 ../hacks/config/cubetwist.xml.h:7
+#: ../hacks/config/cubicgrid.xml.h:7 ../hacks/config/dangerball.xml.h:7
+#: ../hacks/config/deepstars.xml.h:7 ../hacks/config/discoball.xml.h:7
+#: ../hacks/config/dymaxionmap.xml.h:7 ../hacks/config/energystream.xml.h:4
+#: ../hacks/config/eruption.xml.h:12 ../hacks/config/esper.xml.h:7
+#: ../hacks/config/fliptext.xml.h:7 ../hacks/config/flyingtoasters.xml.h:7
+#: ../hacks/config/fontglide.xml.h:7 ../hacks/config/fuzzyflakes.xml.h:7
+#: ../hacks/config/gears.xml.h:7 ../hacks/config/geodesic.xml.h:16
+#: ../hacks/config/gflux.xml.h:7 ../hacks/config/gibson.xml.h:7
+#: ../hacks/config/glknots.xml.h:7 ../hacks/config/glmatrix.xml.h:10
+#: ../hacks/config/glsnake.xml.h:13 ../hacks/config/goop.xml.h:7
+#: ../hacks/config/gravitywell.xml.h:7 ../hacks/config/handsy.xml.h:7
+#: ../hacks/config/headroom.xml.h:7 ../hacks/config/hexadrop.xml.h:7
+#: ../hacks/config/hexstrut.xml.h:7 ../hacks/config/hilbert.xml.h:10
+#: ../hacks/config/hydrostat.xml.h:7 ../hacks/config/hyperball.xml.h:11
+#: ../hacks/config/hypercube.xml.h:11 ../hacks/config/hypnowheel.xml.h:4
+#: ../hacks/config/interference.xml.h:7 ../hacks/config/jigglypuff.xml.h:16
+#: ../hacks/config/jigsaw.xml.h:7 ../hacks/config/juggle.xml.h:7
+#: ../hacks/config/juggler3d.xml.h:7 ../hacks/config/kaleidocycle.xml.h:10
+#: ../hacks/config/mapscroller.xml.h:7 ../hacks/config/maze3d.xml.h:4
+#: ../hacks/config/moebiusgears.xml.h:7 ../hacks/config/nakagin.xml.h:7
+#: ../hacks/config/peepers.xml.h:7 ../hacks/config/penetrate.xml.h:4
+#: ../hacks/config/petri.xml.h:18 ../hacks/config/phosphor.xml.h:8
+#: ../hacks/config/photopile.xml.h:14 ../hacks/config/piecewise.xml.h:10
+#: ../hacks/config/pinion.xml.h:7 ../hacks/config/polyhedra.xml.h:7
+#: ../hacks/config/pong.xml.h:4 ../hacks/config/pyro.xml.h:4
+#: ../hacks/config/quasicrystal.xml.h:7 ../hacks/config/raverhoop.xml.h:13
+#: ../hacks/config/razzledazzle.xml.h:7 ../hacks/config/rocks.xml.h:10
+#: ../hacks/config/rubik.xml.h:8 ../hacks/config/rubikblocks.xml.h:10
+#: ../hacks/config/skytentacles.xml.h:17 ../hacks/config/slidescreen.xml.h:13
+#: ../hacks/config/sonar.xml.h:7 ../hacks/config/speedmine.xml.h:7
+#: ../hacks/config/splitflap.xml.h:7 ../hacks/config/squirtorus.xml.h:7
+#: ../hacks/config/starwars.xml.h:5 ../hacks/config/superquadrics.xml.h:7
+#: ../hacks/config/tangram.xml.h:10 ../hacks/config/topblock.xml.h:7
+#: ../hacks/config/tronbit.xml.h:7 ../hacks/config/unicrud.xml.h:7
+#: ../hacks/config/unknownpleasures.xml.h:10 ../hacks/config/vigilance.xml.h:7
+#: ../hacks/config/voronoi.xml.h:4 ../hacks/config/winduprobot.xml.h:7
+#: ../hacks/config/wormhole.xml.h:7 ../hacks/config/xjack.xml.h:4
+msgid "Fast"
+msgstr "სწრაფი"
+
+#: ../hacks/config/abstractile.xml.h:5 ../hacks/config/ccurve.xml.h:2
+#: ../hacks/config/flame.xml.h:5 ../hacks/config/maze.xml.h:13
+msgid "0 seconds"
+msgstr "0 წამი"
+
+#: ../hacks/config/abstractile.xml.h:6 ../hacks/config/boxed.xml.h:17
+#: ../hacks/config/celtic.xml.h:6 ../hacks/config/coral.xml.h:6
+#: ../hacks/config/cube21.xml.h:22 ../hacks/config/epicycle.xml.h:9
+#: ../hacks/config/flame.xml.h:6 ../hacks/config/glcells.xml.h:6
+#: ../hacks/config/helix.xml.h:6 ../hacks/config/imsmap.xml.h:6
+#: ../hacks/config/rorschach.xml.h:9 ../hacks/config/rubikblocks.xml.h:16
+#: ../hacks/config/tangram.xml.h:6 ../hacks/config/xlyap.xml.h:6
+#: ../hacks/config/xspirograph.xml.h:6
+msgid "Linger"
+msgstr "დაყოვნება"
+
+#: ../hacks/config/abstractile.xml.h:7 ../hacks/config/voronoi.xml.h:16
+msgid "60 seconds"
+msgstr "60 წამი"
+
+#: ../hacks/config/abstractile.xml.h:8
+msgid "Random tile layout"
+msgstr "ფილების შემთხვევითი განლაგება"
+
+#: ../hacks/config/abstractile.xml.h:9
+msgid "Flat tiles"
+msgstr "ბრტყელი ფილები"
+
+#: ../hacks/config/abstractile.xml.h:10
+msgid "Thin tiles"
+msgstr "თხელი ფილები"
+
+#: ../hacks/config/abstractile.xml.h:11
+msgid "Outline tiles"
+msgstr "კონტურული ფილები"
+
+#: ../hacks/config/abstractile.xml.h:12
+msgid "Block tiles"
+msgstr "ბლოკური ფილები"
+
+#: ../hacks/config/abstractile.xml.h:13
+msgid "Neon tiles"
+msgstr "ნეონის ფილები"
+
+#: ../hacks/config/abstractile.xml.h:14
+msgid "Tiled tiles"
+msgstr "კუსებრი ფილები"
+
+#: ../hacks/config/abstractile.xml.h:15 ../hacks/config/anemone.xml.h:16
+#: ../hacks/config/anemotaxis.xml.h:12 ../hacks/config/ant.xml.h:22
+#: ../hacks/config/antinspect.xml.h:5 ../hacks/config/antmaze.xml.h:5
+#: ../hacks/config/antspotlight.xml.h:5 ../hacks/config/apollonian.xml.h:13
+#: ../hacks/config/apple2.xml.h:9 ../hacks/config/atlantis.xml.h:19
+#: ../hacks/config/attraction.xml.h:31 ../hacks/config/atunnel.xml.h:8
+#: ../hacks/config/barcode.xml.h:9 ../hacks/config/beats.xml.h:16
+#: ../hacks/config/binaryhorizon.xml.h:14 ../hacks/config/blaster.xml.h:10
+#: ../hacks/config/blinkbox.xml.h:12 ../hacks/config/blitspin.xml.h:9
+#: ../hacks/config/blocktube.xml.h:11 ../hacks/config/boing.xml.h:14
+#: ../hacks/config/bouboule.xml.h:11 ../hacks/config/bouncingcow.xml.h:13
+#: ../hacks/config/boxed.xml.h:23 ../hacks/config/boxfit.xml.h:15
+#: ../hacks/config/braid.xml.h:13 ../hacks/config/bubble3d.xml.h:11
+#: ../hacks/config/bubbles.xml.h:11 ../hacks/config/bumps.xml.h:8
+#: ../hacks/config/cage.xml.h:6 ../hacks/config/carousel.xml.h:18
+#: ../hacks/config/ccurve.xml.h:11 ../hacks/config/celtic.xml.h:9
+#: ../hacks/config/chompytower.xml.h:15 ../hacks/config/circuit.xml.h:14
+#: ../hacks/config/cityflow.xml.h:17 ../hacks/config/cloudlife.xml.h:12
+#: ../hacks/config/companioncube.xml.h:14 ../hacks/config/compass.xml.h:5
+#: ../hacks/config/coral.xml.h:14 ../hacks/config/covid19.xml.h:14
+#: ../hacks/config/crackberg.xml.h:18 ../hacks/config/critical.xml.h:8
+#: ../hacks/config/crumbler.xml.h:15 ../hacks/config/crystal.xml.h:14
+#: ../hacks/config/cube21.xml.h:26 ../hacks/config/cubenetic.xml.h:26
+#: ../hacks/config/cubestack.xml.h:16 ../hacks/config/cubestorm.xml.h:20
+#: ../hacks/config/cubetwist.xml.h:18 ../hacks/config/cubicgrid.xml.h:12
+#: ../hacks/config/cwaves.xml.h:9 ../hacks/config/cynosure.xml.h:11
+#: ../hacks/config/dangerball.xml.h:14 ../hacks/config/decayscreen.xml.h:23
+#: ../hacks/config/deco.xml.h:14 ../hacks/config/deepstars.xml.h:9
+#: ../hacks/config/deluxe.xml.h:15 ../hacks/config/demon.xml.h:15
+#: ../hacks/config/discoball.xml.h:14 ../hacks/config/discrete.xml.h:11
+#: ../hacks/config/distort.xml.h:19 ../hacks/config/dnalogo.xml.h:9
+#: ../hacks/config/drift.xml.h:11 ../hacks/config/dymaxionmap.xml.h:16
+#: ../hacks/config/endgame.xml.h:6 ../hacks/config/energystream.xml.h:7
+#: ../hacks/config/engine.xml.h:19 ../hacks/config/epicycle.xml.h:13
+#: ../hacks/config/eruption.xml.h:22 ../hacks/config/esper.xml.h:9
+#: ../hacks/config/etruscanvenus.xml.h:42 ../hacks/config/euler2d.xml.h:14
+#: ../hacks/config/extrusion.xml.h:16 ../hacks/config/fadeplot.xml.h:14
+#: ../hacks/config/fiberlamp.xml.h:11 ../hacks/config/filmleader.xml.h:9
+#: ../hacks/config/fireworkx.xml.h:10 ../hacks/config/flag.xml.h:12
+#: ../hacks/config/flame.xml.h:14 ../hacks/config/flipflop.xml.h:14
+#: ../hacks/config/flipscreen3d.xml.h:6 ../hacks/config/fliptext.xml.h:15
+#: ../hacks/config/flow.xml.h:21 ../hacks/config/fluidballs.xml.h:22
+#: ../hacks/config/flurry.xml.h:2 ../hacks/config/flyingtoasters.xml.h:15
+#: ../hacks/config/fontglide.xml.h:16 ../hacks/config/forest.xml.h:8
+#: ../hacks/config/fuzzyflakes.xml.h:12 ../hacks/config/galaxy.xml.h:13
+#: ../hacks/config/gears.xml.h:14 ../hacks/config/geodesic.xml.h:10
+#: ../hacks/config/geodesicgears.xml.h:13 ../hacks/config/gflux.xml.h:19
+#: ../hacks/config/gibson.xml.h:15 ../hacks/config/glblur.xml.h:17
+#: ../hacks/config/glcells.xml.h:32 ../hacks/config/gleidescope.xml.h:14
+#: ../hacks/config/glforestfire.xml.h:16 ../hacks/config/glhanoi.xml.h:16
+#: ../hacks/config/glknots.xml.h:24 ../hacks/config/glmatrix.xml.h:20
+#: ../hacks/config/glplanet.xml.h:19 ../hacks/config/glschool.xml.h:17
+#: ../hacks/config/glslideshow.xml.h:20 ../hacks/config/glsnake.xml.h:18
+#: ../hacks/config/gltext.xml.h:19 ../hacks/config/goop.xml.h:13
+#: ../hacks/config/grav.xml.h:12 ../hacks/config/greynetic.xml.h:6
+#: ../hacks/config/halftone.xml.h:17 ../hacks/config/halo.xml.h:14
+#: ../hacks/config/handsy.xml.h:23 ../hacks/config/headroom.xml.h:19
+#: ../hacks/config/helix.xml.h:8 ../hacks/config/hexadrop.xml.h:22
+#: ../hacks/config/hexstrut.xml.h:17 ../hacks/config/hilbert.xml.h:20
+#: ../hacks/config/hopalong.xml.h:23 ../hacks/config/hydrostat.xml.h:29
+#: ../hacks/config/hyperball.xml.h:8 ../hacks/config/hypercube.xml.h:8
+#: ../hacks/config/hypertorus.xml.h:5 ../hacks/config/hypnowheel.xml.h:8
+#: ../hacks/config/ifs.xml.h:68 ../hacks/config/imsmap.xml.h:18
+#: ../hacks/config/interaggregate.xml.h:8 ../hacks/config/interference.xml.h:21
+#: ../hacks/config/intermomentary.xml.h:8 ../hacks/config/jigglypuff.xml.h:10
+#: ../hacks/config/jigsaw.xml.h:15 ../hacks/config/juggle.xml.h:21
+#: ../hacks/config/juggler3d.xml.h:20 ../hacks/config/julia.xml.h:14
+#: ../hacks/config/kaleidescope.xml.h:12 ../hacks/config/kaleidocycle.xml.h:21
+#: ../hacks/config/klein.xml.h:47 ../hacks/config/kumppa.xml.h:7
+#: ../hacks/config/lament.xml.h:7 ../hacks/config/laser.xml.h:12
+#: ../hacks/config/lavalite.xml.h:16 ../hacks/config/lcdscrub.xml.h:7
+#: ../hacks/config/lightning.xml.h:8 ../hacks/config/lisa.xml.h:16
+#: ../hacks/config/lissie.xml.h:15 ../hacks/config/lmorph.xml.h:17
+#: ../hacks/config/lockward.xml.h:9 ../hacks/config/loop.xml.h:12
+#: ../hacks/config/m6502.xml.h:3 ../hacks/config/mapscroller.xml.h:64
+#: ../hacks/config/marbling.xml.h:10 ../hacks/config/maze.xml.h:12
+#: ../hacks/config/maze3d.xml.h:10 ../hacks/config/memscroller.xml.h:9
+#: ../hacks/config/menger.xml.h:19 ../hacks/config/metaballs.xml.h:16
+#: ../hacks/config/mirrorblob.xml.h:25 ../hacks/config/mismunch.xml.h:13
+#: ../hacks/config/moebius.xml.h:7 ../hacks/config/moebiusgears.xml.h:14
+#: ../hacks/config/moire.xml.h:11 ../hacks/config/moire2.xml.h:9
+#: ../hacks/config/molecule.xml.h:15 ../hacks/config/morph3d.xml.h:11
+#: ../hacks/config/mountain.xml.h:11 ../hacks/config/munch.xml.h:16
+#: ../hacks/config/nakagin.xml.h:12 ../hacks/config/nerverot.xml.h:21
+#: ../hacks/config/noof.xml.h:5 ../hacks/config/noseguy.xml.h:2
+#: ../hacks/config/pacman.xml.h:6 ../hacks/config/pedal.xml.h:8
+#: ../hacks/config/peepers.xml.h:17 ../hacks/config/penetrate.xml.h:8
+#: ../hacks/config/penrose.xml.h:12 ../hacks/config/petri.xml.h:5
+#: ../hacks/config/phosphor.xml.h:13 ../hacks/config/photopile.xml.h:22
+#: ../hacks/config/piecewise.xml.h:15 ../hacks/config/pinion.xml.h:16
+#: ../hacks/config/pipes.xml.h:20 ../hacks/config/polyhedra.xml.h:168
+#: ../hacks/config/polyominoes.xml.h:12 ../hacks/config/polytopes.xml.h:18
+#: ../hacks/config/pong.xml.h:9 ../hacks/config/popsquares.xml.h:21
+#: ../hacks/config/projectiveplane.xml.h:45 ../hacks/config/providence.xml.h:7
+#: ../hacks/config/pulsar.xml.h:14 ../hacks/config/pyro.xml.h:14
+#: ../hacks/config/qix.xml.h:24 ../hacks/config/quasicrystal.xml.h:13
+#: ../hacks/config/queens.xml.h:6 ../hacks/config/raverhoop.xml.h:20
+#: ../hacks/config/razzledazzle.xml.h:20 ../hacks/config/ripples.xml.h:18
+#: ../hacks/config/rocks.xml.h:16 ../hacks/config/romanboy.xml.h:43
+#: ../hacks/config/rorschach.xml.h:11 ../hacks/config/rotor.xml.h:13
+#: ../hacks/config/rotzoomer.xml.h:15 ../hacks/config/rubik.xml.h:11
+#: ../hacks/config/rubikblocks.xml.h:20 ../hacks/config/sballs.xml.h:16
+#: ../hacks/config/scooter.xml.h:17 ../hacks/config/shadebobs.xml.h:13
+#: ../hacks/config/sierpinski.xml.h:13 ../hacks/config/sierpinski3d.xml.h:10
+#: ../hacks/config/skytentacles.xml.h:25 ../hacks/config/slidescreen.xml.h:18
+#: ../hacks/config/slip.xml.h:13 ../hacks/config/sonar.xml.h:25
+#: ../hacks/config/speedmine.xml.h:17 ../hacks/config/sphere.xml.h:8
+#: ../hacks/config/sphereeversion.xml.h:38
+#: ../hacks/config/spheremonics.xml.h:22 ../hacks/config/spiral.xml.h:11
+#: ../hacks/config/splitflap.xml.h:25 ../hacks/config/splodesic.xml.h:11
+#: ../hacks/config/spotlight.xml.h:11 ../hacks/config/sproingies.xml.h:9
+#: ../hacks/config/squiral.xml.h:19 ../hacks/config/squirtorus.xml.h:12
+#: ../hacks/config/stairs.xml.h:5 ../hacks/config/starfish.xml.h:17
+#: ../hacks/config/starwars.xml.h:15 ../hacks/config/stonerview.xml.h:7
+#: ../hacks/config/strange.xml.h:23 ../hacks/config/substrate.xml.h:19
+#: ../hacks/config/superquadrics.xml.h:13 ../hacks/config/surfaces.xml.h:27
+#: ../hacks/config/swirl.xml.h:10 ../hacks/config/t3d.xml.h:15
+#: ../hacks/config/tangram.xml.h:16 ../hacks/config/tessellimage.xml.h:19
+#: ../hacks/config/testx11.xml.h:2 ../hacks/config/thornbird.xml.h:11
+#: ../hacks/config/timetunnel.xml.h:8 ../hacks/config/topblock.xml.h:24
+#: ../hacks/config/triangle.xml.h:8 ../hacks/config/tronbit.xml.h:11
+#: ../hacks/config/truchet.xml.h:5 ../hacks/config/twang.xml.h:18
+#: ../hacks/config/unicrud.xml.h:10 ../hacks/config/unknownpleasures.xml.h:17
+#: ../hacks/config/vermiculate.xml.h:5 ../hacks/config/vfeedback.xml.h:9
+#: ../hacks/config/vidwhacker.xml.h:5 ../hacks/config/vines.xml.h:8
+#: ../hacks/config/voronoi.xml.h:11 ../hacks/config/wander.xml.h:13
+#: ../hacks/config/webcollage.xml.h:11 ../hacks/config/whirlwindwarp.xml.h:8
+#: ../hacks/config/whirlygig.xml.h:31 ../hacks/config/winduprobot.xml.h:22
+#: ../hacks/config/worm.xml.h:10 ../hacks/config/wormhole.xml.h:11
+#: ../hacks/config/xanalogtv.xml.h:2 ../hacks/config/xflame.xml.h:6
+#: ../hacks/config/xjack.xml.h:5 ../hacks/config/xlyap.xml.h:8
+#: ../hacks/config/xmatrix.xml.h:21 ../hacks/config/xrayswarm.xml.h:5
+#: ../hacks/config/xspirograph.xml.h:9 ../hacks/config/zoom.xml.h:15
+msgid "Show frame rate"
+msgstr "კადრების სიხშირის ჩვენება"
+
+#: ../hacks/config/abstractile.xml.h:16
+msgid ""
+"Mosaic patterns of interlocking tiles. Written by Steve Sundstrom; 2004."
+msgstr ""
+"კვეთადი ფილების მოზაიკის ნიმუშები. დაწერილია სტივ სანდშტორმის მიერ. 2004."
+
+#: ../hacks/config/anemone.xml.h:1
+msgid "Anemone"
+msgstr "ანემონი"
+
+#: ../hacks/config/anemone.xml.h:5 ../hacks/config/anemotaxis.xml.h:8
+#: ../hacks/config/beats.xml.h:5 ../hacks/config/binaryhorizon.xml.h:5
+#: ../hacks/config/binaryring.xml.h:8 ../hacks/config/blaster.xml.h:7
+#: ../hacks/config/bouboule.xml.h:5 ../hacks/config/boxed.xml.h:8
+#: ../hacks/config/cityflow.xml.h:5 ../hacks/config/coral.xml.h:11
+#: ../hacks/config/crackberg.xml.h:8 ../hacks/config/crumbler.xml.h:8
+#: ../hacks/config/cubenetic.xml.h:5 ../hacks/config/cubestorm.xml.h:8
+#: ../hacks/config/dangerball.xml.h:8 ../hacks/config/eruption.xml.h:5
+#: ../hacks/config/euler2d.xml.h:5 ../hacks/config/fiberlamp.xml.h:5
+#: ../hacks/config/flame.xml.h:8 ../hacks/config/flow.xml.h:5
+#: ../hacks/config/fluidballs.xml.h:5 ../hacks/config/fuzzyflakes.xml.h:8
+#: ../hacks/config/glcells.xml.h:8 ../hacks/config/glschool.xml.h:5
+#: ../hacks/config/goop.xml.h:8 ../hacks/config/grav.xml.h:5
+#: ../hacks/config/halftone.xml.h:5 ../hacks/config/halo.xml.h:5
+#: ../hacks/config/hydrostat.xml.h:14 ../hacks/config/interaggregate.xml.h:5
+#: ../hacks/config/interference.xml.h:11 ../hacks/config/jigsaw.xml.h:8
+#: ../hacks/config/julia.xml.h:5 ../hacks/config/kaleidescope.xml.h:5
+#: ../hacks/config/lisa.xml.h:5 ../hacks/config/lmorph.xml.h:5
+#: ../hacks/config/nerverot.xml.h:8 ../hacks/config/pedal.xml.h:5
+#: ../hacks/config/peepers.xml.h:8 ../hacks/config/petri.xml.h:10
+#: ../hacks/config/piecewise.xml.h:5 ../hacks/config/qix.xml.h:5
+#: ../hacks/config/rocks.xml.h:5 ../hacks/config/sierpinski.xml.h:5
+#: ../hacks/config/slip.xml.h:5 ../hacks/config/spiral.xml.h:5
+#: ../hacks/config/substrate.xml.h:8 ../hacks/config/swirl.xml.h:5
+#: ../hacks/config/thornbird.xml.h:5 ../hacks/config/topblock.xml.h:13
+#: ../hacks/config/unknownpleasures.xml.h:5 ../hacks/config/voronoi.xml.h:5
+#: ../hacks/config/whirlwindwarp.xml.h:2 ../hacks/config/wormhole.xml.h:8
+msgid "Few"
+msgstr "რამდენიმე"
+
+#: ../hacks/config/anemone.xml.h:6 ../hacks/config/fuzzyflakes.xml.h:20
+#: ../hacks/config/hypnowheel.xml.h:13
+msgid "Arms"
+msgstr "ხელები"
+
+#.
+#. On a 2.93 gHz iMac i7, I get these rates with -delay 0:
+#.
+#. detail 3:  invisible
+#. detail 4:  barely visible
+#. detail 5:  1000+ fps, looks like noise at -delay 0, ok at -delay 20000
+#. detail 8:  ~700+ fps
+#. detail 9:  ~400 fps
+#. detail 10: ~300 fps
+#. detail 11: ~100 fps
+#. detail 12:  ~50 fps
+#. detail 13:  ~17 fps
+#. detail 14:   ~8 fps
+#. detail 15:   ~2 fps
+#.
+#. With the default -delay, CPU load only starts causing the frame rate
+#. to drop below 30 fps detail 12 or higher.
+#.
+#: ../hacks/config/anemone.xml.h:7 ../hacks/config/anemotaxis.xml.h:10
+#: ../hacks/config/ant.xml.h:13 ../hacks/config/apollonian.xml.h:9
+#: ../hacks/config/attraction.xml.h:19 ../hacks/config/beats.xml.h:7
+#: ../hacks/config/blaster.xml.h:9 ../hacks/config/bouboule.xml.h:7
+#: ../hacks/config/braid.xml.h:10 ../hacks/config/cityflow.xml.h:7
+#: ../hacks/config/coral.xml.h:13 ../hacks/config/critical.xml.h:7
+#: ../hacks/config/crumbler.xml.h:10 ../hacks/config/crystal.xml.h:7
+#: ../hacks/config/cubenetic.xml.h:7 ../hacks/config/cubestorm.xml.h:10
+#: ../hacks/config/cynosure.xml.h:7 ../hacks/config/deco.xml.h:7
+#: ../hacks/config/deluxe.xml.h:13 ../hacks/config/demon.xml.h:13
+#: ../hacks/config/discrete.xml.h:10 ../hacks/config/drift.xml.h:10
+#: ../hacks/config/epicycle.xml.h:7 ../hacks/config/eruption.xml.h:7
+#: ../hacks/config/euler2d.xml.h:7 ../hacks/config/fadeplot.xml.h:13
+#: ../hacks/config/fiberlamp.xml.h:7 ../hacks/config/flag.xml.h:11
+#: ../hacks/config/flame.xml.h:10 ../hacks/config/flow.xml.h:7
+#: ../hacks/config/fluidballs.xml.h:7 ../hacks/config/forest.xml.h:7
+#: ../hacks/config/fuzzyflakes.xml.h:10 ../hacks/config/galaxy.xml.h:11
+#: ../hacks/config/glcells.xml.h:10 ../hacks/config/goop.xml.h:10
+#: ../hacks/config/grav.xml.h:7 ../hacks/config/halftone.xml.h:7
+#: ../hacks/config/halo.xml.h:7 ../hacks/config/handsy.xml.h:10
+#: ../hacks/config/hopalong.xml.h:11 ../hacks/config/hydrostat.xml.h:10
+#: ../hacks/config/ifs.xml.h:64 ../hacks/config/imsmap.xml.h:13
+#: ../hacks/config/interaggregate.xml.h:7 ../hacks/config/interference.xml.h:13
+#: ../hacks/config/jigsaw.xml.h:10 ../hacks/config/julia.xml.h:13
+#: ../hacks/config/kaleidescope.xml.h:7 ../hacks/config/laser.xml.h:11
+#: ../hacks/config/lightning.xml.h:7 ../hacks/config/lisa.xml.h:7
+#: ../hacks/config/lissie.xml.h:10 ../hacks/config/lmorph.xml.h:7
+#: ../hacks/config/loop.xml.h:10 ../hacks/config/metaballs.xml.h:10
+#: ../hacks/config/mismunch.xml.h:10 ../hacks/config/moire.xml.h:7
+#: ../hacks/config/moire2.xml.h:7 ../hacks/config/mountain.xml.h:10
+#: ../hacks/config/munch.xml.h:10 ../hacks/config/nerverot.xml.h:10
+#: ../hacks/config/pedal.xml.h:7 ../hacks/config/peepers.xml.h:10
+#: ../hacks/config/penrose.xml.h:7 ../hacks/config/petri.xml.h:12
+#: ../hacks/config/piecewise.xml.h:7 ../hacks/config/polyominoes.xml.h:11
+#: ../hacks/config/qix.xml.h:7 ../hacks/config/razzledazzle.xml.h:10
+#: ../hacks/config/rocks.xml.h:7 ../hacks/config/rotor.xml.h:10
+#: ../hacks/config/shadebobs.xml.h:7 ../hacks/config/sierpinski.xml.h:7
+#: ../hacks/config/slip.xml.h:7 ../hacks/config/sphere.xml.h:7
+#: ../hacks/config/spiral.xml.h:7 ../hacks/config/squiral.xml.h:18
+#: ../hacks/config/starfish.xml.h:16 ../hacks/config/strange.xml.h:22
+#: ../hacks/config/swirl.xml.h:7 ../hacks/config/thornbird.xml.h:7
+#: ../hacks/config/topblock.xml.h:15 ../hacks/config/triangle.xml.h:7
+#: ../hacks/config/unknownpleasures.xml.h:7 ../hacks/config/vines.xml.h:7
+#: ../hacks/config/voronoi.xml.h:7 ../hacks/config/whirlwindwarp.xml.h:4
+#: ../hacks/config/worm.xml.h:7
+msgid "Many"
+msgstr "ბევრი"
+
+#: ../hacks/config/anemone.xml.h:8 ../hacks/config/skytentacles.xml.h:3
+msgid "Tentacles"
+msgstr "საცეცები"
+
+#: ../hacks/config/anemone.xml.h:9 ../hacks/config/cubestack.xml.h:8
+#: ../hacks/config/cubestorm.xml.h:14 ../hacks/config/cubetwist.xml.h:8
+#: ../hacks/config/deluxe.xml.h:5 ../hacks/config/fadeplot.xml.h:5
+#: ../hacks/config/fuzzyflakes.xml.h:21 ../hacks/config/glknots.xml.h:19
+#: ../hacks/config/hexstrut.xml.h:11 ../hacks/config/hilbert.xml.h:15
+#: ../hacks/config/hydrostat.xml.h:16 ../hacks/config/lmorph.xml.h:11
+#: ../hacks/config/razzledazzle.xml.h:14 ../hacks/config/skytentacles.xml.h:8
+#: ../hacks/config/starfish.xml.h:11 ../hacks/config/thornbird.xml.h:8
+msgid "Thin"
+msgstr "თხელი"
+
+#: ../hacks/config/anemone.xml.h:10 ../hacks/config/cubestack.xml.h:9
+#: ../hacks/config/cubetwist.xml.h:9 ../hacks/config/fadeplot.xml.h:6
+#: ../hacks/config/fuzzyflakes.xml.h:22 ../hacks/config/glknots.xml.h:20
+#: ../hacks/config/hydrostat.xml.h:17 ../hacks/config/moire2.xml.h:8
+#: ../hacks/config/skytentacles.xml.h:9 ../hacks/config/thornbird.xml.h:9
+msgid "Thickness"
+msgstr "სისქე"
+
+#: ../hacks/config/anemone.xml.h:11 ../hacks/config/cubestack.xml.h:10
+#: ../hacks/config/cubestorm.xml.h:16 ../hacks/config/cubetwist.xml.h:10
+#: ../hacks/config/deluxe.xml.h:7 ../hacks/config/fadeplot.xml.h:7
+#: ../hacks/config/fuzzyflakes.xml.h:23 ../hacks/config/glknots.xml.h:21
+#: ../hacks/config/hexstrut.xml.h:13 ../hacks/config/hilbert.xml.h:17
+#: ../hacks/config/hydrostat.xml.h:18 ../hacks/config/lmorph.xml.h:13
+#: ../hacks/config/razzledazzle.xml.h:16 ../hacks/config/skytentacles.xml.h:10
+#: ../hacks/config/starfish.xml.h:13 ../hacks/config/thornbird.xml.h:10
+msgid "Thick"
+msgstr "სქელი"
+
+#: ../hacks/config/anemone.xml.h:12 ../hacks/config/pyro.xml.h:10
+#: ../hacks/config/splodesic.xml.h:7 ../hacks/config/winduprobot.xml.h:19
+msgid "Often"
+msgstr "ხშირად"
+
+#: ../hacks/config/anemone.xml.h:13
+msgid "Withdraw freqency"
+msgstr "გადახატვის სიხშირე"
+
+#: ../hacks/config/anemone.xml.h:14
+msgid "Rarely"
+msgstr "იშვიათად"
+
+#: ../hacks/config/anemone.xml.h:15
+msgid "Turn speed"
+msgstr "მობრუნების სიჩქარე"
+
+#: ../hacks/config/anemone.xml.h:17
+msgid "Wiggling tentacles. Written by Gabriel Finch; 2002."
+msgstr ""
+
+#: ../hacks/config/anemotaxis.xml.h:1
+msgid "Anemotaxis"
+msgstr "ანემოტაქსისი"
+
+#. <video href="https://www.youtube.com/watch?v=OZ6zRLLFLk4"/>
+#: ../hacks/config/anemotaxis.xml.h:2 ../hacks/config/ant.xml.h:2
+#: ../hacks/config/antinspect.xml.h:2 ../hacks/config/antmaze.xml.h:2
+#: ../hacks/config/antspotlight.xml.h:2 ../hacks/config/apple2.xml.h:10
+#: ../hacks/config/atlantis.xml.h:2 ../hacks/config/attraction.xml.h:11
+#: ../hacks/config/atunnel.xml.h:2 ../hacks/config/barcode.xml.h:2
+#: ../hacks/config/beats.xml.h:2 ../hacks/config/binaryhorizon.xml.h:2
+#: ../hacks/config/binaryring.xml.h:2 ../hacks/config/blaster.xml.h:2
+#: ../hacks/config/blinkbox.xml.h:2 ../hacks/config/blocktube.xml.h:2
+#: ../hacks/config/bouboule.xml.h:2 ../hacks/config/bouncingcow.xml.h:2
+#: ../hacks/config/boxed.xml.h:2 ../hacks/config/boxfit.xml.h:2
+#: ../hacks/config/braid.xml.h:2 ../hacks/config/bubble3d.xml.h:2
+#: ../hacks/config/bubbles.xml.h:2 ../hacks/config/bumps.xml.h:2
+#: ../hacks/config/cage.xml.h:2 ../hacks/config/carousel.xml.h:2
+#: ../hacks/config/ccurve.xml.h:8 ../hacks/config/celtic.xml.h:2
+#: ../hacks/config/chompytower.xml.h:2 ../hacks/config/circuit.xml.h:2
+#: ../hacks/config/cityflow.xml.h:2 ../hacks/config/cloudlife.xml.h:2
+#: ../hacks/config/companioncube.xml.h:2 ../hacks/config/compass.xml.h:2
+#: ../hacks/config/coral.xml.h:2 ../hacks/config/covid19.xml.h:2
+#: ../hacks/config/crackberg.xml.h:2 ../hacks/config/critical.xml.h:2
+#: ../hacks/config/crumbler.xml.h:2 ../hacks/config/crystal.xml.h:2
+#: ../hacks/config/cube21.xml.h:2 ../hacks/config/cubenetic.xml.h:2
+#: ../hacks/config/cubestack.xml.h:2 ../hacks/config/cubestorm.xml.h:2
+#: ../hacks/config/cubetwist.xml.h:2 ../hacks/config/cubicgrid.xml.h:2
+#: ../hacks/config/cwaves.xml.h:2 ../hacks/config/cynosure.xml.h:2
+#: ../hacks/config/dangerball.xml.h:2 ../hacks/config/decayscreen.xml.h:2
+#: ../hacks/config/deepstars.xml.h:2 ../hacks/config/deluxe.xml.h:2
+#: ../hacks/config/demon.xml.h:2 ../hacks/config/discoball.xml.h:2
+#: ../hacks/config/discrete.xml.h:2 ../hacks/config/distort.xml.h:2
+#: ../hacks/config/dnalogo.xml.h:2 ../hacks/config/drift.xml.h:2
+#: ../hacks/config/dymaxionmap.xml.h:2 ../hacks/config/endgame.xml.h:2
+#: ../hacks/config/engine.xml.h:2 ../hacks/config/epicycle.xml.h:2
+#: ../hacks/config/eruption.xml.h:2 ../hacks/config/esper.xml.h:2
+#: ../hacks/config/etruscanvenus.xml.h:39 ../hacks/config/euler2d.xml.h:2
+#: ../hacks/config/extrusion.xml.h:2 ../hacks/config/fadeplot.xml.h:2
+#: ../hacks/config/fiberlamp.xml.h:2 ../hacks/config/filmleader.xml.h:2
+#: ../hacks/config/fireworkx.xml.h:2 ../hacks/config/flag.xml.h:3
+#: ../hacks/config/flame.xml.h:2 ../hacks/config/flipflop.xml.h:2
+#: ../hacks/config/flipscreen3d.xml.h:2 ../hacks/config/fliptext.xml.h:2
+#: ../hacks/config/flow.xml.h:2 ../hacks/config/fluidballs.xml.h:2
+#: ../hacks/config/flyingtoasters.xml.h:2 ../hacks/config/fontglide.xml.h:2
+#: ../hacks/config/forest.xml.h:2 ../hacks/config/fuzzyflakes.xml.h:2
+#: ../hacks/config/galaxy.xml.h:2 ../hacks/config/gears.xml.h:2
+#: ../hacks/config/geodesic.xml.h:11 ../hacks/config/geodesicgears.xml.h:2
+#: ../hacks/config/gflux.xml.h:2 ../hacks/config/gibson.xml.h:2
+#: ../hacks/config/glblur.xml.h:2 ../hacks/config/glcells.xml.h:2
+#: ../hacks/config/gleidescope.xml.h:2 ../hacks/config/glforestfire.xml.h:2
+#: ../hacks/config/glhanoi.xml.h:2 ../hacks/config/glitchpeg.xml.h:2
+#: ../hacks/config/glknots.xml.h:2 ../hacks/config/glmatrix.xml.h:2
+#: ../hacks/config/glplanet.xml.h:3 ../hacks/config/glschool.xml.h:2
+#: ../hacks/config/glslideshow.xml.h:2 ../hacks/config/glsnake.xml.h:2
+#: ../hacks/config/gltext.xml.h:2 ../hacks/config/goop.xml.h:2
+#: ../hacks/config/grav.xml.h:2 ../hacks/config/gravitywell.xml.h:2
+#: ../hacks/config/greynetic.xml.h:2 ../hacks/config/halftone.xml.h:2
+#: ../hacks/config/halo.xml.h:2 ../hacks/config/handsy.xml.h:2
+#: ../hacks/config/headroom.xml.h:2 ../hacks/config/helix.xml.h:2
+#: ../hacks/config/hexadrop.xml.h:2 ../hacks/config/hexstrut.xml.h:2
+#: ../hacks/config/hopalong.xml.h:2 ../hacks/config/hydrostat.xml.h:2
+#: ../hacks/config/hyperball.xml.h:2 ../hacks/config/hypercube.xml.h:2
+#: ../hacks/config/hypertorus.xml.h:2 ../hacks/config/hypnowheel.xml.h:14
+#: ../hacks/config/ifs.xml.h:2 ../hacks/config/imsmap.xml.h:2
+#: ../hacks/config/interaggregate.xml.h:2 ../hacks/config/interference.xml.h:2
+#: ../hacks/config/intermomentary.xml.h:2 ../hacks/config/jigglypuff.xml.h:11
+#: ../hacks/config/jigsaw.xml.h:2 ../hacks/config/juggle.xml.h:2
+#: ../hacks/config/juggler3d.xml.h:2 ../hacks/config/julia.xml.h:2
+#: ../hacks/config/kaleidescope.xml.h:2 ../hacks/config/kaleidocycle.xml.h:2
+#: ../hacks/config/klein.xml.h:44 ../hacks/config/kumppa.xml.h:2
+#: ../hacks/config/lament.xml.h:2 ../hacks/config/laser.xml.h:2
+#: ../hacks/config/lavalite.xml.h:2 ../hacks/config/lcdscrub.xml.h:2
+#: ../hacks/config/lightning.xml.h:2 ../hacks/config/lisa.xml.h:2
+#: ../hacks/config/lissie.xml.h:2 ../hacks/config/lmorph.xml.h:2
+#: ../hacks/config/lockward.xml.h:2 ../hacks/config/loop.xml.h:2
+#: ../hacks/config/m6502.xml.h:7 ../hacks/config/mapscroller.xml.h:2
+#: ../hacks/config/marbling.xml.h:2 ../hacks/config/maze.xml.h:2
+#: ../hacks/config/maze3d.xml.h:5 ../hacks/config/memscroller.xml.h:2
+#: ../hacks/config/menger.xml.h:2 ../hacks/config/metaballs.xml.h:2
+#: ../hacks/config/mirrorblob.xml.h:2 ../hacks/config/mismunch.xml.h:2
+#: ../hacks/config/moebius.xml.h:2 ../hacks/config/moebiusgears.xml.h:2
+#: ../hacks/config/moire2.xml.h:2 ../hacks/config/molecule.xml.h:2
+#: ../hacks/config/morph3d.xml.h:2 ../hacks/config/mountain.xml.h:2
+#: ../hacks/config/munch.xml.h:2 ../hacks/config/nakagin.xml.h:2
+#: ../hacks/config/nerverot.xml.h:2 ../hacks/config/noof.xml.h:2
+#: ../hacks/config/pacman.xml.h:2 ../hacks/config/peepers.xml.h:2
+#: ../hacks/config/penrose.xml.h:2 ../hacks/config/petri.xml.h:2
+#: ../hacks/config/phosphor.xml.h:2 ../hacks/config/photopile.xml.h:15
+#: ../hacks/config/piecewise.xml.h:2 ../hacks/config/pinion.xml.h:2
+#: ../hacks/config/pipes.xml.h:2 ../hacks/config/polyhedra.xml.h:2
+#: ../hacks/config/polyominoes.xml.h:3 ../hacks/config/polytopes.xml.h:24
+#: ../hacks/config/pong.xml.h:10 ../hacks/config/popsquares.xml.h:2
+#: ../hacks/config/projectiveplane.xml.h:37 ../hacks/config/providence.xml.h:2
+#: ../hacks/config/pulsar.xml.h:2 ../hacks/config/pyro.xml.h:11
+#: ../hacks/config/qix.xml.h:2 ../hacks/config/quasicrystal.xml.h:2
+#: ../hacks/config/queens.xml.h:2 ../hacks/config/raverhoop.xml.h:2
+#: ../hacks/config/razzledazzle.xml.h:2 ../hacks/config/ripples.xml.h:2
+#: ../hacks/config/rocks.xml.h:2 ../hacks/config/romanboy.xml.h:40
+#: ../hacks/config/rotor.xml.h:2 ../hacks/config/rotzoomer.xml.h:2
+#: ../hacks/config/rubik.xml.h:2 ../hacks/config/rubikblocks.xml.h:2
+#: ../hacks/config/sballs.xml.h:2 ../hacks/config/scooter.xml.h:2
+#: ../hacks/config/shadebobs.xml.h:2 ../hacks/config/sierpinski.xml.h:2
+#: ../hacks/config/sierpinski3d.xml.h:2 ../hacks/config/skytentacles.xml.h:11
+#: ../hacks/config/slidescreen.xml.h:2 ../hacks/config/slip.xml.h:2
+#: ../hacks/config/sonar.xml.h:2 ../hacks/config/speedmine.xml.h:2
+#: ../hacks/config/sphere.xml.h:2 ../hacks/config/spheremonics.xml.h:2
+#: ../hacks/config/spiral.xml.h:2 ../hacks/config/splitflap.xml.h:2
+#: ../hacks/config/splodesic.xml.h:2 ../hacks/config/spotlight.xml.h:2
+#: ../hacks/config/sproingies.xml.h:2 ../hacks/config/squiral.xml.h:2
+#: ../hacks/config/squirtorus.xml.h:2 ../hacks/config/stairs.xml.h:2
+#: ../hacks/config/starfish.xml.h:5 ../hacks/config/stonerview.xml.h:2
+#: ../hacks/config/strange.xml.h:2 ../hacks/config/substrate.xml.h:2
+#: ../hacks/config/superquadrics.xml.h:2 ../hacks/config/surfaces.xml.h:2
+#: ../hacks/config/swirl.xml.h:2 ../hacks/config/t3d.xml.h:2
+#: ../hacks/config/tangram.xml.h:2 ../hacks/config/tessellimage.xml.h:2
+#: ../hacks/config/thornbird.xml.h:2 ../hacks/config/topblock.xml.h:2
+#: ../hacks/config/triangle.xml.h:2 ../hacks/config/tronbit.xml.h:2
+#: ../hacks/config/truchet.xml.h:2 ../hacks/config/twang.xml.h:2
+#: ../hacks/config/unicrud.xml.h:2 ../hacks/config/unknownpleasures.xml.h:2
+#: ../hacks/config/vfeedback.xml.h:2 ../hacks/config/vigilance.xml.h:2
+#: ../hacks/config/vines.xml.h:2 ../hacks/config/wander.xml.h:2
+#: ../hacks/config/whirlygig.xml.h:4 ../hacks/config/winduprobot.xml.h:2
+#: ../hacks/config/worm.xml.h:2 ../hacks/config/wormhole.xml.h:2
+#: ../hacks/config/xanalogtv.xml.h:4 ../hacks/config/xflame.xml.h:2
+#: ../hacks/config/xlyap.xml.h:2 ../hacks/config/xmatrix.xml.h:15
+#: ../hacks/config/xrayswarm.xml.h:2 ../hacks/config/xspirograph.xml.h:2
+#: ../hacks/config/zoom.xml.h:2
+msgid "Low"
+msgstr "დაბალი"
+
+#. <video href="https://www.youtube.com/watch?v=OZ6zRLLFLk4"/>
+#: ../hacks/config/anemotaxis.xml.h:3 ../hacks/config/ant.xml.h:3
+#: ../hacks/config/antinspect.xml.h:3 ../hacks/config/antmaze.xml.h:3
+#: ../hacks/config/antspotlight.xml.h:3 ../hacks/config/atlantis.xml.h:3
+#: ../hacks/config/atunnel.xml.h:3 ../hacks/config/barcode.xml.h:3
+#: ../hacks/config/beats.xml.h:3 ../hacks/config/blaster.xml.h:3
+#: ../hacks/config/blinkbox.xml.h:3 ../hacks/config/blocktube.xml.h:3
+#: ../hacks/config/bouboule.xml.h:3 ../hacks/config/bouncingcow.xml.h:3
+#: ../hacks/config/boxed.xml.h:3 ../hacks/config/boxfit.xml.h:3
+#: ../hacks/config/braid.xml.h:3 ../hacks/config/bubble3d.xml.h:3
+#: ../hacks/config/bubbles.xml.h:3 ../hacks/config/bumps.xml.h:3
+#: ../hacks/config/cage.xml.h:3 ../hacks/config/carousel.xml.h:3
+#: ../hacks/config/celtic.xml.h:3 ../hacks/config/chompytower.xml.h:3
+#: ../hacks/config/circuit.xml.h:3 ../hacks/config/cityflow.xml.h:3
+#: ../hacks/config/cloudlife.xml.h:3 ../hacks/config/companioncube.xml.h:3
+#: ../hacks/config/compass.xml.h:3 ../hacks/config/coral.xml.h:3
+#: ../hacks/config/covid19.xml.h:3 ../hacks/config/crackberg.xml.h:3
+#: ../hacks/config/critical.xml.h:3 ../hacks/config/crumbler.xml.h:3
+#: ../hacks/config/crystal.xml.h:3 ../hacks/config/cube21.xml.h:3
+#: ../hacks/config/cubenetic.xml.h:3 ../hacks/config/cubestack.xml.h:3
+#: ../hacks/config/cubestorm.xml.h:3 ../hacks/config/cubetwist.xml.h:3
+#: ../hacks/config/cubicgrid.xml.h:3 ../hacks/config/cwaves.xml.h:3
+#: ../hacks/config/cynosure.xml.h:3 ../hacks/config/dangerball.xml.h:3
+#: ../hacks/config/decayscreen.xml.h:3 ../hacks/config/deepstars.xml.h:3
+#: ../hacks/config/deluxe.xml.h:3 ../hacks/config/demon.xml.h:3
+#: ../hacks/config/discoball.xml.h:3 ../hacks/config/discrete.xml.h:3
+#: ../hacks/config/distort.xml.h:3 ../hacks/config/drift.xml.h:3
+#: ../hacks/config/dymaxionmap.xml.h:3 ../hacks/config/endgame.xml.h:3
+#: ../hacks/config/engine.xml.h:3 ../hacks/config/epicycle.xml.h:3
+#: ../hacks/config/eruption.xml.h:3 ../hacks/config/esper.xml.h:3
+#: ../hacks/config/etruscanvenus.xml.h:40 ../hacks/config/euler2d.xml.h:3
+#: ../hacks/config/extrusion.xml.h:3 ../hacks/config/fadeplot.xml.h:3
+#: ../hacks/config/fiberlamp.xml.h:3 ../hacks/config/fireworkx.xml.h:3
+#: ../hacks/config/flag.xml.h:4 ../hacks/config/flame.xml.h:3
+#: ../hacks/config/flipflop.xml.h:3 ../hacks/config/flipscreen3d.xml.h:3
+#: ../hacks/config/fliptext.xml.h:3 ../hacks/config/flow.xml.h:3
+#: ../hacks/config/fluidballs.xml.h:3 ../hacks/config/flyingtoasters.xml.h:3
+#: ../hacks/config/fontglide.xml.h:3 ../hacks/config/forest.xml.h:3
+#: ../hacks/config/fuzzyflakes.xml.h:3 ../hacks/config/galaxy.xml.h:3
+#: ../hacks/config/gears.xml.h:3 ../hacks/config/geodesic.xml.h:12
+#: ../hacks/config/geodesicgears.xml.h:3 ../hacks/config/gflux.xml.h:3
+#: ../hacks/config/gibson.xml.h:3 ../hacks/config/glblur.xml.h:3
+#: ../hacks/config/glcells.xml.h:3 ../hacks/config/gleidescope.xml.h:3
+#: ../hacks/config/glforestfire.xml.h:3 ../hacks/config/glhanoi.xml.h:3
+#: ../hacks/config/glitchpeg.xml.h:3 ../hacks/config/glknots.xml.h:3
+#: ../hacks/config/glmatrix.xml.h:3 ../hacks/config/glplanet.xml.h:5
+#: ../hacks/config/glschool.xml.h:3 ../hacks/config/glslideshow.xml.h:3
+#: ../hacks/config/glsnake.xml.h:3 ../hacks/config/gltext.xml.h:3
+#: ../hacks/config/goop.xml.h:3 ../hacks/config/grav.xml.h:3
+#: ../hacks/config/gravitywell.xml.h:3 ../hacks/config/greynetic.xml.h:3
+#: ../hacks/config/halftone.xml.h:3 ../hacks/config/halo.xml.h:3
+#: ../hacks/config/handsy.xml.h:3 ../hacks/config/headroom.xml.h:3
+#: ../hacks/config/helix.xml.h:3 ../hacks/config/hexadrop.xml.h:3
+#: ../hacks/config/hexstrut.xml.h:3 ../hacks/config/hilbert.xml.h:9
+#: ../hacks/config/hopalong.xml.h:3 ../hacks/config/hydrostat.xml.h:3
+#: ../hacks/config/hyperball.xml.h:3 ../hacks/config/hypercube.xml.h:3
+#: ../hacks/config/hypertorus.xml.h:3 ../hacks/config/hypnowheel.xml.h:3
+#: ../hacks/config/ifs.xml.h:3 ../hacks/config/imsmap.xml.h:3
+#: ../hacks/config/interaggregate.xml.h:3 ../hacks/config/interference.xml.h:3
+#: ../hacks/config/intermomentary.xml.h:3 ../hacks/config/jigglypuff.xml.h:12
+#: ../hacks/config/jigsaw.xml.h:3 ../hacks/config/juggle.xml.h:3
+#: ../hacks/config/juggler3d.xml.h:3 ../hacks/config/julia.xml.h:3
+#: ../hacks/config/kaleidescope.xml.h:3 ../hacks/config/kaleidocycle.xml.h:3
+#: ../hacks/config/klein.xml.h:45 ../hacks/config/kumppa.xml.h:3
+#: ../hacks/config/lament.xml.h:3 ../hacks/config/laser.xml.h:3
+#: ../hacks/config/lavalite.xml.h:3 ../hacks/config/lcdscrub.xml.h:3
+#: ../hacks/config/lightning.xml.h:3 ../hacks/config/lisa.xml.h:3
+#: ../hacks/config/lissie.xml.h:3 ../hacks/config/lmorph.xml.h:3
+#: ../hacks/config/lockward.xml.h:3 ../hacks/config/loop.xml.h:3
+#: ../hacks/config/mapscroller.xml.h:3 ../hacks/config/marbling.xml.h:3
+#: ../hacks/config/maze.xml.h:3 ../hacks/config/maze3d.xml.h:6
+#: ../hacks/config/memscroller.xml.h:3 ../hacks/config/menger.xml.h:3
+#: ../hacks/config/metaballs.xml.h:3 ../hacks/config/mirrorblob.xml.h:3
+#: ../hacks/config/mismunch.xml.h:3 ../hacks/config/moebius.xml.h:3
+#: ../hacks/config/moebiusgears.xml.h:3 ../hacks/config/moire2.xml.h:3
+#: ../hacks/config/molecule.xml.h:3 ../hacks/config/morph3d.xml.h:3
+#: ../hacks/config/mountain.xml.h:3 ../hacks/config/munch.xml.h:3
+#: ../hacks/config/nakagin.xml.h:3 ../hacks/config/nerverot.xml.h:3
+#: ../hacks/config/noof.xml.h:3 ../hacks/config/pacman.xml.h:3
+#: ../hacks/config/peepers.xml.h:3 ../hacks/config/penrose.xml.h:3
+#: ../hacks/config/petri.xml.h:3 ../hacks/config/phosphor.xml.h:3
+#: ../hacks/config/photopile.xml.h:16 ../hacks/config/piecewise.xml.h:3
+#: ../hacks/config/pinion.xml.h:3 ../hacks/config/pipes.xml.h:3
+#: ../hacks/config/polyhedra.xml.h:3 ../hacks/config/polyominoes.xml.h:4
+#: ../hacks/config/polytopes.xml.h:25 ../hacks/config/popsquares.xml.h:3
+#: ../hacks/config/projectiveplane.xml.h:38 ../hacks/config/providence.xml.h:3
+#: ../hacks/config/pulsar.xml.h:3 ../hacks/config/pyro.xml.h:3
+#: ../hacks/config/qix.xml.h:3 ../hacks/config/quasicrystal.xml.h:3
+#: ../hacks/config/queens.xml.h:3 ../hacks/config/raverhoop.xml.h:3
+#: ../hacks/config/razzledazzle.xml.h:3 ../hacks/config/ripples.xml.h:3
+#: ../hacks/config/rocks.xml.h:3 ../hacks/config/romanboy.xml.h:41
+#: ../hacks/config/rotor.xml.h:3 ../hacks/config/rotzoomer.xml.h:3
+#: ../hacks/config/rubik.xml.h:3 ../hacks/config/rubikblocks.xml.h:3
+#: ../hacks/config/sballs.xml.h:3 ../hacks/config/scooter.xml.h:3
+#: ../hacks/config/shadebobs.xml.h:3 ../hacks/config/sierpinski.xml.h:3
+#: ../hacks/config/sierpinski3d.xml.h:3 ../hacks/config/skytentacles.xml.h:16
+#: ../hacks/config/slidescreen.xml.h:3 ../hacks/config/slip.xml.h:3
+#: ../hacks/config/sonar.xml.h:3 ../hacks/config/speedmine.xml.h:3
+#: ../hacks/config/sphere.xml.h:3 ../hacks/config/spheremonics.xml.h:3
+#: ../hacks/config/spiral.xml.h:3 ../hacks/config/splitflap.xml.h:3
+#: ../hacks/config/splodesic.xml.h:3 ../hacks/config/spotlight.xml.h:3
+#: ../hacks/config/sproingies.xml.h:3 ../hacks/config/squiral.xml.h:3
+#: ../hacks/config/squirtorus.xml.h:3 ../hacks/config/stairs.xml.h:3
+#: ../hacks/config/starfish.xml.h:6 ../hacks/config/stonerview.xml.h:3
+#: ../hacks/config/strange.xml.h:3 ../hacks/config/substrate.xml.h:3
+#: ../hacks/config/superquadrics.xml.h:3 ../hacks/config/surfaces.xml.h:3
+#: ../hacks/config/swirl.xml.h:3 ../hacks/config/t3d.xml.h:3
+#: ../hacks/config/tangram.xml.h:3 ../hacks/config/tessellimage.xml.h:3
+#: ../hacks/config/thornbird.xml.h:3 ../hacks/config/topblock.xml.h:3
+#: ../hacks/config/triangle.xml.h:3 ../hacks/config/tronbit.xml.h:3
+#: ../hacks/config/truchet.xml.h:3 ../hacks/config/twang.xml.h:3
+#: ../hacks/config/unicrud.xml.h:3 ../hacks/config/unknownpleasures.xml.h:3
+#: ../hacks/config/vigilance.xml.h:3 ../hacks/config/vines.xml.h:3
+#: ../hacks/config/voronoi.xml.h:3 ../hacks/config/wander.xml.h:3
+#: ../hacks/config/winduprobot.xml.h:3 ../hacks/config/worm.xml.h:3
+#: ../hacks/config/wormhole.xml.h:3 ../hacks/config/xflame.xml.h:3
+#: ../hacks/config/xlyap.xml.h:3 ../hacks/config/xmatrix.xml.h:16
+#: ../hacks/config/xrayswarm.xml.h:3 ../hacks/config/xspirograph.xml.h:3
+#: ../hacks/config/zoom.xml.h:3
+msgid "Frame rate"
+msgstr "კადრების სიხშირე"
+
+#. <video href="https://www.youtube.com/watch?v=OZ6zRLLFLk4"/>
+#: ../hacks/config/anemotaxis.xml.h:4 ../hacks/config/ant.xml.h:4
+#: ../hacks/config/antinspect.xml.h:4 ../hacks/config/antmaze.xml.h:4
+#: ../hacks/config/antspotlight.xml.h:4 ../hacks/config/apple2.xml.h:12
+#: ../hacks/config/atlantis.xml.h:4 ../hacks/config/attraction.xml.h:13
+#: ../hacks/config/atunnel.xml.h:4 ../hacks/config/barcode.xml.h:4
+#: ../hacks/config/beats.xml.h:4 ../hacks/config/binaryhorizon.xml.h:4
+#: ../hacks/config/binaryring.xml.h:4 ../hacks/config/blaster.xml.h:4
+#: ../hacks/config/blinkbox.xml.h:4 ../hacks/config/blocktube.xml.h:4
+#: ../hacks/config/bouboule.xml.h:4 ../hacks/config/bouncingcow.xml.h:4
+#: ../hacks/config/boxed.xml.h:4 ../hacks/config/boxfit.xml.h:4
+#: ../hacks/config/braid.xml.h:4 ../hacks/config/bubble3d.xml.h:4
+#: ../hacks/config/bubbles.xml.h:4 ../hacks/config/bumps.xml.h:4
+#: ../hacks/config/cage.xml.h:4 ../hacks/config/carousel.xml.h:4
+#: ../hacks/config/ccurve.xml.h:10 ../hacks/config/celtic.xml.h:4
+#: ../hacks/config/chompytower.xml.h:4 ../hacks/config/circuit.xml.h:4
+#: ../hacks/config/cityflow.xml.h:4 ../hacks/config/cloudlife.xml.h:4
+#: ../hacks/config/companioncube.xml.h:4 ../hacks/config/compass.xml.h:4
+#: ../hacks/config/coral.xml.h:4 ../hacks/config/covid19.xml.h:4
+#: ../hacks/config/crackberg.xml.h:4 ../hacks/config/critical.xml.h:4
+#: ../hacks/config/crumbler.xml.h:4 ../hacks/config/crystal.xml.h:4
+#: ../hacks/config/cube21.xml.h:4 ../hacks/config/cubenetic.xml.h:4
+#: ../hacks/config/cubestack.xml.h:4 ../hacks/config/cubestorm.xml.h:4
+#: ../hacks/config/cubetwist.xml.h:4 ../hacks/config/cubicgrid.xml.h:4
+#: ../hacks/config/cwaves.xml.h:4 ../hacks/config/cynosure.xml.h:4
+#: ../hacks/config/dangerball.xml.h:4 ../hacks/config/decayscreen.xml.h:4
+#: ../hacks/config/deepstars.xml.h:4 ../hacks/config/deluxe.xml.h:4
+#: ../hacks/config/demon.xml.h:4 ../hacks/config/discoball.xml.h:4
+#: ../hacks/config/discrete.xml.h:4 ../hacks/config/distort.xml.h:4
+#: ../hacks/config/dnalogo.xml.h:4 ../hacks/config/drift.xml.h:4
+#: ../hacks/config/dymaxionmap.xml.h:4 ../hacks/config/endgame.xml.h:4
+#: ../hacks/config/engine.xml.h:4 ../hacks/config/epicycle.xml.h:4
+#: ../hacks/config/eruption.xml.h:4 ../hacks/config/esper.xml.h:4
+#: ../hacks/config/etruscanvenus.xml.h:41 ../hacks/config/euler2d.xml.h:4
+#: ../hacks/config/extrusion.xml.h:4 ../hacks/config/fadeplot.xml.h:4
+#: ../hacks/config/fiberlamp.xml.h:4 ../hacks/config/filmleader.xml.h:4
+#: ../hacks/config/fireworkx.xml.h:4 ../hacks/config/flag.xml.h:5
+#: ../hacks/config/flame.xml.h:4 ../hacks/config/flipflop.xml.h:4
+#: ../hacks/config/flipscreen3d.xml.h:4 ../hacks/config/fliptext.xml.h:4
+#: ../hacks/config/flow.xml.h:4 ../hacks/config/fluidballs.xml.h:4
+#: ../hacks/config/flyingtoasters.xml.h:4 ../hacks/config/fontglide.xml.h:4
+#: ../hacks/config/forest.xml.h:4 ../hacks/config/fuzzyflakes.xml.h:4
+#: ../hacks/config/galaxy.xml.h:4 ../hacks/config/gears.xml.h:4
+#: ../hacks/config/geodesic.xml.h:13 ../hacks/config/geodesicgears.xml.h:4
+#: ../hacks/config/gflux.xml.h:4 ../hacks/config/gibson.xml.h:4
+#: ../hacks/config/glblur.xml.h:4 ../hacks/config/glcells.xml.h:4
+#: ../hacks/config/gleidescope.xml.h:4 ../hacks/config/glforestfire.xml.h:4
+#: ../hacks/config/glhanoi.xml.h:4 ../hacks/config/glitchpeg.xml.h:4
+#: ../hacks/config/glknots.xml.h:4 ../hacks/config/glmatrix.xml.h:4
+#: ../hacks/config/glplanet.xml.h:7 ../hacks/config/glschool.xml.h:4
+#: ../hacks/config/glslideshow.xml.h:4 ../hacks/config/glsnake.xml.h:4
+#: ../hacks/config/gltext.xml.h:4 ../hacks/config/goop.xml.h:4
+#: ../hacks/config/grav.xml.h:4 ../hacks/config/gravitywell.xml.h:4
+#: ../hacks/config/greynetic.xml.h:4 ../hacks/config/halftone.xml.h:4
+#: ../hacks/config/halo.xml.h:4 ../hacks/config/handsy.xml.h:4
+#: ../hacks/config/headroom.xml.h:4 ../hacks/config/helix.xml.h:4
+#: ../hacks/config/hexadrop.xml.h:4 ../hacks/config/hexstrut.xml.h:4
+#: ../hacks/config/hopalong.xml.h:4 ../hacks/config/hydrostat.xml.h:4
+#: ../hacks/config/hyperball.xml.h:4 ../hacks/config/hypercube.xml.h:4
+#: ../hacks/config/hypertorus.xml.h:4 ../hacks/config/hypnowheel.xml.h:16
+#: ../hacks/config/ifs.xml.h:4 ../hacks/config/imsmap.xml.h:4
+#: ../hacks/config/interaggregate.xml.h:4 ../hacks/config/interference.xml.h:4
+#: ../hacks/config/intermomentary.xml.h:4 ../hacks/config/jigglypuff.xml.h:13
+#: ../hacks/config/jigsaw.xml.h:4 ../hacks/config/juggle.xml.h:4
+#: ../hacks/config/juggler3d.xml.h:4 ../hacks/config/julia.xml.h:4
+#: ../hacks/config/kaleidescope.xml.h:4 ../hacks/config/kaleidocycle.xml.h:4
+#: ../hacks/config/klein.xml.h:46 ../hacks/config/kumppa.xml.h:4
+#: ../hacks/config/lament.xml.h:4 ../hacks/config/laser.xml.h:4
+#: ../hacks/config/lavalite.xml.h:4 ../hacks/config/lcdscrub.xml.h:4
+#: ../hacks/config/lightning.xml.h:4 ../hacks/config/lisa.xml.h:4
+#: ../hacks/config/lissie.xml.h:4 ../hacks/config/lmorph.xml.h:4
+#: ../hacks/config/lockward.xml.h:4 ../hacks/config/loop.xml.h:4
+#: ../hacks/config/m6502.xml.h:9 ../hacks/config/mapscroller.xml.h:4
+#: ../hacks/config/marbling.xml.h:4 ../hacks/config/maze.xml.h:4
+#: ../hacks/config/maze3d.xml.h:7 ../hacks/config/memscroller.xml.h:4
+#: ../hacks/config/menger.xml.h:4 ../hacks/config/metaballs.xml.h:4
+#: ../hacks/config/mirrorblob.xml.h:4 ../hacks/config/mismunch.xml.h:4
+#: ../hacks/config/moebius.xml.h:4 ../hacks/config/moebiusgears.xml.h:4
+#: ../hacks/config/moire2.xml.h:4 ../hacks/config/molecule.xml.h:4
+#: ../hacks/config/morph3d.xml.h:4 ../hacks/config/mountain.xml.h:4
+#: ../hacks/config/munch.xml.h:4 ../hacks/config/nakagin.xml.h:4
+#: ../hacks/config/nerverot.xml.h:4 ../hacks/config/noof.xml.h:4
+#: ../hacks/config/pacman.xml.h:4 ../hacks/config/peepers.xml.h:4
+#: ../hacks/config/penrose.xml.h:4 ../hacks/config/petri.xml.h:4
+#: ../hacks/config/phosphor.xml.h:4 ../hacks/config/photopile.xml.h:17
+#: ../hacks/config/piecewise.xml.h:4 ../hacks/config/pinion.xml.h:4
+#: ../hacks/config/pipes.xml.h:4 ../hacks/config/polyhedra.xml.h:4
+#: ../hacks/config/polyominoes.xml.h:5 ../hacks/config/polytopes.xml.h:26
+#: ../hacks/config/pong.xml.h:12 ../hacks/config/popsquares.xml.h:4
+#: ../hacks/config/projectiveplane.xml.h:39 ../hacks/config/providence.xml.h:4
+#: ../hacks/config/pulsar.xml.h:4 ../hacks/config/pyro.xml.h:13
+#: ../hacks/config/qix.xml.h:4 ../hacks/config/quasicrystal.xml.h:4
+#: ../hacks/config/queens.xml.h:4 ../hacks/config/raverhoop.xml.h:4
+#: ../hacks/config/razzledazzle.xml.h:4 ../hacks/config/ripples.xml.h:4
+#: ../hacks/config/rocks.xml.h:4 ../hacks/config/romanboy.xml.h:42
+#: ../hacks/config/rotor.xml.h:4 ../hacks/config/rotzoomer.xml.h:4
+#: ../hacks/config/rubik.xml.h:4 ../hacks/config/rubikblocks.xml.h:4
+#: ../hacks/config/sballs.xml.h:4 ../hacks/config/scooter.xml.h:4
+#: ../hacks/config/shadebobs.xml.h:4 ../hacks/config/sierpinski.xml.h:4
+#: ../hacks/config/sierpinski3d.xml.h:4 ../hacks/config/skytentacles.xml.h:13
+#: ../hacks/config/slidescreen.xml.h:4 ../hacks/config/slip.xml.h:4
+#: ../hacks/config/sonar.xml.h:4 ../hacks/config/speedmine.xml.h:4
+#: ../hacks/config/sphere.xml.h:4 ../hacks/config/spheremonics.xml.h:4
+#: ../hacks/config/spiral.xml.h:4 ../hacks/config/splitflap.xml.h:4
+#: ../hacks/config/splodesic.xml.h:4 ../hacks/config/spotlight.xml.h:4
+#: ../hacks/config/sproingies.xml.h:4 ../hacks/config/squiral.xml.h:4
+#: ../hacks/config/squirtorus.xml.h:4 ../hacks/config/stairs.xml.h:4
+#: ../hacks/config/starfish.xml.h:7 ../hacks/config/starwars.xml.h:3
+#: ../hacks/config/stonerview.xml.h:4 ../hacks/config/strange.xml.h:4
+#: ../hacks/config/substrate.xml.h:4 ../hacks/config/superquadrics.xml.h:4
+#: ../hacks/config/surfaces.xml.h:4 ../hacks/config/swirl.xml.h:4
+#: ../hacks/config/t3d.xml.h:4 ../hacks/config/tangram.xml.h:4
+#: ../hacks/config/tessellimage.xml.h:4 ../hacks/config/thornbird.xml.h:4
+#: ../hacks/config/topblock.xml.h:4 ../hacks/config/triangle.xml.h:4
+#: ../hacks/config/tronbit.xml.h:4 ../hacks/config/truchet.xml.h:4
+#: ../hacks/config/twang.xml.h:4 ../hacks/config/unicrud.xml.h:4
+#: ../hacks/config/unknownpleasures.xml.h:4 ../hacks/config/vfeedback.xml.h:4
+#: ../hacks/config/vigilance.xml.h:4 ../hacks/config/vines.xml.h:4
+#: ../hacks/config/wander.xml.h:4 ../hacks/config/whirlygig.xml.h:6
+#: ../hacks/config/winduprobot.xml.h:4 ../hacks/config/worm.xml.h:4
+#: ../hacks/config/wormhole.xml.h:4 ../hacks/config/xanalogtv.xml.h:6
+#: ../hacks/config/xflame.xml.h:4 ../hacks/config/xlyap.xml.h:4
+#: ../hacks/config/xmatrix.xml.h:17 ../hacks/config/xrayswarm.xml.h:4
+#: ../hacks/config/xspirograph.xml.h:4 ../hacks/config/zoom.xml.h:4
+msgid "High"
+msgstr "მაღალი"
+
+#: ../hacks/config/anemotaxis.xml.h:5 ../hacks/config/hyperball.xml.h:5
+#: ../hacks/config/hypercube.xml.h:5
+msgid "Near"
+msgstr "ახლოს"
+
+#: ../hacks/config/anemotaxis.xml.h:6
+msgid "Distance"
+msgstr "მანძილი"
+
+#: ../hacks/config/anemotaxis.xml.h:7 ../hacks/config/cubicgrid.xml.h:10
+#: ../hacks/config/hyperball.xml.h:7 ../hacks/config/hypercube.xml.h:7
+msgid "Far"
+msgstr "შორს"
+
+#: ../hacks/config/anemotaxis.xml.h:9
+msgid "Sources"
+msgstr "წყაროები"
+
+#: ../hacks/config/anemotaxis.xml.h:11
+msgid "Searchers"
+msgstr "მძებნელები"
+
+#: ../hacks/config/anemotaxis.xml.h:13
+msgid ""
+"Searches for a source of odor in a turbulent atmosphere. The searcher is "
+"able to sense the odor and determine local instantaneous wind direction. The "
+"goal is to find the source in the shortest mean time. https://"
+"en.wikipedia.org/wiki/Anemotaxis Written by Eugene Balkovsky; 2004."
+msgstr ""
+
+#: ../hacks/config/ant.xml.h:1
+msgid "Ant"
+msgstr "ჭიანჭველა"
+
+#: ../hacks/config/ant.xml.h:5 ../hacks/config/attraction.xml.h:21
+#: ../hacks/config/blinkbox.xml.h:5 ../hacks/config/cityflow.xml.h:12
+#: ../hacks/config/cloudlife.xml.h:9 ../hacks/config/cube21.xml.h:5
+#: ../hacks/config/cubenetic.xml.h:20 ../hacks/config/demon.xml.h:8
+#: ../hacks/config/discoball.xml.h:8 ../hacks/config/discrete.xml.h:5
+#: ../hacks/config/distort.xml.h:8 ../hacks/config/fadeplot.xml.h:8
+#: ../hacks/config/flag.xml.h:6 ../hacks/config/flow.xml.h:8
+#: ../hacks/config/fluidballs.xml.h:8 ../hacks/config/fuzzyflakes.xml.h:25
+#: ../hacks/config/glcells.xml.h:11 ../hacks/config/gleidescope.xml.h:5
+#: ../hacks/config/halftone.xml.h:8 ../hacks/config/hexadrop.xml.h:8
+#: ../hacks/config/hexstrut.xml.h:8 ../hacks/config/hopalong.xml.h:5
+#: ../hacks/config/hydrostat.xml.h:11 ../hacks/config/interference.xml.h:8
+#: ../hacks/config/julia.xml.h:8 ../hacks/config/lisa.xml.h:10
+#: ../hacks/config/lissie.xml.h:5 ../hacks/config/loop.xml.h:5
+#: ../hacks/config/metaballs.xml.h:12 ../hacks/config/moire.xml.h:8
+#: ../hacks/config/penrose.xml.h:8 ../hacks/config/photopile.xml.h:2
+#: ../hacks/config/piecewise.xml.h:11 ../hacks/config/rorschach.xml.h:2
+#: ../hacks/config/rubikblocks.xml.h:5 ../hacks/config/sierpinski.xml.h:8
+#: ../hacks/config/slidescreen.xml.h:14 ../hacks/config/slip.xml.h:8
+#: ../hacks/config/spotlight.xml.h:8 ../hacks/config/squiral.xml.h:7
+#: ../hacks/config/topblock.xml.h:8 ../hacks/config/twang.xml.h:14
+msgid "Small"
+msgstr "პატარა"
+
+#: ../hacks/config/ant.xml.h:6 ../hacks/config/demon.xml.h:9
+#: ../hacks/config/discrete.xml.h:6 ../hacks/config/flag.xml.h:7
+#: ../hacks/config/flow.xml.h:9 ../hacks/config/lissie.xml.h:6
+#: ../hacks/config/loop.xml.h:6 ../hacks/config/sierpinski.xml.h:9
+#: ../hacks/config/slip.xml.h:9
+msgid "Timeout"
+msgstr "ვადა"
+
+#: ../hacks/config/ant.xml.h:7 ../hacks/config/attraction.xml.h:23
+#: ../hacks/config/blinkbox.xml.h:7 ../hacks/config/cityflow.xml.h:14
+#: ../hacks/config/cloudlife.xml.h:11 ../hacks/config/cube21.xml.h:7
+#: ../hacks/config/cubenetic.xml.h:22 ../hacks/config/demon.xml.h:10
+#: ../hacks/config/discoball.xml.h:10 ../hacks/config/discrete.xml.h:7
+#: ../hacks/config/distort.xml.h:10 ../hacks/config/fadeplot.xml.h:10
+#: ../hacks/config/flag.xml.h:8 ../hacks/config/flow.xml.h:10
+#: ../hacks/config/fluidballs.xml.h:10 ../hacks/config/fuzzyflakes.xml.h:27
+#: ../hacks/config/glcells.xml.h:27 ../hacks/config/gleidescope.xml.h:7
+#: ../hacks/config/halftone.xml.h:12 ../hacks/config/hexadrop.xml.h:10
+#: ../hacks/config/hexstrut.xml.h:10 ../hacks/config/hopalong.xml.h:7
+#: ../hacks/config/hydrostat.xml.h:13 ../hacks/config/interference.xml.h:10
+#: ../hacks/config/julia.xml.h:10 ../hacks/config/lisa.xml.h:12
+#: ../hacks/config/lissie.xml.h:7 ../hacks/config/loop.xml.h:7
+#: ../hacks/config/moire.xml.h:10 ../hacks/config/penrose.xml.h:10
+#: ../hacks/config/photopile.xml.h:4 ../hacks/config/piecewise.xml.h:13
+#: ../hacks/config/rorschach.xml.h:4 ../hacks/config/rubikblocks.xml.h:7
+#: ../hacks/config/sierpinski.xml.h:10 ../hacks/config/slidescreen.xml.h:16
+#: ../hacks/config/slip.xml.h:10 ../hacks/config/spotlight.xml.h:10
+#: ../hacks/config/squiral.xml.h:9 ../hacks/config/topblock.xml.h:10
+#: ../hacks/config/twang.xml.h:16
+msgid "Large"
+msgstr "დიდი"
+
+#: ../hacks/config/ant.xml.h:8
+msgid "Sharp turns"
+msgstr "მკვეთრი მოსახვევები"
+
+#: ../hacks/config/ant.xml.h:9
+msgid "Truchet lines"
+msgstr "ტრუშეს ხაზები"
+
+#: ../hacks/config/ant.xml.h:10
+msgid "Draw eyes"
+msgstr "თვალების დახატვა"
+
+#: ../hacks/config/ant.xml.h:11
+msgid "Three"
+msgstr "სამი"
+
+#.
+#. On a 2.93 gHz iMac i7, I get these rates with -delay 0:
+#.
+#. detail 3:  invisible
+#. detail 4:  barely visible
+#. detail 5:  1000+ fps, looks like noise at -delay 0, ok at -delay 20000
+#. detail 8:  ~700+ fps
+#. detail 9:  ~400 fps
+#. detail 10: ~300 fps
+#. detail 11: ~100 fps
+#. detail 12:  ~50 fps
+#. detail 13:  ~17 fps
+#. detail 14:   ~8 fps
+#. detail 15:   ~2 fps
+#.
+#. With the default -delay, CPU load only starts causing the frame rate
+#. to drop below 30 fps detail 12 or higher.
+#.
+#: ../hacks/config/ant.xml.h:12 ../hacks/config/apollonian.xml.h:8
+#: ../hacks/config/attraction.xml.h:18 ../hacks/config/bouboule.xml.h:9
+#: ../hacks/config/braid.xml.h:9 ../hacks/config/critical.xml.h:6
+#: ../hacks/config/crystal.xml.h:6 ../hacks/config/cynosure.xml.h:6
+#: ../hacks/config/deco.xml.h:6 ../hacks/config/deluxe.xml.h:12
+#: ../hacks/config/demon.xml.h:12 ../hacks/config/discrete.xml.h:9
+#: ../hacks/config/drift.xml.h:9 ../hacks/config/epicycle.xml.h:6
+#: ../hacks/config/eruption.xml.h:6 ../hacks/config/euler2d.xml.h:13
+#: ../hacks/config/fadeplot.xml.h:12 ../hacks/config/flag.xml.h:10
+#: ../hacks/config/flame.xml.h:13 ../hacks/config/flow.xml.h:12
+#: ../hacks/config/forest.xml.h:6 ../hacks/config/galaxy.xml.h:10
+#: ../hacks/config/grav.xml.h:9 ../hacks/config/halo.xml.h:9
+#: ../hacks/config/hopalong.xml.h:10 ../hacks/config/ifs.xml.h:45
+#: ../hacks/config/imsmap.xml.h:12 ../hacks/config/interference.xml.h:16
+#: ../hacks/config/julia.xml.h:12 ../hacks/config/laser.xml.h:10
+#: ../hacks/config/lightning.xml.h:6 ../hacks/config/lisa.xml.h:9
+#: ../hacks/config/lissie.xml.h:9 ../hacks/config/loop.xml.h:9
+#: ../hacks/config/metaballs.xml.h:9 ../hacks/config/moire.xml.h:6
+#: ../hacks/config/moire2.xml.h:6 ../hacks/config/mountain.xml.h:9
+#: ../hacks/config/penrose.xml.h:6 ../hacks/config/polyominoes.xml.h:10
+#: ../hacks/config/popsquares.xml.h:7 ../hacks/config/rocks.xml.h:15
+#: ../hacks/config/rotor.xml.h:9 ../hacks/config/scooter.xml.h:15
+#: ../hacks/config/shadebobs.xml.h:6 ../hacks/config/sierpinski.xml.h:12
+#: ../hacks/config/slip.xml.h:12 ../hacks/config/sphere.xml.h:6
+#: ../hacks/config/spiral.xml.h:10 ../hacks/config/squiral.xml.h:17
+#: ../hacks/config/starfish.xml.h:15 ../hacks/config/strange.xml.h:21
+#: ../hacks/config/swirl.xml.h:9 ../hacks/config/triangle.xml.h:6
+#: ../hacks/config/vines.xml.h:6 ../hacks/config/worm.xml.h:6
+msgid "Number of colors"
+msgstr "ფერების რაოდენობა"
+
+#: ../hacks/config/ant.xml.h:14
+msgid "Ants count"
+msgstr "ჭიანჭველების რაოდენობა"
+
+#: ../hacks/config/ant.xml.h:15
+msgid "Ant size"
+msgstr "ჭიანჭველების ზომა"
+
+#: ../hacks/config/ant.xml.h:16
+msgid "Random cell shape"
+msgstr "უჯრედის შემთხვევითი ფორმა"
+
+#: ../hacks/config/ant.xml.h:17
+msgid "Three sided cells"
+msgstr "სამკედლიანი უჯრედები"
+
+#: ../hacks/config/ant.xml.h:18
+msgid "Four sided cells"
+msgstr "ოთხკედლიანი უჯრედები"
+
+#: ../hacks/config/ant.xml.h:19
+msgid "Six sided cells"
+msgstr "ექვსკედლიანი უჯრედები"
+
+#: ../hacks/config/ant.xml.h:20
+msgid "Nine sided cells"
+msgstr "ცხრაკედლიანი უჯრედები"
+
+#: ../hacks/config/ant.xml.h:21
+msgid "Twelve sided cells"
+msgstr "თორმეტკედლიანი უჯრედები"
+
+#: ../hacks/config/ant.xml.h:24
+#, no-c-format
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 4.22. A cellular automaton that is really a two-dimensional Turing "
+"machine: as the heads (\"ants\") walk along the screen, they change pixel "
+"values in their path. Then, as they pass over changed pixels, their behavior "
+"is influenced. https://en.wikipedia.org/wiki/Langton%27s_ant https://"
+"en.wikipedia.org/wiki/Turing_machine Written by David Bagley; 1997."
+msgstr ""
+
+#: ../hacks/config/antinspect.xml.h:1
+msgid "Ant Inspect"
+msgstr "ჭიანჭველა ამოწმებს"
+
+#: ../hacks/config/antinspect.xml.h:6
+msgid "Draw shadows"
+msgstr "ჩრდილების დახატვა"
+
+#: ../hacks/config/antinspect.xml.h:7
+msgid "Ants move spheres around a circle. Written by Blair Tennessy; 2004."
+msgstr ""
+
+#: ../hacks/config/antmaze.xml.h:1
+msgid "Ant Maze"
+msgstr "ჭიანჭველების ლაბირინთი"
+
+#: ../hacks/config/antmaze.xml.h:6
+msgid "Ants walk around a simple maze. Written by Blair Tennessy; 2005."
+msgstr ""
+
+#: ../hacks/config/antspotlight.xml.h:1
+msgid "Ant Spotlight"
+msgstr "ჭიანჭველა-ფანარი"
+
+#: ../hacks/config/antspotlight.xml.h:6
+msgid "An ant walks over an image. Written by Blair Tennessy; 2003."
+msgstr ""
+
+#: ../hacks/config/apollonian.xml.h:1
+msgid "Apollonian"
+msgstr "აპოლონისთვის მიძღვნილი"
+
+#: ../hacks/config/apollonian.xml.h:2 ../hacks/config/tangram.xml.h:13
+msgid "Draw labels"
+msgstr "ჭდეების დახატვა"
+
+#: ../hacks/config/apollonian.xml.h:3
+msgid "Include alternate geometries"
+msgstr "ალტერნატიული გეომეტრიების ჩასმა"
+
+#: ../hacks/config/apollonian.xml.h:4 ../hacks/config/tessellimage.xml.h:11
+msgid "Shallow"
+msgstr "მარჩხი"
+
+#: ../hacks/config/apollonian.xml.h:5 ../hacks/config/flipflop.xml.h:11
+#: ../hacks/config/geodesic.xml.h:18 ../hacks/config/splodesic.xml.h:8
+msgid "Depth"
+msgstr "სიღრმე"
+
+#: ../hacks/config/apollonian.xml.h:6 ../hacks/config/tessellimage.xml.h:13
+msgid "Deep"
+msgstr "ღრმა"
+
+#: ../hacks/config/apollonian.xml.h:7 ../hacks/config/attraction.xml.h:17
+#: ../hacks/config/bouboule.xml.h:8 ../hacks/config/braid.xml.h:8
+#: ../hacks/config/critical.xml.h:5 ../hacks/config/crystal.xml.h:5
+#: ../hacks/config/cynosure.xml.h:5 ../hacks/config/deco.xml.h:5
+#: ../hacks/config/deluxe.xml.h:11 ../hacks/config/demon.xml.h:11
+#: ../hacks/config/discrete.xml.h:8 ../hacks/config/drift.xml.h:8
+#: ../hacks/config/epicycle.xml.h:5 ../hacks/config/euler2d.xml.h:12
+#: ../hacks/config/fadeplot.xml.h:11 ../hacks/config/flag.xml.h:9
+#: ../hacks/config/flame.xml.h:12 ../hacks/config/flow.xml.h:11
+#: ../hacks/config/forest.xml.h:5 ../hacks/config/galaxy.xml.h:9
+#: ../hacks/config/grav.xml.h:8 ../hacks/config/halo.xml.h:8
+#: ../hacks/config/handsy.xml.h:8 ../hacks/config/hopalong.xml.h:9
+#: ../hacks/config/imsmap.xml.h:11 ../hacks/config/interference.xml.h:15
+#: ../hacks/config/julia.xml.h:11 ../hacks/config/laser.xml.h:9
+#: ../hacks/config/lightning.xml.h:5 ../hacks/config/lisa.xml.h:8
+#: ../hacks/config/lissie.xml.h:8 ../hacks/config/loop.xml.h:8
+#: ../hacks/config/metaballs.xml.h:8 ../hacks/config/moire.xml.h:5
+#: ../hacks/config/moire2.xml.h:5 ../hacks/config/mountain.xml.h:8
+#: ../hacks/config/nerverot.xml.h:11 ../hacks/config/penrose.xml.h:5
+#: ../hacks/config/polyominoes.xml.h:9 ../hacks/config/rocks.xml.h:14
+#: ../hacks/config/rotor.xml.h:8 ../hacks/config/shadebobs.xml.h:5
+#: ../hacks/config/sierpinski.xml.h:11 ../hacks/config/slip.xml.h:11
+#: ../hacks/config/sphere.xml.h:5 ../hacks/config/spiral.xml.h:9
+#: ../hacks/config/squiral.xml.h:16 ../hacks/config/starfish.xml.h:14
+#: ../hacks/config/strange.xml.h:20 ../hacks/config/swirl.xml.h:8
+#: ../hacks/config/triangle.xml.h:5 ../hacks/config/vines.xml.h:5
+#: ../hacks/config/worm.xml.h:5
+msgid "Two"
+msgstr "ორი"
+
+#: ../hacks/config/apollonian.xml.h:15
+#, no-c-format
+msgid ""
+"A fractal packing of circles with smaller circles, demonstrating Descartes's "
+"theorem. https://en.wikipedia.org/wiki/Apollonian_gasket https://"
+"en.wikipedia.org/wiki/Descartes%27_theorem Written by Allan R. Wilks and "
+"David Bagley; 2002."
+msgstr ""
+
+#: ../hacks/config/apple2.xml.h:1 ../hacks/config/bsod.xml.h:14
+msgid "Apple ]["
+msgstr "Apple ]["
+
+#: ../hacks/config/apple2.xml.h:2
+msgid "Choose display mode randomly"
+msgstr "ჩვენების რეჟიმის შემთხვევითი არჩვა"
+
+#: ../hacks/config/apple2.xml.h:3
+msgid "Display scrolling text"
+msgstr "მოძრავი ტექსტის ჩვენება"
+
+#: ../hacks/config/apple2.xml.h:4
+msgid "Display images"
+msgstr "გამოსახულებების ჩვენება"
+
+#: ../hacks/config/apple2.xml.h:5
+msgid "Run basic programs"
+msgstr "მარტივი პროგრამების გაშვება"
+
+#: ../hacks/config/apple2.xml.h:6 ../hacks/config/blitspin.xml.h:6
+#: ../hacks/config/bumps.xml.h:5 ../hacks/config/decayscreen.xml.h:5
+#: ../hacks/config/distort.xml.h:5 ../hacks/config/flame.xml.h:7
+#: ../hacks/config/gleidescope.xml.h:8 ../hacks/config/glslideshow.xml.h:5
+#: ../hacks/config/maze.xml.h:15 ../hacks/config/ripples.xml.h:5
+#: ../hacks/config/rotzoomer.xml.h:5 ../hacks/config/slidescreen.xml.h:8
+#: ../hacks/config/spotlight.xml.h:5 ../hacks/config/tessellimage.xml.h:8
+#: ../hacks/config/twang.xml.h:5 ../hacks/config/zoom.xml.h:5
+msgid "10 seconds"
+msgstr "10 წამი"
+
+#: ../hacks/config/apple2.xml.h:7 ../hacks/config/binaryhorizon.xml.h:9
+#: ../hacks/config/blitspin.xml.h:7 ../hacks/config/braid.xml.h:6
+#: ../hacks/config/bsod.xml.h:3 ../hacks/config/bumps.xml.h:6
+#: ../hacks/config/cynosure.xml.h:9 ../hacks/config/decayscreen.xml.h:6
+#: ../hacks/config/deco.xml.h:3 ../hacks/config/distort.xml.h:6
+#: ../hacks/config/drift.xml.h:6 ../hacks/config/eruption.xml.h:20
+#: ../hacks/config/euler2d.xml.h:11 ../hacks/config/galaxy.xml.h:7
+#: ../hacks/config/geodesicgears.xml.h:6 ../hacks/config/glitchpeg.xml.h:6
+#: ../hacks/config/glsnake.xml.h:6 ../hacks/config/hopalong.xml.h:6
+#: ../hacks/config/laser.xml.h:7 ../hacks/config/menger.xml.h:6
+#: ../hacks/config/metaballs.xml.h:6 ../hacks/config/mismunch.xml.h:6
+#: ../hacks/config/moire.xml.h:3 ../hacks/config/molecule.xml.h:6
+#: ../hacks/config/munch.xml.h:6 ../hacks/config/nerverot.xml.h:6
+#: ../hacks/config/pedal.xml.h:3 ../hacks/config/polyhedra.xml.h:9
+#: ../hacks/config/polyominoes.xml.h:7 ../hacks/config/ripples.xml.h:6
+#: ../hacks/config/rotzoomer.xml.h:6 ../hacks/config/shadebobs.xml.h:11
+#: ../hacks/config/sierpinski3d.xml.h:6 ../hacks/config/slidescreen.xml.h:9
+#: ../hacks/config/spheremonics.xml.h:6 ../hacks/config/spotlight.xml.h:6
+#: ../hacks/config/starfish.xml.h:9 ../hacks/config/substrate.xml.h:6
+#: ../hacks/config/superquadrics.xml.h:10 ../hacks/config/surfaces.xml.h:6
+#: ../hacks/config/tessellimage.xml.h:9 ../hacks/config/twang.xml.h:6
+#: ../hacks/config/vermiculate.xml.h:3 ../hacks/config/vidwhacker.xml.h:3
+#: ../hacks/config/wander.xml.h:7 ../hacks/config/zoom.xml.h:6
+msgid "Duration"
+msgstr "ხანგრძლოვობა"
+
+#: ../hacks/config/apple2.xml.h:8 ../hacks/config/blitspin.xml.h:8
+#: ../hacks/config/bumps.xml.h:7 ../hacks/config/decayscreen.xml.h:7
+#: ../hacks/config/distort.xml.h:7 ../hacks/config/glitchpeg.xml.h:7
+#: ../hacks/config/ripples.xml.h:7 ../hacks/config/rotzoomer.xml.h:7
+#: ../hacks/config/slidescreen.xml.h:10 ../hacks/config/spotlight.xml.h:7
+#: ../hacks/config/tessellimage.xml.h:10 ../hacks/config/twang.xml.h:7
+#: ../hacks/config/zoom.xml.h:7
+msgid "10 minutes"
+msgstr "10 წუთი"
+
+#: ../hacks/config/apple2.xml.h:11 ../hacks/config/filmleader.xml.h:3
+#: ../hacks/config/m6502.xml.h:8 ../hacks/config/vfeedback.xml.h:3
+#: ../hacks/config/xanalogtv.xml.h:5
+msgid "Color Knob"
+msgstr "პიქსელის ფერი"
+
+#: ../hacks/config/apple2.xml.h:13 ../hacks/config/filmleader.xml.h:5
+#: ../hacks/config/m6502.xml.h:10 ../hacks/config/vfeedback.xml.h:5
+#: ../hacks/config/xanalogtv.xml.h:7
+msgid "Tint Knob"
+msgstr "პიქსელის ტონი"
+
+#: ../hacks/config/apple2.xml.h:14 ../hacks/config/filmleader.xml.h:7
+#: ../hacks/config/m6502.xml.h:14 ../hacks/config/pong.xml.h:11
+#: ../hacks/config/vfeedback.xml.h:7 ../hacks/config/xanalogtv.xml.h:8
+msgid "Brightness Knob"
+msgstr "პიქსელის სიკაშკაშე"
+
+#: ../hacks/config/apple2.xml.h:15 ../hacks/config/filmleader.xml.h:8
+#: ../hacks/config/m6502.xml.h:15 ../hacks/config/pong.xml.h:13
+#: ../hacks/config/vfeedback.xml.h:8 ../hacks/config/xanalogtv.xml.h:9
+msgid "Contrast Knob"
+msgstr "პიქსელის კონტრასტი"
+
+#: ../hacks/config/apple2.xml.h:16
+msgid ""
+"An Apple ][+ computer simulation, in all its 1979 glory. It also reproduces "
+"the appearance of display on a color television set of the period. In "
+"\"Basic Programming Mode\", a simulated user types in a BASIC program and "
+"runs it. In \"Text Mode\", it displays the output of a program, or the "
+"contents of a file or URL. In \"Slideshow Mode\", it chooses random images "
+"and displays them within the limitations of the Apple ][ display hardware. "
+"(Six available colors in hi-res mode!) On MacOS and Linux, this program is "
+"also a fully-functional VT100 emulator! Run it as an application instead of "
+"as a screen saver and you can use it as a terminal. https://en.wikipedia.org/"
+"wiki/Apple_II_series Written by Trevor Blackwell and Jamie Zawinski; 2003."
+msgstr ""
+
+#: ../hacks/config/atlantis.xml.h:1
+msgid "Atlantis"
+msgstr "ატლანტისი"
+
+#: ../hacks/config/atlantis.xml.h:6
+msgid "Whale speed"
+msgstr "ვეშაპის სიჩქარე"
+
+#: ../hacks/config/atlantis.xml.h:8
+msgid "Shy"
+msgstr "მორცხვი"
+
+#: ../hacks/config/atlantis.xml.h:9
+msgid "Shark proximity"
+msgstr "ზვიგენის სიახლოვე"
+
+#: ../hacks/config/atlantis.xml.h:10
+msgid "Agressive"
+msgstr "აგრესიული"
+
+#: ../hacks/config/atlantis.xml.h:11 ../hacks/config/boxed.xml.h:20
+#: ../hacks/config/flyingtoasters.xml.h:8 ../hacks/config/glschool.xml.h:8
+#: ../hacks/config/glslideshow.xml.h:16 ../hacks/config/jigglypuff.xml.h:18
+#: ../hacks/config/juggle.xml.h:11 ../hacks/config/juggler3d.xml.h:11
+#: ../hacks/config/mirrorblob.xml.h:11 ../hacks/config/pipes.xml.h:11
+#: ../hacks/config/webcollage.xml.h:2
+msgid "None"
+msgstr "არაფერი"
+
+#: ../hacks/config/atlantis.xml.h:12
+msgid "Number of sharks"
+msgstr "ზვიგენების რაოდენობა"
+
+#: ../hacks/config/atlantis.xml.h:13 ../hacks/config/companioncube.xml.h:10
+#: ../hacks/config/deluxe.xml.h:10 ../hacks/config/demon.xml.h:7
+#: ../hacks/config/gears.xml.h:10 ../hacks/config/glhanoi.xml.h:11
+#: ../hacks/config/lisa.xml.h:15 ../hacks/config/lissie.xml.h:13
+#: ../hacks/config/skytentacles.xml.h:4
+msgid "20"
+msgstr "20"
+
+#: ../hacks/config/atlantis.xml.h:14
+msgid "Shimmering water"
+msgstr "მოლივლივე წყალი"
+
+#: ../hacks/config/atlantis.xml.h:15
+msgid "Clear water"
+msgstr "წმინდა წყალი"
+
+#: ../hacks/config/atlantis.xml.h:16
+msgid "Flat background"
+msgstr "ბრტყელი ფონი"
+
+#: ../hacks/config/atlantis.xml.h:17
+msgid "Gradient background"
+msgstr "გრადიენტის ფონი"
+
+#: ../hacks/config/atlantis.xml.h:18 ../hacks/config/atunnel.xml.h:7
+#: ../hacks/config/beats.xml.h:15 ../hacks/config/blinkbox.xml.h:11
+#: ../hacks/config/blocktube.xml.h:10 ../hacks/config/boing.xml.h:13
+#: ../hacks/config/bouncingcow.xml.h:12 ../hacks/config/boxed.xml.h:24
+#: ../hacks/config/cage.xml.h:5 ../hacks/config/chompytower.xml.h:14
+#: ../hacks/config/cityflow.xml.h:16 ../hacks/config/companioncube.xml.h:13
+#: ../hacks/config/covid19.xml.h:13 ../hacks/config/crackberg.xml.h:17
+#: ../hacks/config/crumbler.xml.h:14 ../hacks/config/cube21.xml.h:25
+#: ../hacks/config/cubenetic.xml.h:25 ../hacks/config/cubestack.xml.h:15
+#: ../hacks/config/cubestorm.xml.h:19 ../hacks/config/cubetwist.xml.h:17
+#: ../hacks/config/dangerball.xml.h:13 ../hacks/config/discoball.xml.h:13
+#: ../hacks/config/dnalogo.xml.h:8 ../hacks/config/dymaxionmap.xml.h:15
+#: ../hacks/config/extrusion.xml.h:15 ../hacks/config/flipflop.xml.h:13
+#: ../hacks/config/flyingtoasters.xml.h:14 ../hacks/config/gears.xml.h:13
+#: ../hacks/config/geodesic.xml.h:6 ../hacks/config/geodesicgears.xml.h:10
+#: ../hacks/config/gibson.xml.h:14 ../hacks/config/glcells.xml.h:33
+#: ../hacks/config/glforestfire.xml.h:15 ../hacks/config/glhanoi.xml.h:15
+#: ../hacks/config/glknots.xml.h:23 ../hacks/config/glmatrix.xml.h:19
+#: ../hacks/config/glplanet.xml.h:18 ../hacks/config/glschool.xml.h:13
+#: ../hacks/config/glsnake.xml.h:17 ../hacks/config/gltext.xml.h:18
+#: ../hacks/config/handsy.xml.h:22 ../hacks/config/headroom.xml.h:17
+#: ../hacks/config/hexstrut.xml.h:16 ../hacks/config/hilbert.xml.h:21
+#: ../hacks/config/hydrostat.xml.h:28 ../hacks/config/hypertorus.xml.h:6
+#: ../hacks/config/jigglypuff.xml.h:9 ../hacks/config/kaleidocycle.xml.h:20
+#: ../hacks/config/lament.xml.h:6 ../hacks/config/lavalite.xml.h:15
+#: ../hacks/config/menger.xml.h:18 ../hacks/config/mirrorblob.xml.h:26
+#: ../hacks/config/moebiusgears.xml.h:13 ../hacks/config/molecule.xml.h:11
+#: ../hacks/config/nakagin.xml.h:11 ../hacks/config/peepers.xml.h:16
+#: ../hacks/config/pinion.xml.h:15 ../hacks/config/pipes.xml.h:21
+#: ../hacks/config/polyhedra.xml.h:166 ../hacks/config/providence.xml.h:6
+#: ../hacks/config/queens.xml.h:5 ../hacks/config/rubikblocks.xml.h:19
+#: ../hacks/config/sballs.xml.h:15 ../hacks/config/sierpinski3d.xml.h:9
+#: ../hacks/config/speedmine.xml.h:16 ../hacks/config/spheremonics.xml.h:21
+#: ../hacks/config/splitflap.xml.h:24 ../hacks/config/sproingies.xml.h:8
+#: ../hacks/config/squirtorus.xml.h:11 ../hacks/config/stonerview.xml.h:5
+#: ../hacks/config/superquadrics.xml.h:12 ../hacks/config/tangram.xml.h:14
+#: ../hacks/config/topblock.xml.h:23 ../hacks/config/tronbit.xml.h:10
+#: ../hacks/config/unknownpleasures.xml.h:16
+msgid "Wireframe"
+msgstr "კარკასი"
+
+#: ../hacks/config/atlantis.xml.h:20
+msgid "Sharks, dolphins and whales. Written by Mark Kilgard; 1998."
+msgstr ""
+
+#: ../hacks/config/attraction.xml.h:1
+msgid "Attraction"
+msgstr "ღირსშესანიშნაობა"
+
+#: ../hacks/config/attraction.xml.h:2 ../hacks/config/juggle.xml.h:13
+#: ../hacks/config/juggler3d.xml.h:13
+msgid "Balls"
+msgstr "ბურთები"
+
+#: ../hacks/config/attraction.xml.h:3 ../hacks/config/deluxe.xml.h:6
+#: ../hacks/config/lmorph.xml.h:12 ../hacks/config/pedal.xml.h:6
+#: ../hacks/config/razzledazzle.xml.h:15 ../hacks/config/starfish.xml.h:12
+#: ../hacks/config/surfaces.xml.h:23 ../hacks/config/whirlygig.xml.h:3
+msgid "Lines"
+msgstr "ხაზები"
+
+#: ../hacks/config/attraction.xml.h:4
+msgid "Tails"
+msgstr "კუდები"
+
+#: ../hacks/config/attraction.xml.h:5 ../hacks/config/crumbler.xml.h:9
+msgid "Polygons"
+msgstr "მრავალკუთხედები"
+
+#: ../hacks/config/attraction.xml.h:6
+msgid "Splines"
+msgstr "სპლაინები"
+
+#: ../hacks/config/attraction.xml.h:7
+msgid "Filled splines"
+msgstr "შევსებული სპლაინები"
+
+#: ../hacks/config/attraction.xml.h:8
+msgid "Bounce off walls"
+msgstr "კედლებიდან არეკვლა"
+
+#: ../hacks/config/attraction.xml.h:9
+msgid "Ignore screen edges"
+msgstr "ეკრანის კიდეების იგნორი"
+
+#: ../hacks/config/attraction.xml.h:10 ../hacks/config/metaballs.xml.h:11
+msgid "Ball count"
+msgstr "ბურთების რაოდენობა"
+
+#: ../hacks/config/attraction.xml.h:12
+msgid "Environmental viscosity"
+msgstr "გარემოს სიბლანტე"
+
+#: ../hacks/config/attraction.xml.h:14 ../hacks/config/binaryring.xml.h:5
+#: ../hacks/config/blocktube.xml.h:5 ../hacks/config/braid.xml.h:5
+#: ../hacks/config/celtic.xml.h:5 ../hacks/config/cube21.xml.h:21
+#: ../hacks/config/cubestorm.xml.h:11 ../hacks/config/cynosure.xml.h:8
+#: ../hacks/config/drift.xml.h:5 ../hacks/config/eruption.xml.h:19
+#: ../hacks/config/euler2d.xml.h:8 ../hacks/config/fiberlamp.xml.h:8
+#: ../hacks/config/flow.xml.h:13 ../hacks/config/galaxy.xml.h:6
+#: ../hacks/config/glcells.xml.h:5 ../hacks/config/hydrostat.xml.h:19
+#: ../hacks/config/juggle.xml.h:8 ../hacks/config/juggler3d.xml.h:8
+#: ../hacks/config/laser.xml.h:6 ../hacks/config/menger.xml.h:5
+#: ../hacks/config/metaballs.xml.h:5 ../hacks/config/mismunch.xml.h:5
+#: ../hacks/config/munch.xml.h:5 ../hacks/config/nerverot.xml.h:5
+#: ../hacks/config/petri.xml.h:22 ../hacks/config/photopile.xml.h:18
+#: ../hacks/config/pipes.xml.h:8 ../hacks/config/polyominoes.xml.h:6
+#: ../hacks/config/rotor.xml.h:5 ../hacks/config/rubikblocks.xml.h:15
+#: ../hacks/config/shadebobs.xml.h:10 ../hacks/config/sierpinski3d.xml.h:5
+#: ../hacks/config/skytentacles.xml.h:5 ../hacks/config/slidescreen.xml.h:5
+#: ../hacks/config/sonar.xml.h:15 ../hacks/config/spheremonics.xml.h:5
+#: ../hacks/config/substrate.xml.h:5 ../hacks/config/superquadrics.xml.h:9
+#: ../hacks/config/surfaces.xml.h:5 ../hacks/config/vermiculate.xml.h:2
+#: ../hacks/config/wander.xml.h:6 ../hacks/config/whirlwindwarp.xml.h:5
+msgid "Short"
+msgstr "მოკლე"
+
+#: ../hacks/config/attraction.xml.h:15 ../hacks/config/euler2d.xml.h:9
+#: ../hacks/config/juggle.xml.h:12 ../hacks/config/juggler3d.xml.h:12
+#: ../hacks/config/sonar.xml.h:16
+msgid "Trail length"
+msgstr "კვალის ზომა"
+
+#: ../hacks/config/attraction.xml.h:16 ../hacks/config/binaryring.xml.h:7
+#: ../hacks/config/blocktube.xml.h:7 ../hacks/config/braid.xml.h:7
+#: ../hacks/config/celtic.xml.h:7 ../hacks/config/cube21.xml.h:23
+#: ../hacks/config/cubestorm.xml.h:13 ../hacks/config/cynosure.xml.h:10
+#: ../hacks/config/drift.xml.h:7 ../hacks/config/eruption.xml.h:21
+#: ../hacks/config/euler2d.xml.h:10 ../hacks/config/fiberlamp.xml.h:10
+#: ../hacks/config/flow.xml.h:15 ../hacks/config/fontglide.xml.h:10
+#: ../hacks/config/galaxy.xml.h:8 ../hacks/config/glcells.xml.h:7
+#: ../hacks/config/hydrostat.xml.h:21 ../hacks/config/juggle.xml.h:10
+#: ../hacks/config/juggler3d.xml.h:10 ../hacks/config/laser.xml.h:8
+#: ../hacks/config/menger.xml.h:7 ../hacks/config/metaballs.xml.h:7
+#: ../hacks/config/mismunch.xml.h:7 ../hacks/config/munch.xml.h:7
+#: ../hacks/config/nerverot.xml.h:7 ../hacks/config/petri.xml.h:24
+#: ../hacks/config/photopile.xml.h:20 ../hacks/config/pipes.xml.h:10
+#: ../hacks/config/polyominoes.xml.h:8 ../hacks/config/raverhoop.xml.h:17
+#: ../hacks/config/rotor.xml.h:7 ../hacks/config/rubikblocks.xml.h:17
+#: ../hacks/config/shadebobs.xml.h:12 ../hacks/config/sierpinski3d.xml.h:7
+#: ../hacks/config/skytentacles.xml.h:7 ../hacks/config/slidescreen.xml.h:7
+#: ../hacks/config/sonar.xml.h:17 ../hacks/config/spheremonics.xml.h:7
+#: ../hacks/config/substrate.xml.h:7 ../hacks/config/superquadrics.xml.h:11
+#: ../hacks/config/surfaces.xml.h:7 ../hacks/config/tangram.xml.h:7
+#: ../hacks/config/vermiculate.xml.h:4 ../hacks/config/wander.xml.h:8
+#: ../hacks/config/whirlwindwarp.xml.h:7 ../hacks/config/xlyap.xml.h:7
+msgid "Long"
+msgstr "გრძელი"
+
+#: ../hacks/config/attraction.xml.h:20
+msgid "Ball mass"
+msgstr "ბურთის მასა"
+
+#: ../hacks/config/attraction.xml.h:22
+msgid "Repulsion threshold"
+msgstr "ასხლეტვის ზღვარი"
+
+#: ../hacks/config/attraction.xml.h:27
+msgid "Orbital mode"
+msgstr "ორბიტალური რეჟიმი"
+
+#: ../hacks/config/attraction.xml.h:28 ../hacks/config/fuzzyflakes.xml.h:26
+msgid "Radius"
+msgstr "რადიუსი"
+
+#: ../hacks/config/attraction.xml.h:29
+msgid "Outward"
+msgstr "გარეთკენ"
+
+#: ../hacks/config/attraction.xml.h:30
+msgid "Inward"
+msgstr "შიგნითკენ"
+
+#: ../hacks/config/attraction.xml.h:32
+msgid ""
+"Points attract each other and then repel, similar to the strong and weak "
+"nuclear forces. Written by Jamie Zawinski and John Pezaris; 1992."
+msgstr ""
+
+#: ../hacks/config/atunnel.xml.h:1
+msgid "Atunnel"
+msgstr "ჰიპნოზური გვირაბი"
+
+#: ../hacks/config/atunnel.xml.h:5 ../hacks/config/blocktube.xml.h:9
+#: ../hacks/config/cubenetic.xml.h:24 ../hacks/config/gibson.xml.h:13
+#: ../hacks/config/glmatrix.xml.h:18 ../hacks/config/lament.xml.h:5
+#: ../hacks/config/sballs.xml.h:14
+msgid "Textured"
+msgstr "ტექსტურებით"
+
+#: ../hacks/config/atunnel.xml.h:6 ../hacks/config/boing.xml.h:11
+#: ../hacks/config/crackberg.xml.h:12
+msgid "Lighting"
+msgstr "გამოკვეთა"
+
+#: ../hacks/config/atunnel.xml.h:9
+msgid ""
+"Zooming through a textured tunnel. Written by Eric Lassauge and Roman "
+"Podobedov; 2003."
+msgstr ""
+
+#: ../hacks/config/barcode.xml.h:1
+msgid "Barcode"
+msgstr "შტრიხკოდი"
+
+#: ../hacks/config/barcode.xml.h:5
+msgid "Scrolling barcodes"
+msgstr "შტრიხკოდებსი გადახვევა"
+
+#: ../hacks/config/barcode.xml.h:6
+msgid "Barcode grid"
+msgstr "შტრიხკოდის ბადე"
+
+#: ../hacks/config/barcode.xml.h:7
+msgid "Barcode clock (AM/PM)"
+msgstr "შტრიხკოდის საათი (AM/PM)"
+
+#: ../hacks/config/barcode.xml.h:8
+msgid "Barcode clock (24 hour)"
+msgstr "შტრიხკოდის საათი (24 სთ)"
+
+#: ../hacks/config/barcode.xml.h:10
+msgid ""
+"Scrolling UPC-A, UPC-E, EAN-8 and EAN-13 barcodes. CONSUME! https://"
+"en.wikipedia.org/wiki/Universal_Product_Code https://en.wikipedia.org/wiki/"
+"European_Article_Number Written by Dan Bornstein and Jamie Zawinski; 2003."
+msgstr ""
+
+#: ../hacks/config/beats.xml.h:1
+msgid "Beats"
+msgstr "ტაქტი"
+
+#: ../hacks/config/beats.xml.h:6 ../hacks/config/boxed.xml.h:9
+#: ../hacks/config/fluidballs.xml.h:6
+msgid "Number of balls"
+msgstr "ბურთების რაოდენობა"
+
+#: ../hacks/config/beats.xml.h:8
+msgid "Random cycle style"
+msgstr "შემთხვევით გამეორების სტილი"
+
+#: ../hacks/config/beats.xml.h:9
+msgid "Clockwise cycle"
+msgstr "სტილი საათის ისრის მიმართულებით"
+
+#: ../hacks/config/beats.xml.h:10
+msgid "Rain dance cycle"
+msgstr "წვიმის ცეკვის სტილი"
+
+#: ../hacks/config/beats.xml.h:11
+msgid "Metronome cycle"
+msgstr "მეტრონომის სტილი"
+
+#: ../hacks/config/beats.xml.h:12
+msgid "Galaxy cycle"
+msgstr "გალაქტიკის ციკლი"
+
+#: ../hacks/config/beats.xml.h:13
+msgid "Tick"
+msgstr "ტიკ"
+
+#: ../hacks/config/beats.xml.h:14
+msgid "Motion Blur"
+msgstr "გადღაბნილი მოძრაობა"
+
+#: ../hacks/config/beats.xml.h:17
+msgid ""
+"Draws figures that move around at a slightly different rate from each other, "
+"creating interesting chaotic and ordered patterns. Written by David Eccles; "
+"2020."
+msgstr ""
+
+#: ../hacks/config/binaryhorizon.xml.h:1
+msgid "Binary Horizon"
+msgstr "ბინარული ჰორიზონტი"
+
+#: ../hacks/config/binaryhorizon.xml.h:3 ../hacks/config/binaryring.xml.h:3
+msgid "Growth delay"
+msgstr "ზრდის დაყოვნება"
+
+#: ../hacks/config/binaryhorizon.xml.h:6 ../hacks/config/binaryring.xml.h:9
+#: ../hacks/config/eruption.xml.h:9
+msgid "Number of particles"
+msgstr "ნაწილაკების რაოდენობა"
+
+#: ../hacks/config/binaryhorizon.xml.h:7 ../hacks/config/binaryring.xml.h:10
+#: ../hacks/config/boxed.xml.h:10 ../hacks/config/circuit.xml.h:7
+#: ../hacks/config/glschool.xml.h:7 ../hacks/config/gravitywell.xml.h:14
+#: ../hacks/config/julia.xml.h:7 ../hacks/config/mountain.xml.h:7
+#: ../hacks/config/pipes.xml.h:13 ../hacks/config/sproingies.xml.h:6
+#: ../hacks/config/squirtorus.xml.h:10 ../hacks/config/substrate.xml.h:10
+#: ../hacks/config/vigilance.xml.h:10 ../hacks/config/winduprobot.xml.h:10
+#: ../hacks/config/wormhole.xml.h:10
+msgid "Lots"
+msgstr "ბევრი"
+
+#: ../hacks/config/binaryhorizon.xml.h:8
+msgid "1 sec"
+msgstr "1 წმ"
+
+#: ../hacks/config/binaryhorizon.xml.h:10 ../hacks/config/bsod.xml.h:4
+#: ../hacks/config/geodesicgears.xml.h:7 ../hacks/config/m6502.xml.h:6
+#: ../hacks/config/molecule.xml.h:7 ../hacks/config/vidwhacker.xml.h:4
+msgid "2 minutes"
+msgstr "2 წუთი"
+
+#: ../hacks/config/binaryhorizon.xml.h:11 ../hacks/config/fuzzyflakes.xml.h:11
+msgid "Random colors"
+msgstr "შემთხვევითი ფერი"
+
+#: ../hacks/config/binaryhorizon.xml.h:12
+msgid "Two contrasting colors"
+msgstr "ორი კონტრასტული ფერი"
+
+#: ../hacks/config/binaryhorizon.xml.h:13
+msgid "Randomize every particle's color"
+msgstr "ყველა ნაწილაკის ფერის შემთხვევითობა"
+
+#: ../hacks/config/binaryhorizon.xml.h:15
+msgid ""
+"A system of path tracing particles evolves continuously from an initial "
+"horizon, alternating between colors. Written by Patrick Leiser, J. Tarbell "
+"and Emilio Del Tessandoro; 2021."
+msgstr ""
+
+#: ../hacks/config/binaryring.xml.h:1
+msgid "Binary Ring"
+msgstr "ბინარული რგოლი"
+
+#: ../hacks/config/binaryring.xml.h:6
+msgid "Ring Radius"
+msgstr "რგოლის რადიუსი"
+
+#: ../hacks/config/binaryring.xml.h:11
+msgid "Fade with colors"
+msgstr "მინავლება ფერებით"
+
+#: ../hacks/config/binaryring.xml.h:12
+msgid ""
+"A system of path tracing particles evolves continuously from an initial "
+"creation, alternating dark and light colors. Written by J. Tarbell and "
+"Emilio Del Tessandoro; 2014."
+msgstr ""
+
+#: ../hacks/config/blaster.xml.h:1
+msgid "Blaster"
+msgstr "ბლასტერი"
+
+#: ../hacks/config/blaster.xml.h:5
+msgid "Robots"
+msgstr "რობოტები"
+
+#: ../hacks/config/blaster.xml.h:6 ../hacks/config/penetrate.xml.h:5
+msgid "Lasers"
+msgstr "ლაზერები"
+
+#: ../hacks/config/blaster.xml.h:8 ../hacks/config/dymaxionmap.xml.h:11
+#: ../hacks/config/glplanet.xml.h:13
+msgid "Stars"
+msgstr "ვარსკვლავი"
+
+#: ../hacks/config/blaster.xml.h:11
+msgid ""
+"Flying space-combat robots (cleverly disguised as colored circles) do battle "
+"in front of a moving star field. Written by Jonathan Lin; 1999."
+msgstr ""
+
+#: ../hacks/config/blinkbox.xml.h:1
+msgid "Blink Box"
+msgstr "ყუთის ციმციმი"
+
+#: ../hacks/config/blinkbox.xml.h:6
+msgid "Box size"
+msgstr "ყუთის ზომა"
+
+#: ../hacks/config/blinkbox.xml.h:8 ../hacks/config/phosphor.xml.h:7
+msgid "Fade"
+msgstr "მინავლება"
+
+#: ../hacks/config/blinkbox.xml.h:9 ../hacks/config/strange.xml.h:18
+msgid "Motion blur"
+msgstr "გადღაბნილი მოძრაობა"
+
+#: ../hacks/config/blinkbox.xml.h:10
+msgid "Dissolve"
+msgstr "გახსნა"
+
+#: ../hacks/config/blinkbox.xml.h:13
+msgid ""
+"A motion-blurred ball bounces inside a box whose tiles only become visible "
+"upon impact. Written by Jeremy English; 2003."
+msgstr ""
+
+#: ../hacks/config/blitspin.xml.h:1
+msgid "Blit Spin"
+msgstr ""
+
+#: ../hacks/config/blitspin.xml.h:3
+msgid "Fuzzy rotation speed"
+msgstr "ბუნდოვანი ბრუნვის სიჩქარე"
+
+#: ../hacks/config/blitspin.xml.h:5
+msgid "90 degree rotation speed"
+msgstr "90 გრადუსით მობრუნების სიჩქარე"
+
+#: ../hacks/config/blitspin.xml.h:10
+msgid ""
+"Repeatedly rotates an image by 90 degrees by using bitwise-logical "
+"operations. The bitmap is divided into quadrants, and the quadrants are "
+"shifted clockwise. Then the same thing is done again with progressively "
+"smaller quadrants, except that all sub-quadrants of a given size are rotated "
+"in parallel. As you watch it, the image appears to dissolve into static and "
+"then reconstitute itself, but rotated. Written by Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/blocktube.xml.h:1
+msgid "Block Tube"
+msgstr "ბლოკის მილი"
+
+#: ../hacks/config/blocktube.xml.h:6
+msgid "Color hold time"
+msgstr "ფერის დაყოვნების დრო"
+
+#: ../hacks/config/blocktube.xml.h:8
+msgid "Color change time"
+msgstr "ფერის შეცვლის დრო"
+
+#: ../hacks/config/blocktube.xml.h:12
+msgid ""
+"A swirling, falling tunnel of reflective slabs. They fade from hue to hue. "
+"Written by Lars R. Damerow; 2003."
+msgstr ""
+
+#: ../hacks/config/boing.xml.h:1
+msgid "Boing"
+msgstr "ბოინგი"
+
+#: ../hacks/config/boing.xml.h:2 ../hacks/config/boxed.xml.h:11
+#: ../hacks/config/pinion.xml.h:9 ../hacks/config/sonar.xml.h:12
+#: ../hacks/config/winduprobot.xml.h:11
+msgid "Tiny"
+msgstr "პაწაწინა"
+
+#: ../hacks/config/boing.xml.h:3 ../hacks/config/discoball.xml.h:9
+#: ../hacks/config/lisa.xml.h:11 ../hacks/config/lissie.xml.h:14
+#: ../hacks/config/loop.xml.h:11 ../hacks/config/rotor.xml.h:12
+#: ../hacks/config/rubik.xml.h:9 ../hacks/config/wander.xml.h:12
+#: ../hacks/config/worm.xml.h:9
+msgid "Size"
+msgstr "ზომა"
+
+#: ../hacks/config/boing.xml.h:4 ../hacks/config/boxed.xml.h:13
+#: ../hacks/config/glcells.xml.h:13 ../hacks/config/pinion.xml.h:11
+#: ../hacks/config/sonar.xml.h:14 ../hacks/config/winduprobot.xml.h:13
+msgid "Huge"
+msgstr "უზარმაზარი"
+
+#: ../hacks/config/boing.xml.h:8
+msgid "Meridians"
+msgstr "მერიდიანები"
+
+#: ../hacks/config/boing.xml.h:9
+msgid "Parallels"
+msgstr "პარალელები"
+
+#: ../hacks/config/boing.xml.h:10
+msgid "Smoothing"
+msgstr "დარბილება"
+
+#: ../hacks/config/boing.xml.h:12 ../hacks/config/unknownpleasures.xml.h:6
+msgid "Scanlines"
+msgstr "რასტრული სტრიქონები"
+
+#: ../hacks/config/boing.xml.h:15
+msgid ""
+"A clone of the first graphics demo for the Amiga 1000. The original Boing "
+"was written by Dale Luck and RJ Mical during a break at the 1984 Consumer "
+"Electronics Show (or so the legend goes.) https://en.wikipedia.org/wiki/"
+"Amiga#Boing_Ball Written by Jamie Zawinski; 2005."
+msgstr ""
+
+#: ../hacks/config/bouboule.xml.h:1
+msgid "Bouboule"
+msgstr "ფუმფულა"
+
+#: ../hacks/config/bouboule.xml.h:6
+msgid "Number of spots"
+msgstr "წერტილების რაოდენობა"
+
+#: ../hacks/config/bouboule.xml.h:10 ../hacks/config/rocks.xml.h:13
+msgid "Do Red/Blue 3D separation"
+msgstr "წითელი/ლურჯი 3D განცალკევება"
+
+#: ../hacks/config/bouboule.xml.h:12
+msgid ""
+"A deforming balloon with varying-sized spots painted on its invisible "
+"surface. Written by Jeremie Petit; 1997."
+msgstr ""
+
+#: ../hacks/config/bouncingcow.xml.h:1
+msgid "Bouncing Cow"
+msgstr "მხტუნავი ძროხა"
+
+#: ../hacks/config/bouncingcow.xml.h:6
+msgid "Bounce speed"
+msgstr "ხტუნვის სიჩქარე"
+
+#: ../hacks/config/bouncingcow.xml.h:8
+msgid "Moo"
+msgstr "მუუ"
+
+#: ../hacks/config/bouncingcow.xml.h:9
+msgid "Number of cows"
+msgstr "ძროხების რაოდენობა"
+
+#: ../hacks/config/bouncingcow.xml.h:10
+msgid "Herd"
+msgstr "ნახირი"
+
+#: ../hacks/config/bouncingcow.xml.h:11
+msgid "Mathematically ideal cows (spherical, frictionless)"
+msgstr ""
+
+#: ../hacks/config/bouncingcow.xml.h:14
+msgid ""
+"A Cow. A Trampoline. Together, they fight crime. Written by Jamie Zawinski; "
+"2003."
+msgstr ""
+
+#: ../hacks/config/boxed.xml.h:1
+msgid "Boxed"
+msgstr "ყუთში"
+
+#: ../hacks/config/boxed.xml.h:12 ../hacks/config/fluidballs.xml.h:9
+msgid "Ball size"
+msgstr "ბურთის ზომა"
+
+#: ../hacks/config/boxed.xml.h:14 ../hacks/config/hopalong.xml.h:14
+msgid "Popcorn"
+msgstr "ბატი-ბუტი"
+
+#: ../hacks/config/boxed.xml.h:15
+msgid "Explosion force"
+msgstr "აფეთქების ძალა"
+
+#: ../hacks/config/boxed.xml.h:16
+msgid "Nuke"
+msgstr "ატომური ბომბი"
+
+#: ../hacks/config/boxed.xml.h:18
+msgid "Explosion decay"
+msgstr "აფეთქების დაყოვნება"
+
+#: ../hacks/config/boxed.xml.h:19
+msgid "Pop!"
+msgstr "ბაბახ!"
+
+#: ../hacks/config/boxed.xml.h:21
+msgid "Explosion momentum"
+msgstr "აფეთქების დარტყმა"
+
+#: ../hacks/config/boxed.xml.h:22 ../hacks/config/xmatrix.xml.h:20
+msgid "Full"
+msgstr "სრული"
+
+#: ../hacks/config/boxed.xml.h:25
+msgid ""
+"A box full of 3D bouncing balls that explode. Written by Sander van Grieken; "
+"2002."
+msgstr ""
+
+#: ../hacks/config/boxfit.xml.h:1
+msgid "Box Fit"
+msgstr "ყუთის ზომა"
+
+#: ../hacks/config/boxfit.xml.h:5 ../hacks/config/cityflow.xml.h:6
+#: ../hacks/config/cubenetic.xml.h:6
+msgid "Boxes"
+msgstr "ყუთები"
+
+#: ../hacks/config/boxfit.xml.h:6
+msgid "Grow by"
+msgstr "ზრდის პირობა"
+
+#: ../hacks/config/boxfit.xml.h:7
+msgid "Spacing"
+msgstr "დაშორება"
+
+#: ../hacks/config/boxfit.xml.h:8 ../hacks/config/popsquares.xml.h:6
+msgid "Border"
+msgstr "საზღვარი"
+
+#: ../hacks/config/boxfit.xml.h:9
+msgid "Boxes or circles"
+msgstr "ყუთები ან წრეები"
+
+#: ../hacks/config/boxfit.xml.h:10
+msgid "Boxes only"
+msgstr "მხოლოდ ყუთები"
+
+#: ../hacks/config/boxfit.xml.h:11
+msgid "Circles only"
+msgstr "მხოლოდ წრეები"
+
+#: ../hacks/config/boxfit.xml.h:12
+msgid "Color gradient"
+msgstr "ფერის გრადიენტი"
+
+#: ../hacks/config/boxfit.xml.h:13
+msgid "Grab images"
+msgstr "სურათის გადაღება"
+
+#: ../hacks/config/boxfit.xml.h:14
+msgid "Peek at underlying images"
+msgstr "ქვედა სურათებზე გაჭვრეტა"
+
+#: ../hacks/config/boxfit.xml.h:16
+msgid ""
+"Packs the screen with growing squares or circles which grow until they "
+"touch, then stop. Written by Jamie Zawinski; 2005."
+msgstr ""
+
+#: ../hacks/config/braid.xml.h:1
+msgid "Braid"
+msgstr "ნაწნავი"
+
+#: ../hacks/config/braid.xml.h:11
+msgid "Number of rings"
+msgstr "ბეჭდების რაოდენობა"
+
+#: ../hacks/config/braid.xml.h:12 ../hacks/config/epicycle.xml.h:11
+#: ../hacks/config/hilbert.xml.h:16 ../hacks/config/nerverot.xml.h:20
+msgid "Line thickness"
+msgstr "ხაზის სისქე"
+
+#: ../hacks/config/braid.xml.h:14
+msgid "Inter-braided concentric circles. Written by John Neil; 1997."
+msgstr ""
+
+#: ../hacks/config/bsod.xml.h:1
+msgid "BSOD"
+msgstr "BSOD"
+
+#: ../hacks/config/bsod.xml.h:2 ../hacks/config/carousel.xml.h:8
+#: ../hacks/config/geodesicgears.xml.h:5 ../hacks/config/m6502.xml.h:4
+#: ../hacks/config/molecule.xml.h:5
+msgid "5 seconds"
+msgstr "5 წამი"
+
+#: ../hacks/config/bsod.xml.h:5
+msgid "Windows 3.1"
+msgstr "Windows 3.1"
+
+#: ../hacks/config/bsod.xml.h:6
+msgid "Windows NT"
+msgstr "Windows NT"
+
+#: ../hacks/config/bsod.xml.h:7
+msgid "Windows 2000  "
+msgstr "Windows 2000  "
+
+#: ../hacks/config/bsod.xml.h:8
+msgid "Windows 10    "
+msgstr "Windows 10    "
+
+#: ../hacks/config/bsod.xml.h:9
+msgid "VMware ESXi-Arm"
+msgstr "VMware ESXi-Arm"
+
+#: ../hacks/config/bsod.xml.h:10
+msgid "MS-DOS"
+msgstr "MS-DOS"
+
+#: ../hacks/config/bsod.xml.h:11
+msgid "GLaDOS"
+msgstr "GLaDOS"
+
+#: ../hacks/config/bsod.xml.h:12
+msgid "AmigaDOS"
+msgstr "AmigaDOS"
+
+#: ../hacks/config/bsod.xml.h:13
+msgid "Android"
+msgstr "Android"
+
+#: ../hacks/config/bsod.xml.h:15
+msgid "Ransomware"
+msgstr "Ransomware"
+
+#: ../hacks/config/bsod.xml.h:16
+msgid "NVidia"
+msgstr "NVidia"
+
+#: ../hacks/config/bsod.xml.h:17
+msgid "OS/2"
+msgstr "OS/2"
+
+#: ../hacks/config/bsod.xml.h:18
+msgid "Sad Mac"
+msgstr "Sad Mac"
+
+#: ../hacks/config/bsod.xml.h:19
+msgid "Mac bomb"
+msgstr "Mac bomb"
+
+#: ../hacks/config/bsod.xml.h:20
+msgid "MacsBug"
+msgstr "MacsBug"
+
+#: ../hacks/config/bsod.xml.h:21
+msgid "MacOS X"
+msgstr "MacOS X"
+
+#: ../hacks/config/bsod.xml.h:22
+msgid "VMware"
+msgstr "VMware"
+
+#: ../hacks/config/bsod.xml.h:23
+msgid "Atari"
+msgstr "Atari"
+
+#: ../hacks/config/bsod.xml.h:24
+msgid "OS/390"
+msgstr "OS/390"
+
+#: ../hacks/config/bsod.xml.h:25
+msgid "HVX/GCOS"
+msgstr "HVX/GCOS"
+
+#: ../hacks/config/bsod.xml.h:26
+msgid "Encom"
+msgstr "Encom"
+
+#: ../hacks/config/bsod.xml.h:27
+msgid "NCD XTerm"
+msgstr "NCD XTerm"
+
+#: ../hacks/config/bsod.xml.h:28
+msgid "ATM"
+msgstr "ATM"
+
+#: ../hacks/config/bsod.xml.h:29
+msgid "DVD"
+msgstr "DVD"
+
+#: ../hacks/config/bsod.xml.h:30
+msgid "Nintendo"
+msgstr "Nintendo"
+
+#: ../hacks/config/bsod.xml.h:31
+msgid "Tivo"
+msgstr "Tivo"
+
+#: ../hacks/config/bsod.xml.h:32
+msgid "VMS"
+msgstr "VMS"
+
+#: ../hacks/config/bsod.xml.h:33
+msgid "BSD"
+msgstr "BSD"
+
+#: ../hacks/config/bsod.xml.h:34
+msgid "Linux (fsck)"
+msgstr "Linux (fsck)"
+
+#: ../hacks/config/bsod.xml.h:35
+msgid "Linux (sparc)"
+msgstr "Linux (sparc)"
+
+#: ../hacks/config/bsod.xml.h:36
+msgid "Linux (hppa)"
+msgstr "Linux (hppa)"
+
+#: ../hacks/config/bsod.xml.h:37
+msgid "Solaris"
+msgstr "Solaris"
+
+#: ../hacks/config/bsod.xml.h:38
+msgid "SCO"
+msgstr "SCO"
+
+#: ../hacks/config/bsod.xml.h:39
+msgid "HPUX"
+msgstr "HPUX"
+
+#: ../hacks/config/bsod.xml.h:40
+msgid "Tru64"
+msgstr "Tru64"
+
+#: ../hacks/config/bsod.xml.h:41
+msgid "GNOME"
+msgstr "GNOME"
+
+#: ../hacks/config/bsod.xml.h:43
+#, no-c-format
+msgid ""
+"Blue Screen of Death: a large collection of simulated crashes from various "
+"other operating systems. https://en.wikipedia.org/wiki/Blue_Screen_of_Death "
+"https://en.wikipedia.org/wiki/Screen_of_death https://en.wikipedia.org/wiki/"
+"Guru_Meditation https://en.wikipedia.org/wiki/Row_of_Bombs https://"
+"en.wikipedia.org/wiki/Bomb_%28symbol%29 Written by Jamie Zawinski; 1998."
+msgstr ""
+
+#: ../hacks/config/bubble3d.xml.h:1
+msgid "Bubble 3D"
+msgstr "Bubble 3D"
+
+#: ../hacks/config/bubble3d.xml.h:5
+msgid "Transparent bubbles"
+msgstr "გამჭვირვალე ბუშტები"
+
+#: ../hacks/config/bubble3d.xml.h:6 ../hacks/config/flurry.xml.h:10
+#: ../hacks/config/rotzoomer.xml.h:9 ../hacks/config/sballs.xml.h:5
+#: ../hacks/config/starfish.xml.h:2
+msgid "Random"
+msgstr "შემთხვევითი"
+
+#. DarkOrange is probably the closest named color.
+#: ../hacks/config/bubble3d.xml.h:7 ../hacks/config/phosphor.xml.h:11
+msgid "Amber"
+msgstr "ქარვისფერი"
+
+#: ../hacks/config/bubble3d.xml.h:8 ../hacks/config/fuzzyflakes.xml.h:16
+#: ../hacks/config/phosphor.xml.h:9
+msgid "Green"
+msgstr "მწვანე"
+
+#: ../hacks/config/bubble3d.xml.h:9 ../hacks/config/fuzzyflakes.xml.h:18
+msgid "Blue"
+msgstr "ლურჯი"
+
+#: ../hacks/config/bubble3d.xml.h:10 ../hacks/config/cube21.xml.h:13
+#: ../hacks/config/phosphor.xml.h:12
+msgid "White"
+msgstr "თეთრი"
+
+#: ../hacks/config/bubble3d.xml.h:12
+msgid ""
+"Rising, undulating 3D bubbles, with transparency and specular reflections. "
+"Written by Richard Jones; 1998."
+msgstr ""
+
+#: ../hacks/config/bubbles.xml.h:1
+msgid "Bubbles"
+msgstr "ბუშტები"
+
+#: ../hacks/config/bubbles.xml.h:5
+msgid "Draw circles instead of bubble images"
+msgstr ""
+
+#: ../hacks/config/bubbles.xml.h:6
+msgid "Don't hide bubbles when they pop"
+msgstr ""
+
+#: ../hacks/config/bubbles.xml.h:7
+msgid "Leave trails"
+msgstr "კვალის დატოვება"
+
+#: ../hacks/config/bubbles.xml.h:8
+msgid "Bubbles rise"
+msgstr "ბუშტების ამოსვლა"
+
+#: ../hacks/config/bubbles.xml.h:9
+msgid "Bubbles float"
+msgstr "ბუშტების ცურვა"
+
+#: ../hacks/config/bubbles.xml.h:10
+msgid "Bubbles fall"
+msgstr "ბუშტების ჩაძირვა"
+
+#: ../hacks/config/bubbles.xml.h:12
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. This simulates the kind of bubble formation that happens when "
+"water boils: small bubbles appear, and as they get closer to each other, "
+"they combine to form larger bubbles, which eventually pop. Written by James "
+"Macnicol; 1996."
+msgstr ""
+
+#: ../hacks/config/bumps.xml.h:1 ../hacks/config/mirrorblob.xml.h:15
+msgid "Bumps"
+msgstr "გამობურცვები"
+
+#: ../hacks/config/bumps.xml.h:9
+msgid ""
+"A spotlight roams across an embossed version of a loaded image. Written by "
+"Shane Smit; 1999."
+msgstr ""
+
+#: ../hacks/config/cage.xml.h:1
+msgid "Cage"
+msgstr "გალია"
+
+#: ../hacks/config/cage.xml.h:7
+msgid ""
+"Escher's \"Impossible Cage\". https://en.wikipedia.org/wiki/"
+"Maurits_Cornelis_Escher Written by Marcelo Vianna; 1998."
+msgstr ""
+
+#: ../hacks/config/carousel.xml.h:1
+msgid "Carousel"
+msgstr "კარუსელი"
+
+#: ../hacks/config/carousel.xml.h:6 ../hacks/config/ccurve.xml.h:6
+#: ../hacks/config/cubestack.xml.h:6 ../hacks/config/cubetwist.xml.h:6
+#: ../hacks/config/dymaxionmap.xml.h:6 ../hacks/config/geodesic.xml.h:15
+#: ../hacks/config/hydrostat.xml.h:6 ../hacks/config/photopile.xml.h:13
+#: ../hacks/config/tronbit.xml.h:6 ../hacks/config/unicrud.xml.h:6
+msgid "Animation speed"
+msgstr "ანიმაციის სიჩქარე"
+
+#: ../hacks/config/carousel.xml.h:9 ../hacks/config/glslideshow.xml.h:6
+#: ../hacks/config/mirrorblob.xml.h:9 ../hacks/config/photopile.xml.h:19
+msgid "Time until loading a new image"
+msgstr "დრო ახალი გამოსახულების ჩატვირთვამდე"
+
+#: ../hacks/config/carousel.xml.h:10 ../hacks/config/coral.xml.h:7
+#: ../hacks/config/deco.xml.h:4 ../hacks/config/helix.xml.h:7
+#: ../hacks/config/mapscroller.xml.h:11 ../hacks/config/moire.xml.h:4
+#: ../hacks/config/pedal.xml.h:4 ../hacks/config/rorschach.xml.h:10
+#: ../hacks/config/xspirograph.xml.h:7
+msgid "1 minute"
+msgstr "%1 წუთი"
+
+#: ../hacks/config/carousel.xml.h:11 ../hacks/config/photopile.xml.h:8
+msgid "Number of images"
+msgstr "გამოსახულებების რაოდენობა"
+
+#: ../hacks/config/carousel.xml.h:12
+msgid "Tilt in/out and left/right"
+msgstr "დახრა შიგნით/გარეთ და მარჯვნივ/მარცხნივ"
+
+#: ../hacks/config/carousel.xml.h:13
+msgid "Tilt in/out only"
+msgstr "მხოლოდ, შიგნით/გარეთ დახრა"
+
+#: ../hacks/config/carousel.xml.h:14
+msgid "Tilt left/right only"
+msgstr "მხოლოდ, მარჯვნივ/მარცხნივ დახრა"
+
+#: ../hacks/config/carousel.xml.h:15
+msgid "No tilting"
+msgstr "დახრის გარეშე"
+
+#: ../hacks/config/carousel.xml.h:16
+msgid "Zoom in/out"
+msgstr "გადიდება/დაპატარავება"
+
+#: ../hacks/config/carousel.xml.h:17 ../hacks/config/esper.xml.h:8
+#: ../hacks/config/glslideshow.xml.h:19 ../hacks/config/photopile.xml.h:21
+msgid "Show file names"
+msgstr "ფაილის სახელების ჩვენება"
+
+#: ../hacks/config/carousel.xml.h:19
+msgid ""
+"Loads several random images, and displays them flying in a circular "
+"formation. Images are replaced periodically. Written by Jamie Zawinski; 2005."
+msgstr ""
+
+#: ../hacks/config/ccurve.xml.h:1
+msgid "C Curve"
+msgstr "C მრუდი"
+
+#: ../hacks/config/ccurve.xml.h:3
+msgid "Change image every"
+msgstr "გამოსახულების შეცვლა ყოველ"
+
+#: ../hacks/config/ccurve.xml.h:4 ../hacks/config/epicycle.xml.h:10
+#: ../hacks/config/glslideshow.xml.h:15 ../hacks/config/glsnake.xml.h:7
+#: ../hacks/config/polyhedra.xml.h:10 ../hacks/config/starfish.xml.h:10
+msgid "30 seconds"
+msgstr "30 წამი"
+
+#: ../hacks/config/ccurve.xml.h:9 ../hacks/config/coral.xml.h:9
+#: ../hacks/config/imsmap.xml.h:9 ../hacks/config/kumppa.xml.h:5
+#: ../hacks/config/qix.xml.h:9 ../hacks/config/quasicrystal.xml.h:8
+#: ../hacks/config/razzledazzle.xml.h:12 ../hacks/config/squiral.xml.h:14
+#: ../hacks/config/superquadrics.xml.h:8 ../hacks/config/wander.xml.h:5
+#: ../hacks/config/xmatrix.xml.h:19
+msgid "Density"
+msgstr "სიმკვრივე"
+
+#: ../hacks/config/ccurve.xml.h:12
+msgid ""
+"Generates self-similar linear fractals, including the classic \"C Curve\". "
+"https://en.wikipedia.org/wiki/Levy_C_curve Written by Rick Campbell; 1999."
+msgstr ""
+
+#: ../hacks/config/celtic.xml.h:1
+msgid "Celtic"
+msgstr "კელტური"
+
+#: ../hacks/config/celtic.xml.h:8
+msgid "Draw graph"
+msgstr "გრაფიკის დახატვა"
+
+#: ../hacks/config/celtic.xml.h:10
+msgid ""
+"Repeatedly draws random Celtic cross-stitch patterns. https://"
+"en.wikipedia.org/wiki/Celtic_knot https://en.wikipedia.org/wiki/"
+"Knots_and_graphs Written by Max Froumentin; 2005."
+msgstr ""
+
+#: ../hacks/config/chompytower.xml.h:1
+msgid "Chompy Tower"
+msgstr ""
+
+#: ../hacks/config/chompytower.xml.h:6 ../hacks/config/nakagin.xml.h:6
+#: ../hacks/config/pinion.xml.h:8 ../hacks/config/squirtorus.xml.h:6
+msgid "Scrolling speed"
+msgstr "აწევ-ჩამოწევის სიჩქარე"
+
+#: ../hacks/config/chompytower.xml.h:8 ../hacks/config/glknots.xml.h:17
+#: ../hacks/config/gravitywell.xml.h:8 ../hacks/config/jigsaw.xml.h:12
+#: ../hacks/config/lavalite.xml.h:11 ../hacks/config/mirrorblob.xml.h:14
+#: ../hacks/config/spheremonics.xml.h:8
+#: ../hacks/config/unknownpleasures.xml.h:11
+msgid "Resolution"
+msgstr "გარჩევადობა"
+
+#: ../hacks/config/chompytower.xml.h:9
+msgid "high"
+msgstr "მაღალი"
+
+#: ../hacks/config/chompytower.xml.h:10 ../hacks/config/circuit.xml.h:11
+#: ../hacks/config/companioncube.xml.h:11 ../hacks/config/covid19.xml.h:12
+#: ../hacks/config/crumbler.xml.h:13 ../hacks/config/cube21.xml.h:19
+#: ../hacks/config/cubestorm.xml.h:18 ../hacks/config/cubetwist.xml.h:16
+#: ../hacks/config/dangerball.xml.h:12 ../hacks/config/discoball.xml.h:12
+#: ../hacks/config/energystream.xml.h:6 ../hacks/config/engine.xml.h:18
+#: ../hacks/config/flipflop.xml.h:6 ../hacks/config/gears.xml.h:12
+#: ../hacks/config/geodesic.xml.h:9 ../hacks/config/geodesicgears.xml.h:12
+#: ../hacks/config/hexstrut.xml.h:15 ../hacks/config/hilbert.xml.h:19
+#: ../hacks/config/moebiusgears.xml.h:11 ../hacks/config/nakagin.xml.h:8
+#: ../hacks/config/polyhedra.xml.h:164 ../hacks/config/raverhoop.xml.h:19
+#: ../hacks/config/rubikblocks.xml.h:13 ../hacks/config/splodesic.xml.h:10
+#: ../hacks/config/surfaces.xml.h:26 ../hacks/config/tronbit.xml.h:8
+#: ../hacks/config/unicrud.xml.h:9
+msgid "Spin"
+msgstr "სპინი"
+
+#: ../hacks/config/chompytower.xml.h:11 ../hacks/config/companioncube.xml.h:12
+#: ../hacks/config/covid19.xml.h:11 ../hacks/config/crumbler.xml.h:12
+#: ../hacks/config/cube21.xml.h:20 ../hacks/config/cubenetic.xml.h:8
+#: ../hacks/config/cubestack.xml.h:14 ../hacks/config/cubestorm.xml.h:17
+#: ../hacks/config/cubetwist.xml.h:15 ../hacks/config/dangerball.xml.h:11
+#: ../hacks/config/discoball.xml.h:11 ../hacks/config/dymaxionmap.xml.h:13
+#: ../hacks/config/energystream.xml.h:5 ../hacks/config/engine.xml.h:17
+#: ../hacks/config/gears.xml.h:11 ../hacks/config/geodesic.xml.h:8
+#: ../hacks/config/geodesicgears.xml.h:11 ../hacks/config/glblur.xml.h:8
+#: ../hacks/config/glforestfire.xml.h:11 ../hacks/config/glknots.xml.h:22
+#: ../hacks/config/glplanet.xml.h:10 ../hacks/config/gltext.xml.h:9
+#: ../hacks/config/handsy.xml.h:11 ../hacks/config/headroom.xml.h:16
+#: ../hacks/config/hexstrut.xml.h:14 ../hacks/config/hilbert.xml.h:18
+#: ../hacks/config/hypnowheel.xml.h:6 ../hacks/config/kaleidocycle.xml.h:19
+#: ../hacks/config/lavalite.xml.h:14 ../hacks/config/menger.xml.h:9
+#: ../hacks/config/moebiusgears.xml.h:10 ../hacks/config/molecule.xml.h:16
+#: ../hacks/config/nakagin.xml.h:9 ../hacks/config/polyhedra.xml.h:165
+#: ../hacks/config/raverhoop.xml.h:18 ../hacks/config/rubikblocks.xml.h:14
+#: ../hacks/config/spheremonics.xml.h:9 ../hacks/config/splitflap.xml.h:23
+#: ../hacks/config/splodesic.xml.h:9 ../hacks/config/surfaces.xml.h:25
+#: ../hacks/config/tronbit.xml.h:9 ../hacks/config/unicrud.xml.h:8
+#: ../hacks/config/wander.xml.h:1
+msgid "Wander"
+msgstr "ხეტიალი"
+
+#: ../hacks/config/chompytower.xml.h:12 ../hacks/config/jigsaw.xml.h:14
+#: ../hacks/config/nakagin.xml.h:10 ../hacks/config/sonar.xml.h:24
+msgid "Tilt"
+msgstr "მოხრა"
+
+#: ../hacks/config/chompytower.xml.h:13 ../hacks/config/cwaves.xml.h:8
+#: ../hacks/config/glknots.xml.h:18 ../hacks/config/jigsaw.xml.h:13
+#: ../hacks/config/lavalite.xml.h:13 ../hacks/config/skytentacles.xml.h:24
+msgid "Smooth"
+msgstr "რბილი"
+
+#: ../hacks/config/chompytower.xml.h:16
+msgid "This tree's got teeth! Written by Jamie Zawinski; 2022."
+msgstr ""
+
+#: ../hacks/config/circuit.xml.h:1
+msgid "Circuit"
+msgstr "წრედი"
+
+#: ../hacks/config/circuit.xml.h:5 ../hacks/config/gravitywell.xml.h:12
+#: ../hacks/config/hydrostat.xml.h:8 ../hacks/config/mismunch.xml.h:8
+#: ../hacks/config/mountain.xml.h:5 ../hacks/config/munch.xml.h:8
+#: ../hacks/config/pipes.xml.h:5 ../hacks/config/shadebobs.xml.h:8
+#: ../hacks/config/sproingies.xml.h:5 ../hacks/config/squirtorus.xml.h:8
+#: ../hacks/config/vigilance.xml.h:8 ../hacks/config/winduprobot.xml.h:8
+msgid "One"
+msgstr "ერთი"
+
+#: ../hacks/config/circuit.xml.h:6
+msgid "Parts"
+msgstr "ნაწილებ"
+
+#: ../hacks/config/circuit.xml.h:9 ../hacks/config/jigglypuff.xml.h:15
+#: ../hacks/config/pinion.xml.h:6
+msgid "Rotation speed"
+msgstr "ბრუნვის სიჩქარე"
+
+#: ../hacks/config/circuit.xml.h:12
+msgid "Flat coloring"
+msgstr "ბრტყელი გაფერადება"
+
+#: ../hacks/config/circuit.xml.h:13 ../hacks/config/gflux.xml.h:16
+msgid "Directional lighting"
+msgstr "მიმართული სინათლე"
+
+#: ../hacks/config/circuit.xml.h:15
+msgid "Electronic components float around. Written by Ben Buxton; 2001."
+msgstr ""
+
+#: ../hacks/config/cityflow.xml.h:1
+msgid "City Flow"
+msgstr "ქალაქის დინება"
+
+#: ../hacks/config/cityflow.xml.h:8
+msgid "Skew"
+msgstr "გადახრა"
+
+#: ../hacks/config/cityflow.xml.h:10 ../hacks/config/gflux.xml.h:6
+#: ../hacks/config/interference.xml.h:6
+msgid "Wave speed"
+msgstr "ტალღის სიჩქარე"
+
+#: ../hacks/config/cityflow.xml.h:13
+msgid "Wave overlap"
+msgstr "ტალღის გადაფარვა"
+
+#: ../hacks/config/cityflow.xml.h:15
+msgid "Wave complexity"
+msgstr "ტალღის სირთულე"
+
+#: ../hacks/config/cityflow.xml.h:18
+msgid ""
+"Waves move across a sea of boxes. The city swells. The walls are closing in. "
+"Written by Jamie Zawinski; 2014."
+msgstr ""
+
+#: ../hacks/config/cloudlife.xml.h:1
+msgid "Cloud Life"
+msgstr "ღრუბლის ცხოვრება"
+
+#: ../hacks/config/cloudlife.xml.h:5
+msgid "Young"
+msgstr "ახალგაზრდა"
+
+#: ../hacks/config/cloudlife.xml.h:6
+msgid "Max age"
+msgstr "მაქს. ასაკი"
+
+#: ../hacks/config/cloudlife.xml.h:7
+msgid "Old"
+msgstr "ძველი"
+
+#: ../hacks/config/cloudlife.xml.h:8
+msgid "Initial density"
+msgstr "საწყისი სიმკვრივე"
+
+#: ../hacks/config/cloudlife.xml.h:10 ../hacks/config/demon.xml.h:14
+#: ../hacks/config/petri.xml.h:26 ../hacks/config/slidescreen.xml.h:15
+msgid "Cell size"
+msgstr "უჯრედის ზომა"
+
+#: ../hacks/config/cloudlife.xml.h:14
+#, no-c-format
+msgid ""
+"Cloud-like formations based on a variant of Conway's Life. The difference is "
+"that cells have a maximum age, after which they count as 3 for populating "
+"the next generation. This makes long-lived formations explode instead of "
+"just sitting there. https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life "
+"Written by Don Marti; 2003."
+msgstr ""
+
+#: ../hacks/config/companioncube.xml.h:1
+msgid "Companion Cube"
+msgstr "პარტნიორი კუბი"
+
+#: ../hacks/config/companioncube.xml.h:6 ../hacks/config/distort.xml.h:14
+#: ../hacks/config/peepers.xml.h:11
+msgid "Bounce"
+msgstr "ხტუნვა"
+
+#: ../hacks/config/companioncube.xml.h:8 ../hacks/config/deluxe.xml.h:8
+#: ../hacks/config/geodesic.xml.h:17 ../hacks/config/gflux.xml.h:11
+#: ../hacks/config/glcells.xml.h:28 ../hacks/config/glhanoi.xml.h:9
+#: ../hacks/config/glsnake.xml.h:5 ../hacks/config/hypnowheel.xml.h:9
+#: ../hacks/config/lavalite.xml.h:8 ../hacks/config/lisa.xml.h:13
+#: ../hacks/config/lissie.xml.h:11 ../hacks/config/projectiveplane.xml.h:34
+#: ../hacks/config/raverhoop.xml.h:5 ../hacks/config/scooter.xml.h:11
+#: ../hacks/config/skytentacles.xml.h:2 ../hacks/config/sphereeversion.xml.h:32
+#: ../hacks/config/strange.xml.h:9
+msgid "1"
+msgstr "1"
+
+#: ../hacks/config/companioncube.xml.h:9
+msgid "Number of cubes"
+msgstr "კუბების რაოდენობა"
+
+#: ../hacks/config/companioncube.xml.h:16
+#, no-c-format
+msgid ""
+"The symptoms most commonly produced by Enrichment Center testing are "
+"superstition, perceiving inanimate objects as alive, and hallucinations. The "
+"Enrichment Center reminds you that the weighted companion cube will never "
+"threaten to stab you and, in fact, cannot speak. In the event that the "
+"Weighted Companion Cube does speak, the Enrichment Center urges you to "
+"disregard its advice. https://en.wikipedia.org/wiki/Portal_%28video_game%29 "
+"Written by Jamie Zawinski; 2011."
+msgstr ""
+
+#: ../hacks/config/compass.xml.h:1
+msgid "Compass"
+msgstr "კომპასი"
+
+#: ../hacks/config/compass.xml.h:6
+msgid ""
+"A compass, with all elements spinning about randomly, for that \"lost and "
+"nauseous\" feeling. Written by Jamie Zawinski; 1999."
+msgstr ""
+
+#: ../hacks/config/coral.xml.h:1
+msgid "Coral"
+msgstr "მარჯნისფერი"
+
+#: ../hacks/config/coral.xml.h:5 ../hacks/config/deco.xml.h:2
+#: ../hacks/config/epicycle.xml.h:8 ../hacks/config/glitchpeg.xml.h:5
+#: ../hacks/config/glslideshow.xml.h:13 ../hacks/config/helix.xml.h:5
+#: ../hacks/config/moire.xml.h:2 ../hacks/config/pedal.xml.h:2
+#: ../hacks/config/polyhedra.xml.h:8 ../hacks/config/rorschach.xml.h:8
+#: ../hacks/config/starfish.xml.h:8 ../hacks/config/xspirograph.xml.h:5
+msgid "1 second"
+msgstr "1 წამი"
+
+#: ../hacks/config/coral.xml.h:8 ../hacks/config/fireworkx.xml.h:7
+#: ../hacks/config/gflux.xml.h:8 ../hacks/config/glblur.xml.h:5
+#: ../hacks/config/glmatrix.xml.h:5 ../hacks/config/gravitywell.xml.h:11
+#: ../hacks/config/imsmap.xml.h:8 ../hacks/config/lavalite.xml.h:5
+#: ../hacks/config/marbling.xml.h:6 ../hacks/config/pyro.xml.h:5
+#: ../hacks/config/qix.xml.h:8 ../hacks/config/raverhoop.xml.h:8
+#: ../hacks/config/razzledazzle.xml.h:11 ../hacks/config/squiral.xml.h:13
+#: ../hacks/config/xmatrix.xml.h:18
+msgid "Sparse"
+msgstr "გაბნეული"
+
+#: ../hacks/config/coral.xml.h:10 ../hacks/config/fireworkx.xml.h:5
+#: ../hacks/config/gflux.xml.h:10 ../hacks/config/glblur.xml.h:7
+#: ../hacks/config/glmatrix.xml.h:7 ../hacks/config/gravitywell.xml.h:9
+#: ../hacks/config/imsmap.xml.h:10 ../hacks/config/lavalite.xml.h:7
+#: ../hacks/config/marbling.xml.h:8 ../hacks/config/pyro.xml.h:7
+#: ../hacks/config/qix.xml.h:10 ../hacks/config/raverhoop.xml.h:10
+#: ../hacks/config/razzledazzle.xml.h:13 ../hacks/config/squiral.xml.h:15
+msgid "Dense"
+msgstr "მკვრივი"
+
+#: ../hacks/config/coral.xml.h:12 ../hacks/config/glcells.xml.h:29
+#: ../hacks/config/squiral.xml.h:6
+msgid "Seeds"
+msgstr "მარცვლები"
+
+#: ../hacks/config/coral.xml.h:15
+msgid "Simulates colorful coral growth. Written by Frederick Roeber; 1997."
+msgstr ""
+
+#: ../hacks/config/covid19.xml.h:1
+msgid "COVID19"
+msgstr "COVID19"
+
+#: ../hacks/config/covid19.xml.h:8
+msgid "Taiwan"
+msgstr "ტაივანი"
+
+#: ../hacks/config/covid19.xml.h:9
+msgid "Government Response"
+msgstr "მთავრობის პასუხი"
+
+#: ../hacks/config/covid19.xml.h:10
+msgid "United States"
+msgstr "ამერიკის შეერთებული შტატები"
+
+#: ../hacks/config/covid19.xml.h:15
+msgid ""
+"SARS-CoV-2. Get vaccinated. Wear a mask. Written by Jamie Zawinski; 2020."
+msgstr ""
+
+#: ../hacks/config/crackberg.xml.h:1
+msgid "Crackberg"
+msgstr "ხეტიალი"
+
+#: ../hacks/config/crackberg.xml.h:5
+msgid "Mouse hole"
+msgstr "თაგვის სორო"
+
+#: ../hacks/config/crackberg.xml.h:6
+msgid "Visibility"
+msgstr "ხილვადობა"
+
+#: ../hacks/config/crackberg.xml.h:7
+msgid "Eagle nest"
+msgstr "არწივის ბუდე"
+
+#: ../hacks/config/crackberg.xml.h:9
+msgid "Subdivisions"
+msgstr "ქვედანაყოფები"
+
+#: ../hacks/config/crackberg.xml.h:10
+msgid "Hurt me"
+msgstr "მატკინე"
+
+#: ../hacks/config/crackberg.xml.h:11 ../hacks/config/cubetwist.xml.h:14
+msgid "Flat shading"
+msgstr "ბრტყელი დაჩრდილვა"
+
+#: ../hacks/config/crackberg.xml.h:13 ../hacks/config/flurry.xml.h:6
+msgid "Water"
+msgstr "წყალი"
+
+#: ../hacks/config/crackberg.xml.h:14
+msgid "Confused"
+msgstr "დაბნეული"
+
+#: ../hacks/config/crackberg.xml.h:15
+msgid "Immediate"
+msgstr "უეცარი"
+
+#: ../hacks/config/crackberg.xml.h:16 ../hacks/config/glslideshow.xml.h:18
+msgid "Letterbox"
+msgstr "საფოსტო ყუთი"
+
+#: ../hacks/config/crackberg.xml.h:19 ../hacks/config/etruscanvenus.xml.h:21
+#: ../hacks/config/imsmap.xml.h:14 ../hacks/config/klein.xml.h:18
+#: ../hacks/config/projectiveplane.xml.h:10 ../hacks/config/romanboy.xml.h:22
+#: ../hacks/config/sphereeversion.xml.h:18
+msgid "Random coloration"
+msgstr "შემთხვევითი შეფერილობა"
+
+#: ../hacks/config/crackberg.xml.h:20
+msgid "Earthy coloration"
+msgstr "შეფერვა (დედამიწა)"
+
+#: ../hacks/config/crackberg.xml.h:21
+msgid "Icy coloration"
+msgstr "შეფერვა (ყინული)"
+
+#: ../hacks/config/crackberg.xml.h:22
+msgid "Swampy coloration"
+msgstr "შეფერვა (ჭაობი)"
+
+#: ../hacks/config/crackberg.xml.h:23
+msgid "Vomitous coloration"
+msgstr "ამოფრქვევით შეღებვა"
+
+#: ../hacks/config/crackberg.xml.h:24
+msgid ""
+"Flies through height maps, optionally animating the creation and destruction "
+"of generated tiles; tiles `grow' into place. Written by Matus Telgarsky; "
+"2005."
+msgstr ""
+
+#: ../hacks/config/critical.xml.h:1
+msgid "Critical"
+msgstr "კრიტიკული"
+
+#: ../hacks/config/critical.xml.h:9
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws a system of self-organizing lines. It starts out as "
+"random squiggles, but after a few iterations, order begins to appear. "
+"Written by Martin Pool; 1999."
+msgstr ""
+
+#: ../hacks/config/crumbler.xml.h:1
+msgid "Crumbler"
+msgstr ""
+
+#: ../hacks/config/crumbler.xml.h:11
+msgid "Fractures"
+msgstr "მოტეხილობები"
+
+#: ../hacks/config/crumbler.xml.h:16
+msgid ""
+"Randomly subdivides a ball into voronoi chunks, then further subdivides one "
+"of the remaining pieces. https://en.wikipedia.org/wiki/Voronoi_diagram "
+"https://en.wikipedia.org/wiki/Convex_hull https://en.wikipedia.org/wiki/"
+"Quickhull Written by Jamie Zawinski; 2018."
+msgstr ""
+
+#: ../hacks/config/crystal.xml.h:1
+msgid "Crystal"
+msgstr "Crystal"
+
+#: ../hacks/config/crystal.xml.h:8
+msgid "Number of crystals"
+msgstr "კრისტალების რაოდენობა"
+
+#: ../hacks/config/crystal.xml.h:9
+msgid "Horizontal symmetries"
+msgstr "ჰორიზონტალური სიმეტრიები"
+
+#: ../hacks/config/crystal.xml.h:10
+msgid "Vertical symmetries"
+msgstr "ვერტიკალური სიმეტრიები"
+
+#: ../hacks/config/crystal.xml.h:11 ../hacks/config/spheremonics.xml.h:19
+msgid "Draw grid"
+msgstr "ბადის დახაზვა"
+
+#: ../hacks/config/crystal.xml.h:12
+msgid "Draw cell"
+msgstr "უჯრედების დახატვა"
+
+#: ../hacks/config/crystal.xml.h:13
+msgid "Center on screen"
+msgstr "ეკრანის ცენტრი"
+
+#: ../hacks/config/crystal.xml.h:15
+msgid ""
+"Moving polygons, similar to a kaleidoscope. See also the \"Kaleidescope\" "
+"and \"GLeidescope\" screen savers. https://en.wikipedia.org/wiki/"
+"Kaleidoscope Written by Jouk Jansen; 1998."
+msgstr ""
+
+#: ../hacks/config/cube21.xml.h:1
+msgid "Cube 21"
+msgstr "კუბი 21"
+
+#: ../hacks/config/cube21.xml.h:6 ../hacks/config/rubikblocks.xml.h:6
+msgid "Cube size"
+msgstr "კუბის ზომა"
+
+#: ../hacks/config/cube21.xml.h:9 ../hacks/config/quasicrystal.xml.h:11
+#: ../hacks/config/rocks.xml.h:11 ../hacks/config/rubik.xml.h:7
+#: ../hacks/config/rubikblocks.xml.h:9 ../hacks/config/topblock.xml.h:16
+msgid "Rotation"
+msgstr "შემობრუნება"
+
+#: ../hacks/config/cube21.xml.h:11 ../hacks/config/rubikblocks.xml.h:11
+msgid "Start as cube"
+msgstr "კუბად დაწყება"
+
+#: ../hacks/config/cube21.xml.h:12 ../hacks/config/rubikblocks.xml.h:12
+msgid "Start as random shape"
+msgstr "შემთხვევითი ფორმით დაწყება"
+
+#: ../hacks/config/cube21.xml.h:14
+msgid "Random color"
+msgstr "შემთხვევითი ფერი"
+
+#: ../hacks/config/cube21.xml.h:15
+msgid "Silver edition"
+msgstr "ვერცხლისფერი ვერსია"
+
+#: ../hacks/config/cube21.xml.h:16
+msgid "Two random colors"
+msgstr "ორი შემთხვევითი ფერი"
+
+#: ../hacks/config/cube21.xml.h:17
+msgid "Classic edition"
+msgstr "კლასიკური გამოცემა"
+
+#: ../hacks/config/cube21.xml.h:18
+msgid "Six random colors"
+msgstr "ექვსი შემთხვევითი ფერი"
+
+#: ../hacks/config/cube21.xml.h:24 ../hacks/config/rubikblocks.xml.h:18
+msgid "Outlines"
+msgstr "კონტურები"
+
+#: ../hacks/config/cube21.xml.h:28
+#, no-c-format
+msgid ""
+"The \"Cube 21\" Rubik-like puzzle, also known as \"Square-1\". The rotations "
+"are chosen randomly. See also the \"Rubik\", \"RubikBlocks\" and \"GLSnake\" "
+"screen savers. https://en.wikipedia.org/wiki/Square_One_%28puzzle%29 Written "
+"by Vasek Potocek; 2005."
+msgstr ""
+
+#: ../hacks/config/cubenetic.xml.h:1
+msgid "Cubenetic"
+msgstr "კუბიზმი"
+
+#: ../hacks/config/cubenetic.xml.h:9 ../hacks/config/glblur.xml.h:9
+#: ../hacks/config/glknots.xml.h:8 ../hacks/config/gltext.xml.h:10
+#: ../hacks/config/handsy.xml.h:12 ../hacks/config/kaleidocycle.xml.h:11
+#: ../hacks/config/menger.xml.h:10 ../hacks/config/molecule.xml.h:17
+#: ../hacks/config/spheremonics.xml.h:10 ../hacks/config/splitflap.xml.h:15
+msgid "Don't rotate"
+msgstr "არ შეაბრუნო"
+
+#: ../hacks/config/cubenetic.xml.h:10 ../hacks/config/glblur.xml.h:10
+#: ../hacks/config/glknots.xml.h:9 ../hacks/config/gltext.xml.h:11
+#: ../hacks/config/handsy.xml.h:13 ../hacks/config/kaleidocycle.xml.h:12
+#: ../hacks/config/lavalite.xml.h:23 ../hacks/config/menger.xml.h:11
+#: ../hacks/config/molecule.xml.h:18 ../hacks/config/spheremonics.xml.h:11
+#: ../hacks/config/splitflap.xml.h:16
+msgid "Rotate around X axis"
+msgstr "შემობრუნება X ღერძის გარშემო"
+
+#: ../hacks/config/cubenetic.xml.h:11 ../hacks/config/glblur.xml.h:11
+#: ../hacks/config/glknots.xml.h:10 ../hacks/config/gltext.xml.h:12
+#: ../hacks/config/handsy.xml.h:14 ../hacks/config/kaleidocycle.xml.h:13
+#: ../hacks/config/lavalite.xml.h:24 ../hacks/config/menger.xml.h:12
+#: ../hacks/config/molecule.xml.h:19 ../hacks/config/spheremonics.xml.h:12
+#: ../hacks/config/splitflap.xml.h:17
+msgid "Rotate around Y axis"
+msgstr "შემობრუნება Y ღერძის გარშემო"
+
+#: ../hacks/config/cubenetic.xml.h:12 ../hacks/config/glblur.xml.h:12
+#: ../hacks/config/glknots.xml.h:11 ../hacks/config/gltext.xml.h:13
+#: ../hacks/config/handsy.xml.h:15 ../hacks/config/kaleidocycle.xml.h:14
+#: ../hacks/config/lavalite.xml.h:25 ../hacks/config/menger.xml.h:13
+#: ../hacks/config/molecule.xml.h:20 ../hacks/config/spheremonics.xml.h:13
+#: ../hacks/config/splitflap.xml.h:18
+msgid "Rotate around Z axis"
+msgstr "შემობრუნება Z ღერძის გარშემო"
+
+#: ../hacks/config/cubenetic.xml.h:13 ../hacks/config/glblur.xml.h:13
+#: ../hacks/config/glknots.xml.h:12 ../hacks/config/gltext.xml.h:14
+#: ../hacks/config/handsy.xml.h:16 ../hacks/config/kaleidocycle.xml.h:15
+#: ../hacks/config/lavalite.xml.h:26 ../hacks/config/menger.xml.h:14
+#: ../hacks/config/molecule.xml.h:21 ../hacks/config/spheremonics.xml.h:14
+#: ../hacks/config/splitflap.xml.h:19
+msgid "Rotate around X and Y axes"
+msgstr "შემობრუნება X და Y ღერძების გარშემო"
+
+#: ../hacks/config/cubenetic.xml.h:14 ../hacks/config/glblur.xml.h:14
+#: ../hacks/config/glknots.xml.h:13 ../hacks/config/gltext.xml.h:15
+#: ../hacks/config/handsy.xml.h:17 ../hacks/config/kaleidocycle.xml.h:16
+#: ../hacks/config/lavalite.xml.h:27 ../hacks/config/menger.xml.h:15
+#: ../hacks/config/molecule.xml.h:22 ../hacks/config/spheremonics.xml.h:15
+#: ../hacks/config/splitflap.xml.h:20
+msgid "Rotate around X and Z axes"
+msgstr "შემობრუნება X და Z ღერძების გარშემო"
+
+#: ../hacks/config/cubenetic.xml.h:15 ../hacks/config/glblur.xml.h:15
+#: ../hacks/config/glknots.xml.h:14 ../hacks/config/gltext.xml.h:16
+#: ../hacks/config/handsy.xml.h:18 ../hacks/config/kaleidocycle.xml.h:17
+#: ../hacks/config/lavalite.xml.h:28 ../hacks/config/menger.xml.h:16
+#: ../hacks/config/molecule.xml.h:23 ../hacks/config/spheremonics.xml.h:16
+#: ../hacks/config/splitflap.xml.h:21
+msgid "Rotate around Y and Z axes"
+msgstr "შემობრუნება Y და Z ღერძების გარშემო"
+
+#: ../hacks/config/cubenetic.xml.h:16 ../hacks/config/glblur.xml.h:16
+#: ../hacks/config/glknots.xml.h:15 ../hacks/config/gltext.xml.h:17
+#: ../hacks/config/handsy.xml.h:19 ../hacks/config/kaleidocycle.xml.h:18
+#: ../hacks/config/lavalite.xml.h:29 ../hacks/config/menger.xml.h:17
+#: ../hacks/config/molecule.xml.h:24 ../hacks/config/spheremonics.xml.h:17
+#: ../hacks/config/splitflap.xml.h:22
+msgid "Rotate around all three axes"
+msgstr "შემობრუნება სამივე ღერძის გარშემო"
+
+#: ../hacks/config/cubenetic.xml.h:18
+msgid "Surface pattern speed"
+msgstr "ზედაპირის ნიმუშის სიჩქარე"
+
+#: ../hacks/config/cubenetic.xml.h:21
+msgid "Surface pattern overlap"
+msgstr "ზედაპირის ნიმუშის გადაფარვა"
+
+#: ../hacks/config/cubenetic.xml.h:23
+msgid "Surface pattern complexity"
+msgstr "ზედაპირის ნიმუშის სირთულე"
+
+#: ../hacks/config/cubenetic.xml.h:27
+msgid ""
+"A cubist Lavalite, sort of. A pulsating set of overlapping boxes with ever-"
+"changing blobby patterns undulating across their surfaces. Written by Jamie "
+"Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/cubestack.xml.h:1
+msgid "Cube Stack"
+msgstr "კუბების ნაკრები"
+
+#: ../hacks/config/cubestack.xml.h:11 ../hacks/config/hypertorus.xml.h:8
+#: ../hacks/config/qix.xml.h:21 ../hacks/config/webcollage.xml.h:8
+msgid "Transparent"
+msgstr "გამჭვირვალე"
+
+#: ../hacks/config/cubestack.xml.h:12
+msgid "Opacity"
+msgstr "გაუმჭვირვალობა"
+
+#: ../hacks/config/cubestack.xml.h:13 ../hacks/config/mirrorblob.xml.h:19
+#: ../hacks/config/webcollage.xml.h:10
+msgid "Opaque"
+msgstr "გაუმჭვირვალე"
+
+#: ../hacks/config/cubestack.xml.h:17
+msgid ""
+"An endless stack of unfolding, translucent cubes. Written by Jamie Zawinski; "
+"2016."
+msgstr ""
+
+#: ../hacks/config/cubestorm.xml.h:1
+msgid "Cube Storm"
+msgstr "კუბების ქარიშხალი"
+
+#: ../hacks/config/cubestorm.xml.h:9
+msgid "Cubes"
+msgstr "კუბები"
+
+#: ../hacks/config/cubestorm.xml.h:12 ../hacks/config/rotor.xml.h:6
+#: ../hacks/config/skytentacles.xml.h:6 ../hacks/config/wander.xml.h:9
+msgid "Length"
+msgstr "სიგრძე"
+
+#: ../hacks/config/cubestorm.xml.h:15
+msgid "Struts"
+msgstr "სამაგრი"
+
+#: ../hacks/config/cubestorm.xml.h:21
+msgid ""
+"Boxes change shape and intersect each other, filling space. Written by Jamie "
+"Zawinski; 2003."
+msgstr ""
+
+#: ../hacks/config/cubetwist.xml.h:1
+msgid "Cube Twist"
+msgstr "ჩალაგებული კუბები"
+
+#: ../hacks/config/cubetwist.xml.h:11 ../hacks/config/glsnake.xml.h:8
+msgid "Tight"
+msgstr "ვიწრო"
+
+#: ../hacks/config/cubetwist.xml.h:12 ../hacks/config/quasicrystal.xml.h:10
+msgid "Displacement"
+msgstr "გადაადგილება"
+
+#: ../hacks/config/cubetwist.xml.h:13
+msgid "Wide"
+msgstr "ფართო"
+
+#: ../hacks/config/cubetwist.xml.h:19
+msgid ""
+"A series of nested cubes rotate and slide recursively. Written by Jamie "
+"Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/cubicgrid.xml.h:1
+msgid "Cubic Grid"
+msgstr "კუბური ბადე"
+
+#: ../hacks/config/cubicgrid.xml.h:8
+msgid "Close"
+msgstr "დახურვა"
+
+#: ../hacks/config/cubicgrid.xml.h:9
+msgid "Dot spacing"
+msgstr "წერტილების დაშორება"
+
+#: ../hacks/config/cubicgrid.xml.h:11
+msgid "Big dots"
+msgstr "დიდი წერტილები"
+
+#: ../hacks/config/cubicgrid.xml.h:13
+msgid "Random symmetry"
+msgstr "შემთხვევითი სიმეტრია"
+
+#: ../hacks/config/cubicgrid.xml.h:14
+msgid "Cubic symmetry"
+msgstr "კუბური სიმეტრია"
+
+#: ../hacks/config/cubicgrid.xml.h:15
+msgid "Hexagonal symmetry"
+msgstr "ჰექსაგონალური სიმეტრია"
+
+#: ../hacks/config/cubicgrid.xml.h:16
+msgid "A rotating lattice of colored points. Written by Vasek Potocek; 2007."
+msgstr ""
+
+#: ../hacks/config/cwaves.xml.h:1
+msgid "C Waves"
+msgstr "C ტალღები"
+
+#: ../hacks/config/cwaves.xml.h:5 ../hacks/config/flame.xml.h:11
+#: ../hacks/config/jigglypuff.xml.h:21 ../hacks/config/marbling.xml.h:9
+#: ../hacks/config/tessellimage.xml.h:12
+msgid "Complexity"
+msgstr "სირთულე"
+
+#: ../hacks/config/cwaves.xml.h:6
+msgid "Rough"
+msgstr "უხეში"
+
+#: ../hacks/config/cwaves.xml.h:7
+msgid "Color transitions"
+msgstr "ფერის გადასვლები"
+
+#: ../hacks/config/cwaves.xml.h:10
+msgid ""
+"A field of sinusoidal colors languidly scrolls. It's relaxing. Written by "
+"Jamie Zawinski; 2007."
+msgstr ""
+
+#: ../hacks/config/cynosure.xml.h:1
+msgid "Cynosure"
+msgstr "ყურადღების ცენტრი"
+
+#: ../hacks/config/cynosure.xml.h:12
+msgid ""
+"Random dropshadowed rectangles pop onto the screen in lockstep. Written by "
+"Ozymandias G. Desiderata, Jamie Zawinski, and Stephen Linhart; 1998."
+msgstr ""
+
+#: ../hacks/config/dangerball.xml.h:1
+msgid "Danger Ball"
+msgstr "სახიფათო ბურთი"
+
+#: ../hacks/config/dangerball.xml.h:6 ../hacks/config/headroom.xml.h:6
+msgid "Spike growth"
+msgstr ""
+
+#: ../hacks/config/dangerball.xml.h:9
+msgid "Number of spikes"
+msgstr ""
+
+#: ../hacks/config/dangerball.xml.h:10
+msgid "Ouch"
+msgstr "ვაი"
+
+#: ../hacks/config/dangerball.xml.h:15
+msgid "A spiky ball. Ouch! Written by Jamie Zawinski; 2001."
+msgstr ""
+
+#: ../hacks/config/decayscreen.xml.h:1
+msgid "Decay Screen"
+msgstr "ეკრანის დაშლა"
+
+#: ../hacks/config/decayscreen.xml.h:8
+msgid "Random melt style"
+msgstr "დნობის შემთხვევითი სტილი"
+
+#: ../hacks/config/decayscreen.xml.h:9
+msgid "Shuffle melt"
+msgstr "შემთხვევითი დნობა"
+
+#: ../hacks/config/decayscreen.xml.h:10
+msgid "Melt up"
+msgstr "ადნობა"
+
+#: ../hacks/config/decayscreen.xml.h:11
+msgid "Melt down"
+msgstr "ჩამოდნობა"
+
+#: ../hacks/config/decayscreen.xml.h:12
+msgid "Melt left"
+msgstr "მარცხნივ დადნობა"
+
+#: ../hacks/config/decayscreen.xml.h:13
+msgid "Melt right"
+msgstr "მარჯვნივ დადნობა"
+
+#: ../hacks/config/decayscreen.xml.h:14
+msgid "Melt up, left"
+msgstr "დადნობა მაღლა, მარცხნივ"
+
+#: ../hacks/config/decayscreen.xml.h:15
+msgid "Melt up, right"
+msgstr "დადნობა მაღლა, მარჯვნივ"
+
+#: ../hacks/config/decayscreen.xml.h:16
+msgid "Melt down, left"
+msgstr "დადნობა დაბლა, მარცხნივ"
+
+#: ../hacks/config/decayscreen.xml.h:17
+msgid "Melt down, right"
+msgstr "დადნობა დაბლა, მარჯვნივ"
+
+#: ../hacks/config/decayscreen.xml.h:18
+msgid "Melt towards center"
+msgstr "დადნობა ცენტრისკენ"
+
+#: ../hacks/config/decayscreen.xml.h:19
+msgid "Melt away from center"
+msgstr "დადნობა ცენტრიდან"
+
+#: ../hacks/config/decayscreen.xml.h:20
+msgid "Melty melt"
+msgstr "ძლიერი დნობა"
+
+#: ../hacks/config/decayscreen.xml.h:21
+msgid "Stretchy melt"
+msgstr "ერთგვაროვანი დნობა"
+
+#: ../hacks/config/decayscreen.xml.h:22
+msgid "Fuzzy melt"
+msgstr "არაერთგვაროვანი დნობა"
+
+#: ../hacks/config/decayscreen.xml.h:24
+msgid ""
+"Melts an image in various ways. Warning, if the effect continues after the "
+"screen saver is off, seek medical attention. Written by David Wald, Vivek "
+"Khera, Jamie Zawinski, and Vince Levey; 1993."
+msgstr ""
+
+#: ../hacks/config/deco.xml.h:1
+msgid "Deco"
+msgstr "დეკუ"
+
+#: ../hacks/config/deco.xml.h:8
+msgid "Minimum width"
+msgstr "მინიმალური სიგანე"
+
+#: ../hacks/config/deco.xml.h:9
+msgid "Minimum height"
+msgstr "მინიმალური სიმაღლე"
+
+#: ../hacks/config/deco.xml.h:10
+msgid "Maximum depth"
+msgstr "მაქსიმალური სიღრმე"
+
+#: ../hacks/config/deco.xml.h:11
+msgid "Smooth colors"
+msgstr "რბილი ფერები"
+
+#: ../hacks/config/deco.xml.h:12
+msgid "Golden ratio"
+msgstr "ოქროს ფარდობა"
+
+#: ../hacks/config/deco.xml.h:13
+msgid "Mondrian"
+msgstr "მონდრიანი"
+
+#: ../hacks/config/deco.xml.h:15
+msgid ""
+"Subdivides and colors rectangles randomly, for a Mondrian-esque effect. "
+"https://en.wikipedia.org/wiki/Piet_Mondrian#Paris_1919.E2.80.931938 Written "
+"by Jamie Zawinski and Michael Bayne; 1997."
+msgstr ""
+
+#: ../hacks/config/deepstars.xml.h:1
+msgid "Deep Stars"
+msgstr "სიღრმისეული ვარსკვლავები"
+
+#: ../hacks/config/deepstars.xml.h:8
+msgid "Smear"
+msgstr "ნაცხი"
+
+#: ../hacks/config/deepstars.xml.h:10
+msgid ""
+"A long exposure of the night sky, showing star paths as vapor trails. "
+"Written by Jamie Zawinski; 2019."
+msgstr ""
+
+#: ../hacks/config/deluxe.xml.h:1
+msgid "Deluxe"
+msgstr "მდიდრული"
+
+#: ../hacks/config/deluxe.xml.h:9
+msgid "Shapes"
+msgstr "მოყვანილობები"
+
+#: ../hacks/config/deluxe.xml.h:14 ../hacks/config/mirrorblob.xml.h:18
+msgid "Transparency"
+msgstr "გამჭვირვალობა"
+
+#: ../hacks/config/deluxe.xml.h:16
+msgid "Pulsing stars, circles, and lines. Written by Jamie Zawinski; 1999."
+msgstr ""
+
+#: ../hacks/config/demon.xml.h:1
+msgid "Demon"
+msgstr "დემონი"
+
+#: ../hacks/config/demon.xml.h:5 ../hacks/config/gears.xml.h:8
+#: ../hacks/config/glhanoi.xml.h:5 ../hacks/config/interference.xml.h:18
+#: ../hacks/config/voronoi.xml.h:8
+msgid "0"
+msgstr "0"
+
+#: ../hacks/config/demon.xml.h:6
+msgid "States"
+msgstr "შტატები"
+
+#: ../hacks/config/demon.xml.h:17
+#, no-c-format
+msgid ""
+"A cellular automaton that starts with a random field, and organizes it into "
+"stripes and spirals. https://en.wikipedia.org/wiki/Maxwell%27s_demon Written "
+"by David Bagley; 1999."
+msgstr ""
+
+#: ../hacks/config/discoball.xml.h:1
+msgid "Discoball"
+msgstr "დისკობურთი"
+
+#: ../hacks/config/discoball.xml.h:15
+msgid "A dusty, dented disco ball. Woop woop. Written by Jamie Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/discrete.xml.h:1
+msgid "Discrete"
+msgstr "დისკრეტული"
+
+#: ../hacks/config/discrete.xml.h:12
+msgid ""
+"Discrete map fractal systems, including variants of Hopalong, Julia, and "
+"others. Written by Tim Auckland; 1998."
+msgstr ""
+
+#: ../hacks/config/distort.xml.h:1
+msgid "Distort"
+msgstr "დამახინჯება"
+
+#: ../hacks/config/distort.xml.h:9
+msgid "Lens size"
+msgstr "ლინზის ზომა"
+
+#: ../hacks/config/distort.xml.h:11
+msgid "Lens count"
+msgstr "ლინზების რაოდენობა"
+
+#: ../hacks/config/distort.xml.h:12
+msgid "Normal"
+msgstr "ნორმალი"
+
+#: ../hacks/config/distort.xml.h:13
+msgid "Swamp thing"
+msgstr "არსება ჭაობიდან"
+
+#: ../hacks/config/distort.xml.h:15
+msgid "Reflect"
+msgstr "არეკვლა"
+
+#: ../hacks/config/distort.xml.h:16
+msgid "Magnify"
+msgstr "გადიდება"
+
+#: ../hacks/config/distort.xml.h:17
+msgid "Black hole"
+msgstr "შავი ხვრელი"
+
+#: ../hacks/config/distort.xml.h:18
+msgid "Vortex"
+msgstr "მორევი"
+
+#: ../hacks/config/distort.xml.h:20
+msgid ""
+"Wandering lenses distort an image in various ways. Written by Jonas Munsin; "
+"1998."
+msgstr ""
+
+#: ../hacks/config/dnalogo.xml.h:1
+msgid "DNA Logo"
+msgstr "DNA ლოგო"
+
+#: ../hacks/config/dnalogo.xml.h:3
+msgid "Frame Rate"
+msgstr "კადრების სიხშირე"
+
+#: ../hacks/config/dnalogo.xml.h:5
+msgid "DNA Lounge logo"
+msgstr "DNA ლაუნჯის ლოგო"
+
+#: ../hacks/config/dnalogo.xml.h:6
+msgid "DNA Pizza logo"
+msgstr "DNA პიცის ლოგო"
+
+#: ../hacks/config/dnalogo.xml.h:7
+msgid "DNA Lounge and DNA Pizza logos"
+msgstr "DNA ლაუნჯისა და პიცის ლოგოები"
+
+#: ../hacks/config/dnalogo.xml.h:10
+msgid ""
+"DNA Lounge Restaurant -- Bar -- Nightclub -- Cafe -- Est. 1985. 375 Eleventh "
+"Street San Francisco, CA 94103 Written by Jamie Zawinski; 2001."
+msgstr ""
+
+#: ../hacks/config/drift.xml.h:1
+msgid "Drift"
+msgstr "დრეიფი"
+
+#: ../hacks/config/drift.xml.h:12
+msgid ""
+"Drifting recursive fractal cosmic flames. Written by Scott Draves; 1997."
+msgstr ""
+
+#: ../hacks/config/dymaxionmap.xml.h:1
+msgid "Dymaxion Map"
+msgstr "დიმაქსიონის რუკა"
+
+#: ../hacks/config/dymaxionmap.xml.h:8
+msgid "Flat map"
+msgstr "ბრტყელი რუკა"
+
+#: ../hacks/config/dymaxionmap.xml.h:9
+msgid "Satellite map"
+msgstr "თანამგზავრული რუკა"
+
+#: ../hacks/config/dymaxionmap.xml.h:10
+msgid "Day / night smoothness"
+msgstr "დღე / ღამის სიგლუვე"
+
+#: ../hacks/config/dymaxionmap.xml.h:12
+msgid "Lat / Long"
+msgstr "გან / გრძ"
+
+#: ../hacks/config/dymaxionmap.xml.h:14 ../hacks/config/glplanet.xml.h:12
+#: ../hacks/config/moebiusgears.xml.h:12
+msgid "Roll"
+msgstr "გაგორება"
+
+#: ../hacks/config/dymaxionmap.xml.h:18
+#, no-c-format
+msgid ""
+"Buckminster Fuller's map of the Earth projected onto the surface of an "
+"unfolded icosahedron. It depicts the Earth's continents as one island, or "
+"nearly contiguous land masses. This screen saver animates the progression of "
+"the dusk terminator across the flattened globe. It includes both satellite "
+"and flat-colored map imagery, and can load and convert other Equirectangular-"
+"projected maps. \"Dymaxion Map\" and \"The Fuller Projection Map\" are "
+"trademarks of The Buckminster Fuller Institute. The original Dymaxion Map "
+"image is copyright 1982 by The Buckminster Fuller Institute. (This program "
+"does not use their imagery, only similar trigonometry.) The Dymaxion Map was "
+"covered by now-expired US Patent 2,393,676 (Richard Buckminster Fuller, "
+"1946). https://en.wikipedia.org/wiki/Dymaxion_map https://en.wikipedia.org/"
+"wiki/Buckminster_Fuller https://en.wikipedia.org/wiki/"
+"List_of_map_projections https://en.wikipedia.org/wiki/"
+"Cahill%E2%80%93Keyes_projection https://en.wikipedia.org/wiki/"
+"Waterman_butterfly_projection Written by Jamie Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/endgame.xml.h:1
+msgid "Endgame"
+msgstr "ენდშპილი"
+
+#: ../hacks/config/endgame.xml.h:5
+msgid "Low resolution chess pieces"
+msgstr "დაბალი გარჩევადობი ჭადრაკის ფიგურები"
+
+#: ../hacks/config/endgame.xml.h:7
+msgid ""
+"Black slips out of three mating nets, but the fourth one holds him tight! A "
+"brilliant composition! See also the \"Queens\" screen saver. https://"
+"en.wikipedia.org/wiki/Chess_endgame Written by Blair Tennessy and Jamie "
+"Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/energystream.xml.h:1
+msgid "Energy Stream"
+msgstr "ენერგიის ნაკადი"
+
+#: ../hacks/config/energystream.xml.h:8
+msgid ""
+"A flow of particles which form an energy stream. Written by Eugene "
+"Sandulenko and Konrad \"Yoghurt\" Zagorowicz; 2016."
+msgstr ""
+
+#: ../hacks/config/engine.xml.h:1
+msgid "Engine"
+msgstr "ძრავი"
+
+#: ../hacks/config/engine.xml.h:5
+msgid "Random engine"
+msgstr "შემთხვევითი ძრავა"
+
+#: ../hacks/config/engine.xml.h:6
+msgid "Honda Insight (3 cylinders)"
+msgstr "Honda Insight (3 ცილინდრი)"
+
+#: ../hacks/config/engine.xml.h:7
+msgid "BMW M3 (4 cylinders)"
+msgstr "BMW M3 (4 ცილინდრი)"
+
+#: ../hacks/config/engine.xml.h:8
+msgid "VW Beetle (4 cylinders, flat)"
+msgstr "VW Beetle (4 ცილინდრი, ბრტყელი)"
+
+#: ../hacks/config/engine.xml.h:9
+msgid "Audi Quattro (5 cylinders)"
+msgstr "Audi Quattro (5 ცილინდრი)"
+
+#: ../hacks/config/engine.xml.h:10
+msgid "BMW M5 (6 cylinders)"
+msgstr "BMW M5 (6 ცილინდრი)"
+
+#: ../hacks/config/engine.xml.h:11
+msgid "Subaru XT (6 cylinders, V)"
+msgstr "Subaru XT (6 ცილინდი, V)"
+
+#: ../hacks/config/engine.xml.h:12
+msgid "Porsche 911 (6 cylinders, flat)"
+msgstr "Porsche 911 (6 ცილინდრი, ბრტყელი)"
+
+#: ../hacks/config/engine.xml.h:13
+msgid "Corvette Z06 (8 cylinders, V)"
+msgstr "Corvette Z06 (8 ცილინდრი, V)"
+
+#: ../hacks/config/engine.xml.h:14
+msgid "Dodge Viper (10 cylinders, V)"
+msgstr "Dodge Viper (10 ცილინდრი, V)"
+
+#: ../hacks/config/engine.xml.h:15
+msgid "Jaguar XKE (12 cylinders, V)"
+msgstr "Jaguar XKE (12 ცილინდრი, V)"
+
+#: ../hacks/config/engine.xml.h:16
+msgid "Show engine name"
+msgstr "ძრავის სახელის ჩვენება"
+
+#: ../hacks/config/engine.xml.h:20
+msgid ""
+"Internal combusion engines. https://en.wikipedia.org/wiki/"
+"Internal_combustion_engine#Operation Written by Ben Buxton, Ed Beroset and "
+"Jamie Zawinski; 2001."
+msgstr ""
+"შიდაწვის ძრავები. https://en.wikipedia.org/wiki/"
+"Internal_combustion_engine#Operation ავტორები: Buxton, Ed Beroset და Jamie "
+"Zawinski; 2001."
+
+#: ../hacks/config/epicycle.xml.h:1
+msgid "Epicycle"
+msgstr "ეპიციკლი"
+
+#: ../hacks/config/epicycle.xml.h:12
+msgid "Harmonics"
+msgstr "ჰარმონიები"
+
+#: ../hacks/config/epicycle.xml.h:14
+msgid ""
+"A pre-heliocentric model of planetary motion. This draws the path traced out "
+"by a point on the edge of a circle. That circle rotates around a point on "
+"the rim of another circle, and so on, several times. The geometry of "
+"epicycles was perfected by Hipparchus of Rhodes at some time around 125 "
+"B.C., 185 years after the birth of Aristarchus of Samos, the inventor of the "
+"heliocentric universe model. Hipparchus applied epicycles to the Sun and the "
+"Moon. Ptolemy of Alexandria went on to apply them to what was then the known "
+"universe, at around 150 A.D. Copernicus went on to apply them to the "
+"heliocentric model at the beginning of the sixteenth century. Johannes "
+"Kepler discovered that the planets actually move in elliptical orbits in "
+"about 1602. The inverse-square law of gravity was suggested by Boulliau in "
+"1645. Isaac Newton's Principia Mathematica was published in 1687, and proved "
+"that Kepler's laws derived from Newtonian gravitation. https://"
+"en.wikipedia.org/wiki/Deferent_and_epicycle Written by James Youngman; 1998."
+msgstr ""
+
+#: ../hacks/config/eruption.xml.h:1
+msgid "Eruption"
+msgstr "ამოფრქვევა"
+
+#: ../hacks/config/eruption.xml.h:8
+msgid "Little"
+msgstr "პატარა"
+
+#: ../hacks/config/eruption.xml.h:11
+msgid "Cooling factor"
+msgstr "გაგრილების ფაქტორი"
+
+#: ../hacks/config/eruption.xml.h:13
+msgid "Pleasant"
+msgstr "სასიამოვნო"
+
+#: ../hacks/config/eruption.xml.h:14
+msgid "Heat"
+msgstr "სითბო"
+
+#: ../hacks/config/eruption.xml.h:15
+msgid "Inferno"
+msgstr "ჯოჯოხეთი"
+
+#: ../hacks/config/eruption.xml.h:16
+msgid "Negative"
+msgstr "უარყოფითი"
+
+#: ../hacks/config/eruption.xml.h:17 ../hacks/config/fluidballs.xml.h:12
+#: ../hacks/config/hydrostat.xml.h:23 ../hacks/config/qix.xml.h:23
+#: ../hacks/config/speedmine.xml.h:9
+msgid "Gravity"
+msgstr "მიზიდულობა"
+
+#: ../hacks/config/eruption.xml.h:18
+msgid "Positive"
+msgstr "დადებითი"
+
+#: ../hacks/config/eruption.xml.h:23
+msgid ""
+"Exploding fireworks. See also the \"Fireworkx\", \"XFlame\" and \"Pyro\" "
+"screen savers. Written by W.P. van Paassen; 2003."
+msgstr ""
+
+#: ../hacks/config/esper.xml.h:1
+msgid "Esper"
+msgstr "ესპერი"
+
+#: ../hacks/config/esper.xml.h:10
+msgid ""
+"\"Enhance 224 to 176. Pull out track right. Center in pull back. Pull back. "
+"Wait a minute. Go right. Stop. Enhance 57 19. Track 45 left. Gimme a "
+"hardcopy right there.\" The Esper Machine was a voice-controlled forensic "
+"device used by LAPD in 2019, as documented in the 1982 film, Blade Runner. "
+"It was capable of enhancing photographs to an extreme degree, including "
+"reconstructing different viewpoints within the space from the reflections on "
+"various objects in the photograph. Written by Jamie Zawinski; 2017."
+msgstr ""
+
+#: ../hacks/config/etruscanvenus.xml.h:1
+msgid "Etruscan Venus"
+msgstr "ეტრუსკული ვენერა"
+
+#: ../hacks/config/etruscanvenus.xml.h:2 ../hacks/config/klein.xml.h:6
+#: ../hacks/config/projectiveplane.xml.h:40 ../hacks/config/qix.xml.h:15
+#: ../hacks/config/romanboy.xml.h:2
+msgid "Random motion"
+msgstr "შემთხვევითი მოძრაობა"
+
+#: ../hacks/config/etruscanvenus.xml.h:3 ../hacks/config/klein.xml.h:7
+#: ../hacks/config/projectiveplane.xml.h:41 ../hacks/config/romanboy.xml.h:3
+msgid "Walk"
+msgstr "გასეირნება"
+
+#: ../hacks/config/etruscanvenus.xml.h:4 ../hacks/config/klein.xml.h:8
+#: ../hacks/config/projectiveplane.xml.h:42 ../hacks/config/romanboy.xml.h:4
+msgid "Turn"
+msgstr "გრუპეტო"
+
+#: ../hacks/config/etruscanvenus.xml.h:5 ../hacks/config/klein.xml.h:10
+#: ../hacks/config/projectiveplane.xml.h:44 ../hacks/config/romanboy.xml.h:6
+msgid "Show orientation marks"
+msgstr "ორიენტაციის ნიშნების ჩვენება"
+
+#: ../hacks/config/etruscanvenus.xml.h:6
+msgid "Deform the surface"
+msgstr "ზედაპირის დეფორმაცია"
+
+#: ../hacks/config/etruscanvenus.xml.h:7 ../hacks/config/klein.xml.h:41
+#: ../hacks/config/romanboy.xml.h:8 ../hacks/config/sphereeversion.xml.h:5
+msgid "1.0"
+msgstr "1.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:8 ../hacks/config/romanboy.xml.h:9
+#: ../hacks/config/sphereeversion.xml.h:6
+msgid "Deformation speed"
+msgstr "დეფორმატიის სიჩქარე"
+
+#: ../hacks/config/etruscanvenus.xml.h:9 ../hacks/config/klein.xml.h:43
+#: ../hacks/config/romanboy.xml.h:10 ../hacks/config/sphereeversion.xml.h:7
+msgid "100.0"
+msgstr "100.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:10 ../hacks/config/romanboy.xml.h:11
+msgid "0.0"
+msgstr "0.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:11 ../hacks/config/romanboy.xml.h:12
+msgid "Initial deformation"
+msgstr "საწყისი დეფორმაცია"
+
+#: ../hacks/config/etruscanvenus.xml.h:12
+msgid "3999.0"
+msgstr "3999.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:13 ../hacks/config/klein.xml.h:11
+#: ../hacks/config/projectiveplane.xml.h:2 ../hacks/config/romanboy.xml.h:14
+#: ../hacks/config/sphereeversion.xml.h:8
+msgid "Random surface"
+msgstr "შემთხვევითი ზედაპირი"
+
+#: ../hacks/config/etruscanvenus.xml.h:14 ../hacks/config/klein.xml.h:12
+#: ../hacks/config/polytopes.xml.h:2 ../hacks/config/projectiveplane.xml.h:3
+#: ../hacks/config/romanboy.xml.h:15
+msgid "Wireframe mesh"
+msgstr "კარკასის ბადე"
+
+#: ../hacks/config/etruscanvenus.xml.h:15 ../hacks/config/klein.xml.h:13
+#: ../hacks/config/mirrorblob.xml.h:27 ../hacks/config/polytopes.xml.h:3
+#: ../hacks/config/projectiveplane.xml.h:4 ../hacks/config/romanboy.xml.h:16
+#: ../hacks/config/sphereeversion.xml.h:9
+msgid "Solid surface"
+msgstr "მყარი ზედაპირი"
+
+#: ../hacks/config/etruscanvenus.xml.h:16 ../hacks/config/klein.xml.h:14
+#: ../hacks/config/polytopes.xml.h:4 ../hacks/config/projectiveplane.xml.h:5
+#: ../hacks/config/romanboy.xml.h:17 ../hacks/config/sphereeversion.xml.h:10
+msgid "Transparent surface"
+msgstr "გამჭვირვალე ზედაპირი"
+
+#: ../hacks/config/etruscanvenus.xml.h:17 ../hacks/config/klein.xml.h:15
+#: ../hacks/config/projectiveplane.xml.h:6 ../hacks/config/romanboy.xml.h:18
+#: ../hacks/config/sphereeversion.xml.h:11
+msgid "Random pattern"
+msgstr "შემთხვევითი ნიმუში"
+
+#: ../hacks/config/etruscanvenus.xml.h:18 ../hacks/config/hypertorus.xml.h:9
+#: ../hacks/config/klein.xml.h:16 ../hacks/config/projectiveplane.xml.h:7
+#: ../hacks/config/romanboy.xml.h:19 ../hacks/config/sphereeversion.xml.h:12
+msgid "Solid object"
+msgstr "მყარი ობიექტი"
+
+#: ../hacks/config/etruscanvenus.xml.h:19
+#: ../hacks/config/projectiveplane.xml.h:8 ../hacks/config/romanboy.xml.h:20
+msgid "Distance bands"
+msgstr "დაშორების გუნდები"
+
+#: ../hacks/config/etruscanvenus.xml.h:20
+#: ../hacks/config/projectiveplane.xml.h:9 ../hacks/config/romanboy.xml.h:21
+msgid "Direction bands"
+msgstr "მიმართულების გუნდები"
+
+#: ../hacks/config/etruscanvenus.xml.h:22 ../hacks/config/hypertorus.xml.h:16
+#: ../hacks/config/klein.xml.h:19 ../hacks/config/projectiveplane.xml.h:11
+#: ../hacks/config/romanboy.xml.h:23
+msgid "One-sided"
+msgstr "ერთმხრიანი"
+
+#: ../hacks/config/etruscanvenus.xml.h:23 ../hacks/config/hypertorus.xml.h:17
+#: ../hacks/config/klein.xml.h:20 ../hacks/config/projectiveplane.xml.h:12
+#: ../hacks/config/romanboy.xml.h:24 ../hacks/config/sphereeversion.xml.h:19
+msgid "Two-sided"
+msgstr "ორმხრივი"
+
+#: ../hacks/config/etruscanvenus.xml.h:24
+#: ../hacks/config/projectiveplane.xml.h:13 ../hacks/config/romanboy.xml.h:25
+msgid "Distance colors"
+msgstr "დაშორების ფერები"
+
+#: ../hacks/config/etruscanvenus.xml.h:25
+#: ../hacks/config/projectiveplane.xml.h:14 ../hacks/config/romanboy.xml.h:26
+msgid "Direction colors"
+msgstr "მიმართულების ფერები"
+
+#: ../hacks/config/etruscanvenus.xml.h:26 ../hacks/config/hypertorus.xml.h:19
+#: ../hacks/config/klein.xml.h:23 ../hacks/config/projectiveplane.xml.h:16
+#: ../hacks/config/romanboy.xml.h:27
+msgid "Change colors"
+msgstr "ფერების შეცვლა"
+
+#: ../hacks/config/etruscanvenus.xml.h:27 ../hacks/config/romanboy.xml.h:28
+#: ../hacks/config/sphereeversion.xml.h:23
+msgid "Random Projection"
+msgstr "შემთხვევითი პროექცია"
+
+#: ../hacks/config/etruscanvenus.xml.h:28 ../hacks/config/romanboy.xml.h:29
+#: ../hacks/config/sphereeversion.xml.h:24
+msgid "Perspective"
+msgstr "პერსპექტივა"
+
+#: ../hacks/config/etruscanvenus.xml.h:29 ../hacks/config/romanboy.xml.h:30
+#: ../hacks/config/sphereeversion.xml.h:25
+msgid "Orthographic"
+msgstr "ორთოგრაფიული"
+
+#: ../hacks/config/etruscanvenus.xml.h:30 ../hacks/config/hypertorus.xml.h:24
+#: ../hacks/config/klein.xml.h:30 ../hacks/config/polytopes.xml.h:19
+#: ../hacks/config/romanboy.xml.h:31 ../hacks/config/sphereeversion.xml.h:33
+msgid "-4.0"
+msgstr "-4.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:31 ../hacks/config/romanboy.xml.h:32
+#: ../hacks/config/sphereeversion.xml.h:34
+msgid "X rotation speed"
+msgstr "X ბრუნვის სიჩქარე"
+
+#: ../hacks/config/etruscanvenus.xml.h:32 ../hacks/config/hypertorus.xml.h:26
+#: ../hacks/config/klein.xml.h:32 ../hacks/config/polytopes.xml.h:21
+#: ../hacks/config/romanboy.xml.h:33 ../hacks/config/sphereeversion.xml.h:35
+msgid "4.0"
+msgstr "4.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:33 ../hacks/config/romanboy.xml.h:34
+#: ../hacks/config/sphereeversion.xml.h:36
+msgid "Y rotation speed"
+msgstr "Y ბრუნვის სიჩქარე"
+
+#: ../hacks/config/etruscanvenus.xml.h:34 ../hacks/config/romanboy.xml.h:35
+#: ../hacks/config/sphereeversion.xml.h:37
+msgid "Z rotation speed"
+msgstr "Z ბრუნვის სიჩქარე"
+
+#: ../hacks/config/etruscanvenus.xml.h:35 ../hacks/config/klein.xml.h:38
+#: ../hacks/config/romanboy.xml.h:36
+msgid "-180.0"
+msgstr "-180.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:36 ../hacks/config/klein.xml.h:39
+#: ../hacks/config/romanboy.xml.h:37
+msgid "Walking direction"
+msgstr "სიარულის მიმართულება"
+
+#: ../hacks/config/etruscanvenus.xml.h:37 ../hacks/config/klein.xml.h:40
+#: ../hacks/config/romanboy.xml.h:38
+msgid "180.0"
+msgstr "180.0"
+
+#: ../hacks/config/etruscanvenus.xml.h:38 ../hacks/config/klein.xml.h:42
+#: ../hacks/config/romanboy.xml.h:39
+msgid "Walking speed"
+msgstr "სიარულის სიჩქარე"
+
+#: ../hacks/config/etruscanvenus.xml.h:44
+#, no-c-format
+msgid ""
+"A 3D immersion of a Klein bottle that smoothly deforms between the Etruscan "
+"Venus surface, the Roman surface, the Boy surface, and the Ida surface. "
+"Topologically, all surfaces are Klein bottles, even the Roman and Boy "
+"surfaces, which are doubly covered and therefore appear to be an immersed "
+"real projective plane. You can walk on the Klein bottle or rotate it in 3D. "
+"Since all the surfaces except the Ida surfaces have points where the surface "
+"normal is not well defined for some points, walking is performed on the Ida "
+"surface. Furthermore, it is possible to smoothly deform the surface between "
+"the Etruscan Venus surface, the Roman surface, the Boy surface, and the Ida "
+"surface surface while turning it. Inspired by George K. Francis's book \"A "
+"Topological Picturebook\", Springer, 1987, George K. Francis's paper \"The "
+"Etruscan Venus\" in P. Concus, R. Finn, and D. A. Hoffman: \"Geometric "
+"Analysis and Computer Graphics\", Springer, 1991, and a video entitled \"The "
+"Etruscan Venus\" by Donna J. Cox, George K. Francis, and Raymond L. Idaszak, "
+"presented at SIGGRAPH 1989. https://en.wikipedia.org/wiki/Boy%27s_surface "
+"https://en.wikipedia.org/wiki/Roman_surface https://en.wikipedia.org/wiki/"
+"Klein_bottle https://mathworld.wolfram.com/BoySurface.html https://"
+"mathworld.wolfram.com/RomanSurface.html https://mathworld.wolfram.com/"
+"EtruscanVenusSurface.html https://mathworld.wolfram.com/IdaSurface.html "
+"Written by Carsten Steger; 2020."
+msgstr ""
+
+#: ../hacks/config/euler2d.xml.h:1
+msgid "Euler 2D"
+msgstr "ეილერი 2D"
+
+#: ../hacks/config/euler2d.xml.h:6 ../hacks/config/whirlwindwarp.xml.h:3
+msgid "Particles"
+msgstr "ნაწილაკები"
+
+#: ../hacks/config/euler2d.xml.h:16
+#, no-c-format
+msgid ""
+"Simulates two dimensional incompressible inviscid fluid flow. https://"
+"en.wikipedia.org/wiki/Euler_equations_%28fluid_dynamics%29 https://"
+"en.wikipedia.org/wiki/Inviscid_flow Written by Stephen Montgomery-Smith; "
+"2002."
+msgstr ""
+
+#: ../hacks/config/extrusion.xml.h:1
+msgid "Extrusion"
+msgstr "გამოწნევა"
+
+#: ../hacks/config/extrusion.xml.h:5 ../hacks/config/morph3d.xml.h:5
+#: ../hacks/config/polytopes.xml.h:5
+msgid "Random object"
+msgstr "შემთხვევითი ობიექტი"
+
+#: ../hacks/config/extrusion.xml.h:6
+msgid "Helix 2"
+msgstr "სპირალი 2"
+
+#: ../hacks/config/extrusion.xml.h:7
+msgid "Helix 3"
+msgstr "სპირალი 3"
+
+#: ../hacks/config/extrusion.xml.h:8
+msgid "Helix 4"
+msgstr "სპირალი 4"
+
+#: ../hacks/config/extrusion.xml.h:9
+msgid "Join offset"
+msgstr "შერწყმის წანაცვლება"
+
+#: ../hacks/config/extrusion.xml.h:10
+msgid "Screw"
+msgstr "ჭანჭიკი"
+
+#: ../hacks/config/extrusion.xml.h:11
+msgid "Taper"
+msgstr "კონუსი"
+
+#: ../hacks/config/extrusion.xml.h:12
+msgid "Twistoid"
+msgstr "ტვისტოიდი"
+
+#: ../hacks/config/extrusion.xml.h:13
+msgid "Use flat coloring"
+msgstr "ბრტყელი გაფერადების გამოყენება"
+
+#: ../hacks/config/extrusion.xml.h:14
+msgid "Use lighting"
+msgstr "განათების გამოყენება"
+
+#: ../hacks/config/extrusion.xml.h:17
+msgid ""
+"Various extruded shapes twist and turn inside out. Written by Linas Vepstas, "
+"David Konerding, and Jamie Zawinski; 1999."
+msgstr ""
+
+#: ../hacks/config/fadeplot.xml.h:1
+msgid "Fade Plot"
+msgstr ""
+
+#: ../hacks/config/fadeplot.xml.h:9 ../hacks/config/lcdscrub.xml.h:6
+#: ../hacks/config/spiral.xml.h:8
+msgid "Cycles"
+msgstr "ციკლები"
+
+#: ../hacks/config/fadeplot.xml.h:15
+msgid ""
+"A waving ribbon follows a sinusoidal path. Written by Bas van Gaalen and "
+"Charles Vidal; 1997."
+msgstr ""
+
+#: ../hacks/config/fiberlamp.xml.h:1
+msgid "Fiber Lamp"
+msgstr "ოპტიკურბოჭკოვანი ნათურა"
+
+#: ../hacks/config/fiberlamp.xml.h:6
+msgid "Fibers"
+msgstr "ფიბრა"
+
+#: ../hacks/config/fiberlamp.xml.h:9
+msgid "Time between knocks"
+msgstr "დრო კაკუნს შორის"
+
+#: ../hacks/config/fiberlamp.xml.h:12
+msgid "A fiber-optic lamp. Groovy. Written by Tim Auckland; 2005."
+msgstr ""
+
+#: ../hacks/config/filmleader.xml.h:1
+msgid "Film Leader"
+msgstr "ფილმის ლიდერი"
+
+#: ../hacks/config/filmleader.xml.h:6 ../hacks/config/pong.xml.h:6
+#: ../hacks/config/unknownpleasures.xml.h:13 ../hacks/config/vfeedback.xml.h:6
+msgid "Noise"
+msgstr "ხმაური"
+
+#: ../hacks/config/filmleader.xml.h:10
+msgid ""
+"A looping countdown based on the SMPTE Universal Film leader on a simulation "
+"of an old analog television. https://en.wikipedia.org/wiki/Film_leader "
+"Written by Jamie Zawinski; 2018."
+msgstr ""
+
+#: ../hacks/config/fireworkx.xml.h:1
+msgid "Fireworkx"
+msgstr "ფეირვერკი"
+
+#: ../hacks/config/fireworkx.xml.h:6 ../hacks/config/lavalite.xml.h:6
+msgid "Activity"
+msgstr "აქტივობა"
+
+#: ../hacks/config/fireworkx.xml.h:8
+msgid "Light flash"
+msgstr "სინათლის გაელვება"
+
+#: ../hacks/config/fireworkx.xml.h:9
+msgid "Shells upward"
+msgstr "ფეიერვერკების ზემოთ გაშვება"
+
+#: ../hacks/config/fireworkx.xml.h:11
+msgid ""
+"Exploding fireworks. See also the \"Eruption\", \"XFlame\" and \"Pyro\" "
+"screen savers. Written by Rony B Chandran; 2004."
+msgstr ""
+
+#: ../hacks/config/flag.xml.h:1
+msgid "Flag"
+msgstr "ალამი"
+
+#: ../hacks/config/flag.xml.h:2
+msgid "Text for flag"
+msgstr "ტექსტი ალმისთვის"
+
+#: ../hacks/config/flag.xml.h:13
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. This draws a waving colored flag, that undulates its way "
+"around the screen. The flag can contain arbitrary text and images. By "
+"default, it displays either the current system name and OS type, or a "
+"picture of \"Bob\". Written by Charles Vidal and Jamie Zawinski; 1997."
+msgstr ""
+
+#: ../hacks/config/flame.xml.h:1
+msgid "Flame"
+msgstr "ალი"
+
+#: ../hacks/config/flame.xml.h:9
+msgid "Number of fractals"
+msgstr "ფრაქტალების რაოდენობა"
+
+#: ../hacks/config/flame.xml.h:15
+msgid "Iterative fractals. Written by Scott Draves; 1993."
+msgstr ""
+
+#: ../hacks/config/flipflop.xml.h:1
+msgid "Flip Flop"
+msgstr ""
+
+#: ../hacks/config/flipflop.xml.h:5
+msgid "Stopped"
+msgstr "გაჩერებულია"
+
+#: ../hacks/config/flipflop.xml.h:7
+msgid "Whirlwind"
+msgstr "გრიგალი"
+
+#: ../hacks/config/flipflop.xml.h:8
+msgid "Draw Tiles"
+msgstr "ფილების დახატვა"
+
+#: ../hacks/config/flipflop.xml.h:9
+msgid "Draw Sticks"
+msgstr "წკირების დახატვა"
+
+#: ../hacks/config/flipflop.xml.h:10
+msgid "Width"
+msgstr "სიგანე"
+
+#: ../hacks/config/flipflop.xml.h:12
+msgid "Load image"
+msgstr "გამოსახულების ჩატვირთვა"
+
+#: ../hacks/config/flipflop.xml.h:15
+msgid ""
+"Colored tiles swap with each other. Written by Kevin Ogden and Sergio "
+"Gutierrez; 2003."
+msgstr ""
+
+#: ../hacks/config/flipscreen3d.xml.h:1
+msgid "Flip Screen 3D"
+msgstr ""
+
+#: ../hacks/config/flipscreen3d.xml.h:5 ../hacks/config/gleidescope.xml.h:12
+#: ../hacks/config/glplanet.xml.h:11 ../hacks/config/ifs.xml.h:67
+#: ../hacks/config/tangram.xml.h:15 ../hacks/config/topblock.xml.h:17
+msgid "Rotate"
+msgstr "შემობრუნება"
+
+#: ../hacks/config/flipscreen3d.xml.h:7
+msgid ""
+"Spins and deforms an image. Written by Ben Buxton and Jamie Zawinski; 2001."
+msgstr ""
+
+#: ../hacks/config/fliptext.xml.h:1
+msgid "Flip Text"
+msgstr "ტექსტის ამობრუნება"
+
+#: ../hacks/config/fliptext.xml.h:8
+msgid "Random text alignment"
+msgstr "ტექსტის შემთხვევითი გასწორება"
+
+#: ../hacks/config/fliptext.xml.h:9 ../hacks/config/starwars.xml.h:7
+msgid "Flush left text"
+msgstr "მარცხენა ტექსტის გაწმენდა"
+
+#: ../hacks/config/fliptext.xml.h:10 ../hacks/config/starwars.xml.h:8
+msgid "Centered text"
+msgstr "დაცენტრებული ტექსტი"
+
+#: ../hacks/config/fliptext.xml.h:11 ../hacks/config/starwars.xml.h:9
+msgid "Flush right text"
+msgstr "მარჯვენა ტექსტის გაწმენდა"
+
+#: ../hacks/config/fliptext.xml.h:12 ../hacks/config/starwars.xml.h:17
+msgid "Font point size"
+msgstr "ფონტის წერტილის ზომა"
+
+#: ../hacks/config/fliptext.xml.h:13 ../hacks/config/gibson.xml.h:12
+msgid "Text columns"
+msgstr "ტექსტის სვეტები"
+
+#: ../hacks/config/fliptext.xml.h:14 ../hacks/config/starwars.xml.h:16
+msgid "Text lines"
+msgstr "ტექსტის ხაზები"
+
+#: ../hacks/config/fliptext.xml.h:16
+msgid ""
+"Successive pages of text flip in and out in a soothing 3D pattern. Written "
+"by Jamie Zawinski; 2005."
+msgstr ""
+
+#: ../hacks/config/flow.xml.h:1
+msgid "Flow"
+msgstr "დინება"
+
+#: ../hacks/config/flow.xml.h:6 ../hacks/config/galaxy.xml.h:5
+#: ../hacks/config/glforestfire.xml.h:6 ../hacks/config/julia.xml.h:6
+#: ../hacks/config/kaleidocycle.xml.h:6 ../hacks/config/laser.xml.h:5
+#: ../hacks/config/lisa.xml.h:14 ../hacks/config/lissie.xml.h:12
+#: ../hacks/config/piecewise.xml.h:6 ../hacks/config/qix.xml.h:18
+#: ../hacks/config/rocks.xml.h:6 ../hacks/config/rotor.xml.h:11
+#: ../hacks/config/rubik.xml.h:5 ../hacks/config/shadebobs.xml.h:9
+#: ../hacks/config/slip.xml.h:6 ../hacks/config/spiral.xml.h:6
+#: ../hacks/config/squirtorus.xml.h:9 ../hacks/config/swirl.xml.h:6
+#: ../hacks/config/worm.xml.h:8
+msgid "Count"
+msgstr "რაოდენობა"
+
+#: ../hacks/config/flow.xml.h:14
+msgid "Length of trails"
+msgstr "კვალი სიგრძე"
+
+#: ../hacks/config/flow.xml.h:16
+msgid "Rotating around attractor"
+msgstr ""
+
+#: ../hacks/config/flow.xml.h:17
+msgid "Ride in the flow"
+msgstr "სიარული ნაკადში"
+
+#: ../hacks/config/flow.xml.h:18 ../hacks/config/glschool.xml.h:16
+#: ../hacks/config/molecule.xml.h:10 ../hacks/config/spheremonics.xml.h:20
+msgid "Draw bounding box"
+msgstr "შემომსაზღვრელი ჩარჩოს დახატვა"
+
+#: ../hacks/config/flow.xml.h:19
+msgid "Periodic attractors"
+msgstr "პერიოდული მიმზიდველები"
+
+#: ../hacks/config/flow.xml.h:20
+msgid "Search for new attractors"
+msgstr "ახალი მიმზიდველების მოძებნა"
+
+#: ../hacks/config/flow.xml.h:22
+msgid ""
+"Strange attractors formed of flows in a 3D differential equation phase "
+"space. Features the popular attractors described by Lorentz, Roessler, "
+"Birkhoff and Duffing, and can discover entirely new attractors by itself. "
+"https://en.wikipedia.org/wiki/Attractor#Strange_attractor Written by Tim "
+"Auckland; 1998."
+msgstr ""
+
+#: ../hacks/config/fluidballs.xml.h:1
+msgid "Fluid Balls"
+msgstr "სითხის ბურთულები"
+
+#: ../hacks/config/fluidballs.xml.h:11
+msgid "      Freefall"
+msgstr "      თავისუფალი ვარდნა"
+
+#: ../hacks/config/fluidballs.xml.h:13
+msgid "Jupiter"
+msgstr "იუპიტერი"
+
+#: ../hacks/config/fluidballs.xml.h:14
+msgid "Still"
+msgstr "სტატიკური გამოსახულება"
+
+#: ../hacks/config/fluidballs.xml.h:15
+msgid "Wind"
+msgstr "ქარი"
+
+#: ../hacks/config/fluidballs.xml.h:16
+msgid "Hurricane"
+msgstr "გრიგალი"
+
+#: ../hacks/config/fluidballs.xml.h:17
+msgid "Clay"
+msgstr "თიხა"
+
+#: ../hacks/config/fluidballs.xml.h:18 ../hacks/config/twang.xml.h:11
+msgid "Friction"
+msgstr "ხახუნი"
+
+#: ../hacks/config/fluidballs.xml.h:19
+msgid "Rubber"
+msgstr "რეზინი"
+
+#: ../hacks/config/fluidballs.xml.h:20
+msgid "Various ball sizes"
+msgstr "სხვადასხვა ზომის ბურთი"
+
+#: ../hacks/config/fluidballs.xml.h:21
+msgid "Shake box"
+msgstr "შერყევის ყუთი"
+
+#: ../hacks/config/fluidballs.xml.h:23
+msgid ""
+"A particle system of bouncing balls. Gravity moves around to shake the box. "
+"Written by Peter Birtles and Jamie Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/flurry.xml.h:1
+msgid "Flurry"
+msgstr ""
+
+#: ../hacks/config/flurry.xml.h:3
+msgid "Classic"
+msgstr "კლასიკური"
+
+#: ../hacks/config/flurry.xml.h:4
+msgid "RGB"
+msgstr "RGB"
+
+#: ../hacks/config/flurry.xml.h:5
+msgid "Fire"
+msgstr "ცეცხლი"
+
+#: ../hacks/config/flurry.xml.h:7
+msgid "Binary"
+msgstr "გამშვები"
+
+#: ../hacks/config/flurry.xml.h:8
+msgid "Psychedelic"
+msgstr "ფსიქოდელია"
+
+#: ../hacks/config/flurry.xml.h:9
+msgid "Insane"
+msgstr "არანორმალური"
+
+#: ../hacks/config/flurry.xml.h:11
+msgid ""
+"A colourful star(fish)like flurry of particles. Written by Calum Robinson "
+"and Tobias Sargeant; 2002."
+msgstr ""
+
+#: ../hacks/config/flyingtoasters.xml.h:1
+msgid "Flying Toasters"
+msgstr "მფრინავი ტოსტერები"
+
+#: ../hacks/config/flyingtoasters.xml.h:6
+msgid "Air speed"
+msgstr "ჰაერის სიჩქარე"
+
+#: ../hacks/config/flyingtoasters.xml.h:9
+msgid "Number of toasters"
+msgstr "ტოსტერების რაოდენობა"
+
+#: ../hacks/config/flyingtoasters.xml.h:10
+msgid "Swarm"
+msgstr ""
+
+#: ../hacks/config/flyingtoasters.xml.h:11
+msgid "Number of slices"
+msgstr "ნაჭრების რაოდენობა"
+
+#: ../hacks/config/flyingtoasters.xml.h:12 ../hacks/config/jigglypuff.xml.h:6
+#: ../hacks/config/winduprobot.xml.h:20
+msgid "Chrome"
+msgstr "ქრომი"
+
+#: ../hacks/config/flyingtoasters.xml.h:13
+#: ../hacks/config/glforestfire.xml.h:14 ../hacks/config/glmatrix.xml.h:15
+#: ../hacks/config/glschool.xml.h:14
+msgid "Fog"
+msgstr "ნისლი"
+
+#: ../hacks/config/flyingtoasters.xml.h:17
+#, no-c-format
+msgid ""
+"A fleet of 3d space-age jet-powered flying toasters (and toast!) Inspired by "
+"the ancient Berkeley Systems After Dark flying toasters. https://"
+"en.wikipedia.org/wiki/After_Dark_%28software%29#Flying_Toasters Written by "
+"Jamie Zawinski and Devon Dossett; 2003."
+msgstr ""
+
+#: ../hacks/config/fontglide.xml.h:1
+msgid "Font Glide"
+msgstr "ფონტის სრიალი"
+
+#: ../hacks/config/fontglide.xml.h:8 ../hacks/config/raverhoop.xml.h:15
+#: ../hacks/config/tangram.xml.h:5 ../hacks/config/xlyap.xml.h:5
+msgid "Brief"
+msgstr "მოკლე"
+
+#: ../hacks/config/fontglide.xml.h:9
+msgid "Page linger"
+msgstr "გვერდის გაჩერება"
+
+#: ../hacks/config/fontglide.xml.h:11
+msgid "Pages of text"
+msgstr "ტექსტის გვერდები"
+
+#: ../hacks/config/fontglide.xml.h:12
+msgid "Horizontally scrolling text"
+msgstr "ჰორიზონტალურად გადახვევადი ტექსტი"
+
+#: ../hacks/config/fontglide.xml.h:13
+msgid "Random display style"
+msgstr "შემთხვევითი ჩვენების სტილი"
+
+#: ../hacks/config/fontglide.xml.h:14
+msgid "Font border thickness"
+msgstr "ფონტის საზღვრის სისქე"
+
+#: ../hacks/config/fontglide.xml.h:15
+msgid "Vapor trails"
+msgstr "ორთქლის კვალები"
+
+#: ../hacks/config/fontglide.xml.h:17
+msgid ""
+"Puts text on the screen using large characters that glide in from the edges, "
+"assemble, then disperse. Alternately, it can simply scroll whole sentences "
+"from right to left. Written by Jamie Zawinski; 2003."
+msgstr ""
+
+#: ../hacks/config/forest.xml.h:1 ../hacks/config/glforestfire.xml.h:10
+msgid "Forest"
+msgstr "ტყე"
+
+#: ../hacks/config/forest.xml.h:9
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Fractal trees. Written by Peter Baumung; 1997."
+msgstr ""
+
+#: ../hacks/config/fuzzyflakes.xml.h:1
+msgid "Fuzzy Flakes"
+msgstr ""
+
+#: ../hacks/config/fuzzyflakes.xml.h:9 ../hacks/config/hypnowheel.xml.h:10
+#: ../hacks/config/xspirograph.xml.h:8
+msgid "Layers"
+msgstr "ფენები"
+
+#: ../hacks/config/fuzzyflakes.xml.h:13
+msgid "Red"
+msgstr "წითელი"
+
+#: ../hacks/config/fuzzyflakes.xml.h:14
+msgid "Pink"
+msgstr "ვარდისფერი"
+
+#: ../hacks/config/fuzzyflakes.xml.h:15
+msgid "Yellow"
+msgstr "ყვითელი"
+
+#: ../hacks/config/fuzzyflakes.xml.h:17
+msgid "Cyan"
+msgstr "ცისფერი"
+
+#: ../hacks/config/fuzzyflakes.xml.h:19
+msgid "Magenta"
+msgstr "ალისფერი"
+
+#: ../hacks/config/fuzzyflakes.xml.h:24
+msgid "Border thickness"
+msgstr ""
+
+#: ../hacks/config/fuzzyflakes.xml.h:28
+msgid ""
+"Falling colored snowflake/flower shapes. https://en.wikipedia.org/wiki/"
+"Snowflake Written by Barry Dmytro; 2004."
+msgstr ""
+
+#: ../hacks/config/galaxy.xml.h:1
+msgid "Galaxy"
+msgstr "გალაქტიკა"
+
+#: ../hacks/config/galaxy.xml.h:12
+msgid "Rotate viewpoint"
+msgstr ""
+
+#: ../hacks/config/galaxy.xml.h:14
+msgid ""
+"Spinning galaxies collide. Written by Uli Siegmund, Harald Backert, and "
+"Hubert Feyrer; 1997."
+msgstr ""
+
+#: ../hacks/config/gears.xml.h:1
+msgid "Gears"
+msgstr ""
+
+#: ../hacks/config/gears.xml.h:9
+msgid "Gear count"
+msgstr ""
+
+#: ../hacks/config/gears.xml.h:15
+msgid ""
+"Interlocking gears. See also the \"Pinion\" and \"Möbius Gears\" screen "
+"savers. https://en.wikipedia.org/wiki/Involute_gear https://en.wikipedia.org/"
+"wiki/Epicyclic_gearing Written by Jamie Zawinski; 2007."
+msgstr ""
+
+#: ../hacks/config/geodesic.xml.h:1
+msgid "Geodesic"
+msgstr "გეოდეზიური"
+
+#: ../hacks/config/geodesic.xml.h:2
+msgid "Mesh faces"
+msgstr "ბადის ზედაპირები"
+
+#: ../hacks/config/geodesic.xml.h:3
+msgid "Solid faces"
+msgstr "მყარი ზედაპირები"
+
+#: ../hacks/config/geodesic.xml.h:4
+msgid "Stellated faces"
+msgstr "ვარსკვლავური ზედაპირები"
+
+#: ../hacks/config/geodesic.xml.h:5
+msgid "Inverse Stellated"
+msgstr "შებრუნებული ვარსკვლავი"
+
+#: ../hacks/config/geodesic.xml.h:7
+msgid "Random face style"
+msgstr "ზედაპირის შემთხვევითი სტილი"
+
+#: ../hacks/config/geodesic.xml.h:19 ../hacks/config/kaleidocycle.xml.h:5
+#: ../hacks/config/sphereeversion.xml.h:31 ../hacks/config/strange.xml.h:11
+msgid "8"
+msgstr "8"
+
+#: ../hacks/config/geodesic.xml.h:20
+msgid ""
+"A mesh geodesic sphere of increasing and decreasing complexity. A geodesic "
+"sphere is an icosohedron whose equilateral faces are sub-divided into non-"
+"equilateral triangles to more closely approximate a sphere. The animation "
+"shows the equilateral triangles subdivided into four coplanar equilateral "
+"triangles; and then inflated outward, causing the sub-triangles to no longer "
+"be equilateral, but to more closely approximate the surface of a sphere. "
+"https://en.wikipedia.org/wiki/Geodesic_dome https://en.wikipedia.org/wiki/"
+"Buckminster_Fuller Written by Jamie Zawinski; 2013."
+msgstr ""
+
+#: ../hacks/config/geodesicgears.xml.h:1
+msgid "Geodesic Gears"
+msgstr "გეოდეზიური კბილანები"
+
+#: ../hacks/config/geodesicgears.xml.h:8
+msgid "Describe gears"
+msgstr "აღწერეთ კბილანები"
+
+#: ../hacks/config/geodesicgears.xml.h:9
+msgid "Number gears"
+msgstr "კბილანების რაოდენობა"
+
+#: ../hacks/config/geodesicgears.xml.h:14
+msgid ""
+"A set of meshed gears arranged on the surface of a sphere. https://"
+"en.wikipedia.org/wiki/Geodesic_dome https://en.wikipedia.org/wiki/"
+"Involute_gear https://en.wikipedia.org/wiki/Buckminster_Fuller Written by "
+"Jamie Zawinski; 2014."
+msgstr ""
+
+#: ../hacks/config/gflux.xml.h:1
+msgid "GFlux"
+msgstr "GFlux"
+
+#: ../hacks/config/gflux.xml.h:9
+msgid "Mesh density"
+msgstr "ბადის სიმკვრივე"
+
+#: ../hacks/config/gflux.xml.h:12 ../hacks/config/glmatrix.xml.h:16
+msgid "Waves"
+msgstr "ტალღები"
+
+#: ../hacks/config/gflux.xml.h:13 ../hacks/config/glhanoi.xml.h:13
+#: ../hacks/config/hilbert.xml.h:14 ../hacks/config/lavalite.xml.h:10
+#: ../hacks/config/strange.xml.h:19
+msgid "10"
+msgstr "10"
+
+#: ../hacks/config/gflux.xml.h:14
+msgid "Wire mesh"
+msgstr "მავთულის ბადე"
+
+#: ../hacks/config/gflux.xml.h:15
+msgid "Flat lighting"
+msgstr "ბრტყელი განათება"
+
+#: ../hacks/config/gflux.xml.h:17
+msgid "Checkerboard"
+msgstr "ჭადრაკის დაფა"
+
+#: ../hacks/config/gflux.xml.h:18
+msgid "Picture"
+msgstr "სურათი"
+
+#: ../hacks/config/gflux.xml.h:20
+msgid "Undulating waves on a rotating grid. Written by Josiah Pease; 2000."
+msgstr ""
+
+#: ../hacks/config/gibson.xml.h:1
+msgid "Gibson"
+msgstr "გიბსონი"
+
+#: ../hacks/config/gibson.xml.h:6 ../hacks/config/glmatrix.xml.h:9
+msgid "Glyph speed"
+msgstr "გლიფის სიჩქარე"
+
+#: ../hacks/config/gibson.xml.h:8
+msgid "Grid width"
+msgstr "ბადის სიგანე"
+
+#: ../hacks/config/gibson.xml.h:9
+msgid "Grid depth"
+msgstr "ბადის სიღრმე"
+
+#: ../hacks/config/gibson.xml.h:10
+msgid "Tower depth"
+msgstr "კოშკის სიღრმე"
+
+#: ../hacks/config/gibson.xml.h:11
+msgid "Tower spacing"
+msgstr "კოშკის დაშორება"
+
+#: ../hacks/config/gibson.xml.h:16
+msgid ""
+"Hacking the Gibson, as per the 1995 classic film, HACKERS. Cereal Killer: "
+"\"Oh yeah, you want a seriously righteous hack, you score one of those "
+"Gibsons, man. You know, supercomputers they use to like, do physics, and "
+"look for oil and stuff?\" Phantom Phreak: \"Ain't no way, man, security's "
+"too tight. The big iron?\" Zero Cool: \"Maybe. But, if I were gonna hack "
+"some heavy metal, I'd, uh, work my way back through some low security, and "
+"try the back door.\" Cereal Killer: \"Yeah but oh man, wouldn't you just "
+"love to get one of those Gibsons, baby? Ooooh!\" Phantom Phreak: \"Yo, who "
+"ate all of my fries?\" Written by Jamie Zawinski; 2020."
+msgstr ""
+
+#: ../hacks/config/glblur.xml.h:1
+msgid "GL Blur"
+msgstr "GL ბუნდოვნება"
+
+#: ../hacks/config/glblur.xml.h:6
+msgid "Blur smoothness"
+msgstr "ბუნდოვნების სიგლუვე"
+
+#: ../hacks/config/glblur.xml.h:18
+msgid ""
+"Flowing field effects from the vapor trails around a moving object. This is "
+"done by rendering the scene into a small texture, then repeatedly rendering "
+"increasingly-enlarged and increasingly-transparent versions of that texture "
+"onto the frame buffer. As such, it's quite GPU-intensive: if you don't have "
+"a very good graphics card, it will hurt your machine bad. Written by Jamie "
+"Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/glcells.xml.h:1
+msgid "GL Cells"
+msgstr "GL უჯრედები"
+
+#: ../hacks/config/glcells.xml.h:9
+msgid "Max cells"
+msgstr "მაქს. უჯრედები"
+
+#: ../hacks/config/glcells.xml.h:12
+msgid "Cell radius"
+msgstr "უჯრედის რადიუსი"
+
+#: ../hacks/config/glcells.xml.h:14
+msgid "Lowest sphere detail"
+msgstr "უმდაბლესი სფეროს დეტალი"
+
+#: ../hacks/config/glcells.xml.h:15
+msgid "Medium sphere detail"
+msgstr "საშუალო სფეროს დეტალი"
+
+#: ../hacks/config/glcells.xml.h:16
+msgid "Normal sphere detail"
+msgstr "ნორმალური სფეროს დეტალი"
+
+#: ../hacks/config/glcells.xml.h:17
+msgid "More sphere detail"
+msgstr "მეტი სფეროს დეტალი"
+
+#: ../hacks/config/glcells.xml.h:18
+msgid "Highest sphere detail"
+msgstr "უმაღლესი სფეროს დეტალი"
+
+#: ../hacks/config/glcells.xml.h:19
+msgid "Starve"
+msgstr "შიმშილი"
+
+#: ../hacks/config/glcells.xml.h:20
+msgid "Min food"
+msgstr "მინ. საჭმელი"
+
+#: ../hacks/config/glcells.xml.h:21
+msgid "Gorge"
+msgstr "ხეობა"
+
+#: ../hacks/config/glcells.xml.h:22
+msgid "Max food"
+msgstr "მაქს. საჭმელი"
+
+#: ../hacks/config/glcells.xml.h:23
+msgid "Quick"
+msgstr "სწრაფი"
+
+#: ../hacks/config/glcells.xml.h:24
+msgid "Cell division"
+msgstr "უჯრედის გაყოფა"
+
+#: ../hacks/config/glcells.xml.h:26
+msgid "Min distance"
+msgstr "მინ. დაშორება"
+
+#: ../hacks/config/glcells.xml.h:30
+msgid "15"
+msgstr "15"
+
+#: ../hacks/config/glcells.xml.h:31
+msgid "Keep dead cells"
+msgstr "მკვდარი უჯრედების შენარჩუნება"
+
+#: ../hacks/config/glcells.xml.h:34
+msgid ""
+"Cells growing, dividing and dying on your screen. Microscopic pathos. "
+"Written by Matthias Toussaint; 2007."
+msgstr ""
+
+#: ../hacks/config/gleidescope.xml.h:1
+msgid "Gleidescope"
+msgstr "გლეიდესკოპი"
+
+#: ../hacks/config/gleidescope.xml.h:6
+msgid "Size of tube"
+msgstr "მილის ზომა"
+
+#: ../hacks/config/gleidescope.xml.h:9
+msgid "Image duration"
+msgstr "გამოსახულების ხანგრძლივობა"
+
+#: ../hacks/config/gleidescope.xml.h:10 ../hacks/config/glslideshow.xml.h:7
+msgid "5 minutes"
+msgstr "5 წუთი"
+
+#: ../hacks/config/gleidescope.xml.h:11
+msgid "Move"
+msgstr "გადატანა"
+
+#: ../hacks/config/gleidescope.xml.h:13 ../hacks/config/hyperball.xml.h:6
+#: ../hacks/config/hypercube.xml.h:6 ../hacks/config/mirrorblob.xml.h:6
+#: ../hacks/config/strange.xml.h:14 ../hacks/config/zoom.xml.h:1
+msgid "Zoom"
+msgstr "გადიდება"
+
+#: ../hacks/config/gleidescope.xml.h:15
+msgid ""
+"A kaleidoscope that operates on a loaded image. https://en.wikipedia.org/"
+"wiki/Kaleidoscope Written by Andrew Dean; 2003."
+msgstr ""
+
+#: ../hacks/config/glforestfire.xml.h:1
+msgid "GL Forest Fire"
+msgstr ""
+
+#: ../hacks/config/glforestfire.xml.h:5
+msgid "Rain"
+msgstr "წვიმა"
+
+#: ../hacks/config/glforestfire.xml.h:7
+msgid "Huge fire"
+msgstr "უზარმაზარი ცეცხლი"
+
+#: ../hacks/config/glforestfire.xml.h:8
+msgid "Desert"
+msgstr "უდაბნო"
+
+#: ../hacks/config/glforestfire.xml.h:9
+msgid "Number of trees"
+msgstr "ხეების რაოდენობა"
+
+#: ../hacks/config/glforestfire.xml.h:12
+msgid "Textures"
+msgstr "ტექსტურები"
+
+#: ../hacks/config/glforestfire.xml.h:13
+msgid "Shadows"
+msgstr "ჩრდილები"
+
+#: ../hacks/config/glforestfire.xml.h:17
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws an animation of sprinkling fire-like 3D triangles in a "
+"landscape filled with trees. Written by Eric Lassauge; 2002."
+msgstr ""
+
+#: ../hacks/config/glhanoi.xml.h:1
+msgid "GL Hanoi"
+msgstr "GL Hanoi"
+
+#: ../hacks/config/glhanoi.xml.h:6
+msgid "Number of disks"
+msgstr "დისკების რაოდენობა"
+
+#: ../hacks/config/glhanoi.xml.h:7
+msgid "31"
+msgstr "31"
+
+#: ../hacks/config/glhanoi.xml.h:8
+msgid "Number of poles"
+msgstr "ძელების რაოდენობა"
+
+#: ../hacks/config/glhanoi.xml.h:10
+msgid "Speed (of smallest disks)"
+msgstr "სიჩქარე (ყველაზე პატარა დისკების)"
+
+#: ../hacks/config/glhanoi.xml.h:12
+msgid "Length of disk trails"
+msgstr ""
+
+#: ../hacks/config/glhanoi.xml.h:14 ../hacks/config/pulsar.xml.h:7
+msgid "Enable fog"
+msgstr "ნისლის ჩართვა"
+
+#: ../hacks/config/glhanoi.xml.h:17 ../hacks/config/pulsar.xml.h:6
+msgid "Enable lighting"
+msgstr "განათების ჩართვა"
+
+#: ../hacks/config/glhanoi.xml.h:18
+msgid ""
+"Solves the Towers of Hanoi puzzle. Move N disks from one pole to another, "
+"one disk at a time, with no disk ever resting on a disk smaller than itself. "
+"https://en.wikipedia.org/wiki/Tower_of_Hanoi Written by Dave Atkinson; 2005."
+msgstr ""
+
+#: ../hacks/config/glitchpeg.xml.h:1
+msgid "GlitchPEG"
+msgstr "GlitchPEG"
+
+#: ../hacks/config/glitchpeg.xml.h:8
+msgid "Glitchiness"
+msgstr ""
+
+#: ../hacks/config/glitchpeg.xml.h:9
+msgid ""
+"Loads an image, corrupts it, and then displays the corrupted version, "
+"several times a second. After a while, finds a new image to corrupt. Written "
+"by Jamie Zawinski; 2018."
+msgstr ""
+
+#: ../hacks/config/glknots.xml.h:1
+msgid "GL Knots"
+msgstr "GL კვანძები"
+
+#: ../hacks/config/glknots.xml.h:16
+msgid "Segmented"
+msgstr "სეგმენტირებული"
+
+#: ../hacks/config/glknots.xml.h:25
+msgid ""
+"Generates some twisting 3d knot patterns. Spins 'em around. https://"
+"en.wikipedia.org/wiki/Knot_theory Written by Jamie Zawinski; 2003."
+msgstr ""
+
+#: ../hacks/config/glmatrix.xml.h:1
+msgid "GL Matrix"
+msgstr "GL მატრიცა"
+
+#: ../hacks/config/glmatrix.xml.h:6
+msgid "Glyph density"
+msgstr "გლიფის სიმკვრივე"
+
+#: ../hacks/config/glmatrix.xml.h:11 ../hacks/config/xmatrix.xml.h:4
+msgid "Matrix encoding"
+msgstr "მატრიცის კოდირება"
+
+#: ../hacks/config/glmatrix.xml.h:12 ../hacks/config/xmatrix.xml.h:5
+msgid "Binary encoding"
+msgstr "ბინარული კოდირება"
+
+#: ../hacks/config/glmatrix.xml.h:13 ../hacks/config/xmatrix.xml.h:6
+msgid "Hexadecimal encoding"
+msgstr "თექვსმეტობითი კოდირება"
+
+#: ../hacks/config/glmatrix.xml.h:14 ../hacks/config/xmatrix.xml.h:7
+msgid "Genetic encoding"
+msgstr "გენეტიკური კოდრება"
+
+#: ../hacks/config/glmatrix.xml.h:17
+msgid "Panning"
+msgstr "პანინგ"
+
+#: ../hacks/config/glmatrix.xml.h:21
+msgid ""
+"The 3D \"digital rain\" effect, as seen in the title sequence of \"The "
+"Matrix\". See also \"xmatrix\" for a 2D rendering of the similar effect that "
+"appeared on the computer monitors actually *in* the movie. https://"
+"en.wikipedia.org/wiki/Matrix_digital_rain Written by Jamie Zawinski; 2003."
+msgstr ""
+
+#: ../hacks/config/glplanet.xml.h:1
+msgid "GL Planet"
+msgstr "GL პლანეტა"
+
+#: ../hacks/config/glplanet.xml.h:8
+msgid "Day image"
+msgstr "დღის გამოსახულება"
+
+#: ../hacks/config/glplanet.xml.h:9
+msgid "Night image"
+msgstr "ღამის გამოსახულება"
+
+#: ../hacks/config/glplanet.xml.h:14
+msgid "Random Shape"
+msgstr "შემთხვევითი ფორმა"
+
+#: ../hacks/config/glplanet.xml.h:15
+msgid "Globe"
+msgstr "გლობალური"
+
+#: ../hacks/config/glplanet.xml.h:16
+msgid "Mercator"
+msgstr "სავაჭრო"
+
+#: ../hacks/config/glplanet.xml.h:17
+msgid "Equirectangular"
+msgstr "თანასწორკუთხა"
+
+#: ../hacks/config/glplanet.xml.h:20
+msgid ""
+"The Earth, bouncing around in space, rendered with satellite imagery of the "
+"planet in both sunlight and darkness. If you would like it to display a "
+"different planet, any pair of Equirectangular-projected maps will work. The "
+"maps that come with \"ssystem\" work well. Written by David Konerding and "
+"Jamie Zawinski; 1998."
+msgstr ""
+
+#: ../hacks/config/glschool.xml.h:1
+msgid "GL School"
+msgstr "GL სკოლა"
+
+#: ../hacks/config/glschool.xml.h:6
+msgid "Fish count"
+msgstr "თევზის რაოდენობა"
+
+#: ../hacks/config/glschool.xml.h:9
+msgid "Avoidance"
+msgstr "თავიდან აცილება"
+
+#: ../hacks/config/glschool.xml.h:10
+msgid "Velocity matching"
+msgstr ""
+
+#: ../hacks/config/glschool.xml.h:11
+msgid "Centering"
+msgstr "დაცენტრება"
+
+#: ../hacks/config/glschool.xml.h:12
+msgid "Goal following"
+msgstr ""
+
+#: ../hacks/config/glschool.xml.h:15
+msgid "Draw goal"
+msgstr ""
+
+#: ../hacks/config/glschool.xml.h:18
+msgid ""
+"A school of fish, using the classic \"Boids\" algorithm by Craig Reynolds. "
+"https://en.wikipedia.org/wiki/Boids Written by David C. Lambert and Jamie "
+"Zawinski; 2006."
+msgstr ""
+
+#: ../hacks/config/glslideshow.xml.h:1
+msgid "GL Slideshow"
+msgstr ""
+
+#: ../hacks/config/glslideshow.xml.h:9
+#, no-c-format
+msgid "50%"
+msgstr "50%"
+
+#: ../hacks/config/glslideshow.xml.h:10
+msgid "Always show at least this much of the image"
+msgstr ""
+
+#: ../hacks/config/glslideshow.xml.h:12 ../hacks/config/substrate.xml.h:15
+#, no-c-format
+msgid "100%"
+msgstr "100%"
+
+#: ../hacks/config/glslideshow.xml.h:14
+msgid "Pan/zoom duration"
+msgstr ""
+
+#: ../hacks/config/glslideshow.xml.h:17
+msgid "Crossfade duration"
+msgstr ""
+
+#: ../hacks/config/glslideshow.xml.h:21
+msgid ""
+"Loads a random sequence of images and smoothly scans and zooms around in "
+"each, fading from pan to pan. Written by Jamie Zawinski and Mike Oliphant; "
+"2003."
+msgstr ""
+
+#: ../hacks/config/glsnake.xml.h:1
+msgid "GL Snake"
+msgstr "GL გველი"
+
+#: ../hacks/config/glsnake.xml.h:9
+msgid "Packing"
+msgstr "შეფუთვა"
+
+#: ../hacks/config/glsnake.xml.h:10
+msgid "Loose"
+msgstr "ფართო"
+
+#: ../hacks/config/glsnake.xml.h:12
+msgid "Angular velocity"
+msgstr "კუთხოვანი სიჩქარე"
+
+#: ../hacks/config/glsnake.xml.h:14
+msgid "Y angular velocity"
+msgstr "Y კუთხური სიჩქარე"
+
+#: ../hacks/config/glsnake.xml.h:15
+msgid "Z angular velocity"
+msgstr "Z კუთხური სიჩქარე"
+
+#: ../hacks/config/glsnake.xml.h:16 ../hacks/config/unicrud.xml.h:11
+msgid "Show titles"
+msgstr "სათაურების ჩვენება"
+
+#: ../hacks/config/glsnake.xml.h:20
+#, no-c-format
+msgid ""
+"The \"Rubik's Snake\" puzzle. See also the \"Rubik\" and \"Cube21\" screen "
+"savers. https://en.wikipedia.org/wiki/Rubik%27s_Snake Written by Jamie "
+"Wilkinson, Andrew Bennetts, and Peter Aylett; 2002."
+msgstr ""
+
+#: ../hacks/config/gltext.xml.h:1
+msgid "GL Text"
+msgstr "GL ტექსტი"
+
+#: ../hacks/config/gltext.xml.h:5
+msgid "Display system information"
+msgstr ""
+
+#: ../hacks/config/gltext.xml.h:6
+msgid "Display date and time"
+msgstr ""
+
+#: ../hacks/config/gltext.xml.h:7 ../hacks/config/handsy.xml.h:20
+#: ../hacks/config/splitflap.xml.h:13
+msgid "Always face front"
+msgstr ""
+
+#: ../hacks/config/gltext.xml.h:8 ../hacks/config/handsy.xml.h:21
+#: ../hacks/config/splitflap.xml.h:14
+msgid "Spin all the way around"
+msgstr ""
+
+#: ../hacks/config/gltext.xml.h:20
+msgid ""
+"A few lines of text spinning around in a solid 3D font. The text can use "
+"strftime() escape codes to display the current date and time. Written by "
+"Jamie Zawinski; 2001."
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:1
+msgid "Goop"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:9
+msgid "Blobs"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:11
+msgid "Elasticity"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:12
+msgid "Speed limit"
+msgstr "სიჩქარის ლიმიტი"
+
+#: ../hacks/config/goop.xml.h:14
+msgid "Transparent blobs"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:15
+msgid "Opaque blobs"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:16
+msgid "XOR blobs"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:17
+msgid "Additive colors (transmitted light)"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:18
+msgid "Subtractive colors (reflected light)"
+msgstr ""
+
+#: ../hacks/config/goop.xml.h:19
+msgid ""
+"Translucent amoeba-like blobs wander the screen. Written by Jamie Zawinski; "
+"1997."
+msgstr ""
+
+#: ../hacks/config/grav.xml.h:1
+msgid "Grav"
+msgstr ""
+
+#: ../hacks/config/grav.xml.h:6
+msgid "Number of objects"
+msgstr "ობიექტების რაოდენობა"
+
+#: ../hacks/config/grav.xml.h:10
+msgid "Orbital decay"
+msgstr ""
+
+#: ../hacks/config/grav.xml.h:11
+msgid "Object trails"
+msgstr ""
+
+#: ../hacks/config/grav.xml.h:13
+msgid ""
+"An orbital simulation, or perhaps a cloud chamber. Written by Greg Bowering; "
+"1997."
+msgstr ""
+
+#: ../hacks/config/gravitywell.xml.h:1
+msgid "Gravity Well"
+msgstr ""
+
+#: ../hacks/config/gravitywell.xml.h:10
+msgid "Grid Size"
+msgstr "ბადის ზომა"
+
+#: ../hacks/config/gravitywell.xml.h:13 ../hacks/config/scooter.xml.h:12
+msgid "Number of stars"
+msgstr "ვარსკვლავების რაოდენობა"
+
+#: ../hacks/config/gravitywell.xml.h:15
+msgid ""
+"Massive objects distort space in a two dimensional universe. Written by "
+"Jamie Zawinski; 2019."
+msgstr ""
+
+#: ../hacks/config/greynetic.xml.h:1
+msgid "Greynetic"
+msgstr ""
+
+#: ../hacks/config/greynetic.xml.h:5
+msgid "Grey"
+msgstr "ნაცრისფერი"
+
+#: ../hacks/config/greynetic.xml.h:7
+msgid ""
+"Colored, stippled and transparent rectangles. Written by Jamie Zawinski; "
+"1992."
+msgstr ""
+
+#: ../hacks/config/halftone.xml.h:1
+msgid "Halftone"
+msgstr "ნახევარტონი"
+
+#: ../hacks/config/halftone.xml.h:6
+msgid "Gravity points"
+msgstr ""
+
+#: ../hacks/config/halftone.xml.h:9
+msgid "Dot size"
+msgstr "წერტილის ზომა"
+
+#: ../hacks/config/halftone.xml.h:10 ../hacks/config/metaballs.xml.h:14
+msgid "Big"
+msgstr "დიდი"
+
+#: ../hacks/config/halftone.xml.h:11
+msgid "Dot fill factor"
+msgstr ""
+
+#: ../hacks/config/halftone.xml.h:13
+msgid "Minimum speed"
+msgstr "მინიმალური სიჩქარე"
+
+#: ../hacks/config/halftone.xml.h:14
+msgid "Maximum speed"
+msgstr "მაქსიმალური სიჩქარე"
+
+#: ../hacks/config/halftone.xml.h:15
+msgid "Minimum mass"
+msgstr "მინიმალური მასა"
+
+#: ../hacks/config/halftone.xml.h:16
+msgid "Maximum mass"
+msgstr "მაქსიმალური მასა"
+
+#: ../hacks/config/halftone.xml.h:18
+msgid ""
+"A halftone dot pattern in motion. Draws the gravity force in each point on "
+"the screen seen through a halftone dot pattern. The gravity force is "
+"calculated from a set of moving mass points. View it from a distance for "
+"best effect. https://en.wikipedia.org/wiki/Halftone Written by Peter Jaric; "
+"2002."
+msgstr ""
+
+#: ../hacks/config/halo.xml.h:1
+msgid "Halo"
+msgstr ""
+
+#: ../hacks/config/halo.xml.h:6
+msgid "Number of circles"
+msgstr "წრეების რაოდენობა"
+
+#: ../hacks/config/halo.xml.h:10
+msgid "Random mode"
+msgstr "შემთხვევითი რეჟიმი"
+
+#: ../hacks/config/halo.xml.h:11
+msgid "Seuss mode"
+msgstr ""
+
+#: ../hacks/config/halo.xml.h:12
+msgid "Ramp mode"
+msgstr ""
+
+#: ../hacks/config/halo.xml.h:13
+msgid "Animate circles"
+msgstr "წრეწირების ანიმაცია"
+
+#: ../hacks/config/halo.xml.h:15
+msgid ""
+"Circular interference patterns. https://en.wikipedia.org/wiki/Moire_pattern "
+"Written by Jamie Zawinski; 1993."
+msgstr ""
+
+#: ../hacks/config/handsy.xml.h:1
+msgid "Handsy"
+msgstr ""
+
+#: ../hacks/config/handsy.xml.h:9
+msgid "Number of hands"
+msgstr "ხელების რაოდენობა"
+
+#: ../hacks/config/handsy.xml.h:24
+msgid ""
+"A set of robotic hands communicate non-verbally. Written by Jamie Zawinski; "
+"2018."
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:1
+msgid "Headroom"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:8
+msgid "Don't wobble"
+msgstr "არ იკანკალო"
+
+#: ../hacks/config/headroom.xml.h:9
+msgid "Wobble around X axis"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:10
+msgid "Wobble around Y axis"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:11
+msgid "Wobble around Z axis"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:12
+msgid "Wobble around X and Y axes"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:13
+msgid "Wobble around X and Z axes"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:14
+msgid "Wobble around Y and Z axes"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:15
+msgid "Wobble around all three axes"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:18
+msgid "Mask Headroom"
+msgstr ""
+
+#: ../hacks/config/headroom.xml.h:20
+msgid ""
+"\"Back in my day, we used to say 'No future'. Well. This is it.\" -- Blank "
+"Reg \"I can dump down all the information in the mind. Then I can eliminate "
+"any information I don't want. My parrot squawks in much the same way. For "
+"the moment, the computer power is only enough to generate a human head.\" -- "
+"Bryce Lynch Written by Jamie Zawinski; 2020."
+msgstr ""
+
+#: ../hacks/config/helix.xml.h:1
+msgid "Helix"
+msgstr "სპირალი"
+
+#: ../hacks/config/helix.xml.h:9
+msgid "Spirally string-art-ish patterns. Written by Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/hexadrop.xml.h:1
+msgid "Hexadrop"
+msgstr ""
+
+#: ../hacks/config/hexadrop.xml.h:9 ../hacks/config/penrose.xml.h:9
+#: ../hacks/config/twang.xml.h:15
+msgid "Tile size"
+msgstr "ფილის ზომა"
+
+#: ../hacks/config/hexadrop.xml.h:11 ../hacks/config/klein.xml.h:2
+msgid "Random shape"
+msgstr "შემთხვევითი ფორმა"
+
+#: ../hacks/config/hexadrop.xml.h:12
+msgid "Triangles"
+msgstr "სამკუთხედები"
+
+#: ../hacks/config/hexadrop.xml.h:13
+msgid "Squares"
+msgstr "კვარატები"
+
+#: ../hacks/config/hexadrop.xml.h:14
+msgid "Hexagons"
+msgstr "ექვსკუთხედები"
+
+#: ../hacks/config/hexadrop.xml.h:15
+msgid "Octagons"
+msgstr "რვაკუთხედები"
+
+#: ../hacks/config/hexadrop.xml.h:16
+msgid "Random speed"
+msgstr "შემთხვევითი სიჩქარე"
+
+#: ../hacks/config/hexadrop.xml.h:17
+msgid "Uniform speed"
+msgstr "ერთგვაროვანი სიჩქარე"
+
+#: ../hacks/config/hexadrop.xml.h:18
+msgid "Non-uniform speed"
+msgstr "არაერთგვაროვანი სიჩქარე"
+
+#: ../hacks/config/hexadrop.xml.h:19
+msgid "Random sync"
+msgstr "შემთხვევითი სინქრონიზაცია"
+
+#: ../hacks/config/hexadrop.xml.h:20
+msgid "Synchronized"
+msgstr "სინქრონიზებულია"
+
+#: ../hacks/config/hexadrop.xml.h:21
+msgid "Non-synchronized"
+msgstr "არასინქრონიზებული"
+
+#: ../hacks/config/hexadrop.xml.h:23
+msgid ""
+"A grid of hexagons or other shapes, with tiles dropping out. https://"
+"en.wikipedia.org/wiki/Tiling_by_regular_polygons Written by Jamie Zawinski; "
+"2013."
+msgstr ""
+
+#: ../hacks/config/hexstrut.xml.h:1
+msgid "Hex Strut"
+msgstr ""
+
+#: ../hacks/config/hexstrut.xml.h:9
+msgid "Hexagon Size"
+msgstr ""
+
+#: ../hacks/config/hexstrut.xml.h:12
+msgid "Line Thickness"
+msgstr "ხაზის სისქე"
+
+#: ../hacks/config/hexstrut.xml.h:18
+msgid ""
+"A grid of hexagons composed of rotating Y-shaped struts. Waves of rotation "
+"and color changes randomly propagate across the plane. Written by Jamie "
+"Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/hilbert.xml.h:1
+msgid "Hilbert"
+msgstr ""
+
+#: ../hacks/config/hilbert.xml.h:2
+msgid "2D or 3D"
+msgstr ""
+
+#: ../hacks/config/hilbert.xml.h:3
+msgid "2D"
+msgstr "2D"
+
+#: ../hacks/config/hilbert.xml.h:4
+msgid "3D"
+msgstr "3D"
+
+#: ../hacks/config/hilbert.xml.h:5
+msgid "Open or closed paths"
+msgstr ""
+
+#: ../hacks/config/hilbert.xml.h:6
+msgid "Closed"
+msgstr "დახურულია"
+
+#: ../hacks/config/hilbert.xml.h:7
+msgid "Open"
+msgstr "გახსნა"
+
+#.
+#. On a 2.93 gHz iMac i7, I get these rates with -delay 0:
+#.
+#. detail 3:  invisible
+#. detail 4:  barely visible
+#. detail 5:  1000+ fps, looks like noise at -delay 0, ok at -delay 20000
+#. detail 8:  ~700+ fps
+#. detail 9:  ~400 fps
+#. detail 10: ~300 fps
+#. detail 11: ~100 fps
+#. detail 12:  ~50 fps
+#. detail 13:  ~17 fps
+#. detail 14:   ~8 fps
+#. detail 15:   ~2 fps
+#.
+#. With the default -delay, CPU load only starts causing the frame rate
+#. to drop below 30 fps detail 12 or higher.
+#.
+#: ../hacks/config/hilbert.xml.h:12 ../hacks/config/hypnowheel.xml.h:12
+#: ../hacks/config/ifs.xml.h:23 ../hacks/config/sphereeversion.xml.h:27
+msgid "2"
+msgstr "2"
+
+#: ../hacks/config/hilbert.xml.h:13
+msgid "Recursion levels"
+msgstr "რეკურსიის დონეები"
+
+#: ../hacks/config/hilbert.xml.h:22
+msgid ""
+"The recursive Hilbert space-filling curve, both 2D and 3D variants. The "
+"Hilbert path is a single contiguous line that can fill a volume without "
+"crossing itself. As a data structure, Hilbert paths are useful because "
+"ordering along the curve preserves locality: points that are close together "
+"along the curve are also close together in space. The converse is often, but "
+"not always, true. The coloration reflects this. https://en.wikipedia.org/"
+"wiki/Hilbert_curve Written by Jamie Zawinski; 2011."
+msgstr ""
+
+#: ../hacks/config/hopalong.xml.h:1
+msgid "Hopalong"
+msgstr ""
+
+#: ../hacks/config/hopalong.xml.h:8 ../hacks/config/interference.xml.h:17
+#: ../hacks/config/qix.xml.h:11 ../hacks/config/wander.xml.h:10
+msgid "Color contrast"
+msgstr ""
+
+#: ../hacks/config/hopalong.xml.h:12
+msgid "Sine"
+msgstr "სინუსიოდი"
+
+#: ../hacks/config/hopalong.xml.h:13
+msgid "Martin"
+msgstr "მარტინი"
+
+#: ../hacks/config/hopalong.xml.h:15
+msgid "Jong"
+msgstr "იონგი"
+
+#: ../hacks/config/hopalong.xml.h:16
+msgid "RR"
+msgstr "RR"
+
+#: ../hacks/config/hopalong.xml.h:17
+msgid "EJK1"
+msgstr "EJK1"
+
+#: ../hacks/config/hopalong.xml.h:18
+msgid "EJK2"
+msgstr "EJK2"
+
+#: ../hacks/config/hopalong.xml.h:19
+msgid "EJK3"
+msgstr "EJK3"
+
+#: ../hacks/config/hopalong.xml.h:20
+msgid "EJK4"
+msgstr "EJK4"
+
+#: ../hacks/config/hopalong.xml.h:21
+msgid "EJK5"
+msgstr "EJK5"
+
+#: ../hacks/config/hopalong.xml.h:22
+msgid "EJK6"
+msgstr "EJK6"
+
+#: ../hacks/config/hopalong.xml.h:24
+msgid ""
+"Lacy fractal patterns based on iteration in the imaginary plane, from a 1986 "
+"Scientific American article. See also the \"Discrete\" screen saver. Written "
+"by Patrick Naughton; 1992."
+msgstr ""
+
+#: ../hacks/config/hydrostat.xml.h:1
+msgid "Hydrostat"
+msgstr "ჰიდროსტატი"
+
+#: ../hacks/config/hydrostat.xml.h:9
+msgid "Number of squid"
+msgstr "კალმარის რაოდენობა"
+
+#: ../hacks/config/hydrostat.xml.h:12
+msgid "Head size"
+msgstr "თავის ზომა"
+
+#: ../hacks/config/hydrostat.xml.h:15
+msgid "Number of tentacles"
+msgstr "საცეცების რაოდენობა"
+
+#: ../hacks/config/hydrostat.xml.h:20
+msgid "Length of tentacles"
+msgstr "საცეცების სიგრძე"
+
+#: ../hacks/config/hydrostat.xml.h:22
+msgid "Weak"
+msgstr "სუსტი"
+
+#: ../hacks/config/hydrostat.xml.h:24 ../hacks/config/jigglypuff.xml.h:20
+msgid "Strong"
+msgstr "ძლიერი"
+
+#: ../hacks/config/hydrostat.xml.h:25
+msgid "Current"
+msgstr "მიმდინარე"
+
+#: ../hacks/config/hydrostat.xml.h:26
+msgid "Viscosity"
+msgstr "სიბლანტე"
+
+#: ../hacks/config/hydrostat.xml.h:27
+msgid "Pulse"
+msgstr "პულსი"
+
+#: ../hacks/config/hydrostat.xml.h:30
+msgid ""
+"Wiggly squid or jellyfish with many tentacles. A muscular hydrostat is a "
+"biological structure used to move its host about, consisting of muscles with "
+"no skeletal support. It performs its hydraulic movement without fluid in a "
+"separate compartment, as in a hydrostatic skeleton. https://en.wikipedia.org/"
+"wiki/Muscular_hydrostat Written by Justin Windle and Jamie Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/hyperball.xml.h:1
+msgid "Hyperball"
+msgstr "ჰიპერბურთი"
+
+#: ../hacks/config/hyperball.xml.h:10 ../hacks/config/hypercube.xml.h:10
+msgid "XW rotation"
+msgstr "XW ბრუნვა"
+
+#: ../hacks/config/hyperball.xml.h:12 ../hacks/config/hypercube.xml.h:12
+msgid "XY rotation"
+msgstr "XY ბრუნვა"
+
+#: ../hacks/config/hyperball.xml.h:13 ../hacks/config/hypercube.xml.h:13
+msgid "XZ rotation"
+msgstr "XZ ბრუნვა"
+
+#: ../hacks/config/hyperball.xml.h:14 ../hacks/config/hypercube.xml.h:14
+msgid "YW rotation"
+msgstr "YW ბრუნვა"
+
+#: ../hacks/config/hyperball.xml.h:15 ../hacks/config/hypercube.xml.h:15
+msgid "YZ rotation"
+msgstr "YZ ბრუნვა"
+
+#: ../hacks/config/hyperball.xml.h:16 ../hacks/config/hypercube.xml.h:16
+msgid "ZW rotation"
+msgstr "ZW ბრუნვა"
+
+#: ../hacks/config/hyperball.xml.h:17
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.10. It has been replaced by the more general \"Polytopes\" screen "
+"saver, which can display this object as well as others. The Polytopes \"120-"
+"cell\" object corresponds to this one. Hyperball is to hypercube as "
+"dodecahedron is to cube: this displays a 2D projection of the sequence of 3D "
+"objects which are the projections of the 4D analog to the dodecahedron. "
+"Technically, it is a \"120 cell polytope\". https://en.wikipedia.org/wiki/"
+"Hypercube https://en.wikipedia.org/wiki/Regular_polytope Written by Joe "
+"Keane; 2000."
+msgstr ""
+
+#: ../hacks/config/hypercube.xml.h:1
+msgid "Hypercube"
+msgstr "ჰიპერკუბი"
+
+#: ../hacks/config/hypercube.xml.h:17
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.10. It has been replaced by the more general \"Polytopes\" screen "
+"saver, which can display this object as well as others. This displays 2D "
+"projections of the sequence of 3D objects which are the projections of the "
+"4D analog to the cube: as a square is composed of four lines, each touching "
+"two others; and a cube is composed of six squares, each touching four "
+"others; a hypercube is composed of eight cubes, each touching six others. To "
+"make it easier to visualize the rotation, it uses a different color for the "
+"edges of each face. Don't think about it too long, or your brain will melt. "
+"https://en.wikipedia.org/wiki/Hypercube https://en.wikipedia.org/wiki/"
+"Tesseract https://en.wikipedia.org/wiki/Regular_polytope Written by Joe "
+"Keane, Fritz Mueller, and Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:1
+msgid "Hypertorus"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:7 ../hacks/config/mismunch.xml.h:12
+#: ../hacks/config/munch.xml.h:15 ../hacks/config/winduprobot.xml.h:16
+msgid "Solid"
+msgstr "მყარი"
+
+#: ../hacks/config/hypertorus.xml.h:10
+msgid "Transparent bands"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:11
+msgid "1 transparent spiral"
+msgstr "1 გამჭვირვალე სპირალი"
+
+#: ../hacks/config/hypertorus.xml.h:12
+msgid "2 transparent spirals"
+msgstr "2 გამჭვირვალე სპირალი"
+
+#: ../hacks/config/hypertorus.xml.h:13
+msgid "4 transparent spirals"
+msgstr "4 გამჭვირვალე სპირალი"
+
+#: ../hacks/config/hypertorus.xml.h:14
+msgid "8 transparent spirals"
+msgstr "8 გამჭვირვალე სპირალი"
+
+#: ../hacks/config/hypertorus.xml.h:15
+msgid "16 Transparent spirals"
+msgstr "16 გამჭვირვალე სპირალი"
+
+#: ../hacks/config/hypertorus.xml.h:18
+msgid "Color wheel"
+msgstr "ფერის ბორბალი"
+
+#: ../hacks/config/hypertorus.xml.h:20 ../hacks/config/klein.xml.h:25
+#: ../hacks/config/polytopes.xml.h:14 ../hacks/config/projectiveplane.xml.h:18
+msgid "Perspective 3D"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:21 ../hacks/config/klein.xml.h:26
+#: ../hacks/config/polytopes.xml.h:15 ../hacks/config/projectiveplane.xml.h:19
+msgid "Orthographic 3D"
+msgstr "ორთოგრაფიული 3D"
+
+#: ../hacks/config/hypertorus.xml.h:22 ../hacks/config/klein.xml.h:28
+#: ../hacks/config/polytopes.xml.h:16 ../hacks/config/projectiveplane.xml.h:21
+msgid "Perspective 4D"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:23 ../hacks/config/klein.xml.h:29
+#: ../hacks/config/polytopes.xml.h:17 ../hacks/config/projectiveplane.xml.h:22
+msgid "Orthographic 4D"
+msgstr "ორთოგრაფიული 4D"
+
+#: ../hacks/config/hypertorus.xml.h:25 ../hacks/config/klein.xml.h:31
+#: ../hacks/config/polytopes.xml.h:20
+msgid "WX rotation speed"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:27 ../hacks/config/klein.xml.h:33
+#: ../hacks/config/polytopes.xml.h:22
+msgid "WY rotation speed"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:28 ../hacks/config/klein.xml.h:34
+#: ../hacks/config/polytopes.xml.h:23
+msgid "WZ rotation speed"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:29 ../hacks/config/klein.xml.h:35
+#: ../hacks/config/polytopes.xml.h:27
+msgid "XY rotation speed"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:30 ../hacks/config/klein.xml.h:36
+#: ../hacks/config/polytopes.xml.h:28
+msgid "XZ rotation speed"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:31 ../hacks/config/klein.xml.h:37
+#: ../hacks/config/polytopes.xml.h:29
+msgid "YZ rotation speed"
+msgstr ""
+
+#: ../hacks/config/hypertorus.xml.h:32
+msgid ""
+"A Clifford Torus is a torus lying on the surface of a 4D hypersphere. "
+"Inspired by Thomas Banchoff's book \"Beyond the Third Dimension: Geometry, "
+"Computer Graphics, and Higher Dimensions\", Scientific American Library, "
+"1990. https://en.wikipedia.org/wiki/N-sphere https://en.wikipedia.org/wiki/"
+"Clifford_torus https://en.wikipedia.org/wiki/Regular_polytope Written by "
+"Carsten Steger; 2003."
+msgstr ""
+
+#: ../hacks/config/hypnowheel.xml.h:1
+msgid "Hypnowheel"
+msgstr "ჰიპნობორბალი"
+
+#: ../hacks/config/hypnowheel.xml.h:7
+msgid "Symmetric twisting"
+msgstr ""
+
+#: ../hacks/config/hypnowheel.xml.h:11 ../hacks/config/intermomentary.xml.h:5
+msgid "50"
+msgstr "50"
+
+#: ../hacks/config/hypnowheel.xml.h:15
+msgid "Twistiness"
+msgstr ""
+
+#: ../hacks/config/hypnowheel.xml.h:17
+msgid ""
+"Overlapping, translucent spiral patterns. The tightness of their spirals "
+"fluctuates in and out. https://en.wikipedia.org/wiki/Moire_pattern Written "
+"by Jamie Zawinski; 2008."
+msgstr ""
+
+#: ../hacks/config/ifs.xml.h:1
+msgid "IFS"
+msgstr "IFS"
+
+#: ../hacks/config/ifs.xml.h:24
+msgid "Number of functions"
+msgstr "ფუნქციების რაოდენობა"
+
+#: ../hacks/config/ifs.xml.h:25
+msgid "6"
+msgstr "6"
+
+#: ../hacks/config/ifs.xml.h:26
+msgid "Detail"
+msgstr "დეტალები"
+
+#: ../hacks/config/ifs.xml.h:65
+msgid "Translate"
+msgstr "თარგმნა"
+
+#: ../hacks/config/ifs.xml.h:66 ../hacks/config/marbling.xml.h:7
+#: ../hacks/config/squiral.xml.h:8
+msgid "Scale"
+msgstr "მასშტაბი"
+
+#: ../hacks/config/ifs.xml.h:69
+msgid ""
+"Clouds of iterated function systems spin and collide. Note that the "
+"\"Detail\" parameter is exponential. Number of points drawn is "
+"functions^detail. https://en.wikipedia.org/wiki/Iterated_function_system "
+"Written by Chris Le Sueur and Robby Griffin; 1997."
+msgstr ""
+
+#: ../hacks/config/imsmap.xml.h:1
+msgid "IMS Map"
+msgstr ""
+
+#: ../hacks/config/imsmap.xml.h:5
+msgid "1 Second"
+msgstr "1 წამი"
+
+#: ../hacks/config/imsmap.xml.h:7
+msgid "1 Minute"
+msgstr "1 წთ"
+
+#: ../hacks/config/imsmap.xml.h:15
+msgid "Hue gradients"
+msgstr ""
+
+#: ../hacks/config/imsmap.xml.h:16
+msgid "Saturation gradients"
+msgstr ""
+
+#: ../hacks/config/imsmap.xml.h:17
+msgid "Brightness gradients"
+msgstr ""
+
+#: ../hacks/config/imsmap.xml.h:19
+msgid ""
+"Recursive cloud-like fractal patterns. Written by Juergen Nickelsen and "
+"Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/interaggregate.xml.h:1
+msgid "Interaggregate"
+msgstr ""
+
+#: ../hacks/config/interaggregate.xml.h:6
+#: ../hacks/config/intermomentary.xml.h:6
+msgid "Number of discs"
+msgstr ""
+
+#: ../hacks/config/interaggregate.xml.h:9
+msgid ""
+"Pale pencil-like scribbles slowly fill the screen. A surface is filled with "
+"a hundred medium to small sized circles. Each circle has a different size "
+"and direction, but moves at the same slow rate. Displays the instantaneous "
+"intersections of the circles as well as the aggregate intersections of the "
+"circles. Though actually it doesn't look like circles at all! Written by "
+"Casey Reas, William Ngan, Robert Hodgin, and Jamie Zawinski; 2004."
+msgstr ""
+
+#: ../hacks/config/interference.xml.h:1
+msgid "Interference"
+msgstr "ინტერფერენცია"
+
+#: ../hacks/config/interference.xml.h:9
+msgid "Wave size"
+msgstr "ტალღის ზომა"
+
+#: ../hacks/config/interference.xml.h:12
+msgid "Number of waves"
+msgstr "ტალღების რაოდენობა"
+
+#: ../hacks/config/interference.xml.h:14 ../hacks/config/marbling.xml.h:5
+#: ../hacks/config/t3d.xml.h:11
+msgid "Magnification"
+msgstr "გადიდება"
+
+#: ../hacks/config/interference.xml.h:19
+msgid "Hue"
+msgstr "ჰუე"
+
+#: ../hacks/config/interference.xml.h:20
+msgid "360"
+msgstr "360"
+
+#: ../hacks/config/interference.xml.h:22
+msgid "Decaying sinusoidal waves make colors. Written by Hannu Mallat; 1998."
+msgstr ""
+
+#: ../hacks/config/intermomentary.xml.h:1
+msgid "Intermomentary"
+msgstr ""
+
+#: ../hacks/config/intermomentary.xml.h:7
+msgid "400"
+msgstr "400"
+
+#: ../hacks/config/intermomentary.xml.h:9
+msgid ""
+"Blinking dots interact with each other circularly. A surface is filled with "
+"a hundred medium to small sized circles. Each circle has a different size "
+"and direction, but moves at the same slow rate. Displays the instantaneous "
+"intersections of the circles as well as the aggregate intersections of the "
+"circles. The circles begin with a radius of 1 pixel and slowly increase to "
+"some arbitrary size. Circles are drawn with small moving points along the "
+"perimeter. The intersections are rendered as glowing orbs. Glowing orbs are "
+"rendered only when a perimeter point moves past the intersection point. "
+"Written by Casey Reas, William Ngan, Robert Hodgin, and Jamie Zawinski; 2004."
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:1
+msgid "Jiggly Puff"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:2
+msgid "Randomize almost everything"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:3
+msgid "Cycle"
+msgstr "ციკლი"
+
+#: ../hacks/config/jigglypuff.xml.h:4
+msgid "Flower box"
+msgstr "ყვავილის ყუთი"
+
+#: ../hacks/config/jigglypuff.xml.h:5
+msgid "Clown barf"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:7 ../hacks/config/sphere.xml.h:1
+msgid "Sphere"
+msgstr "სფერო"
+
+#: ../hacks/config/jigglypuff.xml.h:8 ../hacks/config/morph3d.xml.h:6
+#: ../hacks/config/polyhedra.xml.h:22 ../hacks/config/sballs.xml.h:6
+msgid "Tetrahedron"
+msgstr "ტეტრაჰედრონი"
+
+#: ../hacks/config/jigglypuff.xml.h:17
+msgid "Inertial damping"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:19
+msgid "Vertex-vertex force"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:22
+msgid "Sphere strength"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:23
+msgid "Expand"
+msgstr "ამოკეცვა"
+
+#: ../hacks/config/jigglypuff.xml.h:24
+msgid "Vertex-vertex behavior"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:25
+msgid "Collapse"
+msgstr "ჩაკეცვა"
+
+#: ../hacks/config/jigglypuff.xml.h:26
+msgid "Spookiness"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:27
+msgid "Spoooooky"
+msgstr ""
+
+#: ../hacks/config/jigglypuff.xml.h:28
+msgid ""
+"Quasi-spherical objects are distorted. You have a tetrahedron with "
+"tesselated faces. The vertices on these faces have forces on them: one "
+"proportional to the distance from the surface of a sphere; and one "
+"proportional to the distance from the neighbors. They also have inertia. The "
+"resulting effect can range from a shape that does nothing, to a frenetic "
+"polygon storm. Somewhere in between there it usually manifests as a blob "
+"that jiggles in a kind of disturbing manner. Written by Keith Macleod; 2003."
+msgstr ""
+
+#: ../hacks/config/jigsaw.xml.h:1
+msgid "Jigsaw"
+msgstr "მოზაიკა"
+
+#: ../hacks/config/jigsaw.xml.h:9
+msgid "Puzzle pieces"
+msgstr ""
+
+#: ../hacks/config/jigsaw.xml.h:11
+msgid "Chunky"
+msgstr ""
+
+#: ../hacks/config/jigsaw.xml.h:16
+msgid ""
+"Carves an image up into a jigsaw puzzle, shuffles it, and solves it. https://"
+"en.wikipedia.org/wiki/Jigsaw_puzzle https://en.wikipedia.org/wiki/"
+"Tessellation Written by Jamie Zawinski; 1997."
+msgstr ""
+
+#: ../hacks/config/juggle.xml.h:1
+msgid "Juggle"
+msgstr ""
+
+#: ../hacks/config/juggle.xml.h:9 ../hacks/config/juggler3d.xml.h:9
+msgid "Performance length"
+msgstr "შესრულების სიგრძე"
+
+#: ../hacks/config/juggle.xml.h:14 ../hacks/config/juggler3d.xml.h:14
+msgid "Clubs"
+msgstr "ჯვარი"
+
+#: ../hacks/config/juggle.xml.h:15 ../hacks/config/juggler3d.xml.h:15
+msgid "Rings"
+msgstr "ბეჭდები"
+
+#: ../hacks/config/juggle.xml.h:16 ../hacks/config/juggler3d.xml.h:16
+msgid "Knives"
+msgstr "დანები"
+
+#: ../hacks/config/juggle.xml.h:17
+msgid "Flaming torches"
+msgstr ""
+
+#: ../hacks/config/juggle.xml.h:18 ../hacks/config/juggler3d.xml.h:17
+msgid "Bowling balls"
+msgstr ""
+
+#: ../hacks/config/juggle.xml.h:19 ../hacks/config/juggler3d.xml.h:18
+msgid "Print Cambridge juggling pattern descriptions"
+msgstr ""
+
+#: ../hacks/config/juggle.xml.h:20 ../hacks/config/juggler3d.xml.h:19
+msgid "Juggle this pattern"
+msgstr ""
+
+#: ../hacks/config/juggle.xml.h:22
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.09. It has been replaced by the \"Juggler3D\" screen saver. "
+"Written by Tim Auckland; 2002."
+msgstr ""
+
+#: ../hacks/config/juggler3d.xml.h:1
+msgid "Juggler 3D"
+msgstr ""
+
+#: ../hacks/config/juggler3d.xml.h:21
+msgid ""
+"A 3D juggling stick-person, with Cambridge juggling pattern notation used to "
+"describe the patterns juggled. https://en.wikipedia.org/wiki/Siteswap "
+"Written by Tim Auckland and Jamie Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/julia.xml.h:1
+msgid "Julia"
+msgstr "Julia"
+
+#: ../hacks/config/julia.xml.h:9 ../hacks/config/rorschach.xml.h:3
+msgid "Iterations"
+msgstr "იტერაციები"
+
+#: ../hacks/config/julia.xml.h:15
+msgid ""
+"The Julia set is a close relative of the Mandelbrot set. The small moving "
+"dot indicates the control point from which the rest of the image was "
+"generated. See also the \"Discrete\" screen saver. https://en.wikipedia.org/"
+"wiki/Julia_set Written by Sean McCullough; 1997."
+msgstr ""
+
+#: ../hacks/config/kaleidescope.xml.h:1
+msgid "Kaleidescope"
+msgstr "კალეიდოსკოპი"
+
+#: ../hacks/config/kaleidescope.xml.h:6 ../hacks/config/qix.xml.h:6
+msgid "Segments"
+msgstr "სეგმენტი"
+
+#: ../hacks/config/kaleidescope.xml.h:8 ../hacks/config/sphereeversion.xml.h:28
+msgid "3"
+msgstr "3"
+
+#: ../hacks/config/kaleidescope.xml.h:9 ../hacks/config/quasicrystal.xml.h:12
+msgid "Symmetry"
+msgstr "სიმეტრია"
+
+#: ../hacks/config/kaleidescope.xml.h:10
+msgid "32"
+msgstr "32"
+
+#: ../hacks/config/kaleidescope.xml.h:11
+msgid "Trails"
+msgstr "კვალები"
+
+#: ../hacks/config/kaleidescope.xml.h:13
+msgid ""
+"A simple kaleidoscope made of line segments. See \"GLeidescope\" for a more "
+"sophisticated take. https://en.wikipedia.org/wiki/Kaleidoscope Written by "
+"Ron Tapia; 1997."
+msgstr ""
+
+#: ../hacks/config/kaleidocycle.xml.h:1
+msgid "Kaleidocycle"
+msgstr ""
+
+#: ../hacks/config/kaleidocycle.xml.h:7 ../hacks/config/raverhoop.xml.h:7
+msgid "64"
+msgstr "64"
+
+#: ../hacks/config/kaleidocycle.xml.h:22
+msgid ""
+"Draw a ring composed of tetrahedra connected at the edges that twists and "
+"rotates toroidally. When a series of tetrahedra are joined at the edges in a "
+"loop, it is possible for them to rotate continously through the center "
+"without deforming. This only works with an even number of tetrahedra, and "
+"there must be eight or more, or they don't fit. Written by Jamie Zawinski; "
+"2013."
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:1
+msgid "Klein"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:3
+msgid "Figure 8"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:4
+msgid "Pinched torus"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:5
+msgid "Lawson"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:9 ../hacks/config/projectiveplane.xml.h:43
+msgid "Walk and turn"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:17
+msgid "See-through bands"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:21
+msgid "Rainbow colors"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:22 ../hacks/config/projectiveplane.xml.h:15
+msgid "4d depth colors"
+msgstr ""
+
+#: ../hacks/config/klein.xml.h:24 ../hacks/config/projectiveplane.xml.h:17
+msgid "Random 3D"
+msgstr "შემთხვევითი 3D"
+
+#: ../hacks/config/klein.xml.h:27 ../hacks/config/projectiveplane.xml.h:20
+msgid "Random 4D"
+msgstr "შემთხვევითი 4D"
+
+#: ../hacks/config/klein.xml.h:48
+msgid ""
+"A Klein bottle is the 4D analog of a möbius strip. You can walk on the "
+"surface of the bottle or rotate it in 4D or walk on it while it rotates in "
+"4D. Inspired by Thomas Banchoff's book \"Beyond the Third Dimension: "
+"Geometry, Computer Graphics, and Higher Dimensions\", Scientific American "
+"Library, 1990. https://en.wikipedia.org/wiki/Klein_bottle Written by Carsten "
+"Steger; 2008."
+msgstr ""
+
+#: ../hacks/config/kumppa.xml.h:1
+msgid "Kumppa"
+msgstr ""
+
+#: ../hacks/config/kumppa.xml.h:6
+msgid "Randomize"
+msgstr "შემთხვევით"
+
+#: ../hacks/config/kumppa.xml.h:8
+msgid ""
+"Spiraling, spinning, and very, very fast splashes of color rush toward the "
+"screen. Written by Teemu Suutari; 1998."
+msgstr ""
+
+#: ../hacks/config/lament.xml.h:1
+msgid "Lament"
+msgstr ""
+
+#: ../hacks/config/lament.xml.h:9
+#, no-c-format
+msgid ""
+"Lemarchand's Box, the Lament Configuration. Warning: occasionally opens "
+"doors. https://en.wikipedia.org/wiki/Lemarchand%27s_box Written by Jamie "
+"Zawinski; 1998."
+msgstr ""
+
+#: ../hacks/config/laser.xml.h:1
+msgid "Laser"
+msgstr "ლაზერი"
+
+#: ../hacks/config/laser.xml.h:13
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Moving radiating lines, that look vaguely like scanning laser "
+"beams. (Frankie say relax.) Written by Pascal Pensa; 1997."
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:1
+msgid "Lavalite"
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:9
+msgid "Max blobs"
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:12
+msgid "Impatient"
+msgstr "მოუთმენელი"
+
+#: ../hacks/config/lavalite.xml.h:17
+msgid "Classic Lavalite"
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:18
+msgid "Giant Lavalite"
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:19
+msgid "Cone Lavalite"
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:20
+msgid "Rocket Lavalite"
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:21
+msgid "Random Lamp Style"
+msgstr ""
+
+#: ../hacks/config/lavalite.xml.h:22
+msgid "Don't Rotate"
+msgstr "არ შეაბრუნო"
+
+#: ../hacks/config/lavalite.xml.h:30
+msgid ""
+"Blobs of a mysterious substance are heated, slowly rise to the top of the "
+"bottle, and then drop back down as they cool. \"LAVA LITE(r) and the "
+"configuration of the LAVA(r) brand motion lamp are registered trademarks of "
+"Haggerty Enterprises, Inc. The configuration of the globe and base of the "
+"motion lamp are registered trademarks of Haggerty Enterprises, Inc. in the "
+"U.S.A. and in other countries around the world.\" https://en.wikipedia.org/"
+"wiki/Lava_lamp https://en.wikipedia.org/wiki/Metaballs https://"
+"en.wikipedia.org/wiki/Lavarand Written by Jamie Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/lcdscrub.xml.h:1
+msgid "LCD Scrub"
+msgstr ""
+
+#: ../hacks/config/lcdscrub.xml.h:5
+msgid "Line spread"
+msgstr ""
+
+#: ../hacks/config/lcdscrub.xml.h:8
+msgid "Horizontal white"
+msgstr "ჰორიზონტალური თეთრი"
+
+#: ../hacks/config/lcdscrub.xml.h:9
+msgid "Vertical white"
+msgstr "ვერტიკალური თეთრი"
+
+#: ../hacks/config/lcdscrub.xml.h:10
+msgid "Diagonal white"
+msgstr "დიაგონალური თეთრი"
+
+#: ../hacks/config/lcdscrub.xml.h:11
+msgid "Solid white"
+msgstr "სულ თეთრი"
+
+#: ../hacks/config/lcdscrub.xml.h:12
+msgid "Primary colors"
+msgstr "ძირითადი ფერები"
+
+#: ../hacks/config/lcdscrub.xml.h:13
+msgid "Horizontal black"
+msgstr "ჰორიზონტალური შავი"
+
+#: ../hacks/config/lcdscrub.xml.h:14
+msgid "Vertical black"
+msgstr "ვერტიკალური შავი"
+
+#: ../hacks/config/lcdscrub.xml.h:15
+msgid "Diagonal black"
+msgstr "დიაგონალური შავი"
+
+#: ../hacks/config/lcdscrub.xml.h:16
+msgid "Solid black"
+msgstr "სულ შავი"
+
+#: ../hacks/config/lcdscrub.xml.h:18
+#, no-c-format
+msgid ""
+"Repairs burn-in on LCD monitors. This saver is functional, rather than "
+"pretty. Believe it or not, screen burn is not a thing of the past. It can "
+"happen to LCD screens pretty easily, even in this modern age. However, "
+"leaving the screen on and displaying high contrast images can often repair "
+"the damage. That's what this screen saver does. See also: https://"
+"web.archive.org/web/20020817075924/http%3A//docs.info.apple.com/article.html?"
+"artnum=88343 Inspired by a like-named and long-defunct program by Daniel "
+"Sandler. Written by Jamie Zawinski; 2008."
+msgstr ""
+
+#: ../hacks/config/lightning.xml.h:1
+msgid "Lightning"
+msgstr "ელვა"
+
+#: ../hacks/config/lightning.xml.h:9
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Crackling fractal lightning bolts. Written by Keith Romberg; "
+"1997."
+msgstr ""
+
+#: ../hacks/config/lisa.xml.h:1
+msgid "Lisa"
+msgstr "ლისა"
+
+#: ../hacks/config/lisa.xml.h:6
+msgid "Steps"
+msgstr "ნაბიჯები"
+
+#: ../hacks/config/lisa.xml.h:17
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Lissajous loops. https://en.wikipedia.org/wiki/Lissajous_curve "
+"Written by Caleb Cullen; 1997."
+msgstr ""
+
+#: ../hacks/config/lissie.xml.h:1
+msgid "Lissie"
+msgstr "ლისი"
+
+#: ../hacks/config/lissie.xml.h:16
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Lissajous loops. This one draws the progress of circular "
+"shapes along a path. https://en.wikipedia.org/wiki/Lissajous_curve Written "
+"by Alexander Jolk; 1997."
+msgstr ""
+
+#: ../hacks/config/lmorph.xml.h:1
+msgid "LMorph"
+msgstr "LMorph"
+
+#: ../hacks/config/lmorph.xml.h:6
+msgid "Control points"
+msgstr "საკონტროლო წერტილები"
+
+#: ../hacks/config/lmorph.xml.h:8
+msgid "Less"
+msgstr "ნაკლები"
+
+#: ../hacks/config/lmorph.xml.h:9
+msgid "Interpolation steps"
+msgstr "ინტერპოლაციის ნაბიჯები"
+
+#: ../hacks/config/lmorph.xml.h:10
+msgid "More"
+msgstr "მეტი"
+
+#: ../hacks/config/lmorph.xml.h:14
+msgid "Open and closed figures"
+msgstr "ღია და დახურული ფიგურები"
+
+#: ../hacks/config/lmorph.xml.h:15
+msgid "Open figures"
+msgstr "ღია ფიგურები"
+
+#: ../hacks/config/lmorph.xml.h:16
+msgid "Closed figures"
+msgstr "დახურული ფიგურები"
+
+#: ../hacks/config/lmorph.xml.h:18
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. This generates random spline-ish line drawings and morphs "
+"between them. Written by Sverre H. Huseby and Glenn T. Lines; 1995."
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:1
+msgid "Lockward"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:5
+msgid "Miniumum rotator idle time"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:6
+msgid "Minimum blink idle time"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:7
+msgid "Minimum blink dwell time"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:8
+msgid "Blinking effects"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:10
+msgid "Maximum rotator idle time"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:11
+msgid "Maximum blink idle time"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:12
+msgid "Maximum blink dwell time"
+msgstr ""
+
+#: ../hacks/config/lockward.xml.h:13
+msgid ""
+"A translucent spinning, blinking thing. Sort of a cross between the wards in "
+"an old combination lock and those old backlit information displays that "
+"animated and changed color via polarized light. Written by Leo L. Schwab; "
+"2007."
+msgstr ""
+
+#: ../hacks/config/loop.xml.h:1
+msgid "Loop"
+msgstr "მარყუჟი"
+
+#: ../hacks/config/loop.xml.h:14
+#, no-c-format
+msgid ""
+"A cellular automaton that generates loop-shaped colonies that spawn, age, "
+"and eventually die. https://en.wikipedia.org/wiki/Langton%27s_loops Written "
+"by David Bagley; 1999."
+msgstr ""
+
+#: ../hacks/config/m6502.xml.h:1
+msgid "m6502"
+msgstr "m6502"
+
+#: ../hacks/config/m6502.xml.h:2
+msgid "Assembly file"
+msgstr ""
+
+#: ../hacks/config/m6502.xml.h:5
+msgid "Display time for each program"
+msgstr ""
+
+#: ../hacks/config/m6502.xml.h:11
+msgid "500"
+msgstr "500"
+
+#: ../hacks/config/m6502.xml.h:12
+msgid "Instructions per second"
+msgstr "ინსტრუქცია/წმ"
+
+#: ../hacks/config/m6502.xml.h:13
+msgid "120000"
+msgstr "120000"
+
+#: ../hacks/config/m6502.xml.h:16
+msgid ""
+"Emulates a 6502 microprocessor, and runs some example programs on it. The "
+"family of 6502 chips were used throughout the 70's and 80's in machines such "
+"as the Atari 2600, Commodore PET, VIC20 and C64, Apple ][, and the NES. Some "
+"example programs are included, and it can also read in an assembly file as "
+"input. Original JavaScript Version by Stian Soreng: http://www.6502asm.com/. "
+"Ported to XScreenSaver by Jeremy English. Written by Stian Soreng and Jeremy "
+"English; 2007."
+msgstr ""
+
+#: ../hacks/config/mapscroller.xml.h:1
+msgid "Map Scroller"
+msgstr ""
+
+#: ../hacks/config/mapscroller.xml.h:6
+msgid "Scroll speed"
+msgstr "ჩოჩიის სიჩქარე"
+
+#: ../hacks/config/mapscroller.xml.h:8
+msgid "Countries"
+msgstr "ქვეყნები"
+
+#: ../hacks/config/mapscroller.xml.h:9
+msgid "Zoom level"
+msgstr "გადიდების დონე"
+
+#: ../hacks/config/mapscroller.xml.h:10
+msgid "Streets"
+msgstr "ქუჩები"
+
+#: ../hacks/config/mapscroller.xml.h:12
+msgid "Re-randomize every"
+msgstr ""
+
+#: ../hacks/config/mapscroller.xml.h:13
+msgid "2 hours"
+msgstr "2 საათი"
+
+#: ../hacks/config/mapscroller.xml.h:14
+msgid "Open Street Map"
+msgstr "Open Street Map"
+
+#: ../hacks/config/mapscroller.xml.h:15
+msgid "OSM Humanitarian Map"
+msgstr ""
+
+#: ../hacks/config/mapscroller.xml.h:16
+msgid "Stamen Toner B&W Map"
+msgstr ""
+
+#: ../hacks/config/mapscroller.xml.h:17
+msgid "Stamen Terrain Map"
+msgstr ""
+
+#: ../hacks/config/mapscroller.xml.h:18
+msgid "Stamen Watercolor Map"
+msgstr ""
+
+#: ../hacks/config/mapscroller.xml.h:19
+msgid "Fully random location"
+msgstr "სრულად შემთხვევითი მდებარეობა"
+
+#: ../hacks/config/mapscroller.xml.h:20
+msgid "Random city"
+msgstr "შემთხვევითი ქალაქი"
+
+#. New York, London, Paris, Munich, everybody talk about pop muzik
+#: ../hacks/config/mapscroller.xml.h:22
+msgid "Amsterdam"
+msgstr "ამსტერდამი"
+
+#: ../hacks/config/mapscroller.xml.h:23
+msgid "Athens"
+msgstr "ათენი"
+
+#: ../hacks/config/mapscroller.xml.h:24
+msgid "Austin"
+msgstr "ოსტინი"
+
+#: ../hacks/config/mapscroller.xml.h:25
+msgid "Barcelona"
+msgstr "ბარსელონა"
+
+#: ../hacks/config/mapscroller.xml.h:26
+msgid "Berlin"
+msgstr "ბერლინი"
+
+#: ../hacks/config/mapscroller.xml.h:27
+msgid "Boston"
+msgstr "ბოსტონი"
+
+#: ../hacks/config/mapscroller.xml.h:28
+msgid "Budapest"
+msgstr "ბუდაპეშტი"
+
+#: ../hacks/config/mapscroller.xml.h:29
+msgid "Buenos Aires"
+msgstr "ბუენოს აირესი"
+
+#: ../hacks/config/mapscroller.xml.h:30
+msgid "Cairo"
+msgstr "ქაირო"
+
+#: ../hacks/config/mapscroller.xml.h:31
+msgid "Casablanca"
+msgstr "კასაბლანკა"
+
+#: ../hacks/config/mapscroller.xml.h:32
+msgid "Chicago"
+msgstr "ჩიკაგო"
+
+#: ../hacks/config/mapscroller.xml.h:33
+msgid "Havana"
+msgstr "ჰავანა"
+
+#: ../hacks/config/mapscroller.xml.h:34
+msgid "Hong Kong"
+msgstr "ჰონგკონგი"
+
+#: ../hacks/config/mapscroller.xml.h:35
+msgid "Honolulu"
+msgstr "ჰონოლულუ"
+
+#: ../hacks/config/mapscroller.xml.h:36
+msgid "Las Vegas"
+msgstr "ლას ვეგასი"
+
+#: ../hacks/config/mapscroller.xml.h:37
+msgid "London"
+msgstr "ლონდონი"
+
+#: ../hacks/config/mapscroller.xml.h:38
+msgid "Los Angeles"
+msgstr "ლოს ანჯელესი"
+
+#: ../hacks/config/mapscroller.xml.h:39
+msgid "Luxembourg"
+msgstr "ლუქსემბურგი"
+
+#: ../hacks/config/mapscroller.xml.h:40
+msgid "Madrid"
+msgstr "მადრიდი"
+
+#: ../hacks/config/mapscroller.xml.h:41
+msgid "Melbourne"
+msgstr "მელბურნი"
+
+#: ../hacks/config/mapscroller.xml.h:42
+msgid "Mexico City"
+msgstr "მეხიკო სითი"
+
+#: ../hacks/config/mapscroller.xml.h:43
+msgid "Moscow"
+msgstr "მოსკოვი"
+
+#: ../hacks/config/mapscroller.xml.h:44
+msgid "Mumbai"
+msgstr "მუმბაი"
+
+#: ../hacks/config/mapscroller.xml.h:45
+msgid "Munich"
+msgstr "მიუნხენი"
+
+#: ../hacks/config/mapscroller.xml.h:46
+msgid "New Orleans"
+msgstr "ნიუ ორლეანსი"
+
+#: ../hacks/config/mapscroller.xml.h:47
+msgid "New York"
+msgstr "ნიუ იორკი"
+
+#: ../hacks/config/mapscroller.xml.h:48
+msgid "Paris"
+msgstr "პარიზი"
+
+#: ../hacks/config/mapscroller.xml.h:49
+msgid "Portland"
+msgstr "პორტლანდი"
+
+#: ../hacks/config/mapscroller.xml.h:50
+msgid "Prague"
+msgstr "პრაღა"
+
+#: ../hacks/config/mapscroller.xml.h:51
+msgid "Rome"
+msgstr "რომი"
+
+#: ../hacks/config/mapscroller.xml.h:52
+msgid "San Francisco"
+msgstr "სან-ფრანცისკო"
+
+#: ../hacks/config/mapscroller.xml.h:53
+msgid "Seattle"
+msgstr "სიეტლი"
+
+#: ../hacks/config/mapscroller.xml.h:54
+msgid "Seoul"
+msgstr "სეული"
+
+#: ../hacks/config/mapscroller.xml.h:55
+msgid "Shanghai"
+msgstr "შანხაი"
+
+#: ../hacks/config/mapscroller.xml.h:56
+msgid "Stockholm"
+msgstr "სტოქჰოლმი"
+
+#: ../hacks/config/mapscroller.xml.h:57
+msgid "Sydney"
+msgstr "სიდნეი"
+
+#: ../hacks/config/mapscroller.xml.h:58
+msgid "São Paulo"
+msgstr "საო პაულო"
+
+#: ../hacks/config/mapscroller.xml.h:59
+msgid "Tokyo"
+msgstr "ტოკიო"
+
+#: ../hacks/config/mapscroller.xml.h:60
+msgid "Toronto"
+msgstr "ტორონტო"
+
+#: ../hacks/config/mapscroller.xml.h:61
+msgid "Washington"
+msgstr "ვაშინგტონი"
+
+#: ../hacks/config/mapscroller.xml.h:62
+msgid "Show coordinates"
+msgstr "კოორდინატების ჩვენება"
+
+#: ../hacks/config/mapscroller.xml.h:63
+msgid "Show arrow"
+msgstr "ისრის ჩვენება"
+
+#: ../hacks/config/mapscroller.xml.h:65
+msgid ""
+"A slowly-scrolling map of a random place on Earth. The map images are loaded "
+"from openstreetmap.org, or any compatible service. The Earth is very big, "
+"and full of Things. As you ponder these maps, remember that traffic always "
+"expands to fill all available lanes, every car is a policy failure, and the "
+"concept of \"jaywalking\" was invented for profit by auto industry lobbyists "
+"in the 1920s. OpenStreetMap data is © OpenStreetMap contributors. Written by "
+"Jamie Zawinski; 2022."
+msgstr ""
+
+#: ../hacks/config/marbling.xml.h:1
+msgid "Marbling"
+msgstr ""
+
+#: ../hacks/config/marbling.xml.h:11
+msgid ""
+"Marble-like or cloud-like patterns generated using Perlin Noise and Fractal "
+"Brownian Motion. https://en.wikipedia.org/wiki/Perlin_noise https://"
+"en.wikipedia.org/wiki/Fractional_Brownian_motion Written by Jamie Zawinski "
+"and Dave Odell; 2021."
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:1
+msgid "Maze"
+msgstr "ლაბირინთი"
+
+#: ../hacks/config/maze.xml.h:5
+msgid "Random maze generator"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:6
+msgid "Depth-first backtracking maze generator"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:7
+msgid "Wall-building maze generator (Prim)"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:8
+msgid "Set-joining maze generator (Kruskal)"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:9
+msgid "Head toward exit"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:10
+msgid "Ignorant of exit direction"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:11
+msgid "Grid size"
+msgstr "ბადის ზომა"
+
+#: ../hacks/config/maze.xml.h:14
+msgid "Linger before solving"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:16
+msgid "Linger after solving"
+msgstr ""
+
+#: ../hacks/config/maze.xml.h:17
+msgid ""
+"Generates random mazes, with three different algorithms: Kruskal, Prim, and "
+"a depth-first recursive backtracker. Backtracking and look-ahead paths are "
+"displayed in different colors. https://en.wikipedia.org/wiki/"
+"Maze_generation_algorithm https://en.wikipedia.org/wiki/"
+"Maze_solving_algorithm Written by Martin Weiss, Dave Lemke, Jim Randell, "
+"Jamie Zawinski, Johannes Keukelaar, and Zack Weinberg; 1985."
+msgstr ""
+
+#: ../hacks/config/maze3d.xml.h:1
+msgid "Maze 3D"
+msgstr "3D ლაბირინთი"
+
+#: ../hacks/config/maze3d.xml.h:8
+msgid "Show Overlay"
+msgstr ""
+
+#: ../hacks/config/maze3d.xml.h:9
+msgid "Acid"
+msgstr "ესიდი"
+
+#: ../hacks/config/maze3d.xml.h:11 ../hacks/config/splitflap.xml.h:9
+msgid "Rows"
+msgstr "სტრიქონები"
+
+#: ../hacks/config/maze3d.xml.h:12 ../hacks/config/splitflap.xml.h:8
+msgid "Columns"
+msgstr "სვეტები"
+
+#: ../hacks/config/maze3d.xml.h:13
+msgid "Inverters"
+msgstr ""
+
+#: ../hacks/config/maze3d.xml.h:14
+msgid "Rats"
+msgstr "ვირთხები"
+
+#: ../hacks/config/maze3d.xml.h:15
+msgid ""
+"A re-creation of the 3D Maze screensaver from Windows 95. Written by Sudoer; "
+"2018."
+msgstr ""
+
+#: ../hacks/config/memscroller.xml.h:1
+msgid "Mem Scroller"
+msgstr ""
+
+#: ../hacks/config/memscroller.xml.h:5
+msgid "Dump memory"
+msgstr "მეხსერების დამპი"
+
+#: ../hacks/config/memscroller.xml.h:6
+msgid "Draw random numbers"
+msgstr "შემთხვევითი რიცხვების დახატვა"
+
+#: ../hacks/config/memscroller.xml.h:7
+msgid "Draw in RGB"
+msgstr "RGB-ში დახატვა"
+
+#: ../hacks/config/memscroller.xml.h:8
+msgid "Draw green"
+msgstr "მწვანის დახატვა"
+
+#: ../hacks/config/memscroller.xml.h:10
+msgid ""
+"Scrolls a dump of its own memory in three windows at three different rates. "
+"Written by Jamie Zawinski; 2004."
+msgstr ""
+
+#: ../hacks/config/menger.xml.h:1
+msgid "Menger"
+msgstr ""
+
+#: ../hacks/config/menger.xml.h:8 ../hacks/config/sierpinski3d.xml.h:8
+msgid "Max depth"
+msgstr "მაქს. სიღრმე"
+
+#: ../hacks/config/menger.xml.h:20
+msgid ""
+"The Menger Gasket is a cube-based recursive fractal object analogous to the "
+"Sierpinski Tetrahedron. https://en.wikipedia.org/wiki/Menger_sponge https://"
+"en.wikipedia.org/wiki/Sierpinski_carpet Written by Jamie Zawinski; 2001."
+msgstr ""
+
+#: ../hacks/config/metaballs.xml.h:1
+msgid "Meta Balls"
+msgstr ""
+
+#: ../hacks/config/metaballs.xml.h:13
+msgid "Ball Radius"
+msgstr ""
+
+#: ../hacks/config/metaballs.xml.h:15
+msgid "Ball Movement"
+msgstr ""
+
+#: ../hacks/config/metaballs.xml.h:17
+msgid ""
+"2D meta-balls: overlapping and merging balls with fuzzy edges. https://"
+"en.wikipedia.org/wiki/Metaballs Written by W.P. van Paassen; 2003."
+msgstr ""
+
+#: ../hacks/config/mirrorblob.xml.h:1
+msgid "Mirror Blob"
+msgstr ""
+
+#: ../hacks/config/mirrorblob.xml.h:5
+msgid "0.1x"
+msgstr "0.1x"
+
+#: ../hacks/config/mirrorblob.xml.h:7
+msgid "3.0x"
+msgstr "3.0x"
+
+#: ../hacks/config/mirrorblob.xml.h:8
+msgid "5 sec"
+msgstr "5 წმ"
+
+#: ../hacks/config/mirrorblob.xml.h:10
+msgid "5 min"
+msgstr "5 წთ"
+
+#: ../hacks/config/mirrorblob.xml.h:12
+msgid "Transition duration"
+msgstr ""
+
+#: ../hacks/config/mirrorblob.xml.h:13 ../hacks/config/timetunnel.xml.h:4
+msgid "30 sec"
+msgstr "30 წმ"
+
+#: ../hacks/config/mirrorblob.xml.h:16
+msgid "50 bumps"
+msgstr ""
+
+#: ../hacks/config/mirrorblob.xml.h:17
+msgid "Clear"
+msgstr "გაწმენდა"
+
+#: ../hacks/config/mirrorblob.xml.h:20
+msgid "Enable walls"
+msgstr "კედლების ჩართვა"
+
+#: ../hacks/config/mirrorblob.xml.h:21
+msgid "Enable colouring"
+msgstr "შეფერადების ჩართვა"
+
+#: ../hacks/config/mirrorblob.xml.h:22
+msgid "Enable reflected image"
+msgstr "არეკვლილი გამოსახულების ჩართვა"
+
+#: ../hacks/config/mirrorblob.xml.h:23
+msgid "Show image on background"
+msgstr "ფონზე გამოახულების ჩვენება"
+
+#: ../hacks/config/mirrorblob.xml.h:24
+msgid "Offset texture coordinates"
+msgstr "წანაცვლების ტექსტურის კოორდინატები"
+
+#: ../hacks/config/mirrorblob.xml.h:28
+msgid "A wobbly blob distorts images behind it. Written by Jon Dowdall; 2003."
+msgstr ""
+
+#: ../hacks/config/mismunch.xml.h:1
+msgid "Mismunch"
+msgstr ""
+
+#: ../hacks/config/mismunch.xml.h:9 ../hacks/config/munch.xml.h:9
+msgid "Simultaneous squares"
+msgstr ""
+
+#: ../hacks/config/mismunch.xml.h:11 ../hacks/config/munch.xml.h:14
+#: ../hacks/config/qix.xml.h:22
+msgid "XOR"
+msgstr "XOR"
+
+#: ../hacks/config/mismunch.xml.h:14
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. It was merged with the \"Munch\" screen saver. Munching "
+"errors! This is a creatively broken misimplementation of the classic "
+"munching squares graphics hack. See the \"Munch\" screen saver for the "
+"original. https://en.wikipedia.org/wiki/HAKMEM https://en.wikipedia.org/wiki/"
+"Munching_square Written by Steven Hazel; 2004."
+msgstr ""
+
+#: ../hacks/config/moebius.xml.h:1
+msgid "Möbius"
+msgstr ""
+
+#: ../hacks/config/moebius.xml.h:5
+msgid "Solid floor"
+msgstr ""
+
+#: ../hacks/config/moebius.xml.h:6
+msgid "Draw ants"
+msgstr "ჭიანჭველების დანახვა"
+
+#: ../hacks/config/moebius.xml.h:8
+msgid ""
+"M. C. Escher's \"Möbius Strip II\", an image of ants walking along the "
+"surface of a möbius strip. https://en.wikipedia.org/wiki/Moebius_strip "
+"https://en.wikipedia.org/wiki/Maurits_Cornelis_Escher Written by Marcelo F. "
+"Vianna; 1997."
+msgstr ""
+
+#: ../hacks/config/moebiusgears.xml.h:1
+msgid "Möbius Gears"
+msgstr ""
+
+#: ../hacks/config/moebiusgears.xml.h:8
+msgid "Number of gears"
+msgstr ""
+
+#: ../hacks/config/moebiusgears.xml.h:9
+msgid "Number of teeth"
+msgstr "კბილების რაოდენობა"
+
+#: ../hacks/config/moebiusgears.xml.h:15
+msgid ""
+"An interlinked loop of rotating gears. The layout of the gears follows the "
+"path of a möbius strip. See also the \"Pinion\" and \"Gears\" screen savers. "
+"https://en.wikipedia.org/wiki/Involute_gear https://en.wikipedia.org/wiki/"
+"Moebius_strip Written by Jamie Zawinski; 2007."
+msgstr ""
+
+#: ../hacks/config/moire.xml.h:1
+msgid "Moiré"
+msgstr ""
+
+#: ../hacks/config/moire.xml.h:9 ../hacks/config/rorschach.xml.h:5
+msgid "Offset"
+msgstr "წანაცვლება"
+
+#: ../hacks/config/moire.xml.h:12
+msgid ""
+"When the lines on the screen Make more lines in between, That's a moiré! "
+"https://en.wikipedia.org/wiki/Moire_pattern Written by Jamie Zawinski and "
+"Michael Bayne; 1997."
+msgstr ""
+
+#: ../hacks/config/moire2.xml.h:1
+msgid "Moiré 2"
+msgstr ""
+
+#: ../hacks/config/moire2.xml.h:10
+msgid ""
+"Generates fields of concentric circles or ovals, and combines the planes "
+"with various operations. The planes are moving independently of one another, "
+"causing the interference lines to spray. https://en.wikipedia.org/wiki/"
+"Moire_pattern Written by Jamie Zawinski; 1998."
+msgstr ""
+
+#: ../hacks/config/molecule.xml.h:1
+msgid "Molecule"
+msgstr "მოლეკულა"
+
+#: ../hacks/config/molecule.xml.h:8
+msgid "Label atoms"
+msgstr "ატომის ჭდეები"
+
+#: ../hacks/config/molecule.xml.h:9
+msgid "Describe molecule"
+msgstr "აღწერეთ მოლეკულა"
+
+#: ../hacks/config/molecule.xml.h:12
+msgid "Draw atomic nuclei"
+msgstr "ატომბირთვის დახატვა"
+
+#: ../hacks/config/molecule.xml.h:13
+msgid "Draw atomic bonds"
+msgstr "ატომური ბმების დახატვა"
+
+#: ../hacks/config/molecule.xml.h:14
+msgid "Draw electron shells"
+msgstr "ელექტრონული გარსების დახატვა"
+
+#: ../hacks/config/molecule.xml.h:25
+msgid "PDB file or directory"
+msgstr "PDB ფაილი ან საქაღალდე"
+
+#: ../hacks/config/molecule.xml.h:27
+#, no-c-format
+msgid ""
+"Some interesting molecules. Several molecules are built in, and it can also "
+"read PDB (Protein Data Bank) files as input. https://en.wikipedia.org/wiki/"
+"Protein_Data_Bank_%28file_format%29 Written by Jamie Zawinski; 2001."
+msgstr ""
+
+#: ../hacks/config/morph3d.xml.h:1
+msgid "Morph 3D"
+msgstr ""
+
+#: ../hacks/config/morph3d.xml.h:7 ../hacks/config/polyhedra.xml.h:30
+#: ../hacks/config/sballs.xml.h:7
+msgid "Cube"
+msgstr "კუბი"
+
+#: ../hacks/config/morph3d.xml.h:8 ../hacks/config/polyhedra.xml.h:29
+#: ../hacks/config/sballs.xml.h:8
+msgid "Octahedron"
+msgstr "ოქტაჰედრონი"
+
+#: ../hacks/config/morph3d.xml.h:9 ../hacks/config/polyhedra.xml.h:62
+#: ../hacks/config/sballs.xml.h:9
+msgid "Dodecahedron"
+msgstr "დოდეკაჰედრონი"
+
+#: ../hacks/config/morph3d.xml.h:10 ../hacks/config/polyhedra.xml.h:61
+#: ../hacks/config/sballs.xml.h:10
+msgid "Icosahedron"
+msgstr "იკოსაჰერონი"
+
+#: ../hacks/config/morph3d.xml.h:12
+msgid ""
+"Platonic solids that turn inside out and get spikey. https://"
+"en.wikipedia.org/wiki/Platonic_solid Written by Marcelo Vianna; 1997."
+msgstr ""
+
+#: ../hacks/config/mountain.xml.h:1
+msgid "Mountain"
+msgstr "მთა"
+
+#: ../hacks/config/mountain.xml.h:6
+msgid "Peaks"
+msgstr "პიკები"
+
+#: ../hacks/config/mountain.xml.h:12
+msgid "3D plots that are vaguely mountainous. Written by Pascal Pensa; 1997."
+msgstr ""
+
+#: ../hacks/config/munch.xml.h:1
+msgid "Munch"
+msgstr ""
+
+#: ../hacks/config/munch.xml.h:11
+msgid "Munch or mismunch"
+msgstr ""
+
+#: ../hacks/config/munch.xml.h:12
+msgid "Munch only"
+msgstr ""
+
+#: ../hacks/config/munch.xml.h:13
+msgid "Mismunch only"
+msgstr ""
+
+#: ../hacks/config/munch.xml.h:17
+msgid ""
+"DATAI 2 ADDB 1,2 ROTC 2,-22 XOR 1,2 JRST .-4 As reported by HAKMEM (MIT AI "
+"Memo 239, 1972), Jackson Wright wrote the above PDP-1 code in 1962. That "
+"code still lives on here, 60+ years later. In \"mismunch\" mode, it displays "
+"a creatively broken misimplementation of the classic munching squares "
+"algorithm instead. https://en.wikipedia.org/wiki/HAKMEM https://"
+"en.wikipedia.org/wiki/Munching_square Written by Jackson Wright, Tim "
+"Showalter, Jamie Zawinski and Steven Hazel; 1997."
+msgstr ""
+
+#: ../hacks/config/nakagin.xml.h:1
+msgid "Nakagin"
+msgstr ""
+
+#: ../hacks/config/nakagin.xml.h:13
+msgid ""
+"The Nakagin Capsule Tower was demolished in 2022, but this version will "
+"continue to grow forever. Constructed in 1972, the building was composed of "
+"small prefabricated rooms attached to the two central towers. The capsules "
+"were intended to be mass produced and replaceable. Utilities and fittings "
+"were installed before the capsules were shipped to the site. https://"
+"en.wikipedia.org/wiki/Nakagin_Capsule_Tower Written by Jamie Zawinski; 2022."
+msgstr ""
+
+#: ../hacks/config/nerverot.xml.h:1
+msgid "Nerve Rot"
+msgstr ""
+
+#: ../hacks/config/nerverot.xml.h:9
+msgid "Blot count"
+msgstr ""
+
+#: ../hacks/config/nerverot.xml.h:12 ../hacks/config/raverhoop.xml.h:6
+#: ../hacks/config/razzledazzle.xml.h:9 ../hacks/config/topblock.xml.h:14
+msgid "Colors"
+msgstr "ფერები"
+
+#: ../hacks/config/nerverot.xml.h:13 ../hacks/config/pyro.xml.h:8
+#: ../hacks/config/splodesic.xml.h:5
+msgid "Seldom"
+msgstr ""
+
+#: ../hacks/config/nerverot.xml.h:14
+msgid "Changes"
+msgstr "ცვლილებები"
+
+#: ../hacks/config/nerverot.xml.h:15
+msgid "Frequent"
+msgstr "ხშირი"
+
+#: ../hacks/config/nerverot.xml.h:16
+msgid "Calm"
+msgstr "მშვიდი"
+
+#: ../hacks/config/nerverot.xml.h:17
+msgid "Nervousness"
+msgstr ""
+
+#: ../hacks/config/nerverot.xml.h:18
+msgid "Spastic"
+msgstr ""
+
+#: ../hacks/config/nerverot.xml.h:19
+msgid "Crunchiness"
+msgstr ""
+
+#: ../hacks/config/nerverot.xml.h:22
+msgid "Nervously vibrating squiggles. Written by Dan Bornstein; 2000."
+msgstr ""
+
+#: ../hacks/config/noof.xml.h:1
+msgid "Noof"
+msgstr ""
+
+#: ../hacks/config/noof.xml.h:6
+msgid "Flowery, rotatey patterns. Written by Bill Torzewski; 2004."
+msgstr ""
+
+#: ../hacks/config/noseguy.xml.h:1
+msgid "Nose Guy"
+msgstr ""
+
+#: ../hacks/config/noseguy.xml.h:3
+msgid ""
+"A little man with a big nose wanders around your screen saying things. "
+"Written by Dan Heller and Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/pacman.xml.h:1
+msgid "Pac-Man"
+msgstr ""
+
+#: ../hacks/config/pacman.xml.h:5
+msgid "Player size"
+msgstr ""
+
+#: ../hacks/config/pacman.xml.h:7
+msgid ""
+"Simulates a game of Pac-Man on a randomly-created level. https://"
+"en.wikipedia.org/wiki/Pac-Man Written by Edwin de Jong and Jamie Zawinski; "
+"2004."
+msgstr ""
+
+#: ../hacks/config/pedal.xml.h:1
+msgid "Pedal"
+msgstr "პედალი"
+
+#: ../hacks/config/pedal.xml.h:9
+msgid ""
+"The even-odd winding rule. https://en.wikipedia.org/wiki/Even-odd_rule "
+"https://en.wikipedia.org/wiki/Nonzero-rule Written by Dale Moore; 1995."
+msgstr ""
+
+#: ../hacks/config/peepers.xml.h:1
+msgid "Peepers"
+msgstr ""
+
+#: ../hacks/config/peepers.xml.h:9
+msgid "Number of eyes"
+msgstr "თვალების რაოდენობა"
+
+#: ../hacks/config/peepers.xml.h:12
+msgid "Scroll"
+msgstr "ჩამოქაჩვა"
+
+#: ../hacks/config/peepers.xml.h:13
+msgid "Bounce or scroll"
+msgstr ""
+
+#: ../hacks/config/peepers.xml.h:14
+msgid "Grid"
+msgstr "ბადე"
+
+#: ../hacks/config/peepers.xml.h:15
+msgid "Beholder"
+msgstr ""
+
+#: ../hacks/config/peepers.xml.h:18
+msgid ""
+"Floating eyeballs. Anatomically correct, and they also track the pointer. "
+"Written by Jamie Zawinski; 2018."
+msgstr ""
+
+#: ../hacks/config/penetrate.xml.h:1
+msgid "Penetrate"
+msgstr "შეღწევა"
+
+#: ../hacks/config/penetrate.xml.h:3
+msgid "Explosions"
+msgstr "აფეთქებები"
+
+#: ../hacks/config/penetrate.xml.h:6
+msgid "Start badly, but learn"
+msgstr ""
+
+#: ../hacks/config/penetrate.xml.h:7
+msgid "Always play well"
+msgstr ""
+
+#: ../hacks/config/penetrate.xml.h:9
+msgid ""
+"Simulates (something like) the classic arcade game Missile Command. https://"
+"en.wikipedia.org/wiki/Missile_Command Written by Adam Miller; 1999."
+msgstr ""
+
+#: ../hacks/config/penrose.xml.h:1
+msgid "Penrose"
+msgstr ""
+
+#: ../hacks/config/penrose.xml.h:11
+msgid "Draw ammann lines"
+msgstr ""
+
+#: ../hacks/config/penrose.xml.h:13
+msgid ""
+"Quasiperiodic tilings. In April 1997, Sir Roger Penrose, a British math "
+"professor who has worked with Stephen Hawking on such topics as relativity, "
+"black holes, and whether time has a beginning, filed a copyright-"
+"infringement lawsuit against the Kimberly-Clark Corporation, which Penrose "
+"said copied a pattern he created (a pattern demonstrating that \"a "
+"nonrepeating pattern could exist in nature\") for its Kleenex quilted toilet "
+"paper. Penrose said he doesn't like litigation but, \"When it comes to the "
+"population of Great Britain being invited by a multinational to wipe their "
+"bottoms on what appears to be the work of a Knight of the Realm, then a last "
+"stand must be taken.\" As reported by News of the Weird #491, 4-Jul-1997. "
+"https://en.wikipedia.org/wiki/Penrose_tiling https://en.wikipedia.org/wiki/"
+"Tessellation Written by Timo Korvola; 1997."
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:1
+msgid "Petri"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:6
+msgid "Square"
+msgstr "კვადრატი"
+
+#: ../hacks/config/petri.xml.h:7
+msgid "Colony shape"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:8
+msgid "Diamond"
+msgstr "პრიზმა"
+
+#: ../hacks/config/petri.xml.h:9
+msgid "Fertility"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:11
+msgid "Offspring"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:13
+msgid "Slowly"
+msgstr "ნელა"
+
+#: ../hacks/config/petri.xml.h:14
+msgid "Death comes"
+msgstr "სიკვდილი მოდის"
+
+#: ../hacks/config/petri.xml.h:15
+msgid "Quickly"
+msgstr "სწრაფად"
+
+#: ../hacks/config/petri.xml.h:17
+msgid "Minimum rate of growth"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:19
+msgid "Maximum rate of growth"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:20
+msgid "Minimum rate of death"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:21
+msgid "Maximum rate of death"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:23
+msgid "Minimum lifespan"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:25
+msgid "Maximum lifespan"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:27
+msgid "Mold varieties"
+msgstr ""
+
+#: ../hacks/config/petri.xml.h:28
+msgid ""
+"Colonies of mold grow in a petri dish. Growing colored circles overlap and "
+"leave spiral interference in their wake. Written by Dan Bornstein; 1999."
+msgstr ""
+
+#: ../hacks/config/phosphor.xml.h:1
+msgid "Phosphor"
+msgstr ""
+
+#: ../hacks/config/phosphor.xml.h:5
+msgid "Font scale"
+msgstr "ფონტის გადიდება"
+
+#: ../hacks/config/phosphor.xml.h:14
+msgid ""
+"An old terminal with large pixels and long-sustain phosphor. On MacOS and "
+"Linux, this program is also a fully-functional VT100 emulator! Run it as an "
+"application instead of as a screen saver and you can use it as a terminal. "
+"Written by Jamie Zawinski; 1999."
+msgstr ""
+
+#: ../hacks/config/photopile.xml.h:1
+msgid "Photo Pile"
+msgstr ""
+
+#: ../hacks/config/photopile.xml.h:3
+msgid "Image size"
+msgstr "გამოსახულების ზომა"
+
+#: ../hacks/config/photopile.xml.h:5 ../hacks/config/t3d.xml.h:5
+msgid "0 deg"
+msgstr "0 გრად"
+
+#: ../hacks/config/photopile.xml.h:6
+msgid "Maximum angle from vertical"
+msgstr ""
+
+#: ../hacks/config/photopile.xml.h:7 ../hacks/config/t3d.xml.h:7
+msgid "90 deg"
+msgstr "90 გრად"
+
+#: ../hacks/config/photopile.xml.h:9
+msgid "Simulate instant film"
+msgstr ""
+
+#: ../hacks/config/photopile.xml.h:10
+msgid "Instant film theme"
+msgstr ""
+
+#: ../hacks/config/photopile.xml.h:11
+msgid "Draw drop shadows"
+msgstr ""
+
+#: ../hacks/config/photopile.xml.h:23
+msgid ""
+"Loads images as polaroids and drops them in a pile. Written by Jens Kilian "
+"and Jamie Zawinski; 2008."
+msgstr ""
+
+#: ../hacks/config/piecewise.xml.h:1
+msgid "Piecewise"
+msgstr "ნაწილ-ნაწილ"
+
+#: ../hacks/config/piecewise.xml.h:9
+msgid "Color shift"
+msgstr "ფერის წანაცვლება"
+
+#: ../hacks/config/piecewise.xml.h:12
+msgid "Minimum radius"
+msgstr "მინიმალური რადიუსი"
+
+#: ../hacks/config/piecewise.xml.h:14
+msgid "Maximum radius"
+msgstr "მაქსიმალური რადიუსი"
+
+#: ../hacks/config/piecewise.xml.h:16
+msgid ""
+"Moving circles switch from visibility to invisibility at intersection "
+"points. Written by Geoffrey Irving; 2003."
+msgstr ""
+
+#: ../hacks/config/pinion.xml.h:1
+msgid "Pinion"
+msgstr ""
+
+#: ../hacks/config/pinion.xml.h:10
+msgid "Gear size"
+msgstr ""
+
+#: ../hacks/config/pinion.xml.h:12 ../hacks/config/projectiveplane.xml.h:36
+msgid "100"
+msgstr "100"
+
+#: ../hacks/config/pinion.xml.h:13
+msgid "Max RPM"
+msgstr "მაქს ბრ/წთ"
+
+#: ../hacks/config/pinion.xml.h:14
+msgid "2000"
+msgstr "2000"
+
+#: ../hacks/config/pinion.xml.h:17
+msgid ""
+"A gear system marches across the screen. See also the \"Gears\" and \"Möbius "
+"Gears\" screen savers. https://en.wikipedia.org/wiki/Involute_gear Written "
+"by Jamie Zawinski; 2004."
+msgstr ""
+
+#: ../hacks/config/pipes.xml.h:1
+msgid "Pipes"
+msgstr "ფაიფები"
+
+#: ../hacks/config/pipes.xml.h:6
+msgid "Number of pipes"
+msgstr "მილების რაოდენობა"
+
+#: ../hacks/config/pipes.xml.h:7
+msgid "A hundred"
+msgstr "ასი"
+
+#: ../hacks/config/pipes.xml.h:9
+msgid "Pipe length"
+msgstr "მილის სიგრძე"
+
+#: ../hacks/config/pipes.xml.h:12
+msgid "Gadgetry"
+msgstr ""
+
+#: ../hacks/config/pipes.xml.h:14
+msgid "Fisheye lens"
+msgstr "თევზისთვლის ლინზა"
+
+#: ../hacks/config/pipes.xml.h:15
+msgid "Allow tight turns"
+msgstr ""
+
+#: ../hacks/config/pipes.xml.h:16
+msgid "Curved pipes"
+msgstr ""
+
+#: ../hacks/config/pipes.xml.h:17
+msgid "Ball joints"
+msgstr ""
+
+#: ../hacks/config/pipes.xml.h:18
+msgid "Bolted fittings"
+msgstr ""
+
+#: ../hacks/config/pipes.xml.h:19
+msgid "Random style"
+msgstr ""
+
+#: ../hacks/config/pipes.xml.h:22
+msgid ""
+"A growing plumbing system, with bolts and valves. Written by Marcelo Vianna "
+"and Jamie Zawinski; 1997."
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:1
+msgid "Polyhedra"
+msgstr "პოლიჰედრა"
+
+#: ../hacks/config/polyhedra.xml.h:11
+msgid "Display random polyhedron"
+msgstr "შემთხვევითი პოლიჰედრონის ცხოვრება"
+
+#: ../hacks/config/polyhedra.xml.h:12
+msgid "Pentagonal prism"
+msgstr "პენტაგონალური პრიზმა"
+
+#: ../hacks/config/polyhedra.xml.h:13
+msgid "Pentagonal dipyramid"
+msgstr "პენტაგონალური დიპირამიდა"
+
+#: ../hacks/config/polyhedra.xml.h:14
+msgid "Pentagonal antiprism"
+msgstr "პენტაგონალური ანტიპრიზმა"
+
+#: ../hacks/config/polyhedra.xml.h:15
+msgid "Pentagonal deltohedron"
+msgstr "პენტაგონალური დელტოჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:16
+msgid "Pentagrammic prism"
+msgstr "პენტაგრამული პრიზმა"
+
+#: ../hacks/config/polyhedra.xml.h:17
+msgid "Pentagrammic dipyramid"
+msgstr "პენტაგრამული დიპირამიდა"
+
+#: ../hacks/config/polyhedra.xml.h:18
+msgid "Pentagrammic antiprism"
+msgstr "პენტაგრამული ანტიპრიზმა"
+
+#: ../hacks/config/polyhedra.xml.h:19
+msgid "Pentagrammic deltohedron"
+msgstr "პენტაგრამული დელტოჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:20
+msgid "Pentagrammic crossed antiprism"
+msgstr "პენტაგრამული ჯვარედინი ანტიპრიზმა"
+
+#: ../hacks/config/polyhedra.xml.h:21
+msgid "Pentagrammic concave deltohedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:23
+msgid "Truncated tetrahedron"
+msgstr "წაკვეთილი ტეტრაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:24
+msgid "Triakistetrahedron"
+msgstr "ტრიაკისტეტრაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:25
+msgid "Octahemioctahedron"
+msgstr "ოქტაჰემიოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:26
+msgid "Octahemioctacron"
+msgstr "ოქტაჰემიოქტაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:27
+msgid "Tetrahemihexahedron"
+msgstr "ტეტრაჰემიჰექსადრონი"
+
+#: ../hacks/config/polyhedra.xml.h:28
+msgid "Tetrahemihexacron"
+msgstr "ტეტრაჰემიჰექსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:31
+msgid "Cuboctahedron"
+msgstr "კუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:32
+msgid "Rhombic dodecahedron"
+msgstr "რომბული დოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:33
+msgid "Truncated octahedron"
+msgstr "წაკვეთილი ოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:34
+msgid "Tetrakishexahedron"
+msgstr "ტეტრაკისჰექსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:35
+msgid "Truncated cube"
+msgstr "წაკვეთილი კუბი"
+
+#: ../hacks/config/polyhedra.xml.h:36
+msgid "Triakisoctahedron"
+msgstr "ტრიაკისოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:37
+msgid "Rhombicuboctahedron"
+msgstr "რომბიკუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:38
+msgid "Deltoidal icositetrahedron"
+msgstr "დელტოიდალური იკოსიტეტრაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:39
+msgid "Truncated cuboctahedron"
+msgstr "წაკვეთილი კუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:40
+msgid "Disdyakisdodecahedron"
+msgstr "დისდიაკისდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:41
+msgid "Snub cube"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:42
+msgid "Pentagonal icositetrahedron"
+msgstr "პენტაგონალური იკოსიტეტრაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:43
+msgid "Small cubicuboctahedron"
+msgstr "პატარა კუბიკუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:44
+msgid "Small hexacronic icositetrahedron"
+msgstr "პატარა ჰექსაკრონული იკოსიტეტრაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:45
+msgid "Great cubicuboctahedron"
+msgstr "დიდი კუბიკუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:46
+msgid "Great hexacronic icositetrahedron"
+msgstr "დიდი ჰექსაკრონული იკოსიტეტრაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:47
+msgid "Cubohemioctahedron"
+msgstr "კუბოჰემიოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:48
+msgid "Hexahemioctacron"
+msgstr "ჰექსაჰემოქტაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:49
+msgid "Cubitruncated cuboctahedron"
+msgstr "კუბწაკვეთილი კუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:50
+msgid "Tetradyakishexahedron"
+msgstr "ტეტრადიაკისჰექსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:51
+msgid "Great rhombicuboctahedron"
+msgstr "დიდი რომბიკუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:52
+msgid "Great deltoidal icositetrahedron"
+msgstr "დიდი დელტოიდალური იკოსიტეტრაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:53
+msgid "Small rhombihexahedron"
+msgstr "პატარა რომბიჰექსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:54
+msgid "Small rhombihexacron"
+msgstr "პატარა რომბიჰექსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:55
+msgid "Stellated truncated hexahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:56
+msgid "Great triakisoctahedron"
+msgstr "დიდი ტრიაკისოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:57
+msgid "Great truncated cuboctahedron"
+msgstr "დიდი წაკვეთილი კუბოქტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:58
+msgid "Great disdyakisdodecahedron"
+msgstr "დიდი დისდიაკისდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:59
+msgid "Great rhombihexahedron"
+msgstr "დიდი რომბიჰექსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:60
+msgid "Great rhombihexacron"
+msgstr "დიდი რომბიჰექსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:63
+msgid "Icosidodecahedron"
+msgstr "იკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:64
+msgid "Rhombic triacontahedron"
+msgstr "რომბული ტრიაკონტაჰენდრონი"
+
+#: ../hacks/config/polyhedra.xml.h:65
+msgid "Truncated icosahedron"
+msgstr "წაკვეთილი იკოსაჰერონი"
+
+#: ../hacks/config/polyhedra.xml.h:66
+msgid "Pentakisdodecahedron"
+msgstr "პენტაკისდოდეკაჰენდრონი"
+
+#: ../hacks/config/polyhedra.xml.h:67
+msgid "Truncated dodecahedron"
+msgstr "წაკვეთილი დოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:68
+msgid "Triakisicosahedron"
+msgstr "ტრიაკისოკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:69
+msgid "Rhombicosidodecahedron"
+msgstr "რომბიკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:70
+msgid "Deltoidal hexecontahedron"
+msgstr "დელტოიდალური ჰექსოკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:71
+msgid "Truncated icosidodecahedron"
+msgstr "წაკვეთილი იკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:72
+msgid "Disdyakistriacontahedron"
+msgstr "დისდიაკისტრიაკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:73
+msgid "Snub dodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:74
+msgid "Pentagonal hexecontahedron"
+msgstr "პენტაგონალური ჰექსოკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:75
+msgid "Small ditrigonal icosidodecahedron"
+msgstr "პატარა დიტრიგონალური იკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:76
+msgid "Small triambic icosahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:77
+msgid "Small icosicosidodecahedron"
+msgstr "პატარა იკოსიკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:78
+msgid "Small icosacronic hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:79
+msgid "Small snub icosicosidodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:80
+msgid "Small hexagonal hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:81
+msgid "Small dodecicosidodecahedron"
+msgstr "პატარა დოდეკისოდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:82
+msgid "Small dodecacronic hexecontahedron"
+msgstr "პატარა დოდეკკრონული ჰექსეკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:83
+msgid "Small stellated dodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:84
+msgid "Great dodecahedron"
+msgstr "დიდი დოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:85
+msgid "Great dodecadodecahedron"
+msgstr "დიდი დოდეკადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:86
+msgid "Medial rhombic triacontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:87
+msgid "Truncated great dodecahedron"
+msgstr "წაკვეთილი დიდი დოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:88
+msgid "Small stellapentakisdodecahedron"
+msgstr "პატარა სტელაპენტაკისდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:89
+msgid "Rhombidodecadodecahedron"
+msgstr "რომბიდოდენადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:90
+msgid "Medial deltoidal hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:91
+msgid "Small rhombidodecahedron"
+msgstr "პატარა რომბიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:92
+msgid "Small rhombidodecacron"
+msgstr "პატარა რომბიდოდეკაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:93
+msgid "Snub dodecadodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:94
+msgid "Medial pentagonal hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:95
+msgid "Ditrigonal dodecadodecahedron"
+msgstr "დიტრიგონალური დოდეკადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:96
+msgid "Medial triambic icosahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:97
+msgid "Great ditrigonal dodecicosidodecahedron"
+msgstr "დიდი დიტრიგონალური დოდეკადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:98
+msgid "Great ditrigonal dodecacronic hexecontahedron"
+msgstr "დიდი დიტრიგონალური დოდეკაკრონული ჰექსეცონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:99
+msgid "Small ditrigonal dodecicosidodecahedron"
+msgstr "პატარა დიტრიგონალური დოდეკიკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:100
+msgid "Small ditrigonal dodecacronic hexecontahedron"
+msgstr "პატარა დიტრიგონალური დოდეკაკრონული ჰექსეცონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:101
+msgid "Icosidodecadodecahedron"
+msgstr "იცოსიდოდეკადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:102
+msgid "Medial icosacronic hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:103
+msgid "Icositruncated dodecadodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:104
+msgid "Tridyakisicosahedron"
+msgstr "ტრიდიაკისიკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:105
+msgid "Snub icosidodecadodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:106
+msgid "Medial hexagonal hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:107
+msgid "Great ditrigonal icosidodecahedron"
+msgstr "დიდი დიტრიგონალური იკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:108
+msgid "Great triambic icosahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:109
+msgid "Great icosicosidodecahedron"
+msgstr "დიდი იკოსიკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:110
+msgid "Great icosacronic hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:111
+msgid "Small icosihemidodecahedron"
+msgstr "პატარა იკოსიჰემიდოდეკადრონი"
+
+#: ../hacks/config/polyhedra.xml.h:112
+msgid "Small icosihemidodecacron"
+msgstr "პატარა იკოსიჰემიდოდეკაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:113
+msgid "Small dodecicosahedron"
+msgstr "პატარა დოდეკიკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:114
+msgid "Small dodecicosacron"
+msgstr "პატარა დოდეკიკოსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:115
+msgid "Small dodecahemidodecahedron"
+msgstr "პატარა დოდეკაჰემიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:116
+msgid "Small dodecahemidodecacron"
+msgstr "პატარა დოდეკაჰემიდოდეკაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:117
+msgid "Great stellated dodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:118
+msgid "Great icosahedron"
+msgstr "დიდი იკოსეჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:119
+msgid "Great icosidodecahedron"
+msgstr "დიდი იკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:120
+msgid "Great rhombic triacontahedron"
+msgstr "დიდი რომბული ტრიაკონტაჰენდრონი"
+
+#: ../hacks/config/polyhedra.xml.h:121
+msgid "Great truncated icosahedron"
+msgstr "დიდი წაკვეთილი იკოსაჰერონი"
+
+#: ../hacks/config/polyhedra.xml.h:122
+msgid "Great stellapentakisdodecahedron"
+msgstr "დიდი სტელაპენტაკისდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:123
+msgid "Rhombicosahedron"
+msgstr "რომბიკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:124
+msgid "Rhombicosacron"
+msgstr "რომბიკოსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:125
+msgid "Great snub icosidodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:126
+msgid "Great pentagonal hexecontahedron"
+msgstr "დიდი პენტაგონალური ჰექსოკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:127
+msgid "Small stellated truncated dodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:128
+msgid "Great pentakisdodecahedron"
+msgstr "დიდი პენტაკისდოდეკაჰენდრონი"
+
+#: ../hacks/config/polyhedra.xml.h:129
+msgid "Truncated dodecadodecahedron"
+msgstr "წაკვეთილი დოდეკადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:130
+msgid "Medial disdyakistriacontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:131
+msgid "Inverted snub dodecadodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:132
+msgid "Medial inverted pentagonal hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:133
+msgid "Great dodecicosidodecahedron"
+msgstr "დიდი დოდეკადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:134
+msgid "Great dodecacronic hexecontahedron"
+msgstr "დიდი დოდეკაკრონული ჰექსეკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:135
+msgid "Small dodecahemicosahedron"
+msgstr "პატარა დოდეკაჰემიკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:136
+msgid "Small dodecahemicosacron"
+msgstr "პატარა დოდეკაჰემიკოსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:137
+msgid "Great dodecicosahedron"
+msgstr "დიდი დოდეკიკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:138
+msgid "Great dodecicosacron"
+msgstr "დიდი დოდეკიკოსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:139
+msgid "Great snub dodecicosidodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:140
+msgid "Great hexagonal hexecontahedron"
+msgstr "დიდი ჰექსაგონალური ჰექსოკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:141
+msgid "Great dodecahemicosahedron"
+msgstr "დიდი დოდეკაჰემიკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:142
+msgid "Great dodecahemicosacron"
+msgstr "დიდი დოდეკაჰემიკოსაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:143
+msgid "Great stellated truncated dodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:144
+msgid "Great triakisicosahedron"
+msgstr "დიდი ტრიაკისოკოსაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:145
+msgid "Great rhombicosidodecahedron"
+msgstr "დიდი რომბიკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:146
+msgid "Great deltoidal hexecontahedron"
+msgstr "დიდი დელტოიდალური ჰექსოკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:147
+msgid "Great truncated icosidodecahedron"
+msgstr "დიდი წაკვეთილი იკოსიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:148
+msgid "Great disdyakistriacontahedron"
+msgstr "დიდიდისდიაკისტრიაკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:149
+msgid "Great inverted snub icosidodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:150
+msgid "Great inverted pentagonal hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:151
+msgid "Great dodecahemidodecahedron"
+msgstr "დიდი დოდეკაჰემიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:152
+msgid "Great dodecahemidodecacron"
+msgstr "დიდი დოდეკაჰემიდოდეკაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:153
+msgid "Great icosihemidodecahedron"
+msgstr "დიდი იკოსიჰემიდოდეკადრონი"
+
+#: ../hacks/config/polyhedra.xml.h:154
+msgid "Great icosihemidodecacron"
+msgstr "დიდი იკოსიჰემიდოდეკაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:155
+msgid "Small retrosnub icosicosidodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:156
+msgid "Small hexagrammic hexecontahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:157
+msgid "Great rhombidodecahedron"
+msgstr "დიდი რომბიდოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:158
+msgid "Great rhombidodecacron"
+msgstr "დიდი რომბიდოდეკაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:159
+msgid "Great retrosnub icosidodecahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:160
+msgid "Great pentagrammic hexecontahedron"
+msgstr "დიდი პენტაგრამულ ჰექსეკონტაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:161
+msgid "Great dirhombicosidodecahedron"
+msgstr "დიდი დირომბიკოსადოდეკაჰედრონი"
+
+#: ../hacks/config/polyhedra.xml.h:162
+msgid "Great dirhombicosidodecacron"
+msgstr "დიდი დირომბიკოსადოდეკაკრონი"
+
+#: ../hacks/config/polyhedra.xml.h:163
+msgid "Utah teapotahedron"
+msgstr ""
+
+#: ../hacks/config/polyhedra.xml.h:167
+msgid "Show description"
+msgstr "აღწერის ჩვენება"
+
+#: ../hacks/config/polyhedra.xml.h:169
+msgid ""
+"The 75 uniform polyhedra and their duals, plus 5 prisms and antiprisms, and "
+"some information about each. https://en.wikipedia.org/wiki/Uniform_polyhedra "
+"https://en.wikipedia.org/wiki/Stellation https://en.wikipedia.org/wiki/"
+"Dual_polyhedron https://en.wikipedia.org/wiki/Antiprism Written by Dr. Zvi "
+"Har'El and Jamie Zawinski; 2004."
+msgstr ""
+
+#: ../hacks/config/polyominoes.xml.h:1
+msgid "Polyominoes"
+msgstr ""
+
+#: ../hacks/config/polyominoes.xml.h:2
+msgid "Identical pieces"
+msgstr ""
+
+#: ../hacks/config/polyominoes.xml.h:13
+msgid ""
+"Repeatedly attempts to completely fill a rectangle with irregularly-shaped "
+"puzzle pieces. https://en.wikipedia.org/wiki/Polyomino Written by Stephen "
+"Montgomery-Smith; 2002."
+msgstr ""
+
+#: ../hacks/config/polytopes.xml.h:1
+msgid "Polytopes"
+msgstr ""
+
+#: ../hacks/config/polytopes.xml.h:6
+msgid "5-cell (hyper-tetrahedron)"
+msgstr ""
+
+#: ../hacks/config/polytopes.xml.h:7
+msgid "8-cell (hypercube / tesseract)"
+msgstr ""
+
+#: ../hacks/config/polytopes.xml.h:8
+msgid "16-cell (hyper-octahedron)"
+msgstr ""
+
+#: ../hacks/config/polytopes.xml.h:9
+msgid "24-cell"
+msgstr "24-უჯრედი"
+
+#: ../hacks/config/polytopes.xml.h:10
+msgid "120-cell"
+msgstr "120-უჯრედი"
+
+#: ../hacks/config/polytopes.xml.h:11
+msgid "600-cell"
+msgstr "600-უჯრედი"
+
+#: ../hacks/config/polytopes.xml.h:12
+msgid "Single color"
+msgstr "ერთი ფერი"
+
+#: ../hacks/config/polytopes.xml.h:13
+msgid "Colors By 4D Depth"
+msgstr ""
+
+#: ../hacks/config/polytopes.xml.h:30
+msgid ""
+"The six regular 4D polytopes rotating in 4D. Inspired by H.S.M Coxeter's "
+"book \"Regular Polytopes\", 3rd Edition, Dover Publications, Inc., 1973, and "
+"Thomas Banchoff's book \"Beyond the Third Dimension: Geometry, Computer "
+"Graphics, and Higher Dimensions\", Scientific American Library, 1990. "
+"https://en.wikipedia.org/wiki/Hypercube https://en.wikipedia.org/wiki/"
+"Tesseract https://en.wikipedia.org/wiki/Regular_polytope Written by Carsten "
+"Steger; 2003."
+msgstr ""
+
+#: ../hacks/config/pong.xml.h:1
+msgid "Pong"
+msgstr "პონგი"
+
+#: ../hacks/config/pong.xml.h:3
+msgid "Game speed"
+msgstr "თამაშის სიჩქარე"
+
+#: ../hacks/config/pong.xml.h:5
+msgid "Crisp"
+msgstr ""
+
+#: ../hacks/config/pong.xml.h:7
+msgid "Noisy"
+msgstr "ხმაურიანი"
+
+#: ../hacks/config/pong.xml.h:8
+msgid "Clock mode"
+msgstr "საათის რეჟიმი"
+
+#: ../hacks/config/pong.xml.h:14
+msgid ""
+"The 1971 Pong home video game, including artifacts of an old color TV set. "
+"In clock mode, the score keeps track of the current time. https://"
+"en.wikipedia.org/wiki/Pong Written by Jeremy English, Trevor Blackwell and "
+"Jamie Zawinski; 2003."
+msgstr ""
+
+#: ../hacks/config/popsquares.xml.h:1
+msgid "Pop Squares"
+msgstr ""
+
+#: ../hacks/config/popsquares.xml.h:5
+msgid "Subdivision"
+msgstr "ქვედანაყოფი"
+
+#: ../hacks/config/popsquares.xml.h:8
+msgid "Light red"
+msgstr "ღია წითელი"
+
+#: ../hacks/config/popsquares.xml.h:9
+msgid "Light yellow"
+msgstr "ღია ყვითელი"
+
+#: ../hacks/config/popsquares.xml.h:10
+msgid "Light green"
+msgstr "ღია მწვანე"
+
+#: ../hacks/config/popsquares.xml.h:11
+msgid "Light cyan"
+msgstr "ღია ცისფერი"
+
+#: ../hacks/config/popsquares.xml.h:12
+msgid "Light blue"
+msgstr "ღია ლურჯი"
+
+#: ../hacks/config/popsquares.xml.h:13
+msgid "Light magenta"
+msgstr "ღია ალისფერი"
+
+#: ../hacks/config/popsquares.xml.h:14
+msgid "Dark red"
+msgstr "მუქი წითელი"
+
+#: ../hacks/config/popsquares.xml.h:15
+msgid "Dark yellow"
+msgstr "მუქი ყვითელი"
+
+#: ../hacks/config/popsquares.xml.h:16
+msgid "Dark green"
+msgstr "მუქი მწვანე"
+
+#: ../hacks/config/popsquares.xml.h:17
+msgid "Dark cyan"
+msgstr "მუქი ცისფერი"
+
+#: ../hacks/config/popsquares.xml.h:18
+msgid "Dark blue"
+msgstr "მუქი ლურჯი"
+
+#: ../hacks/config/popsquares.xml.h:19
+msgid "Dark magenta"
+msgstr "მუქი ალისფერი"
+
+#: ../hacks/config/popsquares.xml.h:20
+msgid "Twitch"
+msgstr "Twitch"
+
+#: ../hacks/config/popsquares.xml.h:22
+msgid ""
+"A pop-art-ish looking grid of pulsing colors. Written by Levi Burton; 2003."
+msgstr ""
+
+#: ../hacks/config/projectiveplane.xml.h:1
+msgid "Projective Plane"
+msgstr ""
+
+#: ../hacks/config/projectiveplane.xml.h:23
+msgid "-4"
+msgstr "-4"
+
+#: ../hacks/config/projectiveplane.xml.h:24
+msgid "WX speed"
+msgstr "WX სიჩქარე"
+
+#: ../hacks/config/projectiveplane.xml.h:25 ../hacks/config/scooter.xml.h:8
+#: ../hacks/config/sphereeversion.xml.h:29
+msgid "4"
+msgstr "4"
+
+#: ../hacks/config/projectiveplane.xml.h:26
+msgid "WY speed"
+msgstr "WY სიჩქარე"
+
+#: ../hacks/config/projectiveplane.xml.h:27
+msgid "WZ speed"
+msgstr "WZ სიჩქარე"
+
+#: ../hacks/config/projectiveplane.xml.h:28
+msgid "XY speed"
+msgstr "XY სიჩქარე"
+
+#: ../hacks/config/projectiveplane.xml.h:29
+msgid "XZ speed"
+msgstr "XZ სიჩქარე"
+
+#: ../hacks/config/projectiveplane.xml.h:30
+msgid "YZ speed"
+msgstr "YZ სიჩქარე"
+
+#: ../hacks/config/projectiveplane.xml.h:31
+msgid "-180"
+msgstr "-180"
+
+#: ../hacks/config/projectiveplane.xml.h:32
+msgid "Walk dir     "
+msgstr ""
+
+#: ../hacks/config/projectiveplane.xml.h:33
+msgid "180"
+msgstr "180"
+
+#: ../hacks/config/projectiveplane.xml.h:35
+msgid "Walk speed"
+msgstr ""
+
+#: ../hacks/config/projectiveplane.xml.h:46
+msgid ""
+"A 4D embedding of the real projective plane. You can walk on the surface of "
+"the real projective plane or rotate it in 4D or walk on it while it rotates "
+"in 4D. Inspired by Thomas Banchoff's book \"Beyond the Third Dimension: "
+"Geometry, Computer Graphics, and Higher Dimensions\", Scientific American "
+"Library, 1990. https://en.wikipedia.org/wiki/Real_projective_plane https://"
+"en.wikipedia.org/wiki/Roman_surface https://en.wikipedia.org/wiki/Cross_cap "
+"https://en.wikipedia.org/wiki/Moebius_strip https://mathworld.wolfram.com/"
+"RealProjectivePlane.html https://mathworld.wolfram.com/RomanSurface.html "
+"https://mathworld.wolfram.com/Cross-Cap.html https://mathworld.wolfram.com/"
+"MoebiusStrip.html Written by Carsten Steger; 2014."
+msgstr ""
+
+#: ../hacks/config/providence.xml.h:1
+msgid "Providence"
+msgstr "პროვიდენსი"
+
+#: ../hacks/config/providence.xml.h:5
+msgid "Draw eye"
+msgstr ""
+
+#: ../hacks/config/providence.xml.h:8
+msgid ""
+"\"A pyramid unfinished. In the zenith an eye in a triangle, surrounded by a "
+"glory, proper.\" https://en.wikipedia.org/wiki/Eye_of_Providence Written by "
+"Blair Tennessy; 2004."
+msgstr ""
+
+#: ../hacks/config/pulsar.xml.h:1
+msgid "Pulsar"
+msgstr "პულსარი"
+
+#: ../hacks/config/pulsar.xml.h:5
+msgid "Quad count"
+msgstr ""
+
+#: ../hacks/config/pulsar.xml.h:8
+msgid "Enable texturing"
+msgstr "ტექსტურების ჩართვა"
+
+#: ../hacks/config/pulsar.xml.h:9
+msgid "Enable texture mipmaps"
+msgstr ""
+
+#: ../hacks/config/pulsar.xml.h:10
+msgid "Enable blending"
+msgstr "შერევის ჩართვა"
+
+#: ../hacks/config/pulsar.xml.h:11
+msgid "Anti-alias lines"
+msgstr "ხაზების მომრგვალება"
+
+#: ../hacks/config/pulsar.xml.h:12
+msgid "Enable texture filtering"
+msgstr "ტექსტურების გაფილტვრის ჩართვა"
+
+#: ../hacks/config/pulsar.xml.h:13
+msgid "Enable depth buffer"
+msgstr "სიღრმის ბუფერის ჩართვა"
+
+#: ../hacks/config/pulsar.xml.h:15
+msgid ""
+"Intersecting planes, with alpha blending, fog, textures, and mipmaps. "
+"Written by David Konerding; 1999."
+msgstr ""
+
+#: ../hacks/config/pyro.xml.h:1
+msgid "Pyro"
+msgstr ""
+
+#: ../hacks/config/pyro.xml.h:6
+msgid "Particle density"
+msgstr "ნაწილაკის სიმკვრივე"
+
+#: ../hacks/config/pyro.xml.h:9
+msgid "Launch frequency"
+msgstr "გაშვების სიხშირე"
+
+#: ../hacks/config/pyro.xml.h:12
+msgid "Explosive yield"
+msgstr "აფეთქები გამოსავალი"
+
+#: ../hacks/config/pyro.xml.h:15
+msgid ""
+"Exploding fireworks. See also the \"Fireworkx\", \"Eruption\", and "
+"\"XFlame\" screen savers. Written by Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/qix.xml.h:1
+msgid "Qix"
+msgstr ""
+
+#: ../hacks/config/qix.xml.h:12
+msgid "Line segments"
+msgstr ""
+
+#: ../hacks/config/qix.xml.h:13
+msgid "Solid objects"
+msgstr ""
+
+#: ../hacks/config/qix.xml.h:14
+msgid "Linear motion"
+msgstr ""
+
+#: ../hacks/config/qix.xml.h:16
+msgid "Additive colors"
+msgstr ""
+
+#: ../hacks/config/qix.xml.h:17
+msgid "Subtractive colors"
+msgstr ""
+
+#: ../hacks/config/qix.xml.h:19
+msgid "Max size"
+msgstr "მაქს. ზომა"
+
+#: ../hacks/config/qix.xml.h:20
+msgid "Poly corners"
+msgstr "მრავალკუთხა"
+
+#: ../hacks/config/qix.xml.h:25
+msgid ""
+"Bounces a series of line segments around the screen with various "
+"presentations. https://en.wikipedia.org/wiki/Qix Written by Jamie Zawinski; "
+"1992."
+msgstr ""
+
+#: ../hacks/config/quasicrystal.xml.h:1
+msgid "Quasi-Crystal"
+msgstr "კვაზიკრისტალი"
+
+#: ../hacks/config/quasicrystal.xml.h:9
+msgid "Contrast"
+msgstr "კონტრასტი"
+
+#: ../hacks/config/quasicrystal.xml.h:14
+msgid ""
+"A quasicrystal is a structure that is ordered but aperiodic. Two-dimensional "
+"quasicrystals can be generated by adding a set of planes where x is the sine "
+"of y. Different complex aperiodic plane tilings are produced depending on "
+"the period, position, and rotation of the component planes, and whether the "
+"rotation of the planes is evenly distributed around the circle (the "
+"\"symmetry\" option, above) or random. See also the \"RD-Bomb\", \"CWaves\" "
+"and \"Penrose\" screen savers. https://en.wikipedia.org/wiki/Quasicrystal "
+"Written by Jamie Zawinski; 2013."
+msgstr ""
+
+#: ../hacks/config/queens.xml.h:1
+msgid "Queens"
+msgstr "დედოფლები"
+
+#: ../hacks/config/queens.xml.h:7
+msgid ""
+"The N-Queens problem: how to place N queens on an NxN chessboard such that "
+"no queen can attack a sister? See also the \"Endgame\" screen saver. https://"
+"en.wikipedia.org/wiki/Eight_queens_puzzle Written by Blair Tennessy and "
+"Jamie Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/raverhoop.xml.h:1
+msgid "Raver Hoop"
+msgstr ""
+
+#: ../hacks/config/raverhoop.xml.h:9
+msgid "Lights"
+msgstr "სინათლეები"
+
+#: ../hacks/config/raverhoop.xml.h:12
+msgid "Speed, motion"
+msgstr "სიჩქარე, მოძრაობა"
+
+#: ../hacks/config/raverhoop.xml.h:14
+msgid "Speed, lights"
+msgstr "სიჩქარე, სინათლეები"
+
+#: ../hacks/config/raverhoop.xml.h:16
+msgid "Sustain"
+msgstr ""
+
+#: ../hacks/config/raverhoop.xml.h:21
+msgid ""
+"Simulates an LED hula hoop in a dark room. Oontz oontz oontz. Written by "
+"Jamie Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/razzledazzle.xml.h:1
+msgid "Razzle Dazzle"
+msgstr ""
+
+#: ../hacks/config/razzledazzle.xml.h:8 ../hacks/config/scooter.xml.h:14
+msgid "Mono"
+msgstr "მონო"
+
+#: ../hacks/config/razzledazzle.xml.h:17
+msgid "Ship Outlines"
+msgstr ""
+
+#: ../hacks/config/razzledazzle.xml.h:18
+msgid "Flat Pattern"
+msgstr ""
+
+#: ../hacks/config/razzledazzle.xml.h:19
+msgid "Ships or flat pattern"
+msgstr ""
+
+#: ../hacks/config/razzledazzle.xml.h:22
+#, no-c-format
+msgid ""
+"Generates an infinitely-scrolling sequence of dazzle camouflage patterns. "
+"Dazzle Ships, in addition to being the best album by Orchestral Manoeuvres "
+"in the Dark, were military vessels during World War I and early in World War "
+"II that were painted not to conceal but to confuse: with these Cubist "
+"overlapping stripes, it was very hard to estimate their size, range and "
+"heading. This was a big deal before the invention of Radar. https://"
+"en.wikipedia.org/wiki/Dazzle_camouflage https://en.wikipedia.org/wiki/Cubism "
+"https://en.wikipedia.org/wiki/Dazzle_Ships_%28album%29 https://"
+"en.wikipedia.org/wiki/Acoustic_mirror https://en.wikipedia.org/wiki/Radar "
+"Written by Jamie Zawinski; 2018."
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:1
+msgid "Ripples"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:8
+msgid "Drizzle"
+msgstr "ჟინჟღლი"
+
+#: ../hacks/config/ripples.xml.h:9
+msgid "Drippiness"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:10
+msgid "Storm"
+msgstr "ქარიშხალი"
+
+#: ../hacks/config/ripples.xml.h:11
+msgid "Small drops"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:12
+msgid "Fluidity"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:13
+msgid "Big drops"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:14
+msgid "Moving splashes"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:15
+msgid "Psychedelic colors"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:16
+msgid "Grayscale"
+msgstr "ნაცრისფერი"
+
+#: ../hacks/config/ripples.xml.h:17
+msgid "Magic lighting effect"
+msgstr ""
+
+#: ../hacks/config/ripples.xml.h:19
+msgid ""
+"Rippling interference patterns reminiscent of splashing water distort a "
+"loaded image. Written by Tom Hammersley; 1999."
+msgstr ""
+
+#: ../hacks/config/rocks.xml.h:1
+msgid "Rocks"
+msgstr "ქვები"
+
+#: ../hacks/config/rocks.xml.h:9
+msgid "Velocity"
+msgstr "Velocity"
+
+#: ../hacks/config/rocks.xml.h:12
+msgid "Steering"
+msgstr ""
+
+#: ../hacks/config/rocks.xml.h:17
+msgid "An asteroid field zooms by. Written by Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/romanboy.xml.h:1
+msgid "Roman Boy"
+msgstr ""
+
+#: ../hacks/config/romanboy.xml.h:5
+msgid "Order of the surface"
+msgstr ""
+
+#: ../hacks/config/romanboy.xml.h:7
+msgid "Deform the projective plane"
+msgstr ""
+
+#: ../hacks/config/romanboy.xml.h:13
+msgid "1000.0"
+msgstr "1000.0"
+
+#: ../hacks/config/romanboy.xml.h:45
+#, no-c-format
+msgid ""
+"A 3D immersion of the real projective plane that smoothly deforms between "
+"the Roman surface and the Boy surface. You can walk on the surface of the "
+"real projective plane or rotate it in 3D. Furthermore, it is possible to "
+"smoothly deform the real projective plane between the Roman surface and the "
+"Boy surface while turning it or walking on it. Inspired by François Apéry's "
+"book \"Models of the Real Projective Plane\", Vieweg, 1987. https://"
+"en.wikipedia.org/wiki/Boy%27s_surface https://en.wikipedia.org/wiki/"
+"Roman_surface https://mathworld.wolfram.com/BoySurface.html https://"
+"mathworld.wolfram.com/RomanSurface.html Written by Carsten Steger; 2014."
+msgstr ""
+
+#: ../hacks/config/rorschach.xml.h:1
+msgid "Rorschach"
+msgstr ""
+
+#: ../hacks/config/rorschach.xml.h:6
+msgid "With X symmetry"
+msgstr ""
+
+#: ../hacks/config/rorschach.xml.h:7
+msgid "With Y symmetry"
+msgstr ""
+
+#: ../hacks/config/rorschach.xml.h:12
+msgid ""
+"Inkblot patterns via a reflected random walk. https://en.wikipedia.org/wiki/"
+"Rorschach_inkblot_test https://en.wikipedia.org/wiki/Random_walk Written by "
+"Jamie Zawinski; 1992."
+msgstr ""
+
+#: ../hacks/config/rotor.xml.h:1
+msgid "Rotor"
+msgstr "როტორი"
+
+#: ../hacks/config/rotor.xml.h:14
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws a line segment moving along a complex spiraling curve. "
+"Written by Tom Lawrence; 1997."
+msgstr ""
+
+#: ../hacks/config/rotzoomer.xml.h:1
+msgid "Rot Zoomer"
+msgstr ""
+
+#: ../hacks/config/rotzoomer.xml.h:8
+msgid "Rectangle count"
+msgstr "მართკუთხედების რაოდენობა"
+
+#: ../hacks/config/rotzoomer.xml.h:10
+msgid "Stationary rectangles"
+msgstr ""
+
+#: ../hacks/config/rotzoomer.xml.h:11
+msgid "Wandering rectangles"
+msgstr ""
+
+#: ../hacks/config/rotzoomer.xml.h:12
+msgid "Sweeping arcs"
+msgstr ""
+
+#: ../hacks/config/rotzoomer.xml.h:13
+msgid "Rotating discs"
+msgstr ""
+
+#: ../hacks/config/rotzoomer.xml.h:14
+msgid "Animate"
+msgstr "ან_იმაცია"
+
+#: ../hacks/config/rotzoomer.xml.h:16
+msgid ""
+"Distorts an image by rotating and scaling random sections of it. Written by "
+"Claudio Matsuoka and Jamie Zawinski; 2001."
+msgstr ""
+
+#: ../hacks/config/rubik.xml.h:1
+msgid "Rubik"
+msgstr "რუბიკი"
+
+#: ../hacks/config/rubik.xml.h:10
+msgid "Hide shuffling"
+msgstr "არევის დამალვა"
+
+#: ../hacks/config/rubik.xml.h:13
+#, no-c-format
+msgid ""
+"A Rubik's Cube that repeatedly shuffles and solves itself. See also the "
+"\"GLSnake\" and \"Cube21\" screen savers. https://en.wikipedia.org/wiki/"
+"Rubik%27s_Cube Written by Marcelo Vianna; 1997."
+msgstr ""
+
+#: ../hacks/config/rubikblocks.xml.h:1
+msgid "Rubik Blocks"
+msgstr ""
+
+#: ../hacks/config/rubikblocks.xml.h:21
+msgid ""
+"The \"Rubik's Mirror Blocks\" puzzle. See also the \"Rubik\", \"Cube21\", "
+"and \"GLSnake\" screen savers. https://en.wikipedia.org/wiki/"
+"Combination_puzzles#Irregular_cuboids Written by Vasek Potocek; 2009."
+msgstr ""
+
+#: ../hacks/config/sballs.xml.h:1
+msgid "SBalls"
+msgstr ""
+
+#: ../hacks/config/sballs.xml.h:11
+msgid "Plane"
+msgstr "ზედაპირი"
+
+#: ../hacks/config/sballs.xml.h:12
+msgid "Pyramid"
+msgstr "პირამიდა"
+
+#: ../hacks/config/sballs.xml.h:13
+msgid "Star"
+msgstr "ვარსკვლავი"
+
+#: ../hacks/config/sballs.xml.h:17
+msgid "Textured balls spinning like crazy. Written by Eric Lassauge; 2002."
+msgstr ""
+
+#: ../hacks/config/scooter.xml.h:1
+msgid "Scooter"
+msgstr "სკუტერი"
+
+#: ../hacks/config/scooter.xml.h:5
+msgid "Very slow"
+msgstr "ძალიან ნელი"
+
+#: ../hacks/config/scooter.xml.h:6
+msgid "Boat Speed"
+msgstr ""
+
+#: ../hacks/config/scooter.xml.h:7
+msgid "Very fast"
+msgstr "ძალიან სწრაფი"
+
+#: ../hacks/config/scooter.xml.h:9
+msgid "Number of doors"
+msgstr "კარების რაოდენობა"
+
+#: ../hacks/config/scooter.xml.h:10
+msgid "40"
+msgstr "40"
+
+#: ../hacks/config/scooter.xml.h:13
+msgid "200"
+msgstr "200"
+
+#: ../hacks/config/scooter.xml.h:16
+msgid "Colorful"
+msgstr "ფერადი"
+
+#: ../hacks/config/scooter.xml.h:18
+msgid ""
+"Zooming down a tunnel in a star field. Originally an Amiga hack. Written by "
+"Sven Thoennissen; 2001. Ported by EoflaOE; 2019."
+msgstr ""
+
+#: ../hacks/config/shadebobs.xml.h:1
+msgid "Shade Bobs"
+msgstr ""
+
+#: ../hacks/config/shadebobs.xml.h:14
+msgid ""
+"Oscillating oval patterns that look something like vapor trails or neon "
+"tubes. Written by Shane Smit; 1999."
+msgstr ""
+
+#: ../hacks/config/sierpinski.xml.h:1
+msgid "Sierpinski"
+msgstr ""
+
+#: ../hacks/config/sierpinski.xml.h:6 ../hacks/config/surfaces.xml.h:22
+#: ../hacks/config/thornbird.xml.h:6 ../hacks/config/voronoi.xml.h:6
+msgid "Points"
+msgstr "წერტილები"
+
+#: ../hacks/config/sierpinski.xml.h:14
+msgid ""
+"The 2D Sierpinski triangle fractal. See also the \"Sierpinski3D\" screen "
+"saver. https://en.wikipedia.org/wiki/Sierpinski_triangle Written by Desmond "
+"Daignault; 1997."
+msgstr ""
+
+#: ../hacks/config/sierpinski3d.xml.h:1
+msgid "Sierpinski 3D"
+msgstr ""
+
+#: ../hacks/config/sierpinski3d.xml.h:11
+msgid ""
+"The recursive Sierpinski tetrahedron fractal. https://en.wikipedia.org/wiki/"
+"Sierpinski_triangle#Analogs_in_higher_dimension Written by Jamie Zawinski "
+"and Tim Robinson; 1999."
+msgstr ""
+
+#: ../hacks/config/skytentacles.xml.h:1
+msgid "Sky Tentacles"
+msgstr ""
+
+#: ../hacks/config/skytentacles.xml.h:12
+msgid "Flexibility"
+msgstr ""
+
+#: ../hacks/config/skytentacles.xml.h:14
+msgid "Wiggliness"
+msgstr ""
+
+#: ../hacks/config/skytentacles.xml.h:19
+msgid "X resolution"
+msgstr "X გაფართოება"
+
+#: ../hacks/config/skytentacles.xml.h:20
+msgid "Y resolution"
+msgstr "Y გაფართოება"
+
+#: ../hacks/config/skytentacles.xml.h:21
+msgid "Draw skin"
+msgstr ""
+
+#: ../hacks/config/skytentacles.xml.h:22
+msgid "Cartoony"
+msgstr ""
+
+#: ../hacks/config/skytentacles.xml.h:23
+msgid "Tentacles can intersect"
+msgstr ""
+
+#: ../hacks/config/skytentacles.xml.h:26
+msgid ""
+"There is a tentacled abomination in the sky. From above you it devours. "
+"Written by Jamie Zawinski; 2008."
+msgstr ""
+
+#: ../hacks/config/slidescreen.xml.h:1
+msgid "Slide Screen"
+msgstr ""
+
+#: ../hacks/config/slidescreen.xml.h:6
+msgid "Pause"
+msgstr "შეჩერება"
+
+#: ../hacks/config/slidescreen.xml.h:12
+msgid "Slide speed"
+msgstr ""
+
+#: ../hacks/config/slidescreen.xml.h:17
+msgid "Gutter size"
+msgstr ""
+
+#: ../hacks/config/slidescreen.xml.h:19
+msgid ""
+"A \"fifteen puzzle\" variant, dividing the image into a grid and shuffling. "
+"https://en.wikipedia.org/wiki/Fifteen_puzzle Written by Jamie Zawinski; 1994."
+msgstr ""
+
+#: ../hacks/config/slip.xml.h:1
+msgid "Slip"
+msgstr "სრიალი"
+
+#: ../hacks/config/slip.xml.h:14
+msgid ""
+"A jet engine consumes the image, then puts it through a spin cycle. Written "
+"by Scott Draves and Jamie Zawinski; 1997."
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:1
+msgid "Sonar"
+msgstr "სონარი"
+
+#: ../hacks/config/sonar.xml.h:8
+msgid "Ping local subnet"
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:9
+msgid "Ping known SSH hosts"
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:10
+msgid "Ping Google, Facebook, etc."
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:11
+msgid "Simulation (don't ping)"
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:13
+msgid "Font size"
+msgstr "ფონტის ზომა"
+
+#: ../hacks/config/sonar.xml.h:18
+msgid "Simulation team A name"
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:19
+msgid "A count"
+msgstr "რაოდენობა A"
+
+#: ../hacks/config/sonar.xml.h:20
+msgid "Simulation team B name"
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:21
+msgid "B count"
+msgstr "რაოდენობა B"
+
+#: ../hacks/config/sonar.xml.h:22
+msgid "Resolve host names"
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:23
+msgid "Show ping times"
+msgstr ""
+
+#: ../hacks/config/sonar.xml.h:26
+msgid ""
+"A sonar display pings (get it?) the hosts on your local network, and plots "
+"their distance (response time) from you. The three rings represent ping "
+"times of approximately 2.5, 70 and 2,000 milliseconds respectively. "
+"Alternately, it can run a simulation that doesn't involve hosts. https://"
+"en.wikipedia.org/wiki/Ping#History Written by Jamie Zawinski and Stephen "
+"Martin; 1998."
+msgstr ""
+
+#: ../hacks/config/speedmine.xml.h:1
+msgid "Speed Mine"
+msgstr ""
+
+#: ../hacks/config/speedmine.xml.h:6
+msgid "Max velocity"
+msgstr "მაქს. აჩქარება"
+
+#: ../hacks/config/speedmine.xml.h:8
+msgid "Thrust"
+msgstr "გაწევა"
+
+#: ../hacks/config/speedmine.xml.h:10
+msgid "Tunnel"
+msgstr "გვირაბი"
+
+#: ../hacks/config/speedmine.xml.h:11 ../hacks/config/worm.xml.h:1
+msgid "Worm"
+msgstr "მატლი"
+
+#: ../hacks/config/speedmine.xml.h:12
+msgid "Rocky walls"
+msgstr "ქვიანი კედლები"
+
+#: ../hacks/config/speedmine.xml.h:13
+msgid "Allow wall collisions"
+msgstr ""
+
+#: ../hacks/config/speedmine.xml.h:14
+msgid "Present bonuses"
+msgstr ""
+
+#: ../hacks/config/speedmine.xml.h:15
+msgid "Display crosshair"
+msgstr ""
+
+#: ../hacks/config/speedmine.xml.h:18
+msgid ""
+"Simulates speeding down a rocky mineshaft, or a funky dancing worm. Written "
+"by Conrad Parker; 2001."
+msgstr ""
+
+#: ../hacks/config/sphere.xml.h:9
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws shaded spheres in multiple colors. Written by Tom Duff "
+"and Jamie Zawinski; 1982, 1997."
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:1
+msgid "Sphere Eversion"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:2
+msgid "Random deformation"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:3
+msgid "Analytic"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:4
+msgid "Corrugations"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:13
+msgid "Parallel bands"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:14
+msgid "Meridian bands"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:15
+msgid "Random graticule"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:16
+msgid "With graticule"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:17
+msgid "Without graticule"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:20
+msgid "Parallel colors"
+msgstr "პარალელური ფერები"
+
+#: ../hacks/config/sphereeversion.xml.h:21
+msgid "Meridian colors"
+msgstr "მერიდიანის ფერები"
+
+#: ../hacks/config/sphereeversion.xml.h:22
+msgid "Earth colors"
+msgstr "დედამიწის ფერები"
+
+#: ../hacks/config/sphereeversion.xml.h:26
+msgid "Random surface order"
+msgstr ""
+
+#: ../hacks/config/sphereeversion.xml.h:30
+msgid "5"
+msgstr "5"
+
+#: ../hacks/config/sphereeversion.xml.h:39
+msgid ""
+"Turns a sphere inside out: a smooth deformation (homotopy). During the "
+"eversion, the deformed sphere is allowed to intersect itself transversally, "
+"however, no creases or pinch points occur. Inspired by the following paper: "
+"Adam Bednorz, Witold Bednorz: \"Analytic sphere eversion using ruled "
+"surfaces\", Differential Geometry and its Applications 64:59-79, 2019. Also "
+"by the video \"Outside In\" by The Geometry Center (Bill Thurston, Silvio "
+"Levy, Delle Maxwell, Tamara Munzner, Nathaniel Thurston, David Ben-Zvi, Matt "
+"Headrick, et al.), 1994, and the accompanying booklet Silvio Levy: \"Making "
+"Waves — A Guide to the Ideas Behind Outside In\", A K Peters, Wellesley, MA, "
+"1995. https://en.wikipedia.org/wiki/Sphere_eversion https://"
+"mathworld.wolfram.com/SphereEversion.html Written by Carsten Steger; 2020."
+msgstr ""
+
+#: ../hacks/config/spheremonics.xml.h:1
+msgid "Spheremonics"
+msgstr ""
+
+#: ../hacks/config/spheremonics.xml.h:18
+msgid "Smoothed lines"
+msgstr ""
+
+#: ../hacks/config/spheremonics.xml.h:23
+msgid ""
+"These closed objects are commonly called spherical harmonics, although they "
+"are only remotely related to the mathematical definition found in the "
+"solution to certain wave functions, most notably the eigenfunctions of "
+"angular momentum operators. https://en.wikipedia.org/wiki/"
+"Spherical_harmonics#Visualization_of_the_spherical_harmonics Written by Paul "
+"Bourke and Jamie Zawinski; 2002."
+msgstr ""
+
+#: ../hacks/config/spiral.xml.h:1
+msgid "Spiral"
+msgstr "სპირალური"
+
+#: ../hacks/config/spiral.xml.h:12
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Moving circular moiré patterns. Written by Peter "
+"Schmitzberger; 1997."
+msgstr ""
+
+#: ../hacks/config/splitflap.xml.h:1
+msgid "Split-Flap"
+msgstr ""
+
+#: ../hacks/config/splitflap.xml.h:10
+msgid "Display text"
+msgstr "ტექსტის ჩვენება"
+
+#: ../hacks/config/splitflap.xml.h:11
+msgid "Display 12-hour clock"
+msgstr ""
+
+#: ../hacks/config/splitflap.xml.h:12
+msgid "Display 24-hour clock"
+msgstr ""
+
+#: ../hacks/config/splitflap.xml.h:26
+msgid ""
+"Simulates a split-flap display, an old style of electromechanical sign as "
+"seen in airports and train stations, and commonly used in alarm clocks in "
+"the 1960s and 1970s. https://en.wikipedia.org/wiki/Split-flap_display "
+"https://en.wikipedia.org/wiki/Flip_clock Written by Jamie Zawinski; 2015."
+msgstr ""
+
+#: ../hacks/config/splodesic.xml.h:1
+msgid "Splodesic"
+msgstr ""
+
+#: ../hacks/config/splodesic.xml.h:6
+msgid "Eruption frequency"
+msgstr ""
+
+#: ../hacks/config/splodesic.xml.h:12
+msgid ""
+"A geodesic sphere experiences a series of eruptions. Written by Jamie "
+"Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/spotlight.xml.h:1
+msgid "Spotlight"
+msgstr "პროჟექტორი"
+
+#: ../hacks/config/spotlight.xml.h:9
+msgid "Spotlight size"
+msgstr ""
+
+#: ../hacks/config/spotlight.xml.h:12
+msgid ""
+"A spotlight scanning across a black screen, illuminating a loaded image when "
+"it passes. Written by Rick Schultz and Jamie Zawinski; 1999."
+msgstr ""
+
+#: ../hacks/config/sproingies.xml.h:1
+msgid "Sproingies"
+msgstr ""
+
+#: ../hacks/config/sproingies.xml.h:7
+msgid "Fall off edge"
+msgstr ""
+
+#: ../hacks/config/sproingies.xml.h:11
+#, no-c-format
+msgid ""
+"Slinky-like creatures walk down an infinite staircase and occasionally "
+"explode! https://en.wikipedia.org/wiki/Slinky https://en.wikipedia.org/wiki/"
+"Q%2Abert https://en.wikipedia.org/wiki/Marble_Madness Written by Ed Mackey; "
+"1997."
+msgstr ""
+
+#: ../hacks/config/squiral.xml.h:1
+msgid "Squiral"
+msgstr ""
+
+#: ../hacks/config/squiral.xml.h:5 ../hacks/config/twang.xml.h:9
+msgid "Randomness"
+msgstr "შემთხვევითობა"
+
+#: ../hacks/config/squiral.xml.h:10
+msgid "Left"
+msgstr "მარცხენა"
+
+#: ../hacks/config/squiral.xml.h:11
+msgid "Handedness"
+msgstr ""
+
+#: ../hacks/config/squiral.xml.h:12
+msgid "Right"
+msgstr "მარჯვენა"
+
+#: ../hacks/config/squiral.xml.h:20
+msgid ""
+"Square-spiral-producing automata. The spirals grow outward until they hit "
+"something, then they go around it. Written by Jeff Epler; 1999."
+msgstr ""
+
+#: ../hacks/config/squirtorus.xml.h:1
+msgid "Squirtorus"
+msgstr ""
+
+#: ../hacks/config/squirtorus.xml.h:13
+msgid ""
+"A scrolling landscape vents toroidal rainbows into the sky. Above, the stars "
+"are slowly going out. Written by Jamie Zawinski; 2022."
+msgstr ""
+
+#: ../hacks/config/stairs.xml.h:1
+msgid "Stairs"
+msgstr "კიბეები"
+
+#: ../hacks/config/stairs.xml.h:6
+msgid ""
+"Escher's infinite staircase. https://en.wikipedia.org/wiki/"
+"Maurits_Cornelis_Escher Written by Marcelo Vianna and Jamie Zawinski; 1998."
+msgstr ""
+
+#: ../hacks/config/starfish.xml.h:1
+msgid "Starfish"
+msgstr "ზღვის ვარსკვლავა"
+
+#: ../hacks/config/starfish.xml.h:3
+msgid "Color gradients"
+msgstr "ფერის გრადაციები"
+
+#: ../hacks/config/starfish.xml.h:4
+msgid "Pulsating blob"
+msgstr ""
+
+#: ../hacks/config/starfish.xml.h:18
+msgid ""
+"Undulating, throbbing, star-like patterns pulsate, rotate, and turn inside "
+"out. Written by Jamie Zawinski; 1997."
+msgstr ""
+
+#: ../hacks/config/starwars.xml.h:1
+msgid "Star Wars"
+msgstr "ვარსკვლავური ომები"
+
+#: ../hacks/config/starwars.xml.h:2
+msgid "  Frame rate      Low"
+msgstr ""
+
+#: ../hacks/config/starwars.xml.h:4
+msgid "Scroll speed     Slow"
+msgstr ""
+
+#: ../hacks/config/starwars.xml.h:6
+msgid " Stars speed     Slow"
+msgstr ""
+
+#: ../hacks/config/starwars.xml.h:10
+msgid "Wrap long lines"
+msgstr ""
+
+#: ../hacks/config/starwars.xml.h:11
+msgid "Texture-mapped font"
+msgstr ""
+
+#: ../hacks/config/starwars.xml.h:12
+msgid "Anti-aliased lines"
+msgstr "მომრგვალებულად ხაზები"
+
+#: ../hacks/config/starwars.xml.h:13
+msgid "Thick lines"
+msgstr "სქელის ხაზები"
+
+#: ../hacks/config/starwars.xml.h:14
+msgid "Fade out"
+msgstr "მინავლება"
+
+#: ../hacks/config/starwars.xml.h:18
+msgid "or, Text columns"
+msgstr ""
+
+#: ../hacks/config/starwars.xml.h:19
+msgid ""
+"A stream of text slowly scrolling into the distance at an angle, over a star "
+"field, like at the beginning of the movie of the same name. https://"
+"en.wikipedia.org/wiki/Star_Wars_opening_crawl Written by Jamie Zawinski and "
+"Claudio Matsuoka; 2001."
+msgstr ""
+
+#: ../hacks/config/stonerview.xml.h:1
+msgid "Stoner View"
+msgstr ""
+
+#: ../hacks/config/stonerview.xml.h:6
+msgid "Translucent"
+msgstr "გამჭვირვალე"
+
+#: ../hacks/config/stonerview.xml.h:8
+msgid ""
+"Chains of colorful squares dance around in spirals. Inspired by the classic "
+"SGI \"ElectroPaint\" screen saver from the 1980s. Written by Andrew Plotkin; "
+"2001."
+msgstr ""
+
+#: ../hacks/config/strange.xml.h:1
+msgid "Strange"
+msgstr "უცნაური"
+
+#: ../hacks/config/strange.xml.h:5
+msgid "Curviness"
+msgstr ""
+
+#: ../hacks/config/strange.xml.h:6
+msgid "1k"
+msgstr "1k"
+
+#: ../hacks/config/strange.xml.h:7
+msgid "Number of points"
+msgstr "წერტილების რაოდენობა"
+
+#: ../hacks/config/strange.xml.h:8
+msgid "500k"
+msgstr "500k"
+
+#: ../hacks/config/strange.xml.h:10 ../hacks/config/voronoi.xml.h:9
+msgid "Point size"
+msgstr "წერტილის ზომა"
+
+#: ../hacks/config/strange.xml.h:13
+#, no-c-format
+msgid "10%"
+msgstr "10%"
+
+#: ../hacks/config/strange.xml.h:16
+#, no-c-format
+msgid "400%"
+msgstr "400%"
+
+#: ../hacks/config/strange.xml.h:17
+msgid "Brightness"
+msgstr "სიკაშკაშე"
+
+#: ../hacks/config/strange.xml.h:24
+msgid ""
+"Strange attractors: a swarm of dots swoops and twists around. https://"
+"en.wikipedia.org/wiki/Attractor#Strange_attractor Written by Massimino "
+"Pascal; 1997."
+msgstr ""
+
+#: ../hacks/config/substrate.xml.h:1
+msgid "Substrate"
+msgstr ""
+
+#: ../hacks/config/substrate.xml.h:9
+msgid "Sand grains"
+msgstr "ქვიშის მარცვლები"
+
+#: ../hacks/config/substrate.xml.h:12
+#, no-c-format
+msgid "0%"
+msgstr "0%"
+
+#: ../hacks/config/substrate.xml.h:13
+msgid "Circle percentage"
+msgstr ""
+
+#: ../hacks/config/substrate.xml.h:16
+msgid "Initial cracks"
+msgstr "საწყისი ბზარები"
+
+#: ../hacks/config/substrate.xml.h:17
+msgid "Wireframe only"
+msgstr "მხოლოდ კარკასი"
+
+#: ../hacks/config/substrate.xml.h:18
+msgid "Seamless mode"
+msgstr ""
+
+#: ../hacks/config/substrate.xml.h:20
+msgid ""
+"Crystalline lines grow on a computational substrate. A simple perpendicular "
+"growth rule creates intricate city-like structures. Written by J. Tarbell "
+"and Mike Kershaw; 2004."
+msgstr ""
+
+#: ../hacks/config/superquadrics.xml.h:1
+msgid "Superquadrics"
+msgstr ""
+
+#: ../hacks/config/superquadrics.xml.h:6
+msgid "Spin speed"
+msgstr ""
+
+#: ../hacks/config/superquadrics.xml.h:14
+msgid "Morphing 3D shapes. Written by Ed Mackey; 1987, 1997."
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:1
+msgid "Surfaces"
+msgstr "ზედაპირები"
+
+#: ../hacks/config/surfaces.xml.h:8
+msgid "Random Surface"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:9
+msgid "Dini's Surface"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:10
+msgid "Enneper's Surface"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:11
+msgid "Kuen Surface"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:12
+msgid "Möbius Strip"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:13
+msgid "Seashell"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:14
+msgid "Swallowtail"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:15
+msgid "Bohemian Dome"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:16
+msgid "Whitney Umbrella"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:17
+msgid "Pluecker's Conoid"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:18
+msgid "Henneberg's Surface"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:19
+msgid "Catalan's Surface"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:20
+msgid "Corkscrew Surface"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:21
+msgid "Random Display Mode"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:24
+msgid "Line Loops"
+msgstr ""
+
+#: ../hacks/config/surfaces.xml.h:28
+msgid ""
+"Parametric surfaces. https://mathworld.wolfram.com/DinisSurface.html https://"
+"en.wikipedia.org/wiki/Enneper_surface https://mathworld.wolfram.com/"
+"EnnepersMinimalSurface.html https://mathworld.wolfram.com/KuenSurface.html "
+"https://en.wikipedia.org/wiki/Moebius_strip https://mathworld.wolfram.com/"
+"Seashell.html https://mathworld.wolfram.com/SwallowtailCatastrophe.html "
+"https://mathworld.wolfram.com/BohemianDome.html https://en.wikipedia.org/"
+"wiki/Whitney_umbrella https://mathworld.wolfram.com/PlueckersConoid.html "
+"https://mathworld.wolfram.com/HennebergsMinimalSurface.html https://"
+"mathworld.wolfram.com/CatalansSurface.html https://mathworld.wolfram.com/"
+"CorkscrewSurface.html Written by Andrey Mirtchovski and Carsten Steger; 2003."
+msgstr ""
+
+#: ../hacks/config/swirl.xml.h:1
+msgid "Swirl"
+msgstr "გრიგალი"
+
+#: ../hacks/config/swirl.xml.h:11
+msgid "Flowing, swirly patterns. Written by M. Dobie and R. Taylor; 1997."
+msgstr ""
+
+#: ../hacks/config/t3d.xml.h:1
+msgid "T3D"
+msgstr "T3D"
+
+#: ../hacks/config/t3d.xml.h:6
+msgid "Turn side-to-side"
+msgstr ""
+
+#: ../hacks/config/t3d.xml.h:8
+msgid "Wobbliness"
+msgstr "კანკალი"
+
+#: ../hacks/config/t3d.xml.h:9
+msgid "Cycle seconds"
+msgstr ""
+
+#: ../hacks/config/t3d.xml.h:10
+msgid "Smaller"
+msgstr "უფრო პატარა"
+
+#: ../hacks/config/t3d.xml.h:12
+msgid "Bigger"
+msgstr "უფრო დიდი"
+
+#: ../hacks/config/t3d.xml.h:13
+msgid "Minute tick marks"
+msgstr ""
+
+#: ../hacks/config/t3d.xml.h:14
+msgid "5 minute tick marks"
+msgstr ""
+
+#: ../hacks/config/t3d.xml.h:16
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws a working analog clock composed of floating, throbbing "
+"bubbles. Written by Bernd Paysan; 1999."
+msgstr ""
+
+#: ../hacks/config/tangram.xml.h:1
+msgid "Tangram"
+msgstr ""
+
+#: ../hacks/config/tangram.xml.h:9
+msgid "X rotation"
+msgstr "X შებრუნება"
+
+#: ../hacks/config/tangram.xml.h:11
+msgid "Y rotation"
+msgstr "Y შებრუნება"
+
+#: ../hacks/config/tangram.xml.h:12
+msgid "Z rotation"
+msgstr "Z შებრუნება"
+
+#: ../hacks/config/tangram.xml.h:17
+msgid ""
+"Solves tangram puzzles. https://en.wikipedia.org/wiki/Tangram Written by "
+"Jeremy English; 2005."
+msgstr ""
+
+#: ../hacks/config/tessellimage.xml.h:1
+msgid "Tessellimage"
+msgstr ""
+
+#: ../hacks/config/tessellimage.xml.h:5
+msgid "0.1 second"
+msgstr "0.1 წმ"
+
+#: ../hacks/config/tessellimage.xml.h:7
+msgid "4 seconds"
+msgstr "4 წმ"
+
+#: ../hacks/config/tessellimage.xml.h:14
+msgid "Delaunay or voronoi"
+msgstr ""
+
+#: ../hacks/config/tessellimage.xml.h:15
+msgid "Delaunay"
+msgstr ""
+
+#: ../hacks/config/tessellimage.xml.h:16 ../hacks/config/voronoi.xml.h:1
+msgid "Voronoi"
+msgstr ""
+
+#: ../hacks/config/tessellimage.xml.h:17
+msgid "Fill screen"
+msgstr "ეკრანის შევსება"
+
+#: ../hacks/config/tessellimage.xml.h:18
+msgid "Outline triangles"
+msgstr ""
+
+#: ../hacks/config/tessellimage.xml.h:20
+msgid ""
+"Converts an image to triangles using Delaunay tessellation, or to polygons "
+"using Voronoi tesselation, and animates the result at various depths. More "
+"polygons are allocated to visually complex parts of the image. This is "
+"accomplished by first computing the first derivative of the image: the "
+"distance between each pixel and its neighbors (which is essentially edge "
+"detection or embossing). Then the Delaunay or Voronoi control points are "
+"chosen by selecting those pixels whose distance value is above a certain "
+"threshold: those are the pixels that have the largest change in color/"
+"brightness. https://en.wikipedia.org/wiki/Delaunay_triangulation https://"
+"en.wikipedia.org/wiki/Voronoi_diagram https://en.wikipedia.org/wiki/"
+"Tessellation Written by Jamie Zawinski; 2014."
+msgstr ""
+
+#: ../hacks/config/testx11.xml.h:1
+msgid "Test X11"
+msgstr ""
+
+#: ../hacks/config/testx11.xml.h:3
+msgid ""
+"Test platform for JWXYZ - the X11 compatibility shim for OS X and iOS. End "
+"users shouldn't normally see this one. Written by Dave Odell; 2015."
+msgstr ""
+
+#: ../hacks/config/thornbird.xml.h:1
+msgid "Thornbird"
+msgstr ""
+
+#: ../hacks/config/thornbird.xml.h:12
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 6.05. This fractal is among those generated by \"Discrete\". Written "
+"by Tim Auckland; 2002."
+msgstr ""
+
+#: ../hacks/config/timetunnel.xml.h:1
+msgid "Time Tunnel"
+msgstr "დროის გვირაბი"
+
+#: ../hacks/config/timetunnel.xml.h:2
+msgid "0 sec"
+msgstr "0 წმ"
+
+#: ../hacks/config/timetunnel.xml.h:3
+msgid "Start sequence time"
+msgstr "მიმდევრობის დასაწყისის დრო"
+
+#: ../hacks/config/timetunnel.xml.h:5
+msgid "End sequence time"
+msgstr "მიმდევრობის დასასრულის დრო"
+
+#: ../hacks/config/timetunnel.xml.h:6
+msgid "Draw logo"
+msgstr "ლოგოს დახატვა"
+
+#: ../hacks/config/timetunnel.xml.h:7
+msgid "Run backward"
+msgstr "უკან გაშვება"
+
+#: ../hacks/config/timetunnel.xml.h:9
+msgid ""
+"An animation similar to the title sequence of Dr. Who in the 70s. Written by "
+"Sean P. Brennan; 2005."
+msgstr ""
+
+#: ../hacks/config/topblock.xml.h:1
+msgid "Top Block"
+msgstr "ზედა ბლოკი"
+
+#: ../hacks/config/topblock.xml.h:6
+msgid "Drop speed"
+msgstr ""
+
+#: ../hacks/config/topblock.xml.h:9
+msgid "Carpet size"
+msgstr "ხალიჩის ზომა"
+
+#: ../hacks/config/topblock.xml.h:11
+msgid "Spawn likelyhood"
+msgstr ""
+
+#: ../hacks/config/topblock.xml.h:12
+msgid "Polygon count"
+msgstr ""
+
+#: ../hacks/config/topblock.xml.h:18
+msgid "Follow"
+msgstr "გამოწერა"
+
+#: ../hacks/config/topblock.xml.h:19
+msgid "Blob mode"
+msgstr ""
+
+#: ../hacks/config/topblock.xml.h:20
+msgid "Tunnel mode"
+msgstr ""
+
+#: ../hacks/config/topblock.xml.h:21
+msgid "Carpet"
+msgstr "ხალიჩა"
+
+#: ../hacks/config/topblock.xml.h:22
+msgid "Nipples"
+msgstr "კერტები"
+
+#: ../hacks/config/topblock.xml.h:25
+msgid ""
+"Creates a 3D world with dropping blocks that build up and up. Written by "
+"rednuht; 2006."
+msgstr ""
+
+#: ../hacks/config/triangle.xml.h:1
+msgid "Triangle"
+msgstr "სამკუთხედი"
+
+#: ../hacks/config/triangle.xml.h:9
+msgid ""
+"Generates random mountain ranges using iterative subdivision of triangles. "
+"Written by Tobias Gloth; 1997."
+msgstr ""
+
+#: ../hacks/config/tronbit.xml.h:1
+msgid "Tron Bit"
+msgstr ""
+
+#: ../hacks/config/tronbit.xml.h:12
+msgid ""
+"The character \"Bit\" from the film, \"Tron\". The \"yes\" state is a "
+"tetrahedron; the \"no\" state is the second stellation of an icosahedron; "
+"and the idle state oscillates between a small triambic icosahedron and the "
+"compound of an icosahedron and a dodecahedron. https://en.wikipedia.org/wiki/"
+"List_of_Tron_characters#Bit https://en.wikipedia.org/wiki/Uniform_polyhedra "
+"https://en.wikipedia.org/wiki/Stellation Written by Jamie Zawinski; 2011."
+msgstr ""
+
+#: ../hacks/config/truchet.xml.h:1
+msgid "Truchet"
+msgstr ""
+
+#: ../hacks/config/truchet.xml.h:6
+msgid ""
+"Line- and arc-based truchet patterns that tile the screen. https://"
+"en.wikipedia.org/wiki/Tessellation Written by Adrian Likins; 1998."
+msgstr ""
+
+#: ../hacks/config/twang.xml.h:1
+msgid "Twang"
+msgstr ""
+
+#: ../hacks/config/twang.xml.h:10
+msgid "Jumpy"
+msgstr ""
+
+#: ../hacks/config/twang.xml.h:12
+msgid "Springiness"
+msgstr ""
+
+#: ../hacks/config/twang.xml.h:13
+msgid "Transference"
+msgstr ""
+
+#: ../hacks/config/twang.xml.h:17
+msgid "Border width"
+msgstr "საზღვრის სიგანე"
+
+#: ../hacks/config/twang.xml.h:19
+msgid ""
+"Divides the screen into a grid, and plucks them. Written by Dan Bornstein; "
+"2002."
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:1
+msgid "Unicrud"
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:12
+msgid "Display everything"
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:13
+msgid "Display Latin1"
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:14
+msgid "Display simple characters"
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:15
+msgid "Display mathematical symbols"
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:16
+msgid "Display emoticons"
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:17
+msgid "Display hieroglyphs"
+msgstr ""
+
+#: ../hacks/config/unicrud.xml.h:18
+msgid ""
+"Chooses a random Unicode character and displays it full screen, along with "
+"some information about it. If you only see squares, install better fonts. "
+"https://en.wikipedia.org/wiki/Unicode Written by Jamie Zawinski; 2016."
+msgstr ""
+
+#: ../hacks/config/unknownpleasures.xml.h:1
+msgid "Unknown Pleasures"
+msgstr ""
+
+#: ../hacks/config/unknownpleasures.xml.h:12
+msgid "Amplitude"
+msgstr "ამპლიტუდა"
+
+#: ../hacks/config/unknownpleasures.xml.h:14
+msgid "Orthographic Projection"
+msgstr ""
+
+#: ../hacks/config/unknownpleasures.xml.h:15
+msgid "Buzz"
+msgstr ""
+
+#: ../hacks/config/unknownpleasures.xml.h:18
+msgid "Mask image"
+msgstr ""
+
+#: ../hacks/config/unknownpleasures.xml.h:20
+#, no-c-format
+msgid ""
+"PSR B1919+21 (AKA CP 1919) was the first pulsar ever discovered: a spinning "
+"neutron star emitting a periodic lighthouse-like beacon. An illustration of "
+"the signal received from it was published in Scientific American in 1971, "
+"and later in The Cambridge Encyclopedia of Astronomy in 1977, where it was "
+"seen by Stephen Morris, the drummer of Joy Division, and was consequently "
+"appropriated by Peter Saville for the cover of the band's album \"Unknown "
+"Pleasures\". https://en.wikipedia.org/wiki/Pulsar https://en.wikipedia.org/"
+"wiki/PSR_B1919%2B21 https://en.wikipedia.org/wiki/Unknown_Pleasures https://"
+"en.wikipedia.org/wiki/Peter_Saville_%28graphic_designer%29 https://"
+"en.wikipedia.org/wiki/Joy_Division Written by Jamie Zawinski; 2013."
+msgstr ""
+
+#: ../hacks/config/vermiculate.xml.h:1
+msgid "Vermiculate"
+msgstr ""
+
+#: ../hacks/config/vermiculate.xml.h:6
+msgid "Squiggly worm-like paths. Written by Tyler Pierce; 2001."
+msgstr ""
+
+#: ../hacks/config/vfeedback.xml.h:1
+msgid "VFeedback"
+msgstr ""
+
+#: ../hacks/config/vfeedback.xml.h:10
+msgid ""
+"Simulates video feedback: pointing a video camera at an NTSC television. "
+"Written by Jamie Zawinski; 2018."
+msgstr ""
+
+#: ../hacks/config/vidwhacker.xml.h:1
+msgid "Vid Whacker"
+msgstr ""
+
+#: ../hacks/config/vidwhacker.xml.h:2
+msgid "2 seconds"
+msgstr "2 წამი"
+
+#: ../hacks/config/vidwhacker.xml.h:6
+msgid ""
+"Distorts an image using a random series of filters: edge detection, "
+"subtracting the image from a rotated version of itself, etc. Written by "
+"Jamie Zawinski; 1998."
+msgstr ""
+
+#: ../hacks/config/vigilance.xml.h:1
+msgid "Vigilance"
+msgstr ""
+
+#: ../hacks/config/vigilance.xml.h:9
+msgid "Number of cameras"
+msgstr "კამერების რაოდენობა"
+
+#: ../hacks/config/vigilance.xml.h:11
+msgid ""
+"Security cameras keep careful track of their surroundings. You can trust "
+"them. Everything is completely under control. Written by Jamie Zawinski; "
+"2017."
+msgstr ""
+
+#: ../hacks/config/vines.xml.h:1
+msgid "Vines"
+msgstr ""
+
+#: ../hacks/config/vines.xml.h:9
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Generates a continuous sequence of small, curvy geometric "
+"patterns. Written by Tracy Camp and David Hansen; 1997."
+msgstr ""
+
+#: ../hacks/config/voronoi.xml.h:10
+msgid "50 pixels"
+msgstr "50 პიქსელი"
+
+#: ../hacks/config/voronoi.xml.h:12
+msgid "Wander speed"
+msgstr ""
+
+#: ../hacks/config/voronoi.xml.h:13
+msgid "Insertion speed"
+msgstr "ჩასმის სიჩქარე"
+
+#: ../hacks/config/voronoi.xml.h:14
+msgid "Zoom speed"
+msgstr "გადიდების სიჩქარე"
+
+#: ../hacks/config/voronoi.xml.h:15
+msgid "Zoom frequency"
+msgstr "გადიდების სიხშირე"
+
+#: ../hacks/config/voronoi.xml.h:17
+msgid ""
+"A Voronoi tessellation. Periodically zooms in and adds new points. The "
+"existing points also wander around. There are a set of control points on the "
+"plane, each at the center of a colored cell. Every pixel within that cell is "
+"closer to that cell's control point than to any other control point. That is "
+"what determines the cell's shapes. https://en.wikipedia.org/wiki/"
+"Voronoi_diagram https://en.wikipedia.org/wiki/Tessellation Written by Jamie "
+"Zawinski; 2007."
+msgstr ""
+
+#: ../hacks/config/wander.xml.h:11
+msgid "Draw spots"
+msgstr ""
+
+#: ../hacks/config/wander.xml.h:14
+msgid ""
+"A colorful random-walk. https://en.wikipedia.org/wiki/Random_walk Written by "
+"Rick Campbell; 1999."
+msgstr ""
+
+#: ../hacks/config/webcollage.xml.h:1
+msgid "Web Collage"
+msgstr ""
+
+#: ../hacks/config/webcollage.xml.h:3
+msgid "Delay between images"
+msgstr ""
+
+#: ../hacks/config/webcollage.xml.h:4
+msgid "30 secs"
+msgstr "30 წმ"
+
+#: ../hacks/config/webcollage.xml.h:5
+msgid "2 secs"
+msgstr "2 წმ"
+
+#: ../hacks/config/webcollage.xml.h:6
+msgid "Network timeout"
+msgstr "ქსელის მოლოდინის ვადა გავიდა"
+
+#: ../hacks/config/webcollage.xml.h:7
+msgid "2 min"
+msgstr "2 წთ"
+
+#: ../hacks/config/webcollage.xml.h:9
+msgid "Image opacity"
+msgstr "გამოსახულების_გაუმჭვირვალობა"
+
+#: ../hacks/config/webcollage.xml.h:12
+msgid ""
+"This is what the Internet looks like. This creates collages out of random "
+"images from the World Wide Web. It finds the images by feeding random words "
+"into various search engines, and pulling images (or sections of images) out "
+"of the pages returned. WARNING: THE INTERNET SOMETIMES CONTAINS PORNOGRAPHY. "
+"The Internet being what it is, absolutely anything might show up in the "
+"collage including -- quite possibly -- pornography, or even nudity. Please "
+"act accordingly. See also https://www.jwz.org/webcollage/ Written by Jamie "
+"Zawinski; 1998."
+msgstr ""
+
+#: ../hacks/config/whirlwindwarp.xml.h:1
+msgid "Whirlwind Warp"
+msgstr ""
+
+#: ../hacks/config/whirlwindwarp.xml.h:6
+msgid "Trail size"
+msgstr ""
+
+#: ../hacks/config/whirlwindwarp.xml.h:9
+msgid ""
+"Floating stars are acted upon by a mixture of simple 2D force fields. The "
+"strength of each force field changes continuously, and it is also switched "
+"on and off at random. Written by Paul 'Joey' Clark; 2001."
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:1
+msgid "Whirlygig"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:2
+msgid "Whirlies"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:5
+msgid "X speed"
+msgstr "X სიჩქარე"
+
+#: ../hacks/config/whirlygig.xml.h:7
+msgid "Y speed"
+msgstr "Y სიჩქარე"
+
+#: ../hacks/config/whirlygig.xml.h:8
+msgid "X amplitude"
+msgstr "X ამპლიტუდა"
+
+#: ../hacks/config/whirlygig.xml.h:9
+msgid "Y amplitude"
+msgstr "Y ამპლიტუდა"
+
+#: ../hacks/config/whirlygig.xml.h:10
+msgid "X random"
+msgstr "შემთხვევითი X"
+
+#: ../hacks/config/whirlygig.xml.h:11
+msgid "X spin"
+msgstr "X სპინი"
+
+#: ../hacks/config/whirlygig.xml.h:12
+msgid "X funky"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:13
+msgid "X circle"
+msgstr "X წრე"
+
+#: ../hacks/config/whirlygig.xml.h:14
+msgid "X linear"
+msgstr "წრფივი X"
+
+#: ../hacks/config/whirlygig.xml.h:15
+msgid "X test"
+msgstr "X ტესტი"
+
+#: ../hacks/config/whirlygig.xml.h:16
+msgid "X fun"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:17
+msgid "X innie"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:18
+msgid "X lissajous"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:19
+msgid "Y random"
+msgstr "შემთხვევითი Y"
+
+#: ../hacks/config/whirlygig.xml.h:20
+msgid "Y spin"
+msgstr "სპინი Y"
+
+#: ../hacks/config/whirlygig.xml.h:21
+msgid "Y funky"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:22
+msgid "Y circle"
+msgstr "Y წრე"
+
+#: ../hacks/config/whirlygig.xml.h:23
+msgid "Y linear"
+msgstr "წრფივი Y"
+
+#: ../hacks/config/whirlygig.xml.h:24
+msgid "Y test"
+msgstr "ტესტი Y"
+
+#: ../hacks/config/whirlygig.xml.h:25
+msgid "Y fun"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:26
+msgid "Y innie"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:27
+msgid "Y lissajous"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:28
+msgid "Leave a trail"
+msgstr "კვალის დატოვება"
+
+#: ../hacks/config/whirlygig.xml.h:29
+msgid "Explain modes"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:30
+msgid "Wrap the screen"
+msgstr ""
+
+#: ../hacks/config/whirlygig.xml.h:32
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Zooming chains of sinusoidal spots. Written by Ashton Trey "
+"Belew; 2001."
+msgstr ""
+
+#: ../hacks/config/winduprobot.xml.h:1
+msgid "Windup Robot"
+msgstr ""
+
+#: ../hacks/config/winduprobot.xml.h:6
+msgid "Robot speed"
+msgstr "რობოტის სიჩქარე"
+
+#: ../hacks/config/winduprobot.xml.h:9
+msgid "Number of robots"
+msgstr "რობოტების რაოდენობა"
+
+#: ../hacks/config/winduprobot.xml.h:12
+msgid "Robot size"
+msgstr "რობოტის ზომა"
+
+#: ../hacks/config/winduprobot.xml.h:14
+msgid "Invisible"
+msgstr "უხილავია"
+
+#: ../hacks/config/winduprobot.xml.h:15
+msgid "Robot skin transparency"
+msgstr "რობოტის კანის გამჭვირვალობა"
+
+#: ../hacks/config/winduprobot.xml.h:17
+msgid "Never"
+msgstr "არასდროს"
+
+#: ../hacks/config/winduprobot.xml.h:18
+msgid "Word bubbles"
+msgstr ""
+
+#: ../hacks/config/winduprobot.xml.h:21
+msgid "Fade opacity"
+msgstr "მინავლების გაუმჭვირვალობა"
+
+#: ../hacks/config/winduprobot.xml.h:23
+msgid ""
+"A swarm of wind-up toy robots wander around the table-top, bumping into each "
+"other. Each robot contains a mechanically accurate gear system inside, which "
+"you can see when the robot's shell occasionally fades to transparency. Also, "
+"sometimes a cartoony word bubble pops up above a robot, full of random text. "
+"Written by Jamie Zawinski; 2014."
+msgstr ""
+
+#: ../hacks/config/worm.xml.h:11
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws multicolored worms that crawl around the screen. Written "
+"by Brad Taylor, Dave Lemke, Boris Putanec, and Henrik Theiling; 1991."
+msgstr ""
+
+#: ../hacks/config/wormhole.xml.h:1
+msgid "Wormhole"
+msgstr ""
+
+#: ../hacks/config/wormhole.xml.h:6
+msgid "Star speed"
+msgstr ""
+
+#: ../hacks/config/wormhole.xml.h:9
+msgid "Stars created"
+msgstr ""
+
+#: ../hacks/config/wormhole.xml.h:12
+msgid ""
+"Flying through a colored wormhole in space. Written by Jon Rafkind; 2004."
+msgstr ""
+
+#: ../hacks/config/xanalogtv.xml.h:1
+msgid "XAnalogTV"
+msgstr ""
+
+#: ../hacks/config/xanalogtv.xml.h:3
+msgid "Colorbars only"
+msgstr ""
+
+#: ../hacks/config/xanalogtv.xml.h:10
+msgid ""
+"An old TV set, including artifacts like snow, bloom, distortion, ghosting, "
+"and hash noise. It also simulates the TV warming up. It will cycle through "
+"12 channels, some with images you give it, and some with color bars or "
+"nothing but static. Written by Trevor Blackwell; 2003."
+msgstr ""
+
+#: ../hacks/config/xflame.xml.h:1
+msgid "XFlame"
+msgstr ""
+
+#: ../hacks/config/xflame.xml.h:5
+msgid "Enable blooming"
+msgstr ""
+
+#: ../hacks/config/xflame.xml.h:7
+msgid ""
+"Pulsing fire. It can also take an arbitrary image and set it on fire too. "
+"Written by Carsten Haitzler and many others; 1999."
+msgstr ""
+
+#: ../hacks/config/xjack.xml.h:1
+msgid "XJack"
+msgstr ""
+
+#: ../hacks/config/xjack.xml.h:6
+msgid "A novel by Jack Torrance. Written by Jamie Zawinski; 1997."
+msgstr ""
+
+#: ../hacks/config/xlyap.xml.h:1
+msgid "XLyap"
+msgstr ""
+
+#: ../hacks/config/xlyap.xml.h:9
+msgid ""
+"The Lyapunov exponent makes pretty fractal pictures. https://"
+"en.wikipedia.org/wiki/Lyapunov_exponent Written by Ron Record; 1997."
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:1
+msgid "XMatrix"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:2
+msgid "Small font"
+msgstr "პატარა ფონტი"
+
+#: ../hacks/config/xmatrix.xml.h:3
+msgid "Large font"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:8
+msgid "Piped ASCII text"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:9
+msgid "Synergistic algorithm"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:10
+msgid "Slider algorithm"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:11
+msgid "Expansion algorithm"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:12
+msgid "Run trace program"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:13
+msgid "Knock knock"
+msgstr ""
+
+#: ../hacks/config/xmatrix.xml.h:14
+msgid "Phone number"
+msgstr "ტელეფონის ნომერი"
+
+#: ../hacks/config/xmatrix.xml.h:22
+msgid ""
+"The \"digital rain\" effect, as seen on the computer monitors in \"The "
+"Matrix\". See also \"GLMatrix\" for a 3D rendering of the similar effect "
+"that appeared in the movie's title sequence. https://en.wikipedia.org/wiki/"
+"Matrix_digital_rain Written by Jamie Zawinski; 1999."
+msgstr ""
+
+#: ../hacks/config/xrayswarm.xml.h:1
+msgid "XRaySwarm"
+msgstr ""
+
+#: ../hacks/config/xrayswarm.xml.h:6
+msgid ""
+"Worm-like swarms of particles with vapor trails. Written by Chris Leger; "
+"2000."
+msgstr ""
+
+#: ../hacks/config/xspirograph.xml.h:1
+msgid "XSpirograph"
+msgstr ""
+
+#: ../hacks/config/xspirograph.xml.h:10
+msgid ""
+"Simulates that pen-in-nested-plastic-gears toy from your childhood. https://"
+"en.wikipedia.org/wiki/Spirograph Written by Rohit Singh; 2000."
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:8
+msgid "X mag"
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:9
+msgid " X border"
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:10
+msgid "   X lens"
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:11
+msgid "Y mag"
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:12
+msgid " Y border"
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:13
+msgid "    Y lens"
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:14
+msgid "Lenses"
+msgstr ""
+
+#: ../hacks/config/zoom.xml.h:16
+msgid ""
+"Fatbits! Zooms in on a part of an image and scrolls, distorting each pixel "
+"with its own lens. Written by James Macnicol; 2001."
+msgstr ""
index 16190f74a4ffbff29a7fef36754df16dda0b4680..42ee665f3f2086d9e78c10c1870d62609b3efcfa 100644 (file)
@@ -108,20 +108,20 @@ SRCS              = alpha.c colors.c grabclient.c hsv.c \
                  xshm.c xdbe.c colorbars.c minixpm.c textclient.c \
                  textclient-mobile.c aligned_malloc.c thread_util.c \
                  async_netdb.c xft.c xftwrap.c utf8wc.c pow2.c font-retry.c \
-                 screenshot.c
+                 screenshot.c easing.c doubletime.c
 OBJS           = alpha.o colors.o grabclient.o hsv.o \
                  overlay.o resources.o spline.o usleep.o visual.o \
                  visual-gl.o xmu.o logo.o yarandom.o erase.o \
                  xshm.o xdbe.o colorbars.o minixpm.o textclient.o \
                  aligned_malloc.o thread_util.o \
                  async_netdb.o xft.o xftwrap.o utf8wc.o pow2.o font-retry.o \
-                 screenshot.o
+                 screenshot.o easing.o doubletime.o
 HDRS           = alpha.h colors.h grabclient.h hsv.h resources.h \
                  spline.h usleep.h utils.h version.h visual.h visual-gl.h \
                  vroot.h xmu.h yarandom.h erase.h xshm.h xdbe.h colorbars.h \
                  minixpm.h xscreensaver-intl.h textclient.h aligned_malloc.h \
                  thread_util.h async_netdb.h xft.h xftwrap.h utf8wc.h pow2.h \
-                 font-retry.h queue.h screenshot.h
+                 font-retry.h queue.h screenshot.h easing.h doubletime.h
 STAR           = *
 LOGOS          = images/$(STAR).xpm \
                  images/$(STAR).png \
@@ -226,7 +226,14 @@ colors.o: $(srcdir)/hsv.h
 colors.o: $(srcdir)/utils.h
 colors.o: $(srcdir)/visual.h
 colors.o: $(srcdir)/yarandom.h
+doubletime.o: ../config.h
+doubletime.o: $(srcdir)/doubletime.h
+doubletime.o: $(srcdir)/utils.h
+easing.o: ../config.h
+easing.o: $(srcdir)/easing.h
+easing.o: $(srcdir)/utils.h
 erase.o: ../config.h
+erase.o: $(srcdir)/doubletime.h
 erase.o: $(srcdir)/erase.h
 erase.o: $(srcdir)/resources.h
 erase.o: $(srcdir)/usleep.h
@@ -265,6 +272,7 @@ resources.o: ../config.h
 resources.o: $(srcdir)/resources.h
 resources.o: $(srcdir)/utils.h
 screenshot.o: ../config.h
+screenshot.o: $(srcdir)/doubletime.h
 screenshot.o: $(srcdir)/../driver/blurb.h
 screenshot.o: $(srcdir)/screenshot.h
 screenshot.o: $(srcdir)/visual.h
diff --git a/utils/doubletime.c b/utils/doubletime.c
new file mode 100644 (file)
index 0000000..c5aa87b
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright © 2025 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.
+ */
+
+#include "utils.h"
+#include "doubletime.h"
+#include <sys/time.h>
+
+double
+double_time (void)
+{
+  struct timeval now;
+# ifdef GETTIMEOFDAY_TWO_ARGS
+  struct timezone tzp;
+  gettimeofday(&now, &tzp);
+# else
+  gettimeofday(&now);
+# endif
+
+  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
+}
diff --git a/utils/doubletime.h b/utils/doubletime.h
new file mode 100644 (file)
index 0000000..4067ad0
--- /dev/null
@@ -0,0 +1,18 @@
+/* Copyright © 2025 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.
+ */
+
+#ifndef __DOUBLETIME_H__
+#define __DOUBLETIME_H__
+
+/* Current time as a double, with (probably) microsecond accuracy. */
+extern double double_time (void);
+
+#endif /* __DOUBLETIME_H__ */
diff --git a/utils/easing.c b/utils/easing.c
new file mode 100644 (file)
index 0000000..02afbd2
--- /dev/null
@@ -0,0 +1,282 @@
+/* Copyright © 2025 Jamie Zawinski <jwz@jwz.org>
+ * Easing functions.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#include "utils.h"
+#include "easing.h"
+
+/* These are the same semantics as  CSS and jQuery. */
+
+static double
+easeInSine (double x)
+{
+  return 1 - cos ((x * M_PI) / 2);
+}
+
+static double
+easeOutSine (double x)
+{
+  return sin ((x * M_PI) / 2);
+}
+
+static double
+easeInOutSine (double x)
+{
+  return -(cos (M_PI * x) - 1) / 2;
+}
+
+static double
+easeInQuad (double x)
+{
+  return x * x;
+}
+
+static double
+easeOutQuad (double x)
+{
+  return 1 - (1 - x) * (1 - x);
+}
+
+static double
+easeInOutQuad (double x)
+{
+  return (x < 0.5
+          ? 2 * x * x
+          : 1 - pow (-2 * x + 2, 2) / 2);
+}
+
+static double
+easeInCubic (double x)
+{
+  return x * x * x;
+}
+
+static double
+easeOutCubic (double x)
+{
+  return 1 - pow (1 - x, 3);
+}
+
+static double
+easeInOutCubic (double x)
+{
+  return (x < 0.5
+          ? 4 * x * x * x
+          : 1 - pow (-2 * x + 2, 3) / 2);
+}
+
+static double
+easeInQuart (double x)
+{
+  return x * x * x * x;
+}
+
+static double
+easeOutQuart (double x)
+{
+  return 1 - pow (1 - x, 4);
+}
+
+static double
+easeInOutQuart (double x)
+{
+  return (x < 0.5
+          ? 8 * x * x * x * x
+          : 1 - pow (-2 * x + 2, 4) / 2);
+}
+
+static double
+easeInQuint (double x)
+{
+  return x * x * x * x * x;
+}
+
+static double
+easeOutQuint (double x)
+{
+  return 1 - pow(1 - x, 5);
+}
+
+static double
+easeInOutQuint (double x)
+{
+  return (x < 0.5
+          ? 16 * x * x * x * x * x
+          : 1 - pow (-2 * x + 2, 5) / 2);
+}
+
+static double
+easeInExpo (double x)
+{
+  return x == 0 ? 0 : pow (2, 10 * x - 10);
+}
+
+static double
+easeOutExpo (double x)
+{
+  return x == 1 ? 1 : 1 - pow (2, -10 * x);
+}
+
+static double
+easeInOutExpo (double x)
+{
+  return (x == 0 ? 0 :
+          x == 1 ? 1 :
+          x < 0.5
+          ? pow (2, 20 * x - 10) / 2
+          : (2 - pow(2, -20 * x + 10)) / 2);
+}
+
+static double
+easeInCirc (double x)
+{
+  return 1 - sqrt (1 - pow(x, 2));
+}
+
+static double
+easeOutCirc (double x)
+{
+  return sqrt (1 - pow(x - 1, 2));
+}
+
+static double
+easeInOutCirc (double x)
+{
+  return (x < 0.5
+          ? (1 - sqrt(1 - pow (2 * x, 2))) / 2
+          : (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2);
+}
+
+static double
+easeInBack (double x)
+{
+  double c1 = 1.70158;
+  double c3 = c1 + 1;
+  return c3 * x * x * x - c1 * x * x;
+}
+
+static double
+easeOutBack (double x)
+{
+  double c1 = 1.70158;
+  double c3 = c1 + 1;
+  return 1 + c3 * pow (x - 1, 3) + c1 * pow(x - 1, 2);
+}
+
+static double
+easeInOutBack (double x)
+{
+  double c1 = 1.70158;
+  double c2 = c1 * 1.525;
+  return (x < 0.5
+          ? (pow (2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
+          : (pow (2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2);
+}
+
+static double
+easeInElastic (double x)
+{
+  double c4 = (2 * M_PI) / 3;
+  return (x == 0 ? 0 :
+          x == 1 ? 1 :
+          -pow (2, 10 * x - 10) * sin ((x * 10 - 10.75) * c4));
+}
+
+static double
+easeOutElastic (double x)
+{
+  double c4 = (2 * M_PI) / 3;
+  return (x == 0 ? 0 :
+          x == 1 ? 1 :
+          pow (2, -10 * x) * sin ((x * 10 - 0.75) * c4) + 1);
+}
+
+static double
+easeInOutElastic (double x)
+{
+  double c5 = (2 * M_PI) / 4.5;
+  return (x == 0 ? 0 :
+          x == 1 ? 1 :
+          x < 0.5
+          ? -(pow (2, 20 * x - 10) * sin ((20 * x - 11.125) * c5)) / 2
+          :  (pow(2, -20 * x + 10) * sin ((20 * x - 11.125) * c5)) / 2 + 1);
+}
+
+static double
+easeOutBounce (double x)
+{
+  double n1 = 7.5625;
+  double d1 = 2.75;
+  if (x < 1 / d1) {
+    return n1 * x * x;
+  } else if (x < 2 / d1) {
+    x -= (1.5 / d1);
+    return n1 * x * x + 0.75;
+  } else if (x < 2.5 / d1) {
+    x -= (2.25 / d1);
+    return n1 * x * x + 0.9375;
+  } else {
+    x -= (2.625 / d1);
+    return n1 * x * x + 0.984375;
+  }
+}
+
+static double
+easeInBounce (double x)
+{
+  return 1 - easeOutBounce (1 - x);
+}
+
+static double
+easeInOutBounce (double x)
+{
+  return (x < 0.5
+          ? (1 - easeOutBounce (1 - 2 * x)) / 2
+          : (1 + easeOutBounce (2 * x - 1)) / 2);
+}
+
+double ease (easing_function fn, double x)
+{
+  switch (fn) {
+  case EASE_NONE:          return x;
+  case EASE_IN_SINE:       return easeInSine (x);
+  case EASE_OUT_SINE:      return easeOutSine (x);
+  case EASE_IN_OUT_SINE:    return easeInOutSine (x);
+  case EASE_IN_QUAD:       return easeInQuad (x);
+  case EASE_OUT_QUAD:      return easeOutQuad (x);
+  case EASE_IN_OUT_QUAD:    return easeInOutQuad (x);
+  case EASE_IN_CUBIC:      return easeInCubic (x);
+  case EASE_OUT_CUBIC:     return easeOutCubic (x);
+  case EASE_IN_OUT_CUBIC:   return easeInOutCubic (x);
+  case EASE_IN_QUART:      return easeInQuart (x);
+  case EASE_OUT_QUART:     return easeOutQuart (x);
+  case EASE_IN_OUT_QUART:   return easeInOutQuart (x);
+  case EASE_IN_QUINT:      return easeInQuint (x);
+  case EASE_OUT_QUINT:     return easeOutQuint (x);
+  case EASE_IN_OUT_QUINT:   return easeInOutQuint (x);
+  case EASE_IN_EXPO:       return easeInExpo (x);
+  case EASE_OUT_EXPO:      return easeOutExpo (x);
+  case EASE_IN_OUT_EXPO:    return easeInOutExpo (x);
+  case EASE_IN_CIRC:       return easeInCirc (x);
+  case EASE_OUT_CIRC:      return easeOutCirc (x);
+  case EASE_IN_OUT_CIRC:    return easeInOutCirc (x);
+  case EASE_IN_BACK:       return easeInBack (x);
+  case EASE_OUT_BACK:      return easeOutBack (x);
+  case EASE_IN_OUT_BACK:    return easeInOutBack (x);
+  case EASE_IN_ELASTIC:            return easeInElastic (x);
+  case EASE_OUT_ELASTIC:    return easeOutElastic (x);
+  case EASE_IN_OUT_ELASTIC: return easeInOutElastic (x);
+  case EASE_IN_BOUNCE:     return easeInBounce (x);
+  case EASE_OUT_BOUNCE:            return easeOutBounce (x);
+  case EASE_IN_OUT_BOUNCE:  return easeInOutBounce (x);
+  default:                  abort();
+  }
+}
diff --git a/utils/easing.h b/utils/easing.h
new file mode 100644 (file)
index 0000000..d26192a
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright © 2025 Jamie Zawinski <jwz@jwz.org>
+ * Easing functions.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#ifndef __EASING_H__
+#define __EASING_H__
+
+typedef enum { 
+  EASE_NONE,
+  EASE_IN_SINE,   EASE_OUT_SINE,     EASE_IN_OUT_SINE,
+  EASE_IN_QUAD,    EASE_OUT_QUAD,    EASE_IN_OUT_QUAD,
+  EASE_IN_CUBIC,   EASE_OUT_CUBIC,   EASE_IN_OUT_CUBIC,
+  EASE_IN_QUART,   EASE_OUT_QUART,   EASE_IN_OUT_QUART,
+  EASE_IN_QUINT,   EASE_OUT_QUINT,   EASE_IN_OUT_QUINT,
+  EASE_IN_EXPO,    EASE_OUT_EXPO,    EASE_IN_OUT_EXPO,
+  EASE_IN_CIRC,    EASE_OUT_CIRC,    EASE_IN_OUT_CIRC,
+  EASE_IN_BACK,    EASE_OUT_BACK,    EASE_IN_OUT_BACK,
+  EASE_IN_ELASTIC, EASE_OUT_ELASTIC, EASE_IN_OUT_ELASTIC,
+  EASE_IN_BOUNCE,  EASE_OUT_BOUNCE,  EASE_IN_OUT_BOUNCE
+} easing_function;
+
+extern double ease (easing_function, double);
+
+#endif /* __EASING_H__ */
index 67c386ea478fb26bc8f6c1c3acd9ea2d9ff87fa9..ba8f92c4a9a9f78cdc1f318312a462032fc04bc4 100644 (file)
@@ -1,5 +1,5 @@
 /* erase.c: Erase the screen in various more or less interesting ways.
- * Copyright (c) 1997-2008 Jamie Zawinski <jwz@jwz.org>
+ * Copyright © 1997-2025 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
@@ -20,6 +20,7 @@
 #include "usleep.h"
 #include "resources.h"
 #include "erase.h"
+#include "doubletime.h"
 #include <sys/time.h> /* for gettimeofday() */
 
 extern char *progname;
@@ -59,21 +60,6 @@ struct eraser_state {
 };
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 static void
 random_lines (eraser_state *st)
 {
index 561d4ba348053283b3a3750c2b7704210514e9f8..661ea26c4f0840ca3f926f143a5bde5b3491ac72 100644 (file)
 #ifdef HAVE_SYS_WAIT_H
 # include <sys/wait.h>         /* for waitpid() and associated macros */
 #endif
+#ifdef HAVE_GETXATTR
+# include <sys/xattr.h>
+#endif
 
 
 extern char *progname;
@@ -243,7 +246,7 @@ get_name_from_xprops (Display *dpy, Window window)
   int format;
   unsigned long nitems, bytesafter;
   unsigned char *name = 0;
-  Atom atom = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_FILENAME, False);
+  Atom atom = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_TITLE, False);
   if (XGetWindowProperty (dpy, window, atom,
                           0, 1024, False, XA_STRING,
                           &type, &format, &nitems, &bytesafter,
@@ -251,8 +254,17 @@ get_name_from_xprops (Display *dpy, Window window)
       == Success
       && type != None)
     return (char *) name;
-  else
-    return 0;
+
+  atom = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_FILENAME, False);
+  if (XGetWindowProperty (dpy, window, atom,
+                          0, 1024, False, XA_STRING,
+                          &type, &format, &nitems, &bytesafter,
+                          &name)
+      == Success
+      && type != None)
+    return (char *) name;
+
+  return 0;
 }
 
 
@@ -577,6 +589,40 @@ open_image_name_pipe (const char *dir)
 }
 
 
+/* Returns the URL and title of the given file, if present in xattrs.
+   Duplicated in xscreensaver-getimage.c.
+ */
+static void
+get_file_xattrs (const char *file, char **urlP, char **titleP)
+{
+# ifdef HAVE_GETXATTR
+
+#  ifdef XATTR_ADDITIONAL_OPTIONS
+#   define GETXATTR(F,K,B,S) getxattr (F, K, B, S, 0, 0)
+#  else
+#   define GETXATTR(F,K,B,S) getxattr (F, K, B, S)
+#  endif
+
+  char url[1024], title[1024];
+  ssize_t s;
+
+  s = GETXATTR (file, "user.xdg.origin.url", url, sizeof(url)-1);
+  if (s > 0)
+    {
+      url[s] = 0;
+      *urlP = strdup (url);
+    }
+
+  s = GETXATTR (file, "user.dublincore.title", title, sizeof(title)-1);
+  if (s > 0)
+    {
+      title[s] = 0;
+      *titleP = strdup (title);
+    }
+# endif /* HAVE_GETXATTR */
+}
+
+
 static void
 xscreensaver_getimage_file_cb (XtPointer closure, int *source, XtInputId *id)
 {
@@ -587,6 +633,8 @@ xscreensaver_getimage_file_cb (XtPointer closure, int *source, XtInputId *id)
   const char *dir = clo2->directory;
   char *absfile = 0;
   int i = 0;
+  char *xattr_url   = 0;
+  char *xattr_title = 0;
 
   *buf = 0;
   do {
@@ -650,20 +698,24 @@ xscreensaver_getimage_file_cb (XtPointer closure, int *source, XtInputId *id)
     geom.height = h;
   }
 
-  /* Take the extension off of the file name. */
-  /* Duplicated in driver/xscreensaver-getimage.c. */
-  if (*buf)
+  get_file_xattrs ((absfile ? absfile : buf), &xattr_url, &xattr_title);
+  if (xattr_title)
+    sprintf (buf, "%.100s", xattr_title);
+  else if (xattr_url)
+    sprintf (buf, "%.100s", xattr_url);
+  else if (*buf)
     {
+      /* Take the extension off of the file name. */
+      /* Duplicated in driver/xscreensaver-getimage.c. */
       char *slash = strrchr (buf, '/');
       char *dot = strrchr ((slash ? slash : buf), '.');
       if (dot) *dot = 0;
-      /* Replace slashes with newlines */
-      /* while (dot = strchr(buf, '/')) *dot = '\n'; */
-      /* Replace slashes with spaces */
-      /* while ((dot = strchr(buf, '/'))) *dot = ' '; */
     }
 
-  if (absfile) free (absfile);
+  if (xattr_title) free (xattr_title);
+  if (xattr_url)   free (xattr_url);
+  if (absfile)     free (absfile);
+
   clo2->callback (clo2->screen, clo2->window, clo2->drawable, buf, &geom,
                   clo2->closure);
   clo2->callback = 0;
index 2b8a65ec65e5f8e55ee9859f9995124fa54cbd4b..1edbbe6e4cfdaf2ebb7c72a9e13ab5137547a45b 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright © 1992-2022 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 1992-2025 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
@@ -65,6 +65,7 @@ extern async_load_state *load_image_async_simple (async_load_state *,
 /* Don't use these: this is how "xscreensaver-getimage" and "grabclient.c"
    pass the file name around. */
 #define XA_XSCREENSAVER_IMAGE_FILENAME "_SCREENSAVER_IMAGE_FILENAME"
+#define XA_XSCREENSAVER_IMAGE_TITLE    "_SCREENSAVER_IMAGE_TITLE"
 #define XA_XSCREENSAVER_IMAGE_GEOMETRY "_SCREENSAVER_IMAGE_GEOMETRY"
 
 #ifdef HAVE_JWXYZ
index b51784b49f0ff23e946249e656f24c6b1bb8c3b7..1e010aab57a4025a3eabfafe2eda2d7e744bae85 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "screenshot.h"
 #include "visual.h"
+#include "doubletime.h"
 #include "../driver/blurb.h"
 
 #if defined(__APPLE__) && !defined(HAVE_COCOA)
@@ -85,21 +86,6 @@ ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
 }
 
 
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-
-
 /* Grab a screenshot and return it.
    It will be the size and extent of the given window,
    or the full screen, as requested.
index ee96f93e05235c017c8faee3b82dadaa74c7f26c..584d51cbe370ebf5eeef1f239295f94f17e8e025 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright © 2014-2024 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 2014-2025 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
@@ -816,6 +816,11 @@ main (int argc, char **argv)
       URC URC URC URC URC URC URC URC URC URC URC URC URC URC URC URC URC
       URC URC URC URC URC URC URC URC URC URC URC URC URC URC URC URC URC
       URC URC URC URC URC URC URC URC URC URC URC URC },
+
+    { "7.0", /* RFC 9839 */
+        /* "\u0089\uDEAD\uD9BF\uDFFF" */
+        "\211\355\272\255\355\246\277\355\277\277",
+        URC URC URC URC },
   };
 
   int i;
index fb37b051245fcd9aa3cad43b17c39449a7d58860..03fc4050e9f2a7161f6dce4d274043e0b6ca67cf 100644 (file)
@@ -1,4 +1,4 @@
 static const char screensaver_id[] =
-       "@(#)xscreensaver 6.12 (07-Jul-2025), by Jamie Zawinski (jwz@jwz.org)";
-#define XSCREENSAVER_VERSION "6.12"
-#define XSCREENSAVER_RELEASED 1751914800
+       "@(#)xscreensaver 6.13 (02-Dec-2025), by Jamie Zawinski (jwz@jwz.org)";
+#define XSCREENSAVER_VERSION "6.13"
+#define XSCREENSAVER_RELEASED 1764705600
index 6b394298d98767c81dd615cf6721164661421469..8f4135d4ffa1a8d7d8f0365c8a2314cd53264b1e 100644 (file)
@@ -58,9 +58,27 @@ get_gl_visual (Screen *screen)
   EGLConfig egl_config = 0;
   int egl_major = -1, egl_minor = -1;
 
+  /* If you pass in a non-NULL EGLAttrib list to eglGetPlatformDisplay --
+     even one with no elements, that is, the single terminator { EGL_NONE } --
+     you get the error, "no matching EGL config for X11 visual 0x21".
+     So it is impossible for us to inform EGL which X11 screen number
+     is in use, for any weirdos still using Zaphod multi-head.
+   */
+# if 1
+  EGLAttrib *av = NULL;
+# else
+  EGLAttrib av[10];
+  int ac = 0;
+#  ifdef EGL_PLATFORM_X11_SCREEN_KHR
+  av[ac++] = EGL_PLATFORM_X11_SCREEN_KHR;
+  av[ac++] = (EGLAttrib) screen_number (screen);
+#  endif
+  av[ac] = EGL_NONE;
+#endif
+
   /* This is re-used, no need to close it. */
-  egl_display = eglGetPlatformDisplay (EGL_PLATFORM_X11_KHR,
-                                       (void *) dpy, NULL);
+  egl_display = eglGetPlatformDisplay (EGL_PLATFORM_X11_KHR, (void *) dpy, av);
+
   if (!egl_display)
     {
       fprintf (stderr, "%s: eglGetPlatformDisplay failed\n", progname);
index afbb91199704f000015bff53122a31b33801387e..05681bdf5d19c75b1bb0705ce248a022b5eacdb3 100644 (file)
@@ -1,5 +1,5 @@
 %define        name xscreensaver
-%define        version 6.12
+%define        version 6.13
 
 Summary:       X screen saver and locker
 Name:          %{name}
@@ -33,7 +33,7 @@ BuildRequires:        libXxf86vm-devel
 BuildRequires: xorg-x11-proto-devel
 BuildRequires: mesa-libGL-devel
 BuildRequires: mesa-libGLU-devel
-#BuildRequires:        libgle-devel
+BuildRequires: libgle-devel
 BuildRequires: pam-devel
 BuildRequires: systemd-devel
 BuildRequires: gtk3-devel
@@ -50,6 +50,8 @@ Requires: /etc/pam.d/system-auth
 #Requires: desktop-backgrounds-basic
 Requires: xdg-utils
 Requires: systemd-libs
+Requires: perl
+Requires: (attr or xattr)
 
 Provides: xscreensaver