From a117050fde3687c09ccb910599bb5b98c1d04385 Mon Sep 17 00:00:00 2001 From: Caten Date: Fri, 20 Sep 2024 21:39:48 +0800 Subject: [PATCH] Termux x11 port --- .gitmodules | 68 + android/app/CMakeLists.txt | 58 +- android/app/build.gradle | 80 ++ .../generated/java/com/termux/x11/Prefs.java | 108 ++ android/app/src/main/AndroidManifest.xml | 65 + .../com/termux/x11/ICmdEntryInterface.aidl | 8 + android/app/src/main/cpp/CMakeLists.txt | 107 ++ android/app/src/main/cpp/OpenXR-SDK | 1 + android/app/src/main/cpp/bzip2 | 1 + android/app/src/main/cpp/libepoxy | 1 + android/app/src/main/cpp/libfontenc | 1 + android/app/src/main/cpp/libtirpc | 1 + android/app/src/main/cpp/libx11 | 1 + android/app/src/main/cpp/libxau | 1 + android/app/src/main/cpp/libxcvt | 1 + android/app/src/main/cpp/libxdmcp | 1 + android/app/src/main/cpp/libxfont | 1 + android/app/src/main/cpp/libxkbfile | 1 + android/app/src/main/cpp/libxshmfence | 1 + android/app/src/main/cpp/libxtrans | 1 + android/app/src/main/cpp/lorie/InitInput.c | 283 +++++ android/app/src/main/cpp/lorie/InitOutput.c | 758 ++++++++++++ android/app/src/main/cpp/lorie/InputXKB.c | 898 ++++++++++++++ android/app/src/main/cpp/lorie/android.c | 772 ++++++++++++ android/app/src/main/cpp/lorie/clipboard.c | 579 +++++++++ android/app/src/main/cpp/lorie/dri3.c | 583 +++++++++ android/app/src/main/cpp/lorie/fbconfigs.h | 871 +++++++++++++ android/app/src/main/cpp/lorie/lorie.h | 163 +++ android/app/src/main/cpp/lorie/renderer.c | 714 +++++++++++ android/app/src/main/cpp/lorie/renderer.h | 23 + android/app/src/main/cpp/lorie/shm/LICENSE | 28 + android/app/src/main/cpp/lorie/shm/README.md | 11 + android/app/src/main/cpp/lorie/shm/shm.h | 36 + android/app/src/main/cpp/lorie/shm/shmem.c | 638 ++++++++++ android/app/src/main/cpp/patches/Xtrans.patch | 127 ++ .../app/src/main/cpp/patches/dix-config.h.in | 207 ++++ .../app/src/main/cpp/patches/libepoxy.patch | 170 +++ android/app/src/main/cpp/patches/pixman.patch | 35 + android/app/src/main/cpp/patches/x11.patch | 58 + .../app/src/main/cpp/patches/xkbcomp.patch | 1054 ++++++++++++++++ .../app/src/main/cpp/patches/xkbfile.patch | 27 + .../app/src/main/cpp/patches/xserver.patch | 208 ++++ android/app/src/main/cpp/pixman | 1 + android/app/src/main/cpp/recipes/Xau.cmake | 5 + android/app/src/main/cpp/recipes/Xdmcp.cmake | 5 + android/app/src/main/cpp/recipes/Xfont2.cmake | 70 ++ .../app/src/main/cpp/recipes/fontenc.cmake | 4 + android/app/src/main/cpp/recipes/md.cmake | 193 +++ android/app/src/main/cpp/recipes/pixman.cmake | 91 ++ android/app/src/main/cpp/recipes/tirpc.cmake | 50 + .../app/src/main/cpp/recipes/xkbcomp.cmake | 71 ++ .../app/src/main/cpp/recipes/xorgproto.cmake | 9 + .../app/src/main/cpp/recipes/xserver.cmake | 280 +++++ .../app/src/main/cpp/recipes/xshmfence.cmake | 5 + android/app/src/main/cpp/xkbcomp | 1 + android/app/src/main/cpp/xorgproto | 1 + android/app/src/main/cpp/xrio/android.c | 195 +++ android/app/src/main/cpp/xrio/engine.c | 190 +++ android/app/src/main/cpp/xrio/engine.h | 90 ++ android/app/src/main/cpp/xrio/framebuffer.c | 127 ++ android/app/src/main/cpp/xrio/framebuffer.h | 28 + android/app/src/main/cpp/xrio/input.c | 404 ++++++ android/app/src/main/cpp/xrio/input.h | 82 ++ android/app/src/main/cpp/xrio/math.c | 194 +++ android/app/src/main/cpp/xrio/math.h | 26 + android/app/src/main/cpp/xrio/renderer.c | 565 +++++++++ android/app/src/main/cpp/xrio/renderer.h | 76 ++ android/app/src/main/cpp/xserver | 1 + .../termux/extrakeys/ExtraKeyButton.java | 129 ++ .../termux/extrakeys/ExtraKeysConstants.java | 201 +++ .../termux/extrakeys/ExtraKeysInfo.java | 209 ++++ .../termux/extrakeys/ExtraKeysView.java | 573 +++++++++ .../termux/extrakeys/SpecialButton.java | 53 + .../termux/extrakeys/SpecialButtonState.java | 50 + .../java/com/termux/x11/CmdEntryPoint.java | 251 ++++ .../java/com/termux/x11/LoriePreferences.java | 810 ++++++++++++ .../main/java/com/termux/x11/LorieView.java | 381 ++++++ .../java/com/termux/x11/MainActivity.java | 910 ++++++++++++++ .../main/java/com/termux/x11/XrActivity.java | 386 ++++++ .../termux/x11/input/InputEventSender.java | 237 ++++ .../x11/input/InputStrategyInterface.java | 235 ++++ .../java/com/termux/x11/input/InputStub.java | 45 + .../java/com/termux/x11/input/RenderData.java | 56 + .../com/termux/x11/input/SwipeDetector.java | 126 ++ .../termux/x11/input/TapGestureDetector.java | 214 ++++ .../termux/x11/input/TouchInputHandler.java | 1096 +++++++++++++++++ .../x11/utils/FullscreenWorkaround.java | 63 + .../java/com/termux/x11/utils/GLUtility.java | 130 ++ .../com/termux/x11/utils/KeyInterceptor.java | 123 ++ .../com/termux/x11/utils/SamsungDexUtils.java | 55 + .../termux/x11/utils/TermuxX11ExtraKeys.java | 225 ++++ .../termux/x11/utils/X11ToolbarViewPager.java | 133 ++ .../com/example/tiny_computer/MainActivity.kt | 19 +- .../example/tiny_computer/MainApplication.kt | 7 + .../app/src/main/res/anim/slide_in_left.xml | 26 + .../app/src/main/res/anim/slide_in_right.xml | 26 + .../app/src/main/res/anim/slide_out_left.xml | 26 + .../app/src/main/res/anim/slide_out_right.xml | 26 + .../app/src/main/res/drawable/ic_x11_icon.xml | 27 + .../src/main/res/drawable/mouse_buttons.xml | 15 + .../src/main/res/layout/extra_keys_config.xml | 31 + .../src/main/res/layout/fragment_about.xml | 2 +- .../src/main/res/layout/fragment_license.xml | 6 +- .../app/src/main/res/layout/main_activity.xml | 285 +++++ .../app/src/main/res/layout/preference.xml | 113 ++ .../view_terminal_toolbar_extra_keys.xml | 8 + .../view_terminal_toolbar_text_input.xml | 26 + .../src/main/res/values-zh-rCN/strings.xml | 108 ++ android/app/src/main/res/values/arrays.xml | 83 ++ android/app/src/main/res/values/strings.xml | 111 +- .../res/xml/accessibility_service_config.xml | 9 + android/app/src/main/res/xml/preferences.xml | 76 ++ android/build.gradle | 1 + android/gradle.properties | 2 +- android/settings.gradle | 3 + android/shell-loader/stub/build.gradle | 29 + .../annotationProcessors.json | 1 + .../bundleLibCompileToJarDebug/classes.jar | Bin 0 -> 4563 bytes .../debug/generateDebugRFile/R.jar | Bin 0 -> 288 bytes .../debug/generateDebugRFile/R.txt | 0 .../compile-file-map.properties | 1 + .../debug/packageDebugResources/merger.xml | 2 + .../debug/parseDebugLocalResources/R-def.txt | 2 + .../nestedResourcesValidationReport.txt | 1 + .../generateDebugRFile/package-aware-r.txt | 1 + .../previous-compilation-data.bin | Bin 0 -> 4644 bytes .../stub/src/main/AndroidManifest.xml | 1 + .../main/java/android/app/ActivityThread.java | 17 + .../main/java/android/app/ContextImpl.java | 6 + .../java/android/app/IActivityManager.java | 13 + .../java/android/content/IIntentReceiver.java | 13 + .../java/android/content/IIntentSender.java | 12 + .../android/content/pm/IPackageManager.java | 7 + lib/main.dart | 51 +- lib/workflow.dart | 36 +- pubspec.lock | 68 +- 136 files changed, 19410 insertions(+), 92 deletions(-) create mode 100644 android/app/build/generated/java/com/termux/x11/Prefs.java create mode 100644 android/app/src/main/aidl/com/termux/x11/ICmdEntryInterface.aidl create mode 100644 android/app/src/main/cpp/CMakeLists.txt create mode 160000 android/app/src/main/cpp/OpenXR-SDK create mode 160000 android/app/src/main/cpp/bzip2 create mode 160000 android/app/src/main/cpp/libepoxy create mode 160000 android/app/src/main/cpp/libfontenc create mode 160000 android/app/src/main/cpp/libtirpc create mode 160000 android/app/src/main/cpp/libx11 create mode 160000 android/app/src/main/cpp/libxau create mode 160000 android/app/src/main/cpp/libxcvt create mode 160000 android/app/src/main/cpp/libxdmcp create mode 160000 android/app/src/main/cpp/libxfont create mode 160000 android/app/src/main/cpp/libxkbfile create mode 160000 android/app/src/main/cpp/libxshmfence create mode 160000 android/app/src/main/cpp/libxtrans create mode 100644 android/app/src/main/cpp/lorie/InitInput.c create mode 100644 android/app/src/main/cpp/lorie/InitOutput.c create mode 100644 android/app/src/main/cpp/lorie/InputXKB.c create mode 100644 android/app/src/main/cpp/lorie/android.c create mode 100644 android/app/src/main/cpp/lorie/clipboard.c create mode 100644 android/app/src/main/cpp/lorie/dri3.c create mode 100644 android/app/src/main/cpp/lorie/fbconfigs.h create mode 100644 android/app/src/main/cpp/lorie/lorie.h create mode 100644 android/app/src/main/cpp/lorie/renderer.c create mode 100644 android/app/src/main/cpp/lorie/renderer.h create mode 100644 android/app/src/main/cpp/lorie/shm/LICENSE create mode 100644 android/app/src/main/cpp/lorie/shm/README.md create mode 100644 android/app/src/main/cpp/lorie/shm/shm.h create mode 100644 android/app/src/main/cpp/lorie/shm/shmem.c create mode 100644 android/app/src/main/cpp/patches/Xtrans.patch create mode 100644 android/app/src/main/cpp/patches/dix-config.h.in create mode 100644 android/app/src/main/cpp/patches/libepoxy.patch create mode 100644 android/app/src/main/cpp/patches/pixman.patch create mode 100644 android/app/src/main/cpp/patches/x11.patch create mode 100644 android/app/src/main/cpp/patches/xkbcomp.patch create mode 100644 android/app/src/main/cpp/patches/xkbfile.patch create mode 100644 android/app/src/main/cpp/patches/xserver.patch create mode 160000 android/app/src/main/cpp/pixman create mode 100644 android/app/src/main/cpp/recipes/Xau.cmake create mode 100644 android/app/src/main/cpp/recipes/Xdmcp.cmake create mode 100644 android/app/src/main/cpp/recipes/Xfont2.cmake create mode 100644 android/app/src/main/cpp/recipes/fontenc.cmake create mode 100644 android/app/src/main/cpp/recipes/md.cmake create mode 100644 android/app/src/main/cpp/recipes/pixman.cmake create mode 100644 android/app/src/main/cpp/recipes/tirpc.cmake create mode 100644 android/app/src/main/cpp/recipes/xkbcomp.cmake create mode 100644 android/app/src/main/cpp/recipes/xorgproto.cmake create mode 100644 android/app/src/main/cpp/recipes/xserver.cmake create mode 100644 android/app/src/main/cpp/recipes/xshmfence.cmake create mode 160000 android/app/src/main/cpp/xkbcomp create mode 160000 android/app/src/main/cpp/xorgproto create mode 100644 android/app/src/main/cpp/xrio/android.c create mode 100644 android/app/src/main/cpp/xrio/engine.c create mode 100644 android/app/src/main/cpp/xrio/engine.h create mode 100644 android/app/src/main/cpp/xrio/framebuffer.c create mode 100644 android/app/src/main/cpp/xrio/framebuffer.h create mode 100644 android/app/src/main/cpp/xrio/input.c create mode 100644 android/app/src/main/cpp/xrio/input.h create mode 100644 android/app/src/main/cpp/xrio/math.c create mode 100644 android/app/src/main/cpp/xrio/math.h create mode 100644 android/app/src/main/cpp/xrio/renderer.c create mode 100644 android/app/src/main/cpp/xrio/renderer.h create mode 160000 android/app/src/main/cpp/xserver create mode 100644 android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeyButton.java create mode 100644 android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysConstants.java create mode 100644 android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysInfo.java create mode 100644 android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysView.java create mode 100644 android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButton.java create mode 100644 android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButtonState.java create mode 100644 android/app/src/main/java/com/termux/x11/CmdEntryPoint.java create mode 100644 android/app/src/main/java/com/termux/x11/LoriePreferences.java create mode 100644 android/app/src/main/java/com/termux/x11/LorieView.java create mode 100644 android/app/src/main/java/com/termux/x11/MainActivity.java create mode 100644 android/app/src/main/java/com/termux/x11/XrActivity.java create mode 100644 android/app/src/main/java/com/termux/x11/input/InputEventSender.java create mode 100644 android/app/src/main/java/com/termux/x11/input/InputStrategyInterface.java create mode 100644 android/app/src/main/java/com/termux/x11/input/InputStub.java create mode 100644 android/app/src/main/java/com/termux/x11/input/RenderData.java create mode 100644 android/app/src/main/java/com/termux/x11/input/SwipeDetector.java create mode 100644 android/app/src/main/java/com/termux/x11/input/TapGestureDetector.java create mode 100644 android/app/src/main/java/com/termux/x11/input/TouchInputHandler.java create mode 100644 android/app/src/main/java/com/termux/x11/utils/FullscreenWorkaround.java create mode 100644 android/app/src/main/java/com/termux/x11/utils/GLUtility.java create mode 100644 android/app/src/main/java/com/termux/x11/utils/KeyInterceptor.java create mode 100644 android/app/src/main/java/com/termux/x11/utils/SamsungDexUtils.java create mode 100644 android/app/src/main/java/com/termux/x11/utils/TermuxX11ExtraKeys.java create mode 100644 android/app/src/main/java/com/termux/x11/utils/X11ToolbarViewPager.java create mode 100644 android/app/src/main/res/anim/slide_in_left.xml create mode 100644 android/app/src/main/res/anim/slide_in_right.xml create mode 100644 android/app/src/main/res/anim/slide_out_left.xml create mode 100644 android/app/src/main/res/anim/slide_out_right.xml create mode 100644 android/app/src/main/res/drawable/ic_x11_icon.xml create mode 100644 android/app/src/main/res/drawable/mouse_buttons.xml create mode 100644 android/app/src/main/res/layout/extra_keys_config.xml create mode 100644 android/app/src/main/res/layout/main_activity.xml create mode 100644 android/app/src/main/res/layout/preference.xml create mode 100644 android/app/src/main/res/layout/view_terminal_toolbar_extra_keys.xml create mode 100644 android/app/src/main/res/layout/view_terminal_toolbar_text_input.xml create mode 100644 android/app/src/main/res/xml/accessibility_service_config.xml create mode 100644 android/app/src/main/res/xml/preferences.xml create mode 100644 android/shell-loader/stub/build.gradle create mode 100644 android/shell-loader/stub/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json create mode 100644 android/shell-loader/stub/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar create mode 100644 android/shell-loader/stub/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar create mode 100644 android/shell-loader/stub/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt create mode 100644 android/shell-loader/stub/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties create mode 100644 android/shell-loader/stub/build/intermediates/incremental/debug/packageDebugResources/merger.xml create mode 100644 android/shell-loader/stub/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt create mode 100644 android/shell-loader/stub/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt create mode 100644 android/shell-loader/stub/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt create mode 100644 android/shell-loader/stub/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin create mode 100644 android/shell-loader/stub/src/main/AndroidManifest.xml create mode 100644 android/shell-loader/stub/src/main/java/android/app/ActivityThread.java create mode 100644 android/shell-loader/stub/src/main/java/android/app/ContextImpl.java create mode 100644 android/shell-loader/stub/src/main/java/android/app/IActivityManager.java create mode 100644 android/shell-loader/stub/src/main/java/android/content/IIntentReceiver.java create mode 100644 android/shell-loader/stub/src/main/java/android/content/IIntentSender.java create mode 100644 android/shell-loader/stub/src/main/java/android/content/pm/IPackageManager.java diff --git a/.gitmodules b/.gitmodules index 4f81357..0cbcc36 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,71 @@ [submodule "android/extern/wolfssl"] path = android/extern/wolfssl url = https://github.com/wolfSSL/wolfssl.git +[submodule "android/app/src/main/cpp/libtirpc"] + path = android/app/src/main/cpp/libtirpc + url = https://github.com/alisw/libtirpc + ignore = dirty +[submodule "android/app/src/main/cpp/pixman"] + path = android/app/src/main/cpp/pixman + url = https://gitlab.freedesktop.org/pixman/pixman + ignore = dirty +[submodule "android/app/src/main/cpp/libfontenc"] + path = android/app/src/main/cpp/libfontenc + url = https://gitlab.freedesktop.org/xorg/lib/libfontenc + ignore = dirty +[submodule "android/app/src/main/cpp/libxau"] + path = android/app/src/main/cpp/libxau + url = https://gitlab.freedesktop.org/xorg/lib/libxau + ignore = dirty +[submodule "android/app/src/main/cpp/libxdmcp"] + path = android/app/src/main/cpp/libxdmcp + url = https://gitlab.freedesktop.org/xorg/lib/libxdmcp + ignore = dirty +[submodule "android/app/src/main/cpp/libxfont"] + path = android/app/src/main/cpp/libxfont + url = https://gitlab.freedesktop.org/xorg/lib/libxfont + ignore = dirty +[submodule "android/app/src/main/cpp/libxkbfile"] + path = android/app/src/main/cpp/libxkbfile + url = https://gitlab.freedesktop.org/xorg/lib/libxkbfile + ignore = dirty +[submodule "android/app/src/main/cpp/libxshmfence"] + path = android/app/src/main/cpp/libxshmfence + url = https://gitlab.freedesktop.org/xorg/lib/libxshmfence + ignore = dirty +[submodule "android/app/src/main/cpp/libxtrans"] + path = android/app/src/main/cpp/libxtrans + url = https://gitlab.freedesktop.org/xorg/lib/libxtrans + ignore = dirty +[submodule "android/app/src/main/cpp/libepoxy"] + path = android/app/src/main/cpp/libepoxy + url = https://github.com/anholt/libepoxy + ignore = dirty +[submodule "android/app/src/main/cpp/libxcvt"] + path = android/app/src/main/cpp/libxcvt + url = https://gitlab.freedesktop.org/xorg/lib/libxcvt + ignore = dirty +[submodule "android/app/src/main/cpp/libx11"] + path = android/app/src/main/cpp/libx11 + url = https://gitlab.freedesktop.org/xorg/lib/libx11 + ignore = dirty +[submodule "android/app/src/main/cpp/xorgproto"] + path = android/app/src/main/cpp/xorgproto + url = https://gitlab.freedesktop.org/xorg/proto/xorgproto + ignore = dirty +[submodule "android/app/src/main/cpp/xkbcomp"] + path = android/app/src/main/cpp/xkbcomp + url = https://gitlab.freedesktop.org/xorg/app/xkbcomp + ignore = dirty +[submodule "android/app/src/main/cpp/xserver"] + path = android/app/src/main/cpp/xserver + url = https://gitlab.freedesktop.org/xorg/xserver + ignore = dirty +[submodule "android/app/src/main/cpp/bzip2"] + path = android/app/src/main/cpp/bzip2 + url = https://gitlab.com/bzip2/bzip2 + ignore = dirty +[submodule "android/app/src/main/cpp/OpenXR-SDK"] + path = android/app/src/main/cpp/OpenXR-SDK + url = https://github.com/KhronosGroup/OpenXR-SDK.git + ignore = dirty diff --git a/android/app/CMakeLists.txt b/android/app/CMakeLists.txt index cc111b7..8816bf9 100644 --- a/android/app/CMakeLists.txt +++ b/android/app/CMakeLists.txt @@ -1,4 +1,3 @@ - cmake_minimum_required(VERSION 3.10) project(NativeVNC C CXX ASM) @@ -13,12 +12,10 @@ set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared Libs" FORCE) # Make sure given submodule is checked out macro(avnc_check_submodule name) if (NOT EXISTS "${AVNC_EXTERN_DIR}/${name}/CMakeLists.txt") - message(FATAL_ERROR "git submodule for ${name} is not initialized. - Please run 'git submodule update --init'.") + message(FATAL_ERROR "git submodule for ${name} is not initialized. Please run 'git submodule update --init'.") endif () endmacro() - # Required to enable SIMD support on ARM if (CMAKE_ANDROID_ARCH STREQUAL "arm64") set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} --target=aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}") @@ -26,7 +23,6 @@ elseif (CMAKE_ANDROID_ARCH STREQUAL "arm") set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} --target=arm-linux-androideabi${ANDROID_NATIVE_API_LEVEL}") endif () - ############################################################################### # JPEG ############################################################################### @@ -39,10 +35,10 @@ add_subdirectory(${AVNC_LIBJPEG_SRC_DIR} ${AVNC_LIBJPEG_BUILD_DIR}) # Set these variables so FindJPEG can find the library set(JPEG_LIBRARY ${AVNC_LIBJPEG_BUILD_DIR}/libturbojpeg.a) -set(JPEG_INCLUDE_DIR ${AVNC_LIBJPEG_SRC_DIR}) - -include_directories(${AVNC_LIBJPEG_SRC_DIR} ${AVNC_LIBJPEG_BUILD_DIR}) +# Create an interface library to manage include directories +add_library(libjpeg INTERFACE) +target_include_directories(libjpeg INTERFACE ${AVNC_LIBJPEG_SRC_DIR}) ############################################################################### # SSL @@ -63,13 +59,9 @@ add_definitions(-DOPENSSL_ALL -DOPENSSL_EXTRA -DHAVE_CRL -DHAVE_EX_DATA add_subdirectory(${AVNC_LIBSSL_SRC_DIR} ${AVNC_LIBSSL_BUILD_DIR}) -# Set these variables so FindOpenSSL can find the library -set(OPENSSL_SSL_LIBRARY ${AVNC_LIBSSL_BUILD_DIR}/libwolfssl.a) -set(OPENSSL_CRYPTO_LIBRARY ${AVNC_LIBSSL_BUILD_DIR}/libwolfssl.a) -set(OPENSSL_INCLUDE_DIR ${AVNC_LIBSSL_SRC_DIR}/wolfssl) - -include_directories(${AVNC_LIBSSL_SRC_DIR}) - +# Create an interface library to manage include directories +add_library(libssl INTERFACE) +target_include_directories(libssl INTERFACE ${AVNC_LIBSSL_SRC_DIR}/wolfssl) ############################################################################### # LibVNC @@ -78,29 +70,45 @@ avnc_check_submodule(libvncserver) set(AVNC_LIBVNC_SRC_DIR ${AVNC_EXTERN_DIR}/libvncserver) set(AVNC_LIBVNC_BUILD_DIR ${CMAKE_BINARY_DIR}/libvncserver) -set(WITH_LIBSSH2 OFF CACHE BOOL "Find LibSSH" FORCE) -add_subdirectory(${AVNC_LIBVNC_SRC_DIR} ${AVNC_LIBVNC_BUILD_DIR}) # (source dir, build dir) - -include_directories(${AVNC_LIBVNC_SRC_DIR}/include ${AVNC_LIBVNC_BUILD_DIR}/include) +add_subdirectory(${AVNC_LIBVNC_SRC_DIR} ${AVNC_LIBVNC_BUILD_DIR}) +# Create an interface library to manage include directories +add_library(libvnc INTERFACE) +target_include_directories(libvnc INTERFACE ${AVNC_LIBVNC_SRC_DIR}/include ${AVNC_LIBVNC_BUILD_DIR}/include) ############################################################################### # Native VNC # # It contains implementation of JNI native methods, some NDK scaffolding and -# some helpers for OpenGL ES rendring. This is the library loaded from Java. +# some helpers for OpenGL ES rendering. This is the library loaded from Java. ############################################################################### set(AVNC_NATIVE_SOURCE src/main/cpp/native-vnc.cpp) add_library(native-vnc SHARED ${AVNC_NATIVE_SOURCE}) -target_link_libraries(native-vnc vncclient) - +# Link libraries +target_link_libraries(native-vnc + PRIVATE + libjpeg + libssl + libvnc + vncclient +) # Link NDK libraries find_library(LIB_LOG log) -target_link_libraries(native-vnc ${LIB_LOG}) - find_library(LIB_GLES GLESv2) -target_link_libraries(native-vnc ${LIB_GLES}) + +target_link_libraries(native-vnc + PRIVATE + ${LIB_LOG} + ${LIB_GLES} +) + +############################################################################### +# Termux X11 +# +############################################################################### +set(X11_EXTERN_DIR ${PROJECT_SOURCE_DIR}/src/main/cpp) +add_subdirectory(${X11_EXTERN_DIR}) \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index b7fec47..870d374 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -55,6 +55,8 @@ android { versionCode flutterVersionCode.toInteger() versionName flutterVersionName + buildConfigField "String", "COMMIT", "\"" + ("git rev-parse HEAD\n".execute().getText().trim() ?: (System.getenv('CURRENT_COMMIT') ?: "NO_COMMIT")) + "\"" + javaCompileOptions { annotationProcessorOptions { arguments += ["room.schemaLocation": "$projectDir/roomSchema/".toString()] @@ -68,10 +70,27 @@ android { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug + // remove flutter's default ShrinkResources settings at flutter\packages\flutter_tools\gradle\src\main\flutter.groovy + postprocessing { + removeUnusedCode true + removeUnusedResources true + obfuscate false + optimizeCode true + } + } + debug { + signingConfig signingConfigs.debug + postprocessing { + removeUnusedCode true + removeUnusedResources true + obfuscate false + optimizeCode true + } } } buildFeatures { + aidl true dataBinding true buildConfig true } @@ -106,6 +125,7 @@ dependencies { implementation "androidx.fragment:fragment-ktx:1.6.2" implementation "androidx.appcompat:appcompat:1.6.1" implementation "androidx.preference:preference-ktx:1.2.1" + implementation "androidx.preference:preference:1.2.1" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2" implementation "androidx.dynamicanimation:dynamicanimation:1.0.0" @@ -122,5 +142,65 @@ dependencies { implementation "com.google.android.material:material:1.11.0" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0" implementation "org.connectbot:sshlib:2.2.23" + implementation 'com.github.tiann:FreeReflection:3.1.0' + compileOnly project(':shell-loader:stub') } + +afterEvaluate { + tasks.register("generatePrefs") { + //noinspection UnnecessaryQualifiedReference + def xml = groovy.xml.DOMBuilder.parse((new StringReader(file('src/main/res/xml/preferences.xml').text))) + def preferenceNodes = xml.documentElement.getElementsByTagName("*") + def preferences = [] + + for (int i = 0; i < preferenceNodes.length; i++) { + def node = preferenceNodes.item(i) + if (node.nodeName == 'EditTextPreference' && node.getAttribute("app:key") != "extra_keys_config") + preferences << [ type: 'String', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue") ] + else if (node.nodeName == 'SeekBarPreference') + preferences << [ type: 'Int', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue") ] + else if (node.nodeName == 'ListPreference') { + def entries = node.getAttribute("app:entries") + def values = node.getAttribute("app:entryValues") + preferences << [type: 'List', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue"), + entries: entries.substring(7, entries.length()), values: values.substring(7, values.length())] + } + else if (node.nodeName == 'SwitchPreferenceCompat') + preferences << [ type: 'Boolean', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue") ] + } + + def out = file('build/generated/java/com/termux/x11/Prefs.java') + out.getParentFile().exists() || out.getParentFile().mkdirs() + out.delete() + out.createNewFile() + + out << 'package com.termux.x11;\n' + out << 'import java.util.HashMap;\n' + out << 'import android.content.Context;\n' + out << 'import com.termux.x11.utils.TermuxX11ExtraKeys;\n' + out << 'import com.example.tiny_computer.R;\n' + out << '\n' + out << 'public class Prefs extends LoriePreferences.PrefsProto {\n' + preferences.each { + if (it.type == 'Int' || it.type == 'Boolean') + out << " public final ${it.type}Preference ${it.key} = new ${it.type}Preference(\"${it.key}\", ${it.default});\n" + else if (it.type == 'String') + out << " public final StringPreference ${it.key} = new StringPreference(\"${it.key}\", \"${it.default}\");\n" + else if (it.type == 'List') + out << " public final ${it.type}Preference ${it.key} = new ${it.type}Preference(\"${it.key}\", \"${it.default}\", R.array.${it.entries}, R.array.${it.values});\n" + } + out << ' public final StringPreference extra_keys_config = new StringPreference("extra_keys_config", TermuxX11ExtraKeys.DEFAULT_IVALUE_EXTRA_KEYS);\n' + out << ' public final HashMap keys = new HashMap() {{\n' + preferences.each { out << ' put("' + it.key + '", ' + it.key + ');\n' } + out << ' put("extra_keys_config", extra_keys_config);\n' + out << ' }};\n' + out << '\n' + out << ' public Prefs(Context ctx) {\n' + out << ' super(ctx);\n' + out << ' }\n' + out << '}\n' + } + android.sourceSets.main.java.srcDirs += 'build/generated/java' + preBuild.dependsOn generatePrefs +} \ No newline at end of file diff --git a/android/app/build/generated/java/com/termux/x11/Prefs.java b/android/app/build/generated/java/com/termux/x11/Prefs.java new file mode 100644 index 0000000..8eaf125 --- /dev/null +++ b/android/app/build/generated/java/com/termux/x11/Prefs.java @@ -0,0 +1,108 @@ +package com.termux.x11; +import java.util.HashMap; +import android.content.Context; +import com.termux.x11.utils.TermuxX11ExtraKeys; +import com.example.tiny_computer.R; + +public class Prefs extends LoriePreferences.PrefsProto { + public final ListPreference displayResolutionMode = new ListPreference("displayResolutionMode", "native", R.array.displayResolutionVariants, R.array.displayResolutionVariants); + public final IntPreference displayScale = new IntPreference("displayScale", 100); + public final ListPreference displayResolutionExact = new ListPreference("displayResolutionExact", "1280x1024", R.array.displayResolution, R.array.displayResolution); + public final StringPreference displayResolutionCustom = new StringPreference("displayResolutionCustom", "1280x1024"); + public final BooleanPreference adjustResolution = new BooleanPreference("adjustResolution", false); + public final BooleanPreference displayStretch = new BooleanPreference("displayStretch", false); + public final BooleanPreference Reseed = new BooleanPreference("Reseed", true); + public final BooleanPreference PIP = new BooleanPreference("PIP", true); + public final BooleanPreference fullscreen = new BooleanPreference("fullscreen", true); + public final ListPreference forceOrientation = new ListPreference("forceOrientation", "no", R.array.forceOrientationVariants, R.array.forceOrientationVariants); + public final BooleanPreference hideCutout = new BooleanPreference("hideCutout", false); + public final BooleanPreference keepScreenOn = new BooleanPreference("keepScreenOn", true); + public final BooleanPreference xrMode = new BooleanPreference("xrMode", false); + public final ListPreference touchMode = new ListPreference("touchMode", "1", R.array.touchscreenInputModesEntries, R.array.touchscreenInputModesValues); + public final BooleanPreference scaleTouchpad = new BooleanPreference("scaleTouchpad", true); + public final BooleanPreference showStylusClickOverride = new BooleanPreference("showStylusClickOverride", false); + public final BooleanPreference stylusIsMouse = new BooleanPreference("stylusIsMouse", false); + public final BooleanPreference stylusButtonContactModifierMode = new BooleanPreference("stylusButtonContactModifierMode", false); + public final BooleanPreference showMouseHelper = new BooleanPreference("showMouseHelper", false); + public final BooleanPreference pointerCapture = new BooleanPreference("pointerCapture", false); + public final ListPreference transformCapturedPointer = new ListPreference("transformCapturedPointer", "no", R.array.transformCapturedPointerEntries, R.array.transformCapturedPointerValues); + public final IntPreference capturedPointerSpeedFactor = new IntPreference("capturedPointerSpeedFactor", 100); + public final BooleanPreference tapToMove = new BooleanPreference("tapToMove", true); + public final BooleanPreference showAdditionalKbd = new BooleanPreference("showAdditionalKbd", true); + public final BooleanPreference additionalKbdVisible = new BooleanPreference("additionalKbdVisible", true); + public final BooleanPreference showIMEWhileExternalConnected = new BooleanPreference("showIMEWhileExternalConnected", true); + public final BooleanPreference preferScancodes = new BooleanPreference("preferScancodes", false); + public final BooleanPreference hardwareKbdScancodesWorkaround = new BooleanPreference("hardwareKbdScancodesWorkaround", true); + public final BooleanPreference dexMetaKeyCapture = new BooleanPreference("dexMetaKeyCapture", false); + public final BooleanPreference enableAccessibilityServiceAutomatically = new BooleanPreference("enableAccessibilityServiceAutomatically", false); + public final BooleanPreference pauseKeyInterceptingWithEsc = new BooleanPreference("pauseKeyInterceptingWithEsc", false); + public final BooleanPreference filterOutWinkey = new BooleanPreference("filterOutWinkey", false); + public final BooleanPreference enableGboardCJK = new BooleanPreference("enableGboardCJK", false); + public final BooleanPreference clipboardEnable = new BooleanPreference("clipboardEnable", true); + public final BooleanPreference storeSecondaryDisplayPreferencesSeparately = new BooleanPreference("storeSecondaryDisplayPreferencesSeparately", false); + public final BooleanPreference adjustHeightForEK = new BooleanPreference("adjustHeightForEK", true); + public final BooleanPreference useTermuxEKBarBehaviour = new BooleanPreference("useTermuxEKBarBehaviour", true); + public final IntPreference opacityEKBar = new IntPreference("opacityEKBar", 100); + public final ListPreference swipeUpAction = new ListPreference("swipeUpAction", "no action", R.array.userActionsValues, R.array.userActionsValues); + public final ListPreference swipeDownAction = new ListPreference("swipeDownAction", "toggle additional key bar", R.array.userActionsValues, R.array.userActionsValues); + public final ListPreference volumeUpAction = new ListPreference("volumeUpAction", "no action", R.array.userActionsVolumeUpValues, R.array.userActionsVolumeUpValues); + public final ListPreference volumeDownAction = new ListPreference("volumeDownAction", "no action", R.array.userActionsVolumeDownValues, R.array.userActionsVolumeDownValues); + public final ListPreference backButtonAction = new ListPreference("backButtonAction", "toggle additional key bar", R.array.userActionsValues, R.array.userActionsValues); + public final ListPreference notificationTapAction = new ListPreference("notificationTapAction", "open preferences", R.array.userActionsValues, R.array.userActionsValues); + public final ListPreference notificationButton0Action = new ListPreference("notificationButton0Action", "open preferences", R.array.userActionsValues, R.array.userActionsValues); + public final ListPreference notificationButton1Action = new ListPreference("notificationButton1Action", "exit", R.array.userActionsValues, R.array.userActionsValues); + public final StringPreference extra_keys_config = new StringPreference("extra_keys_config", TermuxX11ExtraKeys.DEFAULT_IVALUE_EXTRA_KEYS); + public final HashMap keys = new HashMap() {{ + put("displayResolutionMode", displayResolutionMode); + put("displayScale", displayScale); + put("displayResolutionExact", displayResolutionExact); + put("displayResolutionCustom", displayResolutionCustom); + put("adjustResolution", adjustResolution); + put("displayStretch", displayStretch); + put("Reseed", Reseed); + put("PIP", PIP); + put("fullscreen", fullscreen); + put("forceOrientation", forceOrientation); + put("hideCutout", hideCutout); + put("keepScreenOn", keepScreenOn); + put("xrMode", xrMode); + put("touchMode", touchMode); + put("scaleTouchpad", scaleTouchpad); + put("showStylusClickOverride", showStylusClickOverride); + put("stylusIsMouse", stylusIsMouse); + put("stylusButtonContactModifierMode", stylusButtonContactModifierMode); + put("showMouseHelper", showMouseHelper); + put("pointerCapture", pointerCapture); + put("transformCapturedPointer", transformCapturedPointer); + put("capturedPointerSpeedFactor", capturedPointerSpeedFactor); + put("tapToMove", tapToMove); + put("showAdditionalKbd", showAdditionalKbd); + put("additionalKbdVisible", additionalKbdVisible); + put("showIMEWhileExternalConnected", showIMEWhileExternalConnected); + put("preferScancodes", preferScancodes); + put("hardwareKbdScancodesWorkaround", hardwareKbdScancodesWorkaround); + put("dexMetaKeyCapture", dexMetaKeyCapture); + put("enableAccessibilityServiceAutomatically", enableAccessibilityServiceAutomatically); + put("pauseKeyInterceptingWithEsc", pauseKeyInterceptingWithEsc); + put("filterOutWinkey", filterOutWinkey); + put("enableGboardCJK", enableGboardCJK); + put("clipboardEnable", clipboardEnable); + put("storeSecondaryDisplayPreferencesSeparately", storeSecondaryDisplayPreferencesSeparately); + put("adjustHeightForEK", adjustHeightForEK); + put("useTermuxEKBarBehaviour", useTermuxEKBarBehaviour); + put("opacityEKBar", opacityEKBar); + put("swipeUpAction", swipeUpAction); + put("swipeDownAction", swipeDownAction); + put("volumeUpAction", volumeUpAction); + put("volumeDownAction", volumeDownAction); + put("backButtonAction", backButtonAction); + put("notificationTapAction", notificationTapAction); + put("notificationButton0Action", notificationButton0Action); + put("notificationButton1Action", notificationButton1Action); + put("extra_keys_config", extra_keys_config); + }}; + + public Prefs(Context ctx) { + super(ctx); + } +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 738f1ba..74b49ed 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -6,11 +6,22 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /dev/null 2>&1 || patch -p1 -N -d ${d} -i ${p} -r -") +# endfunction() + +function(target_apply_patch patch_target d p) + execute_process( + COMMAND powershell -Command "& { + $patchCommand = \"patch -p1 -d ${d} -i ${p} -R --dry-run 2>&1\" + if (Invoke-Expression $patchCommand) { + Invoke-Expression \"patch -p1 -N -d ${d} -i ${p} -r -\" + } + }" + ) +endfunction() + + +set(test_compile_options + "-Wall" + "-Wpointer-arith" + "-Wmissing-declarations" + "-Wformat=2" + "-Winvalid-pch" + "-Wstrict-prototypes" + "-Wmissing-prototypes" + "-Wnested-externs" + "-Wbad-function-cast" + "-Wold-style-definition" + "-Wunused" + "-Wuninitialized" + "-Wshadow" + "-Wmissing-noreturn" + "-Wmissing-format-attribute" + "-Wredundant-decls" + "-Wlogical-op" + "-Werror=implicit" + "-Werror=nonnull" + "-Werror=init-self" + "-Werror=main" + "-Werror=missing-braces" + "-Werror=sequence-point" + "-Werror=return-type" + "-Werror=trigraphs" + "-Werror=array-bounds" + "-Werror=write-strings" + "-Werror=address" + "-Werror=int-to-pointer-cast" + "-Werror=pointer-to-int-cast" + "-fno-strict-aliasing" + "-Wno-unused-but-set-variable" + "-Wno-unused-parameter" + "-Wno-unused-variable" + "-Wno-unused-function" + "-Wno-missing-prototypes" + "-Wno-macro-redefined" + "-Wno-uninitialized" + "-Wno-shadow") + +set(CMAKE_REQUIRED_QUIET_OLD ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET 1) +set(common_compile_options) +set(I 0) +foreach (option ${test_compile_options}) + check_c_compiler_flag(${option} COMPILER_TEST_${I}) + if (COMPILER_TEST_${I}) + set(common_compile_options ${common_compile_options} ${option}) + endif() + MATH(EXPR I "${I}+1") +endforeach () +set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_OLD}) + +foreach(project xorgproto fontenc md pixman tirpc xshmfence Xdmcp Xau Xfont2 xkbcomp xserver) + include(recipes/${project}.cmake) +endforeach() + +if(${ANDROID_ABI} MATCHES "arm64-v8a") + add_subdirectory(OpenXR-SDK) + add_library(XRio SHARED + "xrio/android.c" + "xrio/engine.c" + "xrio/framebuffer.c" + "xrio/input.c" + "xrio/math.c" + "xrio/renderer.c") + target_link_options(XRio PRIVATE "-Wl,--as-needed" "-Wl,--no-undefined" "-fvisibility=hidden") + target_link_libraries(XRio "-Wl,--whole-archive" "-Wl,--no-whole-archive" android log EGL GLESv2 openxr_loader) +endif() diff --git a/android/app/src/main/cpp/OpenXR-SDK b/android/app/src/main/cpp/OpenXR-SDK new file mode 160000 index 0000000..f90488c --- /dev/null +++ b/android/app/src/main/cpp/OpenXR-SDK @@ -0,0 +1 @@ +Subproject commit f90488c4fb1537f4256d09d4a4d3ad5543ebaf24 diff --git a/android/app/src/main/cpp/bzip2 b/android/app/src/main/cpp/bzip2 new file mode 160000 index 0000000..66c46b8 --- /dev/null +++ b/android/app/src/main/cpp/bzip2 @@ -0,0 +1 @@ +Subproject commit 66c46b8c9436613fd81bc5d03f63a61933a4dcc3 diff --git a/android/app/src/main/cpp/libepoxy b/android/app/src/main/cpp/libepoxy new file mode 160000 index 0000000..f13c13c --- /dev/null +++ b/android/app/src/main/cpp/libepoxy @@ -0,0 +1 @@ +Subproject commit f13c13c11cfe271844a8735beb9dc0480572405a diff --git a/android/app/src/main/cpp/libfontenc b/android/app/src/main/cpp/libfontenc new file mode 160000 index 0000000..92a85fd --- /dev/null +++ b/android/app/src/main/cpp/libfontenc @@ -0,0 +1 @@ +Subproject commit 92a85fda2acb4e14ec0b2f6d8fe3eaf2b687218c diff --git a/android/app/src/main/cpp/libtirpc b/android/app/src/main/cpp/libtirpc new file mode 160000 index 0000000..5ca4ca9 --- /dev/null +++ b/android/app/src/main/cpp/libtirpc @@ -0,0 +1 @@ +Subproject commit 5ca4ca92f629d9d83e83544b9239abaaacf0a527 diff --git a/android/app/src/main/cpp/libx11 b/android/app/src/main/cpp/libx11 new file mode 160000 index 0000000..ed9fb55 --- /dev/null +++ b/android/app/src/main/cpp/libx11 @@ -0,0 +1 @@ +Subproject commit ed9fb5535efe1e5278654b6b3994a34337b4bf1a diff --git a/android/app/src/main/cpp/libxau b/android/app/src/main/cpp/libxau new file mode 160000 index 0000000..89429bb --- /dev/null +++ b/android/app/src/main/cpp/libxau @@ -0,0 +1 @@ +Subproject commit 89429bb36de409b204ef105e8b73126a639ccb03 diff --git a/android/app/src/main/cpp/libxcvt b/android/app/src/main/cpp/libxcvt new file mode 160000 index 0000000..922c7e1 --- /dev/null +++ b/android/app/src/main/cpp/libxcvt @@ -0,0 +1 @@ +Subproject commit 922c7e1fb5f976765524ab9ab47567582a9f66dd diff --git a/android/app/src/main/cpp/libxdmcp b/android/app/src/main/cpp/libxdmcp new file mode 160000 index 0000000..1192d3b --- /dev/null +++ b/android/app/src/main/cpp/libxdmcp @@ -0,0 +1 @@ +Subproject commit 1192d3bc407348ff316bd3bffc791b3ac73f591b diff --git a/android/app/src/main/cpp/libxfont b/android/app/src/main/cpp/libxfont new file mode 160000 index 0000000..2c2e44c --- /dev/null +++ b/android/app/src/main/cpp/libxfont @@ -0,0 +1 @@ +Subproject commit 2c2e44c94ef17ecd5003a173237b57b315e28d93 diff --git a/android/app/src/main/cpp/libxkbfile b/android/app/src/main/cpp/libxkbfile new file mode 160000 index 0000000..bf985c6 --- /dev/null +++ b/android/app/src/main/cpp/libxkbfile @@ -0,0 +1 @@ +Subproject commit bf985c68acb1244f51ec91414532a2347fbc1c4c diff --git a/android/app/src/main/cpp/libxshmfence b/android/app/src/main/cpp/libxshmfence new file mode 160000 index 0000000..4fca45a --- /dev/null +++ b/android/app/src/main/cpp/libxshmfence @@ -0,0 +1 @@ +Subproject commit 4fca45a71f08a5bebd12d39c85f49e0b0e4426bf diff --git a/android/app/src/main/cpp/libxtrans b/android/app/src/main/cpp/libxtrans new file mode 160000 index 0000000..edd3f51 --- /dev/null +++ b/android/app/src/main/cpp/libxtrans @@ -0,0 +1 @@ +Subproject commit edd3f51328df9c621277168c9dd77b1e80ccfd7c diff --git a/android/app/src/main/cpp/lorie/InitInput.c b/android/app/src/main/cpp/lorie/InitInput.c new file mode 100644 index 0000000..6b509ff --- /dev/null +++ b/android/app/src/main/cpp/lorie/InitInput.c @@ -0,0 +1,283 @@ +/* + +Copyright 1993, 1998 The Open Group + +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. + +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 OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#include +#include "mi.h" +#include "scrnintstr.h" +#include "inputstr.h" +#include +#include +#include "mipointer.h" +#include "xkbsrv.h" +#include "xserver-properties.h" +#include "exevents.h" +#include "renderer.h" + +#define XI_PEN "TERMUX-X11 PEN" +#define XI_ERASER "TERMUX-X11 ERASER" + +__unused DeviceIntPtr lorieMouse, lorieTouch, lorieKeyboard, loriePen, lorieEraser; + +void +ProcessInputEvents(void) { + mieqProcessInputEvents(); +} + +void +DDXRingBell(__unused int volume, __unused int pitch, __unused int duration) {} + +static int +lorieKeybdProc(DeviceIntPtr pDevice, int onoff) { + DevicePtr pDev = (DevicePtr) pDevice; + + switch (onoff) { + case DEVICE_INIT: + InitKeyboardDeviceStruct(pDevice, NULL, NULL, NULL); + break; + case DEVICE_ON: + pDev->on = TRUE; + break; + case DEVICE_OFF: + pDev->on = FALSE; + break; + case DEVICE_CLOSE: + break; + default: + return BadMatch; + } + return Success; +} + +static Bool +lorieInitPointerButtons(DeviceIntPtr device) { +#define NBUTTONS 10 + BYTE map[NBUTTONS + 1]; + int i; + Atom btn_labels[NBUTTONS] = { 0 }; + + for (i = 1; i <= NBUTTONS; i++) + map[i] = i; + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); + btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + /* don't know about the rest */ + + if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map)) + return FALSE; + + return TRUE; +#undef NBUTTONS +} + +__unused static int +lorieMouseProc(DeviceIntPtr device, int what) { +#define NAXES 4 + Atom axes_labels[NAXES] = { 0 }; + + switch (what) { + case DEVICE_INIT: + device->public.on = FALSE; + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL); + axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL); + + if (!lorieInitPointerButtons(device) + || !InitValuatorClassDeviceStruct(device, NAXES, axes_labels, GetMotionHistorySize(), Relative) + || !InitValuatorAxisStruct(device, 0, axes_labels[0], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative) + || !InitValuatorAxisStruct(device, 1, axes_labels[1], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative) + || !InitValuatorAxisStruct(device, 2, axes_labels[2], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative) + || !InitValuatorAxisStruct(device, 3, axes_labels[3], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative) + || !SetScrollValuator(device, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE) + || !SetScrollValuator(device, 3, SCROLL_TYPE_VERTICAL, 1.0, SCROLL_FLAG_PREFERRED) + || !InitPtrFeedbackClassDeviceStruct(device, (PtrCtrlProcPtr) NoopDDA) + || !InitPointerAccelerationScheme(device, PtrAccelPredictable)) + return BadValue; + + return Success; + + case DEVICE_ON: + device->public.on = TRUE; + return Success; + + case DEVICE_OFF: + case DEVICE_CLOSE: + device->public.on = FALSE; + return Success; + default: + return BadMatch; + } +#undef NAXES +} + +static int +lorieTouchProc(DeviceIntPtr device, int what) { +#define NTOUCHPOINTS 20 +#define NBUTTONS 1 +#define NAXES 2 + Atom btn_labels[NBUTTONS] = { 0 }; + BYTE map[NBUTTONS + 1] = { 0 }; + Atom axes_labels[NAXES] = { 0 }; + + switch (what) { + case DEVICE_INIT: + device->public.on = FALSE; + + map[0] = 1; + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y); + + if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels, GetMotionHistorySize(), Absolute) + || !InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map) + || !InitTouchClassDeviceStruct(device, NTOUCHPOINTS, XIDirectTouch, NAXES) + || !InitValuatorAxisStruct(device, 0, axes_labels[0], 0, 0xFFFF, 10000, 0, 10000, Absolute) + || !InitValuatorAxisStruct(device, 1, axes_labels[1], 0, 0xFFFF, 10000, 0, 10000, Absolute)) + return BadValue; + + return Success; + + case DEVICE_ON: + device->public.on = TRUE; + return Success; + + case DEVICE_OFF: + case DEVICE_CLOSE: + device->public.on = FALSE; + return Success; + default: + return BadMatch; + } +#undef NAXES +#undef NBUTTONS +#undef NTOUCHPOINTS +} + +static int +lorieStylusProc(DeviceIntPtr device, int what) { +#define NBUTTONS 3 +#define NAXES 6 + Atom btn_labels[NBUTTONS] = { 0 }; + Atom axes_labels[NAXES] = { 0 }; + BYTE map[NBUTTONS + 1] = { 0 }; + int i; + + switch (what) { + case DEVICE_INIT: + device->public.on = FALSE; + + for (i = 1; i <= NBUTTONS; i++) + map[i] = i; + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); + axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE); + axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X); + axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y); + axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL); + + /* Valuators - match the xf86-input-wacom ranges */ + if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels, GetMotionHistorySize(), Absolute) + || !InitValuatorAxisStruct(device, 0, axes_labels[0], 0, 0x3FFFF, 10000, 0, 10000, Absolute) + || !InitValuatorAxisStruct(device, 1, axes_labels[1], 0, 0x3FFFF, 10000, 0, 10000, Absolute) + || !InitValuatorAxisStruct(device, 2, axes_labels[2], 0, 0xFFFF, 1, 0, 1, Absolute) // pressure + || !InitValuatorAxisStruct(device, 3, axes_labels[3], -64, 63, 57, 0, 57, Absolute) // tilt x + || !InitValuatorAxisStruct(device, 4, axes_labels[4], -64, 63, 57, 0, 57, Absolute) // tilt y + || !InitValuatorAxisStruct(device, 5, axes_labels[5], -900, 899, 1, 0, 1, Absolute) // abs wheel (airbrush) or rotation (artpen) + || !InitPtrFeedbackClassDeviceStruct(device, (PtrCtrlProcPtr) NoopDDA) + || !InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map)) + return BadValue; + + return Success; + + case DEVICE_ON: + device->public.on = TRUE; + return Success; + + case DEVICE_OFF: + case DEVICE_CLOSE: + device->public.on = FALSE; + return Success; + } + + return BadMatch; +#undef NAXES +#undef NBUTTONS +} + +void +lorieSetStylusEnabled(Bool enabled) { + __android_log_print(ANDROID_LOG_DEBUG, "LorieNative", "Requested stylus: %d, current loriePen %p, current lorieEraser %p\n", enabled, loriePen, lorieEraser); + if (enabled) { + if (loriePen == NULL) { + loriePen = AddInputDevice(serverClient, lorieStylusProc, TRUE); + AssignTypeAndName(loriePen, MakeAtom(XI_PEN, sizeof(XI_PEN) - 1, TRUE), "Lorie pen"); + ActivateDevice(loriePen, FALSE); + EnableDevice(loriePen, TRUE); + AttachDevice(NULL, loriePen, inputInfo.pointer); + } + if (lorieEraser == NULL) { + lorieEraser = AddInputDevice(serverClient, lorieStylusProc, TRUE); + AssignTypeAndName(lorieEraser, MakeAtom(XI_ERASER, sizeof(XI_ERASER) - 1, TRUE), "Lorie eraser"); + ActivateDevice(lorieEraser, FALSE); + EnableDevice(lorieEraser, TRUE); + AttachDevice(NULL, lorieEraser, inputInfo.pointer); + } + } else { + if (loriePen != NULL) { + RemoveDevice(loriePen, TRUE); + loriePen = NULL; + } + if (lorieEraser != NULL) { + RemoveDevice(lorieEraser, TRUE); + lorieEraser = NULL; + } + } +} + +void +InitInput(__unused int argc, __unused char *argv[]) { + lorieMouse = AddInputDevice(serverClient, lorieMouseProc, TRUE); + lorieTouch = AddInputDevice(serverClient, lorieTouchProc, TRUE); + lorieKeyboard = AddInputDevice(serverClient, lorieKeybdProc, TRUE); + AssignTypeAndName(lorieMouse, MakeAtom(XI_MOUSE, sizeof(XI_MOUSE) - 1, TRUE), "Lorie mouse"); + AssignTypeAndName(lorieTouch, MakeAtom(XI_TOUCHSCREEN, sizeof(XI_TOUCHSCREEN) - 1, TRUE), "Lorie touch"); + AssignTypeAndName(lorieKeyboard, MakeAtom(XI_KEYBOARD, sizeof(XI_KEYBOARD) - 1, TRUE), "Lorie keyboard"); + (void) mieqInit(); +} + +void +CloseInput(void) { + mieqFini(); +} diff --git a/android/app/src/main/cpp/lorie/InitOutput.c b/android/app/src/main/cpp/lorie/InitOutput.c new file mode 100644 index 0000000..2aa0a2d --- /dev/null +++ b/android/app/src/main/cpp/lorie/InitOutput.c @@ -0,0 +1,758 @@ +/* + +Copyright 1993, 1998 The Open Group + +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. + +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 OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wstrict-prototypes" +#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions" +#pragma ide diagnostic ignored "cert-err34-c" +#pragma ide diagnostic ignored "ConstantConditionsOC" +#pragma ide diagnostic ignored "ConstantFunctionResult" +#pragma ide diagnostic ignored "bugprone-integer-division" +#pragma clang diagnostic ignored "-Wmissing-noreturn" +#pragma clang diagnostic ignored "-Wformat-nonliteral" + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scrnintstr.h" +#include "servermd.h" +#include "fb.h" +#include "input.h" +#include "mipointer.h" +#include "micmap.h" +#include "dix.h" +#include "miline.h" +#include "glx_extinit.h" +#include "randrstr.h" +#include "damagestr.h" +#include "cursorstr.h" +#include "propertyst.h" +#include "shmint.h" +#include "glxserver.h" +#include "glxutil.h" +#include "fbconfigs.h" + +#include "renderer.h" +#include "inpututils.h" +#include "lorie.h" + +#define unused __attribute__((unused)) +#define wrap(priv, real, mem, func) { priv->mem = real->mem; real->mem = func; } +#define unwrap(priv, real, mem) { real->mem = priv->mem; } +#define USAGE (AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN) +#define log(prio, ...) __android_log_print(ANDROID_LOG_ ## prio, "LorieNative", __VA_ARGS__) + +extern DeviceIntPtr lorieMouse, lorieKeyboard; + +typedef struct { + CloseScreenProcPtr CloseScreen; + CreateScreenResourcesProcPtr CreateScreenResources; + + DamagePtr damage; + OsTimerPtr redrawTimer; + OsTimerPtr fpsTimer; + + Bool cursorMoved; + int timerFd; + + struct { + AHardwareBuffer* buffer; + Bool locked; + Bool legacyDrawing; + uint8_t flip; + uint32_t width, height; + } root; + + JavaVM* vm; + JNIEnv* env; + Bool dri3; +} lorieScreenInfo, *lorieScreenInfoPtr; + +ScreenPtr pScreenPtr; +static lorieScreenInfo lorieScreen = { .root.width = 1280, .root.height = 1024, .dri3 = TRUE }; +static lorieScreenInfoPtr pvfb = &lorieScreen; +static char *xstartup = NULL; + +static Bool TrueNoop() { return TRUE; } +static Bool FalseNoop() { return FALSE; } +static void VoidNoop() {} + +void +ddxGiveUp(unused enum ExitCode error) { + log(ERROR, "Server stopped (%d)", error); + CloseWellKnownConnections(); + UnlockServer(); + exit(error); +} + +static void* ddxReadyThread(unused void* cookie) { + if (xstartup && serverGeneration == 1) { + pid_t pid = fork(); + + if (!pid) { + char DISPLAY[16] = ""; + sprintf(DISPLAY, ":%s", display); + setenv("DISPLAY", DISPLAY, 1); + unsetenv("CLASSPATH"); + execlp(xstartup, xstartup, NULL); + execlp("sh", "sh", "-c", xstartup, NULL); + dprintf(2, "Failed to start command `sh -c \"%s\"`: %s\n", xstartup, strerror(errno)); + abort(); + } else { + int status; + do { + pid_t w = waitpid(pid, &status, 0); + if (w == -1) { + perror("waitpid"); + GiveUp(SIGKILL); + } + + if (WIFEXITED(status)) { + printf("%d exited, status=%d\n", w, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + printf("%d killed by signal %d\n", w, WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + printf("%d stopped by signal %d\n", w, WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + printf("%d continued\n", w); + } + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + GiveUp(SIGINT); + } + } + + return NULL; +} + +void +ddxReady(void) { + if (!xstartup) + xstartup = getenv("TERMUX_X11_XSTARTUP"); + if (!xstartup) + return; + + pthread_t t; + pthread_create(&t, NULL, ddxReadyThread, NULL); +} + +void +OsVendorInit(void) { +} + +void +OsVendorFatalError(unused const char *f, unused va_list args) { + log(ERROR, f, args); +} + +#if defined(DDXBEFORERESET) +void +ddxBeforeReset(void) { + return; +} +#endif + +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) {} +#endif + +void ddxUseMsg(void) { + ErrorF("-xstartup \"command\" start `command` after server startup\n"); + ErrorF("-legacy-drawing use legacy drawing, without using AHardwareBuffers\n"); + ErrorF("-force-bgra force flipping colours (RGBA->BGRA)\n"); + ErrorF("-disable-dri3 disabling DRI3 support (to let lavapipe work)\n"); +} + +int ddxProcessArgument(unused int argc, unused char *argv[], unused int i) { + if (strcmp(argv[i], "-xstartup") == 0) { /* -xstartup "command" */ + CHECK_FOR_REQUIRED_ARGUMENTS(1); + xstartup = argv[++i]; + return 2; + } + + if (strcmp(argv[i], "-legacy-drawing") == 0) { + pvfb->root.legacyDrawing = TRUE; + return 1; + } + + if (strcmp(argv[i], "-force-bgra") == 0) { + pvfb->root.flip = TRUE; + return 1; + } + + if (strcmp(argv[i], "-disable-dri3") == 0) { + pvfb->dri3 = FALSE; + return 1; + } + + return 0; +} + +static RRModePtr lorieCvt(int width, int height, int framerate) { + struct libxcvt_mode_info *info; + char name[128]; + xRRModeInfo modeinfo = {0}; + RRModePtr mode; + + info = libxcvt_gen_mode_info(width, height, framerate, 0, 0); + + snprintf(name, sizeof name, "%dx%d", info->hdisplay, info->vdisplay); + modeinfo.nameLength = strlen(name); + modeinfo.width = info->hdisplay; + modeinfo.height = info->vdisplay; + modeinfo.dotClock = info->dot_clock * 1000.0; + modeinfo.hSyncStart = info->hsync_start; + modeinfo.hSyncEnd = info->hsync_end; + modeinfo.hTotal = info->htotal; + modeinfo.vSyncStart = info->vsync_start; + modeinfo.vSyncEnd = info->vsync_end; + modeinfo.vTotal = info->vtotal; + modeinfo.modeFlags = info->mode_flags; + + mode = RRModeGet(&modeinfo, name); + free(info); + return mode; +} + +static void lorieMoveCursor(unused DeviceIntPtr pDev, unused ScreenPtr pScr, int x, int y) { + renderer_set_cursor_coordinates(x, y); + pvfb->cursorMoved = TRUE; +} + +static void lorieConvertCursor(CursorPtr pCurs, CARD32 *data) { + CursorBitsPtr bits = pCurs->bits; + if (bits->argb) { + for (int i = 0; i < bits->width * bits->height; i++) { + /* Convert bgra to rgba */ + CARD32 p = bits->argb[i]; + data[i] = (p & 0xFF000000) | ((p & 0x00FF0000) >> 16) | (p & 0x0000FF00) | ((p & 0x000000FF) << 16); + } + } else { + CARD32 d, fg, bg, *p; + int x, y, stride, i, bit; + + p = data; + fg = ((pCurs->foreBlue & 0xff00) << 8) | (pCurs->foreGreen & 0xff00) | (pCurs->foreRed >> 8); + bg = ((pCurs->backBlue & 0xff00) << 8) | (pCurs->backGreen & 0xff00) | (pCurs->backRed >> 8); + stride = BitmapBytePad(bits->width); + for (y = 0; y < bits->height; y++) + for (x = 0; x < bits->width; x++) { + i = y * stride + x / 8; + bit = 1 << (x & 7); + d = (bits->source[i] & bit) ? fg : bg; + d = (bits->mask[i] & bit) ? d | 0xff000000 : 0x00000000; + *p++ = d; + } + } +} + +static void lorieSetCursor(unused DeviceIntPtr pDev, unused ScreenPtr pScr, CursorPtr pCurs, int x0, int y0) { + CursorBitsPtr bits = pCurs ? pCurs->bits : NULL; + if (pCurs && bits) { + CARD32 data[bits->width * bits->height * 4]; + + lorieConvertCursor(pCurs, data); + renderer_update_cursor(bits->width, bits->height, bits->xhot, bits->yhot, data); + } else + renderer_update_cursor(0, 0, 0, 0, NULL); + + if (x0 >= 0 && y0 >= 0) + lorieMoveCursor(NULL, NULL, x0, y0); +} + +static miPointerSpriteFuncRec loriePointerSpriteFuncs = { + .RealizeCursor = TrueNoop, + .UnrealizeCursor = TrueNoop, + .SetCursor = lorieSetCursor, + .MoveCursor = lorieMoveCursor, + .DeviceCursorInitialize = TrueNoop, + .DeviceCursorCleanup = VoidNoop +}; + +static miPointerScreenFuncRec loriePointerCursorFuncs = { + .CursorOffScreen = FalseNoop, + .CrossScreen = VoidNoop, + .WarpCursor = miPointerWarpCursor +}; + +static void lorieUpdateBuffer(void) { + AHardwareBuffer_Desc d0 = {}, d1 = {}; + AHardwareBuffer *new = NULL, *old = pvfb->root.buffer; + int status, wasLocked = pvfb->root.locked; + void *data0 = NULL, *data1 = NULL; + + if (pvfb->root.legacyDrawing) { + PixmapPtr pixmap = (PixmapPtr) pScreenPtr->devPrivate; + DrawablePtr draw = &pixmap->drawable; + data0 = malloc(pScreenPtr->width * pScreenPtr->height * 4); + data1 = (draw->width && draw->height) ? pixmap->devPrivate.ptr : NULL; + if (data1) + pixman_blt(data1, data0, draw->width, pScreenPtr->width, 32, 32, 0, 0, 0, 0, + min(draw->width, pScreenPtr->width), min(draw->height, pScreenPtr->height)); + pScreenPtr->ModifyPixmapHeader(pScreenPtr->devPrivate, pScreenPtr->width, pScreenPtr->height, 32, 32, pScreenPtr->width * 4, data0); + free(data1); + return; + } + + if (pScreenPtr->devPrivate) { + d0.width = pScreenPtr->width; + d0.height = pScreenPtr->height; + d0.layers = 1; + d0.usage = USAGE | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; + d0.format = pvfb->root.flip + ? AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM + : AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM; + + /* I could use this, but in this case I must swap colours in the shader. */ + // desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM; + + status = AHardwareBuffer_allocate(&d0, &new); + if (status != 0) + FatalError("Failed to allocate root window pixmap (error %d)", status); + + AHardwareBuffer_describe(new, &d0); + status = AHardwareBuffer_lock(new, USAGE, -1, NULL, &data0); + if (status != 0) + FatalError("Failed to lock root window pixmap (error %d)", status); + + pvfb->root.buffer = new; + pvfb->root.locked = TRUE; + + pScreenPtr->ModifyPixmapHeader(pScreenPtr->devPrivate, d0.width, d0.height, 32, 32, d0.stride * 4, data0); + + renderer_set_buffer(pvfb->env, new); + } + + if (old) { + if (wasLocked) + AHardwareBuffer_unlock(old, NULL); + + if (new && pvfb->root.locked) { + /* + * It is pretty easy. If there is old pixmap we should copy it's contents to new pixmap. + * If it is impossible we should simply request root window exposure. + */ + AHardwareBuffer_describe(old, &d1); + status = AHardwareBuffer_lock(old, USAGE, -1, NULL, &data1); + if (status == 0) { + pixman_blt(data1, data0, d1.stride, d0.stride, + 32, 32, 0, 0, 0, 0, + min(d1.width, d0.width), min(d1.height, d0.height)); + AHardwareBuffer_unlock(old, NULL); + } else { + RegionRec reg; + BoxRec box = {.x1 = 0, .y1 = 0, .x2 = d0.width, .y2 = d0.height}; + RegionInit(®, &box, 1); + pScreenPtr->WindowExposures(pScreenPtr->root, ®); + RegionUninit(®); + AHardwareBuffer_release(old); + return; + } + } + AHardwareBuffer_release(old); + } +} + +static inline void loriePixmapUnlock(PixmapPtr pixmap) { + if (pvfb->root.legacyDrawing) + return renderer_update_root(pixmap->drawable.width, pixmap->drawable.height, pixmap->devPrivate.ptr, pvfb->root.flip); + + if (pvfb->root.locked) + AHardwareBuffer_unlock(pvfb->root.buffer, NULL); + + pvfb->root.locked = FALSE; + pixmap->drawable.pScreen->ModifyPixmapHeader(pixmap, -1, -1, -1, -1, -1, NULL); +} + +static inline Bool loriePixmapLock(PixmapPtr pixmap) { + AHardwareBuffer_Desc desc = {}; + void *data; + int status; + + if (pvfb->root.legacyDrawing) + return TRUE; + + if (!pvfb->root.buffer) { + pvfb->root.locked = FALSE; + return FALSE; + } + + AHardwareBuffer_describe(pvfb->root.buffer, &desc); + status = AHardwareBuffer_lock(pvfb->root.buffer, USAGE, -1, NULL, &data); + pvfb->root.locked = status == 0; + if (pvfb->root.locked) + pixmap->drawable.pScreen->ModifyPixmapHeader(pixmap, desc.width, desc.height, -1, -1, desc.stride * 4, data); + else + FatalError("Failed to lock surface: %d\n", status); + + return pvfb->root.locked; +} + +static void lorieTimerCallback(int fd, unused int r, void *arg) { + char dummy[8]; + read(fd, dummy, 8); + if (renderer_should_redraw() && RegionNotEmpty(DamageRegion(pvfb->damage))) { + int redrawn = FALSE; + ScreenPtr pScreen = (ScreenPtr) arg; + + loriePixmapUnlock(pScreen->GetScreenPixmap(pScreen)); + redrawn = renderer_redraw(pvfb->env, pvfb->root.flip); + if (loriePixmapLock(pScreen->GetScreenPixmap(pScreen)) && redrawn) + DamageEmpty(pvfb->damage); + } else if (pvfb->cursorMoved) + renderer_redraw(pvfb->env, pvfb->root.flip); + + pvfb->cursorMoved = FALSE; +} + +static CARD32 lorieFramecounter(unused OsTimerPtr timer, unused CARD32 time, unused void *arg) { + renderer_print_fps(5000); + return 5000; +} + +static Bool lorieCreateScreenResources(ScreenPtr pScreen) { + Bool ret; + pScreen->CreateScreenResources = pvfb->CreateScreenResources; + + ret = pScreen->CreateScreenResources(pScreen); + if (!ret) + return FALSE; + + pScreen->devPrivate = fbCreatePixmap(pScreen, 0, 0, pScreen->rootDepth, CREATE_PIXMAP_USAGE_BACKING_PIXMAP); + + pvfb->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, NULL); + if (!pvfb->damage) + FatalError("Couldn't setup damage\n"); + + DamageRegister(&(*pScreen->GetScreenPixmap)(pScreen)->drawable, pvfb->damage); + pvfb->fpsTimer = TimerSet(NULL, 0, 5000, lorieFramecounter, pScreen); + lorieUpdateBuffer(); + + return TRUE; +} + +static Bool +lorieCloseScreen(ScreenPtr pScreen) { + unwrap(pvfb, pScreen, CloseScreen) + // No need to call fbDestroyPixmap since AllocatePixmap sets pixmap as PRIVATE_SCREEN so it is destroyed automatically. + return pScreen->CloseScreen(pScreen); +} + +static Bool +lorieRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height, unused CARD32 mmWidth, unused CARD32 mmHeight) { + SetRootClip(pScreen, ROOT_CLIP_NONE); + + pvfb->root.width = pScreen->width = width; + pvfb->root.height = pScreen->height = height; + pScreen->mmWidth = ((double) (width)) * 25.4 / monitorResolution; + pScreen->mmHeight = ((double) (height)) * 25.4 / monitorResolution; + lorieUpdateBuffer(); + + pScreen->ResizeWindow(pScreen->root, 0, 0, width, height, NULL); + DamageEmpty(pvfb->damage); + SetRootClip(pScreen, ROOT_CLIP_FULL); + + RRScreenSizeNotify(pScreen); + update_desktop_dimensions(); + pvfb->cursorMoved = TRUE; + + return TRUE; +} + +static Bool +lorieRRCrtcSet(unused ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode, int x, int y, + Rotation rotation, int numOutput, RROutputPtr *outputs) { + return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutput, outputs); +} + +static Bool +lorieRRGetInfo(unused ScreenPtr pScreen, Rotation *rotations) { + *rotations = RR_Rotate_0; + return TRUE; +} + +static Bool +lorieRandRInit(ScreenPtr pScreen) { + rrScrPrivPtr pScrPriv; + RROutputPtr output; + RRCrtcPtr crtc; + RRModePtr mode; + + char screenName[1024] = "screen"; + + if (!RRScreenInit(pScreen)) + return FALSE; + + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = lorieRRGetInfo; + pScrPriv->rrCrtcSet = lorieRRCrtcSet; + pScrPriv->rrScreenSetSize = lorieRRScreenSetSize; + + RRScreenSetSizeRange(pScreen, 1, 1, 32767, 32767); + + if (FALSE + || !(mode = lorieCvt(pScreen->width, pScreen->height, 30)) + || !(crtc = RRCrtcCreate(pScreen, NULL)) + || !RRCrtcGammaSetSize(crtc, 256) + || !(output = RROutputCreate(pScreen, screenName, sizeof(screenName), NULL)) + || (output->nameLength = strlen(output->name), FalseNoop()) + || !RROutputSetClones(output, NULL, 0) + || !RROutputSetModes(output, &mode, 1, 0) + || !RROutputSetCrtcs(output, &crtc, 1) + || !RROutputSetConnection(output, RR_Connected) + || !RRCrtcNotify(crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output)) + return FALSE; + return TRUE; +} + +static Bool resetRootCursor(unused ClientPtr pClient, unused void *closure) { + CursorVisible = TRUE; + pScreenPtr->DisplayCursor(lorieMouse, pScreenPtr, NullCursor); + pScreenPtr->DisplayCursor(lorieMouse, pScreenPtr, rootCursor); + return TRUE; +} + +static Bool +lorieScreenInit(ScreenPtr pScreen, unused int argc, unused char **argv) { + static int timerFd = -1; + pScreenPtr = pScreen; + + if (timerFd == -1) { + struct itimerspec spec = {0}; + timerFd = timerfd_create(CLOCK_MONOTONIC, 0); + timerfd_settime(timerFd, 0, &spec, NULL); + } + + pvfb->timerFd = timerFd; + SetNotifyFd(timerFd, lorieTimerCallback, X_NOTIFY_READ, pScreen); + + miSetZeroLineBias(pScreen, 0); + pScreen->blackPixel = 0; + pScreen->whitePixel = 1; + + if (FALSE + || !miSetVisualTypesAndMasks(24, ((1 << TrueColor) | (1 << DirectColor)), 8, TrueColor, 0xFF0000, 0x00FF00, 0x0000FF) + || !miSetPixmapDepths() + || !fbScreenInit(pScreen, NULL, pvfb->root.width, pvfb->root.height, monitorResolution, monitorResolution, 0, 32) + || !(!pvfb->dri3 || lorieInitDri3(pScreen)) + || !fbPictureInit(pScreen, 0, 0) + || !lorieRandRInit(pScreen) + || !miPointerInitialize(pScreen, &loriePointerSpriteFuncs, &loriePointerCursorFuncs, TRUE) + || !fbCreateDefColormap(pScreen)) + return FALSE; + + wrap(pvfb, pScreen, CreateScreenResources, lorieCreateScreenResources) + wrap(pvfb, pScreen, CloseScreen, lorieCloseScreen) + + QueueWorkProc(resetRootCursor, NULL, NULL); + ShmRegisterFbFuncs(pScreen); + + return TRUE; +} /* end lorieScreenInit */ + +// From xfixes/cursor.c +static CursorPtr +CursorForDevice(DeviceIntPtr pDev) { + if (!CursorVisible || !EnableCursor) + return NULL; + + if (pDev && pDev->spriteInfo) { + if (pDev->spriteInfo->anim.pCursor) + return pDev->spriteInfo->anim.pCursor; + return pDev->spriteInfo->sprite ? pDev->spriteInfo->sprite->current : NULL; + } + + return NULL; +} + +Bool lorieChangeScreenName(unused ClientPtr pClient, void *closure) { + RROutputPtr output = RRFirstOutput(pScreenPtr); + memset(output->name, 0, 1024); + strncpy(output->name, closure, 1024); + output->name[1023] = '\0'; + output->nameLength = strlen(output->name); + free(closure); + return TRUE; +} + +Bool lorieChangeWindow(unused ClientPtr pClient, void *closure) { + jobject surface = (jobject) closure; + renderer_set_window(pvfb->env, surface, pvfb->root.buffer); + lorieSetCursor(NULL, NULL, CursorForDevice(GetMaster(lorieMouse, MASTER_POINTER)), -1, -1); + + if (pvfb->root.legacyDrawing) { + renderer_update_root(pScreenPtr->width, pScreenPtr->height, ((PixmapPtr) pScreenPtr->devPrivate)->devPrivate.ptr, pvfb->root.flip); + renderer_redraw(pvfb->env, pvfb->root.flip); + } + + return TRUE; +} + +void lorieConfigureNotify(int width, int height, int framerate) { + ScreenPtr pScreen = pScreenPtr; + RROutputPtr output = RRFirstOutput(pScreen); + + if (output && width && height && (pScreen->width != width || pScreen->height != height)) { + CARD32 mmWidth, mmHeight; + RRModePtr mode = lorieCvt(width, height, framerate); + mmWidth = ((double) (mode->mode.width)) * 25.4 / monitorResolution; + mmHeight = ((double) (mode->mode.width)) * 25.4 / monitorResolution; + RROutputSetModes(output, &mode, 1, 0); + RRCrtcNotify(RRFirstEnabledCrtc(pScreen), mode,0, 0,RR_Rotate_0, NULL, 1, &output); + RRScreenSizeSet(pScreen, mode->mode.width, mode->mode.height, mmWidth, mmHeight); + } + + if (framerate > 0) { + long nsecs = 1000 * 1000 * 1000 / framerate; + struct itimerspec spec = { { 0, nsecs }, { 0, nsecs } }; + timerfd_settime(lorieScreen.timerFd, 0, &spec, NULL); + log(VERBOSE, "New framerate is %d", framerate); + + FakeScreenFps = framerate; + present_fake_screen_init(pScreen); + } +} + +void +InitOutput(ScreenInfo * screen_info, int argc, char **argv) { + int depths[] = { 1, 4, 8, 15, 16, 24, 32 }; + int bpp[] = { 1, 8, 8, 16, 16, 32, 32 }; + int i; + + if (monitorResolution == 0) + monitorResolution = 96; + + for(i = 0; i < ARRAY_SIZE(depths); i++) { + screen_info->formats[i].depth = depths[i]; + screen_info->formats[i].bitsPerPixel = bpp[i]; + screen_info->formats[i].scanlinePad = BITMAP_SCANLINE_PAD; + } + + screen_info->imageByteOrder = IMAGE_BYTE_ORDER; + screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + screen_info->bitmapBitOrder = BITMAP_BIT_ORDER; + screen_info->numPixmapFormats = ARRAY_SIZE(depths); + + renderer_init(pvfb->env, &pvfb->root.legacyDrawing, &pvfb->root.flip); + xorgGlxCreateVendor(); + lorieInitClipboard(); + + if (-1 == AddScreen(lorieScreenInit, argc, argv)) { + FatalError("Couldn't add screen %d\n", i); + } +} + +void lorieSetVM(JavaVM* vm) { + pvfb->vm = vm; + (*vm)->AttachCurrentThread(vm, &pvfb->env, NULL); +} + +static GLboolean drawableSwapBuffers(unused ClientPtr client, unused __GLXdrawable * drawable) { return TRUE; } +static void drawableCopySubBuffer(unused __GLXdrawable * basePrivate, unused int x, unused int y, unused int w, unused int h) {} +static __GLXdrawable * createDrawable(unused ClientPtr client, __GLXscreen * screen, DrawablePtr pDraw, + unused XID drawId, int type, XID glxDrawId, __GLXconfig * glxConfig) { + __GLXdrawable *private = calloc(1, sizeof *private); + if (private == NULL) + return NULL; + + if (!__glXDrawableInit(private, screen, pDraw, type, glxDrawId, glxConfig)) { + free(private); + return NULL; + } + + private->destroy = (void (*)(__GLXdrawable *)) free; + private->swapBuffers = drawableSwapBuffers; + private->copySubBuffer = drawableCopySubBuffer; + + return private; +} + +static void glXDRIscreenDestroy(__GLXscreen *baseScreen) { + free(baseScreen->GLXextensions); + free(baseScreen->GLextensions); + free(baseScreen->visuals); + free(baseScreen); +} + +static __GLXscreen *glXDRIscreenProbe(ScreenPtr pScreen) { + __GLXscreen *screen; + + screen = calloc(1, sizeof *screen); + if (screen == NULL) + return NULL; + + screen->destroy = glXDRIscreenDestroy; + screen->createDrawable = createDrawable; + screen->pScreen = pScreen; + screen->fbconfigs = configs; + screen->glvnd = "mesa"; + + __glXInitExtensionEnableBits(screen->glx_enable_bits); + /* There is no real GLX support, but anyways swrast reports it. */ + __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_no_config_context"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_no_error"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_profile"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_create_context_es_profile"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_create_context_es2_profile"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_framebuffer_sRGB"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_fbconfig_float"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); + __glXScreenInit(screen, pScreen); + + return screen; +} + +__GLXprovider __glXDRISWRastProvider = { + glXDRIscreenProbe, + "DRISWRAST", + NULL +}; diff --git a/android/app/src/main/cpp/lorie/InputXKB.c b/android/app/src/main/cpp/lorie/InputXKB.c new file mode 100644 index 0000000..b7d325a --- /dev/null +++ b/android/app/src/main/cpp/lorie/InputXKB.c @@ -0,0 +1,898 @@ +/* Copyright (C) 2009 TightVNC Team + * Copyright (C) 2009 Red Hat, Inc. + * Copyright 2013-2018 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma ide diagnostic ignored "UnusedValue" +#pragma ide diagnostic ignored "ConstantParameter" +#pragma ide diagnostic ignored "misc-no-recursion" +#pragma ide diagnostic ignored "OCDFAInspection" +#pragma clang diagnostic ignored "-Wdeclaration-after-statement" + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include +#include "xkbsrv.h" +#include "xkbstr.h" +#include "eventstr.h" +#include "scrnintstr.h" +#include "mi.h" + +#include +#include + +#ifndef KEYBOARD_OR_FLOAT +#define KEYBOARD_OR_FLOAT MASTER_KEYBOARD +#endif + +#define unused __attribute__((__unused__)) + +extern DeviceIntPtr lorieKeyboard; + +static const KeyCode fakeKeys[] = { + 92, 203, 204, 205, 206, 207 + }; + +static KeySym pressedKeys[256] = {0}; + +/* altKeysym is a table of alternative keysyms which have the same meaning. */ + +static struct altKeysym_t { + KeySym a, b; +} altKeysym[] = { + { XK_Shift_L, XK_Shift_R }, + { XK_Control_L, XK_Control_R }, + { XK_Meta_L, XK_Meta_R }, + { XK_Alt_L, XK_Alt_R }, + { XK_Super_L, XK_Super_R }, + { XK_Hyper_L, XK_Hyper_R }, + { XK_KP_Space, XK_space }, + { XK_KP_Tab, XK_Tab }, + { XK_KP_Enter, XK_Return }, + { XK_KP_F1, XK_F1 }, + { XK_KP_F2, XK_F2 }, + { XK_KP_F3, XK_F3 }, + { XK_KP_F4, XK_F4 }, + { XK_KP_Home, XK_Home }, + { XK_KP_Left, XK_Left }, + { XK_KP_Up, XK_Up }, + { XK_KP_Right, XK_Right }, + { XK_KP_Down, XK_Down }, + { XK_KP_Page_Up, XK_Page_Up }, + { XK_KP_Page_Down, XK_Page_Down }, + { XK_KP_End, XK_End }, + { XK_KP_Begin, XK_Begin }, + { XK_KP_Insert, XK_Insert }, + { XK_KP_Delete, XK_Delete }, + { XK_KP_Equal, XK_equal }, + { XK_KP_Multiply, XK_asterisk }, + { XK_KP_Add, XK_plus }, + { XK_KP_Separator, XK_comma }, + { XK_KP_Subtract, XK_minus }, + { XK_KP_Decimal, XK_period }, + { XK_KP_Divide, XK_slash }, + { XK_KP_0, XK_0 }, + { XK_KP_1, XK_1 }, + { XK_KP_2, XK_2 }, + { XK_KP_3, XK_3 }, + { XK_KP_4, XK_4 }, + { XK_KP_5, XK_5 }, + { XK_KP_6, XK_6 }, + { XK_KP_7, XK_7 }, + { XK_KP_8, XK_8 }, + { XK_KP_9, XK_9 }, + { XK_ISO_Level3_Shift, XK_Mode_switch }, +}; + +void lorieKeysymKeyboardEvent(KeySym keysym, int down); +KeyCode lorieKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state); + +/* Stolen from libX11 */ +static Bool +XkbTranslateKeyCode(register XkbDescPtr xkb, KeyCode key, + register unsigned int mods, unsigned int *mods_rtrn, + KeySym *keysym_rtrn) { + XkbKeyTypeRec *type; + int col,nKeyGroups; + unsigned preserve,effectiveGroup; + KeySym *syms; + + if (mods_rtrn!=NULL) + *mods_rtrn = 0; + + nKeyGroups= XkbKeyNumGroups(xkb,key); + if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) { + if (keysym_rtrn!=NULL) + *keysym_rtrn = NoSymbol; + return FALSE; + } + + syms = XkbKeySymsPtr(xkb,key); + + /* find the offset of the effective group */ + col = 0; + effectiveGroup= XkbGroupForCoreState(mods); + if ( effectiveGroup>=nKeyGroups ) { + unsigned groupInfo= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(groupInfo)) { + default: + effectiveGroup %= nKeyGroups; + break; + case XkbClampIntoRange: + effectiveGroup = nKeyGroups-1; + break; + case XkbRedirectIntoRange: + effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo); + if (effectiveGroup>=nKeyGroups) + effectiveGroup= 0; + break; + } + } + col= (int) effectiveGroup * XkbKeyGroupsWidth(xkb,key); + type = XkbKeyKeyType(xkb,key,effectiveGroup); + + preserve= 0; + if (type->map) { /* find the column (shift level) within the group */ + register int i; + register XkbKTMapEntryPtr entry; + for (i=0,entry=type->map;imap_count;i++,entry++) { + if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) { + col+= entry->level; + if (type->preserve) + preserve= type->preserve[i].mask; + break; + } + } + } + + if (keysym_rtrn!=NULL) + *keysym_rtrn= syms[col]; + if (mods_rtrn) + *mods_rtrn= type->mods.mask&(~preserve); + + return (syms[col]!=NoSymbol); +} + +static XkbAction *XkbKeyActionPtr(XkbDescPtr xkb, KeyCode key, unsigned int mods) { + XkbKeyTypeRec *type; + int col,nKeyGroups; + unsigned effectiveGroup; + unused XkbAction *acts; + + if (!XkbKeyHasActions(xkb, key)) + return NULL; + + nKeyGroups= XkbKeyNumGroups(xkb,key); + if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) + return NULL; + + acts = XkbKeyActionsPtr(xkb,key); + + /* find the offset of the effective group */ + col = 0; + effectiveGroup= XkbGroupForCoreState(mods); + if ( effectiveGroup>=nKeyGroups ) { + unsigned groupInfo= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(groupInfo)) { + default: + effectiveGroup %= nKeyGroups; + break; + case XkbClampIntoRange: + effectiveGroup = nKeyGroups-1; + break; + case XkbRedirectIntoRange: + effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo); + if (effectiveGroup>=nKeyGroups) + effectiveGroup= 0; + break; + } + } + col= (int) effectiveGroup * XkbKeyGroupsWidth(xkb,key); + type = XkbKeyKeyType(xkb,key,effectiveGroup); + + if (type->map) { /* find the column (shift level) within the group */ + register int i; + register XkbKTMapEntryPtr entry; + for (i=0,entry=type->map;imap_count;i++,entry++) { + if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) { + col+= entry->level; + break; + } + } + } + + return &acts[col]; +} + +static unsigned XkbKeyEffectiveGroup(XkbDescPtr xkb, KeyCode key, unsigned int mods) { + int nKeyGroups; + unsigned effectiveGroup; + + nKeyGroups= XkbKeyNumGroups(xkb,key); + if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) + return 0; + + effectiveGroup= XkbGroupForCoreState(mods); + if ( effectiveGroup>=nKeyGroups ) { + unsigned groupInfo= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(groupInfo)) { + default: + effectiveGroup %= nKeyGroups; + break; + case XkbClampIntoRange: + effectiveGroup = nKeyGroups-1; + break; + case XkbRedirectIntoRange: + effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo); + if (effectiveGroup>=nKeyGroups) + effectiveGroup= 0; + break; + } + } + + return effectiveGroup; +} + +static unsigned lorieGetKeyboardState(void) { + DeviceIntPtr master; + + master = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT); + return XkbStateFieldFromRec(&master->key->xkbInfo->state); +} + +static unsigned lorieGetLevelThreeMask(void) { + unsigned state; + KeyCode keycode; + XkbDescPtr xkb; + XkbAction *act; + + /* Group state is still important */ + state = lorieGetKeyboardState(); + state &= ~0xff; + + keycode = lorieKeysymToKeycode(XK_ISO_Level3_Shift, state, NULL); + if (keycode == 0) { + keycode = lorieKeysymToKeycode(XK_Mode_switch, state, NULL); + if (keycode == 0) + return 0; + } + + xkb = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + + act = XkbKeyActionPtr(xkb, keycode, state); + if (act == NULL) + return 0; + if (act->type != XkbSA_SetMods) + return 0; + + if (act->mods.flags & XkbSA_UseModMapMods) + return xkb->map->modmap[keycode]; + else + return act->mods.mask; +} + +static KeyCode loriePressShift(void) { + unsigned state; + + XkbDescPtr xkb; + unsigned int key; + + state = lorieGetKeyboardState(); + if (state & ShiftMask) + return 0; + + xkb = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + XkbAction *act; + unsigned char mask; + + act = XkbKeyActionPtr(xkb, key, state); + if (act == NULL) + continue; + + if (act->type != XkbSA_SetMods) + continue; + + if (act->mods.flags & XkbSA_UseModMapMods) + mask = xkb->map->modmap[key]; + else + mask = act->mods.mask; + + if ((mask & ShiftMask) == ShiftMask) + return key; + } + + return 0; +} + +static size_t lorieReleaseShift(KeyCode *keys, size_t maxKeys) { + size_t count; + + unsigned state; + + DeviceIntPtr master; + XkbDescPtr xkb; + unsigned int key; + + state = lorieGetKeyboardState(); + if (!(state & ShiftMask)) + return 0; + + count = 0; + + master = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT); + xkb = master->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + XkbAction *act; + unsigned char mask; + + if (!key_is_down(master, (int) key, KEY_PROCESSED)) + continue; + + act = XkbKeyActionPtr(xkb, key, state); + if (act == NULL) + continue; + + if (act->type != XkbSA_SetMods) + continue; + + if (act->mods.flags & XkbSA_UseModMapMods) + mask = xkb->map->modmap[key]; + else + mask = act->mods.mask; + + if (!(mask & ShiftMask)) + continue; + + if (count >= maxKeys) + return 0; + + keys[count++] = key; + } + + return count; +} + +static KeyCode loriePressLevelThree(void) { + unsigned state, mask; + + KeyCode keycode; + XkbDescPtr xkb; + XkbAction *act; + + mask = lorieGetLevelThreeMask(); + if (mask == 0) + return 0; + + state = lorieGetKeyboardState(); + if (state & mask) + return 0; + + keycode = lorieKeysymToKeycode(XK_ISO_Level3_Shift, state, NULL); + if (keycode == 0) { + keycode = lorieKeysymToKeycode(XK_Mode_switch, state, NULL); + if (keycode == 0) + return 0; + } + + xkb = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + + act = XkbKeyActionPtr(xkb, keycode, state); + if (act == NULL) + return 0; + if (act->type != XkbSA_SetMods) + return 0; + + return keycode; +} + +static size_t lorieReleaseLevelThree(KeyCode *keys, size_t maxKeys) { + size_t count; + + unsigned state, mask; + + DeviceIntPtr master; + XkbDescPtr xkb; + unsigned int key; + + mask = lorieGetLevelThreeMask(); + if (mask == 0) + return 0; + + state = lorieGetKeyboardState(); + if (!(state & mask)) + return 0; + + count = 0; + + master = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT); + xkb = master->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + XkbAction *act; + unsigned char key_mask; + + if (!key_is_down(master, (int) key, KEY_PROCESSED)) + continue; + + act = XkbKeyActionPtr(xkb, key, state); + if (act == NULL) + continue; + + if (act->type != XkbSA_SetMods) + continue; + + if (act->mods.flags & XkbSA_UseModMapMods) + key_mask = xkb->map->modmap[key]; + else + key_mask = act->mods.mask; + + if (!(key_mask & mask)) + continue; + + if (count >= maxKeys) + return 0; + + keys[count++] = key; + } + + return count; +} + +KeyCode lorieKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state) { + XkbDescPtr xkb; + unsigned int key; // KeyCode has insufficient range for the loop + KeyCode fallback; + KeySym ks; + unsigned level_three_mask; + + if (new_state != NULL) + *new_state = state; + + fallback = 0; + xkb = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + unsigned int state_out; + KeySym dummy; + size_t fakeIdx; + + XkbTranslateKeyCode(xkb, key, state, &state_out, &ks); + if (ks == NoSymbol) + continue; + + /* + * Despite every known piece of documentation on + * XkbTranslateKeyCode() stating that mods_rtrn returns + * the unconsumed modifiers, in reality it always + * returns the _potentially consumed_ modifiers. + */ + state_out = state & ~state_out; + if (state_out & LockMask) + XkbConvertCase(ks, &dummy, &ks); + + if (ks != keysym) + continue; + + /* + * Some keys are never sent by a real keyboard and are + * used in the default layouts as a fallback for + * modifiers. Make sure we use them last as some + * applications can be confused by these normally + * unused keys. + */ + for (fakeIdx = 0; fakeIdx < ARRAY_SIZE(fakeKeys); fakeIdx++) { + if (key == fakeKeys[fakeIdx]) { + if (fallback == 0) + fallback = key; + break; + } + } + if (fakeIdx < ARRAY_SIZE(fakeKeys)) + continue; + + return key; + } + + /* Use the fallback key, if one was found */ + if (fallback != 0) + return fallback; + + if (new_state == NULL) + return 0; + + *new_state = (state & ~ShiftMask) | ((state & ShiftMask) ? 0 : ShiftMask); + key = lorieKeysymToKeycode(keysym, *new_state, NULL); + if (key != 0) + return key; + + level_three_mask = lorieGetLevelThreeMask(); + if (level_three_mask == 0) + return 0; + + *new_state = (state & ~level_three_mask) | + ((state & level_three_mask) ? 0 : level_three_mask); + key = lorieKeysymToKeycode(keysym, *new_state, NULL); + if (key != 0) + return key; + + *new_state = (state & ~(ShiftMask | level_three_mask)) | + ((state & ShiftMask) ? 0 : ShiftMask) | + ((state & level_three_mask) ? 0 : level_three_mask); + key = lorieKeysymToKeycode(keysym, *new_state, NULL); + if (key != 0) + return key; + + return 0; +} + +static int lorieIsAffectedByNumLock(KeyCode keycode) { + unsigned state; + + KeyCode numlock_keycode; + unsigned numlock_mask; + + XkbDescPtr xkb; + XkbAction *act; + + XkbKeyTypeRec *type; + + /* Group state is still important */ + state = lorieGetKeyboardState(); + state &= ~0xff; + + /* + * Not sure if hunting for a virtual modifier called "NumLock", + * or following the keysym Num_Lock is the best approach. We + * try the latter. + */ + numlock_keycode = lorieKeysymToKeycode(XK_Num_Lock, state, NULL); + if (numlock_keycode == 0) + return 0; + + xkb = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + + act = XkbKeyActionPtr(xkb, numlock_keycode, state); + if (act == NULL) + return 0; + if (act->type != XkbSA_LockMods) + return 0; + + if (act->mods.flags & XkbSA_UseModMapMods) + numlock_mask = xkb->map->modmap[keycode]; + else + numlock_mask = act->mods.mask; + + type = XkbKeyKeyType(xkb, keycode, XkbKeyEffectiveGroup(xkb, keycode, state)); + if ((type->mods.mask & numlock_mask) == 0) + return 0; + + return 1; +} + +static KeyCode lorieAddKeysym(KeySym keysym, unused unsigned state) { + DeviceIntPtr master; + XkbDescPtr xkb; + unsigned int key; + + XkbEventCauseRec cause; + XkbChangesRec changes; + + int types[1]; + KeySym *syms; + KeySym upper, lower; + + master = GetMaster(lorieKeyboard, KEYBOARD_OR_FLOAT); + xkb = master->key->xkbInfo->desc; + + static int curFakeKeyIdx = 0; + key = fakeKeys[curFakeKeyIdx++]; + if (curFakeKeyIdx >= ARRAY_SIZE(fakeKeys)) + curFakeKeyIdx = 0; + + memset(&changes, 0, sizeof(changes)); + memset(&cause, 0, sizeof(cause)); + + XkbSetCauseUnknown(&cause) + + /* + * Tools like xkbcomp get confused if there isn't a name + * assigned to the keycode we're trying to use. + */ + if (xkb->names && xkb->names->keys && + (xkb->names->keys[key].name[0] == '\0')) { + xkb->names->keys[key].name[0] = 'I'; + xkb->names->keys[key].name[1] = '0' + (key / 100) % 10; + xkb->names->keys[key].name[2] = '0' + (key / 10) % 10; + xkb->names->keys[key].name[3] = '0' + (key / 1) % 10; + + changes.names.changed |= XkbKeyNamesMask; + changes.names.first_key = key; + changes.names.num_keys = 1; + } + + XkbConvertCase(keysym, &lower, &upper); + types[XkbGroup1Index] = XkbAlphabeticIndex; + + XkbChangeTypesOfKey(xkb, (int) key, 1, XkbGroup1Mask, types, &changes.map); + + syms = XkbKeySymsPtr(xkb, key); + syms[0] = lower; + syms[1] = upper; + + changes.map.changed |= XkbKeySymsMask; + changes.map.first_key_sym = key; + changes.map.num_key_syms = 1; + + XkbSendNotification(master, &changes, &cause); + + return key; +} + +/* + * lorieKeysymKeyboardEvent() - work out the best keycode corresponding + * to the keysym sent by the viewer. This is basically impossible in + * the general case, but we make a best effort by assuming that all + * useful keysyms can be reached using just the Shift and + * Level 3 (AltGr) modifiers. For core keyboards this is basically + * always true, and should be true for most sane, western XKB layouts. + */ +void lorieKeysymKeyboardEvent(KeySym keysym, int down) { + int i; + unsigned state, new_state; + KeyCode keycode; + + unsigned level_three_mask; + KeyCode shift_press, level_three_press; + KeyCode shift_release[8], level_three_release[8]; + size_t shift_release_count, level_three_release_count; + + /* + * Release events must match the press event, so look up what + * keycode we sent for the press. + */ + if (!down) { + for (i = 0;i < 256;i++) { + if (pressedKeys[i] == keysym) { + pressedKeys[i] = NoSymbol; + QueueKeyboardEvents(lorieKeyboard, KeyRelease, i); // "keycode" + mieqProcessInputEvents(); + return; + } + } + + /* + * This can happen quite often as we ignore some + * key presses. + */ + LogMessageVerb(X_DEBUG, -1, "Unexpected release of keysym 0x%x\n", keysym); + return; + } + + /* + * Since we are checking the current state to determine if we need + * to fake modifiers, we must make sure that everything put on the + * input queue is processed before we start. Otherwise, shift may be + * stuck down. + */ + mieqProcessInputEvents(); + + state = lorieGetKeyboardState(); + + keycode = lorieKeysymToKeycode(keysym, state, &new_state); + + /* Try some equivalent keysyms if we couldn't find a perfect match */ + if (keycode == 0) { + for (i = 0;i < sizeof(altKeysym)/sizeof(altKeysym[0]);i++) { + KeySym altsym; + + if (altKeysym[i].a == keysym) + altsym = altKeysym[i].b; + else if (altKeysym[i].b == keysym) + altsym = altKeysym[i].a; + else + continue; + + keycode = lorieKeysymToKeycode(altsym, state, &new_state); + if (keycode != 0) + break; + } + } + + /* No matches. Will have to add a new entry... */ + if (keycode == 0) { + keycode = lorieAddKeysym(keysym, state); + if (keycode == 0) { + LogMessageVerb(X_ERROR, -1, "Failure adding new keysym 0x%x\n", keysym); + return; + } + + LogMessageVerb(X_INFO, 0, "Added unknown keysym 0x%x to keycode %d\n", + keysym, keycode); + + /* + * The state given to addKeysym() is just a hint and + * the actual result might still require some state + * changes. + */ + keycode = lorieKeysymToKeycode(keysym, state, &new_state); + if (keycode == 0) { + LogMessageVerb(X_ERROR, -1, "Newly added keysym 0x%x cannot be generated\n", keysym); + return; + } + } + + /* + * X11 generally lets shift toggle the keys on the numeric pad + * the same way NumLock does. This is however not the case on + * other systems like Windows. As a result, some applications + * get confused when we do a fake shift to get the same effect + * that having NumLock active would produce. + * + * Not all clients have proper NumLock synchronisation (so we + * can avoid faking shift) so we try to avoid the fake shifts + * if we can use an alternative keysym. + */ + if (((state & ShiftMask) != (new_state & ShiftMask)) && lorieIsAffectedByNumLock(keycode)) { + KeyCode keycode2; + unsigned new_state2; + + LogMessageVerb(X_DEBUG, 0, "Finding alternative to keysym 0x%x to avoid fake shift for numpad\n", keysym); + + for (i = 0;i < sizeof(altKeysym)/sizeof(altKeysym[0]);i++) { + KeySym altsym; + + if (altKeysym[i].a == keysym) + altsym = altKeysym[i].b; + else if (altKeysym[i].b == keysym) + altsym = altKeysym[i].a; + else + continue; + + keycode2 = lorieKeysymToKeycode(altsym, state, &new_state2); + if (keycode2 == 0) + continue; + + if (((state & ShiftMask) != (new_state2 & ShiftMask)) && + lorieIsAffectedByNumLock(keycode2)) + continue; + + break; + } + + if (i == sizeof(altKeysym)/sizeof(altKeysym[0])) + LogMessageVerb(X_DEBUG, 0, "No alternative keysym found\n"); + else { + keycode = keycode2; + new_state = new_state2; + } + } + + /* + * "Shifted Tab" is a bit of a mess. Some systems have varying, + * special keysyms for this symbol. VNC mandates that clients + * should always send the plain XK_Tab keysym and the server + * should deduce the meaning based on current Shift state. + * To comply with this, we will find the keycode that sends + * XK_Tab, and make sure that Shift isn't cleared. This can + * possibly result in a different keysym than XK_Tab, but that + * is the desired behaviour. + * + * Note: We never get ISO_Left_Tab here because it's already + * been translated in VNCSConnectionST. + */ + if (keysym == XK_Tab && (state & ShiftMask)) + new_state |= ShiftMask; + + /* + * We need a bigger state change than just shift, + * so we need to know what the mask is for level 3 shifts. + */ + if ((new_state & ~ShiftMask) != (state & ~ShiftMask)) + level_three_mask = lorieGetLevelThreeMask(); + else + level_three_mask = 0; + + shift_press = level_three_press = 0; + shift_release_count = level_three_release_count = 0; + + /* Need a fake press or release of shift? */ + if (!(state & ShiftMask) && (new_state & ShiftMask)) { + shift_press = loriePressShift(); + if (shift_press == 0) { + LogMessageVerb(X_ERROR, -1, "Unable to find a modifier key for Shift\n"); + return; + } + + QueueKeyboardEvents(lorieKeyboard, KeyPress, shift_press); // "temp shift" + } else if ((state & ShiftMask) && !(new_state & ShiftMask)) { + shift_release_count = lorieReleaseShift(shift_release, + sizeof(shift_release)/sizeof(*shift_release)); + if (shift_release_count == 0) { + LogMessageVerb(X_ERROR, -1, "Unable to find the modifier key(s) for releasing Shift\n"); + return; + } + + for (i = 0;i < shift_release_count;i++) + QueueKeyboardEvents(lorieKeyboard, KeyRelease, shift_release[i]); // "temp shift" + } + + /* Need a fake press or release of level three shift? */ + if (!(state & level_three_mask) && (new_state & level_three_mask)) { + level_three_press = loriePressLevelThree(); + if (level_three_press == 0) { + LogMessageVerb(X_ERROR, -1, "Unable to find a modifier key for ISO_Level3_Shift/Mode_Switch\n"); + return; + } + + QueueKeyboardEvents(lorieKeyboard, KeyPress, level_three_press); // "temp level 3 shift" + } else if ((state & level_three_mask) && !(new_state & level_three_mask)) { + level_three_release_count = lorieReleaseLevelThree(level_three_release, + sizeof(level_three_release)/sizeof(*level_three_release)); + if (level_three_release_count == 0) { + LogMessageVerb(X_ERROR, -1, "Unable to find the modifier key(s) for releasing ISO_Level3_Shift/Mode_Switch\n"); + return; + } + + for (i = 0;i < level_three_release_count;i++) + QueueKeyboardEvents(lorieKeyboard, KeyRelease, level_three_release[i]); // "temp level 3 shift" + } + + /* Now press the actual key */ + QueueKeyboardEvents(lorieKeyboard, KeyPress, keycode); // "keycode" + + /* And store the mapping so that we can do a proper release later */ + for (i = 0;i < 256;i++) { + if (i == keycode) + continue; + if (pressedKeys[i] == keysym) { + LogMessageVerb(X_ERROR, -1, "Keysym 0x%x generated by both keys %d and %d", keysym, i, keycode); + pressedKeys[i] = NoSymbol; + } + } + + pressedKeys[keycode] = keysym; + + /* Undo any fake level three shift */ + if (level_three_press != 0) + QueueKeyboardEvents(lorieKeyboard, KeyRelease, level_three_press); // "temp level 3 shift" + else if (level_three_release_count != 0) { + for (i = 0;i < level_three_release_count;i++) + QueueKeyboardEvents(lorieKeyboard, KeyPress, level_three_release[i]); // "temp level 3 shift" + } + + /* Undo any fake shift */ + if (shift_press != 0) + QueueKeyboardEvents(lorieKeyboard, KeyRelease, shift_press); // "temp shift" + else if (shift_release_count != 0) { + for (i = 0;i < shift_release_count;i++) + QueueKeyboardEvents(lorieKeyboard, KeyPress, shift_release[i]); // "temp shift" + } + + /* + * When faking a modifier we are putting a keycode (which can + * currently activate the desired modifier) on the input + * queue. A future modmap change can change the mapping so + * that this keycode means something else entirely. Guard + * against this by processing the queue now. + */ + mieqProcessInputEvents(); +} diff --git a/android/app/src/main/cpp/lorie/android.c b/android/app/src/main/cpp/lorie/android.c new file mode 100644 index 0000000..33ced72 --- /dev/null +++ b/android/app/src/main/cpp/lorie/android.c @@ -0,0 +1,772 @@ +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma ide diagnostic ignored "bugprone-reserved-identifier" +#pragma ide diagnostic ignored "OCUnusedMacroInspection" +#define __USE_GNU +#ifdef HAVE_DIX_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "renderer.h" +#include "lorie.h" + +#define log(prio, ...) __android_log_print(ANDROID_LOG_ ## prio, "LorieNative", __VA_ARGS__) + +static int argc = 0; +static char** argv = NULL; +static int conn_fd = -1; +extern char *__progname; // NOLINT(bugprone-reserved-identifier) +extern DeviceIntPtr lorieMouse, lorieTouch, lorieKeyboard, loriePen, lorieEraser; +extern ScreenPtr pScreenPtr; +extern int ucs2keysym(long ucs); +void lorieKeysymKeyboardEvent(KeySym keysym, int down); + +char *xtrans_unix_path_x11 = NULL; +char *xtrans_unix_dir_x11 = NULL; + +typedef enum { + EVENT_SCREEN_SIZE, + EVENT_TOUCH, + EVENT_MOUSE, + EVENT_KEY, + EVENT_STYLUS, + EVENT_STYLUS_ENABLE, + EVENT_UNICODE, + EVENT_CLIPBOARD_ENABLE, + EVENT_CLIPBOARD_ANNOUNCE, + EVENT_CLIPBOARD_REQUEST, + EVENT_CLIPBOARD_SEND, +} eventType; +typedef union { + uint8_t type; + struct { + uint8_t t; + uint16_t width, height, framerate; + } screenSize; + struct { + uint8_t t; + uint16_t type, id, x, y; + } touch; + struct { + uint8_t t; + float x, y; + uint8_t detail, down, relative; + } mouse; + struct { + uint8_t t; + uint16_t key; + uint8_t state; + } key; + struct { + uint8_t t; + float x, y; + uint16_t pressure; + int8_t tilt_x, tilt_y; + int16_t orientation; + uint8_t buttons, eraser, mouse; + } stylus; + struct { + uint8_t t, enable; + } stylusEnable; + struct { + uint8_t t; + uint32_t code; + } unicode; + struct { + uint8_t t; + uint8_t enable; + } clipboardEnable; + struct { + uint8_t t; + uint32_t count; + } clipboardSend; +} lorieEvent; + +static struct { + jclass self; + jmethodID forName; + jmethodID decode; +} Charset = {0}; + +static struct { + jclass self; + jmethodID toString; +} CharBuffer = {0}; + +static void* startServer(__unused void* cookie) { + lorieSetVM((JavaVM*) cookie); + char* envp[] = { NULL }; + exit(dix_main(argc, (char**) argv, envp)); +} + +static jclass FindClassOrDie(JNIEnv *env, const char* name) { + jclass clazz = (*env)->FindClass(env, name); + if (!clazz) { + char buffer[1024] = {0}; + sprintf(buffer, "class %s not found", name); + log(ERROR, "%s", buffer); + (*env)->FatalError(env, buffer); + return NULL; + } + + return (*env)->NewGlobalRef(env, clazz); +} + +static jclass FindMethodOrDie(JNIEnv *env, jclass clazz, const char* name, const char* signature, jboolean isStatic) { + __typeof__((*env)->GetMethodID) getMethodID = isStatic ? (*env)->GetStaticMethodID : (*env)->GetMethodID; + jmethodID method = getMethodID(env, clazz, name, signature); + if (!method) { + char buffer[1024] = {0}; + sprintf(buffer, "method %s %s not found", name, signature); + log(ERROR, "%s", buffer); + (*env)->FatalError(env, buffer); + return NULL; + } + + return method; +} + +JNIEXPORT jboolean JNICALL +Java_com_termux_x11_CmdEntryPoint_start(JNIEnv *env, __unused jclass cls, jobjectArray args) { + pthread_t t; + JavaVM* vm = NULL; + // execv's argv array is a bit incompatible with Java's String[], so we do some converting here... + argc = (*env)->GetArrayLength(env, args) + 1; // Leading executable path + argv = (char**) calloc(argc, sizeof(char*)); + + argv[0] = (char*) "Xlorie"; + for(int i=1; iGetObjectArrayElement(env, args, i - 1)); + const char *pjc = (*env)->GetStringUTFChars(env, js, JNI_FALSE); + argv[i] = (char *) calloc(strlen(pjc) + 1, sizeof(char)); //Extra char for the terminating NULL + strcpy((char *) argv[i], pjc); + (*env)->ReleaseStringUTFChars(env, js, pjc); + } + + { + cpu_set_t mask; + long num_cpus = sysconf(_SC_NPROCESSORS_ONLN); + + for (int i = num_cpus/2; i < num_cpus; i++) + CPU_SET(i, &mask); + + if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) + log(ERROR, "Failed to set process affinity: %s", strerror(errno)); + } + + if (getenv("TERMUX_X11_DEBUG") && !fork()) { + // Printing logs of local logcat. + char pid[32] = {0}; + prctl(PR_SET_PDEATHSIG, SIGTERM); + sprintf(pid, "%d", getppid()); + execlp("logcat", "logcat", "--pid", pid, NULL); + } + + // adb sets TMPDIR to /data/local/tmp which is pretty useless. + if (!strcmp("/data/local/tmp", getenv("TMPDIR") ?: "")) + unsetenv("TMPDIR"); + + if (!getenv("TMPDIR")) { + if (access("/tmp", F_OK) == 0) + setenv("TMPDIR", "/tmp", 1); + else if (access("/data/data/com.termux/files/usr/tmp", F_OK) == 0) + setenv("TMPDIR", "/data/data/com.termux/files/usr/tmp", 1); + } + + if (!getenv("TMPDIR")) { + char* error = (char*) "$TMPDIR is not set. Normally it is pointing to /tmp of a container."; + log(ERROR, "%s", error); + dprintf(2, "%s\n", error); + return JNI_FALSE; + } + + { + char* tmp = getenv("TMPDIR"); + char cwd[1024] = {0}; + + if (!getcwd(cwd, sizeof(cwd)) || access(cwd, F_OK) != 0) + chdir(tmp); + asprintf(&xtrans_unix_path_x11, "%s/.X11-unix/X", tmp); + asprintf(&xtrans_unix_dir_x11, "%s/.X11-unix/", tmp); + } + + log(VERBOSE, "Using TMPDIR=\"%s\"", getenv("TMPDIR")); + + { + const char *root_dir = dirname(getenv("TMPDIR")); + const char* pathes[] = { + "/etc/X11/fonts", "/usr/share/fonts/X11", "/share/fonts", NULL + }; + for (int i=0; pathes[i]; i++) { + char current_path[1024] = {0}; + snprintf(current_path, sizeof(current_path), "%s%s", root_dir, pathes[i]); + if (access(current_path, F_OK) == 0) { + char default_font_path[4096] = {0}; + snprintf(default_font_path, sizeof(default_font_path), + "%s/misc,%s/TTF,%s/OTF,%s/Type1,%s/100dpi,%s/75dpi", + current_path, current_path, current_path, current_path, current_path, current_path); + defaultFontPath = strdup(default_font_path); + break; + } + } + } + + if (!getenv("XKB_CONFIG_ROOT")) { + // chroot case + const char *root_dir = dirname(getenv("TMPDIR")); + char current_path[1024] = {0}; + snprintf(current_path, sizeof(current_path), "%s/usr/share/X11/xkb", root_dir); + if (access(current_path, F_OK) == 0) + setenv("XKB_CONFIG_ROOT", current_path, 1); + } + + if (!getenv("XKB_CONFIG_ROOT")) { + // proot case + if (access("/usr/share/X11/xkb", F_OK) == 0) + setenv("XKB_CONFIG_ROOT", "/usr/share/X11/xkb", 1); + // Termux case + else if (access("/data/data/com.termux/files/usr/share/X11/xkb", F_OK) == 0) + setenv("XKB_CONFIG_ROOT", "/data/data/com.termux/files/usr/share/X11/xkb", 1); + } + + if (!getenv("XKB_CONFIG_ROOT")) { + char* error = (char*) "$XKB_CONFIG_ROOT is not set. Normally it is pointing to /usr/share/X11/xkb of a container."; + log(ERROR, "%s", error); + dprintf(2, "%s\n", error); + return JNI_FALSE; + } + + XkbBaseDirectory = getenv("XKB_CONFIG_ROOT"); + if (access(XkbBaseDirectory, F_OK) != 0) { + log(ERROR, "%s is unaccessible: %s\n", XkbBaseDirectory, strerror(errno)); + printf("%s is unaccessible: %s\n", XkbBaseDirectory, strerror(errno)); + return JNI_FALSE; + } + + (*env)->GetJavaVM(env, &vm); + + pthread_create(&t, NULL, startServer, vm); + return JNI_TRUE; +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_CmdEntryPoint_windowChanged(JNIEnv *env, __unused jobject cls, jobject surface, jstring jname) { + const char *name = !jname ? NULL : (*env)->GetStringUTFChars(env, jname, JNI_FALSE); + QueueWorkProc(lorieChangeScreenName, NULL, name ? strndup(name, 1024) : strdup("screen")); + if (name) + (*env)->ReleaseStringUTFChars(env, jname, name); + + QueueWorkProc(lorieChangeWindow, NULL, surface ? (*env)->NewGlobalRef(env, surface) : NULL); +} + +static Bool sendConfigureNotify(__unused ClientPtr pClient, void *closure) { + // This must be done only on X server thread. + lorieEvent* e = closure; + __android_log_print(ANDROID_LOG_ERROR, "tx11-request", "window changed: %d %d", e->screenSize.width, e->screenSize.height); + lorieConfigureNotify(e->screenSize.width, e->screenSize.height, e->screenSize.framerate); + free(e); + return TRUE; +} + +static Bool handleClipboardAnnounce(__unused ClientPtr pClient, __unused void *closure) { + // This must be done only on X server thread. + lorieHandleClipboardAnnounce(); + return TRUE; +} + +static Bool handleClipboardData(__unused ClientPtr pClient, void *closure) { + // This must be done only on X server thread. + lorieHandleClipboardData(closure); + return TRUE; +} + +void handleLorieEvents(int fd, __unused int ready, __unused void *ignored) { + DrawablePtr screenDrawable = &pScreenPtr->GetScreenPixmap(pScreenPtr)->drawable; + ValuatorMask mask; + lorieEvent e = {0}; + valuator_mask_zero(&mask); + + if (ready & X_NOTIFY_ERROR) { + InputThreadUnregisterDev(fd); + close(fd); + conn_fd = -1; + lorieEnableClipboardSync(FALSE); + return; + } + + again: + if (read(fd, &e, sizeof(e)) == sizeof(e)) { + switch(e.type) { + case EVENT_SCREEN_SIZE: { + lorieEvent *copy = calloc(1, sizeof(lorieEvent)); + *copy = e; + QueueWorkProc(sendConfigureNotify, NULL, copy); + break; + } + case EVENT_TOUCH: { + double x = max(min((float) e.touch.x, screenDrawable->width), 0); + double y = max(min((float) e.touch.y, screenDrawable->height), 0); + DDXTouchPointInfoPtr touch = TouchFindByDDXID(lorieTouch, e.touch.id, FALSE); + + // Avoid duplicating events + if (touch && touch->active) { + double oldx = 0, oldy = 0; + if (e.touch.type == XI_TouchUpdate && + valuator_mask_fetch_double(touch->valuators, 0, &oldx) && + valuator_mask_fetch_double(touch->valuators, 1, &oldy) && + oldx == x && oldy == y) + break; + } + + // Sometimes activity part does not send XI_TouchBegin and sends only XI_TouchUpdate. + if (e.touch.type == XI_TouchUpdate && (!touch || !touch->active)) + e.touch.type = XI_TouchBegin; + + if (e.touch.type == XI_TouchEnd && (!touch || !touch->active)) + break; + + valuator_mask_set_double(&mask, 0, x * 0xFFFF / (float) screenDrawable->width); + valuator_mask_set_double(&mask, 1, y * 0xFFFF / (float) screenDrawable->height); + QueueTouchEvents(lorieTouch, e.touch.type, e.touch.id, 0, &mask); + break; + } + case EVENT_STYLUS: { + static int buttons_prev = 0; + uint32_t released, pressed, diff; + DeviceIntPtr device = e.stylus.mouse ? lorieMouse : (e.stylus.eraser ? lorieEraser : loriePen); + if (!device) { + __android_log_print(ANDROID_LOG_DEBUG, "LorieNative", "got stylus event but device is not requested\n"); + break; + } + __android_log_print(ANDROID_LOG_DEBUG, "LorieNative", "got stylus event %f %f %d %d %d %d %s\n", e.stylus.x, e.stylus.y, e.stylus.pressure, e.stylus.tilt_x, e.stylus.tilt_y, e.stylus.orientation, + device == lorieMouse ? "lorieMouse" : (device == loriePen ? "loriePen" : "lorieEraser")); + + valuator_mask_set_double(&mask, 0, max(min(e.stylus.x, screenDrawable->width), 0)); + valuator_mask_set_double(&mask, 1, max(min(e.stylus.y, screenDrawable->height), 0)); + if (device != lorieMouse) { + valuator_mask_set_double(&mask, 2, e.stylus.pressure); + valuator_mask_set_double(&mask, 3, e.stylus.tilt_x); + valuator_mask_set_double(&mask, 4, e.stylus.tilt_y); + valuator_mask_set_double(&mask, 5, e.stylus.orientation); + } + QueuePointerEvents(device, MotionNotify, 0, POINTER_ABSOLUTE | POINTER_DESKTOP | (device == lorieMouse ? POINTER_NORAW : 0), &mask); + + diff = buttons_prev ^ e.stylus.buttons; + released = diff & ~e.stylus.buttons; + pressed = diff & e.stylus.buttons; + + for (int i=0; i<3; i++) { + if (released & 0x1) { + QueuePointerEvents(device, ButtonRelease, i + 1, POINTER_RELATIVE, NULL); + __android_log_print(ANDROID_LOG_DEBUG, "LorieNative", "sending %d press", i+1); + } + if (pressed & 0x1) { + QueuePointerEvents(device, ButtonPress, i + 1, POINTER_RELATIVE, NULL); + __android_log_print(ANDROID_LOG_DEBUG, "LorieNative", "sending %d release", i+1); + } + released >>= 1; + pressed >>= 1; + } + buttons_prev = e.stylus.buttons; + + break; + } + case EVENT_STYLUS_ENABLE: { + lorieSetStylusEnabled(e.stylusEnable.enable); + break; + } + case EVENT_MOUSE: { + int flags; + switch(e.mouse.detail) { + case 0: // BUTTON_UNDEFINED + flags = (e.mouse.relative) ? POINTER_RELATIVE | POINTER_ACCELERATE : POINTER_ABSOLUTE | POINTER_SCREEN | POINTER_NORAW; + if (!e.mouse.relative) { + e.mouse.x = max(0, min(e.mouse.x, screenDrawable->width)); + e.mouse.y = max(0, min(e.mouse.y, screenDrawable->height)); + } + valuator_mask_set_double(&mask, 0, (double) e.mouse.x); + valuator_mask_set_double(&mask, 1, (double) e.mouse.y); + QueuePointerEvents(lorieMouse, MotionNotify, 0, flags, &mask); + break; + case 1: // BUTTON_LEFT + case 2: // BUTTON_MIDDLE + case 3: // BUTTON_RIGHT + QueuePointerEvents(lorieMouse, e.mouse.down ? ButtonPress : ButtonRelease, e.mouse.detail, POINTER_RELATIVE, NULL); + break; + case 4: // BUTTON_SCROLL + if (e.mouse.x) { + valuator_mask_zero(&mask); + valuator_mask_set_double(&mask, 2, (double) e.mouse.x / 120); + QueuePointerEvents(lorieMouse, MotionNotify, 0, POINTER_RELATIVE, &mask); + } + if (e.mouse.y) { + valuator_mask_zero(&mask); + valuator_mask_set_double(&mask, 3, (double) e.mouse.y / 120); + QueuePointerEvents(lorieMouse, MotionNotify, 0, POINTER_RELATIVE, &mask); + } + break; + } + break; + } + case EVENT_KEY: + QueueKeyboardEvents(lorieKeyboard, e.key.state ? KeyPress : KeyRelease, e.key.key); + break; + case EVENT_UNICODE: { + int ks = ucs2keysym((long) e.unicode.code); + __android_log_print(ANDROID_LOG_DEBUG, "LorieNative", "Trying to input keysym %d\n", ks); + lorieKeysymKeyboardEvent(ks, TRUE); + lorieKeysymKeyboardEvent(ks, FALSE); + break; + } + case EVENT_CLIPBOARD_ENABLE: + lorieEnableClipboardSync(e.clipboardEnable.enable); + break; + case EVENT_CLIPBOARD_ANNOUNCE: + QueueWorkProc(handleClipboardAnnounce, NULL, NULL); + break; + case EVENT_CLIPBOARD_SEND: { + char *data = calloc(1, e.clipboardSend.count + 1); + read(conn_fd, data, e.clipboardSend.count); + data[e.clipboardSend.count] = 0; + QueueWorkProc(handleClipboardData, NULL, data); + } + } + + int n; + if (ioctl(fd, FIONREAD, &n) >= 0 && n > sizeof(e)) + goto again; + } +} + +void lorieSendClipboardData(const char* data) { + if (data && conn_fd != -1) { + size_t len = strlen(data); + lorieEvent e = { .clipboardSend = { .t = EVENT_CLIPBOARD_SEND, .count = len } }; + write(conn_fd, &e, sizeof(e)); + write(conn_fd, data, len); + } +} + +void lorieRequestClipboard(void) { + if (conn_fd != -1) { + lorieEvent e = { .type = EVENT_CLIPBOARD_REQUEST }; + write(conn_fd, &e, sizeof(e)); + } +} + +static Bool addFd(__unused ClientPtr pClient, void *closure) { + InputThreadRegisterDev((int) (int64_t) closure, handleLorieEvents, NULL); + conn_fd = (int) (int64_t) closure; + return TRUE; +} + +JNIEXPORT jobject JNICALL +Java_com_termux_x11_CmdEntryPoint_getXConnection(JNIEnv *env, __unused jobject cls) { + int client[2]; + jclass ParcelFileDescriptorClass = (*env)->FindClass(env, "android/os/ParcelFileDescriptor"); + jmethodID adoptFd = (*env)->GetStaticMethodID(env, ParcelFileDescriptorClass, "adoptFd", "(I)Landroid/os/ParcelFileDescriptor;"); + socketpair(AF_UNIX, SOCK_STREAM, 0, client); + fcntl(client[0], F_SETFL, fcntl(client[0], F_GETFL, 0) | O_NONBLOCK); + QueueWorkProc(addFd, NULL, (void*) (int64_t) client[1]); + + return (*env)->CallStaticObjectMethod(env, ParcelFileDescriptorClass, adoptFd, client[0]); +} + +void* logcatThread(void *arg) { + char buffer[4096]; + size_t len; + while((len = read((int) (int64_t) arg, buffer, 4096)) >=0) + write(2, buffer, len); + close((int) (int64_t) arg); + return NULL; +} + +JNIEXPORT jobject JNICALL +Java_com_termux_x11_CmdEntryPoint_getLogcatOutput(JNIEnv *env, __unused jobject cls) { + jclass ParcelFileDescriptorClass = (*env)->FindClass(env, "android/os/ParcelFileDescriptor"); + jmethodID adoptFd = (*env)->GetStaticMethodID(env, ParcelFileDescriptorClass, "adoptFd", "(I)Landroid/os/ParcelFileDescriptor;"); + const char *debug = getenv("TERMUX_X11_DEBUG"); + if (debug && !strcmp(debug, "1")) { + pthread_t t; + int p[2]; + pipe(p); + fchmod(p[1], 0777); + pthread_create(&t, NULL, logcatThread, (void*) (uint64_t) p[0]); + return (*env)->CallStaticObjectMethod(env, ParcelFileDescriptorClass, adoptFd, p[1]); + } + return NULL; +} + +JNIEXPORT jboolean JNICALL +Java_com_termux_x11_CmdEntryPoint_connected(__unused JNIEnv *env, __unused jclass clazz) { + return conn_fd != -1; +} + +static inline void checkConnection(JNIEnv* env) { + int retval, b = 0; + + if (conn_fd == -1) + return; + + if ((retval = recv(conn_fd, &b, 1, MSG_PEEK)) <= 0 && errno != EAGAIN) { + log(DEBUG, "recv %d %s", retval, strerror(errno)); + jclass cls = (*env)->FindClass(env, "com/termux/x11/CmdEntryPoint"); + jmethodID method = !cls ? NULL : (*env)->GetStaticMethodID(env, cls, "requestConnection", "()V"); + if (method) + (*env)->CallStaticVoidMethod(env, cls, method); + + close(conn_fd); + conn_fd = -1; + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_connect(__unused JNIEnv* env, __unused jobject cls, jint fd) { + if (!Charset.self) { + // Init clipboard-related JNI stuff + Charset.self = FindClassOrDie(env, "java/nio/charset/Charset"); + Charset.forName = FindMethodOrDie(env, Charset.self, "forName", "(Ljava/lang/String;)Ljava/nio/charset/Charset;", JNI_TRUE); + Charset.decode = FindMethodOrDie(env, Charset.self, "decode", "(Ljava/nio/ByteBuffer;)Ljava/nio/CharBuffer;", JNI_FALSE); + + CharBuffer.self = FindClassOrDie(env, "java/nio/CharBuffer"); + CharBuffer.toString = FindMethodOrDie(env, CharBuffer.self, "toString", "()Ljava/lang/String;", JNI_FALSE); + } + + conn_fd = fd; + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + checkConnection(env); + log(DEBUG, "XCB connection is successfull"); +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_handleXEvents(JNIEnv *env, jobject thiz) { + checkConnection(env); + if (conn_fd != -1) { + lorieEvent e = {0}; + + again: + if (read(conn_fd, &e, sizeof(e)) == sizeof(e)) { + switch(e.type) { + case EVENT_CLIPBOARD_SEND: { + char clipboard[e.clipboardSend.count + 1]; + read(conn_fd, clipboard, sizeof(clipboard)); + clipboard[e.clipboardSend.count] = 0; + log(DEBUG, "Clipboard content (%zu symbols) is %s", strlen(clipboard), clipboard); + jmethodID id = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, thiz), "setClipboardText","(Ljava/lang/String;)V"); + jobject bb = (*env)->NewDirectByteBuffer(env, clipboard, strlen(clipboard)); + jobject charset = (*env)->CallStaticObjectMethod(env, Charset.self, Charset.forName, (*env)->NewStringUTF(env, "UTF-8")); + jobject cb = (*env)->CallObjectMethod(env, charset, Charset.decode, bb); + (*env)->DeleteLocalRef(env, bb); + + jstring str = (*env)->CallObjectMethod(env, cb, CharBuffer.toString); + (*env)->CallVoidMethod(env, thiz, id, str); + break; + } + case EVENT_CLIPBOARD_REQUEST: { + (*env)->CallVoidMethod(env, thiz, (*env)->GetMethodID(env, (*env)->GetObjectClass(env, thiz), "requestClipboard", "()V")); + break; + } + } + } + + int n; + if (ioctl(conn_fd, FIONREAD, &n) >= 0 && n > sizeof(e)) + goto again; + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_startLogcat(JNIEnv *env, __unused jobject cls, jint fd) { + log(DEBUG, "Starting logcat with output to given fd"); + + switch(fork()) { + case -1: + log(ERROR, "fork: %s", strerror(errno)); + return; + case 0: + dup2(fd, 1); + dup2(fd, 2); + prctl(PR_SET_PDEATHSIG, SIGTERM); + char buf[64] = {0}; + sprintf(buf, "--pid=%d", getppid()); + execl("/system/bin/logcat", "logcat", buf, NULL); + log(ERROR, "exec logcat: %s", strerror(errno)); + (*env)->FatalError(env, "Exiting"); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_setClipboardSyncEnabled(__unused JNIEnv* env, __unused jobject cls, jboolean enable, __unused jboolean ignored) { + if (conn_fd != -1) { + lorieEvent e = { .clipboardEnable = { .t = EVENT_CLIPBOARD_ENABLE, .enable = enable } }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_sendClipboardAnnounce(JNIEnv *env, __unused jobject thiz) { + if (conn_fd != -1) { + lorieEvent e = { .type = EVENT_CLIPBOARD_ANNOUNCE }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_sendClipboardEvent(JNIEnv *env, __unused jobject thiz, jbyteArray text) { + if (conn_fd != -1 && text) { + jsize length = (*env)->GetArrayLength(env, text); + jbyte* str = (*env)->GetByteArrayElements(env, text, NULL); + lorieEvent e = { .clipboardSend = { .t = EVENT_CLIPBOARD_SEND, .count = length } }; + write(conn_fd, &e, sizeof(e)); + write(conn_fd, str, length); + (*env)->ReleaseByteArrayElements(env, text, str, JNI_ABORT); + checkConnection(env); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_sendWindowChange(__unused JNIEnv* env, __unused jobject cls, jint width, jint height, jint framerate) { + if (conn_fd != -1) { + lorieEvent e = { .screenSize = { .t = EVENT_SCREEN_SIZE, .width = width, .height = height, .framerate = framerate } }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_sendMouseEvent(__unused JNIEnv* env, __unused jobject cls, jfloat x, jfloat y, jint which_button, jboolean button_down, jboolean relative) { + if (conn_fd != -1) { + lorieEvent e = { .mouse = { .t = EVENT_MOUSE, .x = x, .y = y, .detail = which_button, .down = button_down, .relative = relative } }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_sendTouchEvent(__unused JNIEnv* env, __unused jobject cls, jint action, jint id, jint x, jint y) { + if (conn_fd != -1 && action != -1) { + lorieEvent e = { .touch = { .t = EVENT_TOUCH, .type = action, .id = id, .x = x, .y = y } }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_sendStylusEvent(JNIEnv *env, __unused jobject thiz, jfloat x, jfloat y, + jint pressure, jint tilt_x, jint tilt_y, + jint orientation, jint buttons, jboolean eraser, jboolean mouse) { + if (conn_fd != -1) { + lorieEvent e = { .stylus = { .t = EVENT_STYLUS, .x = x, .y = y, .pressure = pressure, .tilt_x = tilt_x, .tilt_y = tilt_y, .orientation = orientation, .buttons = buttons, .eraser = eraser, .mouse = mouse } }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_requestStylusEnabled(JNIEnv *env, __unused jclass clazz, jboolean enabled) { + if (conn_fd != -1) { + lorieEvent e = { .stylusEnable = { .t = EVENT_STYLUS_ENABLE, .enable = enabled } }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } +} + +JNIEXPORT jboolean JNICALL +Java_com_termux_x11_LorieView_sendKeyEvent(__unused JNIEnv* env, __unused jobject cls, jint scan_code, jint key_code, jboolean key_down) { + if (conn_fd != -1) { + int code = (scan_code) ?: android_to_linux_keycode[key_code]; + log(DEBUG, "Sending key: %d (%d %d %d)", code + 8, scan_code, key_code, key_down); + lorieEvent e = { .key = { .t = EVENT_KEY, .key = code + 8, .state = key_down } }; + write(conn_fd, &e, sizeof(e)); + checkConnection(env); + } + + return true; +} + +JNIEXPORT void JNICALL +Java_com_termux_x11_LorieView_sendTextEvent(JNIEnv *env, __unused jobject thiz, jbyteArray text) { + if (conn_fd != -1 && text) { + jsize length = (*env)->GetArrayLength(env, text); + jbyte *str = (*env)->GetByteArrayElements(env, text, NULL); + char *p = (char*) str; + mbstate_t state = { 0 }; + log(DEBUG, "Parsing text: %.*s", length, str); + + while (*p) { + wchar_t wc; + size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &state); + + if (len == (size_t)-1 || len == (size_t)-2) { + log(ERROR, "Invalid UTF-8 sequence encountered"); + break; + } + + if (len == 0) + break; + + log(DEBUG, "Sending unicode event: %lc (U+%X)", wc, wc); + lorieEvent e = { .unicode = { .t = EVENT_UNICODE, .code = wc } }; + write(conn_fd, &e, sizeof(e)); + p += len; + if (p - (char*) str >= length) + break; + usleep(30000); + } + + (*env)->ReleaseByteArrayElements(env, text, str, JNI_ABORT); + checkConnection(env); + } +} + +void abort(void) { + _exit(134); +} + +void exit(int code) { + _exit(code); +} + +#if 1 +// It is needed to redirect stderr to logcat +static void* stderrToLogcatThread(__unused void* cookie) { + FILE *fp; + int p[2]; + size_t len; + char *line = NULL; + pipe(p); + + fp = fdopen(p[0], "r"); + + dup2(p[1], 2); + dup2(p[1], 1); + while ((getline(&line, &len, fp)) != -1) { + log(DEBUG, "%s%s", line, (line[len - 1] == '\n') ? "" : "\n"); + } + + return NULL; +} + +__attribute__((constructor)) static void init(void) { + pthread_t t; + if (!strcmp("com.termux.x11", __progname)) + pthread_create(&t, NULL, stderrToLogcatThread, NULL); +} + +#endif + diff --git a/android/app/src/main/cpp/lorie/clipboard.c b/android/app/src/main/cpp/lorie/clipboard.c new file mode 100644 index 0000000..243ec14 --- /dev/null +++ b/android/app/src/main/cpp/lorie/clipboard.c @@ -0,0 +1,579 @@ +/* Copyright 2016-2019 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#pragma clang diagnostic ignored "-Wunknown-pragmas" + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "lorie.h" + +/* utility functions for text conversion */ + +static inline void lorieConvertLF(const char* src, char *dst, size_t bytes) { + size_t i = 0, j = 0; + for (; i < bytes; i++) + if (src[i] != '\r') + dst[j++] = src[i]; +} + +static inline void lorieLatin1ToUTF8(unsigned char* out, const unsigned char* in) { + while (*in) + if (*in < 128) + *out++ = *in++; + else + *out++ = 0xc2 + (*in > 0xbf), *out++ = (*in++ & 0x3f) + 0x80; +} + +static inline int lorieCheckUTF8(const unsigned char *utf, size_t size) { + int ix; + unsigned char c; + + for (ix = 0; (c = utf[ix]) && ix < size;) { + if (c & 0x80) { + if ((utf[ix + 1] & 0xc0) != 0x80) + return 0; + if ((c & 0xe0) == 0xe0) { + if ((utf[ix + 2] & 0xc0) != 0x80) + return 0; + if ((c & 0xf0) == 0xf0) { + if ((c & 0xf8) != 0xf0 || (utf[ix + 3] & 0xc0) != 0x80) + return 0; + ix += 4; + /* 4-byte code */ + } else + /* 3-byte code */ + ix += 3; + } else + /* 2-byte code */ + ix += 2; + } else + /* 1-byte code */ + ix++; + } + return 1; +} + +static size_t lorieUtf8ToUCS4(const char* src, size_t max, unsigned* dst) { + size_t count, consumed; + + *dst = 0xfffd; + + if (max == 0) + return 0; + + consumed = 1; + + if ((*src & 0x80) == 0) { + *dst = *src; + count = 0; + } else if ((*src & 0xe0) == 0xc0) { + *dst = *src & 0x1f; + count = 1; + } else if ((*src & 0xf0) == 0xe0) { + *dst = *src & 0x0f; + count = 2; + } else if ((*src & 0xf8) == 0xf0) { + *dst = *src & 0x07; + count = 3; + } else { + // Invalid sequence, consume all continuation characters + src++; + max--; + while ((max-- > 0) && ((*src++ & 0xc0) == 0x80)) + consumed++; + return consumed; + } + + src++; + max--; + + while (count--) { + consumed++; + + // Invalid or truncated sequence? + if ((max == 0) || ((*src & 0xc0) != 0x80)) { + *dst = 0xfffd; + return consumed; + } + + *dst <<= 6; + *dst |= *src & 0x3f; + + src++; + max--; + } + + // UTF-16 surrogate code point? + if ((*dst >= 0xd800) && (*dst < 0xe000)) + *dst = 0xfffd; + + return consumed; +} + +static const char *lorieUtf8ToLatin1(const char *src) { + size_t sz; + + const char* in; + size_t in_len; + + // Compute output size + sz = 0; + in = src; + in_len = -1; + while ((in_len > 0) && (*in != '\0')) { + size_t len; + unsigned ucs; + + len = lorieUtf8ToUCS4(in, in_len, &ucs); + in += len; + in_len -= len; + sz++; + } + + // Reserve space + unsigned char out[sz + 1]; + memset(out, 0, sz + 1); + size_t position = 0; + + // And convert + in = src; + in_len = 4.294967295E9; + while ((in_len > 0) && (*in != '\0')) { + size_t len; + unsigned ucs; + + len = lorieUtf8ToUCS4(in, in_len, &ucs); + in += len; + in_len -= len; + + if (ucs > 0xff) + out[position++] = '?'; + else + out[position++] = (unsigned char)ucs; + } + + return strdup((const char*) out); +} + +/* end utility functions */ + +#define log(prio, ...) __android_log_print(ANDROID_LOG_ ## prio, "LorieNative", __VA_ARGS__) +extern ScreenPtr pScreenPtr; + +static int (*origProcSendEvent)(ClientPtr) = NULL; +static int (*origProcConvertSelection)(ClientPtr) = NULL; +static Atom xaTIMESTAMP = 0, xaTEXT = 0, xaCLIPBOARD = 0, xaTARGETS = 0, xaSTRING = 0, xaUTF8_STRING = 0; +static Bool clipboardEnabled = FALSE; +static const char* cachedData = NULL; + +struct LorieDataTarget { + ClientPtr client; + Atom selection; + Atom target; + Atom property; + Window requestor; + CARD32 time; + struct LorieDataTarget* next; +} *lorieDataTargetHead; + +void lorieEnableClipboardSync(Bool enable) { + clipboardEnabled = enable; +} + +/* functions related to clipboard receiving */ + +static void lorieSelectionRequest(Atom selection, Atom target) { + Selection *pSel; + + if (clipboardEnabled && dixLookupSelection(&pSel, selection, serverClient, DixGetAttrAccess) == Success) { + xEvent event = {0}; + event.u.u.type = SelectionRequest; + event.u.selectionRequest.owner = pSel->window; + event.u.selectionRequest.time = currentTime.milliseconds; + event.u.selectionRequest.requestor = pScreenPtr->root->drawable.id; + event.u.selectionRequest.selection = selection; + event.u.selectionRequest.target = target; + event.u.selectionRequest.property = target; + WriteEventsToClient(pSel->client, 1, &event); + } +} + +static Bool lorieHasAtom(Atom atom, const Atom list[], size_t size) { + for (size_t i = 0; i < size; i++) + if (list[i] == atom) + return TRUE; + + return FALSE; +} + +static void lorieHandleSelection(Atom target) { + PropertyPtr prop; + if (target != xaTARGETS && target != xaSTRING && target != xaUTF8_STRING) + return; + + if (dixLookupProperty(&prop, pScreenPtr->root, target, serverClient, DixReadAccess) != Success) + return; + + log(DEBUG, "Selection notification for CLIPBOARD (target %s, type %s)\n", NameForAtom(target), NameForAtom(prop->type)); + + if (target == xaTARGETS && prop->type == XA_ATOM && prop->format == 32) { + if (lorieHasAtom(xaUTF8_STRING, (const Atom*)prop->data, prop->size)) + lorieSelectionRequest(xaCLIPBOARD, xaUTF8_STRING); + else if (lorieHasAtom(xaSTRING, (const Atom*)prop->data, prop->size)) + lorieSelectionRequest(xaCLIPBOARD, xaSTRING); + } else if (target == xaSTRING && prop->type == xaSTRING && prop->format == 8) { + if (prop->format != 8 || prop->type != xaSTRING) + return; + + char filtered[prop->size + 1], utf8[(prop->size + 1) * 2]; + memset(filtered, 0, sizeof(filtered)); + memset(utf8, 0, sizeof(utf8)); + + lorieConvertLF(prop->data, filtered, prop->size); + lorieLatin1ToUTF8((unsigned char*) utf8, (unsigned char*) filtered); + log(DEBUG, "Sending clipboard to clients (%zu bytes)\n", strlen(utf8)); + lorieSendClipboardData(utf8); + } else if (target == xaUTF8_STRING && prop->type == xaUTF8_STRING && prop->format == 8) { + char filtered[prop->size + 1]; + + if (!lorieCheckUTF8(prop->data, prop->size)) { + dprintf(2, "Invalid UTF-8 sequence in clipboard\n"); + return; + } + + memset(filtered, 0, prop->size + 1); + lorieConvertLF(prop->data, filtered, prop->size); + + log(DEBUG, "Sending clipboard to clients (%zu bytes)\n", strlen(filtered)); + lorieSendClipboardData(filtered); + } +} + +static int lorieProcSendEvent(ClientPtr client) { + REQUEST(xSendEventReq) + REQUEST_SIZE_MATCH(xSendEventReq); + __typeof__(stuff->event.u.selectionNotify)* e = &stuff->event.u.selectionNotify; + + if (clipboardEnabled && e->requestor == pScreenPtr->root->drawable.id && + stuff->event.u.u.type == SelectionNotify && e->selection == xaCLIPBOARD && e->target == e->property) + lorieHandleSelection(e->target); + + return origProcSendEvent(client); +} + +static void lorieSelectionCallback(__unused CallbackListPtr *callbacks, __unused void * data, void * args) { + SelectionInfoRec *info = (SelectionInfoRec *) args; + + if (clipboardEnabled && info->selection->selection == xaCLIPBOARD && info->kind == SelectionSetOwner) + lorieSelectionRequest(xaCLIPBOARD, xaTARGETS); +} + +/* end functions related to clipboard receiving */ + +/* functions related to clipboard announcing and sending */ + +static int lorieConvertSelection(ClientPtr client, Atom selection, Atom target, Atom property, Window requestor, CARD32 time, const char* data) { + Selection *pSel; + WindowPtr pWin; + int rc; + + Atom realProperty; + + xEvent event; + + if (data == NULL) { + log(DEBUG, "Selection request for %s (type %s)", + NameForAtom(selection), NameForAtom(target)); + } else { + log(DEBUG, "Sending data for selection request for %s (type %s)", + NameForAtom(selection), NameForAtom(target)); + } + + rc = dixLookupSelection(&pSel, selection, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + /* We do not validate the time argument because neither does + * dix/selection.c and some clients (e.g. Qt) relies on this */ + + rc = dixLookupWindow(&pWin, requestor, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + if (property != None) + realProperty = property; + else + realProperty = target; + + /* FIXME: MULTIPLE target */ + + if (target == xaTARGETS) { + Atom targets[] = { xaTARGETS, xaTIMESTAMP, + xaSTRING, xaTEXT, xaUTF8_STRING }; + + rc = dixChangeWindowProperty(serverClient, pWin, realProperty, + XA_ATOM, 32, PropModeReplace, + sizeof(targets)/sizeof(targets[0]), + targets, TRUE); + if (rc != Success) + return rc; + } else if (target == xaTIMESTAMP) { + rc = dixChangeWindowProperty(serverClient, pWin, realProperty, + XA_INTEGER, 32, PropModeReplace, 1, + &pSel->lastTimeChanged.milliseconds, + TRUE); + if (rc != Success) + return rc; + } else { + if (data == NULL) { + struct LorieDataTarget* ldt; + + if ((target != xaSTRING) && (target != xaTEXT) && + (target != xaUTF8_STRING)) + return BadMatch; + + ldt = calloc(1, sizeof(struct LorieDataTarget)); + if (ldt == NULL) + return BadAlloc; + + ldt->client = client; + ldt->selection = selection; + ldt->target = target; + ldt->property = property; + ldt->requestor = requestor; + ldt->time = time; + + ldt->next = lorieDataTargetHead; + lorieDataTargetHead = ldt; + + log(DEBUG, "Requesting clipboard data from client"); + lorieRequestClipboard(); + + return Success; + } else { + if ((target == xaSTRING) || (target == xaTEXT)) { + const char* latin1 = lorieUtf8ToLatin1(data); + if (latin1 == NULL) + return BadAlloc; + + rc = dixChangeWindowProperty(serverClient, pWin, realProperty, + XA_STRING, 8, PropModeReplace, + strlen(latin1), latin1, TRUE); + + free((void*) latin1); + + if (rc != Success) + return rc; + } else if (target == xaUTF8_STRING) { + rc = dixChangeWindowProperty(serverClient, pWin, realProperty, + xaUTF8_STRING, 8, PropModeReplace, + strlen(data), data, TRUE); + if (rc != Success) + return rc; + } else { + return BadMatch; + } + } + } + + event.u.u.type = SelectionNotify; + event.u.selectionNotify.time = time; + event.u.selectionNotify.requestor = requestor; + event.u.selectionNotify.selection = selection; + event.u.selectionNotify.target = target; + event.u.selectionNotify.property = property; + WriteEventsToClient(client, 1, &event); + return Success; +} + +static int lorieProcConvertSelection(ClientPtr client) { + Bool paramsOkay; + WindowPtr pWin; + Selection *pSel; + int rc; + + REQUEST(xConvertSelectionReq) + REQUEST_SIZE_MATCH(xConvertSelectionReq); + + rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + paramsOkay = ValidAtom(stuff->selection) && ValidAtom(stuff->target); + paramsOkay &= (stuff->property == None) || ValidAtom(stuff->property); + if (!paramsOkay) { + client->errorValue = stuff->property; + return BadAtom; + } + + /* Do we own this selection? */ + rc = dixLookupSelection(&pSel, stuff->selection, client, DixReadAccess); + if (rc == Success && pSel->client == serverClient && pSel->window == pScreenPtr->root->drawable.id) { + /* cachedData will be NULL for the first request, but can then be + * reused once we've gotten the data once from the client */ + rc = lorieConvertSelection(client, stuff->selection, + stuff->target, stuff->property, + stuff->requestor, stuff->time, + cachedData); + if (rc != Success) { + xEvent event; + + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = SelectionNotify; + event.u.selectionNotify.time = stuff->time; + event.u.selectionNotify.requestor = stuff->requestor; + event.u.selectionNotify.selection = stuff->selection; + event.u.selectionNotify.target = stuff->target; + event.u.selectionNotify.property = None; + WriteEventsToClient(client, 1, &event); + } + + return Success; + } + + return origProcConvertSelection(client); +} + +static int lorieOwnSelection(Atom selection) { + Selection *pSel; + int rc; + + SelectionInfoRec info; + + rc = dixLookupSelection(&pSel, selection, serverClient, DixSetAttrAccess); + if (rc == Success) { + if (pSel->client && (pSel->client != serverClient)) { + xEvent event = { + .u.selectionClear.time = currentTime.milliseconds, + .u.selectionClear.window = pSel->window, + .u.selectionClear.atom = pSel->selection + }; + event.u.u.type = SelectionClear; + WriteEventsToClient(pSel->client, 1, &event); + } + } else if (rc == BadMatch) { + pSel = dixAllocateObjectWithPrivates(Selection, PRIVATE_SELECTION); + if (!pSel) + return BadAlloc; + + pSel->selection = selection; + + rc = XaceHookSelectionAccess(serverClient, &pSel, DixCreateAccess | DixSetAttrAccess); + if (rc != Success) { + free(pSel); + return rc; + } + + pSel->next = CurrentSelections; + CurrentSelections = pSel; + } + else + return rc; + + pSel->lastTimeChanged = currentTime; + pSel->window = pScreenPtr->root->drawable.id; + pSel->pWin = pScreenPtr->root; + pSel->client = serverClient; + + log(DEBUG, "Grabbed %s selection", NameForAtom(selection)); + + info.selection = pSel; + info.client = serverClient; + info.kind = SelectionSetOwner; + CallCallbacks(&SelectionCallback, &info); + + return Success; +} + +void lorieHandleClipboardAnnounce(void) { + // The data has changed in some way, so whatever is in our cache is now stale + free((void*) cachedData); + cachedData = NULL; + + int rc; + + log(DEBUG, "Remote clipboard announced, grabbing local ownership"); + + rc = lorieOwnSelection(xaCLIPBOARD); + if (rc != Success) + log(ERROR, "Could not set CLIPBOARD selection"); +} + +void lorieHandleClipboardData(const char* data) { + struct LorieDataTarget* next; + + log(DEBUG, "Got remote clipboard data, sending to X11 clients"); + + free((void*) cachedData); + cachedData = data; + + while (lorieDataTargetHead != NULL) { + int rc; + xEvent event; + + rc = lorieConvertSelection(lorieDataTargetHead->client, + lorieDataTargetHead->selection, + lorieDataTargetHead->target, + lorieDataTargetHead->property, + lorieDataTargetHead->requestor, + lorieDataTargetHead->time, + cachedData); + if (rc != Success) { + event.u.u.type = SelectionNotify; + event.u.selectionNotify.time = lorieDataTargetHead->time; + event.u.selectionNotify.requestor = lorieDataTargetHead->requestor; + event.u.selectionNotify.selection = lorieDataTargetHead->selection; + event.u.selectionNotify.target = lorieDataTargetHead->target; + event.u.selectionNotify.property = None; + WriteEventsToClient(lorieDataTargetHead->client, 1, &event); + } + + next = lorieDataTargetHead->next; + free(lorieDataTargetHead); + lorieDataTargetHead = next; + } +} + +/* end functions related to clipboard announcing and sending */ + +void lorieInitClipboard(void) { +#define ATOM(name) xa##name = MakeAtom(#name, strlen(#name), TRUE) + ATOM(TIMESTAMP); ATOM(TEXT); ATOM(CLIPBOARD); ATOM(TARGETS); ATOM(STRING); ATOM(UTF8_STRING); + + if (!origProcConvertSelection) { + origProcConvertSelection = ProcVector[X_ConvertSelection]; + ProcVector[X_ConvertSelection] = lorieProcConvertSelection; + } + + if (!origProcSendEvent) { + origProcSendEvent = ProcVector[X_SendEvent]; + ProcVector[X_SendEvent] = lorieProcSendEvent; + } + + if (!AddCallback(&SelectionCallback, lorieSelectionCallback, NULL)) + FatalError("Adding SelectionCallback failed\n"); +} \ No newline at end of file diff --git a/android/app/src/main/cpp/lorie/dri3.c b/android/app/src/main/cpp/lorie/dri3.c new file mode 100644 index 0000000..81594d9 --- /dev/null +++ b/android/app/src/main/cpp/lorie/dri3.c @@ -0,0 +1,583 @@ +#pragma clang diagnostic ignored "-Wstrict-prototypes" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "screenint.h" +#include "lorie.h" +#include "renderer.h" + +#define log(prio, ...) __android_log_print(ANDROID_LOG_ ## prio, "LorieNative", __VA_ARGS__) + +/* + * Design is pretty simple. + * We need somehow attach Android's HardwareBuffers and turnip's textures to X11 pixmaps. + * + * About turnip. + * We can not simply import Mesa's texture since we do not use Mesa in project + * and even in the case it we ever use it we can not mix mesa with Android's libEGL. + * Xext's shm allows us to attach dmabuf fd with given width, height and offset, + * but does not let us specify stride of buffer. + * For this case we use DRI3's pixmap_from_fds request since it allows us specify + * width, height, stride and even import fd from client. + * + * About Android Hardware Buffers. + * NDK API does not let us simply flatten GraphicBuffer like it is done in regular AOSP code + * or even simply extract native handle which contains data and file descriptors + * needed to recreate GraphicBuffer in different process. + * But we have AHardwareBuffer_sendHandleToUnixSocket and AHardwareBuffer_recvHandleFromUnixSocket + * which let us send and receive AHardwareBuffer (aka GraphicBuffer) through Unix socket. + * So X11 client can simply open socketpair, wait for a while until server sends one byte + * and respond with AhardwareBuffer using AHardwareBuffer_sendHandleToUnixSocket. + * About attaching AHardwareBuffer to X11 pixmap: + * We can not simply do AHardwareBuffer_lock after creating pixmap and expect it to work. + * Some platforms (especially platforms with separate GPU memory which can not be accessed with CPU) + * explicitly copy contents of video memory to CPU memory on AHardwareBuffer_lock and content of buffer + * copied this way is not affected by any actions in X11 client process. + * So we must explicitly call AHardwareBuffer_lock when GC needs to access pixmap + * and call AHardwareBuffer_unlock when it finishes its work. + * Also we consider AHardwareBuffer we have to be read-only, write allowed only for X11 client. + * So all functions except CopyArea applied to pixmap with attached AHardwareBuffer should be no-ops. + */ + +static DevPrivateKeyRec lorieGCPrivateKey; +static DevPrivateKeyRec lorieScrPrivateKey; +static DevPrivateKeyRec lorieAHBPixPrivateKey; +static DevPrivateKeyRec lorieMmappedPixPrivateKey; + +typedef struct { + const GCOps *ops; + const GCFuncs *funcs; +} LorieGCPrivRec, *LorieGCPrivPtr; + +typedef struct { + CreateGCProcPtr CreateGC; + DestroyPixmapProcPtr DestroyPixmap; +} LorieScrPrivRec, *LorieScrPrivPtr; + +typedef struct { + AHardwareBuffer* buffer; +} LorieAHBPixPrivRec, *LorieAHBPixPrivPtr; + +static Bool FalseNoop() { return FALSE; } + +#define lorieGCPriv(pGC) LorieGCPrivPtr pGCPriv = dixLookupPrivate(&(pGC)->devPrivates, &lorieGCPrivateKey) +#define lorieScrPriv(pScr) LorieScrPrivPtr pScrPriv = ((LorieScrPrivPtr) dixLookupPrivate(&(pScr)->devPrivates, &lorieScrPrivateKey)) +#define loriePixFromDrawable(pDrawable, suffix) \ + PixmapPtr pDrawable ## Pix ## suffix = (pDrawable->type == DRAWABLE_PIXMAP) ? \ + (PixmapPtr) (((char*) pDrawable) - offsetof(PixmapRec, drawable)) : 0 +#define loriePixPriv(pDrawable, suffix) \ + LorieAHBPixPrivPtr pPixPriv ## suffix = (pDrawable ## Pix ## suffix) ? ((LorieAHBPixPrivPtr) \ + dixLookupPrivate(&(pDrawable ## Pix ## suffix)->devPrivates, &lorieAHBPixPrivateKey)) : 0 + +#define wrap(priv, real, mem, func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define LORIE_GC_OP_PROLOGUE(pGC) \ + lorieGCPriv(pGC); \ + const GCFuncs *oldFuncs = pGC->funcs; \ + const GCOps *oldOps = pGC->ops; \ + unwrap(pGCPriv, pGC, funcs); \ + unwrap(pGCPriv, pGC, ops); \ + +#define LORIE_GC_OP_EPILOGUE(pGC) \ + wrap(pGCPriv, pGC, funcs, oldFuncs); \ + wrap(pGCPriv, pGC, ops, oldOps) + +#define LORIE_GC_FUNC_PROLOGUE(pGC) \ + lorieGCPriv(pGC); \ + unwrap(pGCPriv, pGC, funcs); \ + if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops) + +#define LORIE_GC_FUNC_EPILOGUE(pGC) \ + wrap(pGCPriv, pGC, funcs, &lorieGCFuncs); \ + if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &lorieGCOps) + +#define unwrap(priv, real, mem) {\ + real->mem = priv->mem; \ +} + +static const GCOps lorieGCOps; +static const GCFuncs lorieGCFuncs; + +static void lorieValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) { + LORIE_GC_FUNC_PROLOGUE(pGC) + (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable); + LORIE_GC_FUNC_EPILOGUE(pGC) +} + +static void lorieChangeGC(GCPtr pGC, unsigned long mask) { + LORIE_GC_FUNC_PROLOGUE(pGC) + (*pGC->funcs->ChangeGC) (pGC, mask); + LORIE_GC_FUNC_EPILOGUE(pGC) +} + +static void lorieCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) { + LORIE_GC_FUNC_PROLOGUE(pGCSrc) + (*pGCSrc->funcs->CopyGC) (pGCSrc, mask, pGCDst); + LORIE_GC_FUNC_EPILOGUE(pGCSrc) +} + +static void lorieDestroyGC(GCPtr pGC) { + LORIE_GC_FUNC_PROLOGUE(pGC) + (*pGC->funcs->DestroyGC) (pGC); + LORIE_GC_FUNC_EPILOGUE(pGC) +} + +static void lorieChangeClip(GCPtr pGC, int type, void *pvalue, int nrects) { + LORIE_GC_FUNC_PROLOGUE(pGC) + (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); + LORIE_GC_FUNC_EPILOGUE(pGC) +} + +static void lorieDestroyClip(GCPtr pGC) { + LORIE_GC_FUNC_PROLOGUE(pGC) + (*pGC->funcs->DestroyClip) (pGC); + LORIE_GC_FUNC_EPILOGUE(pGC) +} + +static void lorieCopyClip(GCPtr pgcDst, GCPtr pgcSrc) { + LORIE_GC_FUNC_PROLOGUE(pgcDst) + (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc); + LORIE_GC_FUNC_EPILOGUE(pgcDst) +} + +static const GCFuncs lorieGCFuncs = { + lorieValidateGC, lorieChangeGC, lorieCopyGC, lorieDestroyGC, + lorieChangeClip, lorieDestroyClip, lorieCopyClip +}; + +static void lorieFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit, DDXPointPtr pptInit, int * pwidthInit, int fSorted) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void lorieSetSpans(DrawablePtr pDrawable, GCPtr pGC, char * psrc, DDXPointPtr ppt, int * pwidth, int nspans, int fSorted) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char * pBits) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static RegionPtr lorieCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pSrc, 0); + loriePixPriv(pSrc, 0); + loriePixFromDrawable(pDst, 1); + loriePixPriv(pDst, 1); + RegionPtr r = NULL; + Bool wasLocked = TRUE; + if (pPixPriv0 && !pPixPriv1) { + wasLocked = pSrcPix0->devPrivate.ptr != NULL; + if (!wasLocked) { + void *addr = NULL; + int error; + if ((error = AHardwareBuffer_lock(pPixPriv0->buffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, NULL, &addr)) != 0) + log(ERROR, "DRI3: AHardwareBuffer_lock failed: %d", error); + if (addr) + pSrc->pScreen->ModifyPixmapHeader(pSrcPix0, 0, 0, 0, 0, 0, addr); + } + } + + if (!pPixPriv1) + r = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); + + if (!wasLocked) { + AHardwareBuffer_unlock(pPixPriv0->buffer, NULL); + pSrcPix0->devPrivate.ptr = NULL; + } + LORIE_GC_OP_EPILOGUE(pGC) + return r; +} + +static RegionPtr lorieCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitPlane) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pSrcDrawable, 0); + loriePixFromDrawable(pDstDrawable, 1); + loriePixPriv(pSrcDrawable, 0); + loriePixPriv(pDstDrawable, 1); + RegionPtr r = NULL; + if (!pPixPriv0 && !pPixPriv1) + r = (*pGC->ops->CopyPlane) (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); + LORIE_GC_OP_EPILOGUE(pGC) + return r; +} + +static void loriePolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, pptInit); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSegs) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, pSegs); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle * pRects) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, pRects); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, parcs); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void lorieFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, int count, DDXPointPtr pPts) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pPts); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, xRectangle * prectInit) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrectFill, prectInit); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, parcs); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static int loriePolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char * chars) { + LORIE_GC_OP_PROLOGUE(pGC) + int r = x; + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + r = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); + LORIE_GC_OP_EPILOGUE(pGC) + return r; +} + +static int loriePolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short * chars) { + LORIE_GC_OP_PROLOGUE(pGC) + int r = x; + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + r = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); + LORIE_GC_OP_EPILOGUE(pGC) + return r; +} + +static void lorieImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char * chars) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void lorieImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short * chars) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void lorieImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyphBase) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyphBase) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDrawable, 0); + loriePixPriv(pDrawable, 0); + if (!pPixPriv0) + (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static void loriePushPixels(GCPtr pGC, PixmapPtr pBitMapPix0, DrawablePtr pDst, int w, int h, int x, int y) { + LORIE_GC_OP_PROLOGUE(pGC) + loriePixFromDrawable(pDst, 1); + loriePixPriv(pBitMap, 0); + loriePixPriv(pDst, 1); + if (!pPixPriv0 && !pPixPriv1) + (*pGC->ops->PushPixels) (pGC, pBitMapPix0, pDst, w, h, x, y); + LORIE_GC_OP_EPILOGUE(pGC) +} + +static const GCOps lorieGCOps = { + lorieFillSpans, lorieSetSpans, + loriePutImage, lorieCopyArea, + lorieCopyPlane, loriePolyPoint, + loriePolylines, loriePolySegment, + loriePolyRectangle, loriePolyArc, + lorieFillPolygon, loriePolyFillRect, + loriePolyFillArc, loriePolyText8, + loriePolyText16, lorieImageText8, + lorieImageText16, lorieImageGlyphBlt, + loriePolyGlyphBlt, loriePushPixels, +}; + +static Bool +lorieCreateGC(GCPtr pGC) { + ScreenPtr pScreen = pGC->pScreen; + + lorieScrPriv(pScreen); + lorieGCPriv(pGC); + Bool ret; + + unwrap(pScrPriv, pScreen, CreateGC) + if ((ret = (*pScreen->CreateGC) (pGC))) { + pGCPriv->ops = pGC->ops; + pGCPriv->funcs = pGC->funcs; + pGC->funcs = &lorieGCFuncs; + pGC->ops = &lorieGCOps; + } + wrap(pScrPriv, pScreen, CreateGC, lorieCreateGC) + + return ret; +} + +static Bool +lorieDestroyPixmap(PixmapPtr pPixmap) { + Bool ret; + void *ptr = NULL; + LorieAHBPixPrivPtr pPixPriv = NULL; + size_t size = 0; + ScreenPtr pScreen = pPixmap->drawable.pScreen; + lorieScrPriv(pScreen); + + if (pPixmap->refcnt == 1 && pPixmap->drawable.width && pPixmap->drawable.height) { + ptr = dixLookupPrivate(&pPixmap->devPrivates, &lorieMmappedPixPrivateKey); + pPixPriv = dixLookupPrivate(&pPixmap->devPrivates, &lorieAHBPixPrivateKey); + size = pPixmap->devKind * pPixmap->drawable.height; + } + + unwrap(pScrPriv, pScreen, DestroyPixmap) + ret = (*pScreen->DestroyPixmap) (pPixmap); + wrap(pScrPriv, pScreen, DestroyPixmap, lorieDestroyPixmap) + + if (ptr) + munmap(ptr, size); + + if (pPixPriv) { + if (pPixPriv->buffer) + AHardwareBuffer_release(pPixPriv->buffer); + free(pPixPriv); + } + + return ret; +} + +static PixmapPtr loriePixmapFromFds(ScreenPtr screen, CARD8 num_fds, const int *fds, CARD16 width, CARD16 height, + const CARD32 *strides, const CARD32 *offsets, CARD8 depth, __unused CARD8 bpp, CARD64 modifier) { + const CARD64 AHARDWAREBUFFER_SOCKET_FD = 1255; + const CARD64 RAW_MMAPPABLE_FD = 1274; + PixmapPtr pixmap = NullPixmap; + LorieAHBPixPrivPtr pPixPriv = NULL; + if (num_fds > 1) { + log(ERROR, "DRI3: More than 1 fd"); + return NULL; + } + + if (modifier != RAW_MMAPPABLE_FD && modifier != AHARDWAREBUFFER_SOCKET_FD) { + log(ERROR, "DRI3: Modifier is not RAW_MMAPPABLE_FD or AHARDWAREBUFFER_SOCKET_FD"); + return NULL; + } + + if (modifier == RAW_MMAPPABLE_FD) { + void *addr = mmap(NULL, strides[0] * height, PROT_READ, MAP_SHARED, fds[0], offsets[0]); + if (!addr || addr == MAP_FAILED) { + log(ERROR, "DRI3: RAW_MMAPPABLE_FD: mmap failed"); + return NULL; + } + + pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); + if (!pixmap) { + log(ERROR, "DRI3: RAW_MMAPPABLE_FD: failed to create pixmap"); + munmap(addr, strides[0] * height); + return NULL; + } + + dixSetPrivate(&pixmap->devPrivates, &lorieMmappedPixPrivateKey, addr); + screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], addr); + + return pixmap; + } else if (modifier == AHARDWAREBUFFER_SOCKET_FD) { + AHardwareBuffer_Desc desc; + struct stat info; + int r; + if (fstat(fds[0], &info) != 0) { + log(ERROR, "DRI3: fstat failed: %s", strerror(errno)); + return NULL; + } + + if (!S_ISSOCK(info.st_mode)) { + log(ERROR, "DRI3: modifier is AHARDWAREBUFFER_SOCKET_FD but fd is not a socket"); + return NULL; + } + + pPixPriv = calloc(1, sizeof(LorieAHBPixPrivRec)); + if (!pPixPriv) { + log(ERROR, "DRI3: AHARDWAREBUFFER_SOCKET_FD: failed to allocate LorieAHBPixPrivRec"); + return NULL; + } + + pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); + if (!pixmap) { + log(ERROR, "DRI3: failed to create pixmap"); + goto fail; + } + + dixSetPrivate(&pixmap->devPrivates, &lorieAHBPixPrivateKey, pPixPriv); + + // Sending signal to other end of socket to send buffer. + uint8_t buf = 1; + if (write(fds[0], &buf, 1) != 1) { + log(ERROR, "DRI3: AHARDWAREBUFFER_SOCKET_FD: failed to write to socket: %s", strerror(errno)); + goto fail; + } + + if ((r = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], &pPixPriv->buffer)) != 0) { + log(ERROR, "DRI3: AHARDWAREBUFFER_SOCKET_FD: failed to obtain AHardwareBuffer from socket: %d", r); + goto fail; + } + + if (!pPixPriv->buffer) { + log(ERROR, "DRI3: AHARDWAREBUFFER_SOCKET_FD: did not receive AHardwareSocket from buffer"); + goto fail; + } + + AHardwareBuffer_describe(pPixPriv->buffer, &desc); + if (desc.format != AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM + && desc.format != AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM + && desc.format != AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM) { + log(ERROR, "DRI3: AHARDWAREBUFFER_SOCKET_FD: wrong format of AHardwareBuffer. Must be one of: AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM (stands for 5)."); + goto fail; + } + + pixmap->devPrivate.ptr = NULL; + screen->ModifyPixmapHeader(pixmap, desc.width, desc.height, 0, 0, desc.stride * 4, NULL); + return pixmap; + } + + fail: + if (pPixPriv) { + if (pPixPriv->buffer) + AHardwareBuffer_release(pPixPriv->buffer); + free(pPixPriv); + } + + if (pixmap) + fbDestroyPixmap(pixmap); + + return NULL; +} + +static int lorieGetFormats(__unused ScreenPtr screen, CARD32 *num_formats, CARD32 **formats) { + *num_formats = 0; + *formats = NULL; + return TRUE; +} + +static int lorieGetModifiers(__unused ScreenPtr screen, __unused uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers) { + *num_modifiers = 0; + *modifiers = NULL; + return TRUE; +} + +static dri3_screen_info_rec dri3Info = { + .version = 2, + .fds_from_pixmap = FalseNoop, + .pixmap_from_fds = loriePixmapFromFds, + .get_formats = lorieGetFormats, + .get_modifiers = lorieGetModifiers, + .get_drawable_modifiers = FalseNoop +}; + +Bool lorieInitDri3(ScreenPtr pScreen) { + LorieScrPrivPtr pScrPriv; + + if (!dixRegisterPrivateKey(&lorieScrPrivateKey, PRIVATE_SCREEN, 0)) + return FALSE; + + if (dixLookupPrivate(&pScreen->devPrivates, &lorieScrPrivateKey)) + return TRUE; + + if (!dixRegisterPrivateKey(&lorieGCPrivateKey, PRIVATE_GC, sizeof(LorieGCPrivRec)) + || !dixRegisterPrivateKey(&lorieAHBPixPrivateKey, PRIVATE_PIXMAP, 0) + || !dixRegisterPrivateKey(&lorieMmappedPixPrivateKey, PRIVATE_PIXMAP, 0) + || !dri3_screen_init(pScreen, &dri3Info)) + return FALSE; + + pScrPriv = malloc(sizeof(LorieScrPrivRec)); + if (!pScrPriv) + return FALSE; + + wrap(pScrPriv, pScreen, CreateGC, lorieCreateGC) + wrap(pScrPriv, pScreen, DestroyPixmap, lorieDestroyPixmap) + + dixSetPrivate(&pScreen->devPrivates, &lorieScrPrivateKey, pScrPriv); + return TRUE; +} diff --git a/android/app/src/main/cpp/lorie/fbconfigs.h b/android/app/src/main/cpp/lorie/fbconfigs.h new file mode 100644 index 0000000..e0f0753 --- /dev/null +++ b/android/app/src/main/cpp/lorie/fbconfigs.h @@ -0,0 +1,871 @@ +/* + * For some reasong configs generated on top of parameters + * extracted from GL configs do not work for glxgears and glmark + */ + +/* + * dprintf(2, "static __GLXconfig configs[] = {\n"); + * int index = 0; + * for (__GLXconfig *m = screen->base.fbconfigs; m != NULL; m = m->next) { + * dprintf(2, " (__GLXconfig) { NULL, %s, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X },\n", + * m->duplicatedForComp ? "TRUE" : "FALSE", + * m->doubleBufferMode, m->stereoMode, + * m->redBits, m->greenBits, m->blueBits, m->alphaBits, + * m->redMask, m->greenMask, m->blueMask, m->alphaMask, + * m->rgbBits, m->indexBits, + * m->accumRedBits, m->accumGreenBits, m->accumBlueBits, m->accumAlphaBits, + * m->depthBits, m->stencilBits, m->numAuxBuffers, m->level, + * m->visualID, m->visualType, m->visualRating, + * m->transparentPixel, m->transparentRed, m->transparentGreen, m->transparentBlue, m->transparentAlpha, + * m->transparentIndex, + * m->sampleBuffers, m->samples, m->drawableType, m->renderType, m->fbconfigID, + * m->maxPbufferWidth, m->maxPbufferHeight, m->maxPbufferPixels, m->optimalPbufferWidth, m->optimalPbufferHeight, + * m->visualSelectGroup, m->swapMethod, + * m->bindToTextureRgb, m->bindToTextureRgba, m->bindToMipmapTexture, m->bindToTextureTargets, + * m->yInverted, m->sRGBCapable); + * } + * dprintf(2, "};\n"); + */ + +static __GLXconfig configs[] = { + (__GLXconfig) { &configs[1], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[2], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[3], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[4], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[5], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[6], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[7], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[8], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[9], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[10], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[11], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[12], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[13], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[14], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[15], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[16], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[17], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[18], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[19], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[20], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[21], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[22], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[23], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[24], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[25], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[26], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[27], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[28], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[29], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[30], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[31], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[32], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[33], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[34], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[35], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[36], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[37], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[38], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[39], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[40], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[41], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[42], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[43], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[44], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[45], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[46], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[47], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[48], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[49], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[50], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[51], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[52], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[53], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[54], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[55], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[56], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[57], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[58], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[59], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[60], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[61], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[62], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[63], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[64], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[65], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[66], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[67], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[68], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[69], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[70], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[71], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[72], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[73], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[74], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[75], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[76], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[77], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[78], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[79], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[80], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[81], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[82], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[83], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[84], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[85], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[86], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[87], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[88], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[89], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[90], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[91], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[92], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[93], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[94], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[95], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[96], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[97], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[98], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[99], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[100], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[101], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[102], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[103], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[104], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[105], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[106], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[107], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[108], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[109], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[110], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[111], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[112], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[113], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[114], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[115], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[116], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[117], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[118], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[119], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[120], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[121], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[122], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[123], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[124], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[125], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[126], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[127], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[128], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[129], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[130], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[131], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[132], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[133], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[134], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[135], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[136], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[137], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[138], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[139], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[140], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[141], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[142], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[143], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[144], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[145], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[146], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[147], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[148], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[149], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[150], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[151], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[152], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[153], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[154], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[155], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[156], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[157], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[158], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[159], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[160], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[161], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[162], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[163], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[164], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[165], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[166], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[167], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[168], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[169], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[170], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[171], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[172], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[173], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[174], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[175], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[176], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[177], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[178], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[179], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[180], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[181], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[182], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[183], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[184], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[185], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[186], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[187], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[188], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[189], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[190], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[191], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[192], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[193], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[194], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[195], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[196], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[197], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[198], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[199], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[200], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[201], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[202], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[203], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[204], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[205], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[206], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[207], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[208], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[209], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[210], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[211], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[212], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[213], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[214], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[215], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[216], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[217], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[218], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[219], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[220], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[221], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[222], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[223], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[224], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[225], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[226], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[227], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[228], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[229], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[230], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[231], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[232], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[233], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[234], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[235], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[236], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[237], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[238], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[239], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[240], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[241], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[242], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[243], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[244], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[245], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[246], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[247], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[248], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[249], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[250], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[251], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[252], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[253], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[254], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[255], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[256], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[257], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[258], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[259], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[260], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[261], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[262], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[263], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[264], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[265], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[266], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[267], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[268], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[269], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[270], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[271], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[272], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[273], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[274], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[275], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[276], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[277], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[278], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[279], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[280], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[281], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[282], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[283], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[284], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[285], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[286], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[287], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[288], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[289], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[290], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[291], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[292], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[293], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[294], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[295], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[296], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[297], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[298], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[299], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[300], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[301], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[302], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[303], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[304], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[305], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[306], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[307], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[308], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[309], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[310], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[311], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[312], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[313], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[314], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[315], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[316], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[317], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[318], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[319], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[320], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[321], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[322], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[323], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[324], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[325], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[326], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[327], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[328], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[329], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[330], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[331], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[332], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[333], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[334], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[335], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[336], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[337], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[338], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[339], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[340], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[341], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[342], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[343], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[344], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[345], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[346], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[347], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[348], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[349], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[350], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[351], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[352], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[353], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[354], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[355], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[356], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[357], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[358], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[359], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[360], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[361], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[362], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[363], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[364], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[365], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[366], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[367], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[368], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[369], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[370], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[371], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[372], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[373], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[374], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[375], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[376], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[377], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[378], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[379], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[380], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[381], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[382], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[383], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[384], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[385], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[386], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[387], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[388], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[389], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[390], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[391], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[392], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[393], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[394], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[395], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[396], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[397], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[398], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[399], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[400], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[401], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[402], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[403], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[404], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[405], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[406], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[407], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[408], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[409], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[410], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[411], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[412], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[413], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[414], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[415], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[416], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[417], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[418], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[419], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[420], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[421], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[422], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[423], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[424], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[425], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[426], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[427], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[428], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[429], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[430], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[431], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[432], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[433], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[434], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[435], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[436], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[437], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[438], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[439], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[440], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[441], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[442], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[443], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[444], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[445], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[446], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[447], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[448], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[449], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[450], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[451], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[452], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[453], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[454], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[455], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[456], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[457], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[458], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[459], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[460], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[461], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[462], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[463], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[464], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[465], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[466], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[467], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[468], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[469], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[470], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[471], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[472], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[473], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[474], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[475], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[476], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[477], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[478], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[479], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[480], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[481], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[482], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[483], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[484], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[485], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[486], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[487], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[488], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[489], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[490], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[491], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[492], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[493], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[494], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[495], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF00000, 0xFFC00, 0x3FF, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[496], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[497], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[498], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[499], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[500], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[501], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[502], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[503], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[504], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[505], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[506], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[507], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[508], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[509], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[510], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[511], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[512], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[513], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[514], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[515], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[516], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[517], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[518], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[519], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[520], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[521], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[522], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[523], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[524], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[525], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[526], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[527], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[528], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[529], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[530], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[531], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[532], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[533], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[534], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[535], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[536], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[537], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[538], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[539], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[540], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x2, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[541], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[542], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[543], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[544], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[545], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[546], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[547], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[548], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[549], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[550], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[551], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[552], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[553], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[554], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[555], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[556], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[557], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[558], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[559], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[560], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[561], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[562], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[563], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[564], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[565], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[566], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[567], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[568], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[569], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[570], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[571], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[572], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[573], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[574], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[575], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[576], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[577], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[578], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[579], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[580], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[581], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[582], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[583], FALSE, 0x0, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[584], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[585], FALSE, 0x1, 0x0, 0xA, 0xA, 0xA, 0x0, 0x3FF, 0xFFC00, 0x3FF00000, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[586], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[587], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[588], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[589], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[590], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[591], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[592], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[593], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[594], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[595], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[596], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[597], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[598], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[599], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[600], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[601], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[602], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[603], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[604], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[605], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[606], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[607], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[608], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[609], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[610], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[611], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[612], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[613], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[614], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[615], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[616], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[617], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[618], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[619], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[620], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[621], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[622], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[623], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[624], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[625], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[626], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[627], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[628], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[629], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[630], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[631], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[632], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[633], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[634], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[635], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[636], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[637], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[638], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[639], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[640], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[641], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[642], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[643], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[644], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[645], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[646], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[647], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[648], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[649], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[650], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[651], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[652], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[653], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[654], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[655], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[656], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[657], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[658], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[659], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[660], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[661], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[662], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[663], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[664], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[665], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[666], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[667], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[668], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[669], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[670], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[671], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[672], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[673], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[674], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[675], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[676], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[677], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[678], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[679], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[680], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[681], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[682], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[683], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[684], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[685], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[686], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[687], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[688], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[689], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[690], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[691], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[692], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[693], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[694], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[695], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[696], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[697], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[698], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[699], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[700], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[701], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[702], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[703], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[704], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[705], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[706], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[707], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[708], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[709], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[710], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[711], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[712], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[713], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[714], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[715], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[716], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[717], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[718], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[719], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[720], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[721], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[722], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[723], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[724], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[725], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[726], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[727], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[728], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[729], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[730], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[731], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[732], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[733], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[734], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[735], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[736], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[737], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[738], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[739], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[740], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[741], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[742], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[743], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[744], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[745], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[746], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[747], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[748], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[749], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[750], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[751], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[752], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[753], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[754], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[755], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[756], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[757], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[758], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[759], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[760], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[761], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[762], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[763], FALSE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[764], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[765], FALSE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x0, 0xFF0000, 0xFF00, 0xFF, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[766], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[767], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[768], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[769], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[770], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[771], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[772], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[773], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[774], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[775], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[776], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[777], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[778], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[779], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[780], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[781], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[782], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[783], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[784], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[785], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[786], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[787], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[788], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[789], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[790], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[791], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[792], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[793], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[794], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[795], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x10, 0x10, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8001, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[796], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[797], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[798], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[799], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[800], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[801], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[802], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[803], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[804], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[805], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[806], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[807], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[808], FALSE, 0x0, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[809], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[810], FALSE, 0x1, 0x0, 0x5, 0x6, 0x5, 0x0, 0xF800, 0x7E0, 0x1F, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8003, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x1, 0x4, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[811], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[812], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[813], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[814], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[815], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[816], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[817], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[818], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[819], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[820], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[821], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[822], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[823], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[824], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[825], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x0 }, + (__GLXconfig) { &configs[826], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[827], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[828], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[829], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[830], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[831], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[832], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[833], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[834], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[835], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[836], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[837], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x8, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[838], TRUE, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { &configs[839], TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8063, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, + (__GLXconfig) { NULL, TRUE, 0x1, 0x0, 0x8, 0x8, 0x8, 0x8, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x8002, 0x8000, 0x8000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8062, 0x1, 0x1, 0x0, 0x7, 0x1, 0x1 }, +}; \ No newline at end of file diff --git a/android/app/src/main/cpp/lorie/lorie.h b/android/app/src/main/cpp/lorie/lorie.h new file mode 100644 index 0000000..8658640 --- /dev/null +++ b/android/app/src/main/cpp/lorie/lorie.h @@ -0,0 +1,163 @@ +#pragma once + +#include +#include +#include "linux/input-event-codes.h" + +void lorieSetVM(JavaVM* vm); +Bool lorieChangeScreenName(ClientPtr pClient, void *closure); +Bool lorieChangeWindow(ClientPtr pClient, void *closure); +void lorieConfigureNotify(int width, int height, int framerate); +void lorieEnableClipboardSync(Bool enable); +void lorieSendClipboardData(const char* data); +void lorieInitClipboard(void); +void lorieRequestClipboard(void); +void lorieHandleClipboardAnnounce(void); +void lorieHandleClipboardData(const char* data); +Bool lorieInitDri3(ScreenPtr pScreen); +void lorieSetStylusEnabled(Bool enabled); + +static int android_to_linux_keycode[304] = { + [ 4 /* ANDROID_KEYCODE_BACK */] = KEY_ESC, + [ 7 /* ANDROID_KEYCODE_0 */] = KEY_0, + [ 8 /* ANDROID_KEYCODE_1 */] = KEY_1, + [ 9 /* ANDROID_KEYCODE_2 */] = KEY_2, + [ 10 /* ANDROID_KEYCODE_3 */] = KEY_3, + [ 11 /* ANDROID_KEYCODE_4 */] = KEY_4, + [ 12 /* ANDROID_KEYCODE_5 */] = KEY_5, + [ 13 /* ANDROID_KEYCODE_6 */] = KEY_6, + [ 14 /* ANDROID_KEYCODE_7 */] = KEY_7, + [ 15 /* ANDROID_KEYCODE_8 */] = KEY_8, + [ 16 /* ANDROID_KEYCODE_9 */] = KEY_9, + [ 17 /* ANDROID_KEYCODE_STAR */] = KEY_KPASTERISK, + [ 19 /* ANDROID_KEYCODE_DPAD_UP */] = KEY_UP, + [ 20 /* ANDROID_KEYCODE_DPAD_DOWN */] = KEY_DOWN, + [ 21 /* ANDROID_KEYCODE_DPAD_LEFT */] = KEY_LEFT, + [ 22 /* ANDROID_KEYCODE_DPAD_RIGHT */] = KEY_RIGHT, + [ 23 /* ANDROID_KEYCODE_DPAD_CENTER */] = KEY_ENTER, + [ 24 /* ANDROID_KEYCODE_VOLUME_UP */] = KEY_VOLUMEUP, // XF86XK_AudioRaiseVolume + [ 25 /* ANDROID_KEYCODE_VOLUME_DOWN */] = KEY_VOLUMEDOWN, // XF86XK_AudioLowerVolume + [ 26 /* ANDROID_KEYCODE_POWER */] = KEY_POWER, + [ 27 /* ANDROID_KEYCODE_CAMERA */] = KEY_CAMERA, + [ 28 /* ANDROID_KEYCODE_CLEAR */] = KEY_CLEAR, + [ 29 /* ANDROID_KEYCODE_A */] = KEY_A, + [ 30 /* ANDROID_KEYCODE_B */] = KEY_B, + [ 31 /* ANDROID_KEYCODE_C */] = KEY_C, + [ 32 /* ANDROID_KEYCODE_D */] = KEY_D, + [ 33 /* ANDROID_KEYCODE_E */] = KEY_E, + [ 34 /* ANDROID_KEYCODE_F */] = KEY_F, + [ 35 /* ANDROID_KEYCODE_G */] = KEY_G, + [ 36 /* ANDROID_KEYCODE_H */] = KEY_H, + [ 37 /* ANDROID_KEYCODE_I */] = KEY_I, + [ 38 /* ANDROID_KEYCODE_J */] = KEY_J, + [ 39 /* ANDROID_KEYCODE_K */] = KEY_K, + [ 40 /* ANDROID_KEYCODE_L */] = KEY_L, + [ 41 /* ANDROID_KEYCODE_M */] = KEY_M, + [ 42 /* ANDROID_KEYCODE_N */] = KEY_N, + [ 43 /* ANDROID_KEYCODE_O */] = KEY_O, + [ 44 /* ANDROID_KEYCODE_P */] = KEY_P, + [ 45 /* ANDROID_KEYCODE_Q */] = KEY_Q, + [ 46 /* ANDROID_KEYCODE_R */] = KEY_R, + [ 47 /* ANDROID_KEYCODE_S */] = KEY_S, + [ 48 /* ANDROID_KEYCODE_T */] = KEY_T, + [ 49 /* ANDROID_KEYCODE_U */] = KEY_U, + [ 50 /* ANDROID_KEYCODE_V */] = KEY_V, + [ 51 /* ANDROID_KEYCODE_W */] = KEY_W, + [ 52 /* ANDROID_KEYCODE_X */] = KEY_X, + [ 53 /* ANDROID_KEYCODE_Y */] = KEY_Y, + [ 54 /* ANDROID_KEYCODE_Z */] = KEY_Z, + [ 55 /* ANDROID_KEYCODE_COMMA */] = KEY_COMMA, + [ 56 /* ANDROID_KEYCODE_PERIOD */] = KEY_DOT, + [ 57 /* ANDROID_KEYCODE_ALT_LEFT */] = KEY_LEFTALT, + [ 58 /* ANDROID_KEYCODE_ALT_RIGHT */] = KEY_RIGHTALT, + [ 59 /* ANDROID_KEYCODE_SHIFT_LEFT */] = KEY_LEFTSHIFT, + [ 60 /* ANDROID_KEYCODE_SHIFT_RIGHT */] = KEY_RIGHTSHIFT, + [ 61 /* ANDROID_KEYCODE_TAB */] = KEY_TAB, + [ 62 /* ANDROID_KEYCODE_SPACE */] = KEY_SPACE, + [ 64 /* ANDROID_KEYCODE_EXPLORER */] = KEY_WWW, + [ 65 /* ANDROID_KEYCODE_ENVELOPE */] = KEY_MAIL, + [ 66 /* ANDROID_KEYCODE_ENTER */] = KEY_ENTER, + [ 67 /* ANDROID_KEYCODE_DEL */] = KEY_BACKSPACE, + [ 68 /* ANDROID_KEYCODE_GRAVE */] = KEY_GRAVE, + [ 69 /* ANDROID_KEYCODE_MINUS */] = KEY_MINUS, + [ 70 /* ANDROID_KEYCODE_EQUALS */] = KEY_EQUAL, + [ 71 /* ANDROID_KEYCODE_LEFT_BRACKET */] = KEY_LEFTBRACE, + [ 72 /* ANDROID_KEYCODE_RIGHT_BRACKET */] = KEY_RIGHTBRACE, + [ 73 /* ANDROID_KEYCODE_BACKSLASH */] = KEY_BACKSLASH, + [ 74 /* ANDROID_KEYCODE_SEMICOLON */] = KEY_SEMICOLON, + [ 75 /* ANDROID_KEYCODE_APOSTROPHE */] = KEY_APOSTROPHE, + [ 76 /* ANDROID_KEYCODE_SLASH */] = KEY_SLASH, + [ 81 /* ANDROID_KEYCODE_PLUS */] = KEY_KPPLUS, + [ 82 /* ANDROID_KEYCODE_MENU */] = KEY_CONTEXT_MENU, + [ 84 /* ANDROID_KEYCODE_SEARCH */] = KEY_SEARCH, + [ 85 /* ANDROID_KEYCODE_MEDIA_PLAY_PAUSE */] = KEY_PLAYPAUSE, + [ 86 /* ANDROID_KEYCODE_MEDIA_STOP */] = KEY_STOP_RECORD, + [ 87 /* ANDROID_KEYCODE_MEDIA_NEXT */] = KEY_NEXTSONG, + [ 88 /* ANDROID_KEYCODE_MEDIA_PREVIOUS */] = KEY_PREVIOUSSONG, + [ 89 /* ANDROID_KEYCODE_MEDIA_REWIND */] = KEY_REWIND, + [ 90 /* ANDROID_KEYCODE_MEDIA_FAST_FORWARD */] = KEY_FASTFORWARD, + [ 91 /* ANDROID_KEYCODE_MUTE */] = KEY_MUTE, + [ 92 /* ANDROID_KEYCODE_PAGE_UP */] = KEY_PAGEUP, + [ 93 /* ANDROID_KEYCODE_PAGE_DOWN */] = KEY_PAGEDOWN, + [ 111 /* ANDROID_KEYCODE_ESCAPE */] = KEY_ESC, + [ 112 /* ANDROID_KEYCODE_FORWARD_DEL */] = KEY_DELETE, + [ 113 /* ANDROID_KEYCODE_CTRL_LEFT */] = KEY_LEFTCTRL, + [ 114 /* ANDROID_KEYCODE_CTRL_RIGHT */] = KEY_RIGHTCTRL, + [ 115 /* ANDROID_KEYCODE_CAPS_LOCK */] = KEY_CAPSLOCK, + [ 116 /* ANDROID_KEYCODE_SCROLL_LOCK */] = KEY_SCROLLLOCK, + [ 117 /* ANDROID_KEYCODE_META_LEFT */] = KEY_LEFTMETA, + [ 118 /* ANDROID_KEYCODE_META_RIGHT */] = KEY_RIGHTMETA, + [ 120 /* ANDROID_KEYCODE_SYSRQ */] = KEY_PRINT, + [ 121 /* ANDROID_KEYCODE_BREAK */] = KEY_BREAK, + [ 122 /* ANDROID_KEYCODE_MOVE_HOME */] = KEY_HOME, + [ 123 /* ANDROID_KEYCODE_MOVE_END */] = KEY_END, + [ 124 /* ANDROID_KEYCODE_INSERT */] = KEY_INSERT, + [ 125 /* ANDROID_KEYCODE_FORWARD */] = KEY_FORWARD, + [ 126 /* ANDROID_KEYCODE_MEDIA_PLAY */] = KEY_PLAYCD, + [ 127 /* ANDROID_KEYCODE_MEDIA_PAUSE */] = KEY_PAUSECD, + [ 128 /* ANDROID_KEYCODE_MEDIA_CLOSE */] = KEY_CLOSECD, + [ 129 /* ANDROID_KEYCODE_MEDIA_EJECT */] = KEY_EJECTCD, + [ 130 /* ANDROID_KEYCODE_MEDIA_RECORD */] = KEY_RECORD, + [ 131 /* ANDROID_KEYCODE_F1 */] = KEY_F1, + [ 132 /* ANDROID_KEYCODE_F2 */] = KEY_F2, + [ 133 /* ANDROID_KEYCODE_F3 */] = KEY_F3, + [ 134 /* ANDROID_KEYCODE_F4 */] = KEY_F4, + [ 135 /* ANDROID_KEYCODE_F5 */] = KEY_F5, + [ 136 /* ANDROID_KEYCODE_F6 */] = KEY_F6, + [ 137 /* ANDROID_KEYCODE_F7 */] = KEY_F7, + [ 138 /* ANDROID_KEYCODE_F8 */] = KEY_F8, + [ 139 /* ANDROID_KEYCODE_F9 */] = KEY_F9, + [ 140 /* ANDROID_KEYCODE_F10 */] = KEY_F10, + [ 141 /* ANDROID_KEYCODE_F11 */] = KEY_F11, + [ 142 /* ANDROID_KEYCODE_F12 */] = KEY_F12, + [ 143 /* ANDROID_KEYCODE_NUM_LOCK */] = KEY_NUMLOCK, + [ 144 /* ANDROID_KEYCODE_NUMPAD_0 */] = KEY_KP0, + [ 145 /* ANDROID_KEYCODE_NUMPAD_1 */] = KEY_KP1, + [ 146 /* ANDROID_KEYCODE_NUMPAD_2 */] = KEY_KP2, + [ 147 /* ANDROID_KEYCODE_NUMPAD_3 */] = KEY_KP3, + [ 148 /* ANDROID_KEYCODE_NUMPAD_4 */] = KEY_KP4, + [ 149 /* ANDROID_KEYCODE_NUMPAD_5 */] = KEY_KP5, + [ 150 /* ANDROID_KEYCODE_NUMPAD_6 */] = KEY_KP6, + [ 151 /* ANDROID_KEYCODE_NUMPAD_7 */] = KEY_KP7, + [ 152 /* ANDROID_KEYCODE_NUMPAD_8 */] = KEY_KP8, + [ 153 /* ANDROID_KEYCODE_NUMPAD_9 */] = KEY_KP9, + [ 154 /* ANDROID_KEYCODE_NUMPAD_DIVIDE */] = KEY_KPSLASH, + [ 155 /* ANDROID_KEYCODE_NUMPAD_MULTIPLY */] = KEY_KPASTERISK, + [ 156 /* ANDROID_KEYCODE_NUMPAD_SUBTRACT */] = KEY_KPMINUS, + [ 157 /* ANDROID_KEYCODE_NUMPAD_ADD */] = KEY_KPPLUS, + [ 158 /* ANDROID_KEYCODE_NUMPAD_DOT */] = KEY_KPDOT, + [ 159 /* ANDROID_KEYCODE_NUMPAD_COMMA */] = KEY_KPCOMMA, + [ 160 /* ANDROID_KEYCODE_NUMPAD_ENTER */] = KEY_KPENTER, + [ 161 /* ANDROID_KEYCODE_NUMPAD_EQUALS */] = KEY_KPEQUAL, + [ 162 /* ANDROID_KEYCODE_NUMPAD_LEFT_PAREN */] = KEY_KPLEFTPAREN, + [ 163 /* ANDROID_KEYCODE_NUMPAD_RIGHT_PAREN */] = KEY_KPRIGHTPAREN, + [ 164 /* ANDROID_KEYCODE_VOLUME_MUTE */] = KEY_MUTE, + [ 165 /* ANDROID_KEYCODE_INFO */] = KEY_INFO, + [ 166 /* ANDROID_KEYCODE_CHANNEL_UP */] = KEY_CHANNELUP, + [ 167 /* ANDROID_KEYCODE_CHANNEL_DOWN */] = KEY_CHANNELDOWN, + [ 168 /* ANDROID_KEYCODE_ZOOM_IN */] = KEY_ZOOMIN, + [ 169 /* ANDROID_KEYCODE_ZOOM_OUT */] = KEY_ZOOMOUT, + [ 170 /* ANDROID_KEYCODE_TV */] = KEY_TV, + [ 208 /* ANDROID_KEYCODE_CALENDAR */] = KEY_CALENDAR, + [ 210 /* ANDROID_KEYCODE_CALCULATOR */] = KEY_CALC, +}; diff --git a/android/app/src/main/cpp/lorie/renderer.c b/android/app/src/main/cpp/lorie/renderer.c new file mode 100644 index 0000000..8003440 --- /dev/null +++ b/android/app/src/main/cpp/lorie/renderer.c @@ -0,0 +1,714 @@ +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma ide diagnostic ignored "UnusedParameter" +#pragma ide diagnostic ignored "DanglingPointer" +#pragma ide diagnostic ignored "ConstantConditionsOC" +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#pragma ide diagnostic ignored "UnreachableCode" +#pragma ide diagnostic ignored "OCUnusedMacroInspection" +#pragma ide diagnostic ignored "misc-no-recursion" +#define EGL_EGLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES + +#include +#include +#include +#include +#include +#include +#include +#include "renderer.h" +#include "os.h" + +#define log(...) __android_log_print(ANDROID_LOG_DEBUG, "gles-renderer", __VA_ARGS__) +#define loge(...) __android_log_print(ANDROID_LOG_ERROR, "gles-renderer", __VA_ARGS__) + +static GLuint create_program(const char* p_vertex_source, const char* p_fragment_source); + +static int eglCheckError(int line) { + char* desc; + int err = eglGetError(); + switch(err) { +#define E(code, text) case code: desc = (char*) text; break + case EGL_SUCCESS: desc = NULL; // "No error" + E(EGL_NOT_INITIALIZED, "EGL not initialized or failed to initialize"); + E(EGL_BAD_ACCESS, "Resource inaccessible"); + E(EGL_BAD_ALLOC, "Cannot allocate resources"); + E(EGL_BAD_ATTRIBUTE, "Unrecognized attribute or attribute value"); + E(EGL_BAD_CONTEXT, "Invalid EGL context"); + E(EGL_BAD_CONFIG, "Invalid EGL frame buffer configuration"); + E(EGL_BAD_CURRENT_SURFACE, "Current surface is no longer valid"); + E(EGL_BAD_DISPLAY, "Invalid EGL display"); + E(EGL_BAD_SURFACE, "Invalid surface"); + E(EGL_BAD_MATCH, "Inconsistent arguments"); + E(EGL_BAD_PARAMETER, "Invalid argument"); + E(EGL_BAD_NATIVE_PIXMAP, "Invalid native pixmap"); + E(EGL_BAD_NATIVE_WINDOW, "Invalid native window"); + E(EGL_CONTEXT_LOST, "Context lost"); +#undef E + default: desc = (char*) "Unknown error"; + } + + if (desc) + log("Xlorie: egl error on line %d: %s\n", line, desc); + + return err; +} + +static const char* eglErrorLabel(int code) { + switch(code) { + case EGL_SUCCESS: return NULL; // "No error" +#define E(code) case code: return #code; break + E(EGL_NOT_INITIALIZED); + E(EGL_BAD_ACCESS); + E(EGL_BAD_ALLOC); + E(EGL_BAD_ATTRIBUTE); + E(EGL_BAD_CONTEXT); + E(EGL_BAD_CONFIG); + E(EGL_BAD_CURRENT_SURFACE); + E(EGL_BAD_DISPLAY); + E(EGL_BAD_SURFACE); + E(EGL_BAD_MATCH); + E(EGL_BAD_PARAMETER); + E(EGL_BAD_NATIVE_PIXMAP); + E(EGL_BAD_NATIVE_WINDOW); + E(EGL_CONTEXT_LOST); +#undef E + default: return "EGL_UNKNOWN_ERROR"; + } + +} + +static void checkGlError(int line) { + GLenum error; + char *desc = NULL; + for (error = glGetError(); error; error = glGetError()) { + switch (error) { +#define E(code) case code: desc = (char*)#code; break + E(GL_INVALID_ENUM); + E(GL_INVALID_VALUE); + E(GL_INVALID_OPERATION); + E(GL_STACK_OVERFLOW_KHR); + E(GL_STACK_UNDERFLOW_KHR); + E(GL_OUT_OF_MEMORY); + E(GL_INVALID_FRAMEBUFFER_OPERATION); + E(GL_CONTEXT_LOST_KHR); + default: + continue; +#undef E + } + log("Xlorie: GLES %d ERROR: %s.\n", line, desc); + return; + } +} + +#define checkGlError() checkGlError(__LINE__) + + +static const char vertex_shader[] = + "attribute vec4 position;\n" + "attribute vec2 texCoords;" + "varying vec2 outTexCoords;\n" + "void main(void) {\n" + " outTexCoords = texCoords;\n" + " gl_Position = position;\n" + "}\n"; + +#define FRAGMENT_SHADER(texture) \ + "precision mediump float;\n" \ + "varying vec2 outTexCoords;\n" \ + "uniform sampler2D texture;\n" \ + "void main(void) {\n" \ + " gl_FragColor = texture2D(texture, outTexCoords)" texture ";\n" \ + "}\n" + +static const char fragment_shader[] = FRAGMENT_SHADER(); +static const char fragment_shader_bgra[] = FRAGMENT_SHADER(".bgra"); + +static EGLDisplay egl_display = EGL_NO_DISPLAY; +static EGLContext ctx = EGL_NO_CONTEXT; +static EGLSurface sfc = EGL_NO_SURFACE; +static EGLConfig cfg = 0; +static EGLNativeWindowType win = 0; +static jobject surface = NULL; +static AHardwareBuffer *buffer = NULL; +static EGLImageKHR image = NULL; +static int renderedFrames = 0; + +static jmethodID Surface_release = NULL; +static jmethodID Surface_destroy = NULL; + +static struct { + GLuint id; + float width, height; +} display; +static struct { + GLuint id; + float x, y, width, height, xhot, yhot; +} cursor; + +GLuint g_texture_program = 0, gv_pos = 0, gv_coords = 0; +GLuint g_texture_program_bgra = 0, gv_pos_bgra = 0, gv_coords_bgra = 0; + +int renderer_init(JNIEnv* env, int* legacy_drawing, uint8_t* flip) { + EGLint major, minor; + EGLint numConfigs; + const EGLint configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 0, + EGL_NONE + }; + const EGLint configAttribs2[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_NONE + }; + const EGLint ctxattribs[] = { + EGL_CONTEXT_CLIENT_VERSION,2, EGL_NONE + }; + + if (ctx) + return 1; + + jclass Surface = (*env)->FindClass(env, "android/view/Surface"); + Surface_release = (*env)->GetMethodID(env, Surface, "release", "()V"); + Surface_destroy = (*env)->GetMethodID(env, Surface, "destroy", "()V"); + if (!Surface_release) { + loge("Failed to find required Surface.release method. Aborting.\n"); + abort(); + } + if (!Surface_destroy) { + loge("Failed to find required Surface.destroy method. Aborting.\n"); + abort(); + } + + egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (egl_display == EGL_NO_DISPLAY) { + log("Xlorie: Got no EGL display.\n"); + eglCheckError(__LINE__); + return 0; + } + + if (eglInitialize(egl_display, &major, &minor) != EGL_TRUE) { + log("Xlorie: Unable to initialize EGL\n"); + eglCheckError(__LINE__); + return 0; + } + log("Xlorie: Initialized EGL version %d.%d\n", major, minor); + eglBindAPI(EGL_OPENGL_ES_API); + + if (eglChooseConfig(egl_display, configAttribs, &cfg, 1, &numConfigs) != EGL_TRUE && + eglChooseConfig(egl_display, configAttribs2, &cfg, 1, &numConfigs) != EGL_TRUE) { + log("Xlorie: eglChooseConfig failed.\n"); + eglCheckError(__LINE__); + return 0; + } + + ctx = eglCreateContext(egl_display, cfg, NULL, ctxattribs); + if (ctx == EGL_NO_CONTEXT) { + log("Xlorie: eglCreateContext failed.\n"); + eglCheckError(__LINE__); + return 0; + } + + if (eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { + log("Xlorie: eglMakeCurrent failed.\n"); + eglCheckError(__LINE__); + return 0; + } + + { + // Some devices do not support sampling from HAL_PIXEL_FORMAT_BGRA_8888, here we are checking it. + const EGLint imageAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; + EGLClientBuffer clientBuffer; + EGLImageKHR img; + AHardwareBuffer *new = NULL; + int status; + AHardwareBuffer_Desc d0 = { + .width = 64, + .height = 64, + .layers = 1, + .usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, + .format = AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM + }; + + status = AHardwareBuffer_allocate(&d0, &new); + if (status != 0 || new == NULL) { + loge("Failed to allocate native buffer (%p, error %d)", new, status); + loge("Forcing legacy drawing"); + *legacy_drawing = 1; + return 1; + } + + uint32_t *pixels; + if (AHardwareBuffer_lock(new, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, NULL, (void **) &pixels) == 0) { + pixels[0] = 0xAABBCCDD; + AHardwareBuffer_unlock(new, NULL); + } else { + loge("Failed to lock native buffer (%p, error %d)", new, status); + loge("Forcing legacy drawing"); + *legacy_drawing = 1; + return 1; + } + + clientBuffer = eglGetNativeClientBufferANDROID(new); + if (!clientBuffer) { + eglCheckError(__LINE__); + loge("Failed to obtain EGLClientBuffer from AHardwareBuffer"); + loge("Forcing legacy drawing"); + *legacy_drawing = 1; + return 1; + } + + if (!(img = eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttributes))) { + if (eglGetError() == EGL_BAD_PARAMETER) { + loge("Sampling from HAL_PIXEL_FORMAT_BGRA_8888 is not supported, forcing AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM"); + *flip = 1; + } else { + loge("Failed to obtain EGLImageKHR from EGLClientBuffer"); + loge("Forcing legacy drawing"); + *legacy_drawing = 1; + } + } else { + // For some reason all devices I checked had no GL_EXT_texture_format_BGRA8888 support, but some of them still provided BGRA extension. + // EGL does not provide functions to query texture format in runtime. + // Workarounds are less performant but at least they let us use Termux:X11 on devices with missing BGRA support. + // We handle two cases. + // If resulting texture has BGRA format but still drawing RGBA we should flip format to RGBA and flip pixels manually in shader. + // In the case if for some reason we can not use HAL_PIXEL_FORMAT_BGRA_8888 we should fallback to legacy drawing method (uploading pixels via glTexImage2D). + const EGLint configAttributes[] = { + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_NONE + }; + EGLConfig checkcfg = 0; + GLuint fbo = 0, texture = 0; + if (eglChooseConfig(egl_display, configAttributes, &checkcfg, 1, &numConfigs) != EGL_TRUE) { + log("Xlorie: check eglChooseConfig failed.\n"); + eglCheckError(__LINE__); + return 0; + } + + EGLContext testctx = eglCreateContext(egl_display, checkcfg, NULL, ctxattribs); + if (testctx == EGL_NO_CONTEXT) { + log("Xlorie: check eglCreateContext failed.\n"); + eglCheckError(__LINE__); + return 0; + } + + const EGLint pbufferAttributes[] = { + EGL_WIDTH, 64, + EGL_HEIGHT, 64, + EGL_NONE, + }; + EGLSurface checksfc = eglCreatePbufferSurface(egl_display, checkcfg, pbufferAttributes); + + if (eglMakeCurrent(egl_display, checksfc, checksfc, testctx) != EGL_TRUE) { + log("Xlorie: check eglMakeCurrent failed.\n"); + eglCheckError(__LINE__); + return 0; + } + + glActiveTexture(GL_TEXTURE0); checkGlError(); + glGenTextures(1, &texture); checkGlError(); + glBindTexture(GL_TEXTURE_2D, texture); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGlError(); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, img); checkGlError(); + glGenFramebuffers(1, &fbo); checkGlError(); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); checkGlError(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); checkGlError(); + uint32_t pixel[64*64]; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); checkGlError(); + if (pixel[0] == 0xAABBCCDD) { + log("Xlorie: GLES draws pixels unchanged, probably system does not support AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM. Forcing bgra.\n"); + *flip = 1; + } else if (pixel[0] != 0xAADDCCBB) { + log("Xlorie: GLES receives broken pixels. Forcing legacy drawing. 0x%X\n", pixel[0]); + *legacy_drawing = 1; + } + eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + } + } + + return 1; +} + +static void renderer_unset_buffer(void) { + if (eglGetCurrentContext() == EGL_NO_CONTEXT) { + loge("There is no current context, `renderer_set_buffer` call is cancelled"); + return; + } + + log("renderer_set_buffer0"); + if (image) + eglDestroyImageKHR(egl_display, image); + if (buffer) + AHardwareBuffer_release(buffer); + + buffer = NULL; +} + +void renderer_set_buffer(JNIEnv* env, AHardwareBuffer* buf) { + const EGLint imageAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; + EGLClientBuffer clientBuffer; + AHardwareBuffer_Desc desc = {0}; + uint8_t flip = 0; + + if (eglGetCurrentContext() == EGL_NO_CONTEXT) { + loge("There is no current context, `renderer_set_buffer` call is cancelled"); + return; + } + + renderer_unset_buffer(); + + buffer = buf; + + glBindTexture(GL_TEXTURE_2D, display.id); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGlError(); + if (buffer) { + AHardwareBuffer_acquire(buffer); + AHardwareBuffer_describe(buffer, &desc); + + display.width = (float) desc.width; + display.height = (float) desc.height; + + clientBuffer = eglGetNativeClientBufferANDROID(buffer); + if (!clientBuffer) { + eglCheckError(__LINE__); + loge("Failed to obtain EGLClientBuffer from AHardwareBuffer"); + } + image = clientBuffer ? eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttributes) : NULL; + if (image != NULL) { + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + flip = desc.format != AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM; + } else { + if (clientBuffer) { + eglCheckError(__LINE__); + loge("Binding AHardwareBuffer to an EGLImage failed."); + } + + display.width = 1; + display.height = 1; + uint32_t data = {0}; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data); + checkGlError(); + } + checkGlError(); + } else { + display.width = 1; + display.height = 1; + uint32_t data = {0}; + loge("There is no AHardwareBuffer, nothing to be bound."); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data); checkGlError(); + } + + renderer_redraw(env, flip); + + log("renderer_set_buffer %p %d %d", buffer, desc.width, desc.height); +} + +void renderer_set_window(JNIEnv* env, jobject new_surface, AHardwareBuffer* new_buffer) { + EGLNativeWindowType window; + if (new_surface && surface && new_surface != surface && (*env)->IsSameObject(env, new_surface, surface)) { + (*env)->DeleteGlobalRef(env, new_surface); + new_surface = NULL; + return; + } + + window = new_surface ? ANativeWindow_fromSurface(env, new_surface) : NULL; + int width = window ? ANativeWindow_getWidth(window) : 0; + int height = window ? ANativeWindow_getHeight(window) : 0; + log("renderer_set_window %p %d %d", window, width, height); + if (window && win == window) + return; + + if (sfc != EGL_NO_SURFACE) { + if (eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { + log("Xlorie: eglMakeCurrent (EGL_NO_SURFACE) failed.\n"); + eglCheckError(__LINE__); + return; + } + if (eglDestroySurface(egl_display, sfc) != EGL_TRUE) { + log("Xlorie: eglDestoySurface failed.\n"); + eglCheckError(__LINE__); + return; + } + } + sfc = EGL_NO_SURFACE; + if (win) + ANativeWindow_release(win); + + if (surface) { + (*env)->CallVoidMethod(env, surface, Surface_release); + (*env)->CallVoidMethod(env, surface, Surface_destroy); + (*env)->DeleteGlobalRef(env, surface); + } + + if (window && (width <= 0 || height <= 0)) { + log("Xlorie: We've got invalid surface. Probably it became invalid before we started working with it.\n"); + ANativeWindow_release(window); + window = NULL; + if (new_surface) { + (*env)->CallVoidMethod(env, new_surface, Surface_release); + (*env)->CallVoidMethod(env, new_surface, Surface_destroy); + (*env)->DeleteGlobalRef(env, new_surface); + new_surface = NULL; + } + } + + win = window; + surface = new_surface; + + if (!win) + return; + + sfc = eglCreateWindowSurface(egl_display, cfg, win, NULL); + if (sfc == EGL_NO_SURFACE) { + log("Xlorie: eglCreateWindowSurface failed.\n"); + eglCheckError(__LINE__); + return; + } + + if (eglMakeCurrent(egl_display, sfc, sfc, ctx) != EGL_TRUE) { + log("Xlorie: eglMakeCurrent failed.\n"); + eglCheckError(__LINE__); + return; + } + + if (!g_texture_program) { + g_texture_program = create_program(vertex_shader, fragment_shader); + if (!g_texture_program) { + log("Xlorie: GLESv2: Unable to create shader program.\n"); + eglCheckError(__LINE__); + return; + } + + g_texture_program_bgra = create_program(vertex_shader, fragment_shader_bgra); + if (!g_texture_program_bgra) { + log("Xlorie: GLESv2: Unable to create bgra shader program.\n"); + eglCheckError(__LINE__); + return; + } + + gv_pos = (GLuint) glGetAttribLocation(g_texture_program, "position"); checkGlError(); + gv_coords = (GLuint) glGetAttribLocation(g_texture_program, "texCoords"); checkGlError(); + + gv_pos_bgra = (GLuint) glGetAttribLocation(g_texture_program_bgra, "position"); checkGlError(); + gv_coords_bgra = (GLuint) glGetAttribLocation(g_texture_program_bgra, "texCoords"); checkGlError(); + + glActiveTexture(GL_TEXTURE0); checkGlError(); + glGenTextures(1, &display.id); checkGlError(); + glGenTextures(1, &cursor.id); checkGlError(); + } + + eglSwapInterval(egl_display, 0); + + if (win && ctx && ANativeWindow_getWidth(win) > 0 && ANativeWindow_getHeight(win) > 0) + glViewport(0, 0, ANativeWindow_getWidth(win), ANativeWindow_getHeight(win)); checkGlError(); + + log("Xlorie: new surface applied: %p\n", sfc); + + if (!new_buffer) { + glClearColor(0.f, 0.f, 0.f, 0.0f); checkGlError(); + glClear(GL_COLOR_BUFFER_BIT); checkGlError(); + } else renderer_set_buffer(env, new_buffer); +} + +void renderer_update_root(int w, int h, void* data, uint8_t flip) { + if (eglGetCurrentContext() == EGL_NO_CONTEXT || !w || !h) + return; + + if (display.width != (float) w || display.height != (float) h) { + display.width = (float) w; + display.height = (float) h; + + glBindTexture(GL_TEXTURE_2D, display.id); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGlError(); + glTexImage2D(GL_TEXTURE_2D, 0, flip ? GL_RGBA : GL_BGRA_EXT, w, h, 0, flip ? GL_RGBA : GL_BGRA_EXT, GL_UNSIGNED_BYTE, data); checkGlError(); + } else { + glBindTexture(GL_TEXTURE_2D, display.id); checkGlError(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, flip ? GL_RGBA : GL_BGRA_EXT, GL_UNSIGNED_BYTE, data); + checkGlError(); + } +} + +void renderer_update_cursor(int w, int h, int xhot, int yhot, void* data) { + log("Xlorie: updating cursor\n"); + cursor.width = (float) w; + cursor.height = (float) h; + cursor.xhot = (float) xhot; + cursor.yhot = (float) yhot; + + if (eglGetCurrentContext() == EGL_NO_CONTEXT || !cursor.width || !cursor.height) + return; + + glBindTexture(GL_TEXTURE_2D, cursor.id); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGlError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGlError(); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); checkGlError(); +} + +void renderer_set_cursor_coordinates(int x, int y) { + cursor.x = (float) x; + cursor.y = (float) y; +} + +static void draw(GLuint id, float x0, float y0, float x1, float y1, uint8_t flip); +static void draw_cursor(void); + +float ia = 0; + +int renderer_should_redraw(void) { + return sfc != EGL_NO_SURFACE && eglGetCurrentContext() != EGL_NO_CONTEXT; +} + +int renderer_redraw(JNIEnv* env, uint8_t flip) { + int err = EGL_SUCCESS; + + if (!sfc || eglGetCurrentContext() == EGL_NO_CONTEXT) + return FALSE; + + draw(display.id, -1.f, -1.f, 1.f, 1.f, flip); + draw_cursor(); + if (eglSwapBuffers(egl_display, sfc) != EGL_TRUE) { + err = eglGetError(); + eglCheckError(__LINE__); + if (err == EGL_BAD_NATIVE_WINDOW || err == EGL_BAD_SURFACE) { + log("We've got %s so window is to be destroyed. " + "Native window disconnected/abandoned, probably activity is destroyed or in background", + eglErrorLabel(err)); + renderer_set_window(env, NULL, NULL); + return FALSE; + } + } + + renderedFrames++; + return TRUE; +} + +void renderer_print_fps(float millis) { + if (renderedFrames) + log("%d frames in %.1f seconds = %.1f FPS", + renderedFrames, millis / 1000, (float) renderedFrames * 1000 / millis); + renderedFrames = 0; +} + +static GLuint load_shader(GLenum shaderType, const char* pSource) { + GLint compiled = 0; + GLuint shader = glCreateShader(shaderType); checkGlError(); + if (shader) { + glShaderSource(shader, 1, &pSource, NULL); checkGlError(); + glCompileShader(shader); checkGlError(); + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); checkGlError(); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); checkGlError(); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); checkGlError(); + log("Xlorie: Could not compile shader %d:\n%s\n", shaderType, buf); + free(buf); + } + glDeleteShader(shader); checkGlError(); + shader = 0; + } + } + } + return shader; +} + +static GLuint create_program(const char* p_vertex_source, const char* p_fragment_source) { + GLuint program, vertexShader, pixelShader; + GLint linkStatus = GL_FALSE; + vertexShader = load_shader(GL_VERTEX_SHADER, p_vertex_source); + pixelShader = load_shader(GL_FRAGMENT_SHADER, p_fragment_source); + if (!pixelShader || !vertexShader) { + return 0; + } + + program = glCreateProgram(); checkGlError(); + if (program) { + glAttachShader(program, vertexShader); checkGlError(); + glAttachShader(program, pixelShader); checkGlError(); + glLinkProgram(program); checkGlError(); + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); checkGlError(); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); checkGlError(); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); checkGlError(); + log("Xlorie: Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(program); checkGlError(); + program = 0; + } + } + return program; +} + +static void draw(GLuint id, float x0, float y0, float x1, float y1, uint8_t flip) { + float coords[20] = { + x0, -y0, 0.f, 0.f, 0.f, + x1, -y0, 0.f, 1.f, 0.f, + x0, -y1, 0.f, 0.f, 1.f, + x1, -y1, 0.f, 1.f, 1.f, + }; + + GLuint p = flip ? gv_pos_bgra : gv_pos, c = flip ? gv_coords_bgra : gv_coords; + + glActiveTexture(GL_TEXTURE0); checkGlError(); + glUseProgram(flip ? g_texture_program_bgra : g_texture_program); checkGlError(); + glBindTexture(GL_TEXTURE_2D, id); checkGlError(); + + glVertexAttribPointer(p, 3, GL_FLOAT, GL_FALSE, 20, coords); checkGlError(); + glVertexAttribPointer(c, 2, GL_FLOAT, GL_FALSE, 20, &coords[3]); checkGlError(); + glEnableVertexAttribArray(p); checkGlError(); + glEnableVertexAttribArray(c); checkGlError(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); checkGlError(); +} + +__unused static void draw_cursor(void) { + float x, y, w, h; + + if (!cursor.width || !cursor.height) + return; + + x = 2.f * (cursor.x - cursor.xhot) / display.width - 1.f; + y = 2.f * (cursor.y - cursor.yhot) / display.height - 1.f; + w = 2.f * cursor.width / display.width; + h = 2.f * cursor.height / display.height; + glEnable(GL_BLEND); checkGlError(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); checkGlError(); + draw(cursor.id, x, y, x + w, y + h, false); + glDisable(GL_BLEND); checkGlError(); +} + diff --git a/android/app/src/main/cpp/lorie/renderer.h b/android/app/src/main/cpp/lorie/renderer.h new file mode 100644 index 0000000..416e469 --- /dev/null +++ b/android/app/src/main/cpp/lorie/renderer.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include + +// X server is already linked to mesa so linking to Android's GLESv2 will confuse the linker. +// That is a reason why we should compile renderer as separate hared library with its own dependencies. +// In that case part of X server's api is unavailable, +// so we should pass addresses to all needed functions to the renderer lib. +typedef void (*renderer_message_func_type) (int type, int verb, const char *format, ...); +__unused void renderer_message_func(renderer_message_func_type function); + +__unused int renderer_init(JNIEnv* env, int* legacy_drawing, uint8_t* flip); +__unused void renderer_set_buffer(JNIEnv* env, AHardwareBuffer* buffer); +__unused void renderer_set_window(JNIEnv* env, jobject surface, AHardwareBuffer* buffer); +__unused int renderer_should_redraw(void); +__unused int renderer_redraw(JNIEnv* env, uint8_t flip); +__unused void renderer_print_fps(float millis); + +__unused void renderer_update_root(int w, int h, void* data, uint8_t flip); +__unused void renderer_update_cursor(int w, int h, int xhot, int yhot, void* data); +__unused void renderer_set_cursor_coordinates(int x, int y); + +#define AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM 5 // Stands to HAL_PIXEL_FORMAT_BGRA_8888 \ No newline at end of file diff --git a/android/app/src/main/cpp/lorie/shm/LICENSE b/android/app/src/main/cpp/lorie/shm/LICENSE new file mode 100644 index 0000000..e741c3e --- /dev/null +++ b/android/app/src/main/cpp/lorie/shm/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2013, Sergii Pylypenko +Copyright (c) 2017, Fredrik Fornwall +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* 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. + +* Neither the name of the {organization} 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. diff --git a/android/app/src/main/cpp/lorie/shm/README.md b/android/app/src/main/cpp/lorie/shm/README.md new file mode 100644 index 0000000..475cf3e --- /dev/null +++ b/android/app/src/main/cpp/lorie/shm/README.md @@ -0,0 +1,11 @@ +libandroid-shmem +================ +System V shared memory (shmget, shmat, shmdt and shmctl) emulation on Android using ashmem for use in [Termux](https://termux.com/). + +The shared memory segments it creates will be automatically destroyed when the creating process destroys them or dies, which differs from the System V shared memory behaviour. + +Based on previous work in https://github.com/pelya/android-shmem. + +Hacking +======= +The project can be developed on Android devices using Termux. Clone the repo and run `make` in the `tests/` folder after editing the library or test cases. diff --git a/android/app/src/main/cpp/lorie/shm/shm.h b/android/app/src/main/cpp/lorie/shm/shm.h new file mode 100644 index 0000000..faab787 --- /dev/null +++ b/android/app/src/main/cpp/lorie/shm/shm.h @@ -0,0 +1,36 @@ +#ifndef _SYS_SHM_H +#define _SYS_SHM_H + +#include +#include +#include + +__BEGIN_DECLS + +#ifndef shmid_ds +# define shmid_ds shmid64_ds +#endif + +/* Shared memory control operations. */ +#undef shmctl +#define shmctl libandroid_shmctl +extern int shmctl(int shmid, int cmd, struct shmid_ds* buf); + +/* Get shared memory area identifier. */ +#undef shmget +#define shmget libandroid_shmget +extern int shmget(key_t key, size_t size, int shmflg); + +/* Attach shared memory segment. */ +#undef shmat +#define shmat libandroid_shmat +extern void *shmat(int shmid, void const* shmaddr, int shmflg); + +/* Detach shared memory segment. */ +#undef shmdt +#define shmdt libandroid_shmdt +extern int shmdt(void const* shmaddr); + +__END_DECLS + +#endif diff --git a/android/app/src/main/cpp/lorie/shm/shmem.c b/android/app/src/main/cpp/lorie/shm/shmem.c new file mode 100644 index 0000000..4ce778e --- /dev/null +++ b/android/app/src/main/cpp/lorie/shm/shmem.c @@ -0,0 +1,638 @@ +#ifdef ANDROID +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __u32 uint32_t +#ifdef ANDROID +#include +#include + +#endif + +#include "shm.h" + +#define DBG(...) +#define ANDROID_SHMEM_SOCKNAME "/dev/shm/%08x" +#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +typedef struct { + // The shmid (shared memory id) contains the socket address (16 bits) + // and a local id (15 bits). + int id; + void *addr; + int descriptor; + size_t size; + bool markedForDeletion; + key_t key; +} shmem_t; + +static shmem_t* shmem = NULL; +static size_t shmem_amount = 0; + +static uint8_t syscall_supported = 0; + +#define ANDROID_LINUX_SHM +#undef SYS_ipc +static bool isProot(void) { + char buf[4096]; + char path[256]; + char exe_path[256]; + int tpid; + + const int status_fd = open("/proc/self/status", O_RDONLY); + if (status_fd == -1) + return false; + + read(status_fd, buf, sizeof(buf) - 1); + close(status_fd); + + const char *tracer_str = strstr(buf, "TracerPid:"); + + if (tracer_str || sscanf(tracer_str, "TracerPid: %d", &tpid) != 1 || !tpid) + return false; + + snprintf(path, sizeof(path), "/proc/%d/exe", tpid); + + ssize_t len = readlink(path, exe_path, sizeof(exe_path) - 1); + if (len == -1) + return false; + + exe_path[len] = '\0'; + return (!strcmp(basename(exe_path), "proot")); +} + +__attribute__((unused, constructor)) +static void check_syscall_support(void) { + if (!isProot()) + return; + + errno = 0; +#ifdef ANDROID_LINUX_SHM +#ifdef SYS_ipc + syscall(SYS_ipc); +#else + syscall(SYS_shmat); +#endif +#endif + if (errno != ENOSYS) + syscall_supported = 1; +} + +// The lower 16 bits of (getpid() + i), where i is a sequence number. +// It is unique among processes as it's only set when bound. +static int ashv_local_socket_id = 0; +// To handle forks we store which pid the ashv_local_socket_id was +// created for. +static int ashv_pid_setup = 0; +static pthread_t ashv_listening_thread_id = 0; + +static int ancil_send_fd(int sock, int fd) +{ + char nothing = '!'; + struct iovec nothing_ptr = { .iov_base = ¬hing, .iov_len = 1 }; + + struct { + struct cmsghdr align; + int fd[1]; + } ancillary_data_buffer; + + struct msghdr message_header = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = ¬hing_ptr, + .msg_iovlen = 1, + .msg_flags = 0, + .msg_control = &ancillary_data_buffer, + .msg_controllen = sizeof(struct cmsghdr) + sizeof(int) + }; + + struct cmsghdr* cmsg = CMSG_FIRSTHDR(&message_header); + cmsg->cmsg_len = message_header.msg_controllen; // sizeof(int); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + ((int*) CMSG_DATA(cmsg))[0] = fd; + + return sendmsg(sock, &message_header, 0) >= 0 ? 0 : -1; +} + +static int ancil_recv_fd(int sock) +{ + char nothing = '!'; + struct iovec nothing_ptr = { .iov_base = ¬hing, .iov_len = 1 }; + + struct { + struct cmsghdr align; + int fd[1]; + } ancillary_data_buffer; + + struct msghdr message_header = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = ¬hing_ptr, + .msg_iovlen = 1, + .msg_flags = 0, + .msg_control = &ancillary_data_buffer, + .msg_controllen = sizeof(struct cmsghdr) + sizeof(int) + }; + + struct cmsghdr* cmsg = CMSG_FIRSTHDR(&message_header); + cmsg->cmsg_len = message_header.msg_controllen; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + ((int*) CMSG_DATA(cmsg))[0] = -1; + + if (recvmsg(sock, &message_header, 0) < 0) return -1; + + return ((int*) CMSG_DATA(cmsg))[0]; +} + +static int ashmem_get_size_region(int fd) +{ +#ifdef ANDROID + //int ret = __ashmem_is_ashmem(fd, 1); + //if (ret < 0) return ret; + return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL)); +#else + return -1; +#endif +} + +/* + * From https://android.googlesource.com/platform/system/core/+/master/libcutils/ashmem-dev.c + * + * ashmem_create_region - creates a new named ashmem region and returns the file + * descriptor, or <0 on error. + * + * `name' is the label to give the region (visible in /proc/pid/maps) + * `size' is the size of the region, in page-aligned bytes + */ +static int ashmem_create_region(char const* name, size_t size) +{ +#ifdef ANDROID + int fd = open("/dev/ashmem", O_RDWR); + if (fd < 0) return fd; + + char name_buffer[ASHMEM_NAME_LEN] = {0}; + strncpy(name_buffer, name, sizeof(name_buffer)); + name_buffer[sizeof(name_buffer)-1] = 0; + + int ret = ioctl(fd, ASHMEM_SET_NAME, name_buffer); + if (ret < 0) goto error; + + ret = ioctl(fd, ASHMEM_SET_SIZE, size); + if (ret < 0) goto error; + + return fd; +error: + close(fd); + return ret; +#endif + return -1; +} + +static void ashv_check_pid() +{ + pid_t mypid = getpid(); + if (ashv_pid_setup == 0) { + ashv_pid_setup = mypid; + } else if (ashv_pid_setup != mypid) { + DBG("%s: Cleaning to new pid=%d from oldpid=%d", __PRETTY_FUNCTION__, mypid, ashv_pid_setup); + // We inherited old state across a fork. + ashv_pid_setup = mypid; + ashv_local_socket_id = 0; + ashv_listening_thread_id = 0; + shmem_amount = 0; + // Unlock if fork left us with held lock from parent thread. + pthread_mutex_unlock(&mutex); + if (shmem != NULL) free(shmem); + shmem = NULL; + } +} + + +// Store index in the lower 15 bits and the socket id in the +// higher 16 bits. +static int ashv_shmid_from_counter(unsigned int counter) +{ + return ashv_local_socket_id * 0x10000 + counter; +} + +static int ashv_socket_id_from_shmid(int shmid) +{ + return shmid / 0x10000; +} + +static int ashv_find_local_index(int shmid) +{ + for (size_t i = 0; i < shmem_amount; i++) + if (shmem[i].id == shmid) + return i; + return -1; +} + +static void* ashv_thread_function(void* arg) +{ + int sock = *(int*)arg; + free(arg); + struct sockaddr_un addr; + socklen_t len = sizeof(addr); + int sendsock; + //DBG("%s: thread started", __PRETTY_FUNCTION__); + while ((sendsock = accept(sock, (struct sockaddr *)&addr, &len)) != -1) { + int shmid; + if (recv(sendsock, &shmid, sizeof(shmid), 0) != sizeof(shmid)) { + DBG("%s: ERROR: recv() returned not %zu bytes", __PRETTY_FUNCTION__, sizeof(shmid)); + close(sendsock); + continue; + } + pthread_mutex_lock(&mutex); + int idx = ashv_find_local_index(shmid); + if (idx != -1) { + if (write(sendsock, &shmem[idx].key, sizeof(key_t)) != sizeof(key_t)) { + DBG("%s: ERROR: write failed: %s", __PRETTY_FUNCTION__, strerror(errno)); + } + if (ancil_send_fd(sendsock, shmem[idx].descriptor) != 0) { + DBG("%s: ERROR: ancil_send_fd() failed: %s", __PRETTY_FUNCTION__, strerror(errno)); + } + } else { + DBG("%s: ERROR: cannot find shmid 0x%x", __PRETTY_FUNCTION__, shmid); + } + pthread_mutex_unlock(&mutex); + close(sendsock); + len = sizeof(addr); + } + DBG ("%s: ERROR: listen() failed, thread stopped", __PRETTY_FUNCTION__); + return NULL; +} + +static void android_shmem_delete(int idx) +{ + if (shmem[idx].descriptor) close(shmem[idx].descriptor); + shmem_amount--; + memmove(&shmem[idx], &shmem[idx+1], (shmem_amount - idx) * sizeof(shmem_t)); +} + +static int ashv_read_remote_segment(int shmid) +{ + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + sprintf(&addr.sun_path[1], ANDROID_SHMEM_SOCKNAME, ashv_socket_id_from_shmid(shmid)); + int addrlen = sizeof(addr.sun_family) + strlen(&addr.sun_path[1]) + 1; + + int recvsock = socket(AF_UNIX, SOCK_STREAM, 0); + if (recvsock == -1) { + DBG ("%s: cannot create UNIX socket: %s", __PRETTY_FUNCTION__, strerror(errno)); + return -1; + } + if (connect(recvsock, (struct sockaddr*) &addr, addrlen) != 0) { + DBG("%s: Cannot connect to UNIX socket %s: %s, len %d", __PRETTY_FUNCTION__, addr.sun_path + 1, strerror(errno), addrlen); + close(recvsock); + return -1; + } + + if (send(recvsock, &shmid, sizeof(shmid), 0) != sizeof(shmid)) { + DBG ("%s: send() failed on socket %s: %s", __PRETTY_FUNCTION__, addr.sun_path + 1, strerror(errno)); + close(recvsock); + return -1; + } + + key_t key; + if (read(recvsock, &key, sizeof(key_t)) != sizeof(key_t)) { + DBG("%s: ERROR: failed read", __PRETTY_FUNCTION__); + close(recvsock); + return -1; + } + + int descriptor = ancil_recv_fd(recvsock); + if (descriptor < 0) { + DBG("%s: ERROR: ancil_recv_fd() failed on socket %s: %s", __PRETTY_FUNCTION__, addr.sun_path + 1, strerror(errno)); + close(recvsock); + return -1; + } + close(recvsock); + + int size = ashmem_get_size_region(descriptor); + if (size == 0 || size == -1) { + DBG ("%s: ERROR: ashmem_get_size_region() returned %d on socket %s: %s", __PRETTY_FUNCTION__, size, addr.sun_path + 1, strerror(errno)); + return -1; + } + + int idx = shmem_amount; + shmem_amount ++; + shmem = realloc(shmem, shmem_amount * sizeof(shmem_t)); + shmem[idx].id = shmid; + shmem[idx].descriptor = descriptor; + shmem[idx].size = size; + shmem[idx].addr = NULL; + shmem[idx].markedForDeletion = false; + shmem[idx].key = key; + return idx; +} + +/* Get shared memory area identifier. */ +int shmget(key_t key, size_t size, int flags) +{ + (void) flags; +#ifdef ANDROID_LINUX_SHM + if (syscall_supported) { + if (size > PTRDIFF_MAX) size = SIZE_MAX; +#ifndef SYS_ipc + return syscall(SYS_shmget, key, size, flags); +#else + return syscall(SYS_ipc, IPCOP_shmget, key, size, flag); +#endif + } +#endif + + ashv_check_pid(); + + // Counter wrapping around at 15 bits. + static size_t shmem_counter = 0; + + if (!ashv_listening_thread_id) { + int sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (!sock) { + DBG ("%s: cannot create UNIX socket: %s", __PRETTY_FUNCTION__, strerror(errno)); + errno = EINVAL; + return -1; + } + int i; + for (i = 0; i < 4096; i++) { + struct sockaddr_un addr; + int len; + memset (&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + ashv_local_socket_id = (getpid() + i) & 0xffff; + sprintf(&addr.sun_path[1], ANDROID_SHMEM_SOCKNAME, ashv_local_socket_id); + len = sizeof(addr.sun_family) + strlen(&addr.sun_path[1]) + 1; + if (bind(sock, (struct sockaddr *)&addr, len) != 0) continue; + DBG("%s: bound UNIX socket %s in pid=%d", __PRETTY_FUNCTION__, addr.sun_path + 1, getpid()); + break; + } + if (i == 4096) { + DBG("%s: cannot bind UNIX socket, bailing out", __PRETTY_FUNCTION__); + ashv_local_socket_id = 0; + errno = ENOMEM; + return -1; + } + if (listen(sock, 4) != 0) { + DBG("%s: listen failed", __PRETTY_FUNCTION__); + errno = ENOMEM; + return -1; + } + int* socket_arg = malloc(sizeof(int)); + *socket_arg = sock; + pthread_create(&ashv_listening_thread_id, NULL, &ashv_thread_function, socket_arg); + } + + int shmid = -1; + + pthread_mutex_lock(&mutex); + char symlink_path[256]; + if (key != IPC_PRIVATE) { + // (1) Check if symlink exists telling us where to connect. + // (2) If so, try to connect and open. + // (3) If connected and opened, done. If connection refused + // take ownership of the key and create the symlink. + // (4) If no symlink, create it. + sprintf(symlink_path, "%s/ashv_key_%d", _PATH_TMP, key); + char path_buffer[256]; + char num_buffer[64]; + while (true) { + int path_length = readlink(symlink_path, path_buffer, sizeof(path_buffer) - 1); + if (path_length != -1) { + path_buffer[path_length] = '\0'; + int shmid = atoi(path_buffer); + if (shmid != 0) { + int idx = ashv_find_local_index(shmid); + + if (idx == -1) { + idx = ashv_read_remote_segment(shmid); + } + + if (idx != -1) { + pthread_mutex_unlock(&mutex); + return shmem[idx].id; + } + } + // TODO: Not sure we should try to remove previous owner if e.g. + // there was a tempporary failture to get a soket. Need to + // distinguish between why ashv_read_remote_segment failed. + unlink(symlink_path); + } + // Take ownership. + // TODO: HAndle error (out of resouces, no infinite loop) + if (shmid == -1) { + shmem_counter = (shmem_counter + 1) & 0x7fff; + shmid = ashv_shmid_from_counter(shmem_counter); + sprintf(num_buffer, "%d", shmid); + } + if (symlink(num_buffer, symlink_path) == 0) break; + } + } + + + int idx = shmem_amount; + char buf[256]; + sprintf(buf, ANDROID_SHMEM_SOCKNAME "-%d", ashv_local_socket_id, idx); + + shmem_amount++; + if (shmid == -1) { + shmem_counter = (shmem_counter + 1) & 0x7fff; + shmid = ashv_shmid_from_counter(shmem_counter); + } + + shmem = realloc(shmem, shmem_amount * sizeof(shmem_t)); + size = ROUND_UP(size, getpagesize()); + shmem[idx].size = size; + shmem[idx].descriptor = ashmem_create_region(buf, size); + shmem[idx].addr = NULL; + shmem[idx].id = shmid; + shmem[idx].markedForDeletion = false; + shmem[idx].key = key; + + if (shmem[idx].descriptor < 0) { + DBG("%s: ashmem_create_region() failed for size %zu: %s", __PRETTY_FUNCTION__, size, strerror(errno)); + shmem_amount --; + shmem = realloc(shmem, shmem_amount * sizeof(shmem_t)); + pthread_mutex_unlock (&mutex); + return -1; + } + pthread_mutex_unlock(&mutex); + + return shmid; +} + +/* Attach shared memory segment. */ +void* shmat(int shmid, void const* shmaddr, int shmflg) +{ +#ifdef ANDROID_LINUX_SHM + if (syscall_supported) { +#ifndef SYS_ipc + return (void *)syscall(SYS_shmat, shmid, shmaddr, shmflg); +#else + unsigned long ret; + ret = syscall(SYS_ipc, IPCOP_shmat, shmid, shmflg, &shmaddr, shmaddr); + return (ret > -(unsigned long)SHMLBA) ? (void *)ret : (void *)shmaddr; +#endif + } +#endif + ashv_check_pid(); + + int socket_id = ashv_socket_id_from_shmid(shmid); + void *addr; + + pthread_mutex_lock(&mutex); + + int idx = ashv_find_local_index(shmid); + if (idx == -1 && socket_id != ashv_local_socket_id) { + idx = ashv_read_remote_segment(shmid); + } + + if (idx == -1) { + DBG ("%s: shmid %x does not exist", __PRETTY_FUNCTION__, shmid); + pthread_mutex_unlock(&mutex); + errno = EINVAL; + return (void*) -1; + } + + if (shmem[idx].addr == NULL) { + shmem[idx].addr = mmap((void*) shmaddr, shmem[idx].size, PROT_READ | (shmflg == 0 ? PROT_WRITE : 0), MAP_SHARED, shmem[idx].descriptor, 0); + if (shmem[idx].addr == MAP_FAILED) { + DBG ("%s: mmap() failed for ID %x FD %d: %s", __PRETTY_FUNCTION__, idx, shmem[idx].descriptor, strerror(errno)); + shmem[idx].addr = NULL; + } + } + addr = shmem[idx].addr; + DBG ("%s: mapped addr %p for FD %d ID %d", __PRETTY_FUNCTION__, addr, shmem[idx].descriptor, idx); + pthread_mutex_unlock (&mutex); + + return addr ? addr : (void *)-1; +} + +/* Detach shared memory segment. */ +int shmdt(void const* shmaddr) +{ +#ifdef ANDROID_LINUX_SHM + if (syscall_supported) { +#ifndef SYS_ipc + return syscall(SYS_shmdt, shmaddr); +#else + return syscall(SYS_ipc, IPCOP_shmdt, 0, 0, 0, shmaddr); +#endif + } +#endif + ashv_check_pid(); + + pthread_mutex_lock(&mutex); + for (size_t i = 0; i < shmem_amount; i++) { + if (shmem[i].addr == shmaddr) { + if (munmap(shmem[i].addr, shmem[i].size) != 0) { + DBG("%s: munmap %p failed", __PRETTY_FUNCTION__, shmaddr); + } + shmem[i].addr = NULL; + DBG("%s: unmapped addr %p for FD %d ID %zu shmid %x", __PRETTY_FUNCTION__, shmaddr, shmem[i].descriptor, i, shmem[i].id); + if (shmem[i].markedForDeletion || ashv_socket_id_from_shmid(shmem[i].id) != ashv_local_socket_id) { + DBG ("%s: deleting shmid %x", __PRETTY_FUNCTION__, shmem[i].id); + android_shmem_delete(i); + } + pthread_mutex_unlock(&mutex); + return 0; + } + } + pthread_mutex_unlock(&mutex); + + DBG("%s: invalid address %p", __PRETTY_FUNCTION__, shmaddr); + /* Could be a remove segment, do not report an error for that. */ + return 0; +} + +/* Shared memory control operation. */ +int shmctl(int shmid, int cmd, struct shmid_ds *buf) +{ +#ifdef ANDROID_LINUX_SHM + if (syscall_supported) { +#ifndef SYS_ipc + return syscall(SYS_shmctl, shmid, cmd, buf); +#else + return syscall(SYS_ipc, IPCOP_shmctl, shmid, cmd, 0, buf, 0); +#endif + } +#endif + ashv_check_pid(); + + if (cmd == IPC_RMID) { + DBG("%s: IPC_RMID for shmid=%x", __PRETTY_FUNCTION__, shmid); + pthread_mutex_lock(&mutex); + int idx = ashv_find_local_index(shmid); + if (idx == -1) { + DBG("%s: shmid=%x does not exist locally", __PRETTY_FUNCTION__, shmid); + /* We do not rm non-local regions, but do not report an error for that. */ + pthread_mutex_unlock(&mutex); + return 0; + } + + if (shmem[idx].addr) { + // shmctl(2): The segment will actually be destroyed only + // after the last process detaches it (i.e., when the shm_nattch + // member of the associated structure shmid_ds is zero. + shmem[idx].markedForDeletion = true; + } else { + android_shmem_delete(idx); + } + pthread_mutex_unlock(&mutex); + return 0; + } else if (cmd == IPC_STAT) { + if (!buf) { + DBG ("%s: ERROR: buf == NULL for shmid %x", __PRETTY_FUNCTION__, shmid); + errno = EINVAL; + return -1; + } + + pthread_mutex_lock(&mutex); + int idx = ashv_find_local_index(shmid); + if (idx == -1) { + DBG ("%s: ERROR: shmid %x does not exist", __PRETTY_FUNCTION__, shmid); + pthread_mutex_unlock (&mutex); + errno = EINVAL; + return -1; + } + /* Report max permissive mode */ + memset(buf, 0, sizeof(struct shmid_ds)); + buf->shm_segsz = shmem[idx].size; + buf->shm_nattch = 1; + buf->shm_perm.key = shmem[idx].key; + buf->shm_perm.uid = geteuid(); + buf->shm_perm.gid = getegid(); + buf->shm_perm.cuid = geteuid(); + buf->shm_perm.cgid = getegid(); + buf->shm_perm.mode = 0666; + buf->shm_perm.seq = 1; + + pthread_mutex_unlock (&mutex); + return 0; + } + + DBG("%s: cmd %d not implemented yet!", __PRETTY_FUNCTION__, cmd); + errno = EINVAL; + return -1; +} diff --git a/android/app/src/main/cpp/patches/Xtrans.patch b/android/app/src/main/cpp/patches/Xtrans.patch new file mode 100644 index 0000000..756045e --- /dev/null +++ b/android/app/src/main/cpp/patches/Xtrans.patch @@ -0,0 +1,127 @@ +diff --git a/Xtranssock.c b/Xtranssock.c +index b06579c..bb5238b 100644 +--- a/Xtranssock.c ++++ b/Xtranssock.c +@@ -200,20 +200,28 @@ static int TRANS(SocketINETClose) (XtransConnInfo ciptr); + + + #if defined(X11_t) +-#define UNIX_PATH "/tmp/.X11-unix/X" +-#define UNIX_DIR "/tmp/.X11-unix" ++extern char* xtrans_unix_path_x11; ++extern char* xtrans_unix_dir_x11; ++#define UNIX_PATH xtrans_unix_path_x11 ++#define UNIX_DIR xtrans_unix_dir_x11 + #endif /* X11_t */ + #if defined(XIM_t) +-#define UNIX_PATH "/tmp/.XIM-unix/XIM" +-#define UNIX_DIR "/tmp/.XIM-unix" ++extern char* xtrans_unix_path_xim; ++extern char* xtrans_unix_dir_xim; ++#define UNIX_PATH xtrans_unix_path_xim ++#define UNIX_DIR xtrans_unix_dir_xim + #endif /* XIM_t */ + #if defined(FS_t) || defined(FONT_t) +-#define UNIX_PATH "/tmp/.font-unix/fs" +-#define UNIX_DIR "/tmp/.font-unix" ++extern char* xtrans_unix_path_fs; ++extern char* xtrans_unix_dir_fs; ++#define UNIX_PATH xtrans_unix_path_fs ++#define UNIX_DIR xtrans_unix_dir_fs + #endif /* FS_t || FONT_t */ + #if defined(ICE_t) +-#define UNIX_PATH "/tmp/.ICE-unix/" +-#define UNIX_DIR "/tmp/.ICE-unix" ++extern char* xtrans_unix_path_ice; ++extern char* xtrans_unix_dir_ice; ++#define UNIX_PATH xtrans_unix_path_ice ++#define UNIX_DIR xtrans_unix_dir_ice + #endif /* ICE_t */ + + +diff --git a/Xtransutil.c b/Xtransutil.c +index 63f0fc3..a9620a6 100644 +--- a/Xtransutil.c ++++ b/Xtransutil.c +@@ -478,27 +478,6 @@ + } + /* Dir doesn't exist. Try to create it */ + +-#if !defined(WIN32) && !defined(__CYGWIN__) +- /* +- * 'sticky' bit requested: assume application makes +- * certain security implications. If effective user ID +- * is != 0: fail as we may not be able to meet them. +- */ +- if (geteuid() != 0) { +- if (mode & 01000) { +- prmsg(1, "mkdir: ERROR: euid != 0," +- "directory %s will not be created.\n", +- path); +-#ifdef FAIL_HARD +- return -1; +-#endif +- } else { +- prmsg(1, "mkdir: Cannot create %s with root ownership\n", +- path); +- } +- } +-#endif +- + #ifndef WIN32 + if (mkdir(path, mode) == 0) { + if (chmod(path, mode)) { +@@ -521,14 +500,9 @@ + + } else { + if (S_ISDIR(buf.st_mode)) { +- int updateOwner = 0; + int updateMode = 0; +- int updatedOwner = 0; + int updatedMode = 0; + int status = 0; +- /* Check if the directory's ownership is OK. */ +- if (buf.st_uid != 0) +- updateOwner = 1; + + /* + * Check if the directory's mode is OK. An exact match isn't +@@ -566,7 +540,7 @@ + * directory's owner and mode. Otherwise it isn't safe to attempt + * to do this. + */ +- if (updateMode || updateOwner) { ++ if (updateMode) { + int fd = -1; + struct stat fbuf; + if ((fd = open(path, O_RDONLY)) != -1) { +@@ -588,8 +562,6 @@ + close(fd); + return -1; + } +- if (updateOwner && fchown(fd, 0, 0) == 0) +- updatedOwner = 1; + if (updateMode && fchmod(fd, mode) == 0) + updatedMode = 1; + close(fd); +@@ -597,20 +569,6 @@ + } + #endif + +- if (updateOwner && !updatedOwner) { +-#ifdef FAIL_HARD +- if (status & FAIL_IF_NOT_ROOT) { +- prmsg(1, "mkdir: ERROR: Owner of %s must be set to root\n", +- path); +- return -1; +- } +-#endif +-#if !defined(__APPLE_CC__) && !defined(__CYGWIN__) +- prmsg(1, "mkdir: Owner of %s should be set to root\n", +- path); +-#endif +- } +- + if (updateMode && !updatedMode) { + #ifdef FAIL_HARD + if (status & FAIL_IF_NOMODE) { diff --git a/android/app/src/main/cpp/patches/dix-config.h.in b/android/app/src/main/cpp/patches/dix-config.h.in new file mode 100644 index 0000000..78e794f --- /dev/null +++ b/android/app/src/main/cpp/patches/dix-config.h.in @@ -0,0 +1,207 @@ +#pragma once + +#define _DIX_CONFIG_H_ 1 +#define HAVE_TYPEOF 1 +#define MONOTONIC_CLOCK 1 +#undef XSERVER_DTRACE +#define X_BYTE_ORDER X_LITTLE_ENDIAN +#define _GNU_SOURCE 1 +#undef HAS_APERTURE_DRV +#define INPUTTHREAD 1 +#define HAVE_PTHREAD_SETNAME_NP_WITH_TID 1 +#undef HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID + +#undef HAVE_LIBBSD +#undef HAVE_SYSTEMD_DAEMON +#undef CONFIG_UDEV +#undef CONFIG_UDEV_KMS +#undef HAVE_DBUS +#undef CONFIG_HAL +#undef SYSTEMD_LOGIND +#undef NEED_DBUS +#undef CONFIG_WSCONS + +#define HAVE_XSHMFENCE 1 +#undef WITH_LIBDRM +#undef GLAMOR_HAS_EGL_QUERY_DMABUF +#undef GLAMOR_HAS_EGL_QUERY_DRIVER +#define GLXEXT 1 +#undef GLAMOR +#undef GLAMOR_HAS_GBM +#undef GLAMOR_HAS_GBM_LINEAR +#undef GBM_BO_WITH_MODIFIERS +#undef GBM_BO_FD_FOR_PLANE + +#define SERVER_MISC_CONFIG_PATH "/usr/lib/xorg" +#define PROJECTROOT "/usr" +#define SYSCONFDIR "/usr/etc" +#define SUID_WRAPPER_DIR "/usr/libexec" +#define COMPILEDDEFAULTFONTPATH "/usr/share/fonts/X11/misc,/usr/share/fonts/X11/TTF,/usr/share/fonts/X11/OTF,/usr/share/fonts/X11/Type1,/usr/share/fonts/X11/100dpi,/usr/share/fonts/X11/75dpi" + +#define HASXDMAUTH 1 +#define SECURE_RPC 1 + +#define HAVE_DLFCN_H 1 +#define HAVE_EXECINFO_H 1 +#define HAVE_FNMATCH_H 1 +#define HAVE_LINUX_AGPGART_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_SYS_AGPGART_H 1 +#define HAVE_SYS_UN_H 1 +#define HAVE_SYS_UTSNAME_H 1 +#define HAVE_SYS_SYSMACROS_H 1 + +#define HAVE_ARC4RANDOM_BUF 1 +#undef HAVE_BACKTRACE +#undef HAVE_LIBUNWIND +#undef HAVE_PSTACK +#define HAVE_CBRT 1 +#define HAVE_EPOLL_CREATE1 1 +#define HAVE_GETUID 1 +#define HAVE_GETEUID 1 +#undef HAVE_ISASTREAM +#undef HAVE_ISSETUGID +#define HAVE_GETIFADDRS 1 +#undef HAVE_GETPEEREID +#undef HAVE_GETPEERUCRED +#define HAVE_GETPROGNAME 1 +#undef HAVE_GETZONEID +#define HAVE_MEMFD_CREATE 1 +#define HAVE_MKOSTEMP 1 +#define HAVE_MMAP 1 +#undef HAVE_OPEN_DEVICE +#define HAVE_POLL 1 +#undef HAVE_POLLSET_CREATE +#define HAVE_POSIX_FALLOCATE 1 +#undef HAVE_PORT_CREATE +#undef HAVE_REALLOCARRAY +#define HAVE_SETEUID 1 +#define HAVE_SETITIMER 1 +#undef HAVE_SHMCTL64 +#define HAVE_SIGACTION 1 +#define HAVE_SIGPROCMASK 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRCASESTR 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_STRNDUP 1 +#undef HAVE_TIMINGSAFE_MEMCMP +#define HAVE_VASPRINTF 1 +#define HAVE_VSNPRINTF 1 +#undef HAVE_WALKCONTEXT +#define BUSFAULT 1 + +#define _XTYPEDEF_POINTER 1 +#define _XITYPEDEF_POINTER 1 + +#define LISTEN_UNIX +#define LISTEN_LOCAL + +#define XTRANS_SEND_FDS 1 + +#define TCPCONN 1 +#define UNIXCONN 1 +#define IPv6 1 + +#define BIGREQS 1 +#define COMPOSITE 1 +#define DAMAGE 1 +#define DBE 1 +#define DGA 1 +#define DPMSExtension 1 +#define DRI2 1 +#define DRI3 1 +#define HAS_SHM 1 +#define MITSHM 1 +#define PANORAMIX 1 +#define PRESENT 1 +#define RANDR 1 +#define RES 1 +#define RENDER 1 +#define SCREENSAVER 1 +#define SHAPE 1 +#define XACE 1 +#define XCMISC 1 +#undef XCSECURITY +#define XDMCP 1 +#undef XF86BIGFONT +#define XF86DRI 1 +#define XF86VIDMODE 1 +#define XFIXES 1 +#define XFreeXDGA 1 +#define XINERAMA 1 +#define XINPUT 1 +#define XRECORD 1 +#undef XSELINUX +#define XSYNC 1 +#define XTEST 1 +#define XV 1 +#define XvExtension 1 +#define XvMCExtension 1 + +/* Use libmd SHA1 functions */ +#define HAVE_SHA1_IN_LIBMD 1 + +#define HAVE_APM 1 +#define HAVE_ACPI 1 + +#undef DDXOSVERRORF +#undef DDXBEFORERESET +#undef DEBUG + +#define XVENDORNAME "The X.Org Foundation" +#define XVENDORNAMESHORT "X.Org" +#define __VENDORDWEBSUPPORT__ "http://wiki.x.org" +#define BUILDERADDR "xorg@lists.freedesktop.org" +#define BUILDERSTRING "" + +#undef SVR4 +#define XKB_DFLT_RULES "evdev" +#undef XORGSERVER +#define XCONFIGFILE "xorg.conf" +#define __XSERVERNAME__ "Xorg" +#define WITH_VGAHW 1 +#undef CSRG_BASED +#undef PCCONS_SUPPORT +#undef PCVT_SUPPORT +#undef SYSCONS_SUPPORT +#undef WSCONS_SUPPORT +#undef XSERVER_LIBPCIACCESS +#undef XSERVER_PLATFORM_BUS + +#ifdef ANDROID +typedef long long quad_t; +typedef unsigned long long u_quad_t; + +#include + +__attribute__((unused)) +static int memfd_create(const char *name, unsigned int flags) { +#ifndef __NR_memfd_create +#if defined __i386__ +#define __NR_memfd_create 356 +#elif defined __x86_64__ +#define __NR_memfd_create 319 +#elif defined __arm__ +#define __NR_memfd_create 385 +#elif defined __aarch64__ +#define __NR_memfd_create 279 +#endif +#endif + +#ifdef __NR_memfd_create + return syscall(__NR_memfd_create, name, flags); // NOLINT(cppcoreguidelines-narrowing-conversions) +#else + errno = ENOSYS; + return -1; +#endif +} +#endif + +#ifdef __ANDROID__ +#define CHECK_EUID 0 +extern int execl_xkbcomp(const char * path, const char * arg, ...); +#define setgid(a) 0 +#define setuid(a) 0 +#endif diff --git a/android/app/src/main/cpp/patches/libepoxy.patch b/android/app/src/main/cpp/patches/libepoxy.patch new file mode 100644 index 0000000..6ccb55a --- /dev/null +++ b/android/app/src/main/cpp/patches/libepoxy.patch @@ -0,0 +1,170 @@ +diff --git a/src/gen_dispatch.py b/src/gen_dispatch.py +index 3daad84..b27931d 100755 +--- a/src/gen_dispatch.py ++++ b/src/gen_dispatch.py +@@ -222,7 +222,7 @@ class Generator(object): + + for child in t: + if child.tag == 'apientry': +- self.typedefs += 'APIENTRY' ++ self.typedefs += '' + if child.text: + self.typedefs += child.text + if child.tail: +@@ -462,13 +462,14 @@ class Generator(object): + + def write_function_ptr_typedefs(self): + for func in self.sorted_functions: +- self.outln('typedef {0} (GLAPIENTRY *{1})({2});'.format(func.ret_type, ++ self.outln('typedef {0} (*{1})({2});'.format(func.ret_type, + func.ptr_type, + func.args_decl)) + + def write_header_header(self, out_file): + self.close() + self.out_file = open(out_file, 'w') ++ self.out_file.truncate(0) + + self.outln('/* GL dispatch header.') + self.outln(' * This is code-generated from the GL API XML files from Khronos.') +@@ -482,7 +483,7 @@ class Generator(object): + self.outln('#include ') + self.outln('') + +- def write_header(self, out_file): ++ def write_header2(self, out_file): + self.write_header_header(out_file) + + self.outln('#include "epoxy/common.h"') +@@ -858,6 +859,82 @@ class Generator(object): + for func in self.sorted_functions: + self.write_function_pointer(func) + ++ def write_header(self, out_file): ++ self.close() ++ self.out_file = open(out_file, 'w') ++ self.out_file.truncate(0) ++ ++ self.outln('/* GL dispatch header.') ++ self.outln(' * This is code-generated from the GL API XML files from Khronos.') ++ self.write_copyright_comment_body() ++ self.outln(' */') ++ self.outln('') ++ ++ self.outln('#pragma once') ++ ++ self.outln('#include ') ++ self.outln('#include ') ++ self.outln('') ++ ++ # Add some ridiculous inttypes.h redefinitions that are ++ # from khrplatform.h and not included in the XML. We ++ # don't directly include khrplatform.h because it's not ++ # present on many systems, and coming up with #ifdefs to ++ # decide when it's not present would be hard. ++ self.outln('#define __khrplatform_h_ 1') ++ self.outln('typedef int8_t khronos_int8_t;') ++ self.outln('typedef int16_t khronos_int16_t;') ++ self.outln('typedef int32_t khronos_int32_t;') ++ self.outln('typedef int64_t khronos_int64_t;') ++ self.outln('typedef uint8_t khronos_uint8_t;') ++ self.outln('typedef uint16_t khronos_uint16_t;') ++ self.outln('typedef uint32_t khronos_uint32_t;') ++ self.outln('typedef uint64_t khronos_uint64_t;') ++ self.outln('typedef float khronos_float_t;') ++ self.outln('#ifdef _WIN64') ++ self.outln('typedef signed long long int khronos_intptr_t;') ++ self.outln('typedef unsigned long long int khronos_uintptr_t;') ++ self.outln('typedef signed long long int khronos_ssize_t;') ++ self.outln('typedef unsigned long long int khronos_usize_t;') ++ self.outln('#else') ++ self.outln('typedef signed long int khronos_intptr_t;') ++ self.outln('typedef unsigned long int khronos_uintptr_t;') ++ self.outln('typedef signed long int khronos_ssize_t;') ++ self.outln('typedef unsigned long int khronos_usize_t;') ++ self.outln('#endif') ++ self.outln('typedef uint64_t khronos_utime_nanoseconds_t;') ++ self.outln('typedef int64_t khronos_stime_nanoseconds_t;') ++ self.outln('#define KHRONOS_MAX_ENUM 0x7FFFFFFF') ++ self.outln('typedef enum {') ++ self.outln(' KHRONOS_FALSE = 0,') ++ self.outln(' KHRONOS_TRUE = 1,') ++ self.outln(' KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM') ++ self.outln('} khronos_boolean_enum_t;') ++ ++ if self.target == "glx": ++ self.outln('#include ') ++ self.outln('#include ') ++ ++ self.out(self.typedefs) ++ self.outln('') ++ self.write_enums() ++ self.outln('') ++ self.write_function_ptr_typedefs() ++ ++ for func in self.sorted_functions: ++ ret = "" ++ if func.ret_type in ("void"): ++ ret = "" ++ elif func.ret_type in ("GLhandleARB", "GLsync", "const GLubyte *", "GLVULKANPROCNV", "void *"): ++ ret = "NULL" ++ elif func.ret_type in ("GLuint", "GLboolean", "GLenum", "GLint", "GLfloat", "GLushort", \ ++ "GLintptr", "GLbitfield", "GLvdpauSurfaceNV", "GLsizei", "GLuint64"): ++ ret = "0" ++ else: ++ raise ValueError('Wrong return type "' + func.ret_type + '"') ++ self.outln('#define {0}(...) {1}'.format(func.name, ret)) ++ ++ + def close(self): + if self.out_file: + self.out_file.close() +@@ -869,10 +946,6 @@ argparser.add_argument('files', metavar='file.xml', nargs='+', help='GL API XML + argparser.add_argument('--outputdir', metavar='dir', required=False, help='Destination directory for files (default to current dir)') + argparser.add_argument('--includedir', metavar='dir', required=False, help='Destination directory for headers') + argparser.add_argument('--srcdir', metavar='dir', required=False, help='Destination directory for source') +-argparser.add_argument('--source', dest='source', action='store_true', required=False, help='Generate the source file') +-argparser.add_argument('--no-source', dest='source', action='store_false', required=False, help='Do not generate the source file') +-argparser.add_argument('--header', dest='header', action='store_true', required=False, help='Generate the header file') +-argparser.add_argument('--no-header', dest='header', action='store_false', required=False, help='Do not generate the header file') + args = argparser.parse_args() + + if args.outputdir: +@@ -890,13 +963,6 @@ if args.srcdir: + else: + srcdir = outputdir + +-build_source = args.source +-build_header = args.header +- +-if not build_source and not build_header: +- build_source = True +- build_header = True +- + for f in args.files: + name = os.path.basename(f).split('.xml')[0] + generator = Generator(name) +@@ -911,22 +977,8 @@ for f in args.files: + + generator.sort_functions() + generator.resolve_aliases() +- generator.fixup_bootstrap_function('glGetString', +- 'epoxy_get_bootstrap_proc_address({0})') +- generator.fixup_bootstrap_function('glGetIntegerv', +- 'epoxy_get_bootstrap_proc_address({0})') +- +- # While this is technically exposed as a GLX extension, it's +- # required to be present as a public symbol by the Linux OpenGL +- # ABI. +- generator.fixup_bootstrap_function('glXGetProcAddress', +- 'epoxy_glx_dlsym({0})') + + generator.prepare_provider_enum() +- +- if build_header: +- generator.write_header(os.path.join(includedir, name + '_generated.h')) +- if build_source: +- generator.write_source(os.path.join(srcdir, name + '_generated_dispatch.c')) ++ generator.write_header(os.path.join(includedir, name + '.h')) + + generator.close() diff --git a/android/app/src/main/cpp/patches/pixman.patch b/android/app/src/main/cpp/patches/pixman.patch new file mode 100644 index 0000000..0b2f94f --- /dev/null +++ b/android/app/src/main/cpp/patches/pixman.patch @@ -0,0 +1,35 @@ +diff -u -r ../pixman-0.32.6/pixman/pixman-arm.c ./pixman/pixman-arm.c +--- ../pixman-0.32.6/pixman/pixman-arm.c 2013-11-17 09:43:18.000000000 +0100 ++++ ./pixman/pixman-arm.c 2014-08-05 12:54:39.252322492 +0200 +@@ -96,30 +96,10 @@ + + #elif defined(__ANDROID__) || defined(ANDROID) /* Android */ + +-#include +- + static arm_cpu_features_t + detect_cpu_features (void) + { +- arm_cpu_features_t features = 0; +- AndroidCpuFamily cpu_family; +- uint64_t cpu_features; +- +- cpu_family = android_getCpuFamily(); +- cpu_features = android_getCpuFeatures(); +- +- if (cpu_family == ANDROID_CPU_FAMILY_ARM) +- { +- if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7) +- features |= ARM_V7; +- +- if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3) +- features |= ARM_VFP; +- +- if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) +- features |= ARM_NEON; +- } +- ++ arm_cpu_features_t features = (ARM_V7 | ARM_VFP | ARM_NEON); + return features; + } + diff --git a/android/app/src/main/cpp/patches/x11.patch b/android/app/src/main/cpp/patches/x11.patch new file mode 100644 index 0000000..d47d02e --- /dev/null +++ b/android/app/src/main/cpp/patches/x11.patch @@ -0,0 +1,58 @@ +diff --git a/src/Quarks.c b/src/Quarks.c +index 0dd91968..dbaf5086 100644 +--- a/src/Quarks.c ++++ b/src/Quarks.c +@@ -105,6 +105,11 @@ static XrmQuark nextUniq = -1; /* next quark from XrmUniqueQuark */ + #define CLEARPERM(q) BYTEREF(q) &= ~(1 << ((q) & 7)) + #endif + ++#undef _XLockMutex ++#undef _XUnlockMutex ++#define _XLockMutex(m) ++#define _XUnlockMutex(m) ++ + /* Permanent memory allocation */ + + #define WALIGN sizeof(unsigned long) +diff --git a/src/Xrm.c b/src/Xrm.c +index a8ebf883..d716fdb0 100644 +--- a/src/Xrm.c ++++ b/src/Xrm.c +@@ -301,6 +301,13 @@ typedef unsigned char XrmBits; + #define is_simple(bits) ((bits) & (NORMAL|BSLASH)) + #define is_special(bits) ((bits) & (ENDOF|BSLASH)) + ++#undef _XLockMutex ++#undef _XUnlockMutex ++#undef _XCreateMutex ++#define _XLockMutex(m) ++#define _XUnlockMutex(m) ++#define _XCreateMutex(m) ++ + /* parsing types */ + static XrmBits const xrmtypes[256] = { + EOS,0,0,0,0,0,0,0, +@@ -500,9 +507,7 @@ static XrmDatabase NewDatabase(void) + _XCreateMutex(&db->linfo); + db->table = (NTable)NULL; + db->mbstate = (XPointer)NULL; +- db->methods = _XrmInitParseInfo(&db->mbstate); +- if (!db->methods) +- db->methods = &mb_methods; ++ db->methods = &mb_methods; + } + return db; + } +--- a/include/X11/Xlocale.h ++++ b/include/X11/Xlocale.h +@@ -32,6 +32,9 @@ from The Open Group. + #include + #include + ++struct __locale_t; ++typedef struct __locale_t* locale_t; ++ + #include + + #endif /* _X11_XLOCALE_H_ */ + \ No newline at end of file diff --git a/android/app/src/main/cpp/patches/xkbcomp.patch b/android/app/src/main/cpp/patches/xkbcomp.patch new file mode 100644 index 0000000..3931bad --- /dev/null +++ b/android/app/src/main/cpp/patches/xkbcomp.patch @@ -0,0 +1,1054 @@ +diff --git a/alias.c b/alias.c +index c914cbc..713067f 100644 +--- a/alias.c ++++ b/alias.c +@@ -155,6 +155,52 @@ MergeAliases(AliasInfo ** into, AliasInfo ** merge, unsigned how_merge) + return True; + } + ++Bool ++XkbComputeEffectiveMap(XkbDescPtr xkb, ++ XkbKeyTypePtr type, ++ unsigned char *map_rtrn) ++{ ++ register int i; ++ unsigned tmp; ++ XkbKTMapEntryPtr entry = NULL; ++ ++ if ((!xkb) || (!type) || (!xkb->server)) ++ return False; ++ ++ if (type->mods.vmods != 0) { ++ if (!XkbVirtualModsToReal(xkb, type->mods.vmods, &tmp)) ++ return False; ++ ++ type->mods.mask = tmp | type->mods.real_mods; ++ entry = type->map; ++ for (i = 0; i < type->map_count; i++, entry++) { ++ tmp = 0; ++ if (entry->mods.vmods != 0) { ++ if (!XkbVirtualModsToReal(xkb, entry->mods.vmods, &tmp)) ++ return False; ++ if (tmp == 0) { ++ entry->active = False; ++ continue; ++ } ++ } ++ entry->active = True; ++ entry->mods.mask = (entry->mods.real_mods | tmp) & type->mods.mask; ++ } ++ } ++ else { ++ type->mods.mask = type->mods.real_mods; ++ } ++ if (map_rtrn != NULL) { ++ bzero(map_rtrn, type->mods.mask + 1); ++ for (i = 0; i < type->map_count; i++) { ++ if (entry && entry->active) { ++ map_rtrn[type->map[i].mods.mask] = type->map[i].level; ++ } ++ } ++ } ++ return True; ++} ++ + int + ApplyAliases(XkbDescPtr xkb, Bool toGeom, AliasInfo ** info_in) + { +diff --git a/compat.c b/compat.c +index 26f4249..c1884b0 100644 +--- a/compat.c ++++ b/compat.c +@@ -571,7 +571,7 @@ SetInterpField(SymInterpInfo *si, XkbDescPtr xkb, const char *field, + return ok; + } + +-LookupEntry groupNames[] = { ++LookupEntry xkbcomp_groupNames[] = { + {"group1", 0x01} + , + {"group2", 0x02} +diff --git a/compat.h b/compat.h +index 799b215..900de43 100644 +--- a/compat.h ++++ b/compat.h +@@ -2,6 +2,6 @@ + #ifndef COMPAT_H + #define COMPAT_H 1 + +-extern LookupEntry groupNames[]; ++extern LookupEntry xkbcomp_groupNames[]; + + #endif /* COMPAT_H */ +diff --git a/indicators.c b/indicators.c +index 470091e..215529d 100644 +--- a/indicators.c ++++ b/indicators.c +@@ -223,7 +223,7 @@ SetIndicatorMapField(LEDInfo *led, XkbDescPtr xkb, const char *field, + if (arrayNdx != NULL) + return ReportIndicatorNotArray(xkb->dpy, led, field); + if (!ExprResolveMask +- (value, &rtrn, SimpleLookup, (XPointer) groupNames)) ++ (value, &rtrn, SimpleLookup, (XPointer) xkbcomp_groupNames)) + return ReportIndicatorBadType(xkb->dpy, led, field, "group mask"); + led->groups = rtrn.uval; + led->defs.defined |= _LED_Groups; +diff --git a/xkbcomp.c b/xkbcomp.c +index 6aedb67..12b0f27 100644 +--- a/xkbcomp.c ++++ b/xkbcomp.c +@@ -24,6 +24,9 @@ + + ********************************************************/ + ++#pragma clang diagnostic ignored "-Wunknown-pragmas" ++#pragma ide diagnostic ignored "bugprone-reserved-identifier" ++ + #include "utils.h" + #include + #include +@@ -43,6 +46,7 @@ + #include "misc.h" + #include "tokens.h" + #include ++#include + + + #ifdef WIN32 +@@ -56,46 +60,17 @@ + + /***====================================================================***/ + +-#define WANT_DEFAULT 0 +-#define WANT_XKM_FILE 1 +-#define WANT_C_HDR 2 +-#define WANT_XKB_FILE 3 +-#define WANT_X_SERVER 4 +-#define WANT_LISTING 5 +- +-#define INPUT_UNKNOWN 0 +-#define INPUT_XKB 1 +-#define INPUT_XKM 2 +- + #ifdef DEBUG + unsigned int debugFlags; + #endif + +-static const char *fileTypeExt[] = { +- "XXX", +- "xkm", +- "h", +- "xkb", +- "dir" +-}; +- +-static unsigned inputFormat, outputFormat; + static const char *rootDir; + static char *inputFile; + static const char *inputMap; + static char *outputFile; +-static const char *inDpyName; +-static const char *outDpyName; +-static Display *inDpy; +-static Display *outDpy; +-static Bool showImplicit = False; +-static Bool synch = False; +-static Bool computeDflts = False; +-static Bool xkblist = False; + unsigned warningLevel = 5; + unsigned verboseLevel = 0; + unsigned dirsToStrip = 0; +-static unsigned optionalParts = 0; + static const char *preErrorMsg = NULL; + static const char *postErrorMsg = NULL; + static const char *errorPrefix = NULL; +@@ -103,192 +78,24 @@ static unsigned int device_id = XkbUseCoreKbd; + + /***====================================================================***/ + +-#define M(m) fprintf(stderr,(m)) +-#define M1(m,a) fprintf(stderr,(m),(a)) +- +-static void +-Usage(int argc, char *argv[]) +-{ +- if (!xkblist) +- M1("Usage: %s [options] input-file [ output-file ]\n", argv[0]); +- else +- M1("Usage: %s [options] file[(map)] ...\n", argv[0]); +- M("Legal options:\n"); +- M("-?,-help Print this message\n"); +- M("-version Print the version number\n"); +- if (!xkblist) +- { +- M("-a Show all actions\n"); +- M("-C Create a C header file\n"); +- } +-#ifdef DEBUG +- M("-d [flags] Report debugging information\n"); +-#endif +- M("-em1 Print before printing first error message\n"); +- M("-emp Print at the start of each message line\n"); +- M("-eml If there were any errors, print before exiting\n"); +- if (!xkblist) +- { +- M("-dflts Compute defaults for missing parts\n"); +- M("-I[] Specifies a top level directory for include\n"); +- M(" directives. Multiple directories are legal.\n"); +- M("-l [flags] List matching maps in the specified files\n"); +- M(" f: list fully specified names\n"); +- M(" h: also list hidden maps\n"); +- M(" l: long listing (show flags)\n"); +- M(" p: also list partial maps\n"); +- M(" R: recursively list subdirectories\n"); +- M(" default is all options off\n"); +- } +- M("-i Specifies device ID (not name) to compile for\n"); +- M("-m[ap] Specifies map to compile\n"); +- M("-o Specifies output file name\n"); +- if (!xkblist) +- { +- M("-opt[ional] Specifies optional components of keymap\n"); +- M(" Errors in optional parts are not fatal\n"); +- M(" can be any combination of:\n"); +- M(" c: compat map g: geometry\n"); +- M(" k: keycodes s: symbols\n"); +- M(" t: types\n"); +- } +- if (xkblist) +- { +- M("-p Specifies the number of slashes to be stripped\n"); +- M(" from the front of the map name on output\n"); +- } +- M("-R[] Specifies the root directory for\n"); +- M(" relative path names\n"); +- M("-synch Force synchronization\n"); +- if (xkblist) +- { +- M("-v [] Set level of detail for listing.\n"); +- M(" flags are as for the -l option\n"); +- } +- M("-w [] Set warning level (0=none, 10=all)\n"); +- if (!xkblist) +- { +- M("-xkb Create an XKB source (.xkb) file\n"); +- M("-xkm Create a compiled key map (.xkm) file\n"); +- } +- return; +-} +- +-/***====================================================================***/ +- +-static void +-setVerboseFlags(const char *str) +-{ +- for (; *str; str++) +- { +- switch (*str) +- { +- case 'f': +- verboseLevel |= WantFullNames; +- break; +- case 'h': +- verboseLevel |= WantHiddenMaps; +- break; +- case 'l': +- verboseLevel |= WantLongListing; +- break; +- case 'p': +- verboseLevel |= WantPartialMaps; +- break; +- case 'R': +- verboseLevel |= ListRecursive; +- break; +- default: +- if (warningLevel > 4) +- { +- WARN("Unknown verbose option \"%c\"\n", (unsigned int) *str); +- ACTION("Ignored\n"); +- } +- break; +- } +- } +- return; +-} +- + static Bool + parseArgs(int argc, char *argv[]) + { +- int i, tmp; +- +- i = strlen(argv[0]); +- tmp = strlen("xkblist"); +- if ((i >= tmp) && (strcmp(&argv[0][i - tmp], "xkblist") == 0)) +- { +- xkblist = True; +- } +- for (i = 1; i < argc; i++) ++ for (register int i = 1; i < argc; i++) + { +- int itmp; + if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) + { +- if (!xkblist) ++ if (inputFile == NULL) ++ inputFile = argv[i]; ++ else if (outputFile == NULL) ++ outputFile = argv[i]; ++ else if (warningLevel > 0) + { +- if (inputFile == NULL) +- inputFile = argv[i]; +- else if (outputFile == NULL) +- outputFile = argv[i]; +- else if (warningLevel > 0) +- { +- WARN("Too many file names on command line\n"); +- ACTION ++ WARN("Too many file names on command line\n"); ++ ACTION + ("Compiling %s, writing to %s, ignoring %s\n", + inputFile, outputFile, argv[i]); +- } + } +- else if (!AddMatchingFiles(argv[i])) +- return False; +- } +- else if ((strcmp(argv[i], "-?") == 0) +- || (strcmp(argv[i], "-help") == 0)) +- { +- Usage(argc, argv); +- exit(0); +- } +- else if (strcmp(argv[i], "-version") == 0) +- { +- printf("xkbcomp %s\n", PACKAGE_VERSION); +- exit(0); +- } else if ((strcmp(argv[i], "-a") == 0) && (!xkblist)) +- { +- showImplicit = True; +- } +- else if ((strcmp(argv[i], "-C") == 0) && (!xkblist)) +- { +- if ((outputFormat != WANT_DEFAULT) +- && (outputFormat != WANT_C_HDR)) +- { +- if (warningLevel > 0) +- { +- WARN("Multiple output file formats specified\n"); +- ACTION("\"%s\" flag ignored\n", argv[i]); +- } +- } +- else +- outputFormat = WANT_C_HDR; +- } +-#ifdef DEBUG +- else if (strcmp(argv[i], "-d") == 0) +- { +- if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) +- { +- debugFlags = 1; +- } +- else +- { +- if (sscanf(argv[++i], "%i", &itmp) == 1) +- debugFlags = itmp; +- } +- INFO("Setting debug flags to %d\n", debugFlags); +- } +-#endif +- else if ((strcmp(argv[i], "-dflts") == 0) && (!xkblist)) +- { +- computeDflts = True; + } + else if (strcmp(argv[i], "-em1") == 0) + { +@@ -356,172 +163,6 @@ parseArgs(int argc, char *argv[]) + else + postErrorMsg = argv[i]; + } +- else if ((strncmp(argv[i], "-I", 2) == 0) && (!xkblist)) +- { +- if (!XkbAddDirectoryToPath(&argv[i][2])) +- { +- ACTION("Exiting\n"); +- exit(1); +- } +- } +- else if ((strncmp(argv[i], "-i", 2) == 0) && (!xkblist)) +- { +- if (++i >= argc) +- { +- if (warningLevel > 0) +- WARN("No device ID specified\n"); +- } +- device_id = atoi(argv[i]); +- } +- else if ((strncmp(argv[i], "-l", 2) == 0) && (!xkblist)) +- { +- if (outputFormat != WANT_DEFAULT) +- { +- if (warningLevel > 0) +- { +- WARN("Multiple output file formats specified\n"); +- ACTION("\"%s\" flag ignored\n", argv[i]); +- } +- } +- else +- { +- if (argv[i][2] != '\0') +- setVerboseFlags(&argv[i][2]); +- xkblist = True; +- if ((inputFile) && (!AddMatchingFiles(inputFile))) +- return False; +- else +- inputFile = NULL; +- if ((outputFile) && (!AddMatchingFiles(outputFile))) +- return False; +- else +- outputFile = NULL; +- } +- } +- else if ((strcmp(argv[i], "-m") == 0) +- || (strcmp(argv[i], "-map") == 0)) +- { +- if (++i >= argc) +- { +- if (warningLevel > 0) +- { +- WARN("No map name specified\n"); +- ACTION("Trailing \"%s\" option ignored\n", argv[i - 1]); +- } +- } +- else if (xkblist) +- { +- if (!AddMapOnly(argv[i])) +- return False; +- } +- else if (inputMap != NULL) +- { +- if (warningLevel > 0) +- { +- WARN("Multiple map names specified\n"); +- ACTION("Compiling %s, ignoring %s\n", inputMap, argv[i]); +- } +- } +- else +- inputMap = argv[i]; +- } +- else if ((strcmp(argv[i], "-merge") == 0) && (!xkblist)) +- { +- /* Ignored */ +- } +- else if (strcmp(argv[i], "-o") == 0) +- { +- if (++i >= argc) +- { +- if (warningLevel > 0) +- { +- WARN("No output file specified\n"); +- ACTION("Trailing \"-o\" option ignored\n"); +- } +- } +- else if (outputFile != NULL) +- { +- if (warningLevel > 0) +- { +- WARN("Multiple output files specified\n"); +- ACTION("Compiling %s, ignoring %s\n", outputFile, +- argv[i]); +- } +- } +- else +- outputFile = argv[i]; +- } +- else if (((strcmp(argv[i], "-opt") == 0) +- || (strcmp(argv[i], "optional") == 0)) && (!xkblist)) +- { +- if (++i >= argc) +- { +- if (warningLevel > 0) +- { +- WARN("No optional components specified\n"); +- ACTION("Trailing \"%s\" option ignored\n", argv[i - 1]); +- } +- } +- else +- { +- for (const char *tmp2 = argv[i]; (*tmp2 != '\0'); tmp2++) +- { +- switch (*tmp2) +- { +- case 'c': +- case 'C': +- optionalParts |= XkmCompatMapMask; +- break; +- case 'g': +- case 'G': +- optionalParts |= XkmGeometryMask; +- break; +- case 'k': +- case 'K': +- optionalParts |= XkmKeyNamesMask; +- break; +- case 's': +- case 'S': +- optionalParts |= XkmSymbolsMask; +- break; +- case 't': +- case 'T': +- optionalParts |= XkmTypesMask; +- break; +- default: +- if (warningLevel > 0) +- { +- WARN +- ("Illegal component for %s option\n", +- argv[i - 1]); +- ACTION +- ("Ignoring unknown specifier \"%c\"\n", +- (unsigned int) *tmp2); +- } +- break; +- } +- } +- } +- } +- else if (strncmp(argv[i], "-p", 2) == 0) +- { +- if (isdigit(argv[i][2])) +- { +- if (sscanf(&argv[i][2], "%i", &itmp) == 1) +- dirsToStrip = itmp; +- } +- else if ((i < (argc - 1)) && (isdigit(argv[i + 1][0]))) +- { +- if (sscanf(argv[++i], "%i", &itmp) == 1) +- dirsToStrip = itmp; +- } +- else +- { +- dirsToStrip = 0; +- } +- if (warningLevel > 5) +- INFO("Setting path count to %d\n", dirsToStrip); +- } + else if (strncmp(argv[i], "-R", 2) == 0) + { + if (argv[i][2] == '\0') +@@ -558,23 +199,6 @@ parseArgs(int argc, char *argv[]) + } + } + } +- else if ((strcmp(argv[i], "-synch") == 0) +- || (strcmp(argv[i], "-s") == 0)) +- { +- synch = True; +- } +- else if (strncmp(argv[i], "-v", 2) == 0) +- { +- const char *str; +- if (argv[i][2] != '\0') +- str = &argv[i][2]; +- else if ((i < (argc - 1)) && (argv[i + 1][0] != '-')) +- str = argv[++i]; +- else +- str = NULL; +- if (str) +- setVerboseFlags(str); +- } + else if (strncmp(argv[i], "-w", 2) == 0) + { + unsigned long utmp; +@@ -605,57 +229,22 @@ parseArgs(int argc, char *argv[]) + else + { + ERROR("Unknown flag \"%s\" on command line\n", argv[i]); +- Usage(argc, argv); + return False; + } + } + } +- else if ((strcmp(argv[i], "-xkb") == 0) && (!xkblist)) +- { +- if ((outputFormat != WANT_DEFAULT) +- && (outputFormat != WANT_XKB_FILE)) +- { +- if (warningLevel > 0) +- { +- WARN("Multiple output file formats specified\n"); +- ACTION("\"%s\" flag ignored\n", argv[i]); +- } +- } +- else +- outputFormat = WANT_XKB_FILE; +- } +- else if ((strcmp(argv[i], "-xkm") == 0) && (!xkblist)) +- { +- if ((outputFormat != WANT_DEFAULT) +- && (outputFormat != WANT_XKM_FILE)) +- { +- if (warningLevel > 0) +- { +- WARN("Multiple output file formats specified\n"); +- ACTION("\"%s\" flag ignored\n", argv[i]); +- } +- } +- else +- outputFormat = WANT_XKM_FILE; +- } ++ else if (strcmp(argv[i], "-xkm") == 0) {} + else + { + ERROR("Unknown flag \"%s\" on command line\n", argv[i]); +- Usage(argc, argv); + return False; + } + } +- if (xkblist) +- inputFormat = INPUT_XKB; +- else if (inputFile == NULL) ++ if (inputFile == NULL) + { + ERROR("No input file specified\n"); + return False; + } +- else if (strcmp(inputFile, "-") == 0) +- { +- inputFormat = INPUT_XKB; +- } + #ifndef WIN32 + else if (strchr(inputFile, ':') == NULL) + { +@@ -698,214 +287,26 @@ parseArgs(int argc, char *argv[]) + return False; + } + } +- if ((len > 4) && (strcmp(&inputFile[len - 4], ".xkm") == 0)) +- { +- inputFormat = INPUT_XKM; +- } +- else +- { +- FILE *file; +- file = fopen(inputFile, "r"); +- if (file) +- { +- if (XkmProbe(file)) +- inputFormat = INPUT_XKM; +- else +- inputFormat = INPUT_XKB; +- fclose(file); +- } +- else +- { +- fprintf(stderr, "Cannot open \"%s\" for reading\n", +- inputFile); +- return False; +- } +- } +- } +- else +- { +- inDpyName = inputFile; +- inputFile = NULL; +- inputFormat = INPUT_XKM; +- } +- +- if (outputFormat == WANT_DEFAULT) +- { +- if (xkblist) +- outputFormat = WANT_LISTING; +- else if (inputFormat == INPUT_XKB) +- outputFormat = WANT_XKM_FILE; +- else +- outputFormat = WANT_XKB_FILE; +- } +- if ((outputFormat == WANT_LISTING) && (inputFormat != INPUT_XKB)) +- { +- if (inputFile) +- ERROR("Cannot generate a listing from a .xkm file (yet)\n"); +- else +- ERROR("Cannot generate a listing from an X connection (yet)\n"); +- return False; +- } +- if (xkblist) +- { +- if (outputFile == NULL) +- outputFile = uStringDup("-"); +- else if (strchr(outputFile, ':') != NULL) ++ if (!access(inputFile, R_OK)) + { +- ERROR("Cannot write a listing to an X connection\n"); + return False; + } + } +- else if ((!outputFile) && (inputFile) && (strcmp(inputFile, "-") == 0)) +- { +-#ifdef HAVE_ASPRINTF +- if (asprintf(&outputFile, "stdin.%s", fileTypeExt[outputFormat]) < 0) +-#else +- size_t len = strlen("stdin") + strlen(fileTypeExt[outputFormat]) + 2; +- outputFile = calloc(len, sizeof(char)); +- if (outputFile != NULL) +- snprintf(outputFile, len, "stdin.%s", fileTypeExt[outputFormat]); +- else +-#endif +- { +- WSGO("Cannot allocate space for output file name\n"); +- ACTION("Exiting\n"); +- exit(1); +- } +- } +- else if ((outputFile == NULL) && (inputFile != NULL)) +- { +- int len; +- const char *base, *ext; +- +- if (inputMap == NULL) +- { +- base = strrchr(inputFile, '/'); +- if (base == NULL) +- base = inputFile; +- else +- base++; +- } +- else +- base = inputMap; +- +- len = strlen(base) + strlen(fileTypeExt[outputFormat]) + 2; +- outputFile = calloc(len, sizeof(char)); +- if (outputFile == NULL) +- { +- WSGO("Cannot allocate space for output file name\n"); +- ACTION("Exiting\n"); +- exit(1); +- } +- ext = strrchr(base, '.'); +- if (ext == NULL) +- snprintf(outputFile, len, "%s.%s", base, fileTypeExt[outputFormat]); +- else +- { +- strcpy(outputFile, base); +- strcpy(&outputFile[ext - base + 1], fileTypeExt[outputFormat]); +- } +- } +- else if (outputFile == NULL) +- { +- int len; +- char *ch, buf[128]; +- const char *name = buf; +- if (inDpyName[0] == ':') +- snprintf(buf, sizeof(buf), "server%s", inDpyName); +- else +- name = inDpyName; +- +- len = strlen(name) + strlen(fileTypeExt[outputFormat]) + 2; +- outputFile = calloc(len, sizeof(char)); +- if (outputFile == NULL) +- { +- WSGO("Cannot allocate space for output file name\n"); +- ACTION("Exiting\n"); +- exit(1); +- } +- strcpy(outputFile, name); +- for (ch = outputFile; (*ch) != '\0'; ch++) +- { +- if (*ch == ':') +- *ch = '-'; +- else if (*ch == '.') +- *ch = '_'; +- } +- *ch++ = '.'; +- strcpy(ch, fileTypeExt[outputFormat]); +- } +-#ifdef WIN32 +- else if (strlen(outputFile) > 2 && +- isalpha(outputFile[0]) && +- outputFile[1] == ':' && strchr(outputFile + 2, ':') == NULL) +- { +- } +-#endif +- else if (strchr(outputFile, ':') != NULL) +- { +- outDpyName = outputFile; +- outputFile = NULL; +- outputFormat = WANT_X_SERVER; +- } + return True; + } + +-static Display * +-GetDisplay(const char *program, const char *dpyName) +-{ +- int mjr, mnr, error; +- Display *dpy; +- +- mjr = XkbMajorVersion; +- mnr = XkbMinorVersion; +- dpy = XkbOpenDisplay(dpyName, NULL, NULL, &mjr, &mnr, &error); +- if (dpy == NULL) +- { +- switch (error) +- { +- case XkbOD_BadLibraryVersion: +- INFO("%s was compiled with XKB version %d.%02d\n", +- program, XkbMajorVersion, XkbMinorVersion); +- ERROR("X library supports incompatible version %d.%02d\n", +- mjr, mnr); +- break; +- case XkbOD_ConnectionRefused: +- ERROR("Cannot open display \"%s\"\n", dpyName); +- break; +- case XkbOD_NonXkbServer: +- ERROR("XKB extension not present on %s\n", dpyName); +- break; +- case XkbOD_BadServerVersion: +- INFO("%s was compiled with XKB version %d.%02d\n", +- program, XkbMajorVersion, XkbMinorVersion); +- ERROR("Server %s uses incompatible version %d.%02d\n", +- dpyName, mjr, mnr); +- break; +- default: +- WSGO("Unknown error %d from XkbOpenDisplay\n", error); +- } +- } +- else if (synch) +- XSynchronize(dpy, True); +- return dpy; +-} +- + /***====================================================================***/ + + #ifdef DEBUG + extern int yydebug; + #endif + +-int +-main(int argc, char *argv[]) +-{ ++int xkbcomp_main(int argc, char *argv[]) { + FILE *file; /* input file (or stdin) */ + XkbFile *rtrn; + XkbFile *mapToUse; + int ok; + XkbFileInfo result; +- Status status; + + scan_set_file(stdin); + #ifdef DEBUG +@@ -916,10 +317,6 @@ main(int argc, char *argv[]) + XkbInitIncludePath(); + if (!parseArgs(argc, argv)) + exit(1); +-#ifdef DEBUG +- if (debugFlags & 0x2) +- yydebug = 1; +-#endif + if (preErrorMsg) + uSetPreErrorMessage(preErrorMsg); + if (errorPrefix) +@@ -929,14 +326,6 @@ main(int argc, char *argv[]) + file = NULL; + XkbInitAtoms(NULL); + XkbAddDefaultDirectoriesToPath(); +- if (xkblist) +- { +- Bool gotSome; +- gotSome = GenerateListing(outputFile); +- if ((warningLevel > 7) && (!gotSome)) +- return -1; +- return 0; +- } + if (inputFile != NULL) + { + if (strcmp(inputFile, "-") == 0) +@@ -949,45 +338,11 @@ main(int argc, char *argv[]) + file = fopen(inputFile, "r"); + } + } +- else if (inDpyName != NULL) +- { +- inDpy = GetDisplay(argv[0], inDpyName); +- if (!inDpy) +- { +- ACTION("Exiting\n"); +- exit(1); +- } +- } +- if (outDpyName != NULL) +- { +- outDpy = GetDisplay(argv[0], outDpyName); +- if (!outDpy) +- { +- ACTION("Exiting\n"); +- exit(1); +- } +- } +- if ((inDpy == NULL) && (outDpy == NULL)) +- { +- int mjr, mnr; +- mjr = XkbMajorVersion; +- mnr = XkbMinorVersion; +- if (!XkbLibraryVersion(&mjr, &mnr)) +- { +- INFO("%s was compiled with XKB version %d.%02d\n", +- argv[0], XkbMajorVersion, XkbMinorVersion); +- ERROR("X library supports incompatible version %d.%02d\n", +- mjr, mnr); +- ACTION("Exiting\n"); +- exit(1); +- } +- } + if (file) + { + ok = True; + setScanState(inputFile, 1); +- if ((inputFormat == INPUT_XKB) /* parse .xkb file */ +- && (XKBParseFile(file, &rtrn) && (rtrn != NULL))) ++ if (XKBParseFile(file, &rtrn) && (rtrn != NULL)) + { + fclose(file); + mapToUse = rtrn; +@@ -1069,61 +424,12 @@ main(int argc, char *argv[]) + } + result.xkb->device_spec = device_id; + } +- else if (inputFormat == INPUT_XKM) /* parse xkm file */ +- { +- unsigned tmp; +- bzero(&result, sizeof(result)); +- if ((result.xkb = XkbAllocKeyboard()) == NULL) +- { +- WSGO("Cannot allocate keyboard description\n"); +- /* NOTREACHED */ +- } +- tmp = XkmReadFile(file, 0, XkmKeymapLegal, &result); +- if (tmp == XkmKeymapLegal) +- { +- ERROR("Cannot read XKM file \"%s\"\n", inputFile); +- ok = False; +- } +- result.xkb->device_spec = device_id; +- } + else + { + INFO("Errors encountered in %s; not compiled.\n", inputFile); + ok = False; + } + } +- else if (inDpy != NULL) +- { +- bzero(&result, sizeof(result)); +- result.type = XkmKeymapFile; +- result.xkb = XkbGetMap(inDpy, XkbAllMapComponentsMask, device_id); +- if (result.xkb == NULL) +- WSGO("Cannot load keyboard description\n"); +- if (XkbGetIndicatorMap(inDpy, ~0, result.xkb) != Success) +- WSGO("Could not load indicator map\n"); +- if (XkbGetControls(inDpy, XkbAllControlsMask, result.xkb) != Success) +- WSGO("Could not load keyboard controls\n"); +- if (XkbGetCompatMap(inDpy, XkbAllCompatMask, result.xkb) != Success) +- WSGO("Could not load compatibility map\n"); +- if (XkbGetNames(inDpy, XkbAllNamesMask, result.xkb) != Success) +- WSGO("Could not load names\n"); +- if ((status = XkbGetGeometry(inDpy, result.xkb)) != Success) +- { +- if (warningLevel > 3) +- { +- char buf[100]; +- buf[0] = '\0'; +- XGetErrorText(inDpy, status, buf, 100); +- WARN("Could not load keyboard geometry for %s\n", inDpyName); +- ACTION("%s\n", buf); +- ACTION("Resulting keymap file will not describe geometry\n"); +- } +- } +- if (computeDflts) +- ok = (ComputeKbdDefaults(result.xkb) == Success); +- else +- ok = True; +- } + else + { + fprintf(stderr, "Cannot open \"%s\" to compile\n", inputFile); +@@ -1132,13 +438,6 @@ main(int argc, char *argv[]) + if (ok) + { + FILE *out = stdout; +- if ((inDpy != outDpy) && +- (XkbChangeKbdDisplay(outDpy, &result) != Success)) +- { +- WSGO("Error converting keyboard display from %s to %s\n", +- inDpyName, outDpyName); +- exit(1); +- } + if (outputFile != NULL) + { + if (strcmp(outputFile, "-") == 0) +@@ -1158,16 +457,8 @@ main(int argc, char *argv[]) + const char *openMode = "w"; + unlink(outputFile); + #ifdef O_BINARY +- switch (outputFormat) +- { +- case WANT_XKM_FILE: +- binMode = O_BINARY; +- openMode = "wb"; +- break; +- default: +- binMode = 0; +- break; +- } ++ binMode = O_BINARY; ++ openMode = "wb"; + #endif + outputFileFd = + open(outputFile, O_WRONLY | O_CREAT | O_EXCL, +@@ -1198,33 +489,7 @@ main(int argc, char *argv[]) + } + } + } +- switch (outputFormat) +- { +- case WANT_XKM_FILE: +- ok = XkbWriteXKMFile(out, &result); +- break; +- case WANT_XKB_FILE: +- ok = XkbWriteXKBFile(out, &result, showImplicit, NULL, NULL); +- break; +- case WANT_C_HDR: +- ok = XkbWriteCFile(out, outputFile, &result); +- break; +- case WANT_X_SERVER: +- if (!(ok = XkbWriteToServer(&result))) +- { +- ERROR("%s in %s\n", _XkbErrMessages[_XkbErrCode], +- _XkbErrLocation ? _XkbErrLocation : "unknown"); +- ACTION("Couldn't write keyboard description to %s\n", +- outDpyName); +- } +- break; +- default: +- WSGO("Unknown output format %d\n", outputFormat); +- ACTION("No output file created\n"); +- ok = False; +- break; +- } +- if (outputFormat != WANT_X_SERVER) ++ ok = XkbWriteXKMFile(out, &result); + { + if (fclose(out)) + { +@@ -1244,11 +509,6 @@ main(int argc, char *argv[]) + } + } + } +- if (inDpy) +- XCloseDisplay(inDpy); +- inDpy = NULL; +- if (outDpy) +- XCloseDisplay(outDpy); + uFinishUp(); + return (ok == 0); + } diff --git a/android/app/src/main/cpp/patches/xkbfile.patch b/android/app/src/main/cpp/patches/xkbfile.patch new file mode 100644 index 0000000..3bc09c7 --- /dev/null +++ b/android/app/src/main/cpp/patches/xkbfile.patch @@ -0,0 +1,27 @@ +diff --git a/src/xkbatom.c b/src/xkbatom.c +index 564cc83..723e6da 100644 +--- a/src/xkbatom.c ++++ b/src/xkbatom.c +@@ -202,9 +202,7 @@ XkbAtomGetString(Display *dpy, Atom atm) + { + if (atm == None) + return NULL; +- if (dpy == NULL) +- return _XkbNameForAtom(atm); +- return XGetAtomName(dpy, atm); ++ return _XkbNameForAtom(atm); + } + + /***====================================================================***/ +@@ -214,10 +212,7 @@ XkbInternAtom(Display *dpy, const char *name, Bool onlyIfExists) + { + if (name == NULL) + return None; +- if (dpy == NULL) { +- return _XkbMakeAtom(name, strlen(name), (!onlyIfExists)); +- } +- return XInternAtom(dpy, name, onlyIfExists); ++ return _XkbMakeAtom(name, strlen(name), (!onlyIfExists)); + } + + /***====================================================================***/ diff --git a/android/app/src/main/cpp/patches/xserver.patch b/android/app/src/main/cpp/patches/xserver.patch new file mode 100644 index 0000000..8ceb1a1 --- /dev/null +++ b/android/app/src/main/cpp/patches/xserver.patch @@ -0,0 +1,208 @@ +diff --git a/Xext/shm.c b/Xext/shm.c +index 071bd1a41..011969283 100644 +--- a/Xext/shm.c ++++ b/Xext/shm.c +@@ -193,6 +193,10 @@ CheckForShmSyscall(void) + + #endif + ++const DevPrivateKey ShmGetDevPrivateKeyRec(void) { ++ return shmPixmapPrivateKey; ++} ++ + static Bool + ShmCloseScreen(ScreenPtr pScreen) + { +diff --git a/Xext/shmint.h b/Xext/shmint.h +index 9dadea756..e4e6f4db6 100644 +--- a/Xext/shmint.h ++++ b/Xext/shmint.h +@@ -80,6 +80,8 @@ typedef struct _ShmDesc { + #define SHMDESC_IS_FD(shmdesc) (0) + #endif + ++extern const DevPrivateKey ShmGetDevPrivateKeyRec(void); ++ + extern _X_EXPORT void + ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs); + +diff --git a/dix/main.c b/dix/main.c +index bfc8addbe..56fb30b63 100644 +--- a/dix/main.c ++++ b/dix/main.c +@@ -266,6 +266,7 @@ dix_main(int argc, char *argv[], char *envp[]) + } + + NotifyParentProcess(); ++ ddxReady(); + + InputThreadInit(); + +diff --git a/include/os.h b/include/os.h +index bb3348b18..1a5400717 100644 +--- a/include/os.h ++++ b/include/os.h +@@ -560,6 +560,8 @@ enum ExitCode { + extern _X_EXPORT void + ddxGiveUp(enum ExitCode error); + extern _X_EXPORT void ++ddxReady(void); ++extern _X_EXPORT void + ddxInputThreadInit(void); + extern _X_EXPORT int + TimeSinceLastInputEvent(void); +diff --git a/include/xkbfile.h b/include/xkbfile.h +index f93d31ab0..f65338ac4 100644 +--- a/include/xkbfile.h ++++ b/include/xkbfile.h +@@ -79,6 +79,36 @@ typedef void (*XkbFileAddOnFunc) (FILE * /* file */ , + + /***====================================================================***/ + ++#define XkbInternAtom XXkbInternAtom ++#define XkbAtomText XXkbAtomText ++#define XkbStringText XXkbStringText ++#define XkbVModIndexText XXkbVModIndexText ++#define XkbVModMaskText XXkbVModMaskText ++#define XkbModMaskText XXkbModMaskText ++#define XkbModIndexText XXkbModIndexText ++#define XkbConfigText XXkbConfigText ++#define XkbKeysymText XXkbKeysymText ++#define XkbKeyNameText XXkbKeyNameText ++#define XkbSIMatchText XXkbSIMatchText ++#define XkbIMWhichStateMaskText XXkbIMWhichStateMaskText ++#define XkbControlsMaskText XXkbControlsMaskText ++#define XkbGeomFPText XXkbGeomFPText ++#define XkbDoodadTypeText XXkbDoodadTypeText ++#define XkbActionTypeText XXkbActionTypeText ++#define XkbActionText XXkbActionText ++#define XkbBehaviorText XXkbBehaviorText ++#define XkbIndentText XXkbIndentText ++#define XkbWriteXKBKeycodes XXkbWriteXKBKeycodes ++#define XkbWriteXKBKeyTypes XXkbWriteXKBKeyTypes ++#define XkbWriteXKBCompatMap XXkbWriteXKBCompatMap ++#define XkbWriteXKBSymbols XXkbWriteXKBSymbols ++#define XkbWriteXKBGeometry XXkbWriteXKBGeometry ++#define XkbWriteXKBKeymapForNames XXkbWriteXKBKeymapForNames ++#define XkbFindKeycodeByName XXkbFindKeycodeByName ++#define XkbConvertGetByNameComponents XXkbConvertGetByNameComponents ++#define XkbNameMatchesPattern XXkbNameMatchesPattern ++#define _XkbKSCheckCase _XXkbKSCheckCase ++ + _XFUNCPROTOBEGIN + + extern _X_EXPORT char *XkbIndentText(unsigned /* size */ +diff --git a/os/osinit.c b/os/osinit.c +index 8575319ff..06c44a416 100644 +--- a/os/osinit.c ++++ b/os/osinit.c +@@ -170,11 +170,11 @@ OsInit(void) + #endif + + if (!been_here) { +-#if !defined(WIN32) || defined(__CYGWIN__) ++#if !defined(WIN32) || defined(__CYGWIN__) || !defined(__ANDROID__) + struct sigaction act, oact; + int i; + +- int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS, ++ int siglist[] = { SIGQUIT, SIGILL, SIGFPE, SIGBUS, + SIGABRT, + SIGSYS, + SIGXCPU, +diff --git a/os/utils.c b/os/utils.c +index 92a66e81a..d2ca69684 100644 +--- a/os/utils.c ++++ b/os/utils.c +@@ -212,6 +212,8 @@ OsSignal(int sig, OsSigHandlerPtr handler) + { + #if defined(WIN32) && !defined(__CYGWIN__) + return signal(sig, handler); ++#elif defined(__ANDROID__) ++ return SIG_DFL; + #else + struct sigaction act, oact; + +@@ -232,7 +234,7 @@ OsSignal(int sig, OsSigHandlerPtr handler) + * server at a time. This keeps the servers from stomping on each other + * if the user forgets to give them different display numbers. + */ +-#define LOCK_DIR "/tmp" ++#define LOCK_DIR (getenv("TMPDIR") ?: "/tmp") + #define LOCK_TMP_PREFIX "/.tX" + #define LOCK_PREFIX "/.X" + #define LOCK_SUFFIX "-lock" +@@ -324,7 +326,7 @@ LockServer(void) + i = 0; + haslock = 0; + while ((!haslock) && (i++ < 3)) { +- haslock = (link(tmp, LockFile) == 0); ++ haslock = (rename(tmp, LockFile) == 0); + if (haslock) { + /* + * We're done. +@@ -1412,6 +1414,10 @@ static struct pid { + int pid; + } *pidlist; + ++extern char* xkbcomp_argv[]; ++extern int xkbcomp_argc; ++int xkbcomp_main(int argc, char *argv[]); ++ + void * + Popen(const char *command, const char *type) + { +@@ -1475,8 +1481,11 @@ Popen(const char *command, const char *type) + } + close(pdes[1]); + } +- execl("/bin/sh", "sh", "-c", command, (char *) NULL); +- _exit(127); ++ ++ for(int j=1; j<= SIGUNUSED; j++) ++ signal(j, SIG_DFL); ++ ++ _exit(xkbcomp_main(xkbcomp_argc, xkbcomp_argv)); + } + + /* Avoid EINTR during stdio calls */ +diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c +index f9b7b06d9..f4b2aeddc 100644 +--- a/xkb/ddxLoad.c ++++ b/xkb/ddxLoad.c +@@ -56,6 +56,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + #define PATHSEPARATOR "/" + #endif + ++char* xkbcomp_argv[16] = {0}; ++int xkbcomp_argc = 0; ++ + static unsigned + LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn); + +@@ -152,6 +155,25 @@ RunXkbComp(xkbcomp_buffer_callback callback, void *userdata) + xkm_output_dir, keymap) == -1) + buf = NULL; + ++ char buf2[256]; ++ char buf3[256]; ++ sprintf(buf2, "-R%s", XkbBaseDirectory); ++ sprintf(buf3, "%s%s.xkm", xkm_output_dir, keymap); ++ xkbcomp_argv[0] = "xkbcomp"; ++ xkbcomp_argv[1] = "-w"; ++ xkbcomp_argv[2] = "1"; ++ xkbcomp_argv[3] = buf2; ++ xkbcomp_argv[4] = "-xkm"; ++ xkbcomp_argv[5] = (char*) xkmfile; ++ xkbcomp_argv[6] = "-em1"; ++ xkbcomp_argv[7] = PRE_ERROR_MSG; ++ xkbcomp_argv[8] = "-emp"; ++ xkbcomp_argv[9] = ERROR_PREFIX; ++ xkbcomp_argv[10] = "-eml"; ++ xkbcomp_argv[11] = POST_ERROR_MSG1; ++ xkbcomp_argv[12] = buf3; ++ xkbcomp_argc = 13; ++ + free(xkbbasedirflag); + + if (!buf) { diff --git a/android/app/src/main/cpp/pixman b/android/app/src/main/cpp/pixman new file mode 160000 index 0000000..b753a6f --- /dev/null +++ b/android/app/src/main/cpp/pixman @@ -0,0 +1 @@ +Subproject commit b753a6f49b9b0ec5df84aff10e174601545bdf79 diff --git a/android/app/src/main/cpp/recipes/Xau.cmake b/android/app/src/main/cpp/recipes/Xau.cmake new file mode 100644 index 0000000..035de0a --- /dev/null +++ b/android/app/src/main/cpp/recipes/Xau.cmake @@ -0,0 +1,5 @@ +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Xau") +add_library(Xau STATIC "libxau/AuDispose.c" "libxau/AuRead.c") +target_include_directories(Xau PUBLIC "libxau/include") +target_compile_options(Xdmcp PRIVATE ${common_compile_options} "-D_GNU_SOURCE=1" "-DHAVE_EXPLICIT_BZERO" "-fPIC") +target_link_libraries(Xau xorgproto) diff --git a/android/app/src/main/cpp/recipes/Xdmcp.cmake b/android/app/src/main/cpp/recipes/Xdmcp.cmake new file mode 100644 index 0000000..c8df746 --- /dev/null +++ b/android/app/src/main/cpp/recipes/Xdmcp.cmake @@ -0,0 +1,5 @@ +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Xdmcp") +add_library(Xdmcp STATIC "libxdmcp/Array.c" "libxdmcp/Fill.c" "libxdmcp/Flush.c" "libxdmcp/Key.c" "libxdmcp/Read.c" "libxdmcp/Unwrap.c" "libxdmcp/Wrap.c" "libxdmcp/Wraphelp.c" "libxdmcp/Write.c") +target_compile_options(Xdmcp PRIVATE "-D_GNU_SOURCE=1" "-DHASXDMAUTH=1" "-DHAVE_ARC4RANDOM_BUF=1" "-DHAVE_GETENTROPY=1" "-DHAVE_LRAND48=1" "-DHAVE_SRAND48=1" "-DHAVE_SYS_RANDOM_H=1" ${common_compile_options}) +target_include_directories(Xdmcp PUBLIC "libxdmcp/include" "${CMAKE_CURRENT_BINARY_DIR}/Xdmcp") +target_link_libraries(Xdmcp PRIVATE xorgproto) diff --git a/android/app/src/main/cpp/recipes/Xfont2.cmake b/android/app/src/main/cpp/recipes/Xfont2.cmake new file mode 100644 index 0000000..f865547 --- /dev/null +++ b/android/app/src/main/cpp/recipes/Xfont2.cmake @@ -0,0 +1,70 @@ +add_library(Xfont2 STATIC + "libxfont/src/stubs/atom.c" + "libxfont/src/stubs/libxfontstubs.c" + "libxfont/src/util/fontaccel.c" + "libxfont/src/util/fontnames.c" + "libxfont/src/util/fontutil.c" + "libxfont/src/util/fontxlfd.c" + "libxfont/src/util/format.c" + "libxfont/src/util/miscutil.c" + "libxfont/src/util/patcache.c" + "libxfont/src/util/private.c" + "libxfont/src/util/utilbitmap.c" + "libxfont/src/util/reallocarray.c" + + "libxfont/src/fontfile/bitsource.c" + "libxfont/src/fontfile/bufio.c" + "libxfont/src/fontfile/decompress.c" + "libxfont/src/fontfile/defaults.c" + "libxfont/src/fontfile/dirfile.c" + "libxfont/src/fontfile/fileio.c" + "libxfont/src/fontfile/filewr.c" + "libxfont/src/fontfile/fontdir.c" + "libxfont/src/fontfile/fontencc.c" + "libxfont/src/fontfile/fontfile.c" + "libxfont/src/fontfile/fontscale.c" + "libxfont/src/fontfile/gunzip.c" + "libxfont/src/fontfile/register.c" + "libxfont/src/fontfile/renderers.c" + "libxfont/src/fontfile/catalogue.c" + + "libxfont/src/bitmap/bitmap.c" + "libxfont/src/bitmap/bitmapfunc.c" + "libxfont/src/bitmap/bitmaputil.c" + "libxfont/src/bitmap/bitscale.c" + "libxfont/src/bitmap/fontink.c" + "libxfont/src/bitmap/bdfread.c" + "libxfont/src/bitmap/bdfutils.c" + "libxfont/src/bitmap/pcfread.c" + "libxfont/src/bitmap/pcfwrite.c" + + "libxfont/src/builtins/dir.c" + "libxfont/src/builtins/file.c" + "libxfont/src/builtins/fonts.c" + "libxfont/src/builtins/fpe.c" + "libxfont/src/builtins/render.c") +target_compile_options(Xfont2 PRIVATE + ${common_compile_options} + "-fvisibility=hidden" + "-DHAVE_ERR_H" + "-DHAVE_STDINT_H=1" + "-DHAVE_READLINK" + "-UHAVE_REALLOCARRAY" + "-DHAVE_REALPATH" + "-DHAVE_STRLCPY" + "-DXFONT_BDFFORMAT=1" + "-DXFONT_BITMAP=1" + "-UXFONT_FREETYPE" + "-DXFONT_PCFFORMAT=1" + "-UXFONT_SNFFORMAT" + "-UX_BZIP2_FONT_COMPRESSION" + "-DX_GZIP_FONT_COMPRESSION=1" + "-D_GNU_SOURCE=1" + "-D_DEFAULT_SOURCE=1" + "-D_BSD_SOURCE=1" + "-DHAS_FCHOWN" + "-DHAS_STICKY_DIR_BIT" + "-D_XOPEN_SOURCE" + "-DNOFILES_MAX=512") +target_include_directories(Xfont2 PRIVATE "libxfont" "libxfont/include" "libfontenc/include") +target_link_libraries(Xfont2 PUBLIC xorgproto) diff --git a/android/app/src/main/cpp/recipes/fontenc.cmake b/android/app/src/main/cpp/recipes/fontenc.cmake new file mode 100644 index 0000000..52b529c --- /dev/null +++ b/android/app/src/main/cpp/recipes/fontenc.cmake @@ -0,0 +1,4 @@ +add_library(fontenc STATIC "libfontenc/src/fontenc.c" "libfontenc/src/encparse.c" "libfontenc/src/reallocarray.c") +target_include_directories(fontenc PUBLIC "libfontenc/include") +target_link_libraries(fontenc PUBLIC xorgproto) +target_compile_options(fontenc PRIVATE "-DFONT_ENCODINGS_DIRECTORY=\"/\"") diff --git a/android/app/src/main/cpp/recipes/md.cmake b/android/app/src/main/cpp/recipes/md.cmake new file mode 100644 index 0000000..29c0d38 --- /dev/null +++ b/android/app/src/main/cpp/recipes/md.cmake @@ -0,0 +1,193 @@ +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/sha1.h" CONTENT " +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + */ + +#ifndef _SHA1_H +#define _SHA1_H + +#include +#include + +#define SHA1_BLOCK_LENGTH 64 +#define SHA1_DIGEST_LENGTH 20 + +typedef struct { + uint32_t state[5]; + uint64_t count; + uint8_t buffer[SHA1_BLOCK_LENGTH]; +} SHA1_CTX; + +void SHA1Init(SHA1_CTX *); +void SHA1Pad(SHA1_CTX *); +void SHA1Transform(uint32_t [5], const uint8_t [SHA1_BLOCK_LENGTH]); +void SHA1Update(SHA1_CTX *, const uint8_t *, size_t); +void SHA1Final(uint8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *); + +#endif /* _SHA1_H */ + +") +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libmd/sha1.c" CONTENT " +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + */ + +#include +#include + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + */ +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) |(rol(block->l[i],8)&0x00FF00FF)) +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +typedef union { + uint8_t c[64]; + uint32_t l[16]; +} CHAR64LONG16; + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +void +SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH]) +{ + uint32_t a, b, c, d, e; + uint8_t workspace[SHA1_BLOCK_LENGTH]; + CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; + + (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); + + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* + * SHA1Init - Initialize new context + */ +void +SHA1Init(SHA1_CTX *context) +{ + + /* SHA1 initialization constants */ + context->count = 0; + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; +} + + +/* + * Run your data through this. + */ +void +SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len) +{ + size_t i, j; + + j = (size_t)((context->count >> 3) & 63); + context->count += (len << 3); + if ((j + len) > 63) { + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1Transform(context->state, (uint8_t *)&data[i]); + j = 0; + } else { + i = 0; + } + (void)memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* + * Add padding and return the message digest. + */ +void +SHA1Pad(SHA1_CTX *context) +{ + uint8_t finalcount[8]; + unsigned int i; + + for (i = 0; i < 8; i++) + finalcount[i] = (uint8_t)((context->count >> ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ + + SHA1Update(context, (uint8_t *)\"\\200\", 1); + while ((context->count & 504) != 448) + SHA1Update(context, (uint8_t *)\"\\0\", 1); + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ +} + +void +SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) +{ + unsigned int i; + + SHA1Pad(context); + if (digest) { + for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { + digest[i] = (uint8_t) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + memset(context, 0, sizeof(*context)); + } +} +") + +add_library(md STATIC "${CMAKE_CURRENT_BINARY_DIR}/libmd/sha1.c") +target_include_directories(md PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/android/app/src/main/cpp/recipes/pixman.cmake b/android/app/src/main/cpp/recipes/pixman.cmake new file mode 100644 index 0000000..c91bc32 --- /dev/null +++ b/android/app/src/main/cpp/recipes/pixman.cmake @@ -0,0 +1,91 @@ +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pixman-config.h" + CONTENT "") +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pixman-version.h" + CONTENT " +#pragma once +#ifndef PIXMAN_H__ +# error pixman-version.h should only be included by pixman.h +#endif + +#define PIXMAN_VERSION_MAJOR 0 +#define PIXMAN_VERSION_MINOR 43 +#define PIXMAN_VERSION_MICRO 4 + +#define PIXMAN_VERSION_STRING \"0.43.4\" +#define PIXMAN_VERSION 4304 + +#ifndef PIXMAN_API +# define PIXMAN_API +#endif +") +check_type_size("long" SIZEOF_LONG) + +set(PIXMAN_SRC + pixman/pixman/pixman.c + pixman/pixman/pixman-access.c + pixman/pixman/pixman-access-accessors.c + pixman/pixman/pixman-bits-image.c + pixman/pixman/pixman-combine32.c + pixman/pixman/pixman-combine-float.c + pixman/pixman/pixman-conical-gradient.c + pixman/pixman/pixman-filter.c + pixman/pixman/pixman-x86.c + pixman/pixman/pixman-mips.c + pixman/pixman/pixman-arm.c + pixman/pixman/pixman-ppc.c + pixman/pixman/pixman-edge.c + pixman/pixman/pixman-edge-accessors.c + pixman/pixman/pixman-fast-path.c + pixman/pixman/pixman-glyph.c + pixman/pixman/pixman-general.c + pixman/pixman/pixman-gradient-walker.c + pixman/pixman/pixman-image.c + pixman/pixman/pixman-implementation.c + pixman/pixman/pixman-linear-gradient.c + pixman/pixman/pixman-matrix.c + pixman/pixman/pixman-noop.c + pixman/pixman/pixman-radial-gradient.c + pixman/pixman/pixman-region16.c + pixman/pixman/pixman-region32.c + pixman/pixman/pixman-solid-fill.c + pixman/pixman/pixman-timer.c + pixman/pixman/pixman-trap.c + pixman/pixman/pixman-utils.c) + +set(PIXMAN_CFLAGS + "-DHAVE_BUILTIN_CLZ=1" + "-DHAVE_PTHREADS=1" + "-DPACKAGE=\"pixman\"" + "-DTLS=__thread" + "-DSIZEOF_LONG=${SIZEOF_LONG}" + "-DUSE_OPENMP=1" + "-Wno-unknown-attributes") + +if("${CMAKE_ANDROID_ARCH_ABI}" STREQUAL "arm64-v8a") + set(PIXMAN_SRC ${PIXMAN_SRC} + "pixman/pixman/pixman-arm-neon.c" + "pixman/pixman/pixman-arma64-neon-asm.S" + "pixman/pixman/pixman-arma64-neon-asm-bilinear.S") + set(PIXMAN_CFLAGS ${PIXMAN_CFLAGS} "-DUSE_ARM_A64_NEON=1") +endif() + +if("${CMAKE_ANDROID_ARCH_ABI}" STREQUAL "armeabi-v7a") + set(PIXMAN_SRC ${PIXMAN_SRC} + "pixman/pixman/pixman-arm-neon.c" + "pixman/pixman/pixman-arm-neon-asm.S" + "pixman/pixman/pixman-arm-neon-asm-bilinear.S" + "pixman/pixman/pixman-arm-simd-asm.S" + "pixman/pixman/pixman-arm-simd-asm-scaled.S") + set(PIXMAN_CFLAGS ${PIXMAN_CFLAGS} "-DUSE_ARM_SIMD=1" "-DUSE_ARM_NEON=1" "-v") +endif() + +if ("${CMAKE_ANDROID_ARCH_ABI}" STREQUAL "x86" OR "${CMAKE_ANDROID_ARCH_ABI}" STREQUAL "x86_64") + set(PIXMAN_CFLAGS ${PIXMAN_CFLAGS} "-msse2" "-Winline" "-mssse3" "-Winline") +endif() + +add_library(pixman STATIC ${PIXMAN_SRC}) +target_compile_options(pixman PRIVATE ${PIXMAN_CFLAGS}) +target_include_directories(pixman PRIVATE pixman "${CMAKE_CURRENT_BINARY_DIR}") +target_apply_patch(pixman "${CMAKE_CURRENT_SOURCE_DIR}/pixman" "${CMAKE_CURRENT_SOURCE_DIR}/patches/pixman.patch") diff --git a/android/app/src/main/cpp/recipes/tirpc.cmake b/android/app/src/main/cpp/recipes/tirpc.cmake new file mode 100644 index 0000000..15492e8 --- /dev/null +++ b/android/app/src/main/cpp/recipes/tirpc.cmake @@ -0,0 +1,50 @@ +add_library(tirpc STATIC + "libtirpc/src/auth_none.c" + "libtirpc/src/auth_unix.c" + "libtirpc/src/authunix_prot.c" + "libtirpc/src/binddynport.c" + "libtirpc/src/clnt_bcast.c" + "libtirpc/src/clnt_dg.c" + "libtirpc/src/clnt_generic.c" + "libtirpc/src/clnt_perror.c" + "libtirpc/src/clnt_raw.c" + "libtirpc/src/clnt_simple.c" + "libtirpc/src/clnt_vc.c" + "libtirpc/src/rpc_dtablesize.c" + "libtirpc/src/getnetconfig.c" + "libtirpc/src/getnetpath.c" + "libtirpc/src/mt_misc.c" + "libtirpc/src/pmap_clnt.c" + "libtirpc/src/pmap_getport.c" + "libtirpc/src/pmap_prot.c" + "libtirpc/src/pmap_prot2.c" + "libtirpc/src/pmap_rmt.c" + "libtirpc/src/rpc_prot.c" + "libtirpc/src/rpc_commondata.c" + "libtirpc/src/rpc_callmsg.c" + "libtirpc/src/rpc_generic.c" + "libtirpc/src/rpc_soc.c" + "libtirpc/src/rpcb_clnt.c" + "libtirpc/src/rpcb_prot.c" + "libtirpc/src/svc.c" + "libtirpc/src/svc_auth.c" + "libtirpc/src/svc_dg.c" + "libtirpc/src/svc_auth_unix.c" + "libtirpc/src/svc_auth_none.c" + "libtirpc/src/svc_generic.c" + "libtirpc/src/svc_raw.c" + "libtirpc/src/svc_simple.c" + "libtirpc/src/svc_vc.c" + "libtirpc/src/getpeereid.c" + "libtirpc/src/debug.c" + "libtirpc/src/xdr.c" + "libtirpc/src/xdr_rec.c" + "libtirpc/src/xdr_array.c" + "libtirpc/src/xdr_mem.c" + "libtirpc/src/xdr_reference.c") +target_include_directories(tirpc PUBLIC "libtirpc/tirpc") +target_compile_options(tirpc PRIVATE "-DPORTMAP" "-DINET6=1" "-DHAVE_FEATURES_H=1" + "-DHAVE_GETRPCBYNAME=1" "-DHAVE_GETRPCBYNUMBER=1" "-DHAVE_SETRPCENT=1" "-DHAVE_ENDRPCENT=1" + "-DHAVE_GETRPCENT=1" "-UHAVE_GSSAPI_GSSAPI_EXT_H" "-UAUTHDES_SUPPORT" "-Dquad_t=long long" + "-Du_quad_t=unsigned long long" "-Dgetdtablesize()=sysconf(_SC_OPEN_MAX)" "-D_GNU_SOURCE" + "-Wall" "-pipe" "-fPIC" "-DPIC" "-Wno-deprecated-non-prototype" "-Wno-macro-redefined") diff --git a/android/app/src/main/cpp/recipes/xkbcomp.cmake b/android/app/src/main/cpp/recipes/xkbcomp.cmake new file mode 100644 index 0000000..bdf6d16 --- /dev/null +++ b/android/app/src/main/cpp/recipes/xkbcomp.cmake @@ -0,0 +1,71 @@ +# Normally xkbcomp is build as executable, but in our case it is better to embed it. + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/X11") + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/ks_tables.h" + COMMAND "gcc" "-o" "${CMAKE_CURRENT_BINARY_DIR}/makekeys" "${CMAKE_CURRENT_SOURCE_DIR}/libx11/src/util/makekeys.c" "&&" + "${CMAKE_CURRENT_BINARY_DIR}/makekeys" "keysymdef.h" "XF86keysym.h" "Sunkeysym.h" "DECkeysym.h" "HPkeysym.h" ">" "${CMAKE_CURRENT_BINARY_DIR}/ks_tables.h" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/xorgproto/include/X11" + COMMENT "Generating source code (ks_tables.h)" + VERBATIM) + +BISON_TARGET(xkbcomp_parser xkbcomp/xkbparse.y ${CMAKE_CURRENT_BINARY_DIR}/xkbparse.c) +add_library(xkbcomp STATIC + "libx11/src/KeyBind.c" + "libx11/src/KeysymStr.c" + "libx11/src/Quarks.c" + "libx11/src/StrKeysym.c" + "libx11/src/Xrm.c" + + "libx11/src/xkb/XKBGeom.c" + "libx11/src/xkb/XKBMisc.c" + "libx11/src/xkb/XKBMAlloc.c" + "libx11/src/xkb/XKBGAlloc.c" + "libx11/src/xkb/XKBAlloc.c" + + "libxkbfile/src/xkbatom.c" + "libxkbfile/src/xkberrs.c" + "libxkbfile/src/xkbmisc.c" + "libxkbfile/src/xkbout.c" + "libxkbfile/src/xkbtext.c" + "libxkbfile/src/xkmout.c" + + "xkbcomp/action.c" + "xkbcomp/alias.c" + "xkbcomp/compat.c" + "xkbcomp/expr.c" + "xkbcomp/geometry.c" + "xkbcomp/indicators.c" + "xkbcomp/keycodes.c" + "xkbcomp/keymap.c" + "xkbcomp/keytypes.c" + "xkbcomp/listing.c" + "xkbcomp/misc.c" + "xkbcomp/parseutils.c" + "xkbcomp/symbols.c" + "xkbcomp/utils.c" + "xkbcomp/vmod.c" + "xkbcomp/xkbcomp.c" + "xkbcomp/xkbparse.y" + "xkbcomp/xkbpath.c" + "xkbcomp/xkbscan.c" + "${CMAKE_CURRENT_BINARY_DIR}/ks_tables.h" + "${CMAKE_CURRENT_BINARY_DIR}/xkbparse.c") +target_include_directories(xkbcomp + PUBLIC + "libxkbfile/include" + PRIVATE + "xkbcomp" + "libx11/include" + "libx11/include/X11" + "libx11/src" + "libx11/src/xlibi18n" + "libxkbfile/include/X11/extensions" + "${CMAKE_CURRENT_BINARY_DIR}") +target_link_libraries(xkbcomp PRIVATE xorgproto) +target_link_options(xkbcomp PRIVATE "-fPIE" "-fPIC") +target_compile_options(xkbcomp PRIVATE ${common_compile_options} "-fvisibility=hidden" "-DHAVE_STRCASECMP" "-DHAVE_STRDUP" "-DDFLT_XKB_CONFIG_ROOT=\"/\"" "-DHAVE_SYS_IOCTL_H" "-fPIE" "-fPIC" "-DPACKAGE_VERSION=\"2.70\"" "-Wno-shadow") +target_apply_patch(xkbcomp "${CMAKE_CURRENT_SOURCE_DIR}/xkbcomp" "${CMAKE_CURRENT_SOURCE_DIR}/patches/xkbcomp.patch") +target_apply_patch(xkbfile "${CMAKE_CURRENT_SOURCE_DIR}/libxkbfile" "${CMAKE_CURRENT_SOURCE_DIR}/patches/xkbfile.patch") +target_apply_patch(X11 "${CMAKE_CURRENT_SOURCE_DIR}/libx11" "${CMAKE_CURRENT_SOURCE_DIR}/patches/x11.patch") diff --git a/android/app/src/main/cpp/recipes/xorgproto.cmake b/android/app/src/main/cpp/recipes/xorgproto.cmake new file mode 100644 index 0000000..8325f05 --- /dev/null +++ b/android/app/src/main/cpp/recipes/xorgproto.cmake @@ -0,0 +1,9 @@ +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/X11") +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/X11/XlibConf.h" CONTENT "\n#pragma once\n#define XTHREADS 1\n#define XUSE_MTSAFE_API 1") +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/libxtrans" "${CMAKE_CURRENT_BINARY_DIR}/X11/Xtrans") + +add_library(xorgproto INTERFACE) +target_include_directories(xorgproto INTERFACE "xorgproto/include") +set(USE_FDS_BITS 1) +configure_file("xorgproto/include/X11/Xpoll.h.in" "${CMAKE_CURRENT_BINARY_DIR}/X11/Xpoll.h" @ONLY) +target_apply_patch(Xtrans "${CMAKE_CURRENT_SOURCE_DIR}/libxtrans" "${CMAKE_CURRENT_SOURCE_DIR}/patches/Xtrans.patch") \ No newline at end of file diff --git a/android/app/src/main/cpp/recipes/xserver.cmake b/android/app/src/main/cpp/recipes/xserver.cmake new file mode 100644 index 0000000..6278b40 --- /dev/null +++ b/android/app/src/main/cpp/recipes/xserver.cmake @@ -0,0 +1,280 @@ +check_type_size("unsigned long" SIZEOF_UNSIGNED_LONG) +configure_file("patches/dix-config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/dix-config.h") + +file(GENERATE + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version-config.h + CONTENT " +#pragma once +#define VENDOR_NAME \"The X.Org Foundation\" +#define VENDOR_RELEASE 12101099 +") + +file(GENERATE + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xkb-config.h + CONTENT " +#pragma once +#define XKB_BASE_DIRECTORY \"/usr/share/X11/xkb/\" +#define XKB_BIN_DIRECTORY \"\" +#define XKB_DFLT_LAYOUT \"us\" +#define XKB_DFLT_MODEL \"pc105\" +#define XKB_DFLT_OPTIONS \"\" +#define XKB_DFLT_RULES \"evdev\" +#define XKB_DFLT_VARIANT \"\" +#define XKM_OUTPUT_DIR (getenv(\"TMPDIR\") ?: \"/tmp\") +") + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/xserver") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/xserver/GL") +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/xserver/GL/glext.h" CONTENT "#include ") +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/xserver/GL/gl.h" + COMMAND Python3::Interpreter "${CMAKE_CURRENT_SOURCE_DIR}/libepoxy/src/gen_dispatch.py" + "--outputdir=${CMAKE_CURRENT_BINARY_DIR}/xserver/GL" "${CMAKE_CURRENT_SOURCE_DIR}/libepoxy/registry/gl.xml" + COMMENT "Generating source code (GL/gl.h)" + VERBATIM) + +set(inc "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}/xserver" + "libxfont/include" + "pixman/pixman" + "xorgproto/include" + "libxkbfile/include" + "xserver/Xext" + "xserver/Xi" + "xserver/composite" + "xserver/damageext" + "xserver/fb" + "xserver/mi" + "xserver/miext/damage" + "xserver/miext/shadow" + "xserver/miext/sync" + "xserver/dbe" + "xserver/dri3" + "xserver/include" + "xserver/present" + "xserver/randr" + "xserver/render" + "xserver/xfixes" + "xserver/glx") + +set(compile_options + ${common_compile_options} + "-std=gnu99" + "-DHAVE_DIX_CONFIG_H" + "-fno-strict-aliasing" + "-fvisibility=hidden" + "-fPIC" + "-D_DEFAULT_SOURCE" + "-D_BSD_SOURCE" + "-DHAS_FCHOWN" + "-DHAS_STICKY_DIR_BIT" + "-D_PATH_TMP=getenv(\"TMPDIR\")?:\"/tmp\"" + "-include" "${CMAKE_CURRENT_SOURCE_DIR}/lorie/shm/shm.h") +if (SIZEOF_UNSIGNED_LONG EQUAL 8) + set(compile_options ${compile_options} "-D_XSERVER64=1") +endif () + +set(DIX_SOURCES + atom.c colormap.c cursor.c devices.c dispatch.c dixfonts.c main.c dixutils.c enterleave.c + events.c eventconvert.c extension.c gc.c gestures.c getevents.c globals.c glyphcurs.c + grabs.c initatoms.c inpututils.c pixmap.c privates.c property.c ptrveloc.c region.c + registry.c resource.c selection.c swaprep.c swapreq.c tables.c touch.c window.c) +list(TRANSFORM DIX_SOURCES PREPEND "xserver/dix/") +add_library(xserver_dix STATIC ${DIX_SOURCES}) +target_include_directories(xserver_dix PRIVATE ${inc}) +target_compile_options(xserver_dix PRIVATE ${compile_options}) + +add_library(xserver_main STATIC + "xserver/dix/stubmain.c") +target_include_directories(xserver_main PRIVATE ${inc}) +target_compile_options(xserver_main PRIVATE ${compile_options}) + +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/drm_fourcc.h" + CONTENT " + #pragma once + #define fourcc_code(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) + #define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') + #define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') + #define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0') + #define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4') + #define DRM_FORMAT_MOD_INVALID -1 +") +add_library(xserver_dri3 STATIC + "xserver/dri3/dri3.c" + "xserver/dri3/dri3_request.c" + "xserver/dri3/dri3_screen.c") +target_include_directories(xserver_dri3 PRIVATE ${inc}) +target_compile_options(xserver_dri3 PRIVATE ${compile_options}) + +set(FB_SOURCES + fballpriv.c fbarc.c fbbits.c fbblt.c fbbltone.c fbcmap_mi.c fbcopy.c fbfill.c fbfillrect.c + fbfillsp.c fbgc.c fbgetsp.c fbglyph.c fbimage.c fbline.c fboverlay.c fbpict.c fbpixmap.c + fbpoint.c fbpush.c fbscreen.c fbseg.c fbsetsp.c fbsolid.c fbtrap.c fbutil.c fbwindow.c) +list(TRANSFORM FB_SOURCES PREPEND "xserver/fb/") +add_library(xserver_fb STATIC ${FB_SOURCES}) +target_include_directories(xserver_fb PRIVATE ${inc}) +target_compile_options(xserver_fb PRIVATE ${compile_options}) + +set(MI_SOURCES + miarc.c mibitblt.c micmap.c micopy.c midash.c midispcur.c mieq.c miexpose.c mifillarc.c + mifillrct.c migc.c miglblt.c mioverlay.c mipointer.c mipoly.c mipolypnt.c mipolyrect.c + mipolyseg.c mipolytext.c mipushpxl.c miscrinit.c misprite.c mivaltree.c miwideline.c + miwindow.c mizerarc.c mizerclip.c mizerline.c) +list(TRANSFORM MI_SOURCES PREPEND "xserver/mi/") +add_library(xserver_mi STATIC ${MI_SOURCES}) +target_include_directories(xserver_mi PRIVATE ${inc}) +target_compile_options(xserver_mi PRIVATE ${compile_options}) + +set(OS_SOURCES + WaitFor.c access.c auth.c backtrace.c client.c connection.c inputthread.c io.c mitauth.c + oscolor.c osinit.c ospoll.c utils.c xdmauth.c xsha1.c xstrans.c xprintf.c log.c strlcpy.c + busfault.c timingsafe_memcmp.c rpcauth.c xdmcp.c) +list(TRANSFORM OS_SOURCES PREPEND "xserver/os/") +add_library(xserver_os STATIC ${OS_SOURCES}) +target_include_directories(xserver_os PRIVATE ${inc}) +target_link_libraries(xserver_os PRIVATE md Xdmcp Xau tirpc) +target_compile_options(xserver_os PRIVATE ${compile_options} "-DCLIENTIDS") + +set(COMPOSITE_SOURCES compalloc.c compext.c compinit.c compoverlay.c compwindow.c) +list(TRANSFORM COMPOSITE_SOURCES PREPEND "xserver/composite/") +add_library(xserver_composite STATIC ${COMPOSITE_SOURCES}) +target_include_directories(xserver_composite PRIVATE ${inc}) +target_compile_options(xserver_composite PRIVATE ${compile_options}) + +add_library(xserver_damageext STATIC "xserver/damageext/damageext.c") +target_include_directories(xserver_damageext PRIVATE ${inc}) +target_compile_options(xserver_damageext PRIVATE ${compile_options}) + +add_library(xserver_dbe STATIC "xserver/dbe/dbe.c" "xserver/dbe/midbe.c") +target_include_directories(xserver_dbe PRIVATE ${inc}) +target_compile_options(xserver_dbe PRIVATE ${compile_options}) + +add_library(xserver_miext_damage STATIC "xserver/miext/damage/damage.c") +target_include_directories(xserver_miext_damage PRIVATE ${inc}) +target_compile_options(xserver_miext_damage PRIVATE ${compile_options}) + +set(MIEXT_SYNC_SOURCES misync.c misyncfd.c misyncshm.c) +list(TRANSFORM MIEXT_SYNC_SOURCES PREPEND "xserver/miext/sync/") +add_library(xserver_miext_sync STATIC ${MIEXT_SYNC_SOURCES}) +target_include_directories(xserver_miext_sync PRIVATE ${inc}) +target_compile_options(xserver_miext_sync PRIVATE ${compile_options}) + +set(PRESENT_SOURCES + present.c present_event.c present_execute.c present_fake.c present_fence.c present_notify.c + present_request.c present_scmd.c present_screen.c present_vblank.c) +list(TRANSFORM PRESENT_SOURCES PREPEND "xserver/present/") +add_library(xserver_present STATIC ${PRESENT_SOURCES}) +target_include_directories(xserver_present PRIVATE ${inc}) +target_compile_options(xserver_present PRIVATE ${compile_options}) + +set(RANDR_SOURCES + randr.c rrcrtc.c rrdispatch.c rrinfo.c rrlease.c rrmode.c rrmonitor.c rroutput.c rrpointer.c + rrproperty.c rrprovider.c rrproviderproperty.c rrscreen.c rrsdispatch.c rrtransform.c + rrxinerama.c) +list(TRANSFORM RANDR_SOURCES PREPEND "xserver/randr/") +add_library(xserver_randr STATIC ${RANDR_SOURCES}) +target_include_directories(xserver_randr PRIVATE ${inc}) +target_compile_options(xserver_randr PRIVATE ${compile_options}) + +add_library(xserver_record STATIC xserver/record/record.c xserver/record/set.c) +target_include_directories(xserver_record PRIVATE ${inc}) +target_compile_options(xserver_record PRIVATE ${compile_options}) + +set(RENDER_SOURCES + animcur.c filter.c glyph.c matrix.c miindex.c mipict.c mirect.c mitrap.c mitri.c picture.c + render.c) +list(TRANSFORM RENDER_SOURCES PREPEND "xserver/render/") +add_library(xserver_render STATIC ${RENDER_SOURCES}) +target_include_directories(xserver_render PRIVATE ${inc}) +target_compile_options(xserver_render PRIVATE ${compile_options}) + +set(XFIXES_SOURCES cursor.c disconnect.c region.c saveset.c select.c xfixes.c) +list(TRANSFORM XFIXES_SOURCES PREPEND "xserver/xfixes/") +add_library(xserver_xfixes STATIC ${XFIXES_SOURCES}) +target_include_directories(xserver_xfixes PRIVATE ${inc}) +target_compile_options(xserver_xfixes PRIVATE ${compile_options}) + +set(XKB_SOURCES + ddxBeep.c ddxCtrls.c ddxLEDs.c ddxLoad.c maprules.c xkmread.c xkbtext.c xkbfmisc.c xkbout.c + xkb.c xkbUtils.c xkbEvents.c xkbAccessX.c xkbSwap.c xkbLEDs.c xkbInit.c xkbActions.c + xkbPrKeyEv.c XKBMisc.c XKBAlloc.c XKBGAlloc.c XKBMAlloc.c) +list(TRANSFORM XKB_SOURCES PREPEND "xserver/xkb/") +add_library(xserver_xkb STATIC ${XKB_SOURCES}) +target_include_directories(xserver_xkb PRIVATE ${inc}) +target_compile_options(xserver_xkb PRIVATE ${compile_options} "-DXkbFreeGeomOverlayKeys=XkbFreeGeomOverlayKeysInternal") + +set(XKB_STUBS_SOURCES ddxKillSrv.c ddxPrivate.c ddxVT.c) +list(TRANSFORM XKB_STUBS_SOURCES PREPEND "xserver/xkb/") +add_library(xserver_xkb_stubs STATIC ${XKB_STUBS_SOURCES}) +target_include_directories(xserver_xkb_stubs PRIVATE ${inc}) +target_compile_options(xserver_xkb_stubs PRIVATE ${compile_options}) + +set(XEXT_SOURCES + bigreq.c geext.c shape.c sleepuntil.c sync.c xcmisc.c xtest.c dpms.c shm.c hashtable.c + xres.c saver.c xace.c xf86bigfont.c panoramiX.c panoramiXprocs.c panoramiXSwap.c xvmain.c + xvdisp.c xvmc.c vidmode.c) +list(TRANSFORM XEXT_SOURCES PREPEND "xserver/Xext/") +add_library(xserver_xext STATIC ${XEXT_SOURCES}) +target_include_directories(xserver_xext PRIVATE ${inc}) +target_compile_options(xserver_xext PRIVATE ${compile_options}) + +set(XI_SOURCES + allowev.c chgdctl.c chgfctl.c chgkbd.c chgkmap.c chgprop.c chgptr.c closedev.c devbell.c + exevents.c extinit.c getbmap.c getdctl.c getfctl.c getfocus.c getkmap.c getmmap.c getprop.c + getselev.c getvers.c grabdev.c grabdevb.c grabdevk.c gtmotion.c listdev.c opendev.c queryst.c + selectev.c sendexev.c setbmap.c setdval.c setfocus.c setmmap.c setmode.c ungrdev.c ungrdevb.c + ungrdevk.c xiallowev.c xibarriers.c xichangecursor.c xichangehierarchy.c xigetclientpointer.c + xigrabdev.c xipassivegrab.c xiproperty.c xiquerydevice.c xiquerypointer.c xiqueryversion.c + xiselectev.c xisetclientpointer.c xisetdevfocus.c xiwarppointer.c) +list(TRANSFORM XI_SOURCES PREPEND "xserver/Xi/") +add_library(xserver_xi STATIC ${XI_SOURCES}) +target_include_directories(xserver_xi PRIVATE ${inc}) +target_compile_options(xserver_xi PRIVATE ${compile_options}) + +add_library(xserver_xi_stubs STATIC "xserver/Xi/stubs.c") +target_include_directories(xserver_xi_stubs PRIVATE ${inc}) +target_compile_options(xserver_xi_stubs PRIVATE ${compile_options}) + +set(GLX_SOURCES + glxext.c indirect_dispatch.c indirect_dispatch_swap.c indirect_reqsize.c indirect_size_get.c + indirect_table.c clientinfo.c createcontext.c extension_string.c indirect_util.c + indirect_program.c indirect_texture_compression.c glxcmds.c glxcmdsswap.c glxext.c + glxscreens.c render2.c render2swap.c renderpix.c renderpixswap.c rensize.c single2.c + single2swap.c singlepix.c singlepixswap.c singlesize.c swap_interval.c xfont.c) +list(TRANSFORM GLX_SOURCES PREPEND "xserver/glx/") +add_library(xserver_glx STATIC ${GLX_SOURCES} "${CMAKE_CURRENT_BINARY_DIR}/xserver/GL/gl.h") +target_include_directories(xserver_glx PRIVATE ${inc}) +target_compile_options(xserver_glx PRIVATE ${compile_options}) + +set(GLXVND_SOURCES + vndcmds.c vndext.c vndservermapping.c vndservervendor.c) +list(TRANSFORM GLXVND_SOURCES PREPEND "xserver/glx/") +add_library(xserver_glxvnd STATIC ${GLXVND_SOURCES}) +target_include_directories(xserver_glxvnd PRIVATE ${inc}) +target_compile_options(xserver_glxvnd PRIVATE ${compile_options}) + +set(XSERVER_LIBS tirpc Xdmcp Xau pixman Xfont2 fontenc GLESv2 xshmfence xkbcomp) +foreach (part glx glxvnd fb mi dix composite damageext dbe randr miext_damage render present xext + dri3 miext_sync xfixes xi xkb record xi_stubs xkb_stubs os) + set(XSERVER_LIBS ${XSERVER_LIBS} xserver_${part}) +endforeach () + +add_library(Xlorie SHARED + "xserver/mi/miinitext.c" + "xserver/hw/xquartz/keysym2ucs.c" + "libxcvt/lib/libxcvt.c" + "lorie/shm/shmem.c" + "lorie/android.c" + "lorie/clipboard.c" + "lorie/dri3.c" + "lorie/InitOutput.c" + "lorie/InitInput.c" + "lorie/InputXKB.c" + "lorie/renderer.c") +target_include_directories(Xlorie PRIVATE ${inc} "libxcvt/include") +target_link_options(Xlorie PRIVATE "-Wl,--as-needed" "-Wl,--no-undefined" "-fvisibility=hidden") +target_link_libraries(Xlorie "-Wl,--whole-archive" ${XSERVER_LIBS} "-Wl,--no-whole-archive" android log m z EGL GLESv2) +target_compile_options(Xlorie PRIVATE ${compile_options}) +target_apply_patch(Xlorie "${CMAKE_CURRENT_SOURCE_DIR}/xserver" "${CMAKE_CURRENT_SOURCE_DIR}/patches/xserver.patch") +target_apply_patch(Xlorie "${CMAKE_CURRENT_SOURCE_DIR}/libepoxy" "${CMAKE_CURRENT_SOURCE_DIR}/patches/libepoxy.patch") diff --git a/android/app/src/main/cpp/recipes/xshmfence.cmake b/android/app/src/main/cpp/recipes/xshmfence.cmake new file mode 100644 index 0000000..b30cb6c --- /dev/null +++ b/android/app/src/main/cpp/recipes/xshmfence.cmake @@ -0,0 +1,5 @@ +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/values.h" CONTENT "#include ") +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/libxshmfence/src/xshmfence.h" "${CMAKE_CURRENT_BINARY_DIR}/X11/xshmfence.h") +add_library(xshmfence STATIC "libxshmfence/src/xshmfence_alloc.c" "libxshmfence/src/xshmfence_futex.c") +target_include_directories(xshmfence PRIVATE "xorgproto/include" "${CMAKE_CURRENT_BINARY_DIR}") +target_compile_options(xshmfence PRIVATE "-DSHMDIR=\"/\"" "-DHAVE_FUTEX" "-DMAXINT=INT_MAX") diff --git a/android/app/src/main/cpp/xkbcomp b/android/app/src/main/cpp/xkbcomp new file mode 160000 index 0000000..3f354d2 --- /dev/null +++ b/android/app/src/main/cpp/xkbcomp @@ -0,0 +1 @@ +Subproject commit 3f354d20f5bc0276e27faa7fb5f6356319aa32c3 diff --git a/android/app/src/main/cpp/xorgproto b/android/app/src/main/cpp/xorgproto new file mode 160000 index 0000000..3076552 --- /dev/null +++ b/android/app/src/main/cpp/xorgproto @@ -0,0 +1 @@ +Subproject commit 3076552555c32cb89ec20ddef638317f0ea303b9 diff --git a/android/app/src/main/cpp/xrio/android.c b/android/app/src/main/cpp/xrio/android.c new file mode 100644 index 0000000..a5daad5 --- /dev/null +++ b/android/app/src/main/cpp/xrio/android.c @@ -0,0 +1,195 @@ +#include + +#include "engine.h" +#include "input.h" +#include "math.h" +#include "renderer.h" + +struct XrEngine xr_engine; +struct XrInput xr_input; +struct XrRenderer xr_renderer; +bool xr_initialized = false; +int xr_params[6] = {}; + +#if defined(_DEBUG) +#include +void GLCheckErrors(const char* file, int line) { + for (int i = 0; i < 10; i++) { + const GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + break; + } + ALOGE("OpenGL error on line %s:%d %d", file, line, error); + } +} + +void OXRCheckErrors(XrResult result, const char* file, int line) { + if (XR_FAILED(result)) { + char errorBuffer[XR_MAX_RESULT_STRING_SIZE]; + xrResultToString(xr_engine->Instance, result, errorBuffer); + ALOGE("OpenXR error on line %s:%d %s", file, line, errorBuffer); + } +} +#endif + +JNIEXPORT void JNICALL Java_com_termux_x11_XrActivity_init(JNIEnv *env, jobject obj) { + + // Do not allow second initialization + if (xr_initialized) { + return; + } + + // Set platform flags + memset(&xr_engine, 0, sizeof(xr_engine)); + xr_engine.PlatformFlag[PLATFORM_CONTROLLER_QUEST] = true; + xr_engine.PlatformFlag[PLATFORM_EXTENSION_PASSTHROUGH] = true; + xr_engine.PlatformFlag[PLATFORM_EXTENSION_PERFORMANCE] = true; + + // Get Java VM + JavaVM* vm; + (*env)->GetJavaVM(env, &vm); + + // Init XR + xrJava java; + java.vm = vm; + java.activity = (*env)->NewGlobalRef(env, obj); + XrEngineInit(&xr_engine, &java, "termux-x11", 1); + XrEngineEnter(&xr_engine); + XrInputInit(&xr_engine, &xr_input); + XrRendererInit(&xr_engine, &xr_renderer); + XrRendererGetResolution(&xr_engine, &xr_renderer, &xr_params[4], &xr_params[5]); + xr_initialized = true; + ALOGV("Init called"); +} + +JNIEXPORT void JNICALL Java_com_termux_x11_XrActivity_teardown(JNIEnv *env, jobject obj) { + if (!xr_initialized) { + return; + } + + XrRendererDestroy(&xr_engine, &xr_renderer); + XrEngineLeave(&xr_engine); + XrEngineDestroy(&xr_engine); + + memset(&xr_engine, 0, sizeof(xr_engine)); + memset(&xr_input, 0, sizeof(xr_input)); + memset(&xr_renderer, 0, sizeof(xr_renderer)); + xr_initialized = false; +} + +JNIEXPORT jboolean JNICALL Java_com_termux_x11_XrActivity_beginFrame(JNIEnv *env, jobject obj) { + if (XrRendererInitFrame(&xr_engine, &xr_renderer)) { + + // Set renderer + int mode = xr_params[1] ? RENDER_MODE_MONO_6DOF : RENDER_MODE_MONO_SCREEN; + xr_renderer.ConfigFloat[CONFIG_CANVAS_DISTANCE] = xr_params[0]; + xr_renderer.ConfigInt[CONFIG_PASSTHROUGH] = xr_params[2]; + xr_renderer.ConfigInt[CONFIG_MODE] = mode; + xr_renderer.ConfigInt[CONFIG_SBS] = xr_params[3]; + + // Recenter if mode switched + static bool last_immersive = false; + if (last_immersive != xr_params[1]) { + XrRendererRecenter(&xr_engine, &xr_renderer); + last_immersive = xr_params[1]; + } + + // Update controllers state + XrInputUpdate(&xr_engine, &xr_input); + + // Lock framebuffer + XrRendererBeginFrame(&xr_renderer, 0); + + return true; + } + return false; +} + +JNIEXPORT void JNICALL Java_com_termux_x11_XrActivity_finishFrame(JNIEnv *env, jobject obj) { + XrRendererEndFrame(&xr_renderer); + XrRendererFinishFrame(&xr_engine, &xr_renderer); +} + +JNIEXPORT jfloatArray JNICALL Java_com_termux_x11_XrActivity_getAxes(JNIEnv *env, jobject obj) { + XrPosef lPose = XrInputGetPose(&xr_input, 0); + XrPosef rPose = XrInputGetPose(&xr_input, 1); + XrVector2f lThumbstick = XrInputGetJoystickState(&xr_input, 0); + XrVector2f rThumbstick = XrInputGetJoystickState(&xr_input, 1); + XrVector3f lPosition = xr_renderer.Projections[0].pose.position; + XrVector3f rPosition = xr_renderer.Projections[1].pose.position; + XrVector3f angles = xr_renderer.HmdOrientation; + + int count = 0; + float data[32]; + data[count++] = XrQuaternionfEulerAngles(lPose.orientation).x; //L_PITCH + data[count++] = XrQuaternionfEulerAngles(lPose.orientation).y; //L_YAW + data[count++] = XrQuaternionfEulerAngles(lPose.orientation).z; //L_ROLL + data[count++] = lThumbstick.x; //L_THUMBSTICK_X + data[count++] = lThumbstick.y; //L_THUMBSTICK_Y + data[count++] = lPose.position.x; //L_X + data[count++] = lPose.position.y; //L_Y + data[count++] = lPose.position.z; //L_Z + data[count++] = XrQuaternionfEulerAngles(rPose.orientation).x; //R_PITCH + data[count++] = XrQuaternionfEulerAngles(rPose.orientation).y; //R_YAW + data[count++] = XrQuaternionfEulerAngles(rPose.orientation).z; //R_ROLL + data[count++] = rThumbstick.x; //R_THUMBSTICK_X + data[count++] = rThumbstick.y; //R_THUMBSTICK_Y + data[count++] = rPose.position.x; //R_X + data[count++] = rPose.position.y; //R_Y + data[count++] = rPose.position.z; //R_Z + data[count++] = angles.x; //HMD_PITCH + data[count++] = angles.y; //HMD_YAW + data[count++] = angles.z; //HMD_ROLL + data[count++] = (lPosition.x + rPosition.x) * 0.5f; //HMD_X + data[count++] = (lPosition.y + rPosition.y) * 0.5f; //HMD_Y + data[count++] = (lPosition.z + rPosition.z) * 0.5f; //HMD_Z + data[count++] = XrVector3fDistance(lPosition, rPosition); //HMD_IPD + + jfloat values[count]; + memcpy(values, data, count * sizeof(float)); + jfloatArray output = (*env)->NewFloatArray(env, count); + (*env)->SetFloatArrayRegion(env, output, (jsize)0, (jsize)count, values); + return output; +} + +JNIEXPORT jbooleanArray JNICALL Java_com_termux_x11_XrActivity_getButtons(JNIEnv *env, jobject obj) { + uint32_t l = XrInputGetButtonState(&xr_input, 0); + uint32_t r = XrInputGetButtonState(&xr_input, 1); + + int count = 0; + bool data[32]; + data[count++] = l & (int)Grip; //L_GRIP + data[count++] = l & (int)Enter; //L_MENU + data[count++] = l & (int)LThumb; //L_THUMBSTICK_PRESS + data[count++] = l & (int)Left; //L_THUMBSTICK_LEFT + data[count++] = l & (int)Right; //L_THUMBSTICK_RIGHT + data[count++] = l & (int)Up; //L_THUMBSTICK_UP + data[count++] = l & (int)Down; //L_THUMBSTICK_DOWN + data[count++] = l & (int)Trigger; //L_TRIGGER + data[count++] = l & (int)X; //L_X + data[count++] = l & (int)Y; //L_Y + data[count++] = r & (int)A; //R_A + data[count++] = r & (int)B; //R_B + data[count++] = r & (int)Grip; //R_GRIP + data[count++] = r & (int)RThumb; //R_THUMBSTICK_PRESS + data[count++] = r & (int)Left; //R_THUMBSTICK_LEFT + data[count++] = r & (int)Right; //R_THUMBSTICK_RIGHT + data[count++] = r & (int)Up; //R_THUMBSTICK_UP + data[count++] = r & (int)Down; //R_THUMBSTICK_DOWN + data[count++] = r & (int)Trigger; //R_TRIGGER + + jboolean values[count]; + memcpy(values, data, count * sizeof(jboolean)); + jbooleanArray output = (*env)->NewBooleanArray(env, count); + (*env)->SetBooleanArrayRegion(env, output, (jsize)0, (jsize)count, values); + return output; +} + + +JNIEXPORT jint JNICALL Java_com_termux_x11_XrActivity_getRenderParam(JNIEnv *env, jobject obj, jint param) { + return xr_params[param]; +} + +JNIEXPORT void JNICALL Java_com_termux_x11_XrActivity_setRenderParam(JNIEnv *env, jobject obj, jint param, jint value) { + xr_params[param] = value; +} diff --git a/android/app/src/main/cpp/xrio/engine.c b/android/app/src/main/cpp/xrio/engine.c new file mode 100644 index 0000000..307cc36 --- /dev/null +++ b/android/app/src/main/cpp/xrio/engine.c @@ -0,0 +1,190 @@ +#include "engine.h" + +#include +#include +#include + +void XrEngineInit(struct XrEngine* engine, void* system, const char* name, int version) { + if (engine->Initialized) + return; + memset(engine, 0, sizeof(engine)); + +#ifdef ANDROID + PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR; + xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", + (PFN_xrVoidFunction*)&xrInitializeLoaderKHR); + if (xrInitializeLoaderKHR != NULL) { + xrJava* java = (xrJava*)system; + XrLoaderInitInfoAndroidKHR loader_info; + memset(&loader_info, 0, sizeof(loader_info)); + loader_info.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR; + loader_info.next = NULL; + loader_info.applicationVM = java->vm; + loader_info.applicationContext = java->activity; + xrInitializeLoaderKHR((XrLoaderInitInfoBaseHeaderKHR*)&loader_info); + } +#endif + + int count = 0; + const char* extensions[32]; +#ifdef XR_USE_GRAPHICS_API_OPENGL_ES + extensions[count++] = XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME; +#endif +#ifdef ANDROID + if (engine->PlatformFlag[PLATFORM_EXTENSION_INSTANCE]) { + extensions[count++] = XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME; + } + if (engine->PlatformFlag[PLATFORM_EXTENSION_PASSTHROUGH]) { + extensions[count++] = XR_FB_PASSTHROUGH_EXTENSION_NAME; + } + if (engine->PlatformFlag[PLATFORM_EXTENSION_PERFORMANCE]) { + extensions[count++] = XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME; + extensions[count++] = XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME; + } +#endif + + // Create the OpenXR instance. + XrApplicationInfo app_info; + memset(&app_info, 0, sizeof(app_info)); + strcpy(app_info.applicationName, name); + strcpy(app_info.engineName, name); + app_info.applicationVersion = version; + app_info.engineVersion = version; + app_info.apiVersion = XR_API_VERSION_1_0; + + XrInstanceCreateInfo instance_info; + memset(&instance_info, 0, sizeof(instance_info)); + instance_info.type = XR_TYPE_INSTANCE_CREATE_INFO; + instance_info.next = NULL; + instance_info.createFlags = 0; + instance_info.applicationInfo = app_info; + instance_info.enabledApiLayerCount = 0; + instance_info.enabledApiLayerNames = NULL; + instance_info.enabledExtensionCount = count; + instance_info.enabledExtensionNames = extensions; + +#ifdef ANDROID + XrInstanceCreateInfoAndroidKHR instance_info_android = {XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR}; + if (engine->PlatformFlag[PLATFORM_EXTENSION_INSTANCE]) { + xrJava* java = (xrJava*)system; + instance_info_android.applicationVM = java->vm; + instance_info_android.applicationActivity = java->activity; + instance_info.next = (XrBaseInStructure*)&instance_info_android; + } +#endif + + XrResult result; + OXR(result = xrCreateInstance(&instance_info, &engine->Instance)); + if (result != XR_SUCCESS) { + ALOGE("Failed to create XR instance: %d", (int)result); + exit(1); + } + + XrInstanceProperties instance_properties; + instance_properties.type = XR_TYPE_INSTANCE_PROPERTIES; + instance_properties.next = NULL; + OXR(xrGetInstanceProperties(engine->Instance, &instance_properties)); + ALOGV("Runtime %s: Version : %d.%d.%d", instance_properties.runtimeName, + XR_VERSION_MAJOR(instance_properties.runtimeVersion), + XR_VERSION_MINOR(instance_properties.runtimeVersion), + XR_VERSION_PATCH(instance_properties.runtimeVersion)); + + XrSystemGetInfo system_info; + memset(&system_info, 0, sizeof(system_info)); + system_info.type = XR_TYPE_SYSTEM_GET_INFO; + system_info.next = NULL; + system_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; + + OXR(result = xrGetSystem(engine->Instance, &system_info, &engine->SystemId)); + if (result != XR_SUCCESS) { + ALOGE("Failed to get system"); + exit(1); + } + + // Get the graphics requirements. +#ifdef XR_USE_GRAPHICS_API_OPENGL_ES + PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = NULL; + OXR(xrGetInstanceProcAddr(engine->Instance, "xrGetOpenGLESGraphicsRequirementsKHR", + (PFN_xrVoidFunction*)(&pfnGetOpenGLESGraphicsRequirementsKHR))); + + XrGraphicsRequirementsOpenGLESKHR graphics_requirements = {}; + graphics_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR; + OXR(pfnGetOpenGLESGraphicsRequirementsKHR(engine->Instance, engine->SystemId, &graphics_requirements)); +#endif + +#ifdef ANDROID + engine->MainThreadId = gettid(); +#endif + engine->Initialized = true; +} + +void XrEngineDestroy(struct XrEngine* engine) { + if (engine->Initialized) { + xrDestroyInstance(engine->Instance); + engine->Initialized = false; + } +} + +void XrEngineEnter(struct XrEngine* engine) { + if (engine->Session) { + ALOGE("EnterXR called with existing session"); + return; + } + + // Create the OpenXR Session. + XrSessionCreateInfo session_info; + memset(&session_info, 0, sizeof(session_info)); +#ifdef XR_USE_GRAPHICS_API_OPENGL_ES + XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl = {}; + graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR; + graphics_binding_gl.next = NULL; + graphics_binding_gl.display = eglGetCurrentDisplay(); + graphics_binding_gl.config = NULL; + graphics_binding_gl.context = eglGetCurrentContext(); + session_info.next = &graphics_binding_gl; +#endif + session_info.type = XR_TYPE_SESSION_CREATE_INFO; + session_info.createFlags = 0; + session_info.systemId = engine->SystemId; + + XrResult result; + OXR(result = xrCreateSession(engine->Instance, &session_info, &engine->Session)); + if (result != XR_SUCCESS) { + ALOGE("Failed to create XR session: %d", (int)result); + exit(1); + } + + // Create a space to the first path + XrReferenceSpaceCreateInfo space_info = {}; + space_info.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO; + space_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW; + space_info.poseInReferenceSpace.orientation.w = 1.0f; + OXR(xrCreateReferenceSpace(engine->Session, &space_info, &engine->HeadSpace)); +} + +void XrEngineLeave(struct XrEngine* engine) { + if (engine->Session) { + OXR(xrDestroySpace(engine->HeadSpace)); + // StageSpace is optional. + if (engine->StageSpace != XR_NULL_HANDLE) { + OXR(xrDestroySpace(engine->StageSpace)); + } + OXR(xrDestroySpace(engine->FakeSpace)); + engine->CurrentSpace = XR_NULL_HANDLE; + OXR(xrDestroySession(engine->Session)); + engine->Session = XR_NULL_HANDLE; + } +} + +void XrEngineWaitForFrame(struct XrEngine* engine) { + XrFrameWaitInfo wait_frame_info = {}; + wait_frame_info.type = XR_TYPE_FRAME_WAIT_INFO; + wait_frame_info.next = NULL; + + XrFrameState frame_state = {}; + frame_state.type = XR_TYPE_FRAME_STATE; + frame_state.next = NULL; + + OXR(xrWaitFrame(engine->Session, &wait_frame_info, &frame_state)); + engine->PredictedDisplayTime = frame_state.predictedDisplayTime; +} diff --git a/android/app/src/main/cpp/xrio/engine.h b/android/app/src/main/cpp/xrio/engine.h new file mode 100644 index 0000000..7c15a0c --- /dev/null +++ b/android/app/src/main/cpp/xrio/engine.h @@ -0,0 +1,90 @@ +#pragma once + +#include + +//#define _DEBUG + +#if defined(_DEBUG) +void GLCheckErrors(const char* file, int line); +void OXRCheckErrors(XrResult result, const char* file, int line); + +#define GL(func) func; GLCheckErrors(__FILE__ , __LINE__); +#define OXR(func) OXRCheckErrors(func, __FILE__ , __LINE__); +#else +#define GL(func) func; +#define OXR(func) func; +#endif + +#ifdef ANDROID +#include +#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, "OpenXR", __VA_ARGS__); +#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "OpenXR", __VA_ARGS__); + +#include +#include +#include +#define XR_USE_PLATFORM_ANDROID 1 +#define XR_USE_GRAPHICS_API_OPENGL_ES 1 +#else +#include +#define ALOGE(...) printf(__VA_ARGS__) +#define ALOGV(...) printf(__VA_ARGS__) +#endif + +#include +#include + +enum { + XrMaxLayerCount = 2 +}; +enum { + XrMaxNumEyes = 2 +}; + +enum XrPlatformFlag { + PLATFORM_CONTROLLER_PICO, + PLATFORM_CONTROLLER_QUEST, + PLATFORM_EXTENSION_INSTANCE, + PLATFORM_EXTENSION_PASSTHROUGH, + PLATFORM_EXTENSION_PERFORMANCE, + PLATFORM_TRACKING_FLOOR, + PLATFORM_MAX +}; + +typedef union { + XrCompositionLayerProjection projection; + XrCompositionLayerQuad quad; +} XrCompositorLayer; + +#ifdef ANDROID +typedef struct { + jobject activity; + JNIEnv* env; + JavaVM* vm; +} xrJava; +#endif + +struct XrEngine { + XrInstance Instance; + XrSession Session; + XrSystemId SystemId; + + XrSpace CurrentSpace; + XrSpace FakeSpace; + XrSpace HeadSpace; + XrSpace StageSpace; + + XrTime PredictedDisplayTime; + + int MainThreadId; + int RenderThreadId; + + bool PlatformFlag[PLATFORM_MAX]; + bool Initialized; +}; + +void XrEngineInit(struct XrEngine* engine, void* system, const char* name, int version); +void XrEngineDestroy(struct XrEngine* engine); +void XrEngineEnter(struct XrEngine* engine); +void XrEngineLeave(struct XrEngine* engine); +void XrEngineWaitForFrame(struct XrEngine* engine); diff --git a/android/app/src/main/cpp/xrio/framebuffer.c b/android/app/src/main/cpp/xrio/framebuffer.c new file mode 100644 index 0000000..ac27bda --- /dev/null +++ b/android/app/src/main/cpp/xrio/framebuffer.c @@ -0,0 +1,127 @@ +#include "framebuffer.h" + +#if XR_USE_GRAPHICS_API_OPENGL_ES +#include +#include +#endif + +#include +#include + +bool XrFramebufferCreate(struct XrFramebuffer *framebuffer, XrSession session, int width, int height) { + memset(framebuffer, 0, sizeof(framebuffer)); +#if XR_USE_GRAPHICS_API_OPENGL_ES + return XrFramebufferCreateGL(framebuffer, session, width, height); +#else + return false; +#endif +} + +void XrFramebufferDestroy(struct XrFramebuffer *framebuffer) { +#if XR_USE_GRAPHICS_API_OPENGL_ES + GL(glDeleteRenderbuffers(framebuffer->SwapchainLength, framebuffer->GLDepthBuffers)); + GL(glDeleteFramebuffers(framebuffer->SwapchainLength, framebuffer->GLFrameBuffers)); + free(framebuffer->GLDepthBuffers); + free(framebuffer->GLFrameBuffers); +#endif + OXR(xrDestroySwapchain(framebuffer->Handle)); + free(framebuffer->SwapchainImage); +} + +void XrFramebufferAcquire(struct XrFramebuffer *framebuffer) { + XrSwapchainImageAcquireInfo acquire_info = {XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO, NULL}; + OXR(xrAcquireSwapchainImage(framebuffer->Handle, &acquire_info, &framebuffer->SwapchainIndex)); + + XrSwapchainImageWaitInfo wait_info; + wait_info.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO; + wait_info.next = NULL; + wait_info.timeout = 1000000; /* timeout in nanoseconds */ + XrResult res = xrWaitSwapchainImage(framebuffer->Handle, &wait_info); + int i = 0; + while ((res != XR_SUCCESS) && (i < 10)) { + res = xrWaitSwapchainImage(framebuffer->Handle, &wait_info); + i++; + ALOGV("Retry xrWaitSwapchainImage %d times due XR_TIMEOUT_EXPIRED (duration %lf ms", + i, wait_info.timeout * (1E-9)); + } + + framebuffer->Acquired = res == XR_SUCCESS; + XrFramebufferSetCurrent(framebuffer); +} + +void XrFramebufferRelease(struct XrFramebuffer *framebuffer) { + if (framebuffer->Acquired) { + XrSwapchainImageReleaseInfo release_info = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL}; + OXR(xrReleaseSwapchainImage(framebuffer->Handle, &release_info)); + framebuffer->Acquired = false; + } +} + +void XrFramebufferSetCurrent(struct XrFramebuffer *framebuffer) { +#if XR_USE_GRAPHICS_API_OPENGL_ES + GL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->GLFrameBuffers[framebuffer->SwapchainIndex])); +#endif +} + +#if XR_USE_GRAPHICS_API_OPENGL_ES +bool XrFramebufferCreateGL(struct XrFramebuffer *framebuffer, XrSession session, int width, int height) { + XrSwapchainCreateInfo swapchain_info; + memset(&swapchain_info, 0, sizeof(swapchain_info)); + swapchain_info.type = XR_TYPE_SWAPCHAIN_CREATE_INFO; + swapchain_info.sampleCount = 1; + swapchain_info.width = width; + swapchain_info.height = height; + swapchain_info.faceCount = 1; + swapchain_info.mipCount = 1; + swapchain_info.arraySize = 1; + + framebuffer->Width = swapchain_info.width; + framebuffer->Height = swapchain_info.height; + + // Create the color swapchain. + swapchain_info.format = GL_SRGB8_ALPHA8_EXT; + swapchain_info.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT; + OXR(xrCreateSwapchain(session, &swapchain_info, &framebuffer->Handle)); + OXR(xrEnumerateSwapchainImages(framebuffer->Handle, 0, &framebuffer->SwapchainLength, NULL)); + framebuffer->SwapchainImage = malloc(framebuffer->SwapchainLength * sizeof(XrSwapchainImageOpenGLESKHR)); + + // Populate the swapchain image array. + for (uint32_t i = 0; i < framebuffer->SwapchainLength; i++) { + XrSwapchainImageOpenGLESKHR* swapchain = (XrSwapchainImageOpenGLESKHR*)framebuffer->SwapchainImage; + swapchain[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR; + swapchain[i].next = NULL; + } + OXR(xrEnumerateSwapchainImages(framebuffer->Handle, framebuffer->SwapchainLength, + &framebuffer->SwapchainLength, + (XrSwapchainImageBaseHeader*)framebuffer->SwapchainImage)); + + framebuffer->GLDepthBuffers = (GLuint*)malloc(framebuffer->SwapchainLength * sizeof(GLuint)); + framebuffer->GLFrameBuffers = (GLuint*)malloc(framebuffer->SwapchainLength * sizeof(GLuint)); + for (uint32_t i = 0; i < framebuffer->SwapchainLength; i++) { + // Create color and depth buffers. + GLuint color_texture = ((XrSwapchainImageOpenGLESKHR*)framebuffer->SwapchainImage)[i].image; + GL(glGenRenderbuffers(1, &framebuffer->GLDepthBuffers[i])); + GL(glBindRenderbuffer(GL_RENDERBUFFER, framebuffer->GLDepthBuffers[i])); + GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height)); + GL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + // Create the frame buffer. + GL(glGenFramebuffers(1, &framebuffer->GLFrameBuffers[i])); + GL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->GLFrameBuffers[i])); + GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + framebuffer->GLDepthBuffers[i])); + GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + framebuffer->GLDepthBuffers[i])); + GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + color_texture, 0)); + GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER)); + GL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) { + ALOGE("Incomplete frame buffer object: %d", renderFramebufferStatus); + return false; + } + } + + return true; +} +#endif diff --git a/android/app/src/main/cpp/xrio/framebuffer.h b/android/app/src/main/cpp/xrio/framebuffer.h new file mode 100644 index 0000000..5983b16 --- /dev/null +++ b/android/app/src/main/cpp/xrio/framebuffer.h @@ -0,0 +1,28 @@ +#pragma once + +#include "engine.h" + +struct XrFramebuffer { + int Width; + int Height; + bool Acquired; + XrSwapchain Handle; + + uint32_t SwapchainIndex; + uint32_t SwapchainLength; + void* SwapchainImage; + + unsigned int* GLDepthBuffers; + unsigned int* GLFrameBuffers; +}; + +bool XrFramebufferCreate(struct XrFramebuffer *framebuffer, XrSession session, int width, int height); +void XrFramebufferDestroy(struct XrFramebuffer *framebuffer); + +void XrFramebufferAcquire(struct XrFramebuffer *framebuffer); +void XrFramebufferRelease(struct XrFramebuffer *framebuffer); +void XrFramebufferSetCurrent(struct XrFramebuffer *framebuffer); + +#if XR_USE_GRAPHICS_API_OPENGL_ES +bool XrFramebufferCreateGL(struct XrFramebuffer *framebuffer, XrSession session, int width, int height); +#endif diff --git a/android/app/src/main/cpp/xrio/input.c b/android/app/src/main/cpp/xrio/input.c new file mode 100644 index 0000000..cec79f8 --- /dev/null +++ b/android/app/src/main/cpp/xrio/input.c @@ -0,0 +1,404 @@ +#include "input.h" +#include "math.h" + +#include +#include + +void XrInputInit(struct XrEngine* engine, struct XrInput* input) { + if (input->Initialized) + return; + memset(input, 0, sizeof(input)); + + // Actions + input->ActionSet = XrInputCreateActionSet(engine->Instance, "running_action_set", "Actionset"); + input->IndexLeft = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_left", "Index left", 0, NULL); + input->IndexRight = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_right","Index right", 0, NULL); + input->ButtonMenu = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "menu_action", "ButtonMenu", 0, NULL); + input->ButtonA = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_a", "XrButton A", 0, NULL); + input->ButtonB = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_b", "XrButton B", 0, NULL); + input->ButtonX = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_x", "XrButton X", 0, NULL); + input->ButtonY = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_y", "XrButton Y", 0, NULL); + input->GripLeft = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_left", "Grip left", 0, NULL); + input->GripRight = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_right", "Grip right", 0, NULL); + input->JoystickLeft = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_left_joy","Move on left Joy", 0, NULL); + input->JoystickRight = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_right_joy","Move on right Joy", 0, NULL); + input->ThumbLeft = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_left","Thumbstick left", 0, NULL); + input->ThumbRight = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_right","Thumbstick right", 0, NULL); + input->VibrateLeftFeedback = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_left_feedback","Vibrate Left Controller", 0, NULL); + input->VibrateRightFeedback = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_right_feedback","Vibrate Right Controller", 0, NULL); + + OXR(xrStringToPath(engine->Instance, "/user/hand/left", &input->LeftHandPath)); + OXR(xrStringToPath(engine->Instance, "/user/hand/right", &input->RightHandPath)); + input->HandPoseLeft = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_left", NULL,1, &input->LeftHandPath); + input->HandPoseRight = XrInputCreateAction(input->ActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_right", NULL,1, &input->RightHandPath); + + XrPath interactionProfilePath = XR_NULL_PATH; + if (engine->PlatformFlag[PLATFORM_CONTROLLER_QUEST]) { + OXR(xrStringToPath(engine->Instance, "/interaction_profiles/oculus/touch_controller",&interactionProfilePath)); + } else if (engine->PlatformFlag[PLATFORM_CONTROLLER_PICO]) { + OXR(xrStringToPath(engine->Instance, "/interaction_profiles/pico/neo3_controller",&interactionProfilePath)); + } + + // Map bindings + XrInstance instance = engine->Instance; + XrActionSuggestedBinding bindings[32]; // large enough for all profiles + int curr = 0; + + if (engine->PlatformFlag[PLATFORM_CONTROLLER_QUEST]) { + bindings[curr++] = XrInputGetBinding(instance, input->IndexLeft, "/user/hand/left/input/trigger"); + bindings[curr++] = XrInputGetBinding(instance, input->IndexRight, "/user/hand/right/input/trigger"); + bindings[curr++] = XrInputGetBinding(instance, input->ButtonMenu, "/user/hand/left/input/menu/click"); + } else if (engine->PlatformFlag[PLATFORM_CONTROLLER_PICO]) { + bindings[curr++] = XrInputGetBinding(instance, input->IndexLeft, "/user/hand/left/input/trigger/click"); + bindings[curr++] = XrInputGetBinding(instance, input->IndexRight, "/user/hand/right/input/trigger/click"); + bindings[curr++] = XrInputGetBinding(instance, input->ButtonMenu, "/user/hand/left/input/back/click"); + bindings[curr++] = XrInputGetBinding(instance, input->ButtonMenu, "/user/hand/right/input/back/click"); + } + bindings[curr++] = XrInputGetBinding(instance, input->ButtonX, "/user/hand/left/input/x/click"); + bindings[curr++] = XrInputGetBinding(instance, input->ButtonY, "/user/hand/left/input/y/click"); + bindings[curr++] = XrInputGetBinding(instance, input->ButtonA, "/user/hand/right/input/a/click"); + bindings[curr++] = XrInputGetBinding(instance, input->ButtonB, "/user/hand/right/input/b/click"); + bindings[curr++] = XrInputGetBinding(instance, input->GripLeft, "/user/hand/left/input/squeeze/value"); + bindings[curr++] = XrInputGetBinding(instance, input->GripRight, "/user/hand/right/input/squeeze/value"); + bindings[curr++] = XrInputGetBinding(instance, input->JoystickLeft, "/user/hand/left/input/thumbstick"); + bindings[curr++] = XrInputGetBinding(instance, input->JoystickRight, "/user/hand/right/input/thumbstick"); + bindings[curr++] = XrInputGetBinding(instance, input->ThumbLeft, "/user/hand/left/input/thumbstick/click"); + bindings[curr++] = XrInputGetBinding(instance, input->ThumbRight, "/user/hand/right/input/thumbstick/click"); + bindings[curr++] = XrInputGetBinding(instance, input->VibrateLeftFeedback, "/user/hand/left/output/haptic"); + bindings[curr++] = XrInputGetBinding(instance, input->VibrateRightFeedback, "/user/hand/right/output/haptic"); + bindings[curr++] = XrInputGetBinding(instance, input->HandPoseLeft, "/user/hand/left/input/aim/pose"); + bindings[curr++] = XrInputGetBinding(instance, input->HandPoseRight, "/user/hand/right/input/aim/pose"); + + XrInteractionProfileSuggestedBinding suggested_bindings = {}; + suggested_bindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING; + suggested_bindings.next = NULL; + suggested_bindings.interactionProfile = interactionProfilePath; + suggested_bindings.suggestedBindings = bindings; + suggested_bindings.countSuggestedBindings = curr; + OXR(xrSuggestInteractionProfileBindings(engine->Instance, &suggested_bindings)); + + // Attach actions + XrSessionActionSetsAttachInfo attach_info = {}; + attach_info.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO; + attach_info.next = NULL; + attach_info.countActionSets = 1; + attach_info.actionSets = &input->ActionSet; + OXR(xrAttachSessionActionSets(engine->Session, &attach_info)); + + // Enumerate actions + char string_buffer[256]; + XrPath action_paths_buffer[32]; + XrAction actions_to_enumerate[] = {input->IndexLeft, + input->IndexRight, + input->ButtonMenu, + input->ButtonA, + input->ButtonB, + input->ButtonX, + input->ButtonY, + input->GripLeft, + input->GripRight, + input->JoystickLeft, + input->JoystickRight, + input->ThumbLeft, + input->ThumbRight, + input->VibrateLeftFeedback, + input->VibrateRightFeedback, + input->HandPoseLeft, + input->HandPoseRight}; + for (int i = 0; i < sizeof(actions_to_enumerate) / sizeof(XrAction); i++) { + XrBoundSourcesForActionEnumerateInfo e = {}; + e.type = XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO; + e.next = NULL; + e.action = actions_to_enumerate[i]; + + // Get Count + uint32_t count_output = 0; + OXR(xrEnumerateBoundSourcesForAction(engine->Session, &e, 0, &count_output, NULL)); + + if (count_output < 32) { + OXR(xrEnumerateBoundSourcesForAction(engine->Session, &e, 32, &count_output, + action_paths_buffer)); + for (uint32_t a = 0; a < count_output; ++a) { + XrInputSourceLocalizedNameGetInfo name_info = {}; + name_info.type = XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO; + name_info.next = NULL; + name_info.sourcePath = action_paths_buffer[a]; + name_info.whichComponents = XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT | + XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT | + XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT; + + uint32_t str_count = 0u; + OXR(xrGetInputSourceLocalizedName(engine->Session, &name_info, 0, &str_count, NULL)); + if (str_count < 256) { + OXR(xrGetInputSourceLocalizedName(engine->Session, &name_info, 256, &str_count, + string_buffer)); + char path_str[256]; + uint32_t str_len = 0; + OXR(xrPathToString(engine->Instance, action_paths_buffer[a], + (uint32_t)sizeof(path_str), &str_len, path_str)); + ALOGV("mapped %s -> %s", path_str, string_buffer); + } + } + } + } + input->Initialized = true; +} + +uint32_t XrInputGetButtonState(struct XrInput* input, int controller) { + switch (controller) { + case 0: + return input->ButtonsLeft; + case 1: + return input->ButtonsRight; + default: + return 0; + } +} + +XrVector2f XrInputGetJoystickState(struct XrInput* input, int controller) { + return input->JoystickState[controller].currentState; +} + +XrPosef XrInputGetPose(struct XrInput* input, int controller) { + return input->ControllerPose[controller].pose; +} + +void XrInputUpdate(struct XrEngine* engine, struct XrInput* input) { + // sync action data + XrActiveActionSet activeActionSet = {}; + activeActionSet.actionSet = input->ActionSet; + activeActionSet.subactionPath = XR_NULL_PATH; + + XrActionsSyncInfo sync_info = {}; + sync_info.type = XR_TYPE_ACTIONS_SYNC_INFO; + sync_info.next = NULL; + sync_info.countActiveActionSets = 1; + sync_info.activeActionSets = &activeActionSet; + OXR(xrSyncActions(engine->Session, &sync_info)); + + // query input action states + XrActionStateGetInfo get_info = {}; + get_info.type = XR_TYPE_ACTION_STATE_GET_INFO; + get_info.next = NULL; + get_info.subactionPath = XR_NULL_PATH; + + XrSession session = engine->Session; + XrInputProcessHaptics(input, session); + + if (input->LeftControllerSpace == XR_NULL_HANDLE) { + input->LeftControllerSpace = XrInputCreateActionSpace(session, input->HandPoseLeft, input->LeftHandPath); + } + if (input->RightControllerSpace == XR_NULL_HANDLE) { + input->RightControllerSpace = XrInputCreateActionSpace(session, input->HandPoseRight, input->RightHandPath); + } + + // button mapping + input->ButtonsLeft = 0; + if (XrInputGetActionStateBoolean(session, input->ButtonMenu).currentState) + input->ButtonsLeft |= (int)Enter; + if (XrInputGetActionStateBoolean(session, input->ButtonX).currentState) + input->ButtonsLeft |= (int)X; + if (XrInputGetActionStateBoolean(session, input->ButtonY).currentState) + input->ButtonsLeft |= (int)Y; + if (XrInputGetActionStateBoolean(session, input->IndexLeft).currentState) + input->ButtonsLeft |= (int)Trigger; + if (XrInputGetActionStateFloat(session, input->GripLeft).currentState > 0.5f) + input->ButtonsLeft |= (int)Grip; + if (XrInputGetActionStateBoolean(session, input->ThumbLeft).currentState) + input->ButtonsLeft |= (int)LThumb; + input->ButtonsRight = 0; + if (XrInputGetActionStateBoolean(session, input->ButtonA).currentState) + input->ButtonsRight |= (int)A; + if (XrInputGetActionStateBoolean(session, input->ButtonB).currentState) + input->ButtonsRight |= (int)B; + if (XrInputGetActionStateBoolean(session, input->IndexRight).currentState) + input->ButtonsRight |= (int)Trigger; + if (XrInputGetActionStateFloat(session, input->GripRight).currentState > 0.5f) + input->ButtonsRight |= (int)Grip; + if (XrInputGetActionStateBoolean(session, input->ThumbRight).currentState) + input->ButtonsRight |= (int)RThumb; + + // thumbstick + input->JoystickState[0] = XrInputGetActionStateVector2(session, input->JoystickLeft); + input->JoystickState[1] = XrInputGetActionStateVector2(session, input->JoystickRight); + if (input->JoystickState[0].currentState.x > 0.5) + input->ButtonsLeft |= (int)Right; + if (input->JoystickState[0].currentState.x < -0.5) + input->ButtonsLeft |= (int)Left; + if (input->JoystickState[0].currentState.y > 0.5) + input->ButtonsLeft |= (int)Up; + if (input->JoystickState[0].currentState.y < -0.5) + input->ButtonsLeft |= (int)Down; + if (input->JoystickState[1].currentState.x > 0.5) + input->ButtonsRight |= (int)Right; + if (input->JoystickState[1].currentState.x < -0.5) + input->ButtonsRight |= (int)Left; + if (input->JoystickState[1].currentState.y > 0.5) + input->ButtonsRight |= (int)Up; + if (input->JoystickState[1].currentState.y < -0.5) + input->ButtonsRight |= (int)Down; + + // pose + for (int i = 0; i < 2; i++) { + memset(&input->ControllerPose[i], 0, sizeof(input->ControllerPose[i])); + input->ControllerPose[i].type = XR_TYPE_SPACE_LOCATION; + XrSpace aim_space[] = {input->LeftControllerSpace, input->RightControllerSpace}; + xrLocateSpace(aim_space[i], engine->CurrentSpace, + (XrTime)(engine->PredictedDisplayTime), &input->ControllerPose[i]); + } +} + +void XrInputVibrate(struct XrInput* input, int duration, int chan, float intensity) { + for (int i = 0; i < 2; ++i) { + int channel = i & chan; + if (channel) { + if (input->VibrationChannelDuration[channel] > 0.0f) + return; + + if (input->VibrationChannelDuration[channel] == -1.0f && duration != 0.0f) + return; + + input->VibrationChannelDuration[channel] = (float)duration; + input->VibrationChannelIntensity[channel] = intensity; + } + } +} + +XrAction XrInputCreateAction(XrActionSet output_set, XrActionType type, const char* name, + const char* desc, int count_subaction_path, XrPath* subaction_path) { + XrActionCreateInfo action_info = {}; + action_info.type = XR_TYPE_ACTION_CREATE_INFO; + action_info.next = NULL; + action_info.actionType = type; + if (count_subaction_path > 0) { + action_info.countSubactionPaths = count_subaction_path; + action_info.subactionPaths = subaction_path; + } + strcpy(action_info.actionName, name); + strcpy(action_info.localizedActionName, desc ? desc : name); + XrAction output = XR_NULL_HANDLE; + OXR(xrCreateAction(output_set, &action_info, &output)); + return output; +} + +XrActionSet XrInputCreateActionSet(XrInstance instance, const char* name, const char* desc) { + XrActionSetCreateInfo action_set_info = {}; + action_set_info.type = XR_TYPE_ACTION_SET_CREATE_INFO; + action_set_info.next = NULL; + action_set_info.priority = 1; + strcpy(action_set_info.actionSetName, name); + strcpy(action_set_info.localizedActionSetName, desc); + XrActionSet output = XR_NULL_HANDLE; + OXR(xrCreateActionSet(instance, &action_set_info, &output)); + return output; +} + +XrSpace XrInputCreateActionSpace(XrSession session, XrAction action, XrPath subaction_path) { + XrActionSpaceCreateInfo action_space_info = {}; + action_space_info.type = XR_TYPE_ACTION_SPACE_CREATE_INFO; + action_space_info.action = action; + action_space_info.poseInActionSpace.orientation.w = 1.0f; + action_space_info.subactionPath = subaction_path; + XrSpace output = XR_NULL_HANDLE; + OXR(xrCreateActionSpace(session, &action_space_info, &output)); + return output; +} + +XrActionStateBoolean XrInputGetActionStateBoolean(XrSession session, XrAction action) { + XrActionStateGetInfo get_info = {}; + get_info.type = XR_TYPE_ACTION_STATE_GET_INFO; + get_info.action = action; + + XrActionStateBoolean state = {}; + state.type = XR_TYPE_ACTION_STATE_BOOLEAN; + + OXR(xrGetActionStateBoolean(session, &get_info, &state)); + return state; +} + +XrActionStateFloat XrInputGetActionStateFloat(XrSession session, XrAction action) { + XrActionStateGetInfo get_info = {}; + get_info.type = XR_TYPE_ACTION_STATE_GET_INFO; + get_info.action = action; + + XrActionStateFloat state = {}; + state.type = XR_TYPE_ACTION_STATE_FLOAT; + + OXR(xrGetActionStateFloat(session, &get_info, &state)); + return state; +} + +XrActionStateVector2f XrInputGetActionStateVector2(XrSession session, XrAction action) { + XrActionStateGetInfo get_info = {}; + get_info.type = XR_TYPE_ACTION_STATE_GET_INFO; + get_info.action = action; + + XrActionStateVector2f state = {}; + state.type = XR_TYPE_ACTION_STATE_VECTOR2F; + + OXR(xrGetActionStateVector2f(session, &get_info, &state)); + return state; +} + +XrActionSuggestedBinding XrInputGetBinding(XrInstance instance, XrAction action, const char* name) { + XrPath bindingPath; + OXR(xrStringToPath(instance, name, &bindingPath)); + + XrActionSuggestedBinding output; + output.action = action; + output.binding = bindingPath; + return output; +} + +int XrInputGetMilliseconds(struct XrInput* input) { + struct timeval tp; + + gettimeofday(&tp, NULL); + + if (!input->SysTimeBase) { + input->SysTimeBase = tp.tv_sec; + return tp.tv_usec / 1000; + } + + return (tp.tv_sec - input->SysTimeBase) * 1000 + tp.tv_usec / 1000; +} + +void XrInputProcessHaptics(struct XrInput* input, XrSession session) { + static float last_frame_timestamp = 0.0f; + float timestamp = (float)(XrInputGetMilliseconds(input)); + float frametime = timestamp - last_frame_timestamp; + last_frame_timestamp = timestamp; + + for (int i = 0; i < 2; ++i) { + if (input->VibrationChannelDuration[i] > 0.0f || input->VibrationChannelDuration[i] == -1.0f) { + // fire haptics using output action + XrHapticVibration vibration = {}; + vibration.type = XR_TYPE_HAPTIC_VIBRATION; + vibration.next = NULL; + vibration.amplitude = input->VibrationChannelIntensity[i]; + vibration.duration = ToXrTime(input->VibrationChannelDuration[i]); + vibration.frequency = 3000; + XrHapticActionInfo haptic_info = {}; + haptic_info.type = XR_TYPE_HAPTIC_ACTION_INFO; + haptic_info.next = NULL; + haptic_info.action = i == 0 ? input->VibrateLeftFeedback : input->VibrateRightFeedback; + OXR(xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader*)&vibration)); + + if (input->VibrationChannelDuration[i] != -1.0f) { + input->VibrationChannelDuration[i] -= frametime; + + if (input->VibrationChannelDuration[i] < 0.0f) { + input->VibrationChannelDuration[i] = 0.0f; + input->VibrationChannelIntensity[i] = 0.0f; + } + } + } else { + // Stop haptics + XrHapticActionInfo haptic_info = {}; + haptic_info.type = XR_TYPE_HAPTIC_ACTION_INFO; + haptic_info.next = NULL; + haptic_info.action = i == 0 ? input->VibrateLeftFeedback : input->VibrateRightFeedback; + OXR(xrStopHapticFeedback(session, &haptic_info)); + } + } +} diff --git a/android/app/src/main/cpp/xrio/input.h b/android/app/src/main/cpp/xrio/input.h new file mode 100644 index 0000000..090a14d --- /dev/null +++ b/android/app/src/main/cpp/xrio/input.h @@ -0,0 +1,82 @@ +#pragma once + +#include "engine.h" + +enum XrButton { + A = 0x00000001, // Set for trigger pulled on the Gear VR and Go Controllers + B = 0x00000002, + RThumb = 0x00000004, + + X = 0x00000100, + Y = 0x00000200, + LThumb = 0x00000400, + + Up = 0x00010000, + Down = 0x00020000, + Left = 0x00040000, + Right = 0x00080000, + Enter = 0x00100000, //< Set for touchpad click on the Go Controller, menu + // button on Left Quest Controller + Back = 0x00200000, //< Back button on the Go Controller (only set when + // a short press comes up) + Grip = 0x04000000, //< grip trigger engaged + Trigger = 0x20000000 //< Index Trigger engaged +}; + +struct XrInput { + + bool Initialized; + + // OpenXR controller mapping + XrActionSet ActionSet; + XrPath LeftHandPath; + XrPath RightHandPath; + XrAction HandPoseLeft; + XrAction HandPoseRight; + XrAction IndexLeft; + XrAction IndexRight; + XrAction ButtonMenu; + XrAction ButtonA; + XrAction ButtonB; + XrAction ButtonX; + XrAction ButtonY; + XrAction GripLeft; + XrAction GripRight; + XrAction JoystickLeft; + XrAction JoystickRight; + XrAction ThumbLeft; + XrAction ThumbRight; + XrAction VibrateLeftFeedback; + XrAction VibrateRightFeedback; + XrSpace LeftControllerSpace; + XrSpace RightControllerSpace; + + // Controller state + uint32_t ButtonsLeft; + uint32_t ButtonsRight; + XrSpaceLocation ControllerPose[2]; + XrActionStateVector2f JoystickState[2]; + float VibrationChannelDuration[2]; + float VibrationChannelIntensity[2]; + + // Timer + unsigned long SysTimeBase; +}; + +void XrInputInit(struct XrEngine* engine, struct XrInput* input); +uint32_t XrInputGetButtonState(struct XrInput* input, int controller); +XrVector2f XrInputGetJoystickState(struct XrInput* input, int controller); +XrPosef XrInputGetPose(struct XrInput* input, int controller); +void XrInputUpdate(struct XrEngine* engine, struct XrInput* input); +void XrInputVibrate(struct XrInput* input, int duration, int chan, float intensity); + +XrAction XrInputCreateAction(XrActionSet output_set, XrActionType type, const char* name, + const char* desc, int count_subaction_path, XrPath* subaction_path); +XrActionSet XrInputCreateActionSet(XrInstance instance, const char* name, const char* desc); +XrSpace XrInputCreateActionSpace(XrSession session, XrAction action, XrPath subaction_path); +XrActionStateBoolean XrInputGetActionStateBoolean(XrSession session, XrAction action); +XrActionStateFloat XrInputGetActionStateFloat(XrSession session, XrAction action); +XrActionStateVector2f XrInputGetActionStateVector2(XrSession session, XrAction action); +XrActionSuggestedBinding XrInputGetBinding(XrInstance instance, XrAction action, const char* name); +int XrInputGetMilliseconds(struct XrInput* input); +void XrInputProcessHaptics(struct XrInput* input, XrSession session); diff --git a/android/app/src/main/cpp/xrio/math.c b/android/app/src/main/cpp/xrio/math.c new file mode 100644 index 0000000..b179cc3 --- /dev/null +++ b/android/app/src/main/cpp/xrio/math.c @@ -0,0 +1,194 @@ +#include "math.h" + +#include +#include + +double FromXrTime(const XrTime time) { + return (time * 1e-9); +} + +XrTime ToXrTime(const double time_in_seconds) { + return (XrTime)(time_in_seconds * 1e9); +} + +float ToDegrees(float rad) { + return (float)(rad / M_PI * 180.0f); +} + +float ToRadians(float deg) { + return (float)(deg * M_PI / 180.0f); +} + +/* +================================================================================ + +XrQuaternionf + +================================================================================ +*/ + +XrQuaternionf XrQuaternionfCreateFromVectorAngle(const XrVector3f axis, const float angle) { + XrQuaternionf r; + if (XrVector3fLengthSquared(axis) == 0.0f) { + r.x = 0; + r.y = 0; + r.z = 0; + r.w = 1; + return r; + } + + XrVector3f unitAxis = XrVector3fNormalized(axis); + float sinHalfAngle = sinf(angle * 0.5f); + + r.w = cosf(angle * 0.5f); + r.x = unitAxis.x * sinHalfAngle; + r.y = unitAxis.y * sinHalfAngle; + r.z = unitAxis.z * sinHalfAngle; + return r; +} + +XrQuaternionf XrQuaternionfMultiply(const XrQuaternionf a, const XrQuaternionf b) { + XrQuaternionf c; + c.x = a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y; + c.y = a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x; + c.z = a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w; + c.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z; + return c; +} + +XrVector3f XrQuaternionfEulerAngles(const XrQuaternionf q) { + float M[16]; + XrQuaternionfToMatrix4f(&q, M); + + XrVector4f v1 = {0, 0, -1, 0}; + XrVector4f v2 = {1, 0, 0, 0}; + XrVector4f v3 = {0, 1, 0, 0}; + + XrVector4f forwardInVRSpace = XrVector4fMultiplyMatrix4f(M, &v1); + XrVector4f rightInVRSpace = XrVector4fMultiplyMatrix4f(M, &v2); + XrVector4f upInVRSpace = XrVector4fMultiplyMatrix4f(M, &v3); + + XrVector3f forward = {-forwardInVRSpace.z, -forwardInVRSpace.x, forwardInVRSpace.y}; + XrVector3f right = {-rightInVRSpace.z, -rightInVRSpace.x, rightInVRSpace.y}; + XrVector3f up = {-upInVRSpace.z, -upInVRSpace.x, upInVRSpace.y}; + + XrVector3f forwardNormal = XrVector3fNormalized(forward); + XrVector3f rightNormal = XrVector3fNormalized(right); + XrVector3f upNormal = XrVector3fNormalized(up); + + return XrVector3fGetAnglesFromVectors(forwardNormal, rightNormal, upNormal); +} + +void XrQuaternionfToMatrix4f(const XrQuaternionf* q, float* m) { + const float ww = q->w * q->w; + const float xx = q->x * q->x; + const float yy = q->y * q->y; + const float zz = q->z * q->z; + + float M[4][4]; + M[0][0] = ww + xx - yy - zz; + M[0][1] = 2 * (q->x * q->y - q->w * q->z); + M[0][2] = 2 * (q->x * q->z + q->w * q->y); + M[0][3] = 0; + + M[1][0] = 2 * (q->x * q->y + q->w * q->z); + M[1][1] = ww - xx + yy - zz; + M[1][2] = 2 * (q->y * q->z - q->w * q->x); + M[1][3] = 0; + + M[2][0] = 2 * (q->x * q->z - q->w * q->y); + M[2][1] = 2 * (q->y * q->z + q->w * q->x); + M[2][2] = ww - xx - yy + zz; + M[2][3] = 0; + + M[3][0] = 0; + M[3][1] = 0; + M[3][2] = 0; + M[3][3] = 1; + + memcpy(m, &M, sizeof(float) * 16); +} + +/* +================================================================================ + +XrVector3f, XrVector4f + +================================================================================ +*/ + + +float XrVector3fDistance(const XrVector3f a, const XrVector3f b) { + XrVector3f diff; + diff.x = a.x - b.x; + diff.y = a.y - b.y; + diff.z = a.z - b.z; + return sqrt(XrVector3fLengthSquared(diff)); +} + +float XrVector3fLengthSquared(const XrVector3f v) { + return v.x * v.x + v.y * v.y + v.z * v.z; +} + +XrVector3f XrVector3fGetAnglesFromVectors(XrVector3f forward, XrVector3f right, XrVector3f up) { + float sp = -forward.z; + + float cp_x_cy = forward.x; + float cp_x_sy = forward.y; + float cp_x_sr = -right.z; + float cp_x_cr = up.z; + + float yaw = atan2(cp_x_sy, cp_x_cy); + float roll = atan2(cp_x_sr, cp_x_cr); + + float cy = cos(yaw); + float sy = sin(yaw); + float cr = cos(roll); + float sr = sin(roll); + + float cp; + if (fabs(cy) > EPSILON) { + cp = cp_x_cy / cy; + } else if (fabs(sy) > EPSILON) { + cp = cp_x_sy / sy; + } else if (fabs(sr) > EPSILON) { + cp = cp_x_sr / sr; + } else if (fabs(cr) > EPSILON) { + cp = cp_x_cr / cr; + } else { + cp = cos(asin(sp)); + } + + float pitch = atan2(sp, cp); + + XrVector3f angles; + angles.x = ToDegrees(pitch); + angles.y = ToDegrees(yaw); + angles.z = ToDegrees(roll); + return angles; +} + +XrVector3f XrVector3fNormalized(const XrVector3f v) { + float rcpLen = 1.0f / sqrtf(XrVector3fLengthSquared(v)); + return XrVector3fScalarMultiply(v, rcpLen); +} + +XrVector3f XrVector3fScalarMultiply(const XrVector3f v, float scale) { + XrVector3f u; + u.x = v.x * scale; + u.y = v.y * scale; + u.z = v.z * scale; + return u; +} + +XrVector4f XrVector4fMultiplyMatrix4f(const float* m, const XrVector4f* v) { + float M[4][4]; + memcpy(&M, m, sizeof(float) * 16); + + XrVector4f out; + out.x = M[0][0] * v->x + M[0][1] * v->y + M[0][2] * v->z + M[0][3] * v->w; + out.y = M[1][0] * v->x + M[1][1] * v->y + M[1][2] * v->z + M[1][3] * v->w; + out.z = M[2][0] * v->x + M[2][1] * v->y + M[2][2] * v->z + M[2][3] * v->w; + out.w = M[3][0] * v->x + M[3][1] * v->y + M[3][2] * v->z + M[3][3] * v->w; + return out; +} diff --git a/android/app/src/main/cpp/xrio/math.h b/android/app/src/main/cpp/xrio/math.h new file mode 100644 index 0000000..dd50cf1 --- /dev/null +++ b/android/app/src/main/cpp/xrio/math.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#ifndef EPSILON +#define EPSILON 0.001f +#endif + +double FromXrTime(const XrTime time); +XrTime ToXrTime(const double time_in_seconds); +float ToDegrees(float rad); +float ToRadians(float deg); + +// XrQuaternionf +XrQuaternionf XrQuaternionfCreateFromVectorAngle(const XrVector3f axis, const float angle); +XrQuaternionf XrQuaternionfMultiply(const XrQuaternionf a, const XrQuaternionf b); +XrVector3f XrQuaternionfEulerAngles(const XrQuaternionf q); +void XrQuaternionfToMatrix4f(const XrQuaternionf* q, float* m); + +// XrVector3f, XrVector4f +float XrVector3fDistance(const XrVector3f a, const XrVector3f b); +float XrVector3fLengthSquared(const XrVector3f v); +XrVector3f XrVector3fGetAnglesFromVectors(XrVector3f forward, XrVector3f right, XrVector3f up); +XrVector3f XrVector3fNormalized(const XrVector3f v); +XrVector3f XrVector3fScalarMultiply(const XrVector3f v, float scale); +XrVector4f XrVector4fMultiplyMatrix4f(const float* m, const XrVector4f* v); diff --git a/android/app/src/main/cpp/xrio/renderer.c b/android/app/src/main/cpp/xrio/renderer.c new file mode 100644 index 0000000..4aae2ad --- /dev/null +++ b/android/app/src/main/cpp/xrio/renderer.c @@ -0,0 +1,565 @@ +#include +#include +#include +#include +#include "engine.h" +#include "math.h" +#include "renderer.h" + +#define DECL_PFN(pfn) PFN_##pfn pfn = NULL +#define INIT_PFN(pfn) OXR(xrGetInstanceProcAddr(engine->Instance, #pfn, (PFN_xrVoidFunction*)(&pfn))) + +DECL_PFN(xrCreatePassthroughFB); +DECL_PFN(xrDestroyPassthroughFB); +DECL_PFN(xrPassthroughStartFB); +DECL_PFN(xrPassthroughPauseFB); +DECL_PFN(xrCreatePassthroughLayerFB); +DECL_PFN(xrDestroyPassthroughLayerFB); +DECL_PFN(xrPassthroughLayerPauseFB); +DECL_PFN(xrPassthroughLayerResumeFB); + +void XrRendererInit(struct XrEngine* engine, struct XrRenderer* renderer) { + if (renderer->Initialized) { + XrRendererDestroy(engine, renderer); + } + memset(renderer, 0, sizeof(renderer)); + + if (engine->PlatformFlag[PLATFORM_EXTENSION_PASSTHROUGH]) { + INIT_PFN(xrCreatePassthroughFB); + INIT_PFN(xrDestroyPassthroughFB); + INIT_PFN(xrPassthroughStartFB); + INIT_PFN(xrPassthroughPauseFB); + INIT_PFN(xrCreatePassthroughLayerFB); + INIT_PFN(xrDestroyPassthroughLayerFB); + INIT_PFN(xrPassthroughLayerPauseFB); + INIT_PFN(xrPassthroughLayerResumeFB); + } + + int eyeW, eyeH; + XrRendererGetResolution(engine, renderer, &eyeW, &eyeH); + renderer->ConfigInt[CONFIG_VIEWPORT_WIDTH] = eyeW; + renderer->ConfigInt[CONFIG_VIEWPORT_HEIGHT] = eyeH; + + // Get the viewport configuration info for the chosen viewport configuration type. + renderer->ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES; + OXR(xrGetViewConfigurationProperties(engine->Instance, engine->SystemId, + XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, + &renderer->ViewportConfig)); + + uint32_t num_spaces = 0; + OXR(xrEnumerateReferenceSpaces(engine->Session, 0, &num_spaces, NULL)); + XrReferenceSpaceType* spaces = (XrReferenceSpaceType*)malloc(num_spaces * sizeof(XrReferenceSpaceType)); + OXR(xrEnumerateReferenceSpaces(engine->Session, num_spaces, &num_spaces, spaces)); + + for (uint32_t i = 0; i < num_spaces; i++) { + if (spaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) { + renderer->StageSupported = true; + break; + } + } + + free(spaces); + + if (engine->CurrentSpace == XR_NULL_HANDLE) { + XrRendererRecenter(engine, renderer); + } + + renderer->Projections = (XrView*)(malloc(XrMaxNumEyes * sizeof(XrView))); + for (int eye = 0; eye < XrMaxNumEyes; eye++) { + memset(&renderer->Projections[eye], 0, sizeof(XrView)); + renderer->Projections[eye].type = XR_TYPE_VIEW; + } + + // Create framebuffers. + int width = renderer->ViewConfig[0].recommendedImageRectWidth; + int height = renderer->ViewConfig[0].recommendedImageRectHeight; + for (int i = 0; i < XrMaxNumEyes; i++) { + XrFramebufferCreate(&renderer->Framebuffer[i], engine->Session, width, height); + } + + if (engine->PlatformFlag[PLATFORM_EXTENSION_PASSTHROUGH]) { + XrPassthroughCreateInfoFB ptci = {XR_TYPE_PASSTHROUGH_CREATE_INFO_FB}; + XrResult result; + OXR(result = xrCreatePassthroughFB(engine->Session, &ptci, &renderer->Passthrough)); + + if (XR_SUCCEEDED(result)) { + XrPassthroughLayerCreateInfoFB plci = {XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB}; + plci.passthrough = renderer->Passthrough; + plci.purpose = XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB; + OXR(xrCreatePassthroughLayerFB(engine->Session, &plci, &renderer->PassthroughLayer)); + } + + OXR(xrPassthroughStartFB(renderer->Passthrough)); + OXR(xrPassthroughLayerResumeFB(renderer->PassthroughLayer)); + } + renderer->Initialized = true; +} + +void XrRendererDestroy(struct XrEngine* engine, struct XrRenderer* renderer) { + if (!renderer->Initialized) { + return; + } + + if (engine->PlatformFlag[PLATFORM_EXTENSION_PASSTHROUGH]) { + if (renderer->PassthroughRunning) { + OXR(xrPassthroughLayerPauseFB(renderer->PassthroughLayer)); + } + OXR(xrPassthroughPauseFB(renderer->Passthrough)); + OXR(xrDestroyPassthroughFB(renderer->Passthrough)); + renderer->Passthrough = XR_NULL_HANDLE; + } + + for (int i = 0; i < XrMaxNumEyes; i++) { + XrFramebufferDestroy(&renderer->Framebuffer[i]); + } + free(renderer->Projections); + renderer->Initialized = false; +} + + +void XrRendererGetResolution(struct XrEngine* engine, struct XrRenderer* renderer, int* pWidth, int* pHeight) { + static int width = 0; + static int height = 0; + + if (engine) { + // Enumerate the viewport configurations. + uint32_t viewport_config_count = 0; + OXR(xrEnumerateViewConfigurations(engine->Instance, engine->SystemId, 0, + &viewport_config_count, NULL)); + + XrViewConfigurationType* viewport_configs = + (XrViewConfigurationType*)malloc(viewport_config_count * sizeof(XrViewConfigurationType)); + + OXR(xrEnumerateViewConfigurations(engine->Instance, engine->SystemId, + viewport_config_count, &viewport_config_count, + viewport_configs)); + + for (uint32_t i = 0; i < viewport_config_count; i++) { + const XrViewConfigurationType viewport_config_type = viewport_configs[i]; + + ALOGV("Viewport configuration type %d", (int)viewport_config_type); + + XrViewConfigurationProperties viewport_config; + viewport_config.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES; + OXR(xrGetViewConfigurationProperties(engine->Instance, engine->SystemId, + viewport_config_type, &viewport_config)); + + uint32_t view_count; + OXR(xrEnumerateViewConfigurationViews(engine->Instance, engine->SystemId, + viewport_config_type, 0, &view_count, NULL)); + + if (view_count > 0) { + XrViewConfigurationView* elements = + (XrViewConfigurationView*)malloc(view_count * sizeof(XrViewConfigurationView)); + + for (uint32_t e = 0; e < view_count; e++) { + elements[e].type = XR_TYPE_VIEW_CONFIGURATION_VIEW; + elements[e].next = NULL; + } + + OXR(xrEnumerateViewConfigurationViews(engine->Instance, engine->SystemId, + viewport_config_type, view_count, &view_count, + elements)); + + // Cache the view config properties for the selected config type. + if (viewport_config_type == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO) { + assert(view_count == XrMaxNumEyes); + for (uint32_t e = 0; e < view_count; e++) { + renderer->ViewConfig[e] = elements[e]; + } + } + + free(elements); + } else { + ALOGE("Empty viewport configuration"); + } + } + + free(viewport_configs); + + *pWidth = width = renderer->ViewConfig[0].recommendedImageRectWidth; + *pHeight = height = renderer->ViewConfig[0].recommendedImageRectHeight; + } else { + // use cached values + *pWidth = width; + *pHeight = height; + } +} + +bool XrRendererInitFrame(struct XrEngine* engine, struct XrRenderer* renderer) { + if (!renderer->Initialized) { + return false; + } + XrRendererHandleXrEvents(engine, renderer); + if (!renderer->SessionActive) { + return false; + } + + XrRendererUpdateStageBounds(engine); + + // Update passthrough + if (renderer->PassthroughRunning != renderer->ConfigInt[CONFIG_PASSTHROUGH]) { + if (renderer->ConfigInt[CONFIG_PASSTHROUGH]) { + OXR(xrPassthroughLayerResumeFB(renderer->PassthroughLayer)); + } else { + OXR(xrPassthroughLayerPauseFB(renderer->PassthroughLayer)); + } + renderer->PassthroughRunning = renderer->ConfigInt[CONFIG_PASSTHROUGH]; + } + + XrEngineWaitForFrame(engine); + + XrViewLocateInfo projection_info = {}; + projection_info.type = XR_TYPE_VIEW_LOCATE_INFO; + projection_info.next = NULL; + projection_info.viewConfigurationType = renderer->ViewportConfig.viewConfigurationType; + projection_info.displayTime = engine->PredictedDisplayTime; + projection_info.space = engine->CurrentSpace; + + XrViewState view_state = {XR_TYPE_VIEW_STATE, NULL}; + + uint32_t projection_capacity = XrMaxNumEyes; + uint32_t projection_count = projection_capacity; + + OXR(xrLocateViews(engine->Session, &projection_info, &view_state, projection_capacity, + &projection_count, renderer->Projections)); + + // Get the HMD pose, predicted for the middle of the time period during which + // the new eye images will be displayed. The number of frames predicted ahead + // depends on the pipeline depth of the engine and the synthesis rate. + // The better the prediction, the less black will be pulled in at the edges. + XrFrameBeginInfo begin_frame_info = {}; + begin_frame_info.type = XR_TYPE_FRAME_BEGIN_INFO; + begin_frame_info.next = NULL; + OXR(xrBeginFrame(engine->Session, &begin_frame_info)); + + renderer->Fov.angleLeft = 0; + renderer->Fov.angleRight = 0; + renderer->Fov.angleUp = 0; + renderer->Fov.angleDown = 0; + for (int eye = 0; eye < XrMaxNumEyes; eye++) { + renderer->Fov.angleLeft += renderer->Projections[eye].fov.angleLeft / 2.0f; + renderer->Fov.angleRight += renderer->Projections[eye].fov.angleRight / 2.0f; + renderer->Fov.angleUp += renderer->Projections[eye].fov.angleUp / 2.0f; + renderer->Fov.angleDown += renderer->Projections[eye].fov.angleDown / 2.0f; + renderer->InvertedViewPose[eye] = renderer->Projections[eye].pose; + } + + renderer->HmdOrientation = XrQuaternionfEulerAngles(renderer->InvertedViewPose[0].orientation); + renderer->LayerCount = 0; + memset(renderer->Layers, 0, sizeof(XrCompositorLayer) * XrMaxLayerCount); + return true; +} + +void XrRendererBeginFrame(struct XrRenderer* renderer, int fbo_index) { + renderer->ConfigInt[CONFIG_CURRENT_FBO] = fbo_index; + XrFramebufferAcquire(&renderer->Framebuffer[fbo_index]); +} + +void XrRendererEndFrame(struct XrRenderer* renderer) { + int fbo_index = renderer->ConfigInt[CONFIG_CURRENT_FBO]; + XrFramebufferRelease(&renderer->Framebuffer[fbo_index]); +} + +void XrRendererFinishFrame(struct XrEngine* engine, struct XrRenderer* renderer) { + int x = 0; + int y = 0; + int w = renderer->Framebuffer[0].Width; + int h = renderer->Framebuffer[0].Height; + if (renderer->ConfigInt[CONFIG_SBS]) { + w /= 2; + } + + int mode = renderer->ConfigInt[CONFIG_MODE]; + XrCompositionLayerProjectionView projection_layer_elements[2] = {}; + if ((mode == RENDER_MODE_MONO_6DOF) || (mode == RENDER_MODE_STEREO_6DOF)) { + renderer->ConfigFloat[CONFIG_MENU_YAW] = renderer->HmdOrientation.y; + + for (int eye = 0; eye < XrMaxNumEyes; eye++) { + struct XrFramebuffer* framebuffer = &renderer->Framebuffer[0]; + XrPosef pose = renderer->InvertedViewPose[0]; + if (renderer->ConfigInt[CONFIG_SBS] && (eye == 1)) { + x += w; + } else if (mode != RENDER_MODE_MONO_6DOF) { + framebuffer = &renderer->Framebuffer[eye]; + pose = renderer->InvertedViewPose[eye]; + } + + XrVector3f pitch_axis = {1, 0, 0}; + XrVector3f yaw_axis = {0, 1, 0}; + XrVector3f rotation = XrQuaternionfEulerAngles(pose.orientation); + XrQuaternionf pitch = XrQuaternionfCreateFromVectorAngle(pitch_axis, -ToRadians(rotation.x)); + XrQuaternionf yaw = XrQuaternionfCreateFromVectorAngle(yaw_axis, ToRadians(rotation.y)); + pose.orientation = XrQuaternionfMultiply(pitch, yaw); + + memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView)); + projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW; + projection_layer_elements[eye].pose = pose; + projection_layer_elements[eye].fov = renderer->Fov; + + memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage)); + projection_layer_elements[eye].subImage.swapchain = framebuffer->Handle; + projection_layer_elements[eye].subImage.imageRect.offset.x = x; + projection_layer_elements[eye].subImage.imageRect.offset.y = y; + projection_layer_elements[eye].subImage.imageRect.extent.width = w; + projection_layer_elements[eye].subImage.imageRect.extent.height = h; + projection_layer_elements[eye].subImage.imageArrayIndex = 0; + } + + XrCompositionLayerProjection projection_layer = {}; + projection_layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION; + projection_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT; + projection_layer.layerFlags |= XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT; + projection_layer.space = engine->CurrentSpace; + projection_layer.viewCount = XrMaxNumEyes; + projection_layer.views = projection_layer_elements; + + renderer->Layers[renderer->LayerCount++].projection = projection_layer; + } else if ((mode == RENDER_MODE_MONO_SCREEN) || (mode == RENDER_MODE_STEREO_SCREEN)) { + // Flat screen pose + float distance = renderer->ConfigFloat[CONFIG_CANVAS_DISTANCE]; + float menu_pitch = ToRadians(renderer->ConfigFloat[CONFIG_MENU_PITCH]); + float menu_yaw = ToRadians(renderer->ConfigFloat[CONFIG_MENU_YAW]); + XrVector3f pos = {renderer->InvertedViewPose[0].position.x - sinf(menu_yaw) * cosf(menu_pitch) * distance, + renderer->InvertedViewPose[0].position.y - sinf(menu_pitch) * distance, + renderer->InvertedViewPose[0].position.z - cosf(menu_yaw) * cosf(menu_pitch) * distance}; + XrVector3f pitch_axis = {1, 0, 0}; + XrVector3f yaw_axis = {0, 1, 0}; + XrQuaternionf pitch = XrQuaternionfCreateFromVectorAngle(pitch_axis, -menu_pitch); + XrQuaternionf yaw = XrQuaternionfCreateFromVectorAngle(yaw_axis, menu_yaw); + + // Setup quad layer + struct XrFramebuffer* framebuffer = &renderer->Framebuffer[0]; + XrCompositionLayerQuad quad_layer = {}; + quad_layer.type = XR_TYPE_COMPOSITION_LAYER_QUAD; + quad_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT; + quad_layer.space = engine->CurrentSpace; + memset(&quad_layer.subImage, 0, sizeof(XrSwapchainSubImage)); + quad_layer.subImage.imageRect.offset.x = x; + quad_layer.subImage.imageRect.offset.y = y; + quad_layer.subImage.imageRect.extent.width = w; + quad_layer.subImage.imageRect.extent.height = h; + quad_layer.subImage.swapchain = framebuffer->Handle; + quad_layer.subImage.imageArrayIndex = 0; + quad_layer.pose.orientation = XrQuaternionfMultiply(pitch, yaw); + quad_layer.pose.position = pos; + quad_layer.size.width = 4; + quad_layer.size.height = 4; + + // Build the cylinder layer + if (renderer->ConfigInt[CONFIG_SBS]) { + quad_layer.eyeVisibility = XR_EYE_VISIBILITY_LEFT; + renderer->Layers[renderer->LayerCount++].quad = quad_layer; + quad_layer.eyeVisibility = XR_EYE_VISIBILITY_RIGHT; + quad_layer.subImage.imageRect.offset.x = w; + renderer->Layers[renderer->LayerCount++].quad = quad_layer; + } else if (mode == RENDER_MODE_MONO_SCREEN) { + quad_layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH; + renderer->Layers[renderer->LayerCount++].quad = quad_layer; + } else { + quad_layer.eyeVisibility = XR_EYE_VISIBILITY_LEFT; + renderer->Layers[renderer->LayerCount++].quad = quad_layer; + quad_layer.eyeVisibility = XR_EYE_VISIBILITY_RIGHT; + quad_layer.subImage.swapchain = renderer->Framebuffer[1].Handle; + renderer->Layers[renderer->LayerCount++].quad = quad_layer; + } + } else { + assert(false); + } + + // Compose the layers for this frame. + const XrCompositionLayerBaseHeader* layers[XrMaxLayerCount] = {}; + for (int i = 0; i < renderer->LayerCount; i++) { + layers[i] = (const XrCompositionLayerBaseHeader*)&renderer->Layers[i]; + } + + XrFrameEndInfo end_frame_info = {}; + end_frame_info.type = XR_TYPE_FRAME_END_INFO; + end_frame_info.displayTime = engine->PredictedDisplayTime; + end_frame_info.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE; + end_frame_info.layerCount = renderer->LayerCount; + end_frame_info.layers = layers; + OXR(xrEndFrame(engine->Session, &end_frame_info)); +} + +void XrRendererBindFramebuffer(struct XrRenderer* renderer) { + if (!renderer->Initialized) + return; + int fbo_index = renderer->ConfigInt[CONFIG_CURRENT_FBO]; + XrFramebufferSetCurrent(&renderer->Framebuffer[fbo_index]); +} + + +void XrRendererRecenter(struct XrEngine* engine, struct XrRenderer* renderer) { + // Calculate recenter reference + XrReferenceSpaceCreateInfo space_info = {}; + space_info.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO; + space_info.poseInReferenceSpace.orientation.w = 1.0f; + if (engine->CurrentSpace != XR_NULL_HANDLE) { + XrSpaceLocation loc = {}; + loc.type = XR_TYPE_SPACE_LOCATION; + OXR(xrLocateSpace(engine->HeadSpace, engine->CurrentSpace, + engine->PredictedDisplayTime, &loc)); + renderer->HmdOrientation = XrQuaternionfEulerAngles(loc.pose.orientation); + + renderer->ConfigFloat[CONFIG_RECENTER_YAW] += renderer->HmdOrientation.y; + float renceter_yaw = ToRadians(renderer->ConfigFloat[CONFIG_RECENTER_YAW]); + space_info.poseInReferenceSpace.orientation.x = 0; + space_info.poseInReferenceSpace.orientation.y = sinf(renceter_yaw / 2); + space_info.poseInReferenceSpace.orientation.z = 0; + space_info.poseInReferenceSpace.orientation.w = cosf(renceter_yaw / 2); + } + + // Delete previous space instances + if (engine->StageSpace != XR_NULL_HANDLE) { + OXR(xrDestroySpace(engine->StageSpace)); + } + if (engine->FakeSpace != XR_NULL_HANDLE) { + OXR(xrDestroySpace(engine->FakeSpace)); + } + + // Create a default stage space to use if SPACE_TYPE_STAGE is not + // supported, or calls to xrGetReferenceSpaceBoundsRect fail. + space_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL; + if (engine->PlatformFlag[PLATFORM_TRACKING_FLOOR]) { + space_info.poseInReferenceSpace.position.y = -1.6750f; + } + OXR(xrCreateReferenceSpace(engine->Session, &space_info, &engine->FakeSpace)); + ALOGV("Created fake stage space from local space with offset"); + engine->CurrentSpace = engine->FakeSpace; + + if (renderer->StageSupported) { + space_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE; + space_info.poseInReferenceSpace.position.y = 0.0; + OXR(xrCreateReferenceSpace(engine->Session, &space_info, &engine->StageSpace)); + ALOGV("Created stage space"); + if (engine->PlatformFlag[PLATFORM_TRACKING_FLOOR]) { + engine->CurrentSpace = engine->StageSpace; + } + } + + // Update menu orientation + renderer->ConfigFloat[CONFIG_MENU_PITCH] = renderer->HmdOrientation.x; + renderer->ConfigFloat[CONFIG_MENU_YAW] = 0.0f; +} + +void XrRendererHandleSessionStateChanges(struct XrEngine* engine, struct XrRenderer* renderer, XrSessionState state) { + if (state == XR_SESSION_STATE_READY) { + assert(renderer->SessionActive == false); + + XrSessionBeginInfo session_begin_info; + memset(&session_begin_info, 0, sizeof(session_begin_info)); + session_begin_info.type = XR_TYPE_SESSION_BEGIN_INFO; + session_begin_info.next = NULL; + session_begin_info.primaryViewConfigurationType = renderer->ViewportConfig.viewConfigurationType; + + XrResult result; + OXR(result = xrBeginSession(engine->Session, &session_begin_info)); + renderer->SessionActive = (result == XR_SUCCESS); + ALOGV("Session active = %d", renderer->SessionActive); + +#ifdef ANDROID + if (renderer->SessionActive && engine->PlatformFlag[PLATFORM_EXTENSION_PERFORMANCE]) { + PFN_xrPerfSettingsSetPerformanceLevelEXT pfnPerfSettingsSetPerformanceLevelEXT = NULL; + OXR(xrGetInstanceProcAddr(engine->Instance, "xrPerfSettingsSetPerformanceLevelEXT", + (PFN_xrVoidFunction*)(&pfnPerfSettingsSetPerformanceLevelEXT))); + + OXR(pfnPerfSettingsSetPerformanceLevelEXT( + engine->Session, XR_PERF_SETTINGS_DOMAIN_CPU_EXT, XR_PERF_SETTINGS_LEVEL_BOOST_EXT)); + OXR(pfnPerfSettingsSetPerformanceLevelEXT( + engine->Session, XR_PERF_SETTINGS_DOMAIN_GPU_EXT, XR_PERF_SETTINGS_LEVEL_BOOST_EXT)); + + PFN_xrSetAndroidApplicationThreadKHR pfnSetAndroidApplicationThreadKHR = NULL; + OXR(xrGetInstanceProcAddr(engine->Instance, "xrSetAndroidApplicationThreadKHR", + (PFN_xrVoidFunction*)(&pfnSetAndroidApplicationThreadKHR))); + + OXR(pfnSetAndroidApplicationThreadKHR(engine->Session, + XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR, + engine->MainThreadId)); + OXR(pfnSetAndroidApplicationThreadKHR(engine->Session, + XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR, + engine->RenderThreadId)); + } +#endif + } else if (state == XR_SESSION_STATE_STOPPING) { + assert(renderer->SessionActive); + + OXR(xrEndSession(engine->Session)); + renderer->SessionActive = false; + } +} + +void XrRendererHandleXrEvents(struct XrEngine* engine, struct XrRenderer* renderer) { + XrEventDataBuffer event_data_bufer = {}; + + // Poll for events + for (;;) { + XrEventDataBaseHeader* base_event_handler = (XrEventDataBaseHeader*)(&event_data_bufer); + base_event_handler->type = XR_TYPE_EVENT_DATA_BUFFER; + base_event_handler->next = NULL; + XrResult r; + OXR(r = xrPollEvent(engine->Instance, &event_data_bufer)); + if (r != XR_SUCCESS) { + break; + } + + switch (base_event_handler->type) { + case XR_TYPE_EVENT_DATA_EVENTS_LOST: + ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_EVENTS_LOST"); + break; + case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: + { + const XrEventDataInstanceLossPending* instance_loss_pending_event = + (XrEventDataInstanceLossPending*)(base_event_handler); + ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: time %lf", + FromXrTime(instance_loss_pending_event->lossTime)); + } + break; + case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: + ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED"); + break; + case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT: + break; + case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: + XrRendererRecenter(engine, renderer); + break; + case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: + { + const XrEventDataSessionStateChanged* session_state_changed_event = + (XrEventDataSessionStateChanged*)(base_event_handler); + switch (session_state_changed_event->state) { + case XR_SESSION_STATE_FOCUSED: + renderer->SessionFocused = true; + break; + case XR_SESSION_STATE_VISIBLE: + renderer->SessionFocused = false; + break; + case XR_SESSION_STATE_READY: + case XR_SESSION_STATE_STOPPING: + XrRendererHandleSessionStateChanges(engine, renderer, session_state_changed_event->state); + break; + default: + break; + } + break; + } + default: + ALOGV("xrPollEvent: Unknown event"); + break; + } + } +} + +void XrRendererUpdateStageBounds(struct XrEngine* engine) { + XrExtent2Df stage_bounds = {}; + + XrResult result; + OXR(result = xrGetReferenceSpaceBoundsRect(engine->Session, XR_REFERENCE_SPACE_TYPE_STAGE, + &stage_bounds)); + if (result != XR_SUCCESS) { + stage_bounds.width = 1.0f; + stage_bounds.height = 1.0f; + + engine->CurrentSpace = engine->FakeSpace; + } +} diff --git a/android/app/src/main/cpp/xrio/renderer.h b/android/app/src/main/cpp/xrio/renderer.h new file mode 100644 index 0000000..ffda39e --- /dev/null +++ b/android/app/src/main/cpp/xrio/renderer.h @@ -0,0 +1,76 @@ +#pragma once + +#include "engine.h" +#include "framebuffer.h" + +enum XrConfigFloat { + // 2D canvas positioning + CONFIG_CANVAS_DISTANCE, + CONFIG_MENU_PITCH, + CONFIG_MENU_YAW, + CONFIG_RECENTER_YAW, + + CONFIG_FLOAT_MAX +}; + +enum XrConfigInt { + // switching between modes + CONFIG_MODE, + CONFIG_PASSTHROUGH, + CONFIG_SBS, + // viewport setup + CONFIG_VIEWPORT_WIDTH, + CONFIG_VIEWPORT_HEIGHT, + // render status + CONFIG_CURRENT_FBO, + + // end + CONFIG_INT_MAX +}; + +enum XrRenderMode { + RENDER_MODE_MONO_SCREEN, + RENDER_MODE_STEREO_SCREEN, + RENDER_MODE_MONO_6DOF, + RENDER_MODE_STEREO_6DOF +}; + +struct XrRenderer { + bool SessionActive; + bool SessionFocused; + bool Initialized; + bool StageSupported; + float ConfigFloat[CONFIG_FLOAT_MAX]; + int ConfigInt[CONFIG_INT_MAX]; + + struct XrFramebuffer Framebuffer[XrMaxNumEyes]; + + int LayerCount; + XrCompositorLayer Layers[XrMaxLayerCount]; + XrPassthroughFB Passthrough; + XrPassthroughLayerFB PassthroughLayer; + bool PassthroughRunning; + XrViewConfigurationProperties ViewportConfig; + XrViewConfigurationView ViewConfig[XrMaxNumEyes]; + + XrFovf Fov; + XrView* Projections; + XrPosef InvertedViewPose[2]; + XrVector3f HmdOrientation; +}; + +void XrRendererInit(struct XrEngine* engine, struct XrRenderer* renderer); +void XrRendererDestroy(struct XrEngine* engine, struct XrRenderer* renderer); +void XrRendererGetResolution(struct XrEngine* engine, struct XrRenderer* renderer, int* pWidth, int* pHeight); + +bool XrRendererInitFrame(struct XrEngine* engine, struct XrRenderer* renderer); +void XrRendererBeginFrame(struct XrRenderer* renderer, int fbo_index); +void XrRendererEndFrame(struct XrRenderer* renderer); +void XrRendererFinishFrame(struct XrEngine* engine, struct XrRenderer* renderer); + +void XrRendererBindFramebuffer(struct XrRenderer* renderer); +void XrRendererRecenter(struct XrEngine* engine, struct XrRenderer* renderer); + +void XrRendererHandleSessionStateChanges(struct XrEngine* engine, struct XrRenderer* renderer, XrSessionState state); +void XrRendererHandleXrEvents(struct XrEngine* engine, struct XrRenderer* renderer); +void XrRendererUpdateStageBounds(struct XrEngine* engine); diff --git a/android/app/src/main/cpp/xserver b/android/app/src/main/cpp/xserver new file mode 160000 index 0000000..be27678 --- /dev/null +++ b/android/app/src/main/cpp/xserver @@ -0,0 +1 @@ +Subproject commit be2767845d6ed3c6dbd25a151051294d0908a995 diff --git a/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeyButton.java b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeyButton.java new file mode 100644 index 0000000..edfe26f --- /dev/null +++ b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeyButton.java @@ -0,0 +1,129 @@ +package com.termux.shared.termux.extrakeys; + +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public class ExtraKeyButton { + + /** The key name for the name of the extra key if using a dict to define the extra key. {key: name, ...} */ + public static final String KEY_KEY_NAME = "key"; + + /** The key name for the macro value of the extra key if using a dict to define the extra key. {macro: value, ...} */ + public static final String KEY_MACRO = "macro"; + + /** The key name for the alternate display name of the extra key if using a dict to define the extra key. {display: name, ...} */ + public static final String KEY_DISPLAY_NAME = "display"; + + /** The key name for the nested dict to define popup extra key info if using a dict to define the extra key. {popup: {key: name, ...}, ...} */ + public static final String KEY_POPUP = "popup"; + + + /** + * The key that will be sent to the terminal, either a control character, like defined in + * {@link ExtraKeysConstants#PRIMARY_KEY_CODES_FOR_STRINGS} (LEFT, RIGHT, PGUP...) or some text. + */ + public final String key; + + /** + * If the key is a macro, i.e. a sequence of keys separated by space. + */ + public final boolean macro; + + /** + * The text that will be displayed on the button. + */ + public final String display; + + /** + * The {@link ExtraKeyButton} containing the information of the popup button (triggered by swipe up). + */ + @Nullable + public final ExtraKeyButton popup; + + + /** + * Initialize a {@link ExtraKeyButton}. + * + * @param config The {@link JSONObject} containing the info to create the {@link ExtraKeyButton}. + * @param extraKeyDisplayMap The {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the + * display text mapping for the keys if a custom value is not defined + * by {@link #KEY_DISPLAY_NAME}. + * @param extraKeyAliasMap The {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the + * aliases for the actual key names. + */ + public ExtraKeyButton(@NonNull JSONObject config, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyDisplayMap, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyAliasMap) throws JSONException { + this(config, null, extraKeyDisplayMap, extraKeyAliasMap); + } + + /** + * Initialize a {@link ExtraKeyButton}. + * + * @param config The {@link JSONObject} containing the info to create the {@link ExtraKeyButton}. + * @param popup The {@link ExtraKeyButton} optional {@link #popup} button. + * @param extraKeyDisplayMap The {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the + * display text mapping for the keys if a custom value is not defined + * by {@link #KEY_DISPLAY_NAME}. + * @param extraKeyAliasMap The {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the + * aliases for the actual key names. + */ + public ExtraKeyButton(@NonNull JSONObject config, @Nullable ExtraKeyButton popup, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyDisplayMap, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyAliasMap) throws JSONException { + String keyFromConfig = getStringFromJson(config, KEY_KEY_NAME); + String macroFromConfig = getStringFromJson(config, KEY_MACRO); + String[] keys; + if (keyFromConfig != null && macroFromConfig != null) { + throw new JSONException("Both key and macro can't be set for the same key. key: \"" + keyFromConfig + "\", macro: \"" + macroFromConfig + "\""); + } else if (keyFromConfig != null) { + keys = new String[]{keyFromConfig}; + this.macro = false; + } else if (macroFromConfig != null) { + keys = macroFromConfig.split(" "); + this.macro = true; + } else { + throw new JSONException("All keys have to specify either key or macro"); + } + + for (int i = 0; i < keys.length; i++) { + keys[i] = replaceAlias(extraKeyAliasMap, keys[i]); + } + + this.key = TextUtils.join(" ", keys); + + String displayFromConfig = getStringFromJson(config, KEY_DISPLAY_NAME); + if (displayFromConfig != null) { + this.display = displayFromConfig; + } else { + this.display = Arrays.stream(keys) + .map(key -> extraKeyDisplayMap.get(key, key)) + .collect(Collectors.joining(" ")); + } + + this.popup = popup; + } + + public String getStringFromJson(@NonNull JSONObject config, @NonNull String key) { + try { + return config.getString(key); + } catch (JSONException e) { + return null; + } + } + + /** + * Replace the alias with its actual key name if found in extraKeyAliasMap. + */ + public static String replaceAlias(@NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyAliasMap, String key) { + return extraKeyAliasMap.get(key, key); + } +} diff --git a/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysConstants.java b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysConstants.java new file mode 100644 index 0000000..bfcc8ee --- /dev/null +++ b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysConstants.java @@ -0,0 +1,201 @@ +package com.termux.shared.termux.extrakeys; + +import android.view.KeyEvent; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ExtraKeysConstants { + + /** Defines the repetitive keys that can be passed to {@link ExtraKeysView#setRepetitiveKeys(List)}. */ + public static List PRIMARY_REPETITIVE_KEYS = Arrays.asList( + "UP", "DOWN", "LEFT", "RIGHT", + "BKSP", "DEL", + "PGUP", "PGDN"); + + /** Defines the {@link KeyEvent} for common keys. */ + public static Map PRIMARY_KEY_CODES_FOR_STRINGS = new HashMap() {{ + put("SPACE", KeyEvent.KEYCODE_SPACE); + put("ESC", KeyEvent.KEYCODE_ESCAPE); + put("TAB", KeyEvent.KEYCODE_TAB); + put("HOME", KeyEvent.KEYCODE_MOVE_HOME); + put("END", KeyEvent.KEYCODE_MOVE_END); + put("PGUP", KeyEvent.KEYCODE_PAGE_UP); + put("PGDN", KeyEvent.KEYCODE_PAGE_DOWN); + put("INS", KeyEvent.KEYCODE_INSERT); + put("DEL", KeyEvent.KEYCODE_FORWARD_DEL); + put("BKSP", KeyEvent.KEYCODE_DEL); + put("UP", KeyEvent.KEYCODE_DPAD_UP); + put("LEFT", KeyEvent.KEYCODE_DPAD_LEFT); + put("RIGHT", KeyEvent.KEYCODE_DPAD_RIGHT); + put("DOWN", KeyEvent.KEYCODE_DPAD_DOWN); + put("ENTER", KeyEvent.KEYCODE_ENTER); + put("F1", KeyEvent.KEYCODE_F1); + put("F2", KeyEvent.KEYCODE_F2); + put("F3", KeyEvent.KEYCODE_F3); + put("F4", KeyEvent.KEYCODE_F4); + put("F5", KeyEvent.KEYCODE_F5); + put("F6", KeyEvent.KEYCODE_F6); + put("F7", KeyEvent.KEYCODE_F7); + put("F8", KeyEvent.KEYCODE_F8); + put("F9", KeyEvent.KEYCODE_F9); + put("F10", KeyEvent.KEYCODE_F10); + put("F11", KeyEvent.KEYCODE_F11); + put("F12", KeyEvent.KEYCODE_F12); + }}; + + /** + * HashMap that implements Python dict.get(key, default) function. + * Default java.util .get(key) is then the same as .get(key, null); + */ + static class CleverMap extends HashMap { + V get(K key, V defaultValue) { + if (containsKey(key)) + return get(key); + else + return defaultValue; + } + } + + public static class ExtraKeyDisplayMap extends CleverMap {} + + /* + * Multiple maps are available to quickly change + * the style of the keys. + */ + + public static class EXTRA_KEY_DISPLAY_MAPS { + /** + * Keys are displayed in a natural looking way, like "→" for "RIGHT" + */ + public static final ExtraKeyDisplayMap CLASSIC_ARROWS_DISPLAY = new ExtraKeyDisplayMap() {{ + // classic arrow keys (for ◀ ▶ ▲ ▼ @see arrowVariationDisplay) + put("LEFT", "←"); // U+2190 ← LEFTWARDS ARROW + put("RIGHT", "→"); // U+2192 → RIGHTWARDS ARROW + put("UP", "↑"); // U+2191 ↑ UPWARDS ARROW + put("DOWN", "↓"); // U+2193 ↓ DOWNWARDS ARROW + }}; + + public static final ExtraKeyDisplayMap WELL_KNOWN_CHARACTERS_DISPLAY = new ExtraKeyDisplayMap() {{ + // well known characters // https://en.wikipedia.org/wiki/{Enter_key, Tab_key, Delete_key} + put("ENTER", "↲"); // U+21B2 ↲ DOWNWARDS ARROW WITH TIP LEFTWARDS + put("TAB", "↹"); // U+21B9 ↹ LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR + put("BKSP", "⌫"); // U+232B ⌫ ERASE TO THE LEFT sometimes seen and easy to understand + put("DEL", "⌦"); // U+2326 ⌦ ERASE TO THE RIGHT not well known but easy to understand + put("DRAWER", "☰"); // U+2630 ☰ TRIGRAM FOR HEAVEN not well known but easy to understand + put("KEYBOARD", "⌨"); // U+2328 ⌨ KEYBOARD not well known but easy to understand + put("PASTE", "⎘"); // U+2398 + put("SCROLL", "⇳"); // U+21F3 + put("PREFERENCES", "⚙"); // U+2699 GEAR not well known but easy to understand + put("EXIT", "╳"); // U+2573 BOX DRAWINGS LIGHT DIAGONAL CROSS not well known but easy to understand + put("MOUSE_HELPER", "\uD83D\uDDB1"); // U+1F5B1 THREE BUTTON MOUSE + put("STYLUS_HELPER", "\uD83D\uDD8C"); // U+1F58C LOWER LEFT PAINTBRUSH + }}; + + public static final ExtraKeyDisplayMap LESS_KNOWN_CHARACTERS_DISPLAY = new ExtraKeyDisplayMap() {{ + // https://en.wikipedia.org/wiki/{Home_key, End_key, Page_Up_and_Page_Down_keys} + // home key can mean "goto the beginning of line" or "goto first page" depending on context, hence the diagonal + put("HOME", "⇱"); // from IEC 9995 // U+21F1 ⇱ NORTH WEST ARROW TO CORNER + put("END", "⇲"); // from IEC 9995 // ⇲ // U+21F2 ⇲ SOUTH EAST ARROW TO CORNER + put("PGUP", "⇑"); // no ISO character exists, U+21D1 ⇑ UPWARDS DOUBLE ARROW will do the trick + put("PGDN", "⇓"); // no ISO character exists, U+21D3 ⇓ DOWNWARDS DOUBLE ARROW will do the trick + }}; + + public static final ExtraKeyDisplayMap NOT_KNOWN_ISO_CHARACTERS = new ExtraKeyDisplayMap() {{ + // Control chars that are more clear as text // https://en.wikipedia.org/wiki/{Function_key, Alt_key, Control_key, Esc_key} + // put("FN", "FN"); // no ISO character exists + put("CTRL", "⎈"); // ISO character "U+2388 ⎈ HELM SYMBOL" is unknown to people and never printed on computers, however "U+25C7 ◇ WHITE DIAMOND" is a nice presentation, and "^" for terminal app and mac is often used + put("ALT", "⎇"); // ISO character "U+2387 ⎇ ALTERNATIVE KEY SYMBOL'" is unknown to people and only printed as the Option key "⌥" on Mac computer + put("ESC", "⎋"); // ISO character "U+238B ⎋ BROKEN CIRCLE WITH NORTHWEST ARROW" is unknown to people and not often printed on computers + }}; + + public static final ExtraKeyDisplayMap NICER_LOOKING_DISPLAY = new ExtraKeyDisplayMap() {{ + // nicer looking for most cases + put("-", "―"); // U+2015 ― HORIZONTAL BAR + }}; + + /** + * Full Iso + */ + public static final ExtraKeyDisplayMap FULL_ISO_CHAR_DISPLAY = new ExtraKeyDisplayMap() {{ + putAll(CLASSIC_ARROWS_DISPLAY); + putAll(WELL_KNOWN_CHARACTERS_DISPLAY); + putAll(LESS_KNOWN_CHARACTERS_DISPLAY); // NEW + putAll(NICER_LOOKING_DISPLAY); + putAll(NOT_KNOWN_ISO_CHARACTERS); // NEW + }}; + + /** + * Only arrows + */ + public static final ExtraKeyDisplayMap ARROWS_ONLY_CHAR_DISPLAY = new ExtraKeyDisplayMap() {{ + putAll(CLASSIC_ARROWS_DISPLAY); + /* putAll(wellKnownCharactersDisplay); */ // REMOVED + /* putAll(lessKnownCharactersDisplay); */ // REMOVED + putAll(NICER_LOOKING_DISPLAY); + }}; + + /** + * Classic symbols and less known symbols + */ + public static final ExtraKeyDisplayMap LOTS_OF_ARROWS_CHAR_DISPLAY = new ExtraKeyDisplayMap() {{ + putAll(CLASSIC_ARROWS_DISPLAY); + putAll(WELL_KNOWN_CHARACTERS_DISPLAY); + putAll(LESS_KNOWN_CHARACTERS_DISPLAY); // NEW + putAll(NICER_LOOKING_DISPLAY); + }}; + + /** + * Some classic symbols everybody knows + */ + public static final ExtraKeyDisplayMap DEFAULT_CHAR_DISPLAY = new ExtraKeyDisplayMap() {{ + putAll(CLASSIC_ARROWS_DISPLAY); + putAll(WELL_KNOWN_CHARACTERS_DISPLAY); + putAll(NICER_LOOKING_DISPLAY); + // all other characters are displayed as themselves + }}; + + } + + + + /** + * Aliases for the keys + */ + public static final ExtraKeyDisplayMap CONTROL_CHARS_ALIASES = new ExtraKeyDisplayMap() {{ + put("ESCAPE", "ESC"); + put("CONTROL", "CTRL"); + put("SHFT", "SHIFT"); + put("RETURN", "ENTER"); // Technically different keys, but most applications won't see the difference + put("FUNCTION", "FN"); + // no alias for ALT + + // Directions are sometimes written as first and last letter for brevety + put("LT", "LEFT"); + put("RT", "RIGHT"); + put("DN", "DOWN"); + // put("UP", "UP"); well, "UP" is already two letters + + put("PAGEUP", "PGUP"); + put("PAGE_UP", "PGUP"); + put("PAGE UP", "PGUP"); + put("PAGE-UP", "PGUP"); + + // no alias for HOME + // no alias for END + + put("PAGEDOWN", "PGDN"); + put("PAGE_DOWN", "PGDN"); + put("PAGE-DOWN", "PGDN"); + + put("DELETE", "DEL"); + put("BACKSPACE", "BKSP"); + + // easier for writing in termux.properties + put("BACKSLASH", "\\"); + put("QUOTE", "\""); + put("APOSTROPHE", "'"); + }}; +} diff --git a/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysInfo.java b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysInfo.java new file mode 100644 index 0000000..cdd2748 --- /dev/null +++ b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysInfo.java @@ -0,0 +1,209 @@ +package com.termux.shared.termux.extrakeys; + +import android.view.View; + +import androidx.annotation.NonNull; + +import com.termux.shared.termux.extrakeys.ExtraKeysConstants.EXTRA_KEY_DISPLAY_MAPS; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * A {@link Class} that defines the info needed by {@link ExtraKeysView} to display the extra key + * views. + * + * The {@code propertiesInfo} passed to the constructors of this class must be json array of arrays. + * Each array element of the json array will be considered a separate row of keys. + * Each key can either be simple string that defines the name of the key or a json dict that defines + * advance info for the key. The syntax can be `'KEY'` or `{key: 'KEY'}`. + * For example `HOME` or `{key: 'HOME', ...}. + * + * In advance json dict mode, the key can also be a sequence of space separated keys instead of one + * key. This can be done by replacing `key` key/value pair of the dict with a `macro` key/value pair. + * The syntax is `{macro: 'KEY COMBINATION'}`. For example {macro: 'HOME RIGHT', ...}. + * + * In advance json dict mode, you can define a nested json dict with the `popup` key which will be + * used as the popup key and will be triggered on swipe up. The syntax can be + * `{key: 'KEY', popup: 'POPUP_KEY'}` or `{key: 'KEY', popup: {macro: 'KEY COMBINATION', display: 'Key combo'}}`. + * For example `{key: 'HOME', popup: {KEY: 'END', ...}, ...}`. + * + * In advance json dict mode, the key can also have a custom display name that can be used as the + * text to display on the button by defining the `display` key. The syntax is `{display: 'DISPLAY'}`. + * For example {display: 'Custom name', ...}. + * + * Examples: + * {@code + * # Empty: + * [] + * + * # Single row: + * [[ESC, TAB, CTRL, ALT, {key: '-', popup: '|'}, DOWN, UP]] + * + * # 2 row: + * [['ESC','/',{key: '-', popup: '|'},'HOME','UP','END','PGUP'], + * ['TAB','CTRL','ALT','LEFT','DOWN','RIGHT','PGDN']] + * + * # Advance: + * [[ + * {key: ESC, popup: {macro: "CTRL f d", display: "tmux exit"}}, + * {key: CTRL, popup: {macro: "CTRL f BKSP", display: "tmux ←"}}, + * {key: ALT, popup: {macro: "CTRL f TAB", display: "tmux →"}}, + * {key: TAB, popup: {macro: "ALT a", display: A-a}}, + * {key: LEFT, popup: HOME}, + * {key: DOWN, popup: PGDN}, + * {key: UP, popup: PGUP}, + * {key: RIGHT, popup: END}, + * {macro: "ALT j", display: A-j, popup: {macro: "ALT g", display: A-g}}, + * {key: KEYBOARD, popup: {macro: "CTRL d", display: exit}} + * ]] + *

+ * } + * + * Aliases are also allowed for the keys that you can pass as {@code extraKeyAliasMap}. Check + * {@link ExtraKeysConstants#CONTROL_CHARS_ALIASES}. + *

+ * Its up to the {@link ExtraKeysView.IExtraKeysView} client on how to handle individual key values + * of an {@link ExtraKeyButton}. They are sent as is via + * {@link ExtraKeysView.IExtraKeysView#onExtraKeyButtonClick(View, ExtraKeyButton, Button)}. The + * {@link com.termux.x11.utils.TermuxX11ExtraKeys} which is an implementation of the interface, + * checks if the key is one of {@link ExtraKeysConstants#PRIMARY_KEY_CODES_FOR_STRINGS} and generates + * a {@link android.view.KeyEvent} for it, and if its not, then converts the key to code points by + * calling {@link CharSequence#codePoints()} and passes them to the terminal as literal strings. + *

+ * Examples: + * {@code + * "ENTER" will trigger the ENTER keycode + * "LEFT" will trigger the LEFT keycode and be displayed as "←" + * "→" will input a "→" character + * "−" will input a "−" character + * "-_-" will input the string "-_-" + * } + * + * For more info, check https://wiki.termux.com/wiki/Touch_Keyboard. + */ +public class ExtraKeysInfo { + + /** + * Matrix of buttons to be displayed in {@link ExtraKeysView}. + */ + private final ExtraKeyButton[][] mButtons; + + /** + * Initialize {@link ExtraKeysInfo}. + * + * @param propertiesInfo The {@link String} containing the info to create the {@link ExtraKeysInfo}. + * Check the class javadoc for details. + * @param style The style to pass to {@link #getCharDisplayMapForStyle(String)} to get the + * {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the display text + * mapping for the keys if a custom value is not defined by + * {@link ExtraKeyButton#KEY_DISPLAY_NAME} for a key. + * @param extraKeyAliasMap The {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the + * aliases for the actual key names. You can create your own or + * optionally pass {@link ExtraKeysConstants#CONTROL_CHARS_ALIASES}. + */ + public ExtraKeysInfo(@NonNull String propertiesInfo, String style, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyAliasMap) throws JSONException { + mButtons = initExtraKeysInfo(propertiesInfo, getCharDisplayMapForStyle(style), extraKeyAliasMap); + } + + /** + * Initialize {@link ExtraKeysInfo}. + * + * @param propertiesInfo The {@link String} containing the info to create the {@link ExtraKeysInfo}. + * Check the class javadoc for details. + * @param extraKeyDisplayMap The {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the + * display text mapping for the keys if a custom value is not defined + * by {@link ExtraKeyButton#KEY_DISPLAY_NAME} for a key. You can create + * your own or optionally pass one of the values defined in + * {@link #getCharDisplayMapForStyle(String)}. + * @param extraKeyAliasMap The {@link ExtraKeysConstants.ExtraKeyDisplayMap} that defines the + * aliases for the actual key names. You can create your own or + * optionally pass {@link ExtraKeysConstants#CONTROL_CHARS_ALIASES}. + */ + public ExtraKeysInfo(@NonNull String propertiesInfo, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyDisplayMap, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyAliasMap) throws JSONException { + mButtons = initExtraKeysInfo(propertiesInfo, extraKeyDisplayMap, extraKeyAliasMap); + } + + private ExtraKeyButton[][] initExtraKeysInfo(@NonNull String propertiesInfo, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyDisplayMap, + @NonNull ExtraKeysConstants.ExtraKeyDisplayMap extraKeyAliasMap) throws JSONException { + // Convert String propertiesInfo to Array of Arrays + JSONArray arr = new JSONArray(propertiesInfo); + Object[][] matrix = new Object[arr.length()][]; + for (int i = 0; i < arr.length(); i++) { + JSONArray line = arr.getJSONArray(i); + matrix[i] = new Object[line.length()]; + for (int j = 0; j < line.length(); j++) { + matrix[i][j] = line.get(j); + } + } + + // convert matrix to buttons + ExtraKeyButton[][] buttons = new ExtraKeyButton[matrix.length][]; + for (int i = 0; i < matrix.length; i++) { + buttons[i] = new ExtraKeyButton[matrix[i].length]; + for (int j = 0; j < matrix[i].length; j++) { + Object key = matrix[i][j]; + + JSONObject jobject = normalizeKeyConfig(key); + + ExtraKeyButton button; + + if (!jobject.has(ExtraKeyButton.KEY_POPUP)) { + // no popup + button = new ExtraKeyButton(jobject, extraKeyDisplayMap, extraKeyAliasMap); + } else { + // a popup + JSONObject popupJobject = normalizeKeyConfig(jobject.get(ExtraKeyButton.KEY_POPUP)); + ExtraKeyButton popup = new ExtraKeyButton(popupJobject, extraKeyDisplayMap, extraKeyAliasMap); + button = new ExtraKeyButton(jobject, popup, extraKeyDisplayMap, extraKeyAliasMap); + } + + buttons[i][j] = button; + } + } + + return buttons; + } + + /** + * Convert "value" -> {"key": "value"}. Required by + * {@link ExtraKeyButton#ExtraKeyButton(JSONObject, ExtraKeyButton, ExtraKeysConstants.ExtraKeyDisplayMap, ExtraKeysConstants.ExtraKeyDisplayMap)}. + */ + private static JSONObject normalizeKeyConfig(Object key) throws JSONException { + JSONObject jobject; + if (key instanceof String) { + jobject = new JSONObject(); + jobject.put(ExtraKeyButton.KEY_KEY_NAME, key); + } else if (key instanceof JSONObject) { + jobject = (JSONObject) key; + } else { + throw new JSONException("An key in the extra-key matrix must be a string or an object"); + } + return jobject; + } + + public ExtraKeyButton[][] getMatrix() { + return mButtons; + } + + @NonNull + public static ExtraKeysConstants.ExtraKeyDisplayMap getCharDisplayMapForStyle(String style) { + switch (style) { + case "arrows-only": + return EXTRA_KEY_DISPLAY_MAPS.ARROWS_ONLY_CHAR_DISPLAY; + case "arrows-all": + return EXTRA_KEY_DISPLAY_MAPS.LOTS_OF_ARROWS_CHAR_DISPLAY; + case "all": + return EXTRA_KEY_DISPLAY_MAPS.FULL_ISO_CHAR_DISPLAY; + case "none": + return new ExtraKeysConstants.ExtraKeyDisplayMap(); + default: + return EXTRA_KEY_DISPLAY_MAPS.DEFAULT_CHAR_DISPLAY; + } + } +} diff --git a/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysView.java b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysView.java new file mode 100644 index 0000000..e744a03 --- /dev/null +++ b/android/app/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysView.java @@ -0,0 +1,573 @@ +package com.termux.shared.termux.extrakeys; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.provider.Settings; +import android.util.AttributeSet; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ScheduledExecutorService; + +import java.util.Map; +import java.util.stream.Collectors; + +import android.view.HapticFeedbackConstants; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.GridLayout; +import android.widget.PopupWindow; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.termux.x11.utils.TermuxX11ExtraKeys; + +/** + * A {@link View} showing extra keys (such as Escape, Ctrl, Alt) not normally available on an Android soft + * keyboards. + *

+ * To use it, add following to a layout file and import it in your activity layout file or inflate + * it with a {@link androidx.viewpager.widget.ViewPager}.: + * {@code + * + * + * } + * + * Then in your activity, get its reference by a call to {@link android.app.Activity#findViewById(int)} + * or {@link LayoutInflater#inflate(int, ViewGroup)} if using {@link androidx.viewpager.widget.ViewPager}. + * Then call {@link #setExtraKeysViewClient(IExtraKeysView)} and pass it the implementation of + * {@link IExtraKeysView} so that you can receive callbacks. You can also override other values set + * in {@link ExtraKeysView#ExtraKeysView(Context, AttributeSet)} by calling the respective functions. + * If you extend {@link ExtraKeysView}, you can also set them in the constructor, but do call super(). + *

+ * After this you will have to make a call to {@link ExtraKeysView#reload() and pass + * it the {@link ExtraKeysInfo} to load and display the extra keys. Read its class javadocs for more + * info on how to create it. + *

+ * Termux app defines the view in res/layout/view_terminal_toolbar_extra_keys and + * inflates it in TerminalToolbarViewPager.instantiateItem() and sets the {@link ExtraKeysView} client + * and calls {@link ExtraKeysView#reload(ExtraKeysInfo). + * The {@link ExtraKeysInfo} is created by TermuxAppSharedProperties.setExtraKeys(). + * Then its got and the view height is adjusted in TermuxActivity.setTerminalToolbarHeight(). + * The client used is TermuxTerminalExtraKeys, which extends + * {@link com.termux.x11.utils.TermuxX11ExtraKeys } to handle Termux app specific logic and + * leave the rest to the super class. + */ +public final class ExtraKeysView extends GridLayout { + /** The client for the {@link ExtraKeysView}. */ + public interface IExtraKeysView { + /** + * This is called by {@link ExtraKeysView} when a button is clicked. This is also called + * for {@link #mRepetitiveKeys} and {@link ExtraKeyButton} that have a popup set. + * However, this is not called for {@link #mSpecialButtons}, whose state can instead be read + * via a call to {@link #readSpecialButton(SpecialButton, boolean)}. + * + * @param view The view that was clicked. + * @param buttonInfo The {@link ExtraKeyButton} for the button that was clicked. + * The button may be a {@link ExtraKeyButton#KEY_MACRO} set which can be + * checked with a call to {@link ExtraKeyButton#macro}. + * @param button The {@link Button} that was clicked. + */ + void onExtraKeyButtonClick(View view, ExtraKeyButton buttonInfo, Button button); + + /** + * This is called by {@link ExtraKeysView} when a button is clicked so that the client + * can perform any hepatic feedback. This is only called in the {@link Button.OnClickListener} + * and not for every repeat. Its also called for {@link #mSpecialButtons}. + * + * @param view The view that was clicked. + * @param buttonInfo The {@link ExtraKeyButton} for the button that was clicked. + * @param button The {@link Button} that was clicked. + * @return Return {@code true} if the client handled the feedback, otherwise {@code false} + * so that {@link ExtraKeysView#performExtraKeyButtonHapticFeedback(View, ExtraKeyButton, Button)} + * can handle it depending on system settings. + */ + boolean performExtraKeyButtonHapticFeedback(View view, ExtraKeyButton buttonInfo, Button button); + } + + /** Defines the default value for {@link #mButtonTextColor} */ + public static final int DEFAULT_BUTTON_TEXT_COLOR = 0xFFFFFFFF; + /** Defines the default value for {@link #mButtonActiveTextColor} */ + public static final int DEFAULT_BUTTON_ACTIVE_TEXT_COLOR = 0xFF80DEEA; + /** Defines the default value for {@link #mButtonBackgroundColor} */ + public static final int DEFAULT_BUTTON_BACKGROUND_COLOR = 0x00000000; + /** Defines the default value for {@link #mButtonActiveBackgroundColor} */ + public static final int DEFAULT_BUTTON_ACTIVE_BACKGROUND_COLOR = 0xFF7F7F7F; + + /** Defines the minimum allowed duration in milliseconds for {@link #mLongPressTimeout}. */ + public static final int MIN_LONG_PRESS_DURATION = 200; + /** Defines the maximum allowed duration in milliseconds for {@link #mLongPressTimeout}. */ + public static final int MAX_LONG_PRESS_DURATION = 3000; + /** Defines the fallback duration in milliseconds for {@link #mLongPressTimeout}. */ + public static final int FALLBACK_LONG_PRESS_DURATION = 400; + + /** Defines the minimum allowed duration in milliseconds for {@link #mLongPressRepeatDelay}. */ + public static final int MIN_LONG_PRESS__REPEAT_DELAY = 5; + /** Defines the maximum allowed duration in milliseconds for {@link #mLongPressRepeatDelay}. */ + public static final int MAX_LONG_PRESS__REPEAT_DELAY = 2000; + /** Defines the default duration in milliseconds for {@link #mLongPressRepeatDelay}. */ + public static final int DEFAULT_LONG_PRESS_REPEAT_DELAY = 80; + + + + /** The implementation of the {@link IExtraKeysView} that acts as a client for the {@link ExtraKeysView}. */ + private IExtraKeysView mExtraKeysViewClient; + + /** The map for the {@link SpecialButton} and their {@link SpecialButtonState}. Defaults to + * the one returned by {@link #getDefaultSpecialButtons(ExtraKeysView)}. */ + private Map mSpecialButtons; + + /** The keys for the {@link SpecialButton} added to {@link #mSpecialButtons}. This is automatically + * set when the call to {@link #setSpecialButtons(Map)} is made. */ + private Set mSpecialButtonsKeys; + + + /** + * The list of keys for which auto repeat of key should be triggered if its extra keys button + * is long pressed. This is done by calling {@link IExtraKeysView#onExtraKeyButtonClick(View, ExtraKeyButton, Button)} + * every {@link #mLongPressRepeatDelay} seconds after {@link #mLongPressTimeout} has passed. + * The default keys are defined by {@link ExtraKeysConstants#PRIMARY_REPETITIVE_KEYS}. + */ + private List mRepetitiveKeys; + + + /** The text color for the extra keys button. Defaults to {@link #DEFAULT_BUTTON_TEXT_COLOR}. */ + private int mButtonTextColor; + /** The text color for the extra keys button when its active. + * Defaults to {@link #DEFAULT_BUTTON_ACTIVE_TEXT_COLOR}. */ + private int mButtonActiveTextColor; + /** The background color for the extra keys button. Defaults to {@link #DEFAULT_BUTTON_BACKGROUND_COLOR}. */ + private int mButtonBackgroundColor; + /** The background color for the extra keys button when its active. Defaults to + * {@link #DEFAULT_BUTTON_ACTIVE_BACKGROUND_COLOR}. */ + private int mButtonActiveBackgroundColor; + + + /** + * Defines the duration in milliseconds before a press turns into a long press. The default + * duration used is the one returned by a call to {@link ViewConfiguration#getLongPressTimeout()} + * which will return the system defined duration which can be changed in accessibility settings. + * The duration must be in between {@link #MIN_LONG_PRESS_DURATION} and {@link #MAX_LONG_PRESS_DURATION}, + * otherwise {@link #FALLBACK_LONG_PRESS_DURATION} is used. + */ + private int mLongPressTimeout; + + /** + * Defines the duration in milliseconds for the delay between trigger of each repeat of + * {@link #mRepetitiveKeys}. The default value is defined by {@link #DEFAULT_LONG_PRESS_REPEAT_DELAY}. + * The duration must be in between {@link #MIN_LONG_PRESS__REPEAT_DELAY} and + * {@link #MAX_LONG_PRESS__REPEAT_DELAY}, otherwise {@link #DEFAULT_LONG_PRESS_REPEAT_DELAY} is used. + */ + private int mLongPressRepeatDelay; + + + /** The popup window shown if {@link ExtraKeyButton#popup} returns a {@code non-null} value + * and a swipe up action is done on an extra key. */ + private PopupWindow mPopupWindow; + + private ScheduledExecutorService mScheduledExecutor; + private Handler mHandler; + private SpecialButtonsLongHoldRunnable mSpecialButtonsLongHoldRunnable; + private int mLongPressCount; + + + public ExtraKeysView(Context context, AttributeSet attrs) { + super(context, attrs); + + setRepetitiveKeys(ExtraKeysConstants.PRIMARY_REPETITIVE_KEYS); + setSpecialButtons(getDefaultSpecialButtons(this)); + + setButtonColors(DEFAULT_BUTTON_TEXT_COLOR, DEFAULT_BUTTON_ACTIVE_TEXT_COLOR, DEFAULT_BUTTON_BACKGROUND_COLOR, DEFAULT_BUTTON_ACTIVE_BACKGROUND_COLOR); + + setLongPressTimeout(ViewConfiguration.getLongPressTimeout()); + setLongPressRepeatDelay(DEFAULT_LONG_PRESS_REPEAT_DELAY); + } + + + /** Set {@link #mExtraKeysViewClient}. */ + public void setExtraKeysViewClient(IExtraKeysView extraKeysViewClient) { + mExtraKeysViewClient = extraKeysViewClient; + } + + /** Set {@link #mRepetitiveKeys}. Must not be {@code null}. */ + public void setRepetitiveKeys(@NonNull List repetitiveKeys) { + mRepetitiveKeys = repetitiveKeys; + } + + /** Set {@link #mSpecialButtonsKeys}. Must not be {@code null}. */ + public void setSpecialButtons(@NonNull Map specialButtons) { + mSpecialButtons = specialButtons; + mSpecialButtonsKeys = this.mSpecialButtons.keySet().stream().map(SpecialButton::getKey).collect(Collectors.toSet()); + } + + + /** + * Set the {@link ExtraKeysView} button colors. + * + * @param buttonTextColor The value for {@link #mButtonTextColor}. + * @param buttonActiveTextColor The value for {@link #mButtonActiveTextColor}. + * @param buttonBackgroundColor The value for {@link #mButtonBackgroundColor}. + * @param buttonActiveBackgroundColor The value for {@link #mButtonActiveBackgroundColor}. + */ + public void setButtonColors(int buttonTextColor, int buttonActiveTextColor, int buttonBackgroundColor, int buttonActiveBackgroundColor) { + mButtonTextColor = buttonTextColor; + mButtonActiveTextColor = buttonActiveTextColor; + mButtonBackgroundColor = buttonBackgroundColor; + mButtonActiveBackgroundColor = buttonActiveBackgroundColor; + } + + + /** Get {@link #mButtonTextColor}. */ + public int getButtonTextColor() { + return mButtonTextColor; + } + + /** Get {@link #mButtonActiveTextColor}. */ + public int getButtonActiveTextColor() { + return mButtonActiveTextColor; + } + + /** Set {@link #mLongPressTimeout}. */ + public void setLongPressTimeout(int longPressDuration) { + if (longPressDuration >= MIN_LONG_PRESS_DURATION && longPressDuration <= MAX_LONG_PRESS_DURATION) { + mLongPressTimeout = longPressDuration; + } else { + mLongPressTimeout = FALLBACK_LONG_PRESS_DURATION; + } + } + + /** Set {@link #mLongPressRepeatDelay}. */ + public void setLongPressRepeatDelay(int longPressRepeatDelay) { + if (mLongPressRepeatDelay >= MIN_LONG_PRESS__REPEAT_DELAY && mLongPressRepeatDelay <= MAX_LONG_PRESS__REPEAT_DELAY) { + mLongPressRepeatDelay = longPressRepeatDelay; + } else { + mLongPressRepeatDelay = DEFAULT_LONG_PRESS_REPEAT_DELAY; + } + } + + /** Get the default map that can be used for {@link #mSpecialButtons}. */ + @NonNull + public Map getDefaultSpecialButtons(ExtraKeysView extraKeysView) { + return new HashMap() {{ + put(SpecialButton.CTRL, new SpecialButtonState(extraKeysView)); + put(SpecialButton.ALT, new SpecialButtonState(extraKeysView)); + put(SpecialButton.SHIFT, new SpecialButtonState(extraKeysView)); + put(SpecialButton.META, new SpecialButtonState(extraKeysView)); + put(SpecialButton.FN, new SpecialButtonState(extraKeysView)); + }}; + } + + /** + * Reload this instance of {@link ExtraKeysView} with the info passed in {@code extraKeysInfo}. + */ + @SuppressLint("ClickableViewAccessibility") + public void reload() { + TermuxX11ExtraKeys.setExtraKeys(); + ExtraKeysInfo extraKeysInfo = TermuxX11ExtraKeys.getExtraKeysInfo(); + if (extraKeysInfo == null) + return; + + for(SpecialButtonState state : mSpecialButtons.values()) + state.buttons = new ArrayList<>(); + + removeAllViews(); + + ExtraKeyButton[][] buttons = extraKeysInfo.getMatrix(); + + setRowCount(buttons.length); + setColumnCount(maximumLength(buttons)); + + for (int row = 0; row < buttons.length; row++) { + for (int col = 0; col < buttons[row].length; col++) { + final ExtraKeyButton buttonInfo = buttons[row][col]; + + Button button; + if (isSpecialButton(buttonInfo)) { + button = createSpecialButton(buttonInfo.key, true); + if (button == null) return; + } else { + button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); + } + + button.setBackground(new ColorDrawable(Color.BLACK) { + public boolean isStateful() { + return true; + } + public boolean hasFocusStateSpecified() { + return true; + } + }); + button.setText(buttonInfo.display); + button.setTextColor(mButtonTextColor); + button.setAllCaps(true); + button.setPadding(0, 0, 0, 0); + + button.setOnClickListener(view -> { + performExtraKeyButtonHapticFeedback(view, buttonInfo, button); + onAnyExtraKeyButtonClick(view, buttonInfo, button); + }); + + button.setOnTouchListener((view, event) -> { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + view.setBackgroundColor(mButtonActiveBackgroundColor); + // Start long press scheduled executors which will be stopped in next MotionEvent + startScheduledExecutors(view, buttonInfo, button); + return true; + + case MotionEvent.ACTION_MOVE: + if (buttonInfo.popup != null) { + // Show popup on swipe up + if (mPopupWindow == null && event.getY() < 0) { + stopScheduledExecutors(); + view.setBackgroundColor(mButtonBackgroundColor); + showPopup(view, buttonInfo.popup); + } + if (mPopupWindow != null && event.getY() > 0) { + view.setBackgroundColor(mButtonActiveBackgroundColor); + dismissPopup(); + } + } + return true; + + case MotionEvent.ACTION_CANCEL: + view.setBackgroundColor(mButtonBackgroundColor); + stopScheduledExecutors(); + return true; + + case MotionEvent.ACTION_UP: + view.setBackgroundColor(mButtonBackgroundColor); + stopScheduledExecutors(); + // If ACTION_UP up was not from a repetitive key or was with a key with a popup button + if (mLongPressCount == 0 || mPopupWindow != null) { + // Trigger popup button click if swipe up complete + if (mPopupWindow != null) { + dismissPopup(); + if (buttonInfo.popup != null) { + onAnyExtraKeyButtonClick(view, buttonInfo.popup, button); + } + } else { + view.performClick(); + } + } + return true; + + default: + return true; + } + }); + + LayoutParams param = new GridLayout.LayoutParams(); + param.width = 0; + param.height = 0; + param.setMargins(0, 0, 0, 0); + param.columnSpec = GridLayout.spec(col, GridLayout.FILL, 1.f); + param.rowSpec = GridLayout.spec(row, GridLayout.FILL, 1.f); + button.setLayoutParams(param); + + addView(button); + } + } + } + + public void onExtraKeyButtonClick(View view, ExtraKeyButton buttonInfo, Button button) { + if (mExtraKeysViewClient != null) + mExtraKeysViewClient.onExtraKeyButtonClick(view, buttonInfo, button); + } + + public void performExtraKeyButtonHapticFeedback(View view, ExtraKeyButton buttonInfo, Button button) { + if (mExtraKeysViewClient != null) { + // If client handled the feedback, then just return + if (mExtraKeysViewClient.performExtraKeyButtonHapticFeedback(view, buttonInfo, button)) + return; + } + + if (Settings.System.getInt(getContext().getContentResolver(), + Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) != 0) { + + if (Build.VERSION.SDK_INT >= 28) { + button.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); + } else { + // Perform haptic feedback only if no total silence mode enabled. + if (Settings.Global.getInt(getContext().getContentResolver(), "zen_mode", 0) != 2) { + button.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); + } + } + } + } + + public void onAnyExtraKeyButtonClick(View view, @NonNull ExtraKeyButton buttonInfo, Button button) { + if (isSpecialButton(buttonInfo)) { + if (mLongPressCount > 0) return; + SpecialButtonState state = mSpecialButtons.get(SpecialButton.valueOf(buttonInfo.key)); + if (state == null) return; + + // Toggle active state and disable lock state if new state is not active + state.setIsActive(!state.isActive); + if (!state.isActive) + state.setIsLocked(false); + } else { + onExtraKeyButtonClick(view, buttonInfo, button); + } + } + + public void startScheduledExecutors(View view, ExtraKeyButton buttonInfo, Button button) { + stopScheduledExecutors(); + mLongPressCount = 0; + if (mRepetitiveKeys.contains(buttonInfo.key)) { + // Auto repeat key if long pressed until ACTION_UP stops it by calling stopScheduledExecutors. + // Currently, only one (last) repeat key can run at a time. Old ones are stopped. + mScheduledExecutor = Executors.newSingleThreadScheduledExecutor(); + mScheduledExecutor.scheduleWithFixedDelay(() -> { + mLongPressCount++; + onExtraKeyButtonClick(view, buttonInfo, button); + }, mLongPressTimeout, mLongPressRepeatDelay, TimeUnit.MILLISECONDS); + } else if (isSpecialButton(buttonInfo)) { + // Lock the key if long pressed by running mSpecialButtonsLongHoldRunnable after + // waiting for mLongPressTimeout milliseconds. If user does not long press, then the + // ACTION_UP triggered will cancel the runnable by calling stopScheduledExecutors before + // it has a chance to run. + SpecialButtonState state = mSpecialButtons.get(SpecialButton.valueOf(buttonInfo.key)); + if (state == null) return; + if (mHandler == null) + mHandler = new Handler(Looper.getMainLooper()); + mSpecialButtonsLongHoldRunnable = new SpecialButtonsLongHoldRunnable(state); + mHandler.postDelayed(mSpecialButtonsLongHoldRunnable, mLongPressTimeout); + } + } + + public void stopScheduledExecutors() { + if (mScheduledExecutor != null) { + mScheduledExecutor.shutdownNow(); + mScheduledExecutor = null; + } + + if (mSpecialButtonsLongHoldRunnable != null && mHandler != null) { + mHandler.removeCallbacks(mSpecialButtonsLongHoldRunnable); + mSpecialButtonsLongHoldRunnable = null; + } + } + + public class SpecialButtonsLongHoldRunnable implements Runnable { + public final SpecialButtonState mState; + + public SpecialButtonsLongHoldRunnable(SpecialButtonState state) { + mState = state; + } + + public void run() { + // Toggle active and lock state + mState.setIsLocked(!mState.isActive); + mState.setIsActive(!mState.isActive); + mLongPressCount++; + } + } + + void showPopup(View view, ExtraKeyButton extraButton) { + int width = view.getMeasuredWidth(); + int height = view.getMeasuredHeight(); + Button button; + if (isSpecialButton(extraButton)) { + button = createSpecialButton(extraButton.key, false); + if (button == null) return; + } else { + button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); + button.setTextColor(mButtonTextColor); + } + button.setText(extraButton.display); + button.setAllCaps(true); + button.setPadding(0, 0, 0, 0); + button.setMinHeight(0); + button.setMinWidth(0); + button.setMinimumWidth(0); + button.setMinimumHeight(0); + button.setWidth(width); + button.setHeight(height); + button.setBackgroundColor(mButtonActiveBackgroundColor); + mPopupWindow = new PopupWindow(this); + mPopupWindow.setWidth(LayoutParams.WRAP_CONTENT); + mPopupWindow.setHeight(LayoutParams.WRAP_CONTENT); + mPopupWindow.setContentView(button); + mPopupWindow.setOutsideTouchable(true); + mPopupWindow.setFocusable(false); + mPopupWindow.showAsDropDown(view, 0, -2 * height); + } + + public void dismissPopup() { + mPopupWindow.setContentView(null); + mPopupWindow.dismiss(); + mPopupWindow = null; + } + + /** Check whether a {@link ExtraKeyButton} is a {@link SpecialButton}. */ + public boolean isSpecialButton(ExtraKeyButton button) { + return mSpecialButtonsKeys.contains(button.key); + } + + /** + * Read whether {@link SpecialButton} registered in {@link #mSpecialButtons} is active or not. + * + * @param specialButton The {@link SpecialButton} to read. + * @param autoSetInActive Set to {@code true} if {@link SpecialButtonState#isActive} should be + * set {@code false} if button is not locked. + * @return Returns {@code null} if button does not exist in {@link #mSpecialButtons}. If button + * exists, then returns {@code true} if the button is created in {@link ExtraKeysView} + * and is active, otherwise {@code false}. + */ + @Nullable + public Boolean readSpecialButton(SpecialButton specialButton, boolean autoSetInActive) { + SpecialButtonState state = mSpecialButtons.get(specialButton); + if (state == null) return null; + + if (!state.isCreated || !state.isActive) + return false; + + // Disable active state only if not locked + if (autoSetInActive && !state.isLocked) + state.setIsActive(false); + + return true; + } + + public Button createSpecialButton(String buttonKey, boolean needUpdate) { + SpecialButtonState state = mSpecialButtons.get(SpecialButton.valueOf(buttonKey)); + if (state == null) return null; + state.setIsCreated(true); + Button button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); + button.setTextColor(state.isActive ? mButtonActiveTextColor : mButtonTextColor); + if (needUpdate) { + state.buttons.add(button); + } + return button; + } + + /** + * General util function to compute the longest column length in a matrix. + */ + public static int maximumLength(Object[][] matrix) { + int m = 0; + for (Object[] row : matrix) + m = Math.max(m, row.length); + return m; + } +} diff --git a/android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButton.java b/android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButton.java new file mode 100644 index 0000000..6cb3052 --- /dev/null +++ b/android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButton.java @@ -0,0 +1,53 @@ +package com.termux.shared.termux.extrakeys; + +import androidx.annotation.NonNull; + +import java.util.HashMap; + +/** The {@link Class} that implements special buttons for {@link ExtraKeysView}. */ +public class SpecialButton { + + private static final HashMap map = new HashMap<>(); + + public static final SpecialButton CTRL = new SpecialButton("CTRL"); + public static final SpecialButton ALT = new SpecialButton("ALT"); + public static final SpecialButton SHIFT = new SpecialButton("SHIFT"); + public static final SpecialButton META = new SpecialButton("META"); + public static final SpecialButton FN = new SpecialButton("FN"); + + /** The special button key. */ + private final String key; + + /** + * Initialize a {@link SpecialButton}. + * + * @param key The unique key name for the special button. The key is registered in {@link #map} + * with which the {@link SpecialButton} can be retrieved via a call to + * {@link #valueOf(String)}. + */ + public SpecialButton(@NonNull final String key) { + this.key = key; + map.put(key, this); + } + + /** Get {@link #key} for this {@link SpecialButton}. */ + public String getKey() { + return key; + } + + /** + * Get the {@link SpecialButton} for {@code key}. + * + * @param key The unique key name for the special button. + */ + public static SpecialButton valueOf(String key) { + return map.get(key); + } + + @NonNull + @Override + public String toString() { + return key; + } + +} diff --git a/android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButtonState.java b/android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButtonState.java new file mode 100644 index 0000000..c960ad5 --- /dev/null +++ b/android/app/src/main/java/com/termux/shared/termux/extrakeys/SpecialButtonState.java @@ -0,0 +1,50 @@ +package com.termux.shared.termux.extrakeys; + +import android.widget.Button; + +import java.util.ArrayList; +import java.util.List; + +/** The {@link Class} that maintains a state of a {@link SpecialButton} */ +public class SpecialButtonState { + + /** If special button has been created for the {@link ExtraKeysView}. */ + boolean isCreated = false; + /** If special button is active. */ + boolean isActive = false; + /** If special button is locked due to long hold on it and should not be deactivated if its + * state is read. */ + boolean isLocked = false; + + List