diff --git a/Makefile.in b/Makefile.in index df7843b08..fbac48c60 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 '*' diff --git a/OSX/Randomizer.plist b/OSX/Randomizer.plist index 4be914739..e00b03381 100644 --- a/OSX/Randomizer.plist +++ b/OSX/Randomizer.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.12 + 6.13 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,12 +25,12 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.12 + 6.13 CFBundleLongVersionString - 6.12 + 6.13 CFBundleGetInfoString - 6.12 + 6.13 NSHumanReadableCopyright - 6.12 + 6.13 diff --git a/OSX/SaverRunner.plist b/OSX/SaverRunner.plist index 5018dfafa..3c5a81eab 100644 --- a/OSX/SaverRunner.plist +++ b/OSX/SaverRunner.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.12 + 6.13 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,13 +25,13 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.12 + 6.13 CFBundleLongVersionString - 6.12 + 6.13 CFBundleGetInfoString - 6.12 + 6.13 NSHumanReadableCopyright - 6.12 + 6.13 NSMainNibFile SaverRunner CFBundleIconFile diff --git a/OSX/Updater.plist b/OSX/Updater.plist index 3e748a277..c0428c10d 100644 --- a/OSX/Updater.plist +++ b/OSX/Updater.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.12 + 6.13 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,13 +25,13 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.12 + 6.13 CFBundleLongVersionString - 6.12 + 6.13 CFBundleGetInfoString - 6.12 + 6.13 NSHumanReadableCopyright - 6.12 + 6.13 NSMainNibFile Updater CFBundleIconFile diff --git a/OSX/XScreenSaver.plist b/OSX/XScreenSaver.plist index ff8702054..b3d7ebf00 100644 --- a/OSX/XScreenSaver.plist +++ b/OSX/XScreenSaver.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.12 + 6.13 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,13 +25,13 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.12 + 6.13 CFBundleLongVersionString - 6.12 + 6.13 CFBundleGetInfoString - 6.12 + 6.13 NSHumanReadableCopyright - 6.12 + 6.13 NSMainNibFile SaverRunner diff --git a/OSX/bindist.rtf b/OSX/bindist.rtf index 3c249e870..285904858 100644 --- a/OSX/bindist.rtf +++ b/OSX/bindist.rtf @@ -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 diff --git a/OSX/iSaverRunner.plist b/OSX/iSaverRunner.plist index 12df7001b..20fde0973 100644 --- a/OSX/iSaverRunner.plist +++ b/OSX/iSaverRunner.plist @@ -17,17 +17,17 @@ CFBundleSignature ???? CFBundleVersion - 6.12 + 6.13 LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.12 + 6.13 CFBundleLongVersionString - 6.12 + 6.13 CFBundleGetInfoString - 6.12 + 6.13 NSHumanReadableCopyright - 6.12 + 6.13 NSMainNibFile iSaverRunner CFBundleDisplayName diff --git a/OSX/tvSaverRunner.plist b/OSX/tvSaverRunner.plist index 5ccbe808d..14cbc742c 100644 --- a/OSX/tvSaverRunner.plist +++ b/OSX/tvSaverRunner.plist @@ -17,17 +17,17 @@ CFBundleSignature ???? CFBundleVersion - 6.12 + 6.13 LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.12 + 6.13 CFBundleLongVersionString - 6.12 + 6.13 CFBundleGetInfoString - 6.12 + 6.13 NSHumanReadableCopyright - 6.12 + 6.13 CFBundleDisplayName ${PRODUCT_NAME} CFBundleIcons diff --git a/OSX/updates.xml b/OSX/updates.xml index 1971a9a15..3af125cbf 100644 --- a/OSX/updates.xml +++ b/OSX/updates.xml @@ -7,6 +7,17 @@ https://www.jwz.org/xscreensaver/updates.xml Updates to xscreensaver. en + + Version 6.13 + https://www.jwz.org/xscreensaver/xscreensaver-6.13.dmg + • 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). ]]>
+ Tue, 02 Dec 2025 17:09:25 -0800 + +
Version 6.10 https://www.jwz.org/xscreensaver/xscreensaver-6.10.dmg diff --git a/OSX/xscreensaver.xcodeproj/project.pbxproj b/OSX/xscreensaver.xcodeproj/project.pbxproj index 7d6d4b603..17bcfed70 100644 --- a/OSX/xscreensaver.xcodeproj/project.pbxproj +++ b/OSX/xscreensaver.xcodeproj/project.pbxproj @@ -1657,6 +1657,12 @@ 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 */; }; @@ -9046,6 +9052,8 @@ 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 = ""; }; AF2D8F311CEBA10300198014 /* jwxyz-timers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "jwxyz-timers.h"; path = "../jwxyz/jwxyz-timers.h"; sourceTree = ""; }; + AF2DBDFD2EDE7D1D008774B9 /* easing.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = easing.c; path = utils/easing.c; sourceTree = ""; }; + AF2DBE012EDE97C1008774B9 /* doubletime.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = doubletime.c; path = utils/doubletime.c; sourceTree = ""; }; 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 = ""; }; AF32D9FC0F3AD1330080F535 /* rubikblocks.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = rubikblocks.xml; sourceTree = ""; }; @@ -15373,6 +15381,8 @@ 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 */, @@ -31000,6 +31010,7 @@ 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 */, @@ -31020,6 +31031,7 @@ 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 */, @@ -31252,6 +31264,7 @@ 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 */, @@ -31337,6 +31350,7 @@ 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 */, @@ -32062,6 +32076,7 @@ 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 */, @@ -32147,6 +32162,7 @@ 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 */, @@ -41867,6 +41883,8 @@ "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", @@ -41984,6 +42002,8 @@ "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 9fc2c3151..4199de03d 100644 --- 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. diff --git a/aclocal.m4 b/aclocal.m4 index 02e15a036..7f1f48d39 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -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, diff --git a/android/xscreensaver/jni/Android.mk b/android/xscreensaver/jni/Android.mk index 28e0e1a16..92f906629 100644 --- a/android/xscreensaver/jni/Android.mk +++ b/android/xscreensaver/jni/Android.mk @@ -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 \ diff --git a/config.h.in b/config.h.in index 94f888e12..af949bb50 100644 --- a/config.h.in +++ b/config.h.in @@ -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 @@ -385,6 +388,9 @@ 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 diff --git a/configure b/configure index 894999ee2..871581edd 100755 --- 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 +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 " 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. diff --git a/configure.ac b/configure.ac index 423ea450d..e49200f4e 100644 --- a/configure.ac +++ b/configure.ac @@ -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 or 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 ], + [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 ]) 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 index 000000000..17172a964 --- /dev/null +++ b/debian/README @@ -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 index 000000000..927b6d57c --- /dev/null +++ b/debian/changelog @@ -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 Mon, 11 Aug 2025 16:28:39 -0700 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..860266f75 --- /dev/null +++ b/debian/control @@ -0,0 +1,57 @@ +Source: xscreensaver +Section: x11 +Priority: optional +Maintainer: Jamie Zawinski +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 index 000000000..110285d3a --- /dev/null +++ b/debian/copyright @@ -0,0 +1,15 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: XScreenSaver +Upstream-Contact: Jamie Zawinski +Source: https://www.jwz.org/xscreensaver/ + +Files: * +Copyright: 1991-2025 Jamie Zawinski +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 index 000000000..66c58a8ce --- /dev/null +++ b/debian/docs @@ -0,0 +1,2 @@ +README +README.hacking diff --git a/debian/postinst b/debian/postinst new file mode 100755 index 000000000..59b225450 --- /dev/null +++ b/debian/postinst @@ -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 index 000000000..be913067a --- /dev/null +++ b/debian/prerm @@ -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 index 000000000..1ec5bc89f --- /dev/null +++ b/debian/rules @@ -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 index 000000000..163aaf8d8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/watch b/debian/watch new file mode 100644 index 000000000..a1355c88e --- /dev/null +++ b/debian/watch @@ -0,0 +1,2 @@ +version=4 +https://www.jwz.org/xscreensaver/download.html xscreensaver-(.*)\.tar\.gz diff --git a/driver/Makefile.in b/driver/Makefile.in index a013b82db..dc7e56661 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -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 diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in index 6abaef220..115900d75 100644 --- a/driver/XScreenSaver.ad.in +++ b/driver/XScreenSaver.ad.in @@ -4,8 +4,8 @@ ! a screen saver and locker for the X window system ! by Jamie Zawinski ! -! version 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/ @@ -98,8 +98,10 @@ ! 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. diff --git a/driver/XScreenSaver_ad.h b/driver/XScreenSaver_ad.h index 420a474a4..df1c16987 100644 --- a/driver/XScreenSaver_ad.h +++ b/driver/XScreenSaver_ad.h @@ -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", diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c index 6f0727da0..9ab785d13 100644 --- a/driver/demo-Gtk.c +++ b/driver/demo-Gtk.c @@ -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); diff --git a/driver/dialog.c b/driver/dialog.c index 7b4336741..d89ebb742 100644 --- a/driver/dialog.c +++ b/driver/dialog.c @@ -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; diff --git a/driver/fade.c b/driver/fade.c index c28989401..3674c1f41 100644 --- a/driver/fade.c +++ b/driver/fade.c @@ -113,6 +113,7 @@ #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 index 000000000..d7808d622 --- /dev/null +++ b/driver/test-wayland-lock.c @@ -0,0 +1,160 @@ +/* test-wayland-lock.c --- test harness for ext-session-lock-v1 + * xscreensaver, Copyright © 2025 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include + +#include +#include + +#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); + } +} diff --git a/driver/wayland-dpms.c b/driver/wayland-dpms.c index 536a86b24..61dcdaf16 100644 --- a/driver/wayland-dpms.c +++ b/driver/wayland-dpms.c @@ -23,6 +23,13 @@ * 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; } diff --git a/driver/wayland-dpy.c b/driver/wayland-dpy.c index db5c922ec..fdf760477 100644 --- a/driver/wayland-dpy.c +++ b/driver/wayland-dpy.c @@ -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); diff --git a/driver/wayland-dpy.h b/driver/wayland-dpy.h index 585dce072..9f9cf4eaf 100644 --- a/driver/wayland-dpy.h +++ b/driver/wayland-dpy.h @@ -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); diff --git a/driver/wayland-idle.c b/driver/wayland-idle.c index 734e35ebc..9c503da7c 100644 --- a/driver/wayland-idle.c +++ b/driver/wayland-idle.c @@ -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 index 000000000..9ddb00d60 --- /dev/null +++ b/driver/wayland-lock.h @@ -0,0 +1,41 @@ +/* xscreensaver, Copyright © 2025 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifndef __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 index 000000000..994977a22 --- /dev/null +++ b/driver/wayland-protocols/ext-session-lock-v1-client-protocol.h @@ -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 +#include +#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 + *
+ *
+ * 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.
+ * 
+ */ +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 index 000000000..b5f80c1b6 --- /dev/null +++ b/driver/wayland-protocols/ext-session-lock-v1-protocol.c @@ -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 +#include +#include +#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 index 000000000..19c12d26c --- /dev/null +++ b/driver/wayland-protocols/ext-session-lock-v1.xml @@ -0,0 +1,328 @@ + + + + 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. + + + + 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. + + + + + This interface is used to request that the session be locked. + + + + + This informs the compositor that the session lock manager object will + no longer be used. Existing objects created through this interface + remain valid. + + + + + + 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. + + + + + + + + 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. + + + + + + + + + + + + + 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. + + + + + + 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. + + + + + + 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. + + + + + + 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. + + + + + + + + + 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. + + + + + + + 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. + + + + + + + + + + + + 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. + + + + + + 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. + + + + + + + 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. + + + + + + + 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 index db577563a..000000000 --- a/driver/wayland-protocols/xdg-shell-v1-client-protocol.h +++ /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 -#include -#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 - *
- *
- * 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.
- * 
- */ -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 index 4faed8df2..000000000 --- a/driver/wayland-protocols/xdg-shell-v1-protocol.c +++ /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 -#include -#include -#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 index c4d4685a3..000000000 --- a/driver/wayland-protocols/xdg-shell.xml +++ /dev/null @@ -1,1415 +0,0 @@ - - - - - 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. - - - - - 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. - - - - - - - - - - - - - - - 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. - - - - - - 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. - - - - - - - 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. - - - - - - - - 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. - - - - - - - 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. - - - - - - - - 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. - - - - - - - - - Notify the compositor that the xdg_positioner will no longer be used. - - - - - - 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. - - - - - - - - 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. - - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - - - - - - - - - - - - - - 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. - - - - - - - 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. - - - - Don't alter the surface position even if it is constrained on some - axis, for example partially outside the edge of an output. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - Resize the surface horizontally so that it is completely - unconstrained. - - - - - Resize the surface vertically so that it is completely unconstrained. - - - - - - - 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. - - - - - - - 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. - - - - - - - - - - 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. - - - - - - 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. - - - - - - - - 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. - - - - - - - - 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. - - - - - - - - - - - - - - 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. - - - - - - 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. - - - - - - - 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. - - - - - - - - - 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. - - - - - - - - - - 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. - - - - - - - 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. - - - - - - - - - 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. - - - - - This request destroys the role surface and unmaps the surface; - see "Unmapping" behavior in interface section for details. - - - - - - - - - - - - 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. - - - - - - - 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. - - - - - - - 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/ - - - - - - - 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. - - - - - - - - - - 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. - - - - - - - - These values are used to indicate which edge of a surface - is being dragged in a resize operation. - - - - - - - - - - - - - - - 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. - - - - - - - - - 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. - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - 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. - - - - - - - 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. - - - - - - - - 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. - - - - - - - - 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. - - - - - - 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. - - - - - - 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. - - - - - - - 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). - - - - - - 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. - - - - - - 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. - - - - - - - - - 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. - - - - - - - - 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. - - - - - - - - - - - - - - - - - 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. - - - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - - - - - - 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. - - - - - - - - - - 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. - - - - - - - - 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. - - - - - - - - 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. - - - - - - diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index b0c637e3a..d60b5d0e3 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -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 { diff --git a/hacks/Makefile.in b/hacks/Makefile.in index 38aebd07a..b0825b1c3 100644 --- a/hacks/Makefile.in +++ b/hacks/Makefile.in @@ -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 diff --git a/hacks/ansi-tty.c b/hacks/ansi-tty.c index 5e506ab38..231251d67 100644 --- a/hacks/ansi-tty.c +++ b/hacks/ansi-tty.c @@ -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 */ diff --git a/hacks/binaryhorizon.man b/hacks/binaryhorizon.man index b909925d7..0ef51b00a 100644 --- a/hacks/binaryhorizon.man +++ b/hacks/binaryhorizon.man @@ -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] diff --git a/hacks/bsod.c b/hacks/bsod.c index c46cd8d1b..3b25d5636 100644 --- a/hacks/bsod.c +++ b/hacks/bsod.c @@ -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; } diff --git a/hacks/celtic.man b/hacks/celtic.man index a0218c1af..02ce3f5d8 100644 --- a/hacks/celtic.man +++ b/hacks/celtic.man @@ -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] diff --git a/hacks/config/README b/hacks/config/README index 1177e6c40..b6591e938 100644 --- a/hacks/config/README +++ b/hacks/config/README @@ -4,8 +4,8 @@ a screen saver and locker for the X window system by Jamie Zawinski - version 6.12 - 07-Jul-2025 + version 6.13 + 02-Dec-2025 https://www.jwz.org/xscreensaver/ diff --git a/hacks/config/endgame.xml b/hacks/config/endgame.xml index a5cdc53ec..117094659 100644 --- a/hacks/config/endgame.xml +++ b/hacks/config/endgame.xml @@ -13,12 +13,13 @@ + <_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. diff --git a/hacks/config/glslideshow.xml b/hacks/config/glslideshow.xml index ae615e8b9..b061b0318 100644 --- a/hacks/config/glslideshow.xml +++ b/hacks/config/glslideshow.xml @@ -8,36 +8,44 @@
- - - - - - - - - + + + + + + + + + + + + - - - +
+ + + +
@@ -47,9 +55,16 @@
<_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. diff --git a/hacks/droste.c b/hacks/droste.c index 0a5631a74..08478fdc4 100644 --- a/hacks/droste.c +++ b/hacks/droste.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright © 2023 Jamie Zawinski +/* xscreensaver, Copyright © 2023-2025 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 @@ -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, diff --git a/hacks/eruption.man b/hacks/eruption.man index 598269baa..553c2e783 100644 --- a/hacks/eruption.man +++ b/hacks/eruption.man @@ -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] diff --git a/hacks/ffmpeg-out.c b/hacks/ffmpeg-out.c index c3e94153a..e894e9b07 100644 --- a/hacks/ffmpeg-out.c +++ b/hacks/ffmpeg-out.c @@ -51,6 +51,12 @@ # 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 */ diff --git a/hacks/filmleader.c b/hacks/filmleader.c index 454b91d0e..3250d3b1a 100644 --- a/hacks/filmleader.c +++ b/hacks/filmleader.c @@ -1,4 +1,4 @@ -/* filmleader, Copyright (c) 2018-2019 Jamie Zawinski +/* filmleader, Copyright © 2018-2025 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 @@ -13,6 +13,7 @@ #include "screenhack.h" #include "analogtv.h" +#include "doubletime.h" #include @@ -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) { diff --git a/hacks/fonts/Makefile.in b/hacks/fonts/Makefile.in index 7e272c856..2ba4b90f7 100644 --- a/hacks/fonts/Makefile.in +++ b/hacks/fonts/Makefile.in @@ -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 index aee7c3576..000000000 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 index 000000000..1af343c52 --- /dev/null +++ b/hacks/fonts/gallant12x22-bsd.c @@ -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, /* .***........ */ +}; diff --git a/hacks/glx/Makefile.in b/hacks/glx/Makefile.in index d6b7dc939..08e0f0711 100644 --- a/hacks/glx/Makefile.in +++ b/hacks/glx/Makefile.in @@ -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 diff --git a/hacks/glx/atunnel.man b/hacks/glx/atunnel.man index 43b8da4b1..785260ae8 100644 --- a/hacks/glx/atunnel.man +++ b/hacks/glx/atunnel.man @@ -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] diff --git a/hacks/glx/beats.man b/hacks/glx/beats.man index 5543403b5..147b3fada 100644 --- a/hacks/glx/beats.man +++ b/hacks/glx/beats.man @@ -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] diff --git a/hacks/glx/carousel.c b/hacks/glx/carousel.c index d265e6f80..901cda2f1 100644 --- a/hacks/glx/carousel.c +++ b/hacks/glx/carousel.c @@ -1,4 +1,4 @@ -/* carousel, Copyright © 2005-2023 Jamie Zawinski +/* carousel, Copyright © 2005-2025 Jamie Zawinski * 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); } diff --git a/hacks/glx/chessgames.h b/hacks/glx/chessgames.h index 28f5c5707..a93015e53 100644 --- a/hacks/glx/chessgames.h +++ b/hacks/glx/chessgames.h @@ -15,329 +15,1202 @@ #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__ */ diff --git a/hacks/glx/chompytower.c b/hacks/glx/chompytower.c index 057f09480..73da06f09 100644 --- a/hacks/glx/chompytower.c +++ b/hacks/glx/chompytower.c @@ -1,4 +1,4 @@ -/* chompytower, Copyright © 2022 Jamie Zawinski +/* chompytower, Copyright © 2022-2025 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 @@ -43,6 +43,8 @@ #include "spline.h" #include "gltrackball.h" #include "gllist.h" +#include "easing.h" +#include "doubletime.h" #include 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; diff --git a/hacks/glx/crumbler.c b/hacks/glx/crumbler.c index fccee8de6..132ecb673 100644 --- a/hacks/glx/crumbler.c +++ b/hacks/glx/crumbler.c @@ -1,4 +1,4 @@ -/* crumbler, Copyright (c) 2018 Jamie Zawinski +/* crumbler, Copyright © 2018-2025 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 @@ -21,6 +21,7 @@ #include "rotator.h" #include "quickhull.h" #include "gltrackball.h" +#include "easing.h" #include #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); diff --git a/hacks/glx/cubestack.c b/hacks/glx/cubestack.c index ef62ab414..e38741374 100644 --- a/hacks/glx/cubestack.c +++ b/hacks/glx/cubestack.c @@ -1,4 +1,4 @@ -/* cubestack, Copyright (c) 2016 Jamie Zawinski +/* cubestack, Copyright © 2016-2025 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 @@ -20,6 +20,7 @@ #include "colors.h" #include "rotator.h" #include "gltrackball.h" +#include "easing.h" #include #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; \ diff --git a/hacks/glx/cubetwist.c b/hacks/glx/cubetwist.c index eed1901c7..fdaea8ad0 100644 --- a/hacks/glx/cubetwist.c +++ b/hacks/glx/cubetwist.c @@ -1,4 +1,4 @@ -/* cubetwist, Copyright (c) 2016-2017 Jamie Zawinski +/* cubetwist, Copyright © 2016-2025 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 @@ -20,6 +20,7 @@ #include "normals.h" #include "rotator.h" #include "gltrackball.h" +#include "easing.h" #include #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; diff --git a/hacks/glx/cubocteversion.man b/hacks/glx/cubocteversion.man index ab65d3895..f25ce1739 100644 --- a/hacks/glx/cubocteversion.man +++ b/hacks/glx/cubocteversion.man @@ -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] diff --git a/hacks/glx/dumpsterfire.c b/hacks/glx/dumpsterfire.c index c0392f4d0..39edc722c 100644 --- a/hacks/glx/dumpsterfire.c +++ b/hacks/glx/dumpsterfire.c @@ -34,6 +34,7 @@ #include "rotator.h" #include "gltrackball.h" #include "gllist.h" +#include "easing.h" #include #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); diff --git a/hacks/glx/dymaxionmap.c b/hacks/glx/dymaxionmap.c index 35e1c1504..37816b146 100644 --- a/hacks/glx/dymaxionmap.c +++ b/hacks/glx/dymaxionmap.c @@ -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); diff --git a/hacks/glx/endgame.c b/hacks/glx/endgame.c index 724af959b..2c1b7f4a1 100644 --- a/hacks/glx/endgame.c +++ b/hacks/glx/endgame.c @@ -15,16 +15,21 @@ * 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 @@ -35,183 +40,224 @@ #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(); - /* - - want to keep alpha values (alpha is involved in transition - effects of the active pieces). - - */ - 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); + /* + + want to keep alpha values (alpha is involved in transition + effects of the active pieces). + + */ + 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 diff --git a/hacks/glx/endgame.man b/hacks/glx/endgame.man index 4b20d460c..02a72dbe0 100644 --- a/hacks/glx/endgame.man +++ b/hacks/glx/endgame.man @@ -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) diff --git a/hacks/glx/esper.c b/hacks/glx/esper.c index 1302cac49..b557908c4 100644 --- a/hacks/glx/esper.c +++ b/hacks/glx/esper.c @@ -1,4 +1,4 @@ -/* esper, Copyright © 2017-2021 Jamie Zawinski +/* esper, Copyright © 2017-2025 Jamie Zawinski * 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. @@ -164,6 +164,7 @@ #include "grab-ximage.h" #include "texfont.h" +#include "doubletime.h" #ifdef HAVE_XSHM_EXTENSION # include "xshm.h" /* to get */ @@ -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) { diff --git a/hacks/glx/gibson.c b/hacks/glx/gibson.c index e90d8d25f..77ce9adc6 100644 --- a/hacks/glx/gibson.c +++ b/hacks/glx/gibson.c @@ -1,4 +1,4 @@ -/* gibson, Copyright (c) 2020-2021 Jamie Zawinski +/* gibson, Copyright © 2020-2025 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 @@ -31,6 +31,7 @@ #include "colors.h" #include "rotator.h" #include "texfont.h" +#include "easing.h" #include #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; diff --git a/hacks/glx/glhanoi.c b/hacks/glx/glhanoi.c index b54428398..415723ae3 100644 --- a/hacks/glx/glhanoi.c +++ b/hacks/glx/glhanoi.c @@ -15,6 +15,7 @@ #include #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); diff --git a/hacks/glx/glslideshow.c b/hacks/glx/glslideshow.c index 24930c8f9..2ee1c6505 100644 --- a/hacks/glx/glslideshow.c +++ b/hacks/glx/glslideshow.c @@ -1,4 +1,4 @@ -/* glslideshow, Copyright © 2003-2022 Jamie Zawinski +/* glslideshow, Copyright © 2003-2025 Jamie Zawinski * 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 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 @@ -64,19 +65,21 @@ #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 /* 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 */ diff --git a/hacks/glx/glslideshow.man b/hacks/glx/glslideshow.man index d1ab1abc2..c22698272 100644 --- a/hacks/glx/glslideshow.man +++ b/hacks/glx/glslideshow.man @@ -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. diff --git a/hacks/glx/grab-ximage.c b/hacks/glx/grab-ximage.c index defefda8d..a63b7333c 100644 --- a/hacks/glx/grab-ximage.c +++ b/hacks/glx/grab-ximage.c @@ -1,5 +1,5 @@ /* grab-ximage.c --- grab the screen to an XImage for use with OpenGL. - * xscreensaver, Copyright © 2001-2022 Jamie Zawinski + * xscreensaver, Copyright © 2001-2025 Jamie Zawinski * * Modified by Richard Weeks Copyright (c) 2020 * @@ -18,6 +18,7 @@ #include "pow2.h" #include "visual.h" #include "xshm.h" +#include "doubletime.h" #include #include @@ -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. diff --git a/hacks/glx/handsy.c b/hacks/glx/handsy.c index f03c70843..2cf1b8e53 100644 --- a/hacks/glx/handsy.c +++ b/hacks/glx/handsy.c @@ -1,4 +1,4 @@ -/* handsy, Copyright © 2018-2023 Jamie Zawinski +/* handsy, Copyright © 2018-2025 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -24,6 +24,7 @@ #include "rotator.h" #include "gltrackball.h" #include "gllist.h" +#include "doubletime.h" #include #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) { diff --git a/hacks/glx/hydrostat.c b/hacks/glx/hydrostat.c index 6ff00e843..836d22a94 100644 --- a/hacks/glx/hydrostat.c +++ b/hacks/glx/hydrostat.c @@ -1,5 +1,4 @@ -/* hydrostat, Copyright (C) 2012 by Justin Windle - * Copyright (c) 2016 Jamie Zawinski +/* hydrostat, Copyright © 2012-2025 Jamie Zawinski * * 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 @@ -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); diff --git a/hacks/glx/mapscroller.c b/hacks/glx/mapscroller.c index 659ae14a9..781b9ef9f 100644 --- a/hacks/glx/mapscroller.c +++ b/hacks/glx/mapscroller.c @@ -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); } diff --git a/hacks/glx/mirrorblob.c b/hacks/glx/mirrorblob.c index ee9717b0b..909637c39 100644 --- a/hacks/glx/mirrorblob.c +++ b/hacks/glx/mirrorblob.c @@ -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. diff --git a/hacks/glx/nakagin.c b/hacks/glx/nakagin.c index afb20a7b4..2a81d6c55 100644 --- a/hacks/glx/nakagin.c +++ b/hacks/glx/nakagin.c @@ -1,4 +1,4 @@ -/* nakagin, Copyright © 2022 Jamie Zawinski +/* nakagin, Copyright © 2022-2025 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 @@ -23,7 +23,9 @@ #include "colors.h" #include "rotator.h" #include "normals.h" +#include "easing.h" #include "gltrackball.h" +#include "doubletime.h" #include #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); diff --git a/hacks/glx/noof.man b/hacks/glx/noof.man index fbbc2c5e8..d021c7597 100644 --- a/hacks/glx/noof.man +++ b/hacks/glx/noof.man @@ -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] diff --git a/hacks/glx/polyhedra.man b/hacks/glx/polyhedra.man index 0408760f3..9ecb85d82 100644 --- a/hacks/glx/polyhedra.man +++ b/hacks/glx/polyhedra.man @@ -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 diff --git a/hacks/glx/raverhoop.c b/hacks/glx/raverhoop.c index 4a5a26a52..8d4b7adf0 100644 --- a/hacks/glx/raverhoop.c +++ b/hacks/glx/raverhoop.c @@ -1,4 +1,4 @@ -/* raverhoop, Copyright (c) 2016 Jamie Zawinski +/* raverhoop, Copyright © 2016-2025 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 @@ -22,6 +22,7 @@ #include "colors.h" #include "rotator.h" #include "gltrackball.h" +#include "easing.h" #include #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; diff --git a/hacks/glx/skulloop.c b/hacks/glx/skulloop.c index bf81bcd56..2cfa76192 100644 --- a/hacks/glx/skulloop.c +++ b/hacks/glx/skulloop.c @@ -1,4 +1,4 @@ -/* skulloop, Copyright © 2023-2024 Jamie Zawinski +/* skulloop, Copyright © 2023-2025 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 @@ -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 diff --git a/hacks/glx/sonar-icmp.c b/hacks/glx/sonar-icmp.c index 232847280..bb3e4b032 100644 --- a/hacks/glx/sonar-icmp.c +++ b/hacks/glx/sonar-icmp.c @@ -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) diff --git a/hacks/glx/sonar.c b/hacks/glx/sonar.c index 80f3fc686..0dd78e04b 100644 --- a/hacks/glx/sonar.c +++ b/hacks/glx/sonar.c @@ -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 #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) { diff --git a/hacks/glx/sphereeversion.man b/hacks/glx/sphereeversion.man index 9d7814945..a290289ca 100644 --- a/hacks/glx/sphereeversion.man +++ b/hacks/glx/sphereeversion.man @@ -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] diff --git a/hacks/glx/squirtorus.c b/hacks/glx/squirtorus.c index e5a3b4e97..0a1776d43 100644 --- a/hacks/glx/squirtorus.c +++ b/hacks/glx/squirtorus.c @@ -1,4 +1,4 @@ -/* squirtorus, Copyright (c) 2022 Jamie Zawinski +/* squirtorus, Copyright © 2022-2025 Jamie Zawinski * 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 @@ -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 */ diff --git a/hacks/glx/texfont.c b/hacks/glx/texfont.c index 8a957f191..43a4d64aa 100644 --- a/hacks/glx/texfont.c +++ b/hacks/glx/texfont.c @@ -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]; diff --git a/hacks/glx/tronbit.c b/hacks/glx/tronbit.c index 966ccf0f6..0ae98ab1f 100644 --- a/hacks/glx/tronbit.c +++ b/hacks/glx/tronbit.c @@ -1,4 +1,4 @@ -/* tronbit, Copyright (c) 2011-2014 Jamie Zawinski +/* tronbit, Copyright © 2011-2025 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 @@ -21,6 +21,7 @@ #include "sphere.h" #include "rotator.h" #include "gltrackball.h" +#include "doubletime.h" #include #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) { diff --git a/hacks/glx/unknownpleasures.c b/hacks/glx/unknownpleasures.c index 00a6052e3..edca09597 100644 --- a/hacks/glx/unknownpleasures.c +++ b/hacks/glx/unknownpleasures.c @@ -1,4 +1,4 @@ -/* unknownpleasures, Copyright © 2013-2019 Jamie Zawinski +/* unknownpleasures, Copyright © 2013-2025 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 @@ -54,6 +54,8 @@ #include "gltrackball.h" #include "ximage-loader.h" #include "grab-ximage.h" +#include "easing.h" +#include "doubletime.h" #include #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); diff --git a/hacks/glx/voronoi.c b/hacks/glx/voronoi.c index d2c3bb704..4f8e1e517 100644 --- a/hacks/glx/voronoi.c +++ b/hacks/glx/voronoi.c @@ -1,4 +1,4 @@ -/* voronoi, Copyright (c) 2007-2018 Jamie Zawinski +/* voronoi, Copyright © 2007-2025 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 @@ -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) { diff --git a/hacks/glx/xlock-gl-utils.c b/hacks/glx/xlock-gl-utils.c index 1d349206c..57c7f7b9c 100644 --- a/hacks/glx/xlock-gl-utils.c +++ b/hacks/glx/xlock-gl-utils.c @@ -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(); } diff --git a/hacks/halftone.man b/hacks/halftone.man index ca82ea434..e07043464 100644 --- a/hacks/halftone.man +++ b/hacks/halftone.man @@ -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 diff --git a/hacks/m6502.c b/hacks/m6502.c index fb9f9c202..018d53f62 100644 --- a/hacks/m6502.c +++ b/hacks/m6502.c @@ -15,6 +15,7 @@ #include "screenhack.h" #include "analogtv.h" #include "asm6502.h" +#include "doubletime.h" #include @@ -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); } - -/* - * 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) { diff --git a/hacks/m6502.man b/hacks/m6502.man index 67e75ffef..21694309c 100644 --- a/hacks/m6502.man +++ b/hacks/m6502.man @@ -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] diff --git a/hacks/metaballs.man b/hacks/metaballs.man index d9afcbbd1..85b3016ea 100644 --- a/hacks/metaballs.man +++ b/hacks/metaballs.man @@ -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. diff --git a/hacks/pong.c b/hacks/pong.c index 2415b168b..ceeedbbd7 100644 --- a/hacks/pong.c +++ b/hacks/pong.c @@ -57,6 +57,8 @@ #include "screenhack.h" #include "analogtv.h" +#include "doubletime.h" + #include #ifndef HAVE_JWXYZ # include @@ -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) { diff --git a/hacks/popsquares.man b/hacks/popsquares.man index e307edde3..c9106187f 100644 --- a/hacks/popsquares.man +++ b/hacks/popsquares.man @@ -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] diff --git a/hacks/recanim.c b/hacks/recanim.c index 7800b5d48..303d90b0f 100644 --- a/hacks/recanim.c +++ b/hacks/recanim.c @@ -1,4 +1,4 @@ -/* recanim, Copyright © 2014-2023 Jamie Zawinski +/* recanim, Copyright © 2014-2025 Jamie Zawinski * 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 diff --git a/hacks/tessellimage.c b/hacks/tessellimage.c index f16c2d87a..53b184cc5 100644 --- a/hacks/tessellimage.c +++ b/hacks/tessellimage.c @@ -1,4 +1,4 @@ -/* tessellimage, Copyright (c) 2014-2018 Jamie Zawinski +/* tessellimage, Copyright © 2014-2025 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 @@ -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) { diff --git a/hacks/vfeedback.c b/hacks/vfeedback.c index 107bfe54d..07a2a64d4 100644 --- a/hacks/vfeedback.c +++ b/hacks/vfeedback.c @@ -1,4 +1,4 @@ -/* vfeedback, Copyright (c) 2018 Jamie Zawinski +/* vfeedback, Copyright © 2018-2025 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 @@ -25,6 +25,8 @@ #include "screenhack.h" #include "analogtv.h" +#include "easing.h" +#include "doubletime.h" #include @@ -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(); diff --git a/hacks/xscreensaver-getimage-file b/hacks/xscreensaver-getimage-file index 7172247b2..5f693447a 100755 --- a/hacks/xscreensaver-getimage-file +++ b/hacks/xscreensaver-getimage-file @@ -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@]*>(.*?)@si); + if ($title) { + $title =~ s/<.*?>//gs; + $title = html_unquote ($title); + $title =~ s/^\s+|\s+$//gs; + } + # The 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); diff --git a/hacks/xscreensaver-getimage-file.man b/hacks/xscreensaver-getimage-file.man index 754e6b116..ebf1d531b 100644 --- a/hacks/xscreensaver-getimage-file.man +++ b/hacks/xscreensaver-getimage-file.man @@ -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] diff --git a/hacks/xscreensaver-getimage-video.man b/hacks/xscreensaver-getimage-video.man index 8edf5184a..f2aff6079 100644 --- a/hacks/xscreensaver-getimage-video.man +++ b/hacks/xscreensaver-getimage-video.man @@ -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] diff --git a/hacks/xscreensaver-getimage.c b/hacks/xscreensaver-getimage.c index 39eb8722a..29a2cb925 100644 --- a/hacks/xscreensaver-getimage.c +++ b/hacks/xscreensaver-getimage.c @@ -144,6 +144,10 @@ # include /* for waitpid() and associated macros */ #endif +#ifdef HAVE_GETXATTR +# include +#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); } diff --git a/hacks/xscreensaver-getimage.man b/hacks/xscreensaver-getimage.man index 155c45c80..62f019055 100644 --- a/hacks/xscreensaver-getimage.man +++ b/hacks/xscreensaver-getimage.man @@ -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 diff --git a/hacks/xscreensaver-text.man b/hacks/xscreensaver-text.man index a56387915..b20f918fd 100644 --- a/hacks/xscreensaver-text.man +++ b/hacks/xscreensaver-text.man @@ -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] diff --git a/jwxyz/jwxyz-android.c b/jwxyz/jwxyz-android.c index ad7ec554f..8523bf62b 100644 --- a/jwxyz/jwxyz-android.c +++ b/jwxyz/jwxyz-android.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright © 2016-2021 Jamie Zawinski +/* xscreensaver, Copyright © 2016-2025 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 @@ -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 diff --git a/jwxyz/jwxyz-timers.c b/jwxyz/jwxyz-timers.c index 1e81ab86a..bec5f70a8 100644 --- a/jwxyz/jwxyz-timers.c +++ b/jwxyz/jwxyz-timers.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 2006-2017 Jamie Zawinski +/* xscreensaver, Copyright © 2006-2025 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -29,6 +29,7 @@ #include #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) { diff --git a/po/Makefile.in.in b/po/Makefile.in.in index 03e816f6d..123a28a36 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -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; \ diff --git a/po/POTFILES.in b/po/POTFILES.in index d3ea9ee68..f7fd69903 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -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 index 000000000..e1a4d1423 --- /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 , 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 \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 " +msgstr "" +"Copyright © 1991-%.4s by\n" +"Jamie Zawinski " + +#: ../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 "ანემოტაქსისი" + +#.