Squashed 'deps/nostalgia/' content from commit 9cb6bd4a
git-subtree-dir: deps/nostalgia git-subtree-split: 9cb6bd4a32e9f39a858f72443ff5c6d40489fe22
This commit is contained in:
		
							
								
								
									
										195
									
								
								deps/glfw/src/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								deps/glfw/src/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,195 @@ | ||||
|  | ||||
| set(common_HEADERS internal.h mappings.h | ||||
|                    "${GLFW_BINARY_DIR}/src/glfw_config.h" | ||||
|                    "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" | ||||
|                    "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") | ||||
| set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c) | ||||
|  | ||||
| add_custom_target(update_mappings | ||||
|     COMMAND "${CMAKE_COMMAND}" -P "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" mappings.h.in mappings.h | ||||
|     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" | ||||
|     COMMENT "Updating gamepad mappings from upstream repository" | ||||
|     SOURCES mappings.h.in "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" | ||||
|     VERBATIM) | ||||
|  | ||||
| set_target_properties(update_mappings PROPERTIES FOLDER "GLFW3") | ||||
|  | ||||
| if (_GLFW_COCOA) | ||||
|     set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h | ||||
|                      posix_thread.h nsgl_context.h egl_context.h osmesa_context.h) | ||||
|     set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m | ||||
|                      cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c | ||||
|                      nsgl_context.m egl_context.c osmesa_context.c) | ||||
| elseif (_GLFW_WIN32) | ||||
|     set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h | ||||
|                      wgl_context.h egl_context.h osmesa_context.h) | ||||
|     set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c | ||||
|                      win32_monitor.c win32_time.c win32_thread.c win32_window.c | ||||
|                      wgl_context.c egl_context.c osmesa_context.c) | ||||
| elseif (_GLFW_X11) | ||||
|     set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h posix_time.h | ||||
|                      posix_thread.h glx_context.h egl_context.h osmesa_context.h) | ||||
|     set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c | ||||
|                      xkb_unicode.c posix_time.c posix_thread.c glx_context.c | ||||
|                      egl_context.c osmesa_context.c) | ||||
| elseif (_GLFW_WAYLAND) | ||||
|     set(glfw_HEADERS ${common_HEADERS} wl_platform.h | ||||
|                      posix_time.h posix_thread.h xkb_unicode.h egl_context.h | ||||
|                      osmesa_context.h) | ||||
|     set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c | ||||
|                      posix_time.c posix_thread.c xkb_unicode.c | ||||
|                      egl_context.c osmesa_context.c) | ||||
|  | ||||
|     ecm_add_wayland_client_protocol(glfw_SOURCES | ||||
|         PROTOCOL | ||||
|         "${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml" | ||||
|         BASENAME xdg-shell) | ||||
|     ecm_add_wayland_client_protocol(glfw_SOURCES | ||||
|         PROTOCOL | ||||
|         "${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" | ||||
|         BASENAME xdg-decoration) | ||||
|     ecm_add_wayland_client_protocol(glfw_SOURCES | ||||
|         PROTOCOL | ||||
|         "${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml" | ||||
|         BASENAME viewporter) | ||||
|     ecm_add_wayland_client_protocol(glfw_SOURCES | ||||
|         PROTOCOL | ||||
|         "${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml" | ||||
|         BASENAME relative-pointer-unstable-v1) | ||||
|     ecm_add_wayland_client_protocol(glfw_SOURCES | ||||
|         PROTOCOL | ||||
|         "${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" | ||||
|         BASENAME pointer-constraints-unstable-v1) | ||||
|     ecm_add_wayland_client_protocol(glfw_SOURCES | ||||
|         PROTOCOL | ||||
|         "${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml" | ||||
|         BASENAME idle-inhibit-unstable-v1) | ||||
| elseif (_GLFW_OSMESA) | ||||
|     set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h | ||||
|                      posix_time.h posix_thread.h osmesa_context.h) | ||||
|     set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c | ||||
|                      null_joystick.c posix_time.c posix_thread.c osmesa_context.c) | ||||
| endif() | ||||
|  | ||||
| if (_GLFW_X11 OR _GLFW_WAYLAND) | ||||
|     if (CMAKE_SYSTEM_NAME STREQUAL "Linux") | ||||
|         set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h) | ||||
|         set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c) | ||||
|     else() | ||||
|         set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h) | ||||
|         set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c) | ||||
|     endif() | ||||
| endif() | ||||
|  | ||||
| # Workaround for CMake not knowing about .m files before version 3.16 | ||||
| if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE) | ||||
|     set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m | ||||
|                                 cocoa_window.m nsgl_context.m PROPERTIES | ||||
|                                 LANGUAGE C) | ||||
| endif() | ||||
|  | ||||
| add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) | ||||
| set_target_properties(glfw PROPERTIES | ||||
|                       OUTPUT_NAME ${GLFW_LIB_NAME} | ||||
|                       VERSION ${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR} | ||||
|                       SOVERSION ${GLFW_VERSION_MAJOR} | ||||
|                       POSITION_INDEPENDENT_CODE ON | ||||
|                       FOLDER "GLFW3") | ||||
|  | ||||
| if (CMAKE_VERSION VERSION_EQUAL "3.1.0" OR | ||||
|     CMAKE_VERSION VERSION_GREATER "3.1.0") | ||||
|  | ||||
|     set_target_properties(glfw PROPERTIES C_STANDARD 99) | ||||
| else() | ||||
|     # Remove this fallback when removing support for CMake version less than 3.1 | ||||
|     target_compile_options(glfw PRIVATE | ||||
|                            "$<$<C_COMPILER_ID:AppleClang>:-std=c99>" | ||||
|                            "$<$<C_COMPILER_ID:Clang>:-std=c99>" | ||||
|                            "$<$<C_COMPILER_ID:GNU>:-std=c99>") | ||||
| endif() | ||||
|  | ||||
| target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H) | ||||
| target_include_directories(glfw PUBLIC | ||||
|                            "$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>" | ||||
|                            "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>") | ||||
| target_include_directories(glfw PRIVATE | ||||
|                            "${GLFW_SOURCE_DIR}/src" | ||||
|                            "${GLFW_BINARY_DIR}/src" | ||||
|                            ${glfw_INCLUDE_DIRS}) | ||||
| target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES}) | ||||
|  | ||||
| # Make GCC warn about declarations that VS 2010 and 2012 won't accept for all | ||||
| # source files that VS will build (Clang ignores this because we set -std=c99) | ||||
| if (CMAKE_C_COMPILER_ID STREQUAL "GNU") | ||||
|     set_source_files_properties(context.c init.c input.c monitor.c vulkan.c | ||||
|                                 window.c win32_init.c win32_joystick.c | ||||
|                                 win32_monitor.c win32_time.c win32_thread.c | ||||
|                                 win32_window.c wgl_context.c egl_context.c | ||||
|                                 osmesa_context.c PROPERTIES | ||||
|                                 COMPILE_FLAGS -Wdeclaration-after-statement) | ||||
| endif() | ||||
|  | ||||
| # Enable a reasonable set of warnings | ||||
| # NOTE: The order matters here, Clang-CL matches both MSVC and Clang | ||||
| if (MSVC) | ||||
|     target_compile_options(glfw PRIVATE "/W3") | ||||
| elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR | ||||
|         CMAKE_C_COMPILER_ID STREQUAL "Clang" OR | ||||
|         CMAKE_C_COMPILER_ID STREQUAL "AppleClang") | ||||
|  | ||||
|     target_compile_options(glfw PRIVATE "-Wall") | ||||
| endif() | ||||
|  | ||||
| if (_GLFW_WIN32) | ||||
|     target_compile_definitions(glfw PRIVATE UNICODE _UNICODE) | ||||
| endif() | ||||
|  | ||||
| # HACK: When building on MinGW, WINVER and UNICODE need to be defined before | ||||
| # the inclusion of stddef.h (by glfw3.h), which is itself included before | ||||
| # win32_platform.h.  We define them here until a saner solution can be found | ||||
| # NOTE: MinGW-w64 and Visual C++ do /not/ need this hack. | ||||
| if (MINGW) | ||||
|     target_compile_definitions(glfw PRIVATE WINVER=0x0501) | ||||
| endif() | ||||
|  | ||||
| if (BUILD_SHARED_LIBS) | ||||
|     if (WIN32) | ||||
|         if (MINGW) | ||||
|             # Remove the dependency on the shared version of libgcc | ||||
|             # NOTE: MinGW-w64 has the correct default but MinGW needs this | ||||
|             target_link_libraries(glfw PRIVATE "-static-libgcc") | ||||
|  | ||||
|             # Remove the lib prefix on the DLL (but not the import library) | ||||
|             set_target_properties(glfw PROPERTIES PREFIX "") | ||||
|  | ||||
|             # Add a suffix to the import library to avoid naming conflicts | ||||
|             set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a") | ||||
|         else() | ||||
|             # Add a suffix to the import library to avoid naming conflicts | ||||
|             set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") | ||||
|         endif() | ||||
|  | ||||
|         target_compile_definitions(glfw INTERFACE GLFW_DLL) | ||||
|     elseif (APPLE) | ||||
|         # Add -fno-common to work around a bug in Apple's GCC | ||||
|         target_compile_options(glfw PRIVATE "-fno-common") | ||||
|     endif() | ||||
|  | ||||
|     if (UNIX) | ||||
|         # Hide symbols not explicitly tagged for export from the shared library | ||||
|         target_compile_options(glfw PRIVATE "-fvisibility=hidden") | ||||
|     endif() | ||||
| endif() | ||||
|  | ||||
| if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC") | ||||
|     target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) | ||||
| endif() | ||||
|  | ||||
| if (GLFW_INSTALL) | ||||
|     install(TARGETS glfw | ||||
|             EXPORT glfwTargets | ||||
|             RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" | ||||
|             ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" | ||||
|             LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") | ||||
| endif() | ||||
|  | ||||
							
								
								
									
										623
									
								
								deps/glfw/src/cocoa_init.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										623
									
								
								deps/glfw/src/cocoa_init.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,623 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 macOS - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
| #include <sys/param.h> // For MAXPATHLEN | ||||
|  | ||||
| // Needed for _NSGetProgname | ||||
| #include <crt_externs.h> | ||||
|  | ||||
| // Change to our application bundle's resources directory, if present | ||||
| // | ||||
| static void changeToResourcesDirectory(void) | ||||
| { | ||||
|     char resourcesPath[MAXPATHLEN]; | ||||
|  | ||||
|     CFBundleRef bundle = CFBundleGetMainBundle(); | ||||
|     if (!bundle) | ||||
|         return; | ||||
|  | ||||
|     CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle); | ||||
|  | ||||
|     CFStringRef last = CFURLCopyLastPathComponent(resourcesURL); | ||||
|     if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo) | ||||
|     { | ||||
|         CFRelease(last); | ||||
|         CFRelease(resourcesURL); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     CFRelease(last); | ||||
|  | ||||
|     if (!CFURLGetFileSystemRepresentation(resourcesURL, | ||||
|                                           true, | ||||
|                                           (UInt8*) resourcesPath, | ||||
|                                           MAXPATHLEN)) | ||||
|     { | ||||
|         CFRelease(resourcesURL); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     CFRelease(resourcesURL); | ||||
|  | ||||
|     chdir(resourcesPath); | ||||
| } | ||||
|  | ||||
| // Set up the menu bar (manually) | ||||
| // This is nasty, nasty stuff -- calls to undocumented semi-private APIs that | ||||
| // could go away at any moment, lots of stuff that really should be | ||||
| // localize(d|able), etc.  Add a nib to save us this horror. | ||||
| // | ||||
| static void createMenuBar(void) | ||||
| { | ||||
|     size_t i; | ||||
|     NSString* appName = nil; | ||||
|     NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary]; | ||||
|     NSString* nameKeys[] = | ||||
|     { | ||||
|         @"CFBundleDisplayName", | ||||
|         @"CFBundleName", | ||||
|         @"CFBundleExecutable", | ||||
|     }; | ||||
|  | ||||
|     // Try to figure out what the calling application is called | ||||
|  | ||||
|     for (i = 0;  i < sizeof(nameKeys) / sizeof(nameKeys[0]);  i++) | ||||
|     { | ||||
|         id name = bundleInfo[nameKeys[i]]; | ||||
|         if (name && | ||||
|             [name isKindOfClass:[NSString class]] && | ||||
|             ![name isEqualToString:@""]) | ||||
|         { | ||||
|             appName = name; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (!appName) | ||||
|     { | ||||
|         char** progname = _NSGetProgname(); | ||||
|         if (progname && *progname) | ||||
|             appName = @(*progname); | ||||
|         else | ||||
|             appName = @"GLFW Application"; | ||||
|     } | ||||
|  | ||||
|     NSMenu* bar = [[NSMenu alloc] init]; | ||||
|     [NSApp setMainMenu:bar]; | ||||
|  | ||||
|     NSMenuItem* appMenuItem = | ||||
|         [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; | ||||
|     NSMenu* appMenu = [[NSMenu alloc] init]; | ||||
|     [appMenuItem setSubmenu:appMenu]; | ||||
|  | ||||
|     [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName] | ||||
|                        action:@selector(orderFrontStandardAboutPanel:) | ||||
|                 keyEquivalent:@""]; | ||||
|     [appMenu addItem:[NSMenuItem separatorItem]]; | ||||
|     NSMenu* servicesMenu = [[NSMenu alloc] init]; | ||||
|     [NSApp setServicesMenu:servicesMenu]; | ||||
|     [[appMenu addItemWithTitle:@"Services" | ||||
|                        action:NULL | ||||
|                 keyEquivalent:@""] setSubmenu:servicesMenu]; | ||||
|     [servicesMenu release]; | ||||
|     [appMenu addItem:[NSMenuItem separatorItem]]; | ||||
|     [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName] | ||||
|                        action:@selector(hide:) | ||||
|                 keyEquivalent:@"h"]; | ||||
|     [[appMenu addItemWithTitle:@"Hide Others" | ||||
|                        action:@selector(hideOtherApplications:) | ||||
|                 keyEquivalent:@"h"] | ||||
|         setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand]; | ||||
|     [appMenu addItemWithTitle:@"Show All" | ||||
|                        action:@selector(unhideAllApplications:) | ||||
|                 keyEquivalent:@""]; | ||||
|     [appMenu addItem:[NSMenuItem separatorItem]]; | ||||
|     [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName] | ||||
|                        action:@selector(terminate:) | ||||
|                 keyEquivalent:@"q"]; | ||||
|  | ||||
|     NSMenuItem* windowMenuItem = | ||||
|         [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; | ||||
|     [bar release]; | ||||
|     NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; | ||||
|     [NSApp setWindowsMenu:windowMenu]; | ||||
|     [windowMenuItem setSubmenu:windowMenu]; | ||||
|  | ||||
|     [windowMenu addItemWithTitle:@"Minimize" | ||||
|                           action:@selector(performMiniaturize:) | ||||
|                    keyEquivalent:@"m"]; | ||||
|     [windowMenu addItemWithTitle:@"Zoom" | ||||
|                           action:@selector(performZoom:) | ||||
|                    keyEquivalent:@""]; | ||||
|     [windowMenu addItem:[NSMenuItem separatorItem]]; | ||||
|     [windowMenu addItemWithTitle:@"Bring All to Front" | ||||
|                           action:@selector(arrangeInFront:) | ||||
|                    keyEquivalent:@""]; | ||||
|  | ||||
|     // TODO: Make this appear at the bottom of the menu (for consistency) | ||||
|     [windowMenu addItem:[NSMenuItem separatorItem]]; | ||||
|     [[windowMenu addItemWithTitle:@"Enter Full Screen" | ||||
|                            action:@selector(toggleFullScreen:) | ||||
|                     keyEquivalent:@"f"] | ||||
|      setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand]; | ||||
|  | ||||
|     // Prior to Snow Leopard, we need to use this oddly-named semi-private API | ||||
|     // to get the application menu working properly. | ||||
|     SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:"); | ||||
|     [NSApp performSelector:setAppleMenuSelector withObject:appMenu]; | ||||
| } | ||||
|  | ||||
| // Create key code translation tables | ||||
| // | ||||
| static void createKeyTables(void) | ||||
| { | ||||
|     int scancode; | ||||
|  | ||||
|     memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes)); | ||||
|     memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes)); | ||||
|  | ||||
|     _glfw.ns.keycodes[0x1D] = GLFW_KEY_0; | ||||
|     _glfw.ns.keycodes[0x12] = GLFW_KEY_1; | ||||
|     _glfw.ns.keycodes[0x13] = GLFW_KEY_2; | ||||
|     _glfw.ns.keycodes[0x14] = GLFW_KEY_3; | ||||
|     _glfw.ns.keycodes[0x15] = GLFW_KEY_4; | ||||
|     _glfw.ns.keycodes[0x17] = GLFW_KEY_5; | ||||
|     _glfw.ns.keycodes[0x16] = GLFW_KEY_6; | ||||
|     _glfw.ns.keycodes[0x1A] = GLFW_KEY_7; | ||||
|     _glfw.ns.keycodes[0x1C] = GLFW_KEY_8; | ||||
|     _glfw.ns.keycodes[0x19] = GLFW_KEY_9; | ||||
|     _glfw.ns.keycodes[0x00] = GLFW_KEY_A; | ||||
|     _glfw.ns.keycodes[0x0B] = GLFW_KEY_B; | ||||
|     _glfw.ns.keycodes[0x08] = GLFW_KEY_C; | ||||
|     _glfw.ns.keycodes[0x02] = GLFW_KEY_D; | ||||
|     _glfw.ns.keycodes[0x0E] = GLFW_KEY_E; | ||||
|     _glfw.ns.keycodes[0x03] = GLFW_KEY_F; | ||||
|     _glfw.ns.keycodes[0x05] = GLFW_KEY_G; | ||||
|     _glfw.ns.keycodes[0x04] = GLFW_KEY_H; | ||||
|     _glfw.ns.keycodes[0x22] = GLFW_KEY_I; | ||||
|     _glfw.ns.keycodes[0x26] = GLFW_KEY_J; | ||||
|     _glfw.ns.keycodes[0x28] = GLFW_KEY_K; | ||||
|     _glfw.ns.keycodes[0x25] = GLFW_KEY_L; | ||||
|     _glfw.ns.keycodes[0x2E] = GLFW_KEY_M; | ||||
|     _glfw.ns.keycodes[0x2D] = GLFW_KEY_N; | ||||
|     _glfw.ns.keycodes[0x1F] = GLFW_KEY_O; | ||||
|     _glfw.ns.keycodes[0x23] = GLFW_KEY_P; | ||||
|     _glfw.ns.keycodes[0x0C] = GLFW_KEY_Q; | ||||
|     _glfw.ns.keycodes[0x0F] = GLFW_KEY_R; | ||||
|     _glfw.ns.keycodes[0x01] = GLFW_KEY_S; | ||||
|     _glfw.ns.keycodes[0x11] = GLFW_KEY_T; | ||||
|     _glfw.ns.keycodes[0x20] = GLFW_KEY_U; | ||||
|     _glfw.ns.keycodes[0x09] = GLFW_KEY_V; | ||||
|     _glfw.ns.keycodes[0x0D] = GLFW_KEY_W; | ||||
|     _glfw.ns.keycodes[0x07] = GLFW_KEY_X; | ||||
|     _glfw.ns.keycodes[0x10] = GLFW_KEY_Y; | ||||
|     _glfw.ns.keycodes[0x06] = GLFW_KEY_Z; | ||||
|  | ||||
|     _glfw.ns.keycodes[0x27] = GLFW_KEY_APOSTROPHE; | ||||
|     _glfw.ns.keycodes[0x2A] = GLFW_KEY_BACKSLASH; | ||||
|     _glfw.ns.keycodes[0x2B] = GLFW_KEY_COMMA; | ||||
|     _glfw.ns.keycodes[0x18] = GLFW_KEY_EQUAL; | ||||
|     _glfw.ns.keycodes[0x32] = GLFW_KEY_GRAVE_ACCENT; | ||||
|     _glfw.ns.keycodes[0x21] = GLFW_KEY_LEFT_BRACKET; | ||||
|     _glfw.ns.keycodes[0x1B] = GLFW_KEY_MINUS; | ||||
|     _glfw.ns.keycodes[0x2F] = GLFW_KEY_PERIOD; | ||||
|     _glfw.ns.keycodes[0x1E] = GLFW_KEY_RIGHT_BRACKET; | ||||
|     _glfw.ns.keycodes[0x29] = GLFW_KEY_SEMICOLON; | ||||
|     _glfw.ns.keycodes[0x2C] = GLFW_KEY_SLASH; | ||||
|     _glfw.ns.keycodes[0x0A] = GLFW_KEY_WORLD_1; | ||||
|  | ||||
|     _glfw.ns.keycodes[0x33] = GLFW_KEY_BACKSPACE; | ||||
|     _glfw.ns.keycodes[0x39] = GLFW_KEY_CAPS_LOCK; | ||||
|     _glfw.ns.keycodes[0x75] = GLFW_KEY_DELETE; | ||||
|     _glfw.ns.keycodes[0x7D] = GLFW_KEY_DOWN; | ||||
|     _glfw.ns.keycodes[0x77] = GLFW_KEY_END; | ||||
|     _glfw.ns.keycodes[0x24] = GLFW_KEY_ENTER; | ||||
|     _glfw.ns.keycodes[0x35] = GLFW_KEY_ESCAPE; | ||||
|     _glfw.ns.keycodes[0x7A] = GLFW_KEY_F1; | ||||
|     _glfw.ns.keycodes[0x78] = GLFW_KEY_F2; | ||||
|     _glfw.ns.keycodes[0x63] = GLFW_KEY_F3; | ||||
|     _glfw.ns.keycodes[0x76] = GLFW_KEY_F4; | ||||
|     _glfw.ns.keycodes[0x60] = GLFW_KEY_F5; | ||||
|     _glfw.ns.keycodes[0x61] = GLFW_KEY_F6; | ||||
|     _glfw.ns.keycodes[0x62] = GLFW_KEY_F7; | ||||
|     _glfw.ns.keycodes[0x64] = GLFW_KEY_F8; | ||||
|     _glfw.ns.keycodes[0x65] = GLFW_KEY_F9; | ||||
|     _glfw.ns.keycodes[0x6D] = GLFW_KEY_F10; | ||||
|     _glfw.ns.keycodes[0x67] = GLFW_KEY_F11; | ||||
|     _glfw.ns.keycodes[0x6F] = GLFW_KEY_F12; | ||||
|     _glfw.ns.keycodes[0x69] = GLFW_KEY_F13; | ||||
|     _glfw.ns.keycodes[0x6B] = GLFW_KEY_F14; | ||||
|     _glfw.ns.keycodes[0x71] = GLFW_KEY_F15; | ||||
|     _glfw.ns.keycodes[0x6A] = GLFW_KEY_F16; | ||||
|     _glfw.ns.keycodes[0x40] = GLFW_KEY_F17; | ||||
|     _glfw.ns.keycodes[0x4F] = GLFW_KEY_F18; | ||||
|     _glfw.ns.keycodes[0x50] = GLFW_KEY_F19; | ||||
|     _glfw.ns.keycodes[0x5A] = GLFW_KEY_F20; | ||||
|     _glfw.ns.keycodes[0x73] = GLFW_KEY_HOME; | ||||
|     _glfw.ns.keycodes[0x72] = GLFW_KEY_INSERT; | ||||
|     _glfw.ns.keycodes[0x7B] = GLFW_KEY_LEFT; | ||||
|     _glfw.ns.keycodes[0x3A] = GLFW_KEY_LEFT_ALT; | ||||
|     _glfw.ns.keycodes[0x3B] = GLFW_KEY_LEFT_CONTROL; | ||||
|     _glfw.ns.keycodes[0x38] = GLFW_KEY_LEFT_SHIFT; | ||||
|     _glfw.ns.keycodes[0x37] = GLFW_KEY_LEFT_SUPER; | ||||
|     _glfw.ns.keycodes[0x6E] = GLFW_KEY_MENU; | ||||
|     _glfw.ns.keycodes[0x47] = GLFW_KEY_NUM_LOCK; | ||||
|     _glfw.ns.keycodes[0x79] = GLFW_KEY_PAGE_DOWN; | ||||
|     _glfw.ns.keycodes[0x74] = GLFW_KEY_PAGE_UP; | ||||
|     _glfw.ns.keycodes[0x7C] = GLFW_KEY_RIGHT; | ||||
|     _glfw.ns.keycodes[0x3D] = GLFW_KEY_RIGHT_ALT; | ||||
|     _glfw.ns.keycodes[0x3E] = GLFW_KEY_RIGHT_CONTROL; | ||||
|     _glfw.ns.keycodes[0x3C] = GLFW_KEY_RIGHT_SHIFT; | ||||
|     _glfw.ns.keycodes[0x36] = GLFW_KEY_RIGHT_SUPER; | ||||
|     _glfw.ns.keycodes[0x31] = GLFW_KEY_SPACE; | ||||
|     _glfw.ns.keycodes[0x30] = GLFW_KEY_TAB; | ||||
|     _glfw.ns.keycodes[0x7E] = GLFW_KEY_UP; | ||||
|  | ||||
|     _glfw.ns.keycodes[0x52] = GLFW_KEY_KP_0; | ||||
|     _glfw.ns.keycodes[0x53] = GLFW_KEY_KP_1; | ||||
|     _glfw.ns.keycodes[0x54] = GLFW_KEY_KP_2; | ||||
|     _glfw.ns.keycodes[0x55] = GLFW_KEY_KP_3; | ||||
|     _glfw.ns.keycodes[0x56] = GLFW_KEY_KP_4; | ||||
|     _glfw.ns.keycodes[0x57] = GLFW_KEY_KP_5; | ||||
|     _glfw.ns.keycodes[0x58] = GLFW_KEY_KP_6; | ||||
|     _glfw.ns.keycodes[0x59] = GLFW_KEY_KP_7; | ||||
|     _glfw.ns.keycodes[0x5B] = GLFW_KEY_KP_8; | ||||
|     _glfw.ns.keycodes[0x5C] = GLFW_KEY_KP_9; | ||||
|     _glfw.ns.keycodes[0x45] = GLFW_KEY_KP_ADD; | ||||
|     _glfw.ns.keycodes[0x41] = GLFW_KEY_KP_DECIMAL; | ||||
|     _glfw.ns.keycodes[0x4B] = GLFW_KEY_KP_DIVIDE; | ||||
|     _glfw.ns.keycodes[0x4C] = GLFW_KEY_KP_ENTER; | ||||
|     _glfw.ns.keycodes[0x51] = GLFW_KEY_KP_EQUAL; | ||||
|     _glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY; | ||||
|     _glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT; | ||||
|  | ||||
|     for (scancode = 0;  scancode < 256;  scancode++) | ||||
|     { | ||||
|         // Store the reverse translation for faster key name lookup | ||||
|         if (_glfw.ns.keycodes[scancode] >= 0) | ||||
|             _glfw.ns.scancodes[_glfw.ns.keycodes[scancode]] = scancode; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Retrieve Unicode data for the current keyboard layout | ||||
| // | ||||
| static GLFWbool updateUnicodeDataNS(void) | ||||
| { | ||||
|     if (_glfw.ns.inputSource) | ||||
|     { | ||||
|         CFRelease(_glfw.ns.inputSource); | ||||
|         _glfw.ns.inputSource = NULL; | ||||
|         _glfw.ns.unicodeData = nil; | ||||
|     } | ||||
|  | ||||
|     _glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource(); | ||||
|     if (!_glfw.ns.inputSource) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Failed to retrieve keyboard layout input source"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.ns.unicodeData = | ||||
|         TISGetInputSourceProperty(_glfw.ns.inputSource, | ||||
|                                   kTISPropertyUnicodeKeyLayoutData); | ||||
|     if (!_glfw.ns.unicodeData) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Failed to retrieve keyboard layout Unicode data"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Load HIToolbox.framework and the TIS symbols we need from it | ||||
| // | ||||
| static GLFWbool initializeTIS(void) | ||||
| { | ||||
|     // This works only because Cocoa has already loaded it properly | ||||
|     _glfw.ns.tis.bundle = | ||||
|         CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox")); | ||||
|     if (!_glfw.ns.tis.bundle) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Failed to load HIToolbox.framework"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     CFStringRef* kPropertyUnicodeKeyLayoutData = | ||||
|         CFBundleGetDataPointerForName(_glfw.ns.tis.bundle, | ||||
|                                       CFSTR("kTISPropertyUnicodeKeyLayoutData")); | ||||
|     _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource = | ||||
|         CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle, | ||||
|                                           CFSTR("TISCopyCurrentKeyboardLayoutInputSource")); | ||||
|     _glfw.ns.tis.GetInputSourceProperty = | ||||
|         CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle, | ||||
|                                           CFSTR("TISGetInputSourceProperty")); | ||||
|     _glfw.ns.tis.GetKbdType = | ||||
|         CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle, | ||||
|                                           CFSTR("LMGetKbdType")); | ||||
|  | ||||
|     if (!kPropertyUnicodeKeyLayoutData || | ||||
|         !TISCopyCurrentKeyboardLayoutInputSource || | ||||
|         !TISGetInputSourceProperty || | ||||
|         !LMGetKbdType) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Failed to load TIS API symbols"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.ns.tis.kPropertyUnicodeKeyLayoutData = | ||||
|         *kPropertyUnicodeKeyLayoutData; | ||||
|  | ||||
|     return updateUnicodeDataNS(); | ||||
| } | ||||
|  | ||||
| @interface GLFWHelper : NSObject | ||||
| @end | ||||
|  | ||||
| @implementation GLFWHelper | ||||
|  | ||||
| - (void)selectedKeyboardInputSourceChanged:(NSObject* )object | ||||
| { | ||||
|     updateUnicodeDataNS(); | ||||
| } | ||||
|  | ||||
| - (void)doNothing:(id)object | ||||
| { | ||||
| } | ||||
|  | ||||
| @end // GLFWHelper | ||||
|  | ||||
| @interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate> | ||||
| @end | ||||
|  | ||||
| @implementation GLFWApplicationDelegate | ||||
|  | ||||
| - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender | ||||
| { | ||||
|     _GLFWwindow* window; | ||||
|  | ||||
|     for (window = _glfw.windowListHead;  window;  window = window->next) | ||||
|         _glfwInputWindowCloseRequest(window); | ||||
|  | ||||
|     return NSTerminateCancel; | ||||
| } | ||||
|  | ||||
| - (void)applicationDidChangeScreenParameters:(NSNotification *) notification | ||||
| { | ||||
|     _GLFWwindow* window; | ||||
|  | ||||
|     for (window = _glfw.windowListHead;  window;  window = window->next) | ||||
|     { | ||||
|         if (window->context.client != GLFW_NO_API) | ||||
|             [window->context.nsgl.object update]; | ||||
|     } | ||||
|  | ||||
|     _glfwPollMonitorsNS(); | ||||
| } | ||||
|  | ||||
| - (void)applicationWillFinishLaunching:(NSNotification *)notification | ||||
| { | ||||
|     if (_glfw.hints.init.ns.menubar) | ||||
|     { | ||||
|         // Menu bar setup must go between sharedApplication and finishLaunching | ||||
|         // in order to properly emulate the behavior of NSApplicationMain | ||||
|  | ||||
|         if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) | ||||
|         { | ||||
|             [[NSBundle mainBundle] loadNibNamed:@"MainMenu" | ||||
|                                           owner:NSApp | ||||
|                                 topLevelObjects:&_glfw.ns.nibObjects]; | ||||
|         } | ||||
|         else | ||||
|             createMenuBar(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| - (void)applicationDidFinishLaunching:(NSNotification *)notification | ||||
| { | ||||
|     _glfw.ns.finishedLaunching = GLFW_TRUE; | ||||
|     _glfwPlatformPostEmptyEvent(); | ||||
|  | ||||
|     // In case we are unbundled, make us a proper UI application | ||||
|     if (_glfw.hints.init.ns.menubar) | ||||
|         [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; | ||||
|  | ||||
|     [NSApp stop:nil]; | ||||
| } | ||||
|  | ||||
| - (void)applicationDidHide:(NSNotification *)notification | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     for (i = 0;  i < _glfw.monitorCount;  i++) | ||||
|         _glfwRestoreVideoModeNS(_glfw.monitors[i]); | ||||
| } | ||||
|  | ||||
| @end // GLFWApplicationDelegate | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void* _glfwLoadLocalVulkanLoaderNS(void) | ||||
| { | ||||
|     CFBundleRef bundle = CFBundleGetMainBundle(); | ||||
|     if (!bundle) | ||||
|         return NULL; | ||||
|  | ||||
|     CFURLRef url = | ||||
|         CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib")); | ||||
|     if (!url) | ||||
|         return NULL; | ||||
|  | ||||
|     char path[PATH_MAX]; | ||||
|     void* handle = NULL; | ||||
|  | ||||
|     if (CFURLGetFileSystemRepresentation(url, true, (UInt8*) path, sizeof(path) - 1)) | ||||
|         handle = _glfw_dlopen(path); | ||||
|  | ||||
|     CFRelease(url); | ||||
|     return handle; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformInit(void) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     _glfw.ns.helper = [[GLFWHelper alloc] init]; | ||||
|  | ||||
|     [NSThread detachNewThreadSelector:@selector(doNothing:) | ||||
|                              toTarget:_glfw.ns.helper | ||||
|                            withObject:nil]; | ||||
|  | ||||
|     if (NSApp) | ||||
|         _glfw.ns.finishedLaunching = GLFW_TRUE; | ||||
|  | ||||
|     [NSApplication sharedApplication]; | ||||
|  | ||||
|     _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; | ||||
|     if (_glfw.ns.delegate == nil) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Failed to create application delegate"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     [NSApp setDelegate:_glfw.ns.delegate]; | ||||
|  | ||||
|     NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event) | ||||
|     { | ||||
|         if ([event modifierFlags] & NSEventModifierFlagCommand) | ||||
|             [[NSApp keyWindow] sendEvent:event]; | ||||
|  | ||||
|         return event; | ||||
|     }; | ||||
|  | ||||
|     _glfw.ns.keyUpMonitor = | ||||
|         [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp | ||||
|                                               handler:block]; | ||||
|  | ||||
|     if (_glfw.hints.init.ns.chdir) | ||||
|         changeToResourcesDirectory(); | ||||
|  | ||||
|     // Press and Hold prevents some keys from emitting repeated characters | ||||
|     NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO}; | ||||
|     [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; | ||||
|  | ||||
|     [[NSNotificationCenter defaultCenter] | ||||
|         addObserver:_glfw.ns.helper | ||||
|            selector:@selector(selectedKeyboardInputSourceChanged:) | ||||
|                name:NSTextInputContextKeyboardSelectionDidChangeNotification | ||||
|              object:nil]; | ||||
|  | ||||
|     createKeyTables(); | ||||
|  | ||||
|     _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); | ||||
|     if (!_glfw.ns.eventSource) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0); | ||||
|  | ||||
|     if (!initializeTIS()) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     _glfwInitTimerNS(); | ||||
|     _glfwInitJoysticksNS(); | ||||
|  | ||||
|     _glfwPollMonitorsNS(); | ||||
|     return GLFW_TRUE; | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| void _glfwPlatformTerminate(void) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     if (_glfw.ns.inputSource) | ||||
|     { | ||||
|         CFRelease(_glfw.ns.inputSource); | ||||
|         _glfw.ns.inputSource = NULL; | ||||
|         _glfw.ns.unicodeData = nil; | ||||
|     } | ||||
|  | ||||
|     if (_glfw.ns.eventSource) | ||||
|     { | ||||
|         CFRelease(_glfw.ns.eventSource); | ||||
|         _glfw.ns.eventSource = NULL; | ||||
|     } | ||||
|  | ||||
|     if (_glfw.ns.delegate) | ||||
|     { | ||||
|         [NSApp setDelegate:nil]; | ||||
|         [_glfw.ns.delegate release]; | ||||
|         _glfw.ns.delegate = nil; | ||||
|     } | ||||
|  | ||||
|     if (_glfw.ns.helper) | ||||
|     { | ||||
|         [[NSNotificationCenter defaultCenter] | ||||
|             removeObserver:_glfw.ns.helper | ||||
|                       name:NSTextInputContextKeyboardSelectionDidChangeNotification | ||||
|                     object:nil]; | ||||
|         [[NSNotificationCenter defaultCenter] | ||||
|             removeObserver:_glfw.ns.helper]; | ||||
|         [_glfw.ns.helper release]; | ||||
|         _glfw.ns.helper = nil; | ||||
|     } | ||||
|  | ||||
|     if (_glfw.ns.keyUpMonitor) | ||||
|         [NSEvent removeMonitor:_glfw.ns.keyUpMonitor]; | ||||
|  | ||||
|     free(_glfw.ns.clipboardString); | ||||
|  | ||||
|     _glfwTerminateNSGL(); | ||||
|     _glfwTerminateJoysticksNS(); | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| const char* _glfwPlatformGetVersionString(void) | ||||
| { | ||||
|     return _GLFW_VERSION_NUMBER " Cocoa NSGL EGL OSMesa" | ||||
| #if defined(_GLFW_BUILD_DLL) | ||||
|         " dynamic" | ||||
| #endif | ||||
|         ; | ||||
| } | ||||
|  | ||||
							
								
								
									
										51
									
								
								deps/glfw/src/cocoa_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								deps/glfw/src/cocoa_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Cocoa - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #include <IOKit/IOKitLib.h> | ||||
| #include <IOKit/IOCFPlugIn.h> | ||||
| #include <IOKit/hid/IOHIDLib.h> | ||||
| #include <IOKit/hid/IOHIDKeys.h> | ||||
|  | ||||
| #define _GLFW_PLATFORM_JOYSTICK_STATE         _GLFWjoystickNS ns | ||||
| #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyJoystick; } | ||||
|  | ||||
| #define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X" | ||||
| #define GLFW_BUILD_COCOA_MAPPINGS | ||||
|  | ||||
| // Cocoa-specific per-joystick data | ||||
| // | ||||
| typedef struct _GLFWjoystickNS | ||||
| { | ||||
|     IOHIDDeviceRef      device; | ||||
|     CFMutableArrayRef   axes; | ||||
|     CFMutableArrayRef   buttons; | ||||
|     CFMutableArrayRef   hats; | ||||
| } _GLFWjoystickNS; | ||||
|  | ||||
|  | ||||
| void _glfwInitJoysticksNS(void); | ||||
| void _glfwTerminateJoysticksNS(void); | ||||
|  | ||||
							
								
								
									
										487
									
								
								deps/glfw/src/cocoa_joystick.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										487
									
								
								deps/glfw/src/cocoa_joystick.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,487 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Cocoa - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <unistd.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include <mach/mach.h> | ||||
| #include <mach/mach_error.h> | ||||
|  | ||||
| #include <CoreFoundation/CoreFoundation.h> | ||||
| #include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h> | ||||
|  | ||||
|  | ||||
| // Joystick element information | ||||
| // | ||||
| typedef struct _GLFWjoyelementNS | ||||
| { | ||||
|     IOHIDElementRef native; | ||||
|     uint32_t        usage; | ||||
|     int             index; | ||||
|     long            minimum; | ||||
|     long            maximum; | ||||
|  | ||||
| } _GLFWjoyelementNS; | ||||
|  | ||||
|  | ||||
| // Returns the value of the specified element of the specified joystick | ||||
| // | ||||
| static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element) | ||||
| { | ||||
|     IOHIDValueRef valueRef; | ||||
|     long value = 0; | ||||
|  | ||||
|     if (js->ns.device) | ||||
|     { | ||||
|         if (IOHIDDeviceGetValue(js->ns.device, | ||||
|                                 element->native, | ||||
|                                 &valueRef) == kIOReturnSuccess) | ||||
|         { | ||||
|             value = IOHIDValueGetIntegerValue(valueRef); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return value; | ||||
| } | ||||
|  | ||||
| // Comparison function for matching the SDL element order | ||||
| // | ||||
| static CFComparisonResult compareElements(const void* fp, | ||||
|                                           const void* sp, | ||||
|                                           void* user) | ||||
| { | ||||
|     const _GLFWjoyelementNS* fe = fp; | ||||
|     const _GLFWjoyelementNS* se = sp; | ||||
|     if (fe->usage < se->usage) | ||||
|         return kCFCompareLessThan; | ||||
|     if (fe->usage > se->usage) | ||||
|         return kCFCompareGreaterThan; | ||||
|     if (fe->index < se->index) | ||||
|         return kCFCompareLessThan; | ||||
|     if (fe->index > se->index) | ||||
|         return kCFCompareGreaterThan; | ||||
|     return kCFCompareEqualTo; | ||||
| } | ||||
|  | ||||
| // Removes the specified joystick | ||||
| // | ||||
| static void closeJoystick(_GLFWjoystick* js) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     if (!js->present) | ||||
|         return; | ||||
|  | ||||
|     for (i = 0;  i < CFArrayGetCount(js->ns.axes);  i++) | ||||
|         free((void*) CFArrayGetValueAtIndex(js->ns.axes, i)); | ||||
|     CFRelease(js->ns.axes); | ||||
|  | ||||
|     for (i = 0;  i < CFArrayGetCount(js->ns.buttons);  i++) | ||||
|         free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i)); | ||||
|     CFRelease(js->ns.buttons); | ||||
|  | ||||
|     for (i = 0;  i < CFArrayGetCount(js->ns.hats);  i++) | ||||
|         free((void*) CFArrayGetValueAtIndex(js->ns.hats, i)); | ||||
|     CFRelease(js->ns.hats); | ||||
|  | ||||
|     _glfwFreeJoystick(js); | ||||
|     _glfwInputJoystick(js, GLFW_DISCONNECTED); | ||||
| } | ||||
|  | ||||
| // Callback for user-initiated joystick addition | ||||
| // | ||||
| static void matchCallback(void* context, | ||||
|                           IOReturn result, | ||||
|                           void* sender, | ||||
|                           IOHIDDeviceRef device) | ||||
| { | ||||
|     int jid; | ||||
|     char name[256]; | ||||
|     char guid[33]; | ||||
|     CFIndex i; | ||||
|     CFTypeRef property; | ||||
|     uint32_t vendor = 0, product = 0, version = 0; | ||||
|     _GLFWjoystick* js; | ||||
|     CFMutableArrayRef axes, buttons, hats; | ||||
|  | ||||
|     for (jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|     { | ||||
|         if (_glfw.joysticks[jid].ns.device == device) | ||||
|             return; | ||||
|     } | ||||
|  | ||||
|     axes    = CFArrayCreateMutable(NULL, 0, NULL); | ||||
|     buttons = CFArrayCreateMutable(NULL, 0, NULL); | ||||
|     hats    = CFArrayCreateMutable(NULL, 0, NULL); | ||||
|  | ||||
|     property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); | ||||
|     if (property) | ||||
|     { | ||||
|         CFStringGetCString(property, | ||||
|                            name, | ||||
|                            sizeof(name), | ||||
|                            kCFStringEncodingUTF8); | ||||
|     } | ||||
|     else | ||||
|         strncpy(name, "Unknown", sizeof(name)); | ||||
|  | ||||
|     property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)); | ||||
|     if (property) | ||||
|         CFNumberGetValue(property, kCFNumberSInt32Type, &vendor); | ||||
|  | ||||
|     property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)); | ||||
|     if (property) | ||||
|         CFNumberGetValue(property, kCFNumberSInt32Type, &product); | ||||
|  | ||||
|     property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey)); | ||||
|     if (property) | ||||
|         CFNumberGetValue(property, kCFNumberSInt32Type, &version); | ||||
|  | ||||
|     // Generate a joystick GUID that matches the SDL 2.0.5+ one | ||||
|     if (vendor && product) | ||||
|     { | ||||
|         sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000", | ||||
|                 (uint8_t) vendor, (uint8_t) (vendor >> 8), | ||||
|                 (uint8_t) product, (uint8_t) (product >> 8), | ||||
|                 (uint8_t) version, (uint8_t) (version >> 8)); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00", | ||||
|                 name[0], name[1], name[2], name[3], | ||||
|                 name[4], name[5], name[6], name[7], | ||||
|                 name[8], name[9], name[10]); | ||||
|     } | ||||
|  | ||||
|     CFArrayRef elements = | ||||
|         IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); | ||||
|  | ||||
|     for (i = 0;  i < CFArrayGetCount(elements);  i++) | ||||
|     { | ||||
|         IOHIDElementRef native = (IOHIDElementRef) | ||||
|             CFArrayGetValueAtIndex(elements, i); | ||||
|         if (CFGetTypeID(native) != IOHIDElementGetTypeID()) | ||||
|             continue; | ||||
|  | ||||
|         const IOHIDElementType type = IOHIDElementGetType(native); | ||||
|         if ((type != kIOHIDElementTypeInput_Axis) && | ||||
|             (type != kIOHIDElementTypeInput_Button) && | ||||
|             (type != kIOHIDElementTypeInput_Misc)) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         CFMutableArrayRef target = NULL; | ||||
|  | ||||
|         const uint32_t usage = IOHIDElementGetUsage(native); | ||||
|         const uint32_t page = IOHIDElementGetUsagePage(native); | ||||
|         if (page == kHIDPage_GenericDesktop) | ||||
|         { | ||||
|             switch (usage) | ||||
|             { | ||||
|                 case kHIDUsage_GD_X: | ||||
|                 case kHIDUsage_GD_Y: | ||||
|                 case kHIDUsage_GD_Z: | ||||
|                 case kHIDUsage_GD_Rx: | ||||
|                 case kHIDUsage_GD_Ry: | ||||
|                 case kHIDUsage_GD_Rz: | ||||
|                 case kHIDUsage_GD_Slider: | ||||
|                 case kHIDUsage_GD_Dial: | ||||
|                 case kHIDUsage_GD_Wheel: | ||||
|                     target = axes; | ||||
|                     break; | ||||
|                 case kHIDUsage_GD_Hatswitch: | ||||
|                     target = hats; | ||||
|                     break; | ||||
|                 case kHIDUsage_GD_DPadUp: | ||||
|                 case kHIDUsage_GD_DPadRight: | ||||
|                 case kHIDUsage_GD_DPadDown: | ||||
|                 case kHIDUsage_GD_DPadLeft: | ||||
|                 case kHIDUsage_GD_SystemMainMenu: | ||||
|                 case kHIDUsage_GD_Select: | ||||
|                 case kHIDUsage_GD_Start: | ||||
|                     target = buttons; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|         else if (page == kHIDPage_Simulation) | ||||
|         { | ||||
|             switch (usage) | ||||
|             { | ||||
|                 case kHIDUsage_Sim_Accelerator: | ||||
|                 case kHIDUsage_Sim_Brake: | ||||
|                 case kHIDUsage_Sim_Throttle: | ||||
|                 case kHIDUsage_Sim_Rudder: | ||||
|                 case kHIDUsage_Sim_Steering: | ||||
|                     target = axes; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|         else if (page == kHIDPage_Button || page == kHIDPage_Consumer) | ||||
|             target = buttons; | ||||
|  | ||||
|         if (target) | ||||
|         { | ||||
|             _GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS)); | ||||
|             element->native  = native; | ||||
|             element->usage   = usage; | ||||
|             element->index   = (int) CFArrayGetCount(target); | ||||
|             element->minimum = IOHIDElementGetLogicalMin(native); | ||||
|             element->maximum = IOHIDElementGetLogicalMax(native); | ||||
|             CFArrayAppendValue(target, element); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     CFRelease(elements); | ||||
|  | ||||
|     CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)), | ||||
|                       compareElements, NULL); | ||||
|     CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)), | ||||
|                       compareElements, NULL); | ||||
|     CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)), | ||||
|                       compareElements, NULL); | ||||
|  | ||||
|     js = _glfwAllocJoystick(name, guid, | ||||
|                             (int) CFArrayGetCount(axes), | ||||
|                             (int) CFArrayGetCount(buttons), | ||||
|                             (int) CFArrayGetCount(hats)); | ||||
|  | ||||
|     js->ns.device  = device; | ||||
|     js->ns.axes    = axes; | ||||
|     js->ns.buttons = buttons; | ||||
|     js->ns.hats    = hats; | ||||
|  | ||||
|     _glfwInputJoystick(js, GLFW_CONNECTED); | ||||
| } | ||||
|  | ||||
| // Callback for user-initiated joystick removal | ||||
| // | ||||
| static void removeCallback(void* context, | ||||
|                            IOReturn result, | ||||
|                            void* sender, | ||||
|                            IOHIDDeviceRef device) | ||||
| { | ||||
|     int jid; | ||||
|  | ||||
|     for (jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|     { | ||||
|         if (_glfw.joysticks[jid].ns.device == device) | ||||
|         { | ||||
|             closeJoystick(_glfw.joysticks + jid); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialize joystick interface | ||||
| // | ||||
| void _glfwInitJoysticksNS(void) | ||||
| { | ||||
|     CFMutableArrayRef matching; | ||||
|     const long usages[] = | ||||
|     { | ||||
|         kHIDUsage_GD_Joystick, | ||||
|         kHIDUsage_GD_GamePad, | ||||
|         kHIDUsage_GD_MultiAxisController | ||||
|     }; | ||||
|  | ||||
|     _glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, | ||||
|                                              kIOHIDOptionsTypeNone); | ||||
|  | ||||
|     matching = CFArrayCreateMutable(kCFAllocatorDefault, | ||||
|                                     0, | ||||
|                                     &kCFTypeArrayCallBacks); | ||||
|     if (!matching) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     for (size_t i = 0;  i < sizeof(usages) / sizeof(long);  i++) | ||||
|     { | ||||
|         const long page = kHIDPage_GenericDesktop; | ||||
|  | ||||
|         CFMutableDictionaryRef dict = | ||||
|             CFDictionaryCreateMutable(kCFAllocatorDefault, | ||||
|                                       0, | ||||
|                                       &kCFTypeDictionaryKeyCallBacks, | ||||
|                                       &kCFTypeDictionaryValueCallBacks); | ||||
|         if (!dict) | ||||
|             continue; | ||||
|  | ||||
|         CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault, | ||||
|                                              kCFNumberLongType, | ||||
|                                              &page); | ||||
|         CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault, | ||||
|                                               kCFNumberLongType, | ||||
|                                               &usages[i]); | ||||
|         if (pageRef && usageRef) | ||||
|         { | ||||
|             CFDictionarySetValue(dict, | ||||
|                                  CFSTR(kIOHIDDeviceUsagePageKey), | ||||
|                                  pageRef); | ||||
|             CFDictionarySetValue(dict, | ||||
|                                  CFSTR(kIOHIDDeviceUsageKey), | ||||
|                                  usageRef); | ||||
|             CFArrayAppendValue(matching, dict); | ||||
|         } | ||||
|  | ||||
|         if (pageRef) | ||||
|             CFRelease(pageRef); | ||||
|         if (usageRef) | ||||
|             CFRelease(usageRef); | ||||
|  | ||||
|         CFRelease(dict); | ||||
|     } | ||||
|  | ||||
|     IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching); | ||||
|     CFRelease(matching); | ||||
|  | ||||
|     IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager, | ||||
|                                                &matchCallback, NULL); | ||||
|     IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager, | ||||
|                                               &removeCallback, NULL); | ||||
|     IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager, | ||||
|                                     CFRunLoopGetMain(), | ||||
|                                     kCFRunLoopDefaultMode); | ||||
|     IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone); | ||||
|  | ||||
|     // Execute the run loop once in order to register any initially-attached | ||||
|     // joysticks | ||||
|     CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); | ||||
| } | ||||
|  | ||||
| // Close all opened joystick handles | ||||
| // | ||||
| void _glfwTerminateJoysticksNS(void) | ||||
| { | ||||
|     int jid; | ||||
|  | ||||
|     for (jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|         closeJoystick(_glfw.joysticks + jid); | ||||
|  | ||||
|     CFRelease(_glfw.ns.hidManager); | ||||
|     _glfw.ns.hidManager = NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) | ||||
| { | ||||
|     if (mode & _GLFW_POLL_AXES) | ||||
|     { | ||||
|         CFIndex i; | ||||
|  | ||||
|         for (i = 0;  i < CFArrayGetCount(js->ns.axes);  i++) | ||||
|         { | ||||
|             _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*) | ||||
|                 CFArrayGetValueAtIndex(js->ns.axes, i); | ||||
|  | ||||
|             const long raw = getElementValue(js, axis); | ||||
|             // Perform auto calibration | ||||
|             if (raw < axis->minimum) | ||||
|                 axis->minimum = raw; | ||||
|             if (raw > axis->maximum) | ||||
|                 axis->maximum = raw; | ||||
|  | ||||
|             const long size = axis->maximum - axis->minimum; | ||||
|             if (size == 0) | ||||
|                 _glfwInputJoystickAxis(js, (int) i, 0.f); | ||||
|             else | ||||
|             { | ||||
|                 const float value = (2.f * (raw - axis->minimum) / size) - 1.f; | ||||
|                 _glfwInputJoystickAxis(js, (int) i, value); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (mode & _GLFW_POLL_BUTTONS) | ||||
|     { | ||||
|         CFIndex i; | ||||
|  | ||||
|         for (i = 0;  i < CFArrayGetCount(js->ns.buttons);  i++) | ||||
|         { | ||||
|             _GLFWjoyelementNS* button = (_GLFWjoyelementNS*) | ||||
|                 CFArrayGetValueAtIndex(js->ns.buttons, i); | ||||
|             const char value = getElementValue(js, button) - button->minimum; | ||||
|             const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE; | ||||
|             _glfwInputJoystickButton(js, (int) i, state); | ||||
|         } | ||||
|  | ||||
|         for (i = 0;  i < CFArrayGetCount(js->ns.hats);  i++) | ||||
|         { | ||||
|             const int states[9] = | ||||
|             { | ||||
|                 GLFW_HAT_UP, | ||||
|                 GLFW_HAT_RIGHT_UP, | ||||
|                 GLFW_HAT_RIGHT, | ||||
|                 GLFW_HAT_RIGHT_DOWN, | ||||
|                 GLFW_HAT_DOWN, | ||||
|                 GLFW_HAT_LEFT_DOWN, | ||||
|                 GLFW_HAT_LEFT, | ||||
|                 GLFW_HAT_LEFT_UP, | ||||
|                 GLFW_HAT_CENTERED | ||||
|             }; | ||||
|  | ||||
|             _GLFWjoyelementNS* hat = (_GLFWjoyelementNS*) | ||||
|                 CFArrayGetValueAtIndex(js->ns.hats, i); | ||||
|             long state = getElementValue(js, hat) - hat->minimum; | ||||
|             if (state < 0 || state > 8) | ||||
|                 state = 8; | ||||
|  | ||||
|             _glfwInputJoystickHat(js, (int) i, states[state]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return js->present; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformUpdateGamepadGUID(char* guid) | ||||
| { | ||||
|     if ((strncmp(guid + 4, "000000000000", 12) == 0) && | ||||
|         (strncmp(guid + 20, "000000000000", 12) == 0)) | ||||
|     { | ||||
|         char original[33]; | ||||
|         strncpy(original, guid, sizeof(original) - 1); | ||||
|         sprintf(guid, "03000000%.4s0000%.4s000000000000", | ||||
|                 original, original + 16); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										631
									
								
								deps/glfw/src/cocoa_monitor.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										631
									
								
								deps/glfw/src/cocoa_monitor.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,631 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 macOS - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <limits.h> | ||||
| #include <math.h> | ||||
|  | ||||
| #include <IOKit/graphics/IOGraphicsLib.h> | ||||
| #include <ApplicationServices/ApplicationServices.h> | ||||
|  | ||||
|  | ||||
| // Get the name of the specified display, or NULL | ||||
| // | ||||
| static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen) | ||||
| { | ||||
|     // IOKit doesn't work on Apple Silicon anymore | ||||
|     // Luckily, 10.15 introduced -[NSScreen localizedName]. | ||||
|     // Use it if available, and fall back to IOKit otherwise. | ||||
|     if (screen) | ||||
|     { | ||||
|         if ([screen respondsToSelector:@selector(localizedName)]) | ||||
|         { | ||||
|             NSString* name = [screen valueForKey:@"localizedName"]; | ||||
|             if (name) | ||||
|                 return _glfw_strdup([name UTF8String]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     io_iterator_t it; | ||||
|     io_service_t service; | ||||
|     CFDictionaryRef info; | ||||
|  | ||||
|     if (IOServiceGetMatchingServices(MACH_PORT_NULL, | ||||
|                                      IOServiceMatching("IODisplayConnect"), | ||||
|                                      &it) != 0) | ||||
|     { | ||||
|         // This may happen if a desktop Mac is running headless | ||||
|         return _glfw_strdup("Display"); | ||||
|     } | ||||
|  | ||||
|     while ((service = IOIteratorNext(it)) != 0) | ||||
|     { | ||||
|         info = IODisplayCreateInfoDictionary(service, | ||||
|                                              kIODisplayOnlyPreferredName); | ||||
|  | ||||
|         CFNumberRef vendorIDRef = | ||||
|             CFDictionaryGetValue(info, CFSTR(kDisplayVendorID)); | ||||
|         CFNumberRef productIDRef = | ||||
|             CFDictionaryGetValue(info, CFSTR(kDisplayProductID)); | ||||
|         if (!vendorIDRef || !productIDRef) | ||||
|         { | ||||
|             CFRelease(info); | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         unsigned int vendorID, productID; | ||||
|         CFNumberGetValue(vendorIDRef, kCFNumberIntType, &vendorID); | ||||
|         CFNumberGetValue(productIDRef, kCFNumberIntType, &productID); | ||||
|  | ||||
|         if (CGDisplayVendorNumber(displayID) == vendorID && | ||||
|             CGDisplayModelNumber(displayID) == productID) | ||||
|         { | ||||
|             // Info dictionary is used and freed below | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         CFRelease(info); | ||||
|     } | ||||
|  | ||||
|     IOObjectRelease(it); | ||||
|  | ||||
|     if (!service) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Failed to find service port for display"); | ||||
|         return _glfw_strdup("Display"); | ||||
|     } | ||||
|  | ||||
|     CFDictionaryRef names = | ||||
|         CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); | ||||
|  | ||||
|     CFStringRef nameRef; | ||||
|  | ||||
|     if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), | ||||
|                                                  (const void**) &nameRef)) | ||||
|     { | ||||
|         // This may happen if a desktop Mac is running headless | ||||
|         CFRelease(info); | ||||
|         return _glfw_strdup("Display"); | ||||
|     } | ||||
|  | ||||
|     const CFIndex size = | ||||
|         CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), | ||||
|                                           kCFStringEncodingUTF8); | ||||
|     char* name = calloc(size + 1, 1); | ||||
|     CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8); | ||||
|  | ||||
|     CFRelease(info); | ||||
|     return name; | ||||
| } | ||||
|  | ||||
| // Check whether the display mode should be included in enumeration | ||||
| // | ||||
| static GLFWbool modeIsGood(CGDisplayModeRef mode) | ||||
| { | ||||
|     uint32_t flags = CGDisplayModeGetIOFlags(mode); | ||||
|  | ||||
|     if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag)) | ||||
|         return GLFW_FALSE; | ||||
|     if (flags & kDisplayModeInterlacedFlag) | ||||
|         return GLFW_FALSE; | ||||
|     if (flags & kDisplayModeStretchedFlag) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 | ||||
|     CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); | ||||
|     if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && | ||||
|         CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) | ||||
|     { | ||||
|         CFRelease(format); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     CFRelease(format); | ||||
| #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Convert Core Graphics display mode to GLFW video mode | ||||
| // | ||||
| static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, | ||||
|                                             double fallbackRefreshRate) | ||||
| { | ||||
|     GLFWvidmode result; | ||||
|     result.width = (int) CGDisplayModeGetWidth(mode); | ||||
|     result.height = (int) CGDisplayModeGetHeight(mode); | ||||
|     result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode)); | ||||
|  | ||||
|     if (result.refreshRate == 0) | ||||
|         result.refreshRate = (int) round(fallbackRefreshRate); | ||||
|  | ||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 | ||||
|     CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); | ||||
|     if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) | ||||
|     { | ||||
|         result.redBits = 5; | ||||
|         result.greenBits = 5; | ||||
|         result.blueBits = 5; | ||||
|     } | ||||
|     else | ||||
| #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ | ||||
|     { | ||||
|         result.redBits = 8; | ||||
|         result.greenBits = 8; | ||||
|         result.blueBits = 8; | ||||
|     } | ||||
|  | ||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 | ||||
|     CFRelease(format); | ||||
| #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| // Starts reservation for display fading | ||||
| // | ||||
| static CGDisplayFadeReservationToken beginFadeReservation(void) | ||||
| { | ||||
|     CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken; | ||||
|  | ||||
|     if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess) | ||||
|     { | ||||
|         CGDisplayFade(token, 0.3, | ||||
|                       kCGDisplayBlendNormal, | ||||
|                       kCGDisplayBlendSolidColor, | ||||
|                       0.0, 0.0, 0.0, | ||||
|                       TRUE); | ||||
|     } | ||||
|  | ||||
|     return token; | ||||
| } | ||||
|  | ||||
| // Ends reservation for display fading | ||||
| // | ||||
| static void endFadeReservation(CGDisplayFadeReservationToken token) | ||||
| { | ||||
|     if (token != kCGDisplayFadeReservationInvalidToken) | ||||
|     { | ||||
|         CGDisplayFade(token, 0.5, | ||||
|                       kCGDisplayBlendSolidColor, | ||||
|                       kCGDisplayBlendNormal, | ||||
|                       0.0, 0.0, 0.0, | ||||
|                       FALSE); | ||||
|         CGReleaseDisplayFadeReservation(token); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Returns the display refresh rate queried from the I/O registry | ||||
| // | ||||
| static double getFallbackRefreshRate(CGDirectDisplayID displayID) | ||||
| { | ||||
|     double refreshRate = 60.0; | ||||
|  | ||||
|     io_iterator_t it; | ||||
|     io_service_t service; | ||||
|  | ||||
|     if (IOServiceGetMatchingServices(MACH_PORT_NULL, | ||||
|                                      IOServiceMatching("IOFramebuffer"), | ||||
|                                      &it) != 0) | ||||
|     { | ||||
|         return refreshRate; | ||||
|     } | ||||
|  | ||||
|     while ((service = IOIteratorNext(it)) != 0) | ||||
|     { | ||||
|         const CFNumberRef indexRef = | ||||
|             IORegistryEntryCreateCFProperty(service, | ||||
|                                             CFSTR("IOFramebufferOpenGLIndex"), | ||||
|                                             kCFAllocatorDefault, | ||||
|                                             kNilOptions); | ||||
|         if (!indexRef) | ||||
|             continue; | ||||
|  | ||||
|         uint32_t index = 0; | ||||
|         CFNumberGetValue(indexRef, kCFNumberIntType, &index); | ||||
|         CFRelease(indexRef); | ||||
|  | ||||
|         if (CGOpenGLDisplayMaskToDisplayID(1 << index) != displayID) | ||||
|             continue; | ||||
|  | ||||
|         const CFNumberRef clockRef = | ||||
|             IORegistryEntryCreateCFProperty(service, | ||||
|                                             CFSTR("IOFBCurrentPixelClock"), | ||||
|                                             kCFAllocatorDefault, | ||||
|                                             kNilOptions); | ||||
|         const CFNumberRef countRef = | ||||
|             IORegistryEntryCreateCFProperty(service, | ||||
|                                             CFSTR("IOFBCurrentPixelCount"), | ||||
|                                             kCFAllocatorDefault, | ||||
|                                             kNilOptions); | ||||
|  | ||||
|         uint32_t clock = 0, count = 0; | ||||
|  | ||||
|         if (clockRef) | ||||
|         { | ||||
|             CFNumberGetValue(clockRef, kCFNumberIntType, &clock); | ||||
|             CFRelease(clockRef); | ||||
|         } | ||||
|  | ||||
|         if (countRef) | ||||
|         { | ||||
|             CFNumberGetValue(countRef, kCFNumberIntType, &count); | ||||
|             CFRelease(countRef); | ||||
|         } | ||||
|  | ||||
|         if (clock > 0 && count > 0) | ||||
|             refreshRate = clock / (double) count; | ||||
|  | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     IOObjectRelease(it); | ||||
|     return refreshRate; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Poll for changes in the set of connected monitors | ||||
| // | ||||
| void _glfwPollMonitorsNS(void) | ||||
| { | ||||
|     uint32_t displayCount; | ||||
|     CGGetOnlineDisplayList(0, NULL, &displayCount); | ||||
|     CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID)); | ||||
|     CGGetOnlineDisplayList(displayCount, displays, &displayCount); | ||||
|  | ||||
|     for (int i = 0;  i < _glfw.monitorCount;  i++) | ||||
|         _glfw.monitors[i]->ns.screen = nil; | ||||
|  | ||||
|     _GLFWmonitor** disconnected = NULL; | ||||
|     uint32_t disconnectedCount = _glfw.monitorCount; | ||||
|     if (disconnectedCount) | ||||
|     { | ||||
|         disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); | ||||
|         memcpy(disconnected, | ||||
|                _glfw.monitors, | ||||
|                _glfw.monitorCount * sizeof(_GLFWmonitor*)); | ||||
|     } | ||||
|  | ||||
|     for (uint32_t i = 0;  i < displayCount;  i++) | ||||
|     { | ||||
|         if (CGDisplayIsAsleep(displays[i])) | ||||
|             continue; | ||||
|  | ||||
|         const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]); | ||||
|         NSScreen* screen = nil; | ||||
|  | ||||
|         for (screen in [NSScreen screens]) | ||||
|         { | ||||
|             NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"]; | ||||
|  | ||||
|             // HACK: Compare unit numbers instead of display IDs to work around | ||||
|             //       display replacement on machines with automatic graphics | ||||
|             //       switching | ||||
|             if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber) | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         // HACK: Compare unit numbers instead of display IDs to work around | ||||
|         //       display replacement on machines with automatic graphics | ||||
|         //       switching | ||||
|         uint32_t j; | ||||
|         for (j = 0;  j < disconnectedCount;  j++) | ||||
|         { | ||||
|             if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber) | ||||
|             { | ||||
|                 disconnected[j]->ns.screen = screen; | ||||
|                 disconnected[j] = NULL; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (j < disconnectedCount) | ||||
|             continue; | ||||
|  | ||||
|         const CGSize size = CGDisplayScreenSize(displays[i]); | ||||
|         char* name = getMonitorName(displays[i], screen); | ||||
|         if (!name) | ||||
|             continue; | ||||
|  | ||||
|         _GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height); | ||||
|         monitor->ns.displayID  = displays[i]; | ||||
|         monitor->ns.unitNumber = unitNumber; | ||||
|         monitor->ns.screen     = screen; | ||||
|  | ||||
|         free(name); | ||||
|  | ||||
|         CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]); | ||||
|         if (CGDisplayModeGetRefreshRate(mode) == 0.0) | ||||
|             monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]); | ||||
|         CGDisplayModeRelease(mode); | ||||
|  | ||||
|         _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST); | ||||
|     } | ||||
|  | ||||
|     for (uint32_t i = 0;  i < disconnectedCount;  i++) | ||||
|     { | ||||
|         if (disconnected[i]) | ||||
|             _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); | ||||
|     } | ||||
|  | ||||
|     free(disconnected); | ||||
|     free(displays); | ||||
| } | ||||
|  | ||||
| // Change the current video mode | ||||
| // | ||||
| void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) | ||||
| { | ||||
|     GLFWvidmode current; | ||||
|     _glfwPlatformGetVideoMode(monitor, ¤t); | ||||
|  | ||||
|     const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired); | ||||
|     if (_glfwCompareVideoModes(¤t, best) == 0) | ||||
|         return; | ||||
|  | ||||
|     CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); | ||||
|     const CFIndex count = CFArrayGetCount(modes); | ||||
|     CGDisplayModeRef native = NULL; | ||||
|  | ||||
|     for (CFIndex i = 0;  i < count;  i++) | ||||
|     { | ||||
|         CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); | ||||
|         if (!modeIsGood(dm)) | ||||
|             continue; | ||||
|  | ||||
|         const GLFWvidmode mode = | ||||
|             vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate); | ||||
|         if (_glfwCompareVideoModes(best, &mode) == 0) | ||||
|         { | ||||
|             native = dm; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (native) | ||||
|     { | ||||
|         if (monitor->ns.previousMode == NULL) | ||||
|             monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); | ||||
|  | ||||
|         CGDisplayFadeReservationToken token = beginFadeReservation(); | ||||
|         CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL); | ||||
|         endFadeReservation(token); | ||||
|     } | ||||
|  | ||||
|     CFRelease(modes); | ||||
| } | ||||
|  | ||||
| // Restore the previously saved (original) video mode | ||||
| // | ||||
| void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor) | ||||
| { | ||||
|     if (monitor->ns.previousMode) | ||||
|     { | ||||
|         CGDisplayFadeReservationToken token = beginFadeReservation(); | ||||
|         CGDisplaySetDisplayMode(monitor->ns.displayID, | ||||
|                                 monitor->ns.previousMode, NULL); | ||||
|         endFadeReservation(token); | ||||
|  | ||||
|         CGDisplayModeRelease(monitor->ns.previousMode); | ||||
|         monitor->ns.previousMode = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     const CGRect bounds = CGDisplayBounds(monitor->ns.displayID); | ||||
|  | ||||
|     if (xpos) | ||||
|         *xpos = (int) bounds.origin.x; | ||||
|     if (ypos) | ||||
|         *ypos = (int) bounds.origin.y; | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, | ||||
|                                          float* xscale, float* yscale) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     if (!monitor->ns.screen) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Cannot query content scale without screen"); | ||||
|     } | ||||
|  | ||||
|     const NSRect points = [monitor->ns.screen frame]; | ||||
|     const NSRect pixels = [monitor->ns.screen convertRectToBacking:points]; | ||||
|  | ||||
|     if (xscale) | ||||
|         *xscale = (float) (pixels.size.width / points.size.width); | ||||
|     if (yscale) | ||||
|         *yscale = (float) (pixels.size.height / points.size.height); | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, | ||||
|                                      int* xpos, int* ypos, | ||||
|                                      int* width, int* height) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     if (!monitor->ns.screen) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Cocoa: Cannot query workarea without screen"); | ||||
|     } | ||||
|  | ||||
|     const NSRect frameRect = [monitor->ns.screen visibleFrame]; | ||||
|  | ||||
|     if (xpos) | ||||
|         *xpos = frameRect.origin.x; | ||||
|     if (ypos) | ||||
|         *ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1); | ||||
|     if (width) | ||||
|         *width = frameRect.size.width; | ||||
|     if (height) | ||||
|         *height = frameRect.size.height; | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     *count = 0; | ||||
|  | ||||
|     CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); | ||||
|     const CFIndex found = CFArrayGetCount(modes); | ||||
|     GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode)); | ||||
|  | ||||
|     for (CFIndex i = 0;  i < found;  i++) | ||||
|     { | ||||
|         CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); | ||||
|         if (!modeIsGood(dm)) | ||||
|             continue; | ||||
|  | ||||
|         const GLFWvidmode mode = | ||||
|             vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate); | ||||
|         CFIndex j; | ||||
|  | ||||
|         for (j = 0;  j < *count;  j++) | ||||
|         { | ||||
|             if (_glfwCompareVideoModes(result + j, &mode) == 0) | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         // Skip duplicate modes | ||||
|         if (j < *count) | ||||
|             continue; | ||||
|  | ||||
|         (*count)++; | ||||
|         result[*count - 1] = mode; | ||||
|     } | ||||
|  | ||||
|     CFRelease(modes); | ||||
|     return result; | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID); | ||||
|     *mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate); | ||||
|     CGDisplayModeRelease(native); | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID); | ||||
|     CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); | ||||
|  | ||||
|     CGGetDisplayTransferByTable(monitor->ns.displayID, | ||||
|                                 size, | ||||
|                                 values, | ||||
|                                 values + size, | ||||
|                                 values + size * 2, | ||||
|                                 &size); | ||||
|  | ||||
|     _glfwAllocGammaArrays(ramp, size); | ||||
|  | ||||
|     for (uint32_t i = 0; i < size; i++) | ||||
|     { | ||||
|         ramp->red[i]   = (unsigned short) (values[i] * 65535); | ||||
|         ramp->green[i] = (unsigned short) (values[i + size] * 65535); | ||||
|         ramp->blue[i]  = (unsigned short) (values[i + size * 2] * 65535); | ||||
|     } | ||||
|  | ||||
|     free(values); | ||||
|     return GLFW_TRUE; | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); | ||||
|  | ||||
|     for (unsigned int i = 0;  i < ramp->size;  i++) | ||||
|     { | ||||
|         values[i]                  = ramp->red[i] / 65535.f; | ||||
|         values[i + ramp->size]     = ramp->green[i] / 65535.f; | ||||
|         values[i + ramp->size * 2] = ramp->blue[i] / 65535.f; | ||||
|     } | ||||
|  | ||||
|     CGSetDisplayTransferByTable(monitor->ns.displayID, | ||||
|                                 ramp->size, | ||||
|                                 values, | ||||
|                                 values + ramp->size, | ||||
|                                 values + ramp->size * 2); | ||||
|  | ||||
|     free(values); | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay); | ||||
|     return monitor->ns.displayID; | ||||
| } | ||||
|  | ||||
							
								
								
									
										209
									
								
								deps/glfw/src/cocoa_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								deps/glfw/src/cocoa_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 macOS - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <dlfcn.h> | ||||
|  | ||||
| #include <Carbon/Carbon.h> | ||||
|  | ||||
| // NOTE: All of NSGL was deprecated in the 10.14 SDK | ||||
| //       This disables the pointless warnings for every symbol we use | ||||
| #ifndef GL_SILENCE_DEPRECATION | ||||
| #define GL_SILENCE_DEPRECATION | ||||
| #endif | ||||
|  | ||||
| #if defined(__OBJC__) | ||||
| #import <Cocoa/Cocoa.h> | ||||
| #else | ||||
| typedef void* id; | ||||
| #endif | ||||
|  | ||||
| // NOTE: Many Cocoa enum values have been renamed and we need to build across | ||||
| //       SDK versions where one is unavailable or the other deprecated | ||||
| //       We use the newer names in code and these macros to handle compatibility | ||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 | ||||
|  #define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat | ||||
|  #define NSEventMaskAny NSAnyEventMask | ||||
|  #define NSEventMaskKeyUp NSKeyUpMask | ||||
|  #define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask | ||||
|  #define NSEventModifierFlagCommand NSCommandKeyMask | ||||
|  #define NSEventModifierFlagControl NSControlKeyMask | ||||
|  #define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask | ||||
|  #define NSEventModifierFlagOption NSAlternateKeyMask | ||||
|  #define NSEventModifierFlagShift NSShiftKeyMask | ||||
|  #define NSEventTypeApplicationDefined NSApplicationDefined | ||||
|  #define NSWindowStyleMaskBorderless NSBorderlessWindowMask | ||||
|  #define NSWindowStyleMaskClosable NSClosableWindowMask | ||||
|  #define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask | ||||
|  #define NSWindowStyleMaskResizable NSResizableWindowMask | ||||
|  #define NSWindowStyleMaskTitled NSTitledWindowMask | ||||
| #endif | ||||
|  | ||||
| typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; | ||||
| typedef VkFlags VkMetalSurfaceCreateFlagsEXT; | ||||
|  | ||||
| typedef struct VkMacOSSurfaceCreateInfoMVK | ||||
| { | ||||
|     VkStructureType                 sType; | ||||
|     const void*                     pNext; | ||||
|     VkMacOSSurfaceCreateFlagsMVK    flags; | ||||
|     const void*                     pView; | ||||
| } VkMacOSSurfaceCreateInfoMVK; | ||||
|  | ||||
| typedef struct VkMetalSurfaceCreateInfoEXT | ||||
| { | ||||
|     VkStructureType                 sType; | ||||
|     const void*                     pNext; | ||||
|     VkMetalSurfaceCreateFlagsEXT    flags; | ||||
|     const void*                     pLayer; | ||||
| } VkMetalSurfaceCreateInfoEXT; | ||||
|  | ||||
| typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*); | ||||
| typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*); | ||||
|  | ||||
| #include "posix_thread.h" | ||||
| #include "cocoa_joystick.h" | ||||
| #include "nsgl_context.h" | ||||
| #include "egl_context.h" | ||||
| #include "osmesa_context.h" | ||||
|  | ||||
| #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) | ||||
| #define _glfw_dlclose(handle) dlclose(handle) | ||||
| #define _glfw_dlsym(handle, name) dlsym(handle, name) | ||||
|  | ||||
| #define _GLFW_EGL_NATIVE_WINDOW  ((EGLNativeWindowType) window->ns.layer) | ||||
| #define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY | ||||
|  | ||||
| #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowNS  ns | ||||
| #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns | ||||
| #define _GLFW_PLATFORM_LIBRARY_TIMER_STATE  _GLFWtimerNS   ns | ||||
| #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorNS ns | ||||
| #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorNS  ns | ||||
|  | ||||
| // HIToolbox.framework pointer typedefs | ||||
| #define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData | ||||
| typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void); | ||||
| #define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource | ||||
| typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef); | ||||
| #define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty | ||||
| typedef UInt8 (*PFN_LMGetKbdType)(void); | ||||
| #define LMGetKbdType _glfw.ns.tis.GetKbdType | ||||
|  | ||||
|  | ||||
| // Cocoa-specific per-window data | ||||
| // | ||||
| typedef struct _GLFWwindowNS | ||||
| { | ||||
|     id              object; | ||||
|     id              delegate; | ||||
|     id              view; | ||||
|     id              layer; | ||||
|  | ||||
|     GLFWbool        maximized; | ||||
|     GLFWbool        occluded; | ||||
|     GLFWbool        retina; | ||||
|  | ||||
|     // Cached window properties to filter out duplicate events | ||||
|     int             width, height; | ||||
|     int             fbWidth, fbHeight; | ||||
|     float           xscale, yscale; | ||||
|  | ||||
|     // The total sum of the distances the cursor has been warped | ||||
|     // since the last cursor motion event was processed | ||||
|     // This is kept to counteract Cocoa doing the same internally | ||||
|     double          cursorWarpDeltaX, cursorWarpDeltaY; | ||||
| } _GLFWwindowNS; | ||||
|  | ||||
| // Cocoa-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryNS | ||||
| { | ||||
|     CGEventSourceRef    eventSource; | ||||
|     id                  delegate; | ||||
|     GLFWbool            finishedLaunching; | ||||
|     GLFWbool            cursorHidden; | ||||
|     TISInputSourceRef   inputSource; | ||||
|     IOHIDManagerRef     hidManager; | ||||
|     id                  unicodeData; | ||||
|     id                  helper; | ||||
|     id                  keyUpMonitor; | ||||
|     id                  nibObjects; | ||||
|  | ||||
|     char                keynames[GLFW_KEY_LAST + 1][17]; | ||||
|     short int           keycodes[256]; | ||||
|     short int           scancodes[GLFW_KEY_LAST + 1]; | ||||
|     char*               clipboardString; | ||||
|     CGPoint             cascadePoint; | ||||
|     // Where to place the cursor when re-enabled | ||||
|     double              restoreCursorPosX, restoreCursorPosY; | ||||
|     // The window whose disabled cursor mode is active | ||||
|     _GLFWwindow*        disabledCursorWindow; | ||||
|  | ||||
|     struct { | ||||
|         CFBundleRef     bundle; | ||||
|         PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource; | ||||
|         PFN_TISGetInputSourceProperty GetInputSourceProperty; | ||||
|         PFN_LMGetKbdType GetKbdType; | ||||
|         CFStringRef     kPropertyUnicodeKeyLayoutData; | ||||
|     } tis; | ||||
| } _GLFWlibraryNS; | ||||
|  | ||||
| // Cocoa-specific per-monitor data | ||||
| // | ||||
| typedef struct _GLFWmonitorNS | ||||
| { | ||||
|     CGDirectDisplayID   displayID; | ||||
|     CGDisplayModeRef    previousMode; | ||||
|     uint32_t            unitNumber; | ||||
|     id                  screen; | ||||
|     double              fallbackRefreshRate; | ||||
| } _GLFWmonitorNS; | ||||
|  | ||||
| // Cocoa-specific per-cursor data | ||||
| // | ||||
| typedef struct _GLFWcursorNS | ||||
| { | ||||
|     id              object; | ||||
| } _GLFWcursorNS; | ||||
|  | ||||
| // Cocoa-specific global timer data | ||||
| // | ||||
| typedef struct _GLFWtimerNS | ||||
| { | ||||
|     uint64_t        frequency; | ||||
| } _GLFWtimerNS; | ||||
|  | ||||
|  | ||||
| void _glfwInitTimerNS(void); | ||||
|  | ||||
| void _glfwPollMonitorsNS(void); | ||||
| void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired); | ||||
| void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor); | ||||
|  | ||||
| float _glfwTransformYNS(float y); | ||||
|  | ||||
| void* _glfwLoadLocalVulkanLoaderNS(void); | ||||
|  | ||||
							
								
								
									
										62
									
								
								deps/glfw/src/cocoa_time.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								deps/glfw/src/cocoa_time.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 macOS - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <mach/mach_time.h> | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialise timer | ||||
| // | ||||
| void _glfwInitTimerNS(void) | ||||
| { | ||||
|     mach_timebase_info_data_t info; | ||||
|     mach_timebase_info(&info); | ||||
|  | ||||
|     _glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| uint64_t _glfwPlatformGetTimerValue(void) | ||||
| { | ||||
|     return mach_absolute_time(); | ||||
| } | ||||
|  | ||||
| uint64_t _glfwPlatformGetTimerFrequency(void) | ||||
| { | ||||
|     return _glfw.timer.ns.frequency; | ||||
| } | ||||
|  | ||||
							
								
								
									
										1848
									
								
								deps/glfw/src/cocoa_window.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1848
									
								
								deps/glfw/src/cocoa_window.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										756
									
								
								deps/glfw/src/context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										756
									
								
								deps/glfw/src/context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,756 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <limits.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Checks whether the desired context attributes are valid | ||||
| // | ||||
| // This function checks things like whether the specified client API version | ||||
| // exists and whether all relevant options have supported and non-conflicting | ||||
| // values | ||||
| // | ||||
| GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) | ||||
| { | ||||
|     if (ctxconfig->share) | ||||
|     { | ||||
|         if (ctxconfig->client == GLFW_NO_API || | ||||
|             ctxconfig->share->context.client == GLFW_NO_API) | ||||
|         { | ||||
|             _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API && | ||||
|         ctxconfig->source != GLFW_EGL_CONTEXT_API && | ||||
|         ctxconfig->source != GLFW_OSMESA_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_INVALID_ENUM, | ||||
|                         "Invalid context creation API 0x%08X", | ||||
|                         ctxconfig->source); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->client != GLFW_NO_API && | ||||
|         ctxconfig->client != GLFW_OPENGL_API && | ||||
|         ctxconfig->client != GLFW_OPENGL_ES_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_INVALID_ENUM, | ||||
|                         "Invalid client API 0x%08X", | ||||
|                         ctxconfig->client); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|     { | ||||
|         if ((ctxconfig->major < 1 || ctxconfig->minor < 0) || | ||||
|             (ctxconfig->major == 1 && ctxconfig->minor > 5) || | ||||
|             (ctxconfig->major == 2 && ctxconfig->minor > 1) || | ||||
|             (ctxconfig->major == 3 && ctxconfig->minor > 3)) | ||||
|         { | ||||
|             // OpenGL 1.0 is the smallest valid version | ||||
|             // OpenGL 1.x series ended with version 1.5 | ||||
|             // OpenGL 2.x series ended with version 2.1 | ||||
|             // OpenGL 3.x series ended with version 3.3 | ||||
|             // For now, let everything else through | ||||
|  | ||||
|             _glfwInputError(GLFW_INVALID_VALUE, | ||||
|                             "Invalid OpenGL version %i.%i", | ||||
|                             ctxconfig->major, ctxconfig->minor); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->profile) | ||||
|         { | ||||
|             if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE && | ||||
|                 ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE) | ||||
|             { | ||||
|                 _glfwInputError(GLFW_INVALID_ENUM, | ||||
|                                 "Invalid OpenGL profile 0x%08X", | ||||
|                                 ctxconfig->profile); | ||||
|                 return GLFW_FALSE; | ||||
|             } | ||||
|  | ||||
|             if (ctxconfig->major <= 2 || | ||||
|                 (ctxconfig->major == 3 && ctxconfig->minor < 2)) | ||||
|             { | ||||
|                 // Desktop OpenGL context profiles are only defined for version 3.2 | ||||
|                 // and above | ||||
|  | ||||
|                 _glfwInputError(GLFW_INVALID_VALUE, | ||||
|                                 "Context profiles are only defined for OpenGL version 3.2 and above"); | ||||
|                 return GLFW_FALSE; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->forward && ctxconfig->major <= 2) | ||||
|         { | ||||
|             // Forward-compatible contexts are only defined for OpenGL version 3.0 and above | ||||
|             _glfwInputError(GLFW_INVALID_VALUE, | ||||
|                             "Forward-compatibility is only defined for OpenGL version 3.0 and above"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|     else if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|     { | ||||
|         if (ctxconfig->major < 1 || ctxconfig->minor < 0 || | ||||
|             (ctxconfig->major == 1 && ctxconfig->minor > 1) || | ||||
|             (ctxconfig->major == 2 && ctxconfig->minor > 0)) | ||||
|         { | ||||
|             // OpenGL ES 1.0 is the smallest valid version | ||||
|             // OpenGL ES 1.x series ended with version 1.1 | ||||
|             // OpenGL ES 2.x series ended with version 2.0 | ||||
|             // For now, let everything else through | ||||
|  | ||||
|             _glfwInputError(GLFW_INVALID_VALUE, | ||||
|                             "Invalid OpenGL ES version %i.%i", | ||||
|                             ctxconfig->major, ctxconfig->minor); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->robustness) | ||||
|     { | ||||
|         if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION && | ||||
|             ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET) | ||||
|         { | ||||
|             _glfwInputError(GLFW_INVALID_ENUM, | ||||
|                             "Invalid context robustness mode 0x%08X", | ||||
|                             ctxconfig->robustness); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->release) | ||||
|     { | ||||
|         if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE && | ||||
|             ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH) | ||||
|         { | ||||
|             _glfwInputError(GLFW_INVALID_ENUM, | ||||
|                             "Invalid context release behavior 0x%08X", | ||||
|                             ctxconfig->release); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Chooses the framebuffer config that best matches the desired one | ||||
| // | ||||
| const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, | ||||
|                                          const _GLFWfbconfig* alternatives, | ||||
|                                          unsigned int count) | ||||
| { | ||||
|     unsigned int i; | ||||
|     unsigned int missing, leastMissing = UINT_MAX; | ||||
|     unsigned int colorDiff, leastColorDiff = UINT_MAX; | ||||
|     unsigned int extraDiff, leastExtraDiff = UINT_MAX; | ||||
|     const _GLFWfbconfig* current; | ||||
|     const _GLFWfbconfig* closest = NULL; | ||||
|  | ||||
|     for (i = 0;  i < count;  i++) | ||||
|     { | ||||
|         current = alternatives + i; | ||||
|  | ||||
|         if (desired->stereo > 0 && current->stereo == 0) | ||||
|         { | ||||
|             // Stereo is a hard constraint | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         // Count number of missing buffers | ||||
|         { | ||||
|             missing = 0; | ||||
|  | ||||
|             if (desired->alphaBits > 0 && current->alphaBits == 0) | ||||
|                 missing++; | ||||
|  | ||||
|             if (desired->depthBits > 0 && current->depthBits == 0) | ||||
|                 missing++; | ||||
|  | ||||
|             if (desired->stencilBits > 0 && current->stencilBits == 0) | ||||
|                 missing++; | ||||
|  | ||||
|             if (desired->auxBuffers > 0 && | ||||
|                 current->auxBuffers < desired->auxBuffers) | ||||
|             { | ||||
|                 missing += desired->auxBuffers - current->auxBuffers; | ||||
|             } | ||||
|  | ||||
|             if (desired->samples > 0 && current->samples == 0) | ||||
|             { | ||||
|                 // Technically, several multisampling buffers could be | ||||
|                 // involved, but that's a lower level implementation detail and | ||||
|                 // not important to us here, so we count them as one | ||||
|                 missing++; | ||||
|             } | ||||
|  | ||||
|             if (desired->transparent != current->transparent) | ||||
|                 missing++; | ||||
|         } | ||||
|  | ||||
|         // These polynomials make many small channel size differences matter | ||||
|         // less than one large channel size difference | ||||
|  | ||||
|         // Calculate color channel size difference value | ||||
|         { | ||||
|             colorDiff = 0; | ||||
|  | ||||
|             if (desired->redBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 colorDiff += (desired->redBits - current->redBits) * | ||||
|                              (desired->redBits - current->redBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->greenBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 colorDiff += (desired->greenBits - current->greenBits) * | ||||
|                              (desired->greenBits - current->greenBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->blueBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 colorDiff += (desired->blueBits - current->blueBits) * | ||||
|                              (desired->blueBits - current->blueBits); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Calculate non-color channel size difference value | ||||
|         { | ||||
|             extraDiff = 0; | ||||
|  | ||||
|             if (desired->alphaBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->alphaBits - current->alphaBits) * | ||||
|                              (desired->alphaBits - current->alphaBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->depthBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->depthBits - current->depthBits) * | ||||
|                              (desired->depthBits - current->depthBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->stencilBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->stencilBits - current->stencilBits) * | ||||
|                              (desired->stencilBits - current->stencilBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->accumRedBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->accumRedBits - current->accumRedBits) * | ||||
|                              (desired->accumRedBits - current->accumRedBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->accumGreenBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->accumGreenBits - current->accumGreenBits) * | ||||
|                              (desired->accumGreenBits - current->accumGreenBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->accumBlueBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->accumBlueBits - current->accumBlueBits) * | ||||
|                              (desired->accumBlueBits - current->accumBlueBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->accumAlphaBits != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) * | ||||
|                              (desired->accumAlphaBits - current->accumAlphaBits); | ||||
|             } | ||||
|  | ||||
|             if (desired->samples != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 extraDiff += (desired->samples - current->samples) * | ||||
|                              (desired->samples - current->samples); | ||||
|             } | ||||
|  | ||||
|             if (desired->sRGB && !current->sRGB) | ||||
|                 extraDiff++; | ||||
|         } | ||||
|  | ||||
|         // Figure out if the current one is better than the best one found so far | ||||
|         // Least number of missing buffers is the most important heuristic, | ||||
|         // then color buffer size match and lastly size match for other buffers | ||||
|  | ||||
|         if (missing < leastMissing) | ||||
|             closest = current; | ||||
|         else if (missing == leastMissing) | ||||
|         { | ||||
|             if ((colorDiff < leastColorDiff) || | ||||
|                 (colorDiff == leastColorDiff && extraDiff < leastExtraDiff)) | ||||
|             { | ||||
|                 closest = current; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (current == closest) | ||||
|         { | ||||
|             leastMissing = missing; | ||||
|             leastColorDiff = colorDiff; | ||||
|             leastExtraDiff = extraDiff; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return closest; | ||||
| } | ||||
|  | ||||
| // Retrieves the attributes of the current context | ||||
| // | ||||
| GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window, | ||||
|                                     const _GLFWctxconfig* ctxconfig) | ||||
| { | ||||
|     int i; | ||||
|     _GLFWwindow* previous; | ||||
|     const char* version; | ||||
|     const char* prefixes[] = | ||||
|     { | ||||
|         "OpenGL ES-CM ", | ||||
|         "OpenGL ES-CL ", | ||||
|         "OpenGL ES ", | ||||
|         NULL | ||||
|     }; | ||||
|  | ||||
|     window->context.source = ctxconfig->source; | ||||
|     window->context.client = GLFW_OPENGL_API; | ||||
|  | ||||
|     previous = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|     glfwMakeContextCurrent((GLFWwindow*) window); | ||||
|  | ||||
|     window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) | ||||
|         window->context.getProcAddress("glGetIntegerv"); | ||||
|     window->context.GetString = (PFNGLGETSTRINGPROC) | ||||
|         window->context.getProcAddress("glGetString"); | ||||
|     if (!window->context.GetIntegerv || !window->context.GetString) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken"); | ||||
|         glfwMakeContextCurrent((GLFWwindow*) previous); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     version = (const char*) window->context.GetString(GL_VERSION); | ||||
|     if (!version) | ||||
|     { | ||||
|         if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "OpenGL version string retrieval is broken"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "OpenGL ES version string retrieval is broken"); | ||||
|         } | ||||
|  | ||||
|         glfwMakeContextCurrent((GLFWwindow*) previous); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     for (i = 0;  prefixes[i];  i++) | ||||
|     { | ||||
|         const size_t length = strlen(prefixes[i]); | ||||
|  | ||||
|         if (strncmp(version, prefixes[i], length) == 0) | ||||
|         { | ||||
|             version += length; | ||||
|             window->context.client = GLFW_OPENGL_ES_API; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (!sscanf(version, "%d.%d.%d", | ||||
|                 &window->context.major, | ||||
|                 &window->context.minor, | ||||
|                 &window->context.revision)) | ||||
|     { | ||||
|         if (window->context.client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "No version found in OpenGL version string"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "No version found in OpenGL ES version string"); | ||||
|         } | ||||
|  | ||||
|         glfwMakeContextCurrent((GLFWwindow*) previous); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (window->context.major < ctxconfig->major || | ||||
|         (window->context.major == ctxconfig->major && | ||||
|          window->context.minor < ctxconfig->minor)) | ||||
|     { | ||||
|         // The desired OpenGL version is greater than the actual version | ||||
|         // This only happens if the machine lacks {GLX|WGL}_ARB_create_context | ||||
|         // /and/ the user has requested an OpenGL version greater than 1.0 | ||||
|  | ||||
|         // For API consistency, we emulate the behavior of the | ||||
|         // {GLX|WGL}_ARB_create_context extension and fail here | ||||
|  | ||||
|         if (window->context.client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "Requested OpenGL version %i.%i, got version %i.%i", | ||||
|                             ctxconfig->major, ctxconfig->minor, | ||||
|                             window->context.major, window->context.minor); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "Requested OpenGL ES version %i.%i, got version %i.%i", | ||||
|                             ctxconfig->major, ctxconfig->minor, | ||||
|                             window->context.major, window->context.minor); | ||||
|         } | ||||
|  | ||||
|         glfwMakeContextCurrent((GLFWwindow*) previous); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (window->context.major >= 3) | ||||
|     { | ||||
|         // OpenGL 3.0+ uses a different function for extension string retrieval | ||||
|         // We cache it here instead of in glfwExtensionSupported mostly to alert | ||||
|         // users as early as possible that their build may be broken | ||||
|  | ||||
|         window->context.GetStringi = (PFNGLGETSTRINGIPROC) | ||||
|             window->context.getProcAddress("glGetStringi"); | ||||
|         if (!window->context.GetStringi) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "Entry point retrieval is broken"); | ||||
|             glfwMakeContextCurrent((GLFWwindow*) previous); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (window->context.client == GLFW_OPENGL_API) | ||||
|     { | ||||
|         // Read back context flags (OpenGL 3.0 and above) | ||||
|         if (window->context.major >= 3) | ||||
|         { | ||||
|             GLint flags; | ||||
|             window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags); | ||||
|  | ||||
|             if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) | ||||
|                 window->context.forward = GLFW_TRUE; | ||||
|  | ||||
|             if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) | ||||
|                 window->context.debug = GLFW_TRUE; | ||||
|             else if (glfwExtensionSupported("GL_ARB_debug_output") && | ||||
|                      ctxconfig->debug) | ||||
|             { | ||||
|                 // HACK: This is a workaround for older drivers (pre KHR_debug) | ||||
|                 //       not setting the debug bit in the context flags for | ||||
|                 //       debug contexts | ||||
|                 window->context.debug = GLFW_TRUE; | ||||
|             } | ||||
|  | ||||
|             if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR) | ||||
|                 window->context.noerror = GLFW_TRUE; | ||||
|         } | ||||
|  | ||||
|         // Read back OpenGL context profile (OpenGL 3.2 and above) | ||||
|         if (window->context.major >= 4 || | ||||
|             (window->context.major == 3 && window->context.minor >= 2)) | ||||
|         { | ||||
|             GLint mask; | ||||
|             window->context.GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); | ||||
|  | ||||
|             if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) | ||||
|                 window->context.profile = GLFW_OPENGL_COMPAT_PROFILE; | ||||
|             else if (mask & GL_CONTEXT_CORE_PROFILE_BIT) | ||||
|                 window->context.profile = GLFW_OPENGL_CORE_PROFILE; | ||||
|             else if (glfwExtensionSupported("GL_ARB_compatibility")) | ||||
|             { | ||||
|                 // HACK: This is a workaround for the compatibility profile bit | ||||
|                 //       not being set in the context flags if an OpenGL 3.2+ | ||||
|                 //       context was created without having requested a specific | ||||
|                 //       version | ||||
|                 window->context.profile = GLFW_OPENGL_COMPAT_PROFILE; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Read back robustness strategy | ||||
|         if (glfwExtensionSupported("GL_ARB_robustness")) | ||||
|         { | ||||
|             // NOTE: We avoid using the context flags for detection, as they are | ||||
|             //       only present from 3.0 while the extension applies from 1.1 | ||||
|  | ||||
|             GLint strategy; | ||||
|             window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, | ||||
|                                         &strategy); | ||||
|  | ||||
|             if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) | ||||
|                 window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET; | ||||
|             else if (strategy == GL_NO_RESET_NOTIFICATION_ARB) | ||||
|                 window->context.robustness = GLFW_NO_RESET_NOTIFICATION; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // Read back robustness strategy | ||||
|         if (glfwExtensionSupported("GL_EXT_robustness")) | ||||
|         { | ||||
|             // NOTE: The values of these constants match those of the OpenGL ARB | ||||
|             //       one, so we can reuse them here | ||||
|  | ||||
|             GLint strategy; | ||||
|             window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, | ||||
|                                         &strategy); | ||||
|  | ||||
|             if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) | ||||
|                 window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET; | ||||
|             else if (strategy == GL_NO_RESET_NOTIFICATION_ARB) | ||||
|                 window->context.robustness = GLFW_NO_RESET_NOTIFICATION; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (glfwExtensionSupported("GL_KHR_context_flush_control")) | ||||
|     { | ||||
|         GLint behavior; | ||||
|         window->context.GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior); | ||||
|  | ||||
|         if (behavior == GL_NONE) | ||||
|             window->context.release = GLFW_RELEASE_BEHAVIOR_NONE; | ||||
|         else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) | ||||
|             window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH; | ||||
|     } | ||||
|  | ||||
|     // Clearing the front buffer to black to avoid garbage pixels left over from | ||||
|     // previous uses of our bit of VRAM | ||||
|     { | ||||
|         PFNGLCLEARPROC glClear = (PFNGLCLEARPROC) | ||||
|             window->context.getProcAddress("glClear"); | ||||
|         glClear(GL_COLOR_BUFFER_BIT); | ||||
|  | ||||
|         if (window->doublebuffer) | ||||
|             window->context.swapBuffers(window); | ||||
|     } | ||||
|  | ||||
|     glfwMakeContextCurrent((GLFWwindow*) previous); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Searches an extension string for the specified extension | ||||
| // | ||||
| GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions) | ||||
| { | ||||
|     const char* start = extensions; | ||||
|  | ||||
|     for (;;) | ||||
|     { | ||||
|         const char* where; | ||||
|         const char* terminator; | ||||
|  | ||||
|         where = strstr(start, string); | ||||
|         if (!where) | ||||
|             return GLFW_FALSE; | ||||
|  | ||||
|         terminator = where + strlen(string); | ||||
|         if (where == start || *(where - 1) == ' ') | ||||
|         { | ||||
|             if (*terminator == ' ' || *terminator == '\0') | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         start = terminator; | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW public API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     if (window && window->context.client == GLFW_NO_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, | ||||
|                         "Cannot make current with a window that has no OpenGL or OpenGL ES context"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (previous) | ||||
|     { | ||||
|         if (!window || window->context.source != previous->context.source) | ||||
|             previous->context.makeCurrent(NULL); | ||||
|     } | ||||
|  | ||||
|     if (window) | ||||
|         window->context.makeCurrent(window); | ||||
| } | ||||
|  | ||||
| GLFWAPI GLFWwindow* glfwGetCurrentContext(void) | ||||
| { | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|     return _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     assert(window != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     if (window->context.client == GLFW_NO_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, | ||||
|                         "Cannot swap buffers of a window that has no OpenGL or OpenGL ES context"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     window->context.swapBuffers(window); | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwSwapInterval(int interval) | ||||
| { | ||||
|     _GLFWwindow* window; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     window = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|     if (!window) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, | ||||
|                         "Cannot set swap interval without a current OpenGL or OpenGL ES context"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     window->context.swapInterval(interval); | ||||
| } | ||||
|  | ||||
| GLFWAPI int glfwExtensionSupported(const char* extension) | ||||
| { | ||||
|     _GLFWwindow* window; | ||||
|     assert(extension != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); | ||||
|  | ||||
|     window = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|     if (!window) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, | ||||
|                         "Cannot query extension without a current OpenGL or OpenGL ES context"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (*extension == '\0') | ||||
|     { | ||||
|         _glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (window->context.major >= 3) | ||||
|     { | ||||
|         int i; | ||||
|         GLint count; | ||||
|  | ||||
|         // Check if extension is in the modern OpenGL extensions string list | ||||
|  | ||||
|         window->context.GetIntegerv(GL_NUM_EXTENSIONS, &count); | ||||
|  | ||||
|         for (i = 0;  i < count;  i++) | ||||
|         { | ||||
|             const char* en = (const char*) | ||||
|                 window->context.GetStringi(GL_EXTENSIONS, i); | ||||
|             if (!en) | ||||
|             { | ||||
|                 _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                                 "Extension string retrieval is broken"); | ||||
|                 return GLFW_FALSE; | ||||
|             } | ||||
|  | ||||
|             if (strcmp(en, extension) == 0) | ||||
|                 return GLFW_TRUE; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // Check if extension is in the old style OpenGL extensions string | ||||
|  | ||||
|         const char* extensions = (const char*) | ||||
|             window->context.GetString(GL_EXTENSIONS); | ||||
|         if (!extensions) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "Extension string retrieval is broken"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         if (_glfwStringInExtensionString(extension, extensions)) | ||||
|             return GLFW_TRUE; | ||||
|     } | ||||
|  | ||||
|     // Check if extension is in the platform-specific string | ||||
|     return window->context.extensionSupported(extension); | ||||
| } | ||||
|  | ||||
| GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) | ||||
| { | ||||
|     _GLFWwindow* window; | ||||
|     assert(procname != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     window = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|     if (!window) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_CURRENT_CONTEXT, | ||||
|                         "Cannot query entry point without a current OpenGL or OpenGL ES context"); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     return window->context.getProcAddress(procname); | ||||
| } | ||||
|  | ||||
							
								
								
									
										790
									
								
								deps/glfw/src/egl_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										790
									
								
								deps/glfw/src/egl_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,790 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 EGL - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <assert.h> | ||||
|  | ||||
|  | ||||
| // Return a description of the specified EGL error | ||||
| // | ||||
| static const char* getEGLErrorString(EGLint error) | ||||
| { | ||||
|     switch (error) | ||||
|     { | ||||
|         case EGL_SUCCESS: | ||||
|             return "Success"; | ||||
|         case EGL_NOT_INITIALIZED: | ||||
|             return "EGL is not or could not be initialized"; | ||||
|         case EGL_BAD_ACCESS: | ||||
|             return "EGL cannot access a requested resource"; | ||||
|         case EGL_BAD_ALLOC: | ||||
|             return "EGL failed to allocate resources for the requested operation"; | ||||
|         case EGL_BAD_ATTRIBUTE: | ||||
|             return "An unrecognized attribute or attribute value was passed in the attribute list"; | ||||
|         case EGL_BAD_CONTEXT: | ||||
|             return "An EGLContext argument does not name a valid EGL rendering context"; | ||||
|         case EGL_BAD_CONFIG: | ||||
|             return "An EGLConfig argument does not name a valid EGL frame buffer configuration"; | ||||
|         case EGL_BAD_CURRENT_SURFACE: | ||||
|             return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid"; | ||||
|         case EGL_BAD_DISPLAY: | ||||
|             return "An EGLDisplay argument does not name a valid EGL display connection"; | ||||
|         case EGL_BAD_SURFACE: | ||||
|             return "An EGLSurface argument does not name a valid surface configured for GL rendering"; | ||||
|         case EGL_BAD_MATCH: | ||||
|             return "Arguments are inconsistent"; | ||||
|         case EGL_BAD_PARAMETER: | ||||
|             return "One or more argument values are invalid"; | ||||
|         case EGL_BAD_NATIVE_PIXMAP: | ||||
|             return "A NativePixmapType argument does not refer to a valid native pixmap"; | ||||
|         case EGL_BAD_NATIVE_WINDOW: | ||||
|             return "A NativeWindowType argument does not refer to a valid native window"; | ||||
|         case EGL_CONTEXT_LOST: | ||||
|             return "The application must destroy all contexts and reinitialise"; | ||||
|         default: | ||||
|             return "ERROR: UNKNOWN EGL ERROR"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Returns the specified attribute of the specified EGLConfig | ||||
| // | ||||
| static int getEGLConfigAttrib(EGLConfig config, int attrib) | ||||
| { | ||||
|     int value; | ||||
|     eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value); | ||||
|     return value; | ||||
| } | ||||
|  | ||||
| // Return the EGLConfig most closely matching the specified hints | ||||
| // | ||||
| static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, | ||||
|                                 const _GLFWfbconfig* desired, | ||||
|                                 EGLConfig* result) | ||||
| { | ||||
|     EGLConfig* nativeConfigs; | ||||
|     _GLFWfbconfig* usableConfigs; | ||||
|     const _GLFWfbconfig* closest; | ||||
|     int i, nativeCount, usableCount; | ||||
|  | ||||
|     eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); | ||||
|     if (!nativeCount) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); | ||||
|     eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount); | ||||
|  | ||||
|     usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); | ||||
|     usableCount = 0; | ||||
|  | ||||
|     for (i = 0;  i < nativeCount;  i++) | ||||
|     { | ||||
|         const EGLConfig n = nativeConfigs[i]; | ||||
|         _GLFWfbconfig* u = usableConfigs + usableCount; | ||||
|  | ||||
|         // Only consider RGB(A) EGLConfigs | ||||
|         if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER) | ||||
|             continue; | ||||
|  | ||||
|         // Only consider window EGLConfigs | ||||
|         if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) | ||||
|             continue; | ||||
|  | ||||
| #if defined(_GLFW_X11) | ||||
|         { | ||||
|             XVisualInfo vi = {0}; | ||||
|  | ||||
|             // Only consider EGLConfigs with associated Visuals | ||||
|             vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID); | ||||
|             if (!vi.visualid) | ||||
|                 continue; | ||||
|  | ||||
|             if (desired->transparent) | ||||
|             { | ||||
|                 int count; | ||||
|                 XVisualInfo* vis = | ||||
|                     XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count); | ||||
|                 if (vis) | ||||
|                 { | ||||
|                     u->transparent = _glfwIsVisualTransparentX11(vis[0].visual); | ||||
|                     XFree(vis); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| #endif // _GLFW_X11 | ||||
|  | ||||
|         if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|         { | ||||
|             if (ctxconfig->major == 1) | ||||
|             { | ||||
|                 if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) | ||||
|                     continue; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) | ||||
|                     continue; | ||||
|             } | ||||
|         } | ||||
|         else if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) | ||||
|                 continue; | ||||
|         } | ||||
|  | ||||
|         u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE); | ||||
|         u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE); | ||||
|         u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE); | ||||
|  | ||||
|         u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE); | ||||
|         u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE); | ||||
|         u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE); | ||||
|  | ||||
|         u->samples = getEGLConfigAttrib(n, EGL_SAMPLES); | ||||
|         u->doublebuffer = desired->doublebuffer; | ||||
|  | ||||
|         u->handle = (uintptr_t) n; | ||||
|         usableCount++; | ||||
|     } | ||||
|  | ||||
|     closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); | ||||
|     if (closest) | ||||
|         *result = (EGLConfig) closest->handle; | ||||
|  | ||||
|     free(nativeConfigs); | ||||
|     free(usableConfigs); | ||||
|  | ||||
|     return closest != NULL; | ||||
| } | ||||
|  | ||||
| static void makeContextCurrentEGL(_GLFWwindow* window) | ||||
| { | ||||
|     if (window) | ||||
|     { | ||||
|         if (!eglMakeCurrent(_glfw.egl.display, | ||||
|                             window->context.egl.surface, | ||||
|                             window->context.egl.surface, | ||||
|                             window->context.egl.handle)) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "EGL: Failed to make context current: %s", | ||||
|                             getEGLErrorString(eglGetError())); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!eglMakeCurrent(_glfw.egl.display, | ||||
|                             EGL_NO_SURFACE, | ||||
|                             EGL_NO_SURFACE, | ||||
|                             EGL_NO_CONTEXT)) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "EGL: Failed to clear current context: %s", | ||||
|                             getEGLErrorString(eglGetError())); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _glfwPlatformSetTls(&_glfw.contextSlot, window); | ||||
| } | ||||
|  | ||||
| static void swapBuffersEGL(_GLFWwindow* window) | ||||
| { | ||||
|     if (window != _glfwPlatformGetTls(&_glfw.contextSlot)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "EGL: The context must be current on the calling thread when swapping buffers"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     eglSwapBuffers(_glfw.egl.display, window->context.egl.surface); | ||||
| } | ||||
|  | ||||
| static void swapIntervalEGL(int interval) | ||||
| { | ||||
|     eglSwapInterval(_glfw.egl.display, interval); | ||||
| } | ||||
|  | ||||
| static int extensionSupportedEGL(const char* extension) | ||||
| { | ||||
|     const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS); | ||||
|     if (extensions) | ||||
|     { | ||||
|         if (_glfwStringInExtensionString(extension, extensions)) | ||||
|             return GLFW_TRUE; | ||||
|     } | ||||
|  | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| static GLFWglproc getProcAddressEGL(const char* procname) | ||||
| { | ||||
|     _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|  | ||||
|     if (window->context.egl.client) | ||||
|     { | ||||
|         GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client, | ||||
|                                                    procname); | ||||
|         if (proc) | ||||
|             return proc; | ||||
|     } | ||||
|  | ||||
|     return eglGetProcAddress(procname); | ||||
| } | ||||
|  | ||||
| static void destroyContextEGL(_GLFWwindow* window) | ||||
| { | ||||
| #if defined(_GLFW_X11) | ||||
|     // NOTE: Do not unload libGL.so.1 while the X11 display is still open, | ||||
|     //       as it will make XCloseDisplay segfault | ||||
|     if (window->context.client != GLFW_OPENGL_API) | ||||
| #endif // _GLFW_X11 | ||||
|     { | ||||
|         if (window->context.egl.client) | ||||
|         { | ||||
|             _glfw_dlclose(window->context.egl.client); | ||||
|             window->context.egl.client = NULL; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (window->context.egl.surface) | ||||
|     { | ||||
|         eglDestroySurface(_glfw.egl.display, window->context.egl.surface); | ||||
|         window->context.egl.surface = EGL_NO_SURFACE; | ||||
|     } | ||||
|  | ||||
|     if (window->context.egl.handle) | ||||
|     { | ||||
|         eglDestroyContext(_glfw.egl.display, window->context.egl.handle); | ||||
|         window->context.egl.handle = EGL_NO_CONTEXT; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialize EGL | ||||
| // | ||||
| GLFWbool _glfwInitEGL(void) | ||||
| { | ||||
|     int i; | ||||
|     const char* sonames[] = | ||||
|     { | ||||
| #if defined(_GLFW_EGL_LIBRARY) | ||||
|         _GLFW_EGL_LIBRARY, | ||||
| #elif defined(_GLFW_WIN32) | ||||
|         "libEGL.dll", | ||||
|         "EGL.dll", | ||||
| #elif defined(_GLFW_COCOA) | ||||
|         "libEGL.dylib", | ||||
| #elif defined(__CYGWIN__) | ||||
|         "libEGL-1.so", | ||||
| #else | ||||
|         "libEGL.so.1", | ||||
| #endif | ||||
|         NULL | ||||
|     }; | ||||
|  | ||||
|     if (_glfw.egl.handle) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
|     for (i = 0;  sonames[i];  i++) | ||||
|     { | ||||
|         _glfw.egl.handle = _glfw_dlopen(sonames[i]); | ||||
|         if (_glfw.egl.handle) | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     if (!_glfw.egl.handle) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0); | ||||
|  | ||||
|     _glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib"); | ||||
|     _glfw.egl.GetConfigs = (PFN_eglGetConfigs) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglGetConfigs"); | ||||
|     _glfw.egl.GetDisplay = (PFN_eglGetDisplay) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglGetDisplay"); | ||||
|     _glfw.egl.GetError = (PFN_eglGetError) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglGetError"); | ||||
|     _glfw.egl.Initialize = (PFN_eglInitialize) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglInitialize"); | ||||
|     _glfw.egl.Terminate = (PFN_eglTerminate) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglTerminate"); | ||||
|     _glfw.egl.BindAPI = (PFN_eglBindAPI) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglBindAPI"); | ||||
|     _glfw.egl.CreateContext = (PFN_eglCreateContext) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglCreateContext"); | ||||
|     _glfw.egl.DestroySurface = (PFN_eglDestroySurface) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglDestroySurface"); | ||||
|     _glfw.egl.DestroyContext = (PFN_eglDestroyContext) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglDestroyContext"); | ||||
|     _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface"); | ||||
|     _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent"); | ||||
|     _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers"); | ||||
|     _glfw.egl.SwapInterval = (PFN_eglSwapInterval) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglSwapInterval"); | ||||
|     _glfw.egl.QueryString = (PFN_eglQueryString) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglQueryString"); | ||||
|     _glfw.egl.GetProcAddress = (PFN_eglGetProcAddress) | ||||
|         _glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress"); | ||||
|  | ||||
|     if (!_glfw.egl.GetConfigAttrib || | ||||
|         !_glfw.egl.GetConfigs || | ||||
|         !_glfw.egl.GetDisplay || | ||||
|         !_glfw.egl.GetError || | ||||
|         !_glfw.egl.Initialize || | ||||
|         !_glfw.egl.Terminate || | ||||
|         !_glfw.egl.BindAPI || | ||||
|         !_glfw.egl.CreateContext || | ||||
|         !_glfw.egl.DestroySurface || | ||||
|         !_glfw.egl.DestroyContext || | ||||
|         !_glfw.egl.CreateWindowSurface || | ||||
|         !_glfw.egl.MakeCurrent || | ||||
|         !_glfw.egl.SwapBuffers || | ||||
|         !_glfw.egl.SwapInterval || | ||||
|         !_glfw.egl.QueryString || | ||||
|         !_glfw.egl.GetProcAddress) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "EGL: Failed to load required entry points"); | ||||
|  | ||||
|         _glfwTerminateEGL(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); | ||||
|     if (_glfw.egl.display == EGL_NO_DISPLAY) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "EGL: Failed to get EGL display: %s", | ||||
|                         getEGLErrorString(eglGetError())); | ||||
|  | ||||
|         _glfwTerminateEGL(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "EGL: Failed to initialize EGL: %s", | ||||
|                         getEGLErrorString(eglGetError())); | ||||
|  | ||||
|         _glfwTerminateEGL(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.egl.KHR_create_context = | ||||
|         extensionSupportedEGL("EGL_KHR_create_context"); | ||||
|     _glfw.egl.KHR_create_context_no_error = | ||||
|         extensionSupportedEGL("EGL_KHR_create_context_no_error"); | ||||
|     _glfw.egl.KHR_gl_colorspace = | ||||
|         extensionSupportedEGL("EGL_KHR_gl_colorspace"); | ||||
|     _glfw.egl.KHR_get_all_proc_addresses = | ||||
|         extensionSupportedEGL("EGL_KHR_get_all_proc_addresses"); | ||||
|     _glfw.egl.KHR_context_flush_control = | ||||
|         extensionSupportedEGL("EGL_KHR_context_flush_control"); | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Terminate EGL | ||||
| // | ||||
| void _glfwTerminateEGL(void) | ||||
| { | ||||
|     if (_glfw.egl.display) | ||||
|     { | ||||
|         eglTerminate(_glfw.egl.display); | ||||
|         _glfw.egl.display = EGL_NO_DISPLAY; | ||||
|     } | ||||
|  | ||||
|     if (_glfw.egl.handle) | ||||
|     { | ||||
|         _glfw_dlclose(_glfw.egl.handle); | ||||
|         _glfw.egl.handle = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #define setAttrib(a, v) \ | ||||
| { \ | ||||
|     assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ | ||||
|     attribs[index++] = a; \ | ||||
|     attribs[index++] = v; \ | ||||
| } | ||||
|  | ||||
| // Create the OpenGL or OpenGL ES context | ||||
| // | ||||
| GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, | ||||
|                                const _GLFWctxconfig* ctxconfig, | ||||
|                                const _GLFWfbconfig* fbconfig) | ||||
| { | ||||
|     EGLint attribs[40]; | ||||
|     EGLConfig config; | ||||
|     EGLContext share = NULL; | ||||
|     int index = 0; | ||||
|  | ||||
|     if (!_glfw.egl.display) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->share) | ||||
|         share = ctxconfig->share->context.egl.handle; | ||||
|  | ||||
|     if (!chooseEGLConfig(ctxconfig, fbconfig, &config)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_FORMAT_UNAVAILABLE, | ||||
|                         "EGL: Failed to find a suitable EGLConfig"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|     { | ||||
|         if (!eglBindAPI(EGL_OPENGL_ES_API)) | ||||
|         { | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                             "EGL: Failed to bind OpenGL ES: %s", | ||||
|                             getEGLErrorString(eglGetError())); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!eglBindAPI(EGL_OPENGL_API)) | ||||
|         { | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                             "EGL: Failed to bind OpenGL: %s", | ||||
|                             getEGLErrorString(eglGetError())); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (_glfw.egl.KHR_create_context) | ||||
|     { | ||||
|         int mask = 0, flags = 0; | ||||
|  | ||||
|         if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             if (ctxconfig->forward) | ||||
|                 flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; | ||||
|  | ||||
|             if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) | ||||
|                 mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; | ||||
|             else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) | ||||
|                 mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->debug) | ||||
|             flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; | ||||
|  | ||||
|         if (ctxconfig->robustness) | ||||
|         { | ||||
|             if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) | ||||
|             { | ||||
|                 setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, | ||||
|                           EGL_NO_RESET_NOTIFICATION_KHR); | ||||
|             } | ||||
|             else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) | ||||
|             { | ||||
|                 setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, | ||||
|                           EGL_LOSE_CONTEXT_ON_RESET_KHR); | ||||
|             } | ||||
|  | ||||
|             flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->noerror) | ||||
|         { | ||||
|             if (_glfw.egl.KHR_create_context_no_error) | ||||
|                 setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE); | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->major != 1 || ctxconfig->minor != 0) | ||||
|         { | ||||
|             setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); | ||||
|             setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); | ||||
|         } | ||||
|  | ||||
|         if (mask) | ||||
|             setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); | ||||
|  | ||||
|         if (flags) | ||||
|             setAttrib(EGL_CONTEXT_FLAGS_KHR, flags); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|             setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); | ||||
|     } | ||||
|  | ||||
|     if (_glfw.egl.KHR_context_flush_control) | ||||
|     { | ||||
|         if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) | ||||
|         { | ||||
|             setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, | ||||
|                       EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR); | ||||
|         } | ||||
|         else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) | ||||
|         { | ||||
|             setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, | ||||
|                       EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     setAttrib(EGL_NONE, EGL_NONE); | ||||
|  | ||||
|     window->context.egl.handle = eglCreateContext(_glfw.egl.display, | ||||
|                                                   config, share, attribs); | ||||
|  | ||||
|     if (window->context.egl.handle == EGL_NO_CONTEXT) | ||||
|     { | ||||
|         _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                         "EGL: Failed to create context: %s", | ||||
|                         getEGLErrorString(eglGetError())); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     // Set up attributes for surface creation | ||||
|     index = 0; | ||||
|  | ||||
|     if (fbconfig->sRGB) | ||||
|     { | ||||
|         if (_glfw.egl.KHR_gl_colorspace) | ||||
|             setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR); | ||||
|     } | ||||
|  | ||||
|     if (!fbconfig->doublebuffer) | ||||
|         setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); | ||||
|  | ||||
|     setAttrib(EGL_NONE, EGL_NONE); | ||||
|  | ||||
|     window->context.egl.surface = | ||||
|         eglCreateWindowSurface(_glfw.egl.display, | ||||
|                                config, | ||||
|                                _GLFW_EGL_NATIVE_WINDOW, | ||||
|                                attribs); | ||||
|     if (window->context.egl.surface == EGL_NO_SURFACE) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "EGL: Failed to create window surface: %s", | ||||
|                         getEGLErrorString(eglGetError())); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     window->context.egl.config = config; | ||||
|  | ||||
|     // Load the appropriate client library | ||||
|     if (!_glfw.egl.KHR_get_all_proc_addresses) | ||||
|     { | ||||
|         int i; | ||||
|         const char** sonames; | ||||
|         const char* es1sonames[] = | ||||
|         { | ||||
| #if defined(_GLFW_GLESV1_LIBRARY) | ||||
|             _GLFW_GLESV1_LIBRARY, | ||||
| #elif defined(_GLFW_WIN32) | ||||
|             "GLESv1_CM.dll", | ||||
|             "libGLES_CM.dll", | ||||
| #elif defined(_GLFW_COCOA) | ||||
|             "libGLESv1_CM.dylib", | ||||
| #else | ||||
|             "libGLESv1_CM.so.1", | ||||
|             "libGLES_CM.so.1", | ||||
| #endif | ||||
|             NULL | ||||
|         }; | ||||
|         const char* es2sonames[] = | ||||
|         { | ||||
| #if defined(_GLFW_GLESV2_LIBRARY) | ||||
|             _GLFW_GLESV2_LIBRARY, | ||||
| #elif defined(_GLFW_WIN32) | ||||
|             "GLESv2.dll", | ||||
|             "libGLESv2.dll", | ||||
| #elif defined(_GLFW_COCOA) | ||||
|             "libGLESv2.dylib", | ||||
| #elif defined(__CYGWIN__) | ||||
|             "libGLESv2-2.so", | ||||
| #else | ||||
|             "libGLESv2.so.2", | ||||
| #endif | ||||
|             NULL | ||||
|         }; | ||||
|         const char* glsonames[] = | ||||
|         { | ||||
| #if defined(_GLFW_OPENGL_LIBRARY) | ||||
|             _GLFW_OPENGL_LIBRARY, | ||||
| #elif defined(_GLFW_WIN32) | ||||
| #elif defined(_GLFW_COCOA) | ||||
| #else | ||||
|             "libGL.so.1", | ||||
| #endif | ||||
|             NULL | ||||
|         }; | ||||
|  | ||||
|         if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|         { | ||||
|             if (ctxconfig->major == 1) | ||||
|                 sonames = es1sonames; | ||||
|             else | ||||
|                 sonames = es2sonames; | ||||
|         } | ||||
|         else | ||||
|             sonames = glsonames; | ||||
|  | ||||
|         for (i = 0;  sonames[i];  i++) | ||||
|         { | ||||
|             // HACK: Match presence of lib prefix to increase chance of finding | ||||
|             //       a matching pair in the jungle that is Win32 EGL/GLES | ||||
|             if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0)) | ||||
|                 continue; | ||||
|  | ||||
|             window->context.egl.client = _glfw_dlopen(sonames[i]); | ||||
|             if (window->context.egl.client) | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         if (!window->context.egl.client) | ||||
|         { | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                             "EGL: Failed to load client library"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     window->context.makeCurrent = makeContextCurrentEGL; | ||||
|     window->context.swapBuffers = swapBuffersEGL; | ||||
|     window->context.swapInterval = swapIntervalEGL; | ||||
|     window->context.extensionSupported = extensionSupportedEGL; | ||||
|     window->context.getProcAddress = getProcAddressEGL; | ||||
|     window->context.destroy = destroyContextEGL; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| #undef setAttrib | ||||
|  | ||||
| // Returns the Visual and depth of the chosen EGLConfig | ||||
| // | ||||
| #if defined(_GLFW_X11) | ||||
| GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, | ||||
|                               const _GLFWctxconfig* ctxconfig, | ||||
|                               const _GLFWfbconfig* fbconfig, | ||||
|                               Visual** visual, int* depth) | ||||
| { | ||||
|     XVisualInfo* result; | ||||
|     XVisualInfo desired; | ||||
|     EGLConfig native; | ||||
|     EGLint visualID = 0, count = 0; | ||||
|     const long vimask = VisualScreenMask | VisualIDMask; | ||||
|  | ||||
|     if (!chooseEGLConfig(ctxconfig, fbconfig, &native)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_FORMAT_UNAVAILABLE, | ||||
|                         "EGL: Failed to find a suitable EGLConfig"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     eglGetConfigAttrib(_glfw.egl.display, native, | ||||
|                        EGL_NATIVE_VISUAL_ID, &visualID); | ||||
|  | ||||
|     desired.screen = _glfw.x11.screen; | ||||
|     desired.visualid = visualID; | ||||
|  | ||||
|     result = XGetVisualInfo(_glfw.x11.display, vimask, &desired, &count); | ||||
|     if (!result) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "EGL: Failed to retrieve Visual for EGLConfig"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     *visual = result->visual; | ||||
|     *depth = result->depth; | ||||
|  | ||||
|     XFree(result); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
| #endif // _GLFW_X11 | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI EGLDisplay glfwGetEGLDisplay(void) | ||||
| { | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY); | ||||
|     return _glfw.egl.display; | ||||
| } | ||||
|  | ||||
| GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); | ||||
|  | ||||
|     if (window->context.source != GLFW_EGL_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return EGL_NO_CONTEXT; | ||||
|     } | ||||
|  | ||||
|     return window->context.egl.handle; | ||||
| } | ||||
|  | ||||
| GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); | ||||
|  | ||||
|     if (window->context.source != GLFW_EGL_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return EGL_NO_SURFACE; | ||||
|     } | ||||
|  | ||||
|     return window->context.egl.surface; | ||||
| } | ||||
|  | ||||
							
								
								
									
										215
									
								
								deps/glfw/src/egl_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								deps/glfw/src/egl_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 EGL - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #if defined(_GLFW_USE_EGLPLATFORM_H) | ||||
|  #include <EGL/eglplatform.h> | ||||
| #elif defined(_GLFW_WIN32) | ||||
|  #define EGLAPIENTRY __stdcall | ||||
| typedef HDC EGLNativeDisplayType; | ||||
| typedef HWND EGLNativeWindowType; | ||||
| #elif defined(_GLFW_COCOA) | ||||
|  #define EGLAPIENTRY | ||||
| typedef void* EGLNativeDisplayType; | ||||
| typedef id EGLNativeWindowType; | ||||
| #elif defined(_GLFW_X11) | ||||
|  #define EGLAPIENTRY | ||||
| typedef Display* EGLNativeDisplayType; | ||||
| typedef Window EGLNativeWindowType; | ||||
| #elif defined(_GLFW_WAYLAND) | ||||
|  #define EGLAPIENTRY | ||||
| typedef struct wl_display* EGLNativeDisplayType; | ||||
| typedef struct wl_egl_window* EGLNativeWindowType; | ||||
| #else | ||||
|  #error "No supported EGL platform selected" | ||||
| #endif | ||||
|  | ||||
| #define EGL_SUCCESS 0x3000 | ||||
| #define EGL_NOT_INITIALIZED 0x3001 | ||||
| #define EGL_BAD_ACCESS 0x3002 | ||||
| #define EGL_BAD_ALLOC 0x3003 | ||||
| #define EGL_BAD_ATTRIBUTE 0x3004 | ||||
| #define EGL_BAD_CONFIG 0x3005 | ||||
| #define EGL_BAD_CONTEXT 0x3006 | ||||
| #define EGL_BAD_CURRENT_SURFACE 0x3007 | ||||
| #define EGL_BAD_DISPLAY 0x3008 | ||||
| #define EGL_BAD_MATCH 0x3009 | ||||
| #define EGL_BAD_NATIVE_PIXMAP 0x300a | ||||
| #define EGL_BAD_NATIVE_WINDOW 0x300b | ||||
| #define EGL_BAD_PARAMETER 0x300c | ||||
| #define EGL_BAD_SURFACE 0x300d | ||||
| #define EGL_CONTEXT_LOST 0x300e | ||||
| #define EGL_COLOR_BUFFER_TYPE 0x303f | ||||
| #define EGL_RGB_BUFFER 0x308e | ||||
| #define EGL_SURFACE_TYPE 0x3033 | ||||
| #define EGL_WINDOW_BIT 0x0004 | ||||
| #define EGL_RENDERABLE_TYPE 0x3040 | ||||
| #define EGL_OPENGL_ES_BIT 0x0001 | ||||
| #define EGL_OPENGL_ES2_BIT 0x0004 | ||||
| #define EGL_OPENGL_BIT 0x0008 | ||||
| #define EGL_ALPHA_SIZE 0x3021 | ||||
| #define EGL_BLUE_SIZE 0x3022 | ||||
| #define EGL_GREEN_SIZE 0x3023 | ||||
| #define EGL_RED_SIZE 0x3024 | ||||
| #define EGL_DEPTH_SIZE 0x3025 | ||||
| #define EGL_STENCIL_SIZE 0x3026 | ||||
| #define EGL_SAMPLES 0x3031 | ||||
| #define EGL_OPENGL_ES_API 0x30a0 | ||||
| #define EGL_OPENGL_API 0x30a2 | ||||
| #define EGL_NONE 0x3038 | ||||
| #define EGL_RENDER_BUFFER 0x3086 | ||||
| #define EGL_SINGLE_BUFFER 0x3085 | ||||
| #define EGL_EXTENSIONS 0x3055 | ||||
| #define EGL_CONTEXT_CLIENT_VERSION 0x3098 | ||||
| #define EGL_NATIVE_VISUAL_ID 0x302e | ||||
| #define EGL_NO_SURFACE ((EGLSurface) 0) | ||||
| #define EGL_NO_DISPLAY ((EGLDisplay) 0) | ||||
| #define EGL_NO_CONTEXT ((EGLContext) 0) | ||||
| #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0) | ||||
|  | ||||
| #define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 | ||||
| #define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 | ||||
| #define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 | ||||
| #define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 | ||||
| #define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd | ||||
| #define EGL_NO_RESET_NOTIFICATION_KHR 0x31be | ||||
| #define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf | ||||
| #define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 | ||||
| #define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 | ||||
| #define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb | ||||
| #define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd | ||||
| #define EGL_CONTEXT_FLAGS_KHR 0x30fc | ||||
| #define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3 | ||||
| #define EGL_GL_COLORSPACE_KHR 0x309d | ||||
| #define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 | ||||
| #define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 | ||||
| #define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 | ||||
| #define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 | ||||
|  | ||||
| typedef int EGLint; | ||||
| typedef unsigned int EGLBoolean; | ||||
| typedef unsigned int EGLenum; | ||||
| typedef void* EGLConfig; | ||||
| typedef void* EGLContext; | ||||
| typedef void* EGLDisplay; | ||||
| typedef void* EGLSurface; | ||||
|  | ||||
| // EGL function pointer typedefs | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*); | ||||
| typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType); | ||||
| typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum); | ||||
| typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext); | ||||
| typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); | ||||
| typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); | ||||
| typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint); | ||||
| typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); | ||||
| #define eglGetConfigAttrib _glfw.egl.GetConfigAttrib | ||||
| #define eglGetConfigs _glfw.egl.GetConfigs | ||||
| #define eglGetDisplay _glfw.egl.GetDisplay | ||||
| #define eglGetError _glfw.egl.GetError | ||||
| #define eglInitialize _glfw.egl.Initialize | ||||
| #define eglTerminate _glfw.egl.Terminate | ||||
| #define eglBindAPI _glfw.egl.BindAPI | ||||
| #define eglCreateContext _glfw.egl.CreateContext | ||||
| #define eglDestroySurface _glfw.egl.DestroySurface | ||||
| #define eglDestroyContext _glfw.egl.DestroyContext | ||||
| #define eglCreateWindowSurface _glfw.egl.CreateWindowSurface | ||||
| #define eglMakeCurrent _glfw.egl.MakeCurrent | ||||
| #define eglSwapBuffers _glfw.egl.SwapBuffers | ||||
| #define eglSwapInterval _glfw.egl.SwapInterval | ||||
| #define eglQueryString _glfw.egl.QueryString | ||||
| #define eglGetProcAddress _glfw.egl.GetProcAddress | ||||
|  | ||||
| #define _GLFW_EGL_CONTEXT_STATE            _GLFWcontextEGL egl | ||||
| #define _GLFW_EGL_LIBRARY_CONTEXT_STATE    _GLFWlibraryEGL egl | ||||
|  | ||||
|  | ||||
| // EGL-specific per-context data | ||||
| // | ||||
| typedef struct _GLFWcontextEGL | ||||
| { | ||||
|    EGLConfig        config; | ||||
|    EGLContext       handle; | ||||
|    EGLSurface       surface; | ||||
|  | ||||
|    void*            client; | ||||
| } _GLFWcontextEGL; | ||||
|  | ||||
| // EGL-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryEGL | ||||
| { | ||||
|     EGLDisplay      display; | ||||
|     EGLint          major, minor; | ||||
|     GLFWbool        prefix; | ||||
|  | ||||
|     GLFWbool        KHR_create_context; | ||||
|     GLFWbool        KHR_create_context_no_error; | ||||
|     GLFWbool        KHR_gl_colorspace; | ||||
|     GLFWbool        KHR_get_all_proc_addresses; | ||||
|     GLFWbool        KHR_context_flush_control; | ||||
|  | ||||
|     void*           handle; | ||||
|  | ||||
|     PFN_eglGetConfigAttrib      GetConfigAttrib; | ||||
|     PFN_eglGetConfigs           GetConfigs; | ||||
|     PFN_eglGetDisplay           GetDisplay; | ||||
|     PFN_eglGetError             GetError; | ||||
|     PFN_eglInitialize           Initialize; | ||||
|     PFN_eglTerminate            Terminate; | ||||
|     PFN_eglBindAPI              BindAPI; | ||||
|     PFN_eglCreateContext        CreateContext; | ||||
|     PFN_eglDestroySurface       DestroySurface; | ||||
|     PFN_eglDestroyContext       DestroyContext; | ||||
|     PFN_eglCreateWindowSurface  CreateWindowSurface; | ||||
|     PFN_eglMakeCurrent          MakeCurrent; | ||||
|     PFN_eglSwapBuffers          SwapBuffers; | ||||
|     PFN_eglSwapInterval         SwapInterval; | ||||
|     PFN_eglQueryString          QueryString; | ||||
|     PFN_eglGetProcAddress       GetProcAddress; | ||||
| } _GLFWlibraryEGL; | ||||
|  | ||||
|  | ||||
| GLFWbool _glfwInitEGL(void); | ||||
| void _glfwTerminateEGL(void); | ||||
| GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, | ||||
|                                const _GLFWctxconfig* ctxconfig, | ||||
|                                const _GLFWfbconfig* fbconfig); | ||||
| #if defined(_GLFW_X11) | ||||
| GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, | ||||
|                               const _GLFWctxconfig* ctxconfig, | ||||
|                               const _GLFWfbconfig* fbconfig, | ||||
|                               Visual** visual, int* depth); | ||||
| #endif /*_GLFW_X11*/ | ||||
|  | ||||
							
								
								
									
										13
									
								
								deps/glfw/src/glfw3.pc.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								deps/glfw/src/glfw3.pc.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| prefix=@CMAKE_INSTALL_PREFIX@ | ||||
| exec_prefix=${prefix} | ||||
| includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ | ||||
| libdir=@CMAKE_INSTALL_FULL_LIBDIR@ | ||||
|  | ||||
| Name: GLFW | ||||
| Description: A multi-platform library for OpenGL, window and input | ||||
| Version: @GLFW_VERSION@ | ||||
| URL: https://www.glfw.org/ | ||||
| Requires.private: @GLFW_PKG_DEPS@ | ||||
| Libs: -L${libdir} -l@GLFW_LIB_NAME@ | ||||
| Libs.private: @GLFW_PKG_LIBS@ | ||||
| Cflags: -I${includedir} | ||||
							
								
								
									
										1
									
								
								deps/glfw/src/glfw3Config.cmake.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								deps/glfw/src/glfw3Config.cmake.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake") | ||||
							
								
								
									
										60
									
								
								deps/glfw/src/glfw_config.h.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								deps/glfw/src/glfw_config.h.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2010-2016 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // As glfw_config.h.in, this file is used by CMake to produce the | ||||
| // glfw_config.h configuration header file.  If you are adding a feature | ||||
| // requiring conditional compilation, this is where to add the macro. | ||||
| //======================================================================== | ||||
| // As glfw_config.h, this file defines compile-time option macros for a | ||||
| // specific platform and development environment.  If you are using the | ||||
| // GLFW CMake files, modify glfw_config.h.in instead of this file.  If you | ||||
| // are using your own build system, make this file define the appropriate | ||||
| // macros in whatever way is suitable. | ||||
| //======================================================================== | ||||
|  | ||||
| // Define this to 1 if building GLFW for X11 | ||||
| #cmakedefine _GLFW_X11 | ||||
| // Define this to 1 if building GLFW for Win32 | ||||
| #cmakedefine _GLFW_WIN32 | ||||
| // Define this to 1 if building GLFW for Cocoa | ||||
| #cmakedefine _GLFW_COCOA | ||||
| // Define this to 1 if building GLFW for Wayland | ||||
| #cmakedefine _GLFW_WAYLAND | ||||
| // Define this to 1 if building GLFW for OSMesa | ||||
| #cmakedefine _GLFW_OSMESA | ||||
|  | ||||
| // Define this to 1 if building as a shared library / dynamic library / DLL | ||||
| #cmakedefine _GLFW_BUILD_DLL | ||||
| // Define this to 1 to use Vulkan loader linked statically into application | ||||
| #cmakedefine _GLFW_VULKAN_STATIC | ||||
|  | ||||
| // Define this to 1 to force use of high-performance GPU on hybrid systems | ||||
| #cmakedefine _GLFW_USE_HYBRID_HPG | ||||
|  | ||||
| // Define this to 1 if xkbcommon supports the compose key | ||||
| #cmakedefine HAVE_XKBCOMMON_COMPOSE_H | ||||
| // Define this to 1 if the libc supports memfd_create() | ||||
| #cmakedefine HAVE_MEMFD_CREATE | ||||
|  | ||||
							
								
								
									
										699
									
								
								deps/glfw/src/glx_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										699
									
								
								deps/glfw/src/glx_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,699 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 GLX - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| #ifndef GLXBadProfileARB | ||||
|  #define GLXBadProfileARB 13 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| // Returns the specified attribute of the specified GLXFBConfig | ||||
| // | ||||
| static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib) | ||||
| { | ||||
|     int value; | ||||
|     glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); | ||||
|     return value; | ||||
| } | ||||
|  | ||||
| // Return the GLXFBConfig most closely matching the specified hints | ||||
| // | ||||
| static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, | ||||
|                                   GLXFBConfig* result) | ||||
| { | ||||
|     GLXFBConfig* nativeConfigs; | ||||
|     _GLFWfbconfig* usableConfigs; | ||||
|     const _GLFWfbconfig* closest; | ||||
|     int i, nativeCount, usableCount; | ||||
|     const char* vendor; | ||||
|     GLFWbool trustWindowBit = GLFW_TRUE; | ||||
|  | ||||
|     // HACK: This is a (hopefully temporary) workaround for Chromium | ||||
|     //       (VirtualBox GL) not setting the window bit on any GLXFBConfigs | ||||
|     vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); | ||||
|     if (vendor && strcmp(vendor, "Chromium") == 0) | ||||
|         trustWindowBit = GLFW_FALSE; | ||||
|  | ||||
|     nativeConfigs = | ||||
|         glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount); | ||||
|     if (!nativeConfigs || !nativeCount) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); | ||||
|     usableCount = 0; | ||||
|  | ||||
|     for (i = 0;  i < nativeCount;  i++) | ||||
|     { | ||||
|         const GLXFBConfig n = nativeConfigs[i]; | ||||
|         _GLFWfbconfig* u = usableConfigs + usableCount; | ||||
|  | ||||
|         // Only consider RGBA GLXFBConfigs | ||||
|         if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT)) | ||||
|             continue; | ||||
|  | ||||
|         // Only consider window GLXFBConfigs | ||||
|         if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) | ||||
|         { | ||||
|             if (trustWindowBit) | ||||
|                 continue; | ||||
|         } | ||||
|  | ||||
|         if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER) != desired->doublebuffer) | ||||
|             continue; | ||||
|  | ||||
|         if (desired->transparent) | ||||
|         { | ||||
|             XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n); | ||||
|             if (vi) | ||||
|             { | ||||
|                 u->transparent = _glfwIsVisualTransparentX11(vi->visual); | ||||
|                 XFree(vi); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE); | ||||
|         u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE); | ||||
|         u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE); | ||||
|  | ||||
|         u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE); | ||||
|         u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE); | ||||
|         u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE); | ||||
|  | ||||
|         u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); | ||||
|         u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); | ||||
|         u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); | ||||
|         u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); | ||||
|  | ||||
|         u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS); | ||||
|  | ||||
|         if (getGLXFBConfigAttrib(n, GLX_STEREO)) | ||||
|             u->stereo = GLFW_TRUE; | ||||
|  | ||||
|         if (_glfw.glx.ARB_multisample) | ||||
|             u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES); | ||||
|  | ||||
|         if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB) | ||||
|             u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); | ||||
|  | ||||
|         u->handle = (uintptr_t) n; | ||||
|         usableCount++; | ||||
|     } | ||||
|  | ||||
|     closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); | ||||
|     if (closest) | ||||
|         *result = (GLXFBConfig) closest->handle; | ||||
|  | ||||
|     XFree(nativeConfigs); | ||||
|     free(usableConfigs); | ||||
|  | ||||
|     return closest != NULL; | ||||
| } | ||||
|  | ||||
| // Create the OpenGL context using legacy API | ||||
| // | ||||
| static GLXContext createLegacyContextGLX(_GLFWwindow* window, | ||||
|                                          GLXFBConfig fbconfig, | ||||
|                                          GLXContext share) | ||||
| { | ||||
|     return glXCreateNewContext(_glfw.x11.display, | ||||
|                                fbconfig, | ||||
|                                GLX_RGBA_TYPE, | ||||
|                                share, | ||||
|                                True); | ||||
| } | ||||
|  | ||||
| static void makeContextCurrentGLX(_GLFWwindow* window) | ||||
| { | ||||
|     if (window) | ||||
|     { | ||||
|         if (!glXMakeCurrent(_glfw.x11.display, | ||||
|                             window->context.glx.window, | ||||
|                             window->context.glx.handle)) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "GLX: Failed to make context current"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!glXMakeCurrent(_glfw.x11.display, None, NULL)) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "GLX: Failed to clear current context"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _glfwPlatformSetTls(&_glfw.contextSlot, window); | ||||
| } | ||||
|  | ||||
| static void swapBuffersGLX(_GLFWwindow* window) | ||||
| { | ||||
|     glXSwapBuffers(_glfw.x11.display, window->context.glx.window); | ||||
| } | ||||
|  | ||||
| static void swapIntervalGLX(int interval) | ||||
| { | ||||
|     _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|  | ||||
|     if (_glfw.glx.EXT_swap_control) | ||||
|     { | ||||
|         _glfw.glx.SwapIntervalEXT(_glfw.x11.display, | ||||
|                                   window->context.glx.window, | ||||
|                                   interval); | ||||
|     } | ||||
|     else if (_glfw.glx.MESA_swap_control) | ||||
|         _glfw.glx.SwapIntervalMESA(interval); | ||||
|     else if (_glfw.glx.SGI_swap_control) | ||||
|     { | ||||
|         if (interval > 0) | ||||
|             _glfw.glx.SwapIntervalSGI(interval); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int extensionSupportedGLX(const char* extension) | ||||
| { | ||||
|     const char* extensions = | ||||
|         glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen); | ||||
|     if (extensions) | ||||
|     { | ||||
|         if (_glfwStringInExtensionString(extension, extensions)) | ||||
|             return GLFW_TRUE; | ||||
|     } | ||||
|  | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| static GLFWglproc getProcAddressGLX(const char* procname) | ||||
| { | ||||
|     if (_glfw.glx.GetProcAddress) | ||||
|         return _glfw.glx.GetProcAddress((const GLubyte*) procname); | ||||
|     else if (_glfw.glx.GetProcAddressARB) | ||||
|         return _glfw.glx.GetProcAddressARB((const GLubyte*) procname); | ||||
|     else | ||||
|         return _glfw_dlsym(_glfw.glx.handle, procname); | ||||
| } | ||||
|  | ||||
| static void destroyContextGLX(_GLFWwindow* window) | ||||
| { | ||||
|     if (window->context.glx.window) | ||||
|     { | ||||
|         glXDestroyWindow(_glfw.x11.display, window->context.glx.window); | ||||
|         window->context.glx.window = None; | ||||
|     } | ||||
|  | ||||
|     if (window->context.glx.handle) | ||||
|     { | ||||
|         glXDestroyContext(_glfw.x11.display, window->context.glx.handle); | ||||
|         window->context.glx.handle = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialize GLX | ||||
| // | ||||
| GLFWbool _glfwInitGLX(void) | ||||
| { | ||||
|     int i; | ||||
|     const char* sonames[] = | ||||
|     { | ||||
| #if defined(_GLFW_GLX_LIBRARY) | ||||
|         _GLFW_GLX_LIBRARY, | ||||
| #elif defined(__CYGWIN__) | ||||
|         "libGL-1.so", | ||||
| #else | ||||
|         "libGL.so.1", | ||||
|         "libGL.so", | ||||
| #endif | ||||
|         NULL | ||||
|     }; | ||||
|  | ||||
|     if (_glfw.glx.handle) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
|     for (i = 0;  sonames[i];  i++) | ||||
|     { | ||||
|         _glfw.glx.handle = _glfw_dlopen(sonames[i]); | ||||
|         if (_glfw.glx.handle) | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     if (!_glfw.glx.handle) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.glx.GetFBConfigs = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs"); | ||||
|     _glfw.glx.GetFBConfigAttrib = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib"); | ||||
|     _glfw.glx.GetClientString = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXGetClientString"); | ||||
|     _glfw.glx.QueryExtension = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXQueryExtension"); | ||||
|     _glfw.glx.QueryVersion = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXQueryVersion"); | ||||
|     _glfw.glx.DestroyContext = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXDestroyContext"); | ||||
|     _glfw.glx.MakeCurrent = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent"); | ||||
|     _glfw.glx.SwapBuffers = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers"); | ||||
|     _glfw.glx.QueryExtensionsString = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString"); | ||||
|     _glfw.glx.CreateNewContext = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext"); | ||||
|     _glfw.glx.CreateWindow = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXCreateWindow"); | ||||
|     _glfw.glx.DestroyWindow = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow"); | ||||
|     _glfw.glx.GetProcAddress = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress"); | ||||
|     _glfw.glx.GetProcAddressARB = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB"); | ||||
|     _glfw.glx.GetVisualFromFBConfig = | ||||
|         _glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig"); | ||||
|  | ||||
|     if (!_glfw.glx.GetFBConfigs || | ||||
|         !_glfw.glx.GetFBConfigAttrib || | ||||
|         !_glfw.glx.GetClientString || | ||||
|         !_glfw.glx.QueryExtension || | ||||
|         !_glfw.glx.QueryVersion || | ||||
|         !_glfw.glx.DestroyContext || | ||||
|         !_glfw.glx.MakeCurrent || | ||||
|         !_glfw.glx.SwapBuffers || | ||||
|         !_glfw.glx.QueryExtensionsString || | ||||
|         !_glfw.glx.CreateNewContext || | ||||
|         !_glfw.glx.CreateWindow || | ||||
|         !_glfw.glx.DestroyWindow || | ||||
|         !_glfw.glx.GetProcAddress || | ||||
|         !_glfw.glx.GetProcAddressARB || | ||||
|         !_glfw.glx.GetVisualFromFBConfig) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "GLX: Failed to load required entry points"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (!glXQueryExtension(_glfw.x11.display, | ||||
|                            &_glfw.glx.errorBase, | ||||
|                            &_glfw.glx.eventBase)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "GLX: Failed to query GLX version"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (_glfw.glx.major == 1 && _glfw.glx.minor < 3) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "GLX: GLX version 1.3 is required"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_EXT_swap_control")) | ||||
|     { | ||||
|         _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) | ||||
|             getProcAddressGLX("glXSwapIntervalEXT"); | ||||
|  | ||||
|         if (_glfw.glx.SwapIntervalEXT) | ||||
|             _glfw.glx.EXT_swap_control = GLFW_TRUE; | ||||
|     } | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_SGI_swap_control")) | ||||
|     { | ||||
|         _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) | ||||
|             getProcAddressGLX("glXSwapIntervalSGI"); | ||||
|  | ||||
|         if (_glfw.glx.SwapIntervalSGI) | ||||
|             _glfw.glx.SGI_swap_control = GLFW_TRUE; | ||||
|     } | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_MESA_swap_control")) | ||||
|     { | ||||
|         _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) | ||||
|             getProcAddressGLX("glXSwapIntervalMESA"); | ||||
|  | ||||
|         if (_glfw.glx.SwapIntervalMESA) | ||||
|             _glfw.glx.MESA_swap_control = GLFW_TRUE; | ||||
|     } | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_ARB_multisample")) | ||||
|         _glfw.glx.ARB_multisample = GLFW_TRUE; | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB")) | ||||
|         _glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE; | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB")) | ||||
|         _glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE; | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_ARB_create_context")) | ||||
|     { | ||||
|         _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) | ||||
|             getProcAddressGLX("glXCreateContextAttribsARB"); | ||||
|  | ||||
|         if (_glfw.glx.CreateContextAttribsARB) | ||||
|             _glfw.glx.ARB_create_context = GLFW_TRUE; | ||||
|     } | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_ARB_create_context_robustness")) | ||||
|         _glfw.glx.ARB_create_context_robustness = GLFW_TRUE; | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_ARB_create_context_profile")) | ||||
|         _glfw.glx.ARB_create_context_profile = GLFW_TRUE; | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile")) | ||||
|         _glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE; | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_ARB_create_context_no_error")) | ||||
|         _glfw.glx.ARB_create_context_no_error = GLFW_TRUE; | ||||
|  | ||||
|     if (extensionSupportedGLX("GLX_ARB_context_flush_control")) | ||||
|         _glfw.glx.ARB_context_flush_control = GLFW_TRUE; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Terminate GLX | ||||
| // | ||||
| void _glfwTerminateGLX(void) | ||||
| { | ||||
|     // NOTE: This function must not call any X11 functions, as it is called | ||||
|     //       after XCloseDisplay (see _glfwPlatformTerminate for details) | ||||
|  | ||||
|     if (_glfw.glx.handle) | ||||
|     { | ||||
|         _glfw_dlclose(_glfw.glx.handle); | ||||
|         _glfw.glx.handle = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #define setAttrib(a, v) \ | ||||
| { \ | ||||
|     assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ | ||||
|     attribs[index++] = a; \ | ||||
|     attribs[index++] = v; \ | ||||
| } | ||||
|  | ||||
| // Create the OpenGL or OpenGL ES context | ||||
| // | ||||
| GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, | ||||
|                                const _GLFWctxconfig* ctxconfig, | ||||
|                                const _GLFWfbconfig* fbconfig) | ||||
| { | ||||
|     int attribs[40]; | ||||
|     GLXFBConfig native = NULL; | ||||
|     GLXContext share = NULL; | ||||
|  | ||||
|     if (ctxconfig->share) | ||||
|         share = ctxconfig->share->context.glx.handle; | ||||
|  | ||||
|     if (!chooseGLXFBConfig(fbconfig, &native)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_FORMAT_UNAVAILABLE, | ||||
|                         "GLX: Failed to find a suitable GLXFBConfig"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|     { | ||||
|         if (!_glfw.glx.ARB_create_context || | ||||
|             !_glfw.glx.ARB_create_context_profile || | ||||
|             !_glfw.glx.EXT_create_context_es2_profile) | ||||
|         { | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                             "GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->forward) | ||||
|     { | ||||
|         if (!_glfw.glx.ARB_create_context) | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->profile) | ||||
|     { | ||||
|         if (!_glfw.glx.ARB_create_context || | ||||
|             !_glfw.glx.ARB_create_context_profile) | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _glfwGrabErrorHandlerX11(); | ||||
|  | ||||
|     if (_glfw.glx.ARB_create_context) | ||||
|     { | ||||
|         int index = 0, mask = 0, flags = 0; | ||||
|  | ||||
|         if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             if (ctxconfig->forward) | ||||
|                 flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; | ||||
|  | ||||
|             if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) | ||||
|                 mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; | ||||
|             else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) | ||||
|                 mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; | ||||
|         } | ||||
|         else | ||||
|             mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; | ||||
|  | ||||
|         if (ctxconfig->debug) | ||||
|             flags |= GLX_CONTEXT_DEBUG_BIT_ARB; | ||||
|  | ||||
|         if (ctxconfig->robustness) | ||||
|         { | ||||
|             if (_glfw.glx.ARB_create_context_robustness) | ||||
|             { | ||||
|                 if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) | ||||
|                 { | ||||
|                     setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, | ||||
|                               GLX_NO_RESET_NOTIFICATION_ARB); | ||||
|                 } | ||||
|                 else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) | ||||
|                 { | ||||
|                     setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, | ||||
|                               GLX_LOSE_CONTEXT_ON_RESET_ARB); | ||||
|                 } | ||||
|  | ||||
|                 flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->release) | ||||
|         { | ||||
|             if (_glfw.glx.ARB_context_flush_control) | ||||
|             { | ||||
|                 if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) | ||||
|                 { | ||||
|                     setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, | ||||
|                               GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); | ||||
|                 } | ||||
|                 else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) | ||||
|                 { | ||||
|                     setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, | ||||
|                               GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->noerror) | ||||
|         { | ||||
|             if (_glfw.glx.ARB_create_context_no_error) | ||||
|                 setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); | ||||
|         } | ||||
|  | ||||
|         // NOTE: Only request an explicitly versioned context when necessary, as | ||||
|         //       explicitly requesting version 1.0 does not always return the | ||||
|         //       highest version supported by the driver | ||||
|         if (ctxconfig->major != 1 || ctxconfig->minor != 0) | ||||
|         { | ||||
|             setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); | ||||
|             setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); | ||||
|         } | ||||
|  | ||||
|         if (mask) | ||||
|             setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); | ||||
|  | ||||
|         if (flags) | ||||
|             setAttrib(GLX_CONTEXT_FLAGS_ARB, flags); | ||||
|  | ||||
|         setAttrib(None, None); | ||||
|  | ||||
|         window->context.glx.handle = | ||||
|             _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, | ||||
|                                               native, | ||||
|                                               share, | ||||
|                                               True, | ||||
|                                               attribs); | ||||
|  | ||||
|         // HACK: This is a fallback for broken versions of the Mesa | ||||
|         //       implementation of GLX_ARB_create_context_profile that fail | ||||
|         //       default 1.0 context creation with a GLXBadProfileARB error in | ||||
|         //       violation of the extension spec | ||||
|         if (!window->context.glx.handle) | ||||
|         { | ||||
|             if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && | ||||
|                 ctxconfig->client == GLFW_OPENGL_API && | ||||
|                 ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE && | ||||
|                 ctxconfig->forward == GLFW_FALSE) | ||||
|             { | ||||
|                 window->context.glx.handle = | ||||
|                     createLegacyContextGLX(window, native, share); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         window->context.glx.handle = | ||||
|             createLegacyContextGLX(window, native, share); | ||||
|     } | ||||
|  | ||||
|     _glfwReleaseErrorHandlerX11(); | ||||
|  | ||||
|     if (!window->context.glx.handle) | ||||
|     { | ||||
|         _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     window->context.glx.window = | ||||
|         glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL); | ||||
|     if (!window->context.glx.window) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     window->context.makeCurrent = makeContextCurrentGLX; | ||||
|     window->context.swapBuffers = swapBuffersGLX; | ||||
|     window->context.swapInterval = swapIntervalGLX; | ||||
|     window->context.extensionSupported = extensionSupportedGLX; | ||||
|     window->context.getProcAddress = getProcAddressGLX; | ||||
|     window->context.destroy = destroyContextGLX; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| #undef setAttrib | ||||
|  | ||||
| // Returns the Visual and depth of the chosen GLXFBConfig | ||||
| // | ||||
| GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, | ||||
|                               const _GLFWctxconfig* ctxconfig, | ||||
|                               const _GLFWfbconfig* fbconfig, | ||||
|                               Visual** visual, int* depth) | ||||
| { | ||||
|     GLXFBConfig native; | ||||
|     XVisualInfo* result; | ||||
|  | ||||
|     if (!chooseGLXFBConfig(fbconfig, &native)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_FORMAT_UNAVAILABLE, | ||||
|                         "GLX: Failed to find a suitable GLXFBConfig"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     result = glXGetVisualFromFBConfig(_glfw.x11.display, native); | ||||
|     if (!result) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "GLX: Failed to retrieve Visual for GLXFBConfig"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     *visual = result->visual; | ||||
|     *depth  = result->depth; | ||||
|  | ||||
|     XFree(result); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     if (window->context.source != GLFW_NATIVE_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     return window->context.glx.handle; | ||||
| } | ||||
|  | ||||
| GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(None); | ||||
|  | ||||
|     if (window->context.source != GLFW_NATIVE_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return None; | ||||
|     } | ||||
|  | ||||
|     return window->context.glx.window; | ||||
| } | ||||
|  | ||||
							
								
								
									
										179
									
								
								deps/glfw/src/glx_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								deps/glfw/src/glx_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 GLX - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #define GLX_VENDOR 1 | ||||
| #define GLX_RGBA_BIT 0x00000001 | ||||
| #define GLX_WINDOW_BIT 0x00000001 | ||||
| #define GLX_DRAWABLE_TYPE 0x8010 | ||||
| #define GLX_RENDER_TYPE 0x8011 | ||||
| #define GLX_RGBA_TYPE 0x8014 | ||||
| #define GLX_DOUBLEBUFFER 5 | ||||
| #define GLX_STEREO 6 | ||||
| #define GLX_AUX_BUFFERS 7 | ||||
| #define GLX_RED_SIZE 8 | ||||
| #define GLX_GREEN_SIZE 9 | ||||
| #define GLX_BLUE_SIZE 10 | ||||
| #define GLX_ALPHA_SIZE 11 | ||||
| #define GLX_DEPTH_SIZE 12 | ||||
| #define GLX_STENCIL_SIZE 13 | ||||
| #define GLX_ACCUM_RED_SIZE 14 | ||||
| #define GLX_ACCUM_GREEN_SIZE 15 | ||||
| #define GLX_ACCUM_BLUE_SIZE 16 | ||||
| #define GLX_ACCUM_ALPHA_SIZE 17 | ||||
| #define GLX_SAMPLES 0x186a1 | ||||
| #define GLX_VISUAL_ID 0x800b | ||||
|  | ||||
| #define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2 | ||||
| #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 | ||||
| #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 | ||||
| #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 | ||||
| #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 | ||||
| #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 | ||||
| #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 | ||||
| #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 | ||||
| #define GLX_CONTEXT_FLAGS_ARB 0x2094 | ||||
| #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 | ||||
| #define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 | ||||
| #define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 | ||||
| #define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 | ||||
| #define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 | ||||
| #define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 | ||||
| #define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 | ||||
| #define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 | ||||
| #define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3 | ||||
|  | ||||
| typedef XID GLXWindow; | ||||
| typedef XID GLXDrawable; | ||||
| typedef struct __GLXFBConfig* GLXFBConfig; | ||||
| typedef struct __GLXcontext* GLXContext; | ||||
| typedef void (*__GLXextproc)(void); | ||||
|  | ||||
| typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*); | ||||
| typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int); | ||||
| typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*); | ||||
| typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*); | ||||
| typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext); | ||||
| typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext); | ||||
| typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable); | ||||
| typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int); | ||||
| typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*); | ||||
| typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool); | ||||
| typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName); | ||||
| typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int); | ||||
| typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig); | ||||
| typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*); | ||||
| typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); | ||||
|  | ||||
| typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int); | ||||
| typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int); | ||||
| typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*); | ||||
|  | ||||
| // libGL.so function pointer typedefs | ||||
| #define glXGetFBConfigs _glfw.glx.GetFBConfigs | ||||
| #define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib | ||||
| #define glXGetClientString _glfw.glx.GetClientString | ||||
| #define glXQueryExtension _glfw.glx.QueryExtension | ||||
| #define glXQueryVersion _glfw.glx.QueryVersion | ||||
| #define glXDestroyContext _glfw.glx.DestroyContext | ||||
| #define glXMakeCurrent _glfw.glx.MakeCurrent | ||||
| #define glXSwapBuffers _glfw.glx.SwapBuffers | ||||
| #define glXQueryExtensionsString _glfw.glx.QueryExtensionsString | ||||
| #define glXCreateNewContext _glfw.glx.CreateNewContext | ||||
| #define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig | ||||
| #define glXCreateWindow _glfw.glx.CreateWindow | ||||
| #define glXDestroyWindow _glfw.glx.DestroyWindow | ||||
|  | ||||
| #define _GLFW_PLATFORM_CONTEXT_STATE            _GLFWcontextGLX glx | ||||
| #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE    _GLFWlibraryGLX glx | ||||
|  | ||||
|  | ||||
| // GLX-specific per-context data | ||||
| // | ||||
| typedef struct _GLFWcontextGLX | ||||
| { | ||||
|     GLXContext      handle; | ||||
|     GLXWindow       window; | ||||
| } _GLFWcontextGLX; | ||||
|  | ||||
| // GLX-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryGLX | ||||
| { | ||||
|     int             major, minor; | ||||
|     int             eventBase; | ||||
|     int             errorBase; | ||||
|  | ||||
|     // dlopen handle for libGL.so.1 | ||||
|     void*           handle; | ||||
|  | ||||
|     // GLX 1.3 functions | ||||
|     PFNGLXGETFBCONFIGSPROC              GetFBConfigs; | ||||
|     PFNGLXGETFBCONFIGATTRIBPROC         GetFBConfigAttrib; | ||||
|     PFNGLXGETCLIENTSTRINGPROC           GetClientString; | ||||
|     PFNGLXQUERYEXTENSIONPROC            QueryExtension; | ||||
|     PFNGLXQUERYVERSIONPROC              QueryVersion; | ||||
|     PFNGLXDESTROYCONTEXTPROC            DestroyContext; | ||||
|     PFNGLXMAKECURRENTPROC               MakeCurrent; | ||||
|     PFNGLXSWAPBUFFERSPROC               SwapBuffers; | ||||
|     PFNGLXQUERYEXTENSIONSSTRINGPROC     QueryExtensionsString; | ||||
|     PFNGLXCREATENEWCONTEXTPROC          CreateNewContext; | ||||
|     PFNGLXGETVISUALFROMFBCONFIGPROC     GetVisualFromFBConfig; | ||||
|     PFNGLXCREATEWINDOWPROC              CreateWindow; | ||||
|     PFNGLXDESTROYWINDOWPROC             DestroyWindow; | ||||
|  | ||||
|     // GLX 1.4 and extension functions | ||||
|     PFNGLXGETPROCADDRESSPROC            GetProcAddress; | ||||
|     PFNGLXGETPROCADDRESSPROC            GetProcAddressARB; | ||||
|     PFNGLXSWAPINTERVALSGIPROC           SwapIntervalSGI; | ||||
|     PFNGLXSWAPINTERVALEXTPROC           SwapIntervalEXT; | ||||
|     PFNGLXSWAPINTERVALMESAPROC          SwapIntervalMESA; | ||||
|     PFNGLXCREATECONTEXTATTRIBSARBPROC   CreateContextAttribsARB; | ||||
|     GLFWbool        SGI_swap_control; | ||||
|     GLFWbool        EXT_swap_control; | ||||
|     GLFWbool        MESA_swap_control; | ||||
|     GLFWbool        ARB_multisample; | ||||
|     GLFWbool        ARB_framebuffer_sRGB; | ||||
|     GLFWbool        EXT_framebuffer_sRGB; | ||||
|     GLFWbool        ARB_create_context; | ||||
|     GLFWbool        ARB_create_context_profile; | ||||
|     GLFWbool        ARB_create_context_robustness; | ||||
|     GLFWbool        EXT_create_context_es2_profile; | ||||
|     GLFWbool        ARB_create_context_no_error; | ||||
|     GLFWbool        ARB_context_flush_control; | ||||
| } _GLFWlibraryGLX; | ||||
|  | ||||
| GLFWbool _glfwInitGLX(void); | ||||
| void _glfwTerminateGLX(void); | ||||
| GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, | ||||
|                                const _GLFWctxconfig* ctxconfig, | ||||
|                                const _GLFWfbconfig* fbconfig); | ||||
| void _glfwDestroyContextGLX(_GLFWwindow* window); | ||||
| GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, | ||||
|                               const _GLFWctxconfig* ctxconfig, | ||||
|                               const _GLFWfbconfig* fbconfig, | ||||
|                               Visual** visual, int* depth); | ||||
|  | ||||
							
								
								
									
										326
									
								
								deps/glfw/src/init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								deps/glfw/src/init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,326 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <stdarg.h> | ||||
| #include <assert.h> | ||||
|  | ||||
|  | ||||
| // NOTE: The global variables below comprise all mutable global data in GLFW | ||||
| //       Any other mutable global variable is a bug | ||||
|  | ||||
| // This contains all mutable state shared between compilation units of GLFW | ||||
| // | ||||
| _GLFWlibrary _glfw = { GLFW_FALSE }; | ||||
|  | ||||
| // These are outside of _glfw so they can be used before initialization and | ||||
| // after termination without special handling when _glfw is cleared to zero | ||||
| // | ||||
| static _GLFWerror _glfwMainThreadError; | ||||
| static GLFWerrorfun _glfwErrorCallback; | ||||
| static _GLFWinitconfig _glfwInitHints = | ||||
| { | ||||
|     GLFW_TRUE,      // hat buttons | ||||
|     { | ||||
|         GLFW_TRUE,  // macOS menu bar | ||||
|         GLFW_TRUE   // macOS bundle chdir | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // Terminate the library | ||||
| // | ||||
| static void terminate(void) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks)); | ||||
|  | ||||
|     while (_glfw.windowListHead) | ||||
|         glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead); | ||||
|  | ||||
|     while (_glfw.cursorListHead) | ||||
|         glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead); | ||||
|  | ||||
|     for (i = 0;  i < _glfw.monitorCount;  i++) | ||||
|     { | ||||
|         _GLFWmonitor* monitor = _glfw.monitors[i]; | ||||
|         if (monitor->originalRamp.size) | ||||
|             _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); | ||||
|         _glfwFreeMonitor(monitor); | ||||
|     } | ||||
|  | ||||
|     free(_glfw.monitors); | ||||
|     _glfw.monitors = NULL; | ||||
|     _glfw.monitorCount = 0; | ||||
|  | ||||
|     free(_glfw.mappings); | ||||
|     _glfw.mappings = NULL; | ||||
|     _glfw.mappingCount = 0; | ||||
|  | ||||
|     _glfwTerminateVulkan(); | ||||
|     _glfwPlatformTerminate(); | ||||
|  | ||||
|     _glfw.initialized = GLFW_FALSE; | ||||
|  | ||||
|     while (_glfw.errorListHead) | ||||
|     { | ||||
|         _GLFWerror* error = _glfw.errorListHead; | ||||
|         _glfw.errorListHead = error->next; | ||||
|         free(error); | ||||
|     } | ||||
|  | ||||
|     _glfwPlatformDestroyTls(&_glfw.contextSlot); | ||||
|     _glfwPlatformDestroyTls(&_glfw.errorSlot); | ||||
|     _glfwPlatformDestroyMutex(&_glfw.errorLock); | ||||
|  | ||||
|     memset(&_glfw, 0, sizeof(_glfw)); | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| char* _glfw_strdup(const char* source) | ||||
| { | ||||
|     const size_t length = strlen(source); | ||||
|     char* result = calloc(length + 1, 1); | ||||
|     strcpy(result, source); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| float _glfw_fminf(float a, float b) | ||||
| { | ||||
|     if (a != a) | ||||
|         return b; | ||||
|     else if (b != b) | ||||
|         return a; | ||||
|     else if (a < b) | ||||
|         return a; | ||||
|     else | ||||
|         return b; | ||||
| } | ||||
|  | ||||
| float _glfw_fmaxf(float a, float b) | ||||
| { | ||||
|     if (a != a) | ||||
|         return b; | ||||
|     else if (b != b) | ||||
|         return a; | ||||
|     else if (a > b) | ||||
|         return a; | ||||
|     else | ||||
|         return b; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                         GLFW event API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Notifies shared code of an error | ||||
| // | ||||
| void _glfwInputError(int code, const char* format, ...) | ||||
| { | ||||
|     _GLFWerror* error; | ||||
|     char description[_GLFW_MESSAGE_SIZE]; | ||||
|  | ||||
|     if (format) | ||||
|     { | ||||
|         va_list vl; | ||||
|  | ||||
|         va_start(vl, format); | ||||
|         vsnprintf(description, sizeof(description), format, vl); | ||||
|         va_end(vl); | ||||
|  | ||||
|         description[sizeof(description) - 1] = '\0'; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (code == GLFW_NOT_INITIALIZED) | ||||
|             strcpy(description, "The GLFW library is not initialized"); | ||||
|         else if (code == GLFW_NO_CURRENT_CONTEXT) | ||||
|             strcpy(description, "There is no current context"); | ||||
|         else if (code == GLFW_INVALID_ENUM) | ||||
|             strcpy(description, "Invalid argument for enum parameter"); | ||||
|         else if (code == GLFW_INVALID_VALUE) | ||||
|             strcpy(description, "Invalid value for parameter"); | ||||
|         else if (code == GLFW_OUT_OF_MEMORY) | ||||
|             strcpy(description, "Out of memory"); | ||||
|         else if (code == GLFW_API_UNAVAILABLE) | ||||
|             strcpy(description, "The requested API is unavailable"); | ||||
|         else if (code == GLFW_VERSION_UNAVAILABLE) | ||||
|             strcpy(description, "The requested API version is unavailable"); | ||||
|         else if (code == GLFW_PLATFORM_ERROR) | ||||
|             strcpy(description, "A platform-specific error occurred"); | ||||
|         else if (code == GLFW_FORMAT_UNAVAILABLE) | ||||
|             strcpy(description, "The requested format is unavailable"); | ||||
|         else if (code == GLFW_NO_WINDOW_CONTEXT) | ||||
|             strcpy(description, "The specified window has no context"); | ||||
|         else | ||||
|             strcpy(description, "ERROR: UNKNOWN GLFW ERROR"); | ||||
|     } | ||||
|  | ||||
|     if (_glfw.initialized) | ||||
|     { | ||||
|         error = _glfwPlatformGetTls(&_glfw.errorSlot); | ||||
|         if (!error) | ||||
|         { | ||||
|             error = calloc(1, sizeof(_GLFWerror)); | ||||
|             _glfwPlatformSetTls(&_glfw.errorSlot, error); | ||||
|             _glfwPlatformLockMutex(&_glfw.errorLock); | ||||
|             error->next = _glfw.errorListHead; | ||||
|             _glfw.errorListHead = error; | ||||
|             _glfwPlatformUnlockMutex(&_glfw.errorLock); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|         error = &_glfwMainThreadError; | ||||
|  | ||||
|     error->code = code; | ||||
|     strcpy(error->description, description); | ||||
|  | ||||
|     if (_glfwErrorCallback) | ||||
|         _glfwErrorCallback(code, description); | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW public API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI int glfwInit(void) | ||||
| { | ||||
|     if (_glfw.initialized) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
|     memset(&_glfw, 0, sizeof(_glfw)); | ||||
|     _glfw.hints.init = _glfwInitHints; | ||||
|  | ||||
|     if (!_glfwPlatformInit()) | ||||
|     { | ||||
|         terminate(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (!_glfwPlatformCreateMutex(&_glfw.errorLock) || | ||||
|         !_glfwPlatformCreateTls(&_glfw.errorSlot) || | ||||
|         !_glfwPlatformCreateTls(&_glfw.contextSlot)) | ||||
|     { | ||||
|         terminate(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError); | ||||
|  | ||||
|     _glfwInitGamepadMappings(); | ||||
|  | ||||
|     _glfw.initialized = GLFW_TRUE; | ||||
|     _glfw.timer.offset = _glfwPlatformGetTimerValue(); | ||||
|  | ||||
|     glfwDefaultWindowHints(); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwTerminate(void) | ||||
| { | ||||
|     if (!_glfw.initialized) | ||||
|         return; | ||||
|  | ||||
|     terminate(); | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwInitHint(int hint, int value) | ||||
| { | ||||
|     switch (hint) | ||||
|     { | ||||
|         case GLFW_JOYSTICK_HAT_BUTTONS: | ||||
|             _glfwInitHints.hatButtons = value; | ||||
|             return; | ||||
|         case GLFW_COCOA_CHDIR_RESOURCES: | ||||
|             _glfwInitHints.ns.chdir = value; | ||||
|             return; | ||||
|         case GLFW_COCOA_MENUBAR: | ||||
|             _glfwInitHints.ns.menubar = value; | ||||
|             return; | ||||
|     } | ||||
|  | ||||
|     _glfwInputError(GLFW_INVALID_ENUM, | ||||
|                     "Invalid init hint 0x%08X", hint); | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) | ||||
| { | ||||
|     if (major != NULL) | ||||
|         *major = GLFW_VERSION_MAJOR; | ||||
|     if (minor != NULL) | ||||
|         *minor = GLFW_VERSION_MINOR; | ||||
|     if (rev != NULL) | ||||
|         *rev = GLFW_VERSION_REVISION; | ||||
| } | ||||
|  | ||||
| GLFWAPI const char* glfwGetVersionString(void) | ||||
| { | ||||
|     return _glfwPlatformGetVersionString(); | ||||
| } | ||||
|  | ||||
| GLFWAPI int glfwGetError(const char** description) | ||||
| { | ||||
|     _GLFWerror* error; | ||||
|     int code = GLFW_NO_ERROR; | ||||
|  | ||||
|     if (description) | ||||
|         *description = NULL; | ||||
|  | ||||
|     if (_glfw.initialized) | ||||
|         error = _glfwPlatformGetTls(&_glfw.errorSlot); | ||||
|     else | ||||
|         error = &_glfwMainThreadError; | ||||
|  | ||||
|     if (error) | ||||
|     { | ||||
|         code = error->code; | ||||
|         error->code = GLFW_NO_ERROR; | ||||
|         if (description && code) | ||||
|             *description = error->description; | ||||
|     } | ||||
|  | ||||
|     return code; | ||||
| } | ||||
|  | ||||
| GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) | ||||
| { | ||||
|     _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); | ||||
|     return cbfun; | ||||
| } | ||||
|  | ||||
							
								
								
									
										1367
									
								
								deps/glfw/src/input.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1367
									
								
								deps/glfw/src/input.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										780
									
								
								deps/glfw/src/internal.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										780
									
								
								deps/glfw/src/internal.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,780 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if defined(_GLFW_USE_CONFIG_H) | ||||
|  #include "glfw_config.h" | ||||
| #endif | ||||
|  | ||||
| #if defined(GLFW_INCLUDE_GLCOREARB) || \ | ||||
|     defined(GLFW_INCLUDE_ES1)       || \ | ||||
|     defined(GLFW_INCLUDE_ES2)       || \ | ||||
|     defined(GLFW_INCLUDE_ES3)       || \ | ||||
|     defined(GLFW_INCLUDE_ES31)      || \ | ||||
|     defined(GLFW_INCLUDE_ES32)      || \ | ||||
|     defined(GLFW_INCLUDE_NONE)      || \ | ||||
|     defined(GLFW_INCLUDE_GLEXT)     || \ | ||||
|     defined(GLFW_INCLUDE_GLU)       || \ | ||||
|     defined(GLFW_INCLUDE_VULKAN)    || \ | ||||
|     defined(GLFW_DLL) | ||||
|  #error "You must not define any header option macros when compiling GLFW" | ||||
| #endif | ||||
|  | ||||
| #define GLFW_INCLUDE_NONE | ||||
| #include "../include/GLFW/glfw3.h" | ||||
|  | ||||
| #define _GLFW_INSERT_FIRST      0 | ||||
| #define _GLFW_INSERT_LAST       1 | ||||
|  | ||||
| #define _GLFW_POLL_PRESENCE     0 | ||||
| #define _GLFW_POLL_AXES         1 | ||||
| #define _GLFW_POLL_BUTTONS      2 | ||||
| #define _GLFW_POLL_ALL          (_GLFW_POLL_AXES | _GLFW_POLL_BUTTONS) | ||||
|  | ||||
| #define _GLFW_MESSAGE_SIZE      1024 | ||||
|  | ||||
| typedef int GLFWbool; | ||||
|  | ||||
| typedef struct _GLFWerror       _GLFWerror; | ||||
| typedef struct _GLFWinitconfig  _GLFWinitconfig; | ||||
| typedef struct _GLFWwndconfig   _GLFWwndconfig; | ||||
| typedef struct _GLFWctxconfig   _GLFWctxconfig; | ||||
| typedef struct _GLFWfbconfig    _GLFWfbconfig; | ||||
| typedef struct _GLFWcontext     _GLFWcontext; | ||||
| typedef struct _GLFWwindow      _GLFWwindow; | ||||
| typedef struct _GLFWlibrary     _GLFWlibrary; | ||||
| typedef struct _GLFWmonitor     _GLFWmonitor; | ||||
| typedef struct _GLFWcursor      _GLFWcursor; | ||||
| typedef struct _GLFWmapelement  _GLFWmapelement; | ||||
| typedef struct _GLFWmapping     _GLFWmapping; | ||||
| typedef struct _GLFWjoystick    _GLFWjoystick; | ||||
| typedef struct _GLFWtls         _GLFWtls; | ||||
| typedef struct _GLFWmutex       _GLFWmutex; | ||||
|  | ||||
| typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*); | ||||
| typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*); | ||||
| typedef void (* _GLFWswapintervalfun)(int); | ||||
| typedef int (* _GLFWextensionsupportedfun)(const char*); | ||||
| typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*); | ||||
| typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*); | ||||
|  | ||||
| #define GL_VERSION 0x1f02 | ||||
| #define GL_NONE 0 | ||||
| #define GL_COLOR_BUFFER_BIT 0x00004000 | ||||
| #define GL_UNSIGNED_BYTE 0x1401 | ||||
| #define GL_EXTENSIONS 0x1f03 | ||||
| #define GL_NUM_EXTENSIONS 0x821d | ||||
| #define GL_CONTEXT_FLAGS 0x821e | ||||
| #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 | ||||
| #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 | ||||
| #define GL_CONTEXT_PROFILE_MASK 0x9126 | ||||
| #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 | ||||
| #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 | ||||
| #define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 | ||||
| #define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 | ||||
| #define GL_NO_RESET_NOTIFICATION_ARB 0x8261 | ||||
| #define GL_CONTEXT_RELEASE_BEHAVIOR 0x82fb | ||||
| #define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc | ||||
| #define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 | ||||
|  | ||||
| typedef int GLint; | ||||
| typedef unsigned int GLuint; | ||||
| typedef unsigned int GLenum; | ||||
| typedef unsigned int GLbitfield; | ||||
| typedef unsigned char GLubyte; | ||||
|  | ||||
| typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield); | ||||
| typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum); | ||||
| typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); | ||||
| typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); | ||||
|  | ||||
| #define VK_NULL_HANDLE 0 | ||||
|  | ||||
| typedef void* VkInstance; | ||||
| typedef void* VkPhysicalDevice; | ||||
| typedef uint64_t VkSurfaceKHR; | ||||
| typedef uint32_t VkFlags; | ||||
| typedef uint32_t VkBool32; | ||||
|  | ||||
| typedef enum VkStructureType | ||||
| { | ||||
|     VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, | ||||
|     VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000, | ||||
|     VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, | ||||
|     VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, | ||||
|     VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, | ||||
|     VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, | ||||
|     VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF | ||||
| } VkStructureType; | ||||
|  | ||||
| typedef enum VkResult | ||||
| { | ||||
|     VK_SUCCESS = 0, | ||||
|     VK_NOT_READY = 1, | ||||
|     VK_TIMEOUT = 2, | ||||
|     VK_EVENT_SET = 3, | ||||
|     VK_EVENT_RESET = 4, | ||||
|     VK_INCOMPLETE = 5, | ||||
|     VK_ERROR_OUT_OF_HOST_MEMORY = -1, | ||||
|     VK_ERROR_OUT_OF_DEVICE_MEMORY = -2, | ||||
|     VK_ERROR_INITIALIZATION_FAILED = -3, | ||||
|     VK_ERROR_DEVICE_LOST = -4, | ||||
|     VK_ERROR_MEMORY_MAP_FAILED = -5, | ||||
|     VK_ERROR_LAYER_NOT_PRESENT = -6, | ||||
|     VK_ERROR_EXTENSION_NOT_PRESENT = -7, | ||||
|     VK_ERROR_FEATURE_NOT_PRESENT = -8, | ||||
|     VK_ERROR_INCOMPATIBLE_DRIVER = -9, | ||||
|     VK_ERROR_TOO_MANY_OBJECTS = -10, | ||||
|     VK_ERROR_FORMAT_NOT_SUPPORTED = -11, | ||||
|     VK_ERROR_SURFACE_LOST_KHR = -1000000000, | ||||
|     VK_SUBOPTIMAL_KHR = 1000001003, | ||||
|     VK_ERROR_OUT_OF_DATE_KHR = -1000001004, | ||||
|     VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, | ||||
|     VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, | ||||
|     VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, | ||||
|     VK_RESULT_MAX_ENUM = 0x7FFFFFFF | ||||
| } VkResult; | ||||
|  | ||||
| typedef struct VkAllocationCallbacks VkAllocationCallbacks; | ||||
|  | ||||
| typedef struct VkExtensionProperties | ||||
| { | ||||
|     char            extensionName[256]; | ||||
|     uint32_t        specVersion; | ||||
| } VkExtensionProperties; | ||||
|  | ||||
| typedef void (APIENTRY * PFN_vkVoidFunction)(void); | ||||
|  | ||||
| #if defined(_GLFW_VULKAN_STATIC) | ||||
|   PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*); | ||||
|   VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*); | ||||
| #else | ||||
|   typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); | ||||
|   typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*); | ||||
|   #define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties | ||||
|   #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr | ||||
| #endif | ||||
|  | ||||
| #if defined(_GLFW_COCOA) | ||||
|  #include "cocoa_platform.h" | ||||
| #elif defined(_GLFW_WIN32) | ||||
|  #include "win32_platform.h" | ||||
| #elif defined(_GLFW_X11) | ||||
|  #include "x11_platform.h" | ||||
| #elif defined(_GLFW_WAYLAND) | ||||
|  #include "wl_platform.h" | ||||
| #elif defined(_GLFW_OSMESA) | ||||
|  #include "null_platform.h" | ||||
| #else | ||||
|  #error "No supported window creation API selected" | ||||
| #endif | ||||
|  | ||||
| // Constructs a version number string from the public header macros | ||||
| #define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r | ||||
| #define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r) | ||||
| #define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \ | ||||
|                                                 GLFW_VERSION_MINOR, \ | ||||
|                                                 GLFW_VERSION_REVISION) | ||||
|  | ||||
| // Checks for whether the library has been initialized | ||||
| #define _GLFW_REQUIRE_INIT()                         \ | ||||
|     if (!_glfw.initialized)                          \ | ||||
|     {                                                \ | ||||
|         _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \ | ||||
|         return;                                      \ | ||||
|     } | ||||
| #define _GLFW_REQUIRE_INIT_OR_RETURN(x)              \ | ||||
|     if (!_glfw.initialized)                          \ | ||||
|     {                                                \ | ||||
|         _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \ | ||||
|         return x;                                    \ | ||||
|     } | ||||
|  | ||||
| // Swaps the provided pointers | ||||
| #define _GLFW_SWAP_POINTERS(x, y) \ | ||||
|     {                             \ | ||||
|         void* t;                  \ | ||||
|         t = x;                    \ | ||||
|         x = y;                    \ | ||||
|         y = t;                    \ | ||||
|     } | ||||
|  | ||||
| // Per-thread error structure | ||||
| // | ||||
| struct _GLFWerror | ||||
| { | ||||
|     _GLFWerror*     next; | ||||
|     int             code; | ||||
|     char            description[_GLFW_MESSAGE_SIZE]; | ||||
| }; | ||||
|  | ||||
| // Initialization configuration | ||||
| // | ||||
| // Parameters relating to the initialization of the library | ||||
| // | ||||
| struct _GLFWinitconfig | ||||
| { | ||||
|     GLFWbool      hatButtons; | ||||
|     struct { | ||||
|         GLFWbool  menubar; | ||||
|         GLFWbool  chdir; | ||||
|     } ns; | ||||
| }; | ||||
|  | ||||
| // Window configuration | ||||
| // | ||||
| // Parameters relating to the creation of the window but not directly related | ||||
| // to the framebuffer.  This is used to pass window creation parameters from | ||||
| // shared code to the platform API. | ||||
| // | ||||
| struct _GLFWwndconfig | ||||
| { | ||||
|     int           width; | ||||
|     int           height; | ||||
|     const char*   title; | ||||
|     GLFWbool      resizable; | ||||
|     GLFWbool      visible; | ||||
|     GLFWbool      decorated; | ||||
|     GLFWbool      focused; | ||||
|     GLFWbool      autoIconify; | ||||
|     GLFWbool      floating; | ||||
|     GLFWbool      maximized; | ||||
|     GLFWbool      centerCursor; | ||||
|     GLFWbool      focusOnShow; | ||||
|     GLFWbool      scaleToMonitor; | ||||
|     struct { | ||||
|         GLFWbool  retina; | ||||
|         char      frameName[256]; | ||||
|     } ns; | ||||
|     struct { | ||||
|         char      className[256]; | ||||
|         char      instanceName[256]; | ||||
|     } x11; | ||||
| }; | ||||
|  | ||||
| // Context configuration | ||||
| // | ||||
| // Parameters relating to the creation of the context but not directly related | ||||
| // to the framebuffer.  This is used to pass context creation parameters from | ||||
| // shared code to the platform API. | ||||
| // | ||||
| struct _GLFWctxconfig | ||||
| { | ||||
|     int           client; | ||||
|     int           source; | ||||
|     int           major; | ||||
|     int           minor; | ||||
|     GLFWbool      forward; | ||||
|     GLFWbool      debug; | ||||
|     GLFWbool      noerror; | ||||
|     int           profile; | ||||
|     int           robustness; | ||||
|     int           release; | ||||
|     _GLFWwindow*  share; | ||||
|     struct { | ||||
|         GLFWbool  offline; | ||||
|     } nsgl; | ||||
| }; | ||||
|  | ||||
| // Framebuffer configuration | ||||
| // | ||||
| // This describes buffers and their sizes.  It also contains | ||||
| // a platform-specific ID used to map back to the backend API object. | ||||
| // | ||||
| // It is used to pass framebuffer parameters from shared code to the platform | ||||
| // API and also to enumerate and select available framebuffer configs. | ||||
| // | ||||
| struct _GLFWfbconfig | ||||
| { | ||||
|     int         redBits; | ||||
|     int         greenBits; | ||||
|     int         blueBits; | ||||
|     int         alphaBits; | ||||
|     int         depthBits; | ||||
|     int         stencilBits; | ||||
|     int         accumRedBits; | ||||
|     int         accumGreenBits; | ||||
|     int         accumBlueBits; | ||||
|     int         accumAlphaBits; | ||||
|     int         auxBuffers; | ||||
|     GLFWbool    stereo; | ||||
|     int         samples; | ||||
|     GLFWbool    sRGB; | ||||
|     GLFWbool    doublebuffer; | ||||
|     GLFWbool    transparent; | ||||
|     uintptr_t   handle; | ||||
| }; | ||||
|  | ||||
| // Context structure | ||||
| // | ||||
| struct _GLFWcontext | ||||
| { | ||||
|     int                 client; | ||||
|     int                 source; | ||||
|     int                 major, minor, revision; | ||||
|     GLFWbool            forward, debug, noerror; | ||||
|     int                 profile; | ||||
|     int                 robustness; | ||||
|     int                 release; | ||||
|  | ||||
|     PFNGLGETSTRINGIPROC  GetStringi; | ||||
|     PFNGLGETINTEGERVPROC GetIntegerv; | ||||
|     PFNGLGETSTRINGPROC   GetString; | ||||
|  | ||||
|     _GLFWmakecontextcurrentfun  makeCurrent; | ||||
|     _GLFWswapbuffersfun         swapBuffers; | ||||
|     _GLFWswapintervalfun        swapInterval; | ||||
|     _GLFWextensionsupportedfun  extensionSupported; | ||||
|     _GLFWgetprocaddressfun      getProcAddress; | ||||
|     _GLFWdestroycontextfun      destroy; | ||||
|  | ||||
|     // This is defined in the context API's context.h | ||||
|     _GLFW_PLATFORM_CONTEXT_STATE; | ||||
|     // This is defined in egl_context.h | ||||
|     _GLFW_EGL_CONTEXT_STATE; | ||||
|     // This is defined in osmesa_context.h | ||||
|     _GLFW_OSMESA_CONTEXT_STATE; | ||||
| }; | ||||
|  | ||||
| // Window and context structure | ||||
| // | ||||
| struct _GLFWwindow | ||||
| { | ||||
|     struct _GLFWwindow* next; | ||||
|  | ||||
|     // Window settings and state | ||||
|     GLFWbool            resizable; | ||||
|     GLFWbool            decorated; | ||||
|     GLFWbool            autoIconify; | ||||
|     GLFWbool            floating; | ||||
|     GLFWbool            focusOnShow; | ||||
|     GLFWbool            shouldClose; | ||||
|     void*               userPointer; | ||||
|     GLFWbool            doublebuffer; | ||||
|     GLFWvidmode         videoMode; | ||||
|     _GLFWmonitor*       monitor; | ||||
|     _GLFWcursor*        cursor; | ||||
|  | ||||
|     int                 minwidth, minheight; | ||||
|     int                 maxwidth, maxheight; | ||||
|     int                 numer, denom; | ||||
|  | ||||
|     GLFWbool            stickyKeys; | ||||
|     GLFWbool            stickyMouseButtons; | ||||
|     GLFWbool            lockKeyMods; | ||||
|     int                 cursorMode; | ||||
|     char                mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; | ||||
|     char                keys[GLFW_KEY_LAST + 1]; | ||||
|     // Virtual cursor position when cursor is disabled | ||||
|     double              virtualCursorPosX, virtualCursorPosY; | ||||
|     GLFWbool            rawMouseMotion; | ||||
|  | ||||
|     _GLFWcontext        context; | ||||
|  | ||||
|     struct { | ||||
|         GLFWwindowposfun          pos; | ||||
|         GLFWwindowsizefun         size; | ||||
|         GLFWwindowclosefun        close; | ||||
|         GLFWwindowrefreshfun      refresh; | ||||
|         GLFWwindowfocusfun        focus; | ||||
|         GLFWwindowiconifyfun      iconify; | ||||
|         GLFWwindowmaximizefun     maximize; | ||||
|         GLFWframebuffersizefun    fbsize; | ||||
|         GLFWwindowcontentscalefun scale; | ||||
|         GLFWmousebuttonfun        mouseButton; | ||||
|         GLFWcursorposfun          cursorPos; | ||||
|         GLFWcursorenterfun        cursorEnter; | ||||
|         GLFWscrollfun             scroll; | ||||
|         GLFWkeyfun                key; | ||||
|         GLFWcharfun               character; | ||||
|         GLFWcharmodsfun           charmods; | ||||
|         GLFWdropfun               drop; | ||||
|     } callbacks; | ||||
|  | ||||
|     // This is defined in the window API's platform.h | ||||
|     _GLFW_PLATFORM_WINDOW_STATE; | ||||
| }; | ||||
|  | ||||
| // Monitor structure | ||||
| // | ||||
| struct _GLFWmonitor | ||||
| { | ||||
|     char            name[128]; | ||||
|     void*           userPointer; | ||||
|  | ||||
|     // Physical dimensions in millimeters. | ||||
|     int             widthMM, heightMM; | ||||
|  | ||||
|     // The window whose video mode is current on this monitor | ||||
|     _GLFWwindow*    window; | ||||
|  | ||||
|     GLFWvidmode*    modes; | ||||
|     int             modeCount; | ||||
|     GLFWvidmode     currentMode; | ||||
|  | ||||
|     GLFWgammaramp   originalRamp; | ||||
|     GLFWgammaramp   currentRamp; | ||||
|  | ||||
|     // This is defined in the window API's platform.h | ||||
|     _GLFW_PLATFORM_MONITOR_STATE; | ||||
| }; | ||||
|  | ||||
| // Cursor structure | ||||
| // | ||||
| struct _GLFWcursor | ||||
| { | ||||
|     _GLFWcursor*    next; | ||||
|  | ||||
|     // This is defined in the window API's platform.h | ||||
|     _GLFW_PLATFORM_CURSOR_STATE; | ||||
| }; | ||||
|  | ||||
| // Gamepad mapping element structure | ||||
| // | ||||
| struct _GLFWmapelement | ||||
| { | ||||
|     uint8_t         type; | ||||
|     uint8_t         index; | ||||
|     int8_t          axisScale; | ||||
|     int8_t          axisOffset; | ||||
| }; | ||||
|  | ||||
| // Gamepad mapping structure | ||||
| // | ||||
| struct _GLFWmapping | ||||
| { | ||||
|     char            name[128]; | ||||
|     char            guid[33]; | ||||
|     _GLFWmapelement buttons[15]; | ||||
|     _GLFWmapelement axes[6]; | ||||
| }; | ||||
|  | ||||
| // Joystick structure | ||||
| // | ||||
| struct _GLFWjoystick | ||||
| { | ||||
|     GLFWbool        present; | ||||
|     float*          axes; | ||||
|     int             axisCount; | ||||
|     unsigned char*  buttons; | ||||
|     int             buttonCount; | ||||
|     unsigned char*  hats; | ||||
|     int             hatCount; | ||||
|     char            name[128]; | ||||
|     void*           userPointer; | ||||
|     char            guid[33]; | ||||
|     _GLFWmapping*   mapping; | ||||
|  | ||||
|     // This is defined in the joystick API's joystick.h | ||||
|     _GLFW_PLATFORM_JOYSTICK_STATE; | ||||
| }; | ||||
|  | ||||
| // Thread local storage structure | ||||
| // | ||||
| struct _GLFWtls | ||||
| { | ||||
|     // This is defined in the platform's thread.h | ||||
|     _GLFW_PLATFORM_TLS_STATE; | ||||
| }; | ||||
|  | ||||
| // Mutex structure | ||||
| // | ||||
| struct _GLFWmutex | ||||
| { | ||||
|     // This is defined in the platform's thread.h | ||||
|     _GLFW_PLATFORM_MUTEX_STATE; | ||||
| }; | ||||
|  | ||||
| // Library global data | ||||
| // | ||||
| struct _GLFWlibrary | ||||
| { | ||||
|     GLFWbool            initialized; | ||||
|  | ||||
|     struct { | ||||
|         _GLFWinitconfig init; | ||||
|         _GLFWfbconfig   framebuffer; | ||||
|         _GLFWwndconfig  window; | ||||
|         _GLFWctxconfig  context; | ||||
|         int             refreshRate; | ||||
|     } hints; | ||||
|  | ||||
|     _GLFWerror*         errorListHead; | ||||
|     _GLFWcursor*        cursorListHead; | ||||
|     _GLFWwindow*        windowListHead; | ||||
|  | ||||
|     _GLFWmonitor**      monitors; | ||||
|     int                 monitorCount; | ||||
|  | ||||
|     _GLFWjoystick       joysticks[GLFW_JOYSTICK_LAST + 1]; | ||||
|     _GLFWmapping*       mappings; | ||||
|     int                 mappingCount; | ||||
|  | ||||
|     _GLFWtls            errorSlot; | ||||
|     _GLFWtls            contextSlot; | ||||
|     _GLFWmutex          errorLock; | ||||
|  | ||||
|     struct { | ||||
|         uint64_t        offset; | ||||
|         // This is defined in the platform's time.h | ||||
|         _GLFW_PLATFORM_LIBRARY_TIMER_STATE; | ||||
|     } timer; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool        available; | ||||
|         void*           handle; | ||||
|         char*           extensions[2]; | ||||
| #if !defined(_GLFW_VULKAN_STATIC) | ||||
|         PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; | ||||
|         PFN_vkGetInstanceProcAddr GetInstanceProcAddr; | ||||
| #endif | ||||
|         GLFWbool        KHR_surface; | ||||
| #if defined(_GLFW_WIN32) | ||||
|         GLFWbool        KHR_win32_surface; | ||||
| #elif defined(_GLFW_COCOA) | ||||
|         GLFWbool        MVK_macos_surface; | ||||
|         GLFWbool        EXT_metal_surface; | ||||
| #elif defined(_GLFW_X11) | ||||
|         GLFWbool        KHR_xlib_surface; | ||||
|         GLFWbool        KHR_xcb_surface; | ||||
| #elif defined(_GLFW_WAYLAND) | ||||
|         GLFWbool        KHR_wayland_surface; | ||||
| #endif | ||||
|     } vk; | ||||
|  | ||||
|     struct { | ||||
|         GLFWmonitorfun  monitor; | ||||
|         GLFWjoystickfun joystick; | ||||
|     } callbacks; | ||||
|  | ||||
|     // This is defined in the window API's platform.h | ||||
|     _GLFW_PLATFORM_LIBRARY_WINDOW_STATE; | ||||
|     // This is defined in the context API's context.h | ||||
|     _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE; | ||||
|     // This is defined in the platform's joystick.h | ||||
|     _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE; | ||||
|     // This is defined in egl_context.h | ||||
|     _GLFW_EGL_LIBRARY_CONTEXT_STATE; | ||||
|     // This is defined in osmesa_context.h | ||||
|     _GLFW_OSMESA_LIBRARY_CONTEXT_STATE; | ||||
| }; | ||||
|  | ||||
| // Global state shared between compilation units of GLFW | ||||
| // | ||||
| extern _GLFWlibrary _glfw; | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformInit(void); | ||||
| void _glfwPlatformTerminate(void); | ||||
| const char* _glfwPlatformGetVersionString(void); | ||||
|  | ||||
| void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); | ||||
| void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); | ||||
| void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); | ||||
| void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled); | ||||
| GLFWbool _glfwPlatformRawMouseMotionSupported(void); | ||||
| int _glfwPlatformCreateCursor(_GLFWcursor* cursor, | ||||
|                               const GLFWimage* image, int xhot, int yhot); | ||||
| int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); | ||||
| void _glfwPlatformDestroyCursor(_GLFWcursor* cursor); | ||||
| void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); | ||||
|  | ||||
| const char* _glfwPlatformGetScancodeName(int scancode); | ||||
| int _glfwPlatformGetKeyScancode(int key); | ||||
|  | ||||
| void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor); | ||||
| void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos); | ||||
| void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, | ||||
|                                          float* xscale, float* yscale); | ||||
| void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height); | ||||
| GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); | ||||
| void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); | ||||
| GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); | ||||
| void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); | ||||
|  | ||||
| void _glfwPlatformSetClipboardString(const char* string); | ||||
| const char* _glfwPlatformGetClipboardString(void); | ||||
|  | ||||
| int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode); | ||||
| void _glfwPlatformUpdateGamepadGUID(char* guid); | ||||
|  | ||||
| uint64_t _glfwPlatformGetTimerValue(void); | ||||
| uint64_t _glfwPlatformGetTimerFrequency(void); | ||||
|  | ||||
| int _glfwPlatformCreateWindow(_GLFWwindow* window, | ||||
|                               const _GLFWwndconfig* wndconfig, | ||||
|                               const _GLFWctxconfig* ctxconfig, | ||||
|                               const _GLFWfbconfig* fbconfig); | ||||
| void _glfwPlatformDestroyWindow(_GLFWwindow* window); | ||||
| void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title); | ||||
| void _glfwPlatformSetWindowIcon(_GLFWwindow* window, | ||||
|                                 int count, const GLFWimage* images); | ||||
| void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos); | ||||
| void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos); | ||||
| void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height); | ||||
| void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); | ||||
| void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, | ||||
|                                       int minwidth, int minheight, | ||||
|                                       int maxwidth, int maxheight); | ||||
| void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom); | ||||
| void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height); | ||||
| void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, | ||||
|                                      int* left, int* top, | ||||
|                                      int* right, int* bottom); | ||||
| void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, | ||||
|                                         float* xscale, float* yscale); | ||||
| void _glfwPlatformIconifyWindow(_GLFWwindow* window); | ||||
| void _glfwPlatformRestoreWindow(_GLFWwindow* window); | ||||
| void _glfwPlatformMaximizeWindow(_GLFWwindow* window); | ||||
| void _glfwPlatformShowWindow(_GLFWwindow* window); | ||||
| void _glfwPlatformHideWindow(_GLFWwindow* window); | ||||
| void _glfwPlatformRequestWindowAttention(_GLFWwindow* window); | ||||
| void _glfwPlatformFocusWindow(_GLFWwindow* window); | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, | ||||
|                                    int xpos, int ypos, int width, int height, | ||||
|                                    int refreshRate); | ||||
| int _glfwPlatformWindowFocused(_GLFWwindow* window); | ||||
| int _glfwPlatformWindowIconified(_GLFWwindow* window); | ||||
| int _glfwPlatformWindowVisible(_GLFWwindow* window); | ||||
| int _glfwPlatformWindowMaximized(_GLFWwindow* window); | ||||
| int _glfwPlatformWindowHovered(_GLFWwindow* window); | ||||
| int _glfwPlatformFramebufferTransparent(_GLFWwindow* window); | ||||
| float _glfwPlatformGetWindowOpacity(_GLFWwindow* window); | ||||
| void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled); | ||||
| void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled); | ||||
| void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled); | ||||
| void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity); | ||||
|  | ||||
| void _glfwPlatformPollEvents(void); | ||||
| void _glfwPlatformWaitEvents(void); | ||||
| void _glfwPlatformWaitEventsTimeout(double timeout); | ||||
| void _glfwPlatformPostEmptyEvent(void); | ||||
|  | ||||
| void _glfwPlatformGetRequiredInstanceExtensions(char** extensions); | ||||
| int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, | ||||
|                                                       VkPhysicalDevice device, | ||||
|                                                       uint32_t queuefamily); | ||||
| VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, | ||||
|                                           _GLFWwindow* window, | ||||
|                                           const VkAllocationCallbacks* allocator, | ||||
|                                           VkSurfaceKHR* surface); | ||||
|  | ||||
| GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls); | ||||
| void _glfwPlatformDestroyTls(_GLFWtls* tls); | ||||
| void* _glfwPlatformGetTls(_GLFWtls* tls); | ||||
| void _glfwPlatformSetTls(_GLFWtls* tls, void* value); | ||||
|  | ||||
| GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex); | ||||
| void _glfwPlatformDestroyMutex(_GLFWmutex* mutex); | ||||
| void _glfwPlatformLockMutex(_GLFWmutex* mutex); | ||||
| void _glfwPlatformUnlockMutex(_GLFWmutex* mutex); | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                         GLFW event API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused); | ||||
| void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos); | ||||
| void _glfwInputWindowSize(_GLFWwindow* window, int width, int height); | ||||
| void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height); | ||||
| void _glfwInputWindowContentScale(_GLFWwindow* window, | ||||
|                                   float xscale, float yscale); | ||||
| void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified); | ||||
| void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized); | ||||
| void _glfwInputWindowDamage(_GLFWwindow* window); | ||||
| void _glfwInputWindowCloseRequest(_GLFWwindow* window); | ||||
| void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor); | ||||
|  | ||||
| void _glfwInputKey(_GLFWwindow* window, | ||||
|                    int key, int scancode, int action, int mods); | ||||
| void _glfwInputChar(_GLFWwindow* window, | ||||
|                     unsigned int codepoint, int mods, GLFWbool plain); | ||||
| void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset); | ||||
| void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); | ||||
| void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos); | ||||
| void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered); | ||||
| void _glfwInputDrop(_GLFWwindow* window, int count, const char** names); | ||||
| void _glfwInputJoystick(_GLFWjoystick* js, int event); | ||||
| void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value); | ||||
| void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value); | ||||
| void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value); | ||||
|  | ||||
| void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement); | ||||
| void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window); | ||||
|  | ||||
| #if defined(__GNUC__) | ||||
| void _glfwInputError(int code, const char* format, ...) | ||||
|     __attribute__((format(printf, 2, 3))); | ||||
| #else | ||||
| void _glfwInputError(int code, const char* format, ...); | ||||
| #endif | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions); | ||||
| const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, | ||||
|                                          const _GLFWfbconfig* alternatives, | ||||
|                                          unsigned int count); | ||||
| GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window, | ||||
|                                     const _GLFWctxconfig* ctxconfig); | ||||
| GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig); | ||||
|  | ||||
| const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, | ||||
|                                         const GLFWvidmode* desired); | ||||
| int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second); | ||||
| _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM); | ||||
| void _glfwFreeMonitor(_GLFWmonitor* monitor); | ||||
| void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size); | ||||
| void _glfwFreeGammaArrays(GLFWgammaramp* ramp); | ||||
| void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); | ||||
|  | ||||
| void _glfwInitGamepadMappings(void); | ||||
| _GLFWjoystick* _glfwAllocJoystick(const char* name, | ||||
|                                   const char* guid, | ||||
|                                   int axisCount, | ||||
|                                   int buttonCount, | ||||
|                                   int hatCount); | ||||
| void _glfwFreeJoystick(_GLFWjoystick* js); | ||||
| void _glfwCenterCursorInContentArea(_GLFWwindow* window); | ||||
|  | ||||
| GLFWbool _glfwInitVulkan(int mode); | ||||
| void _glfwTerminateVulkan(void); | ||||
| const char* _glfwGetVulkanResultString(VkResult result); | ||||
|  | ||||
| char* _glfw_strdup(const char* source); | ||||
| float _glfw_fminf(float a, float b); | ||||
| float _glfw_fmaxf(float a, float b); | ||||
|  | ||||
							
								
								
									
										433
									
								
								deps/glfw/src/linux_joystick.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										433
									
								
								deps/glfw/src/linux_joystick.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,433 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Linux - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/inotify.h> | ||||
| #include <fcntl.h> | ||||
| #include <errno.h> | ||||
| #include <dirent.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #ifndef SYN_DROPPED // < v2.6.39 kernel headers | ||||
| // Workaround for CentOS-6, which is supported till 2020-11-30, but still on v2.6.32 | ||||
| #define SYN_DROPPED 3 | ||||
| #endif | ||||
|  | ||||
| // Apply an EV_KEY event to the specified joystick | ||||
| // | ||||
| static void handleKeyEvent(_GLFWjoystick* js, int code, int value) | ||||
| { | ||||
|     _glfwInputJoystickButton(js, | ||||
|                              js->linjs.keyMap[code - BTN_MISC], | ||||
|                              value ? GLFW_PRESS : GLFW_RELEASE); | ||||
| } | ||||
|  | ||||
| // Apply an EV_ABS event to the specified joystick | ||||
| // | ||||
| static void handleAbsEvent(_GLFWjoystick* js, int code, int value) | ||||
| { | ||||
|     const int index = js->linjs.absMap[code]; | ||||
|  | ||||
|     if (code >= ABS_HAT0X && code <= ABS_HAT3Y) | ||||
|     { | ||||
|         static const char stateMap[3][3] = | ||||
|         { | ||||
|             { GLFW_HAT_CENTERED, GLFW_HAT_UP,       GLFW_HAT_DOWN }, | ||||
|             { GLFW_HAT_LEFT,     GLFW_HAT_LEFT_UP,  GLFW_HAT_LEFT_DOWN }, | ||||
|             { GLFW_HAT_RIGHT,    GLFW_HAT_RIGHT_UP, GLFW_HAT_RIGHT_DOWN }, | ||||
|         }; | ||||
|  | ||||
|         const int hat = (code - ABS_HAT0X) / 2; | ||||
|         const int axis = (code - ABS_HAT0X) % 2; | ||||
|         int* state = js->linjs.hats[hat]; | ||||
|  | ||||
|         // NOTE: Looking at several input drivers, it seems all hat events use | ||||
|         //       -1 for left / up, 0 for centered and 1 for right / down | ||||
|         if (value == 0) | ||||
|             state[axis] = 0; | ||||
|         else if (value < 0) | ||||
|             state[axis] = 1; | ||||
|         else if (value > 0) | ||||
|             state[axis] = 2; | ||||
|  | ||||
|         _glfwInputJoystickHat(js, index, stateMap[state[0]][state[1]]); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         const struct input_absinfo* info = &js->linjs.absInfo[code]; | ||||
|         float normalized = value; | ||||
|  | ||||
|         const int range = info->maximum - info->minimum; | ||||
|         if (range) | ||||
|         { | ||||
|             // Normalize to 0.0 -> 1.0 | ||||
|             normalized = (normalized - info->minimum) / range; | ||||
|             // Normalize to -1.0 -> 1.0 | ||||
|             normalized = normalized * 2.0f - 1.0f; | ||||
|         } | ||||
|  | ||||
|         _glfwInputJoystickAxis(js, index, normalized); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Poll state of absolute axes | ||||
| // | ||||
| static void pollAbsState(_GLFWjoystick* js) | ||||
| { | ||||
|     for (int code = 0;  code < ABS_CNT;  code++) | ||||
|     { | ||||
|         if (js->linjs.absMap[code] < 0) | ||||
|             continue; | ||||
|  | ||||
|         struct input_absinfo* info = &js->linjs.absInfo[code]; | ||||
|  | ||||
|         if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0) | ||||
|             continue; | ||||
|  | ||||
|         handleAbsEvent(js, code, info->value); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8))) | ||||
|  | ||||
| // Attempt to open the specified joystick device | ||||
| // | ||||
| static GLFWbool openJoystickDevice(const char* path) | ||||
| { | ||||
|     for (int jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|     { | ||||
|         if (!_glfw.joysticks[jid].present) | ||||
|             continue; | ||||
|         if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) | ||||
|             return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _GLFWjoystickLinux linjs = {0}; | ||||
|     linjs.fd = open(path, O_RDONLY | O_NONBLOCK); | ||||
|     if (linjs.fd == -1) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     char evBits[(EV_CNT + 7) / 8] = {0}; | ||||
|     char keyBits[(KEY_CNT + 7) / 8] = {0}; | ||||
|     char absBits[(ABS_CNT + 7) / 8] = {0}; | ||||
|     struct input_id id; | ||||
|  | ||||
|     if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 || | ||||
|         ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 || | ||||
|         ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 || | ||||
|         ioctl(linjs.fd, EVIOCGID, &id) < 0) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Linux: Failed to query input device: %s", | ||||
|                         strerror(errno)); | ||||
|         close(linjs.fd); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     // Ensure this device supports the events expected of a joystick | ||||
|     if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits)) | ||||
|     { | ||||
|         close(linjs.fd); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     char name[256] = ""; | ||||
|  | ||||
|     if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0) | ||||
|         strncpy(name, "Unknown", sizeof(name)); | ||||
|  | ||||
|     char guid[33] = ""; | ||||
|  | ||||
|     // Generate a joystick GUID that matches the SDL 2.0.5+ one | ||||
|     if (id.vendor && id.product && id.version) | ||||
|     { | ||||
|         sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000", | ||||
|                 id.bustype & 0xff, id.bustype >> 8, | ||||
|                 id.vendor & 0xff,  id.vendor >> 8, | ||||
|                 id.product & 0xff, id.product >> 8, | ||||
|                 id.version & 0xff, id.version >> 8); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00", | ||||
|                 id.bustype & 0xff, id.bustype >> 8, | ||||
|                 name[0], name[1], name[2], name[3], | ||||
|                 name[4], name[5], name[6], name[7], | ||||
|                 name[8], name[9], name[10]); | ||||
|     } | ||||
|  | ||||
|     int axisCount = 0, buttonCount = 0, hatCount = 0; | ||||
|  | ||||
|     for (int code = BTN_MISC;  code < KEY_CNT;  code++) | ||||
|     { | ||||
|         if (!isBitSet(code, keyBits)) | ||||
|             continue; | ||||
|  | ||||
|         linjs.keyMap[code - BTN_MISC] = buttonCount; | ||||
|         buttonCount++; | ||||
|     } | ||||
|  | ||||
|     for (int code = 0;  code < ABS_CNT;  code++) | ||||
|     { | ||||
|         linjs.absMap[code] = -1; | ||||
|         if (!isBitSet(code, absBits)) | ||||
|             continue; | ||||
|  | ||||
|         if (code >= ABS_HAT0X && code <= ABS_HAT3Y) | ||||
|         { | ||||
|             linjs.absMap[code] = hatCount; | ||||
|             hatCount++; | ||||
|             // Skip the Y axis | ||||
|             code++; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0) | ||||
|                 continue; | ||||
|  | ||||
|             linjs.absMap[code] = axisCount; | ||||
|             axisCount++; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _GLFWjoystick* js = | ||||
|         _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount); | ||||
|     if (!js) | ||||
|     { | ||||
|         close(linjs.fd); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     strncpy(linjs.path, path, sizeof(linjs.path) - 1); | ||||
|     memcpy(&js->linjs, &linjs, sizeof(linjs)); | ||||
|  | ||||
|     pollAbsState(js); | ||||
|  | ||||
|     _glfwInputJoystick(js, GLFW_CONNECTED); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| #undef isBitSet | ||||
|  | ||||
| // Frees all resources associated with the specified joystick | ||||
| // | ||||
| static void closeJoystick(_GLFWjoystick* js) | ||||
| { | ||||
|     close(js->linjs.fd); | ||||
|     _glfwFreeJoystick(js); | ||||
|     _glfwInputJoystick(js, GLFW_DISCONNECTED); | ||||
| } | ||||
|  | ||||
| // Lexically compare joysticks by name; used by qsort | ||||
| // | ||||
| static int compareJoysticks(const void* fp, const void* sp) | ||||
| { | ||||
|     const _GLFWjoystick* fj = fp; | ||||
|     const _GLFWjoystick* sj = sp; | ||||
|     return strcmp(fj->linjs.path, sj->linjs.path); | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialize joystick interface | ||||
| // | ||||
| GLFWbool _glfwInitJoysticksLinux(void) | ||||
| { | ||||
|     const char* dirname = "/dev/input"; | ||||
|  | ||||
|     _glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); | ||||
|     if (_glfw.linjs.inotify > 0) | ||||
|     { | ||||
|         // HACK: Register for IN_ATTRIB to get notified when udev is done | ||||
|         //       This works well in practice but the true way is libudev | ||||
|  | ||||
|         _glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify, | ||||
|                                               dirname, | ||||
|                                               IN_CREATE | IN_ATTRIB | IN_DELETE); | ||||
|     } | ||||
|  | ||||
|     // Continue without device connection notifications if inotify fails | ||||
|  | ||||
|     if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     int count = 0; | ||||
|  | ||||
|     DIR* dir = opendir(dirname); | ||||
|     if (dir) | ||||
|     { | ||||
|         struct dirent* entry; | ||||
|  | ||||
|         while ((entry = readdir(dir))) | ||||
|         { | ||||
|             regmatch_t match; | ||||
|  | ||||
|             if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0) | ||||
|                 continue; | ||||
|  | ||||
|             char path[PATH_MAX]; | ||||
|  | ||||
|             snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); | ||||
|  | ||||
|             if (openJoystickDevice(path)) | ||||
|                 count++; | ||||
|         } | ||||
|  | ||||
|         closedir(dir); | ||||
|     } | ||||
|  | ||||
|     // Continue with no joysticks if enumeration fails | ||||
|  | ||||
|     qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Close all opened joystick handles | ||||
| // | ||||
| void _glfwTerminateJoysticksLinux(void) | ||||
| { | ||||
|     int jid; | ||||
|  | ||||
|     for (jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|     { | ||||
|         _GLFWjoystick* js = _glfw.joysticks + jid; | ||||
|         if (js->present) | ||||
|             closeJoystick(js); | ||||
|     } | ||||
|  | ||||
|     regfree(&_glfw.linjs.regex); | ||||
|  | ||||
|     if (_glfw.linjs.inotify > 0) | ||||
|     { | ||||
|         if (_glfw.linjs.watch > 0) | ||||
|             inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch); | ||||
|  | ||||
|         close(_glfw.linjs.inotify); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void _glfwDetectJoystickConnectionLinux(void) | ||||
| { | ||||
|     if (_glfw.linjs.inotify <= 0) | ||||
|         return; | ||||
|  | ||||
|     ssize_t offset = 0; | ||||
|     char buffer[16384]; | ||||
|     const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer)); | ||||
|  | ||||
|     while (size > offset) | ||||
|     { | ||||
|         regmatch_t match; | ||||
|         const struct inotify_event* e = (struct inotify_event*) (buffer + offset); | ||||
|  | ||||
|         offset += sizeof(struct inotify_event) + e->len; | ||||
|  | ||||
|         if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0) | ||||
|             continue; | ||||
|  | ||||
|         char path[PATH_MAX]; | ||||
|         snprintf(path, sizeof(path), "/dev/input/%s", e->name); | ||||
|  | ||||
|         if (e->mask & (IN_CREATE | IN_ATTRIB)) | ||||
|             openJoystickDevice(path); | ||||
|         else if (e->mask & IN_DELETE) | ||||
|         { | ||||
|             for (int jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|             { | ||||
|                 if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) | ||||
|                 { | ||||
|                     closeJoystick(_glfw.joysticks + jid); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) | ||||
| { | ||||
|     // Read all queued events (non-blocking) | ||||
|     for (;;) | ||||
|     { | ||||
|         struct input_event e; | ||||
|  | ||||
|         errno = 0; | ||||
|         if (read(js->linjs.fd, &e, sizeof(e)) < 0) | ||||
|         { | ||||
|             // Reset the joystick slot if the device was disconnected | ||||
|             if (errno == ENODEV) | ||||
|                 closeJoystick(js); | ||||
|  | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         if (e.type == EV_SYN) | ||||
|         { | ||||
|             if (e.code == SYN_DROPPED) | ||||
|                 _glfw.linjs.dropped = GLFW_TRUE; | ||||
|             else if (e.code == SYN_REPORT) | ||||
|             { | ||||
|                 _glfw.linjs.dropped = GLFW_FALSE; | ||||
|                 pollAbsState(js); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (_glfw.linjs.dropped) | ||||
|             continue; | ||||
|  | ||||
|         if (e.type == EV_KEY) | ||||
|             handleKeyEvent(js, e.code, e.value); | ||||
|         else if (e.type == EV_ABS) | ||||
|             handleAbsEvent(js, e.code, e.value); | ||||
|     } | ||||
|  | ||||
|     return js->present; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformUpdateGamepadGUID(char* guid) | ||||
| { | ||||
| } | ||||
|  | ||||
							
								
								
									
										63
									
								
								deps/glfw/src/linux_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								deps/glfw/src/linux_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Linux - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #include <linux/input.h> | ||||
| #include <linux/limits.h> | ||||
| #include <regex.h> | ||||
|  | ||||
| #define _GLFW_PLATFORM_JOYSTICK_STATE         _GLFWjoystickLinux linjs | ||||
| #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux  linjs | ||||
|  | ||||
| #define _GLFW_PLATFORM_MAPPING_NAME "Linux" | ||||
| #define GLFW_BUILD_LINUX_MAPPINGS | ||||
|  | ||||
| // Linux-specific joystick data | ||||
| // | ||||
| typedef struct _GLFWjoystickLinux | ||||
| { | ||||
|     int                     fd; | ||||
|     char                    path[PATH_MAX]; | ||||
|     int                     keyMap[KEY_CNT - BTN_MISC]; | ||||
|     int                     absMap[ABS_CNT]; | ||||
|     struct input_absinfo    absInfo[ABS_CNT]; | ||||
|     int                     hats[4][2]; | ||||
| } _GLFWjoystickLinux; | ||||
|  | ||||
| // Linux-specific joystick API data | ||||
| // | ||||
| typedef struct _GLFWlibraryLinux | ||||
| { | ||||
|     int                     inotify; | ||||
|     int                     watch; | ||||
|     regex_t                 regex; | ||||
|     GLFWbool                dropped; | ||||
| } _GLFWlibraryLinux; | ||||
|  | ||||
|  | ||||
| GLFWbool _glfwInitJoysticksLinux(void); | ||||
| void _glfwTerminateJoysticksLinux(void); | ||||
| void _glfwDetectJoystickConnectionLinux(void); | ||||
|  | ||||
							
								
								
									
										1001
									
								
								deps/glfw/src/mappings.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1001
									
								
								deps/glfw/src/mappings.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										82
									
								
								deps/glfw/src/mappings.h.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								deps/glfw/src/mappings.h.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // As mappings.h.in, this file is used by CMake to produce the mappings.h | ||||
| // header file.  If you are adding a GLFW specific gamepad mapping, this is | ||||
| // where to put it. | ||||
| //======================================================================== | ||||
| // As mappings.h, this provides all pre-defined gamepad mappings, including | ||||
| // all available in SDL_GameControllerDB.  Do not edit this file.  Any gamepad | ||||
| // mappings not specific to GLFW should be submitted to SDL_GameControllerDB. | ||||
| // This file can be re-generated from mappings.h.in and the upstream | ||||
| // gamecontrollerdb.txt with the 'update_mappings' CMake target. | ||||
| //======================================================================== | ||||
|  | ||||
| // All gamepad mappings not labeled GLFW are copied from the | ||||
| // SDL_GameControllerDB project under the following license: | ||||
| // | ||||
| // Simple DirectMedia Layer | ||||
| // Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied warranty. | ||||
| // In no event will the authors be held liable for any damages arising from the | ||||
| // use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not be | ||||
| //    misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source distribution. | ||||
|  | ||||
| const char* _glfwDefaultMappings[] = | ||||
| { | ||||
| #if defined(GLFW_BUILD_WIN32_MAPPINGS) | ||||
| @GLFW_WIN32_MAPPINGS@ | ||||
| "78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", | ||||
| "78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", | ||||
| "78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", | ||||
| "78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", | ||||
| "78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", | ||||
| "78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", | ||||
| "78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", | ||||
| #endif // GLFW_BUILD_WIN32_MAPPINGS | ||||
|  | ||||
| #if defined(GLFW_BUILD_COCOA_MAPPINGS) | ||||
| @GLFW_COCOA_MAPPINGS@ | ||||
| #endif // GLFW_BUILD_COCOA_MAPPINGS | ||||
|  | ||||
| #if defined(GLFW_BUILD_LINUX_MAPPINGS) | ||||
| @GLFW_LINUX_MAPPINGS@ | ||||
| #endif // GLFW_BUILD_LINUX_MAPPINGS | ||||
| }; | ||||
|  | ||||
							
								
								
									
										542
									
								
								deps/glfw/src/monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										542
									
								
								deps/glfw/src/monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,542 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <math.h> | ||||
| #include <float.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <limits.h> | ||||
|  | ||||
|  | ||||
| // Lexically compare video modes, used by qsort | ||||
| // | ||||
| static int compareVideoModes(const void* fp, const void* sp) | ||||
| { | ||||
|     const GLFWvidmode* fm = fp; | ||||
|     const GLFWvidmode* sm = sp; | ||||
|     const int fbpp = fm->redBits + fm->greenBits + fm->blueBits; | ||||
|     const int sbpp = sm->redBits + sm->greenBits + sm->blueBits; | ||||
|     const int farea = fm->width * fm->height; | ||||
|     const int sarea = sm->width * sm->height; | ||||
|  | ||||
|     // First sort on color bits per pixel | ||||
|     if (fbpp != sbpp) | ||||
|         return fbpp - sbpp; | ||||
|  | ||||
|     // Then sort on screen area | ||||
|     if (farea != sarea) | ||||
|         return farea - sarea; | ||||
|  | ||||
|     // Then sort on width | ||||
|     if (fm->width != sm->width) | ||||
|         return fm->width - sm->width; | ||||
|  | ||||
|     // Lastly sort on refresh rate | ||||
|     return fm->refreshRate - sm->refreshRate; | ||||
| } | ||||
|  | ||||
| // Retrieves the available modes for the specified monitor | ||||
| // | ||||
| static GLFWbool refreshVideoModes(_GLFWmonitor* monitor) | ||||
| { | ||||
|     int modeCount; | ||||
|     GLFWvidmode* modes; | ||||
|  | ||||
|     if (monitor->modes) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
|     modes = _glfwPlatformGetVideoModes(monitor, &modeCount); | ||||
|     if (!modes) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); | ||||
|  | ||||
|     free(monitor->modes); | ||||
|     monitor->modes = modes; | ||||
|     monitor->modeCount = modeCount; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                         GLFW event API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Notifies shared code of a monitor connection or disconnection | ||||
| // | ||||
| void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement) | ||||
| { | ||||
|     if (action == GLFW_CONNECTED) | ||||
|     { | ||||
|         _glfw.monitorCount++; | ||||
|         _glfw.monitors = | ||||
|             realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount); | ||||
|  | ||||
|         if (placement == _GLFW_INSERT_FIRST) | ||||
|         { | ||||
|             memmove(_glfw.monitors + 1, | ||||
|                     _glfw.monitors, | ||||
|                     ((size_t) _glfw.monitorCount - 1) * sizeof(_GLFWmonitor*)); | ||||
|             _glfw.monitors[0] = monitor; | ||||
|         } | ||||
|         else | ||||
|             _glfw.monitors[_glfw.monitorCount - 1] = monitor; | ||||
|     } | ||||
|     else if (action == GLFW_DISCONNECTED) | ||||
|     { | ||||
|         int i; | ||||
|         _GLFWwindow* window; | ||||
|  | ||||
|         for (window = _glfw.windowListHead;  window;  window = window->next) | ||||
|         { | ||||
|             if (window->monitor == monitor) | ||||
|             { | ||||
|                 int width, height, xoff, yoff; | ||||
|                 _glfwPlatformGetWindowSize(window, &width, &height); | ||||
|                 _glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0); | ||||
|                 _glfwPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL); | ||||
|                 _glfwPlatformSetWindowPos(window, xoff, yoff); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (i = 0;  i < _glfw.monitorCount;  i++) | ||||
|         { | ||||
|             if (_glfw.monitors[i] == monitor) | ||||
|             { | ||||
|                 _glfw.monitorCount--; | ||||
|                 memmove(_glfw.monitors + i, | ||||
|                         _glfw.monitors + i + 1, | ||||
|                         ((size_t) _glfw.monitorCount - i) * sizeof(_GLFWmonitor*)); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (_glfw.callbacks.monitor) | ||||
|         _glfw.callbacks.monitor((GLFWmonitor*) monitor, action); | ||||
|  | ||||
|     if (action == GLFW_DISCONNECTED) | ||||
|         _glfwFreeMonitor(monitor); | ||||
| } | ||||
|  | ||||
| // Notifies shared code that a full screen window has acquired or released | ||||
| // a monitor | ||||
| // | ||||
| void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window) | ||||
| { | ||||
|     monitor->window = window; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Allocates and returns a monitor object with the specified name and dimensions | ||||
| // | ||||
| _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) | ||||
| { | ||||
|     _GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor)); | ||||
|     monitor->widthMM = widthMM; | ||||
|     monitor->heightMM = heightMM; | ||||
|  | ||||
|     strncpy(monitor->name, name, sizeof(monitor->name) - 1); | ||||
|  | ||||
|     return monitor; | ||||
| } | ||||
|  | ||||
| // Frees a monitor object and any data associated with it | ||||
| // | ||||
| void _glfwFreeMonitor(_GLFWmonitor* monitor) | ||||
| { | ||||
|     if (monitor == NULL) | ||||
|         return; | ||||
|  | ||||
|     _glfwPlatformFreeMonitor(monitor); | ||||
|  | ||||
|     _glfwFreeGammaArrays(&monitor->originalRamp); | ||||
|     _glfwFreeGammaArrays(&monitor->currentRamp); | ||||
|  | ||||
|     free(monitor->modes); | ||||
|     free(monitor); | ||||
| } | ||||
|  | ||||
| // Allocates red, green and blue value arrays of the specified size | ||||
| // | ||||
| void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) | ||||
| { | ||||
|     ramp->red = calloc(size, sizeof(unsigned short)); | ||||
|     ramp->green = calloc(size, sizeof(unsigned short)); | ||||
|     ramp->blue = calloc(size, sizeof(unsigned short)); | ||||
|     ramp->size = size; | ||||
| } | ||||
|  | ||||
| // Frees the red, green and blue value arrays and clears the struct | ||||
| // | ||||
| void _glfwFreeGammaArrays(GLFWgammaramp* ramp) | ||||
| { | ||||
|     free(ramp->red); | ||||
|     free(ramp->green); | ||||
|     free(ramp->blue); | ||||
|  | ||||
|     memset(ramp, 0, sizeof(GLFWgammaramp)); | ||||
| } | ||||
|  | ||||
| // Chooses the video mode most closely matching the desired one | ||||
| // | ||||
| const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, | ||||
|                                         const GLFWvidmode* desired) | ||||
| { | ||||
|     int i; | ||||
|     unsigned int sizeDiff, leastSizeDiff = UINT_MAX; | ||||
|     unsigned int rateDiff, leastRateDiff = UINT_MAX; | ||||
|     unsigned int colorDiff, leastColorDiff = UINT_MAX; | ||||
|     const GLFWvidmode* current; | ||||
|     const GLFWvidmode* closest = NULL; | ||||
|  | ||||
|     if (!refreshVideoModes(monitor)) | ||||
|         return NULL; | ||||
|  | ||||
|     for (i = 0;  i < monitor->modeCount;  i++) | ||||
|     { | ||||
|         current = monitor->modes + i; | ||||
|  | ||||
|         colorDiff = 0; | ||||
|  | ||||
|         if (desired->redBits != GLFW_DONT_CARE) | ||||
|             colorDiff += abs(current->redBits - desired->redBits); | ||||
|         if (desired->greenBits != GLFW_DONT_CARE) | ||||
|             colorDiff += abs(current->greenBits - desired->greenBits); | ||||
|         if (desired->blueBits != GLFW_DONT_CARE) | ||||
|             colorDiff += abs(current->blueBits - desired->blueBits); | ||||
|  | ||||
|         sizeDiff = abs((current->width - desired->width) * | ||||
|                        (current->width - desired->width) + | ||||
|                        (current->height - desired->height) * | ||||
|                        (current->height - desired->height)); | ||||
|  | ||||
|         if (desired->refreshRate != GLFW_DONT_CARE) | ||||
|             rateDiff = abs(current->refreshRate - desired->refreshRate); | ||||
|         else | ||||
|             rateDiff = UINT_MAX - current->refreshRate; | ||||
|  | ||||
|         if ((colorDiff < leastColorDiff) || | ||||
|             (colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) || | ||||
|             (colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff)) | ||||
|         { | ||||
|             closest = current; | ||||
|             leastSizeDiff = sizeDiff; | ||||
|             leastRateDiff = rateDiff; | ||||
|             leastColorDiff = colorDiff; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return closest; | ||||
| } | ||||
|  | ||||
| // Performs lexical comparison between two @ref GLFWvidmode structures | ||||
| // | ||||
| int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm) | ||||
| { | ||||
|     return compareVideoModes(fm, sm); | ||||
| } | ||||
|  | ||||
| // Splits a color depth into red, green and blue bit depths | ||||
| // | ||||
| void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) | ||||
| { | ||||
|     int delta; | ||||
|  | ||||
|     // We assume that by 32 the user really meant 24 | ||||
|     if (bpp == 32) | ||||
|         bpp = 24; | ||||
|  | ||||
|     // Convert "bits per pixel" to red, green & blue sizes | ||||
|  | ||||
|     *red = *green = *blue = bpp / 3; | ||||
|     delta = bpp - (*red * 3); | ||||
|     if (delta >= 1) | ||||
|         *green = *green + 1; | ||||
|  | ||||
|     if (delta == 2) | ||||
|         *red = *red + 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW public API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI GLFWmonitor** glfwGetMonitors(int* count) | ||||
| { | ||||
|     assert(count != NULL); | ||||
|  | ||||
|     *count = 0; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     *count = _glfw.monitorCount; | ||||
|     return (GLFWmonitor**) _glfw.monitors; | ||||
| } | ||||
|  | ||||
| GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void) | ||||
| { | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     if (!_glfw.monitorCount) | ||||
|         return NULL; | ||||
|  | ||||
|     return (GLFWmonitor*) _glfw.monitors[0]; | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     if (xpos) | ||||
|         *xpos = 0; | ||||
|     if (ypos) | ||||
|         *ypos = 0; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     _glfwPlatformGetMonitorPos(monitor, xpos, ypos); | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, | ||||
|                                     int* xpos, int* ypos, | ||||
|                                     int* width, int* height) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     if (xpos) | ||||
|         *xpos = 0; | ||||
|     if (ypos) | ||||
|         *ypos = 0; | ||||
|     if (width) | ||||
|         *width = 0; | ||||
|     if (height) | ||||
|         *height = 0; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     _glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height); | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     if (widthMM) | ||||
|         *widthMM = 0; | ||||
|     if (heightMM) | ||||
|         *heightMM = 0; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     if (widthMM) | ||||
|         *widthMM = monitor->widthMM; | ||||
|     if (heightMM) | ||||
|         *heightMM = monitor->heightMM; | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle, | ||||
|                                         float* xscale, float* yscale) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     if (xscale) | ||||
|         *xscale = 0.f; | ||||
|     if (yscale) | ||||
|         *yscale = 0.f; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|     _glfwPlatformGetMonitorContentScale(monitor, xscale, yscale); | ||||
| } | ||||
|  | ||||
| GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|     return monitor->name; | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|     monitor->userPointer = pointer; | ||||
| } | ||||
|  | ||||
| GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|     return monitor->userPointer; | ||||
| } | ||||
|  | ||||
| GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) | ||||
| { | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|     _GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun); | ||||
|     return cbfun; | ||||
| } | ||||
|  | ||||
| GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|     assert(count != NULL); | ||||
|  | ||||
|     *count = 0; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     if (!refreshVideoModes(monitor)) | ||||
|         return NULL; | ||||
|  | ||||
|     *count = monitor->modeCount; | ||||
|     return monitor->modes; | ||||
| } | ||||
|  | ||||
| GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     _glfwPlatformGetVideoMode(monitor, &monitor->currentMode); | ||||
|     return &monitor->currentMode; | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) | ||||
| { | ||||
|     unsigned int i; | ||||
|     unsigned short* values; | ||||
|     GLFWgammaramp ramp; | ||||
|     const GLFWgammaramp* original; | ||||
|     assert(handle != NULL); | ||||
|     assert(gamma > 0.f); | ||||
|     assert(gamma <= FLT_MAX); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX) | ||||
|     { | ||||
|         _glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     original = glfwGetGammaRamp(handle); | ||||
|     if (!original) | ||||
|         return; | ||||
|  | ||||
|     values = calloc(original->size, sizeof(unsigned short)); | ||||
|  | ||||
|     for (i = 0;  i < original->size;  i++) | ||||
|     { | ||||
|         float value; | ||||
|  | ||||
|         // Calculate intensity | ||||
|         value = i / (float) (original->size - 1); | ||||
|         // Apply gamma curve | ||||
|         value = powf(value, 1.f / gamma) * 65535.f + 0.5f; | ||||
|         // Clamp to value range | ||||
|         value = _glfw_fminf(value, 65535.f); | ||||
|  | ||||
|         values[i] = (unsigned short) value; | ||||
|     } | ||||
|  | ||||
|     ramp.red = values; | ||||
|     ramp.green = values; | ||||
|     ramp.blue = values; | ||||
|     ramp.size = original->size; | ||||
|  | ||||
|     glfwSetGammaRamp(handle, &ramp); | ||||
|     free(values); | ||||
| } | ||||
|  | ||||
| GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     _glfwFreeGammaArrays(&monitor->currentRamp); | ||||
|     if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp)) | ||||
|         return NULL; | ||||
|  | ||||
|     return &monitor->currentRamp; | ||||
| } | ||||
|  | ||||
| GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     assert(monitor != NULL); | ||||
|     assert(ramp != NULL); | ||||
|     assert(ramp->size > 0); | ||||
|     assert(ramp->red != NULL); | ||||
|     assert(ramp->green != NULL); | ||||
|     assert(ramp->blue != NULL); | ||||
|  | ||||
|     if (ramp->size <= 0) | ||||
|     { | ||||
|         _glfwInputError(GLFW_INVALID_VALUE, | ||||
|                         "Invalid gamma ramp size %i", | ||||
|                         ramp->size); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
|  | ||||
|     if (!monitor->originalRamp.size) | ||||
|     { | ||||
|         if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) | ||||
|             return; | ||||
|     } | ||||
|  | ||||
|     _glfwPlatformSetGammaRamp(monitor, ramp); | ||||
| } | ||||
|  | ||||
							
								
								
									
										64
									
								
								deps/glfw/src/nsgl_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								deps/glfw/src/nsgl_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 macOS - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| // NOTE: Many Cocoa enum values have been renamed and we need to build across | ||||
| //       SDK versions where one is unavailable or the other deprecated | ||||
| //       We use the newer names in code and these macros to handle compatibility | ||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED < 101400 | ||||
|  #define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval | ||||
|  #define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity | ||||
| #endif | ||||
|  | ||||
| #define _GLFW_PLATFORM_CONTEXT_STATE            _GLFWcontextNSGL nsgl | ||||
| #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE    _GLFWlibraryNSGL nsgl | ||||
|  | ||||
| #include <stdatomic.h> | ||||
|  | ||||
|  | ||||
| // NSGL-specific per-context data | ||||
| // | ||||
| typedef struct _GLFWcontextNSGL | ||||
| { | ||||
|     id                pixelFormat; | ||||
|     id                object; | ||||
| } _GLFWcontextNSGL; | ||||
|  | ||||
| // NSGL-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryNSGL | ||||
| { | ||||
|     // dlopen handle for OpenGL.framework (for glfwGetProcAddress) | ||||
|     CFBundleRef     framework; | ||||
| } _GLFWlibraryNSGL; | ||||
|  | ||||
|  | ||||
| GLFWbool _glfwInitNSGL(void); | ||||
| void _glfwTerminateNSGL(void); | ||||
| GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, | ||||
|                                 const _GLFWctxconfig* ctxconfig, | ||||
|                                 const _GLFWfbconfig* fbconfig); | ||||
| void _glfwDestroyContextNSGL(_GLFWwindow* window); | ||||
|  | ||||
							
								
								
									
										376
									
								
								deps/glfw/src/nsgl_context.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										376
									
								
								deps/glfw/src/nsgl_context.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,376 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 macOS - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <unistd.h> | ||||
| #include <math.h> | ||||
|  | ||||
| static void makeContextCurrentNSGL(_GLFWwindow* window) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     if (window) | ||||
|         [window->context.nsgl.object makeCurrentContext]; | ||||
|     else | ||||
|         [NSOpenGLContext clearCurrentContext]; | ||||
|  | ||||
|     _glfwPlatformSetTls(&_glfw.contextSlot, window); | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| static void swapBuffersNSGL(_GLFWwindow* window) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     // HACK: Simulate vsync with usleep as NSGL swap interval does not apply to | ||||
|     //       windows with a non-visible occlusion state | ||||
|     if (window->ns.occluded) | ||||
|     { | ||||
|         int interval = 0; | ||||
|         [window->context.nsgl.object getValues:&interval | ||||
|                                   forParameter:NSOpenGLContextParameterSwapInterval]; | ||||
|  | ||||
|         if (interval > 0) | ||||
|         { | ||||
|             const double framerate = 60.0; | ||||
|             const uint64_t frequency = _glfwPlatformGetTimerFrequency(); | ||||
|             const uint64_t value = _glfwPlatformGetTimerValue(); | ||||
|  | ||||
|             const double elapsed = value / (double) frequency; | ||||
|             const double period = 1.0 / framerate; | ||||
|             const double delay = period - fmod(elapsed, period); | ||||
|  | ||||
|             usleep(floorl(delay * 1e6)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [window->context.nsgl.object flushBuffer]; | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| static void swapIntervalNSGL(int interval) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|     if (window) | ||||
|     { | ||||
|         [window->context.nsgl.object setValues:&interval | ||||
|                                   forParameter:NSOpenGLContextParameterSwapInterval]; | ||||
|     } | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
| static int extensionSupportedNSGL(const char* extension) | ||||
| { | ||||
|     // There are no NSGL extensions | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| static GLFWglproc getProcAddressNSGL(const char* procname) | ||||
| { | ||||
|     CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, | ||||
|                                                        procname, | ||||
|                                                        kCFStringEncodingASCII); | ||||
|  | ||||
|     GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework, | ||||
|                                                           symbolName); | ||||
|  | ||||
|     CFRelease(symbolName); | ||||
|  | ||||
|     return symbol; | ||||
| } | ||||
|  | ||||
| static void destroyContextNSGL(_GLFWwindow* window) | ||||
| { | ||||
|     @autoreleasepool { | ||||
|  | ||||
|     [window->context.nsgl.pixelFormat release]; | ||||
|     window->context.nsgl.pixelFormat = nil; | ||||
|  | ||||
|     [window->context.nsgl.object release]; | ||||
|     window->context.nsgl.object = nil; | ||||
|  | ||||
|     } // autoreleasepool | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialize OpenGL support | ||||
| // | ||||
| GLFWbool _glfwInitNSGL(void) | ||||
| { | ||||
|     if (_glfw.nsgl.framework) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
|     _glfw.nsgl.framework = | ||||
|         CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); | ||||
|     if (_glfw.nsgl.framework == NULL) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "NSGL: Failed to locate OpenGL framework"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Terminate OpenGL support | ||||
| // | ||||
| void _glfwTerminateNSGL(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| // Create the OpenGL context | ||||
| // | ||||
| GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, | ||||
|                                 const _GLFWctxconfig* ctxconfig, | ||||
|                                 const _GLFWfbconfig* fbconfig) | ||||
| { | ||||
|     if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "NSGL: OpenGL ES is not available on macOS"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->major > 2) | ||||
|     { | ||||
|         if (ctxconfig->major == 3 && ctxconfig->minor < 2) | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE) | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Context robustness modes (GL_KHR_robustness) are not yet supported by | ||||
|     // macOS but are not a hard constraint, so ignore and continue | ||||
|  | ||||
|     // Context release behaviors (GL_KHR_context_flush_control) are not yet | ||||
|     // supported by macOS but are not a hard constraint, so ignore and continue | ||||
|  | ||||
|     // Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not | ||||
|     // a hard constraint, so ignore and continue | ||||
|  | ||||
|     // No-error contexts (GL_KHR_no_error) are not yet supported by macOS but | ||||
|     // are not a hard constraint, so ignore and continue | ||||
|  | ||||
| #define addAttrib(a) \ | ||||
| { \ | ||||
|     assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ | ||||
|     attribs[index++] = a; \ | ||||
| } | ||||
| #define setAttrib(a, v) { addAttrib(a); addAttrib(v); } | ||||
|  | ||||
|     NSOpenGLPixelFormatAttribute attribs[40]; | ||||
|     int index = 0; | ||||
|  | ||||
|     addAttrib(NSOpenGLPFAAccelerated); | ||||
|     addAttrib(NSOpenGLPFAClosestPolicy); | ||||
|  | ||||
|     if (ctxconfig->nsgl.offline) | ||||
|     { | ||||
|         addAttrib(NSOpenGLPFAAllowOfflineRenderers); | ||||
|         // NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in | ||||
|         //       Info.plist for unbundled applications | ||||
|         // HACK: This assumes that NSOpenGLPixelFormat will remain | ||||
|         //       a straightforward wrapper of its CGL counterpart | ||||
|         addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching); | ||||
|     } | ||||
|  | ||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 | ||||
|     if (ctxconfig->major >= 4) | ||||
|     { | ||||
|         setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); | ||||
|     } | ||||
|     else | ||||
| #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ | ||||
|     if (ctxconfig->major >= 3) | ||||
|     { | ||||
|         setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->major <= 2) | ||||
|     { | ||||
|         if (fbconfig->auxBuffers != GLFW_DONT_CARE) | ||||
|             setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); | ||||
|  | ||||
|         if (fbconfig->accumRedBits != GLFW_DONT_CARE && | ||||
|             fbconfig->accumGreenBits != GLFW_DONT_CARE && | ||||
|             fbconfig->accumBlueBits != GLFW_DONT_CARE && | ||||
|             fbconfig->accumAlphaBits != GLFW_DONT_CARE) | ||||
|         { | ||||
|             const int accumBits = fbconfig->accumRedBits + | ||||
|                                   fbconfig->accumGreenBits + | ||||
|                                   fbconfig->accumBlueBits + | ||||
|                                   fbconfig->accumAlphaBits; | ||||
|  | ||||
|             setAttrib(NSOpenGLPFAAccumSize, accumBits); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (fbconfig->redBits != GLFW_DONT_CARE && | ||||
|         fbconfig->greenBits != GLFW_DONT_CARE && | ||||
|         fbconfig->blueBits != GLFW_DONT_CARE) | ||||
|     { | ||||
|         int colorBits = fbconfig->redBits + | ||||
|                         fbconfig->greenBits + | ||||
|                         fbconfig->blueBits; | ||||
|  | ||||
|         // macOS needs non-zero color size, so set reasonable values | ||||
|         if (colorBits == 0) | ||||
|             colorBits = 24; | ||||
|         else if (colorBits < 15) | ||||
|             colorBits = 15; | ||||
|  | ||||
|         setAttrib(NSOpenGLPFAColorSize, colorBits); | ||||
|     } | ||||
|  | ||||
|     if (fbconfig->alphaBits != GLFW_DONT_CARE) | ||||
|         setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); | ||||
|  | ||||
|     if (fbconfig->depthBits != GLFW_DONT_CARE) | ||||
|         setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits); | ||||
|  | ||||
|     if (fbconfig->stencilBits != GLFW_DONT_CARE) | ||||
|         setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits); | ||||
|  | ||||
|     if (fbconfig->stereo) | ||||
|     { | ||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 | ||||
|         _glfwInputError(GLFW_FORMAT_UNAVAILABLE, | ||||
|                         "NSGL: Stereo rendering is deprecated"); | ||||
|         return GLFW_FALSE; | ||||
| #else | ||||
|         addAttrib(NSOpenGLPFAStereo); | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     if (fbconfig->doublebuffer) | ||||
|         addAttrib(NSOpenGLPFADoubleBuffer); | ||||
|  | ||||
|     if (fbconfig->samples != GLFW_DONT_CARE) | ||||
|     { | ||||
|         if (fbconfig->samples == 0) | ||||
|         { | ||||
|             setAttrib(NSOpenGLPFASampleBuffers, 0); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             setAttrib(NSOpenGLPFASampleBuffers, 1); | ||||
|             setAttrib(NSOpenGLPFASamples, fbconfig->samples); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB | ||||
|     //       framebuffer, so there's no need (and no way) to request it | ||||
|  | ||||
|     addAttrib(0); | ||||
|  | ||||
| #undef addAttrib | ||||
| #undef setAttrib | ||||
|  | ||||
|     window->context.nsgl.pixelFormat = | ||||
|         [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; | ||||
|     if (window->context.nsgl.pixelFormat == nil) | ||||
|     { | ||||
|         _glfwInputError(GLFW_FORMAT_UNAVAILABLE, | ||||
|                         "NSGL: Failed to find a suitable pixel format"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     NSOpenGLContext* share = nil; | ||||
|  | ||||
|     if (ctxconfig->share) | ||||
|         share = ctxconfig->share->context.nsgl.object; | ||||
|  | ||||
|     window->context.nsgl.object = | ||||
|         [[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat | ||||
|                                    shareContext:share]; | ||||
|     if (window->context.nsgl.object == nil) | ||||
|     { | ||||
|         _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                         "NSGL: Failed to create OpenGL context"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (fbconfig->transparent) | ||||
|     { | ||||
|         GLint opaque = 0; | ||||
|         [window->context.nsgl.object setValues:&opaque | ||||
|                                   forParameter:NSOpenGLContextParameterSurfaceOpacity]; | ||||
|     } | ||||
|  | ||||
|     [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina]; | ||||
|  | ||||
|     [window->context.nsgl.object setView:window->ns.view]; | ||||
|  | ||||
|     window->context.makeCurrent = makeContextCurrentNSGL; | ||||
|     window->context.swapBuffers = swapBuffersNSGL; | ||||
|     window->context.swapInterval = swapIntervalNSGL; | ||||
|     window->context.extensionSupported = extensionSupportedNSGL; | ||||
|     window->context.getProcAddress = getProcAddressNSGL; | ||||
|     window->context.destroy = destroyContextNSGL; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(nil); | ||||
|  | ||||
|     if (window->context.source != GLFW_NATIVE_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return nil; | ||||
|     } | ||||
|  | ||||
|     return window->context.nsgl.object; | ||||
| } | ||||
|  | ||||
							
								
								
									
										52
									
								
								deps/glfw/src/null_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								deps/glfw/src/null_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2016 Google Inc. | ||||
| // Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformInit(void) | ||||
| { | ||||
|     _glfwInitTimerPOSIX(); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformTerminate(void) | ||||
| { | ||||
|     _glfwTerminateOSMesa(); | ||||
| } | ||||
|  | ||||
| const char* _glfwPlatformGetVersionString(void) | ||||
| { | ||||
|     return _GLFW_VERSION_NUMBER " null OSMesa"; | ||||
| } | ||||
|  | ||||
							
								
								
									
										44
									
								
								deps/glfw/src/null_joystick.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								deps/glfw/src/null_joystick.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformUpdateGamepadGUID(char* guid) | ||||
| { | ||||
| } | ||||
|  | ||||
							
								
								
									
										31
									
								
								deps/glfw/src/null_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								deps/glfw/src/null_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #define _GLFW_PLATFORM_JOYSTICK_STATE         struct { int dummyJoystick; } | ||||
| #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; } | ||||
|  | ||||
| #define _GLFW_PLATFORM_MAPPING_NAME "" | ||||
|  | ||||
							
								
								
									
										77
									
								
								deps/glfw/src/null_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								deps/glfw/src/null_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2016 Google Inc. | ||||
| // Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, | ||||
|                                          float* xscale, float* yscale) | ||||
| { | ||||
|     if (xscale) | ||||
|         *xscale = 1.f; | ||||
|     if (yscale) | ||||
|         *yscale = 1.f; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, | ||||
|                                      int* xpos, int* ypos, | ||||
|                                      int* width, int* height) | ||||
| { | ||||
| } | ||||
|  | ||||
| GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) | ||||
| { | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) | ||||
| { | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) | ||||
| { | ||||
| } | ||||
|  | ||||
							
								
								
									
										62
									
								
								deps/glfw/src/null_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								deps/glfw/src/null_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2016 Google Inc. | ||||
| // Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #include <dlfcn.h> | ||||
|  | ||||
| #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null | ||||
|  | ||||
| #define _GLFW_PLATFORM_CONTEXT_STATE         struct { int dummyContext; } | ||||
| #define _GLFW_PLATFORM_MONITOR_STATE         struct { int dummyMonitor; } | ||||
| #define _GLFW_PLATFORM_CURSOR_STATE          struct { int dummyCursor; } | ||||
| #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE  struct { int dummyLibraryWindow; } | ||||
| #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; } | ||||
| #define _GLFW_EGL_CONTEXT_STATE              struct { int dummyEGLContext; } | ||||
| #define _GLFW_EGL_LIBRARY_CONTEXT_STATE      struct { int dummyEGLLibraryContext; } | ||||
|  | ||||
| #include "osmesa_context.h" | ||||
| #include "posix_time.h" | ||||
| #include "posix_thread.h" | ||||
| #include "null_joystick.h" | ||||
|  | ||||
| #if defined(_GLFW_WIN32) | ||||
|  #define _glfw_dlopen(name) LoadLibraryA(name) | ||||
|  #define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) | ||||
|  #define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) | ||||
| #else | ||||
|  #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) | ||||
|  #define _glfw_dlclose(handle) dlclose(handle) | ||||
|  #define _glfw_dlsym(handle, name) dlsym(handle, name) | ||||
| #endif | ||||
|  | ||||
| // Null-specific per-window data | ||||
| // | ||||
| typedef struct _GLFWwindowNull | ||||
| { | ||||
|     int width; | ||||
|     int height; | ||||
| } _GLFWwindowNull; | ||||
|  | ||||
							
								
								
									
										332
									
								
								deps/glfw/src/null_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										332
									
								
								deps/glfw/src/null_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,332 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2016 Google Inc. | ||||
| // Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
|  | ||||
| static int createNativeWindow(_GLFWwindow* window, | ||||
|                               const _GLFWwndconfig* wndconfig) | ||||
| { | ||||
|     window->null.width = wndconfig->width; | ||||
|     window->null.height = wndconfig->height; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformCreateWindow(_GLFWwindow* window, | ||||
|                               const _GLFWwndconfig* wndconfig, | ||||
|                               const _GLFWctxconfig* ctxconfig, | ||||
|                               const _GLFWfbconfig* fbconfig) | ||||
| { | ||||
|     if (!createNativeWindow(window, wndconfig)) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     if (ctxconfig->client != GLFW_NO_API) | ||||
|     { | ||||
|         if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API || | ||||
|             ctxconfig->source == GLFW_OSMESA_CONTEXT_API) | ||||
|         { | ||||
|             if (!_glfwInitOSMesa()) | ||||
|                 return GLFW_FALSE; | ||||
|             if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) | ||||
|                 return GLFW_FALSE; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformDestroyWindow(_GLFWwindow* window) | ||||
| { | ||||
|     if (window->context.destroy) | ||||
|         window->context.destroy(window); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, | ||||
|                                 const GLFWimage* images) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, | ||||
|                                    _GLFWmonitor* monitor, | ||||
|                                    int xpos, int ypos, | ||||
|                                    int width, int height, | ||||
|                                    int refreshRate) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) | ||||
| { | ||||
|     if (width) | ||||
|         *width = window->null.width; | ||||
|     if (height) | ||||
|         *height = window->null.height; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) | ||||
| { | ||||
|     window->null.width = width; | ||||
|     window->null.height = height; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, | ||||
|                                       int minwidth, int minheight, | ||||
|                                       int maxwidth, int maxheight) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) | ||||
| { | ||||
|     if (width) | ||||
|         *width = window->null.width; | ||||
|     if (height) | ||||
|         *height = window->null.height; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, | ||||
|                                      int* left, int* top, | ||||
|                                      int* right, int* bottom) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, | ||||
|                                         float* xscale, float* yscale) | ||||
| { | ||||
|     if (xscale) | ||||
|         *xscale = 1.f; | ||||
|     if (yscale) | ||||
|         *yscale = 1.f; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformIconifyWindow(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformRestoreWindow(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformMaximizeWindow(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
| int _glfwPlatformWindowMaximized(_GLFWwindow* window) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| int _glfwPlatformWindowHovered(_GLFWwindow* window) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) | ||||
| { | ||||
| } | ||||
|  | ||||
| float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) | ||||
| { | ||||
|     return 1.f; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) | ||||
| { | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformRawMouseMotionSupported(void) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformShowWindow(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformUnhideWindow(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformHideWindow(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformFocusWindow(_GLFWwindow* window) | ||||
| { | ||||
| } | ||||
|  | ||||
| int _glfwPlatformWindowFocused(_GLFWwindow* window) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| int _glfwPlatformWindowIconified(_GLFWwindow* window) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| int _glfwPlatformWindowVisible(_GLFWwindow* window) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformPollEvents(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformWaitEvents(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformWaitEventsTimeout(double timeout) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformPostEmptyEvent(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) | ||||
| { | ||||
| } | ||||
|  | ||||
| int _glfwPlatformCreateCursor(_GLFWcursor* cursor, | ||||
|                               const GLFWimage* image, | ||||
|                               int xhot, int yhot) | ||||
| { | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) | ||||
| { | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetClipboardString(const char* string) | ||||
| { | ||||
| } | ||||
|  | ||||
| const char* _glfwPlatformGetClipboardString(void) | ||||
| { | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| const char* _glfwPlatformGetScancodeName(int scancode) | ||||
| { | ||||
|     return ""; | ||||
| } | ||||
|  | ||||
| int _glfwPlatformGetKeyScancode(int key) | ||||
| { | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) | ||||
| { | ||||
| } | ||||
|  | ||||
| int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, | ||||
|                                                       VkPhysicalDevice device, | ||||
|                                                       uint32_t queuefamily) | ||||
| { | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, | ||||
|                                           _GLFWwindow* window, | ||||
|                                           const VkAllocationCallbacks* allocator, | ||||
|                                           VkSurfaceKHR* surface) | ||||
| { | ||||
|     // This seems like the most appropriate error to return here | ||||
|     return VK_ERROR_INITIALIZATION_FAILED; | ||||
| } | ||||
|  | ||||
							
								
								
									
										384
									
								
								deps/glfw/src/osmesa_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										384
									
								
								deps/glfw/src/osmesa_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,384 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 OSMesa - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2016 Google Inc. | ||||
| // Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
|  | ||||
| static void makeContextCurrentOSMesa(_GLFWwindow* window) | ||||
| { | ||||
|     if (window) | ||||
|     { | ||||
|         int width, height; | ||||
|         _glfwPlatformGetFramebufferSize(window, &width, &height); | ||||
|  | ||||
|         // Check to see if we need to allocate a new buffer | ||||
|         if ((window->context.osmesa.buffer == NULL) || | ||||
|             (width != window->context.osmesa.width) || | ||||
|             (height != window->context.osmesa.height)) | ||||
|         { | ||||
|             free(window->context.osmesa.buffer); | ||||
|  | ||||
|             // Allocate the new buffer (width * height * 8-bit RGBA) | ||||
|             window->context.osmesa.buffer = calloc(4, (size_t) width * height); | ||||
|             window->context.osmesa.width  = width; | ||||
|             window->context.osmesa.height = height; | ||||
|         } | ||||
|  | ||||
|         if (!OSMesaMakeCurrent(window->context.osmesa.handle, | ||||
|                                window->context.osmesa.buffer, | ||||
|                                GL_UNSIGNED_BYTE, | ||||
|                                width, height)) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "OSMesa: Failed to make context current"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _glfwPlatformSetTls(&_glfw.contextSlot, window); | ||||
| } | ||||
|  | ||||
| static GLFWglproc getProcAddressOSMesa(const char* procname) | ||||
| { | ||||
|     return (GLFWglproc) OSMesaGetProcAddress(procname); | ||||
| } | ||||
|  | ||||
| static void destroyContextOSMesa(_GLFWwindow* window) | ||||
| { | ||||
|     if (window->context.osmesa.handle) | ||||
|     { | ||||
|         OSMesaDestroyContext(window->context.osmesa.handle); | ||||
|         window->context.osmesa.handle = NULL; | ||||
|     } | ||||
|  | ||||
|     if (window->context.osmesa.buffer) | ||||
|     { | ||||
|         free(window->context.osmesa.buffer); | ||||
|         window->context.osmesa.width = 0; | ||||
|         window->context.osmesa.height = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void swapBuffersOSMesa(_GLFWwindow* window) | ||||
| { | ||||
|     // No double buffering on OSMesa | ||||
| } | ||||
|  | ||||
| static void swapIntervalOSMesa(int interval) | ||||
| { | ||||
|     // No swap interval on OSMesa | ||||
| } | ||||
|  | ||||
| static int extensionSupportedOSMesa(const char* extension) | ||||
| { | ||||
|     // OSMesa does not have extensions | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWbool _glfwInitOSMesa(void) | ||||
| { | ||||
|     int i; | ||||
|     const char* sonames[] = | ||||
|     { | ||||
| #if defined(_GLFW_OSMESA_LIBRARY) | ||||
|         _GLFW_OSMESA_LIBRARY, | ||||
| #elif defined(_WIN32) | ||||
|         "libOSMesa.dll", | ||||
|         "OSMesa.dll", | ||||
| #elif defined(__APPLE__) | ||||
|         "libOSMesa.8.dylib", | ||||
| #elif defined(__CYGWIN__) | ||||
|         "libOSMesa-8.so", | ||||
| #else | ||||
|         "libOSMesa.so.8", | ||||
|         "libOSMesa.so.6", | ||||
| #endif | ||||
|         NULL | ||||
|     }; | ||||
|  | ||||
|     if (_glfw.osmesa.handle) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
|     for (i = 0;  sonames[i];  i++) | ||||
|     { | ||||
|         _glfw.osmesa.handle = _glfw_dlopen(sonames[i]); | ||||
|         if (_glfw.osmesa.handle) | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     if (!_glfw.osmesa.handle) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt) | ||||
|         _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt"); | ||||
|     _glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs) | ||||
|         _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs"); | ||||
|     _glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext) | ||||
|         _glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext"); | ||||
|     _glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent) | ||||
|         _glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent"); | ||||
|     _glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer) | ||||
|         _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer"); | ||||
|     _glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer) | ||||
|         _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer"); | ||||
|     _glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress) | ||||
|         _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress"); | ||||
|  | ||||
|     if (!_glfw.osmesa.CreateContextExt || | ||||
|         !_glfw.osmesa.DestroyContext || | ||||
|         !_glfw.osmesa.MakeCurrent || | ||||
|         !_glfw.osmesa.GetColorBuffer || | ||||
|         !_glfw.osmesa.GetDepthBuffer || | ||||
|         !_glfw.osmesa.GetProcAddress) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "OSMesa: Failed to load required entry points"); | ||||
|  | ||||
|         _glfwTerminateOSMesa(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwTerminateOSMesa(void) | ||||
| { | ||||
|     if (_glfw.osmesa.handle) | ||||
|     { | ||||
|         _glfw_dlclose(_glfw.osmesa.handle); | ||||
|         _glfw.osmesa.handle = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #define setAttrib(a, v) \ | ||||
| { \ | ||||
|     assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ | ||||
|     attribs[index++] = a; \ | ||||
|     attribs[index++] = v; \ | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, | ||||
|                                   const _GLFWctxconfig* ctxconfig, | ||||
|                                   const _GLFWfbconfig* fbconfig) | ||||
| { | ||||
|     OSMesaContext share = NULL; | ||||
|     const int accumBits = fbconfig->accumRedBits + | ||||
|                           fbconfig->accumGreenBits + | ||||
|                           fbconfig->accumBlueBits + | ||||
|                           fbconfig->accumAlphaBits; | ||||
|  | ||||
|     if (ctxconfig->client == GLFW_OPENGL_ES_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "OSMesa: OpenGL ES is not available on OSMesa"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->share) | ||||
|         share = ctxconfig->share->context.osmesa.handle; | ||||
|  | ||||
|     if (OSMesaCreateContextAttribs) | ||||
|     { | ||||
|         int index = 0, attribs[40]; | ||||
|  | ||||
|         setAttrib(OSMESA_FORMAT, OSMESA_RGBA); | ||||
|         setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits); | ||||
|         setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits); | ||||
|         setAttrib(OSMESA_ACCUM_BITS, accumBits); | ||||
|  | ||||
|         if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) | ||||
|         { | ||||
|             setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE); | ||||
|         } | ||||
|         else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) | ||||
|         { | ||||
|             setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE); | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->major != 1 || ctxconfig->minor != 0) | ||||
|         { | ||||
|             setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major); | ||||
|             setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor); | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->forward) | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "OSMesa: Forward-compatible contexts not supported"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         setAttrib(0, 0); | ||||
|  | ||||
|         window->context.osmesa.handle = | ||||
|             OSMesaCreateContextAttribs(attribs, share); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (ctxconfig->profile) | ||||
|         { | ||||
|             _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                             "OSMesa: OpenGL profiles unavailable"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         window->context.osmesa.handle = | ||||
|             OSMesaCreateContextExt(OSMESA_RGBA, | ||||
|                                    fbconfig->depthBits, | ||||
|                                    fbconfig->stencilBits, | ||||
|                                    accumBits, | ||||
|                                    share); | ||||
|     } | ||||
|  | ||||
|     if (window->context.osmesa.handle == NULL) | ||||
|     { | ||||
|         _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                         "OSMesa: Failed to create context"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     window->context.makeCurrent = makeContextCurrentOSMesa; | ||||
|     window->context.swapBuffers = swapBuffersOSMesa; | ||||
|     window->context.swapInterval = swapIntervalOSMesa; | ||||
|     window->context.extensionSupported = extensionSupportedOSMesa; | ||||
|     window->context.getProcAddress = getProcAddressOSMesa; | ||||
|     window->context.destroy = destroyContextOSMesa; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| #undef setAttrib | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width, | ||||
|                                      int* height, int* format, void** buffer) | ||||
| { | ||||
|     void* mesaBuffer; | ||||
|     GLint mesaWidth, mesaHeight, mesaFormat; | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     assert(window != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); | ||||
|  | ||||
|     if (window->context.source != GLFW_OSMESA_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (!OSMesaGetColorBuffer(window->context.osmesa.handle, | ||||
|                               &mesaWidth, &mesaHeight, | ||||
|                               &mesaFormat, &mesaBuffer)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "OSMesa: Failed to retrieve color buffer"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (width) | ||||
|         *width = mesaWidth; | ||||
|     if (height) | ||||
|         *height = mesaHeight; | ||||
|     if (format) | ||||
|         *format = mesaFormat; | ||||
|     if (buffer) | ||||
|         *buffer = mesaBuffer; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle, | ||||
|                                      int* width, int* height, | ||||
|                                      int* bytesPerValue, | ||||
|                                      void** buffer) | ||||
| { | ||||
|     void* mesaBuffer; | ||||
|     GLint mesaWidth, mesaHeight, mesaBytes; | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     assert(window != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); | ||||
|  | ||||
|     if (window->context.source != GLFW_OSMESA_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (!OSMesaGetDepthBuffer(window->context.osmesa.handle, | ||||
|                               &mesaWidth, &mesaHeight, | ||||
|                               &mesaBytes, &mesaBuffer)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "OSMesa: Failed to retrieve depth buffer"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (width) | ||||
|         *width = mesaWidth; | ||||
|     if (height) | ||||
|         *height = mesaHeight; | ||||
|     if (bytesPerValue) | ||||
|         *bytesPerValue = mesaBytes; | ||||
|     if (buffer) | ||||
|         *buffer = mesaBuffer; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     if (window->context.source != GLFW_OSMESA_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     return window->context.osmesa.handle; | ||||
| } | ||||
|  | ||||
							
								
								
									
										92
									
								
								deps/glfw/src/osmesa_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								deps/glfw/src/osmesa_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 OSMesa - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2016 Google Inc. | ||||
| // Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #define OSMESA_RGBA 0x1908 | ||||
| #define OSMESA_FORMAT 0x22 | ||||
| #define OSMESA_DEPTH_BITS 0x30 | ||||
| #define OSMESA_STENCIL_BITS 0x31 | ||||
| #define OSMESA_ACCUM_BITS 0x32 | ||||
| #define OSMESA_PROFILE 0x33 | ||||
| #define OSMESA_CORE_PROFILE 0x34 | ||||
| #define OSMESA_COMPAT_PROFILE 0x35 | ||||
| #define OSMESA_CONTEXT_MAJOR_VERSION 0x36 | ||||
| #define OSMESA_CONTEXT_MINOR_VERSION 0x37 | ||||
|  | ||||
| typedef void* OSMesaContext; | ||||
| typedef void (*OSMESAproc)(void); | ||||
|  | ||||
| typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext); | ||||
| typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext); | ||||
| typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext); | ||||
| typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int); | ||||
| typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**); | ||||
| typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**); | ||||
| typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*); | ||||
| #define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt | ||||
| #define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs | ||||
| #define OSMesaDestroyContext _glfw.osmesa.DestroyContext | ||||
| #define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent | ||||
| #define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer | ||||
| #define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer | ||||
| #define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress | ||||
|  | ||||
| #define _GLFW_OSMESA_CONTEXT_STATE              _GLFWcontextOSMesa osmesa | ||||
| #define _GLFW_OSMESA_LIBRARY_CONTEXT_STATE      _GLFWlibraryOSMesa osmesa | ||||
|  | ||||
|  | ||||
| // OSMesa-specific per-context data | ||||
| // | ||||
| typedef struct _GLFWcontextOSMesa | ||||
| { | ||||
|     OSMesaContext       handle; | ||||
|     int                 width; | ||||
|     int                 height; | ||||
|     void*               buffer; | ||||
| } _GLFWcontextOSMesa; | ||||
|  | ||||
| // OSMesa-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryOSMesa | ||||
| { | ||||
|     void*           handle; | ||||
|  | ||||
|     PFN_OSMesaCreateContextExt      CreateContextExt; | ||||
|     PFN_OSMesaCreateContextAttribs  CreateContextAttribs; | ||||
|     PFN_OSMesaDestroyContext        DestroyContext; | ||||
|     PFN_OSMesaMakeCurrent           MakeCurrent; | ||||
|     PFN_OSMesaGetColorBuffer        GetColorBuffer; | ||||
|     PFN_OSMesaGetDepthBuffer        GetDepthBuffer; | ||||
|     PFN_OSMesaGetProcAddress        GetProcAddress; | ||||
| } _GLFWlibraryOSMesa; | ||||
|  | ||||
|  | ||||
| GLFWbool _glfwInitOSMesa(void); | ||||
| void _glfwTerminateOSMesa(void); | ||||
| GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, | ||||
|                                   const _GLFWctxconfig* ctxconfig, | ||||
|                                   const _GLFWfbconfig* fbconfig); | ||||
|  | ||||
							
								
								
									
										105
									
								
								deps/glfw/src/posix_thread.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								deps/glfw/src/posix_thread.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 POSIX - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <string.h> | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls) | ||||
| { | ||||
|     assert(tls->posix.allocated == GLFW_FALSE); | ||||
|  | ||||
|     if (pthread_key_create(&tls->posix.key, NULL) != 0) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "POSIX: Failed to create context TLS"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     tls->posix.allocated = GLFW_TRUE; | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformDestroyTls(_GLFWtls* tls) | ||||
| { | ||||
|     if (tls->posix.allocated) | ||||
|         pthread_key_delete(tls->posix.key); | ||||
|     memset(tls, 0, sizeof(_GLFWtls)); | ||||
| } | ||||
|  | ||||
| void* _glfwPlatformGetTls(_GLFWtls* tls) | ||||
| { | ||||
|     assert(tls->posix.allocated == GLFW_TRUE); | ||||
|     return pthread_getspecific(tls->posix.key); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetTls(_GLFWtls* tls, void* value) | ||||
| { | ||||
|     assert(tls->posix.allocated == GLFW_TRUE); | ||||
|     pthread_setspecific(tls->posix.key, value); | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     assert(mutex->posix.allocated == GLFW_FALSE); | ||||
|  | ||||
|     if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     return mutex->posix.allocated = GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformDestroyMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     if (mutex->posix.allocated) | ||||
|         pthread_mutex_destroy(&mutex->posix.handle); | ||||
|     memset(mutex, 0, sizeof(_GLFWmutex)); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformLockMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     assert(mutex->posix.allocated == GLFW_TRUE); | ||||
|     pthread_mutex_lock(&mutex->posix.handle); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformUnlockMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     assert(mutex->posix.allocated == GLFW_TRUE); | ||||
|     pthread_mutex_unlock(&mutex->posix.handle); | ||||
| } | ||||
|  | ||||
							
								
								
									
										49
									
								
								deps/glfw/src/posix_thread.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								deps/glfw/src/posix_thread.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 POSIX - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #include <pthread.h> | ||||
|  | ||||
| #define _GLFW_PLATFORM_TLS_STATE    _GLFWtlsPOSIX   posix | ||||
| #define _GLFW_PLATFORM_MUTEX_STATE  _GLFWmutexPOSIX posix | ||||
|  | ||||
|  | ||||
| // POSIX-specific thread local storage data | ||||
| // | ||||
| typedef struct _GLFWtlsPOSIX | ||||
| { | ||||
|     GLFWbool        allocated; | ||||
|     pthread_key_t   key; | ||||
| } _GLFWtlsPOSIX; | ||||
|  | ||||
| // POSIX-specific mutex data | ||||
| // | ||||
| typedef struct _GLFWmutexPOSIX | ||||
| { | ||||
|     GLFWbool        allocated; | ||||
|     pthread_mutex_t handle; | ||||
| } _GLFWmutexPOSIX; | ||||
|  | ||||
							
								
								
									
										87
									
								
								deps/glfw/src/posix_time.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								deps/glfw/src/posix_time.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 POSIX - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <sys/time.h> | ||||
| #include <time.h> | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialise timer | ||||
| // | ||||
| void _glfwInitTimerPOSIX(void) | ||||
| { | ||||
| #if defined(CLOCK_MONOTONIC) | ||||
|     struct timespec ts; | ||||
|  | ||||
|     if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) | ||||
|     { | ||||
|         _glfw.timer.posix.monotonic = GLFW_TRUE; | ||||
|         _glfw.timer.posix.frequency = 1000000000; | ||||
|     } | ||||
|     else | ||||
| #endif | ||||
|     { | ||||
|         _glfw.timer.posix.monotonic = GLFW_FALSE; | ||||
|         _glfw.timer.posix.frequency = 1000000; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| uint64_t _glfwPlatformGetTimerValue(void) | ||||
| { | ||||
| #if defined(CLOCK_MONOTONIC) | ||||
|     if (_glfw.timer.posix.monotonic) | ||||
|     { | ||||
|         struct timespec ts; | ||||
|         clock_gettime(CLOCK_MONOTONIC, &ts); | ||||
|         return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; | ||||
|     } | ||||
|     else | ||||
| #endif | ||||
|     { | ||||
|         struct timeval tv; | ||||
|         gettimeofday(&tv, NULL); | ||||
|         return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; | ||||
|     } | ||||
| } | ||||
|  | ||||
| uint64_t _glfwPlatformGetTimerFrequency(void) | ||||
| { | ||||
|     return _glfw.timer.posix.frequency; | ||||
| } | ||||
|  | ||||
							
								
								
									
										43
									
								
								deps/glfw/src/posix_time.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								deps/glfw/src/posix_time.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 POSIX - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
|  | ||||
| // POSIX-specific global timer data | ||||
| // | ||||
| typedef struct _GLFWtimerPOSIX | ||||
| { | ||||
|     GLFWbool    monotonic; | ||||
|     uint64_t    frequency; | ||||
| } _GLFWtimerPOSIX; | ||||
|  | ||||
|  | ||||
| void _glfwInitTimerPOSIX(void); | ||||
|  | ||||
							
								
								
									
										332
									
								
								deps/glfw/src/vulkan.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										332
									
								
								deps/glfw/src/vulkan.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,332 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #define _GLFW_FIND_LOADER    1 | ||||
| #define _GLFW_REQUIRE_LOADER 2 | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWbool _glfwInitVulkan(int mode) | ||||
| { | ||||
|     VkResult err; | ||||
|     VkExtensionProperties* ep; | ||||
|     uint32_t i, count; | ||||
|  | ||||
|     if (_glfw.vk.available) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
| #if !defined(_GLFW_VULKAN_STATIC) | ||||
| #if defined(_GLFW_VULKAN_LIBRARY) | ||||
|     _glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY); | ||||
| #elif defined(_GLFW_WIN32) | ||||
|     _glfw.vk.handle = _glfw_dlopen("vulkan-1.dll"); | ||||
| #elif defined(_GLFW_COCOA) | ||||
|     _glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib"); | ||||
|     if (!_glfw.vk.handle) | ||||
|         _glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS(); | ||||
| #else | ||||
|     _glfw.vk.handle = _glfw_dlopen("libvulkan.so.1"); | ||||
| #endif | ||||
|     if (!_glfw.vk.handle) | ||||
|     { | ||||
|         if (mode == _GLFW_REQUIRE_LOADER) | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); | ||||
|  | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) | ||||
|         _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr"); | ||||
|     if (!_glfw.vk.GetInstanceProcAddr) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "Vulkan: Loader does not export vkGetInstanceProcAddr"); | ||||
|  | ||||
|         _glfwTerminateVulkan(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) | ||||
|         vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties"); | ||||
|     if (!_glfw.vk.EnumerateInstanceExtensionProperties) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties"); | ||||
|  | ||||
|         _glfwTerminateVulkan(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
| #endif // _GLFW_VULKAN_STATIC | ||||
|  | ||||
|     err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); | ||||
|     if (err) | ||||
|     { | ||||
|         // NOTE: This happens on systems with a loader but without any Vulkan ICD | ||||
|         if (mode == _GLFW_REQUIRE_LOADER) | ||||
|         { | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                             "Vulkan: Failed to query instance extension count: %s", | ||||
|                             _glfwGetVulkanResultString(err)); | ||||
|         } | ||||
|  | ||||
|         _glfwTerminateVulkan(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     ep = calloc(count, sizeof(VkExtensionProperties)); | ||||
|  | ||||
|     err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep); | ||||
|     if (err) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "Vulkan: Failed to query instance extensions: %s", | ||||
|                         _glfwGetVulkanResultString(err)); | ||||
|  | ||||
|         free(ep); | ||||
|         _glfwTerminateVulkan(); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     for (i = 0;  i < count;  i++) | ||||
|     { | ||||
|         if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0) | ||||
|             _glfw.vk.KHR_surface = GLFW_TRUE; | ||||
| #if defined(_GLFW_WIN32) | ||||
|         else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) | ||||
|             _glfw.vk.KHR_win32_surface = GLFW_TRUE; | ||||
| #elif defined(_GLFW_COCOA) | ||||
|         else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0) | ||||
|             _glfw.vk.MVK_macos_surface = GLFW_TRUE; | ||||
|         else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0) | ||||
|             _glfw.vk.EXT_metal_surface = GLFW_TRUE; | ||||
| #elif defined(_GLFW_X11) | ||||
|         else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) | ||||
|             _glfw.vk.KHR_xlib_surface = GLFW_TRUE; | ||||
|         else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0) | ||||
|             _glfw.vk.KHR_xcb_surface = GLFW_TRUE; | ||||
| #elif defined(_GLFW_WAYLAND) | ||||
|         else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) | ||||
|             _glfw.vk.KHR_wayland_surface = GLFW_TRUE; | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     free(ep); | ||||
|  | ||||
|     _glfw.vk.available = GLFW_TRUE; | ||||
|  | ||||
|     _glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions); | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwTerminateVulkan(void) | ||||
| { | ||||
| #if !defined(_GLFW_VULKAN_STATIC) | ||||
|     if (_glfw.vk.handle) | ||||
|         _glfw_dlclose(_glfw.vk.handle); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| const char* _glfwGetVulkanResultString(VkResult result) | ||||
| { | ||||
|     switch (result) | ||||
|     { | ||||
|         case VK_SUCCESS: | ||||
|             return "Success"; | ||||
|         case VK_NOT_READY: | ||||
|             return "A fence or query has not yet completed"; | ||||
|         case VK_TIMEOUT: | ||||
|             return "A wait operation has not completed in the specified time"; | ||||
|         case VK_EVENT_SET: | ||||
|             return "An event is signaled"; | ||||
|         case VK_EVENT_RESET: | ||||
|             return "An event is unsignaled"; | ||||
|         case VK_INCOMPLETE: | ||||
|             return "A return array was too small for the result"; | ||||
|         case VK_ERROR_OUT_OF_HOST_MEMORY: | ||||
|             return "A host memory allocation has failed"; | ||||
|         case VK_ERROR_OUT_OF_DEVICE_MEMORY: | ||||
|             return "A device memory allocation has failed"; | ||||
|         case VK_ERROR_INITIALIZATION_FAILED: | ||||
|             return "Initialization of an object could not be completed for implementation-specific reasons"; | ||||
|         case VK_ERROR_DEVICE_LOST: | ||||
|             return "The logical or physical device has been lost"; | ||||
|         case VK_ERROR_MEMORY_MAP_FAILED: | ||||
|             return "Mapping of a memory object has failed"; | ||||
|         case VK_ERROR_LAYER_NOT_PRESENT: | ||||
|             return "A requested layer is not present or could not be loaded"; | ||||
|         case VK_ERROR_EXTENSION_NOT_PRESENT: | ||||
|             return "A requested extension is not supported"; | ||||
|         case VK_ERROR_FEATURE_NOT_PRESENT: | ||||
|             return "A requested feature is not supported"; | ||||
|         case VK_ERROR_INCOMPATIBLE_DRIVER: | ||||
|             return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible"; | ||||
|         case VK_ERROR_TOO_MANY_OBJECTS: | ||||
|             return "Too many objects of the type have already been created"; | ||||
|         case VK_ERROR_FORMAT_NOT_SUPPORTED: | ||||
|             return "A requested format is not supported on this device"; | ||||
|         case VK_ERROR_SURFACE_LOST_KHR: | ||||
|             return "A surface is no longer available"; | ||||
|         case VK_SUBOPTIMAL_KHR: | ||||
|             return "A swapchain no longer matches the surface properties exactly, but can still be used"; | ||||
|         case VK_ERROR_OUT_OF_DATE_KHR: | ||||
|             return "A surface has changed in such a way that it is no longer compatible with the swapchain"; | ||||
|         case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: | ||||
|             return "The display used by a swapchain does not use the same presentable image layout"; | ||||
|         case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: | ||||
|             return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API"; | ||||
|         case VK_ERROR_VALIDATION_FAILED_EXT: | ||||
|             return "A validation layer found an error"; | ||||
|         default: | ||||
|             return "ERROR: UNKNOWN VULKAN ERROR"; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW public API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI int glfwVulkanSupported(void) | ||||
| { | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); | ||||
|     return _glfwInitVulkan(_GLFW_FIND_LOADER); | ||||
| } | ||||
|  | ||||
| GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count) | ||||
| { | ||||
|     assert(count != NULL); | ||||
|  | ||||
|     *count = 0; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) | ||||
|         return NULL; | ||||
|  | ||||
|     if (!_glfw.vk.extensions[0]) | ||||
|         return NULL; | ||||
|  | ||||
|     *count = 2; | ||||
|     return (const char**) _glfw.vk.extensions; | ||||
| } | ||||
|  | ||||
| GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, | ||||
|                                               const char* procname) | ||||
| { | ||||
|     GLFWvkproc proc; | ||||
|     assert(procname != NULL); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) | ||||
|         return NULL; | ||||
|  | ||||
|     proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname); | ||||
| #if defined(_GLFW_VULKAN_STATIC) | ||||
|     if (!proc) | ||||
|     { | ||||
|         if (strcmp(procname, "vkGetInstanceProcAddr") == 0) | ||||
|             return (GLFWvkproc) vkGetInstanceProcAddr; | ||||
|     } | ||||
| #else | ||||
|     if (!proc) | ||||
|         proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname); | ||||
| #endif | ||||
|  | ||||
|     return proc; | ||||
| } | ||||
|  | ||||
| GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, | ||||
|                                                      VkPhysicalDevice device, | ||||
|                                                      uint32_t queuefamily) | ||||
| { | ||||
|     assert(instance != VK_NULL_HANDLE); | ||||
|     assert(device != VK_NULL_HANDLE); | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); | ||||
|  | ||||
|     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     if (!_glfw.vk.extensions[0]) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "Vulkan: Window surface creation extensions not found"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     return _glfwPlatformGetPhysicalDevicePresentationSupport(instance, | ||||
|                                                              device, | ||||
|                                                              queuefamily); | ||||
| } | ||||
|  | ||||
| GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, | ||||
|                                          GLFWwindow* handle, | ||||
|                                          const VkAllocationCallbacks* allocator, | ||||
|                                          VkSurfaceKHR* surface) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     assert(instance != VK_NULL_HANDLE); | ||||
|     assert(window != NULL); | ||||
|     assert(surface != NULL); | ||||
|  | ||||
|     *surface = VK_NULL_HANDLE; | ||||
|  | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED); | ||||
|  | ||||
|     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) | ||||
|         return VK_ERROR_INITIALIZATION_FAILED; | ||||
|  | ||||
|     if (!_glfw.vk.extensions[0]) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "Vulkan: Window surface creation extensions not found"); | ||||
|         return VK_ERROR_EXTENSION_NOT_PRESENT; | ||||
|     } | ||||
|  | ||||
|     if (window->context.client != GLFW_NO_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_INVALID_VALUE, | ||||
|                         "Vulkan: Window surface creation requires the window to have the client API set to GLFW_NO_API"); | ||||
|         return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; | ||||
|     } | ||||
|  | ||||
|     return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface); | ||||
| } | ||||
|  | ||||
							
								
								
									
										798
									
								
								deps/glfw/src/wgl_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										798
									
								
								deps/glfw/src/wgl_context.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,798 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 WGL - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <malloc.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| // Return the value corresponding to the specified attribute | ||||
| // | ||||
| static int findPixelFormatAttribValue(const int* attribs, | ||||
|                                       int attribCount, | ||||
|                                       const int* values, | ||||
|                                       int attrib) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     for (i = 0;  i < attribCount;  i++) | ||||
|     { | ||||
|         if (attribs[i] == attrib) | ||||
|             return values[i]; | ||||
|     } | ||||
|  | ||||
|     _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                          "WGL: Unknown pixel format attribute requested"); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #define addAttrib(a) \ | ||||
| { \ | ||||
|     assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \ | ||||
|     attribs[attribCount++] = a; \ | ||||
| } | ||||
| #define findAttribValue(a) \ | ||||
|     findPixelFormatAttribValue(attribs, attribCount, values, a) | ||||
|  | ||||
| // Return a list of available and usable framebuffer configs | ||||
| // | ||||
| static int choosePixelFormat(_GLFWwindow* window, | ||||
|                              const _GLFWctxconfig* ctxconfig, | ||||
|                              const _GLFWfbconfig* fbconfig) | ||||
| { | ||||
|     _GLFWfbconfig* usableConfigs; | ||||
|     const _GLFWfbconfig* closest; | ||||
|     int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0; | ||||
|     int attribs[40]; | ||||
|     int values[sizeof(attribs) / sizeof(attribs[0])]; | ||||
|  | ||||
|     if (_glfw.wgl.ARB_pixel_format) | ||||
|     { | ||||
|         const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB; | ||||
|  | ||||
|         if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc, | ||||
|                                           1, 0, 1, &attrib, &nativeCount)) | ||||
|         { | ||||
|             _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                                  "WGL: Failed to retrieve pixel format attribute"); | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         addAttrib(WGL_SUPPORT_OPENGL_ARB); | ||||
|         addAttrib(WGL_DRAW_TO_WINDOW_ARB); | ||||
|         addAttrib(WGL_PIXEL_TYPE_ARB); | ||||
|         addAttrib(WGL_ACCELERATION_ARB); | ||||
|         addAttrib(WGL_RED_BITS_ARB); | ||||
|         addAttrib(WGL_RED_SHIFT_ARB); | ||||
|         addAttrib(WGL_GREEN_BITS_ARB); | ||||
|         addAttrib(WGL_GREEN_SHIFT_ARB); | ||||
|         addAttrib(WGL_BLUE_BITS_ARB); | ||||
|         addAttrib(WGL_BLUE_SHIFT_ARB); | ||||
|         addAttrib(WGL_ALPHA_BITS_ARB); | ||||
|         addAttrib(WGL_ALPHA_SHIFT_ARB); | ||||
|         addAttrib(WGL_DEPTH_BITS_ARB); | ||||
|         addAttrib(WGL_STENCIL_BITS_ARB); | ||||
|         addAttrib(WGL_ACCUM_BITS_ARB); | ||||
|         addAttrib(WGL_ACCUM_RED_BITS_ARB); | ||||
|         addAttrib(WGL_ACCUM_GREEN_BITS_ARB); | ||||
|         addAttrib(WGL_ACCUM_BLUE_BITS_ARB); | ||||
|         addAttrib(WGL_ACCUM_ALPHA_BITS_ARB); | ||||
|         addAttrib(WGL_AUX_BUFFERS_ARB); | ||||
|         addAttrib(WGL_STEREO_ARB); | ||||
|         addAttrib(WGL_DOUBLE_BUFFER_ARB); | ||||
|  | ||||
|         if (_glfw.wgl.ARB_multisample) | ||||
|             addAttrib(WGL_SAMPLES_ARB); | ||||
|  | ||||
|         if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) | ||||
|                 addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (_glfw.wgl.EXT_colorspace) | ||||
|                 addAttrib(WGL_COLORSPACE_EXT); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         nativeCount = DescribePixelFormat(window->context.wgl.dc, | ||||
|                                           1, | ||||
|                                           sizeof(PIXELFORMATDESCRIPTOR), | ||||
|                                           NULL); | ||||
|     } | ||||
|  | ||||
|     usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); | ||||
|  | ||||
|     for (i = 0;  i < nativeCount;  i++) | ||||
|     { | ||||
|         _GLFWfbconfig* u = usableConfigs + usableCount; | ||||
|         pixelFormat = i + 1; | ||||
|  | ||||
|         if (_glfw.wgl.ARB_pixel_format) | ||||
|         { | ||||
|             // Get pixel format attributes through "modern" extension | ||||
|  | ||||
|             if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc, | ||||
|                                               pixelFormat, 0, | ||||
|                                               attribCount, | ||||
|                                               attribs, values)) | ||||
|             { | ||||
|                 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                                     "WGL: Failed to retrieve pixel format attributes"); | ||||
|  | ||||
|                 free(usableConfigs); | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) || | ||||
|                 !findAttribValue(WGL_DRAW_TO_WINDOW_ARB)) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) | ||||
|                 continue; | ||||
|  | ||||
|             if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) | ||||
|                 continue; | ||||
|  | ||||
|             if (findAttribValue(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer) | ||||
|                 continue; | ||||
|  | ||||
|             u->redBits = findAttribValue(WGL_RED_BITS_ARB); | ||||
|             u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB); | ||||
|             u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB); | ||||
|             u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB); | ||||
|  | ||||
|             u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB); | ||||
|             u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB); | ||||
|  | ||||
|             u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB); | ||||
|             u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB); | ||||
|             u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB); | ||||
|             u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB); | ||||
|  | ||||
|             u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB); | ||||
|  | ||||
|             if (findAttribValue(WGL_STEREO_ARB)) | ||||
|                 u->stereo = GLFW_TRUE; | ||||
|  | ||||
|             if (_glfw.wgl.ARB_multisample) | ||||
|                 u->samples = findAttribValue(WGL_SAMPLES_ARB); | ||||
|  | ||||
|             if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|             { | ||||
|                 if (_glfw.wgl.ARB_framebuffer_sRGB || | ||||
|                     _glfw.wgl.EXT_framebuffer_sRGB) | ||||
|                 { | ||||
|                     if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) | ||||
|                         u->sRGB = GLFW_TRUE; | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (_glfw.wgl.EXT_colorspace) | ||||
|                 { | ||||
|                     if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) | ||||
|                         u->sRGB = GLFW_TRUE; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Get pixel format attributes through legacy PFDs | ||||
|  | ||||
|             PIXELFORMATDESCRIPTOR pfd; | ||||
|  | ||||
|             if (!DescribePixelFormat(window->context.wgl.dc, | ||||
|                                      pixelFormat, | ||||
|                                      sizeof(PIXELFORMATDESCRIPTOR), | ||||
|                                      &pfd)) | ||||
|             { | ||||
|                 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                                     "WGL: Failed to describe pixel format"); | ||||
|  | ||||
|                 free(usableConfigs); | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || | ||||
|                 !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && | ||||
|                 (pfd.dwFlags & PFD_GENERIC_FORMAT)) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (pfd.iPixelType != PFD_TYPE_RGBA) | ||||
|                 continue; | ||||
|  | ||||
|             if (!!(pfd.dwFlags & PFD_DOUBLEBUFFER) != fbconfig->doublebuffer) | ||||
|                 continue; | ||||
|  | ||||
|             u->redBits = pfd.cRedBits; | ||||
|             u->greenBits = pfd.cGreenBits; | ||||
|             u->blueBits = pfd.cBlueBits; | ||||
|             u->alphaBits = pfd.cAlphaBits; | ||||
|  | ||||
|             u->depthBits = pfd.cDepthBits; | ||||
|             u->stencilBits = pfd.cStencilBits; | ||||
|  | ||||
|             u->accumRedBits = pfd.cAccumRedBits; | ||||
|             u->accumGreenBits = pfd.cAccumGreenBits; | ||||
|             u->accumBlueBits = pfd.cAccumBlueBits; | ||||
|             u->accumAlphaBits = pfd.cAccumAlphaBits; | ||||
|  | ||||
|             u->auxBuffers = pfd.cAuxBuffers; | ||||
|  | ||||
|             if (pfd.dwFlags & PFD_STEREO) | ||||
|                 u->stereo = GLFW_TRUE; | ||||
|         } | ||||
|  | ||||
|         u->handle = pixelFormat; | ||||
|         usableCount++; | ||||
|     } | ||||
|  | ||||
|     if (!usableCount) | ||||
|     { | ||||
|         _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                         "WGL: The driver does not appear to support OpenGL"); | ||||
|  | ||||
|         free(usableConfigs); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount); | ||||
|     if (!closest) | ||||
|     { | ||||
|         _glfwInputError(GLFW_FORMAT_UNAVAILABLE, | ||||
|                         "WGL: Failed to find a suitable pixel format"); | ||||
|  | ||||
|         free(usableConfigs); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     pixelFormat = (int) closest->handle; | ||||
|     free(usableConfigs); | ||||
|  | ||||
|     return pixelFormat; | ||||
| } | ||||
|  | ||||
| #undef addAttrib | ||||
| #undef findAttribValue | ||||
|  | ||||
| static void makeContextCurrentWGL(_GLFWwindow* window) | ||||
| { | ||||
|     if (window) | ||||
|     { | ||||
|         if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle)) | ||||
|             _glfwPlatformSetTls(&_glfw.contextSlot, window); | ||||
|         else | ||||
|         { | ||||
|             _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                                  "WGL: Failed to make context current"); | ||||
|             _glfwPlatformSetTls(&_glfw.contextSlot, NULL); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!wglMakeCurrent(NULL, NULL)) | ||||
|         { | ||||
|             _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                                  "WGL: Failed to clear current context"); | ||||
|         } | ||||
|  | ||||
|         _glfwPlatformSetTls(&_glfw.contextSlot, NULL); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void swapBuffersWGL(_GLFWwindow* window) | ||||
| { | ||||
|     if (!window->monitor) | ||||
|     { | ||||
|         if (IsWindowsVistaOrGreater()) | ||||
|         { | ||||
|             // DWM Composition is always enabled on Win8+ | ||||
|             BOOL enabled = IsWindows8OrGreater(); | ||||
|  | ||||
|             // HACK: Use DwmFlush when desktop composition is enabled | ||||
|             if (enabled || | ||||
|                 (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)) | ||||
|             { | ||||
|                 int count = abs(window->context.wgl.interval); | ||||
|                 while (count--) | ||||
|                     DwmFlush(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SwapBuffers(window->context.wgl.dc); | ||||
| } | ||||
|  | ||||
| static void swapIntervalWGL(int interval) | ||||
| { | ||||
|     _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); | ||||
|  | ||||
|     window->context.wgl.interval = interval; | ||||
|  | ||||
|     if (!window->monitor) | ||||
|     { | ||||
|         if (IsWindowsVistaOrGreater()) | ||||
|         { | ||||
|             // DWM Composition is always enabled on Win8+ | ||||
|             BOOL enabled = IsWindows8OrGreater(); | ||||
|  | ||||
|             // HACK: Disable WGL swap interval when desktop composition is enabled to | ||||
|             //       avoid interfering with DWM vsync | ||||
|             if (enabled || | ||||
|                 (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)) | ||||
|                 interval = 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (_glfw.wgl.EXT_swap_control) | ||||
|         wglSwapIntervalEXT(interval); | ||||
| } | ||||
|  | ||||
| static int extensionSupportedWGL(const char* extension) | ||||
| { | ||||
|     const char* extensions = NULL; | ||||
|  | ||||
|     if (_glfw.wgl.GetExtensionsStringARB) | ||||
|         extensions = wglGetExtensionsStringARB(wglGetCurrentDC()); | ||||
|     else if (_glfw.wgl.GetExtensionsStringEXT) | ||||
|         extensions = wglGetExtensionsStringEXT(); | ||||
|  | ||||
|     if (!extensions) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     return _glfwStringInExtensionString(extension, extensions); | ||||
| } | ||||
|  | ||||
| static GLFWglproc getProcAddressWGL(const char* procname) | ||||
| { | ||||
|     const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname); | ||||
|     if (proc) | ||||
|         return proc; | ||||
|  | ||||
|     return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname); | ||||
| } | ||||
|  | ||||
| static void destroyContextWGL(_GLFWwindow* window) | ||||
| { | ||||
|     if (window->context.wgl.handle) | ||||
|     { | ||||
|         wglDeleteContext(window->context.wgl.handle); | ||||
|         window->context.wgl.handle = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialize WGL | ||||
| // | ||||
| GLFWbool _glfwInitWGL(void) | ||||
| { | ||||
|     PIXELFORMATDESCRIPTOR pfd; | ||||
|     HGLRC prc, rc; | ||||
|     HDC pdc, dc; | ||||
|  | ||||
|     if (_glfw.wgl.instance) | ||||
|         return GLFW_TRUE; | ||||
|  | ||||
|     _glfw.wgl.instance = LoadLibraryA("opengl32.dll"); | ||||
|     if (!_glfw.wgl.instance) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "WGL: Failed to load opengl32.dll"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.wgl.CreateContext = (PFN_wglCreateContext) | ||||
|         GetProcAddress(_glfw.wgl.instance, "wglCreateContext"); | ||||
|     _glfw.wgl.DeleteContext = (PFN_wglDeleteContext) | ||||
|         GetProcAddress(_glfw.wgl.instance, "wglDeleteContext"); | ||||
|     _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress) | ||||
|         GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress"); | ||||
|     _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC) | ||||
|         GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC"); | ||||
|     _glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext) | ||||
|         GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext"); | ||||
|     _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent) | ||||
|         GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent"); | ||||
|     _glfw.wgl.ShareLists = (PFN_wglShareLists) | ||||
|         GetProcAddress(_glfw.wgl.instance, "wglShareLists"); | ||||
|  | ||||
|     // NOTE: A dummy context has to be created for opengl32.dll to load the | ||||
|     //       OpenGL ICD, from which we can then query WGL extensions | ||||
|     // NOTE: This code will accept the Microsoft GDI ICD; accelerated context | ||||
|     //       creation failure occurs during manual pixel format enumeration | ||||
|  | ||||
|     dc = GetDC(_glfw.win32.helperWindowHandle); | ||||
|  | ||||
|     ZeroMemory(&pfd, sizeof(pfd)); | ||||
|     pfd.nSize = sizeof(pfd); | ||||
|     pfd.nVersion = 1; | ||||
|     pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; | ||||
|     pfd.iPixelType = PFD_TYPE_RGBA; | ||||
|     pfd.cColorBits = 24; | ||||
|  | ||||
|     if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd)) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "WGL: Failed to set pixel format for dummy context"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     rc = wglCreateContext(dc); | ||||
|     if (!rc) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "WGL: Failed to create dummy context"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     pdc = wglGetCurrentDC(); | ||||
|     prc = wglGetCurrentContext(); | ||||
|  | ||||
|     if (!wglMakeCurrent(dc, rc)) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "WGL: Failed to make dummy context current"); | ||||
|         wglMakeCurrent(pdc, prc); | ||||
|         wglDeleteContext(rc); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     // NOTE: Functions must be loaded first as they're needed to retrieve the | ||||
|     //       extension string that tells us whether the functions are supported | ||||
|     _glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) | ||||
|         wglGetProcAddress("wglGetExtensionsStringEXT"); | ||||
|     _glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) | ||||
|         wglGetProcAddress("wglGetExtensionsStringARB"); | ||||
|     _glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) | ||||
|         wglGetProcAddress("wglCreateContextAttribsARB"); | ||||
|     _glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) | ||||
|         wglGetProcAddress("wglSwapIntervalEXT"); | ||||
|     _glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) | ||||
|         wglGetProcAddress("wglGetPixelFormatAttribivARB"); | ||||
|  | ||||
|     // NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not | ||||
|     //       checked below as we are already using them | ||||
|     _glfw.wgl.ARB_multisample = | ||||
|         extensionSupportedWGL("WGL_ARB_multisample"); | ||||
|     _glfw.wgl.ARB_framebuffer_sRGB = | ||||
|         extensionSupportedWGL("WGL_ARB_framebuffer_sRGB"); | ||||
|     _glfw.wgl.EXT_framebuffer_sRGB = | ||||
|         extensionSupportedWGL("WGL_EXT_framebuffer_sRGB"); | ||||
|     _glfw.wgl.ARB_create_context = | ||||
|         extensionSupportedWGL("WGL_ARB_create_context"); | ||||
|     _glfw.wgl.ARB_create_context_profile = | ||||
|         extensionSupportedWGL("WGL_ARB_create_context_profile"); | ||||
|     _glfw.wgl.EXT_create_context_es2_profile = | ||||
|         extensionSupportedWGL("WGL_EXT_create_context_es2_profile"); | ||||
|     _glfw.wgl.ARB_create_context_robustness = | ||||
|         extensionSupportedWGL("WGL_ARB_create_context_robustness"); | ||||
|     _glfw.wgl.ARB_create_context_no_error = | ||||
|         extensionSupportedWGL("WGL_ARB_create_context_no_error"); | ||||
|     _glfw.wgl.EXT_swap_control = | ||||
|         extensionSupportedWGL("WGL_EXT_swap_control"); | ||||
|     _glfw.wgl.EXT_colorspace = | ||||
|         extensionSupportedWGL("WGL_EXT_colorspace"); | ||||
|     _glfw.wgl.ARB_pixel_format = | ||||
|         extensionSupportedWGL("WGL_ARB_pixel_format"); | ||||
|     _glfw.wgl.ARB_context_flush_control = | ||||
|         extensionSupportedWGL("WGL_ARB_context_flush_control"); | ||||
|  | ||||
|     wglMakeCurrent(pdc, prc); | ||||
|     wglDeleteContext(rc); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Terminate WGL | ||||
| // | ||||
| void _glfwTerminateWGL(void) | ||||
| { | ||||
|     if (_glfw.wgl.instance) | ||||
|         FreeLibrary(_glfw.wgl.instance); | ||||
| } | ||||
|  | ||||
| #define setAttrib(a, v) \ | ||||
| { \ | ||||
|     assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ | ||||
|     attribs[index++] = a; \ | ||||
|     attribs[index++] = v; \ | ||||
| } | ||||
|  | ||||
| // Create the OpenGL or OpenGL ES context | ||||
| // | ||||
| GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, | ||||
|                                const _GLFWctxconfig* ctxconfig, | ||||
|                                const _GLFWfbconfig* fbconfig) | ||||
| { | ||||
|     int attribs[40]; | ||||
|     int pixelFormat; | ||||
|     PIXELFORMATDESCRIPTOR pfd; | ||||
|     HGLRC share = NULL; | ||||
|  | ||||
|     if (ctxconfig->share) | ||||
|         share = ctxconfig->share->context.wgl.handle; | ||||
|  | ||||
|     window->context.wgl.dc = GetDC(window->win32.handle); | ||||
|     if (!window->context.wgl.dc) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "WGL: Failed to retrieve DC for window"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig); | ||||
|     if (!pixelFormat) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     if (!DescribePixelFormat(window->context.wgl.dc, | ||||
|                              pixelFormat, sizeof(pfd), &pfd)) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "WGL: Failed to retrieve PFD for selected pixel format"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd)) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "WGL: Failed to set selected pixel format"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|     { | ||||
|         if (ctxconfig->forward) | ||||
|         { | ||||
|             if (!_glfw.wgl.ARB_create_context) | ||||
|             { | ||||
|                 _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                                 "WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable"); | ||||
|                 return GLFW_FALSE; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->profile) | ||||
|         { | ||||
|             if (!_glfw.wgl.ARB_create_context_profile) | ||||
|             { | ||||
|                 _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                                 "WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable"); | ||||
|                 return GLFW_FALSE; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!_glfw.wgl.ARB_create_context || | ||||
|             !_glfw.wgl.ARB_create_context_profile || | ||||
|             !_glfw.wgl.EXT_create_context_es2_profile) | ||||
|         { | ||||
|             _glfwInputError(GLFW_API_UNAVAILABLE, | ||||
|                             "WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (_glfw.wgl.ARB_create_context) | ||||
|     { | ||||
|         int index = 0, mask = 0, flags = 0; | ||||
|  | ||||
|         if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|         { | ||||
|             if (ctxconfig->forward) | ||||
|                 flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; | ||||
|  | ||||
|             if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) | ||||
|                 mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; | ||||
|             else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) | ||||
|                 mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; | ||||
|         } | ||||
|         else | ||||
|             mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; | ||||
|  | ||||
|         if (ctxconfig->debug) | ||||
|             flags |= WGL_CONTEXT_DEBUG_BIT_ARB; | ||||
|  | ||||
|         if (ctxconfig->robustness) | ||||
|         { | ||||
|             if (_glfw.wgl.ARB_create_context_robustness) | ||||
|             { | ||||
|                 if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) | ||||
|                 { | ||||
|                     setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, | ||||
|                               WGL_NO_RESET_NOTIFICATION_ARB); | ||||
|                 } | ||||
|                 else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) | ||||
|                 { | ||||
|                     setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, | ||||
|                               WGL_LOSE_CONTEXT_ON_RESET_ARB); | ||||
|                 } | ||||
|  | ||||
|                 flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->release) | ||||
|         { | ||||
|             if (_glfw.wgl.ARB_context_flush_control) | ||||
|             { | ||||
|                 if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) | ||||
|                 { | ||||
|                     setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, | ||||
|                               WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); | ||||
|                 } | ||||
|                 else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) | ||||
|                 { | ||||
|                     setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, | ||||
|                               WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (ctxconfig->noerror) | ||||
|         { | ||||
|             if (_glfw.wgl.ARB_create_context_no_error) | ||||
|                 setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); | ||||
|         } | ||||
|  | ||||
|         // NOTE: Only request an explicitly versioned context when necessary, as | ||||
|         //       explicitly requesting version 1.0 does not always return the | ||||
|         //       highest version supported by the driver | ||||
|         if (ctxconfig->major != 1 || ctxconfig->minor != 0) | ||||
|         { | ||||
|             setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); | ||||
|             setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); | ||||
|         } | ||||
|  | ||||
|         if (flags) | ||||
|             setAttrib(WGL_CONTEXT_FLAGS_ARB, flags); | ||||
|  | ||||
|         if (mask) | ||||
|             setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); | ||||
|  | ||||
|         setAttrib(0, 0); | ||||
|  | ||||
|         window->context.wgl.handle = | ||||
|             wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs); | ||||
|         if (!window->context.wgl.handle) | ||||
|         { | ||||
|             const DWORD error = GetLastError(); | ||||
|  | ||||
|             if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB)) | ||||
|             { | ||||
|                 if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|                 { | ||||
|                     _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                                     "WGL: Driver does not support OpenGL version %i.%i", | ||||
|                                     ctxconfig->major, | ||||
|                                     ctxconfig->minor); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                                     "WGL: Driver does not support OpenGL ES version %i.%i", | ||||
|                                     ctxconfig->major, | ||||
|                                     ctxconfig->minor); | ||||
|                 } | ||||
|             } | ||||
|             else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB)) | ||||
|             { | ||||
|                 _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                                 "WGL: Driver does not support the requested OpenGL profile"); | ||||
|             } | ||||
|             else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB)) | ||||
|             { | ||||
|                 _glfwInputError(GLFW_INVALID_VALUE, | ||||
|                                 "WGL: The share context is not compatible with the requested context"); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (ctxconfig->client == GLFW_OPENGL_API) | ||||
|                 { | ||||
|                     _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                                     "WGL: Failed to create OpenGL context"); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     _glfwInputError(GLFW_VERSION_UNAVAILABLE, | ||||
|                                     "WGL: Failed to create OpenGL ES context"); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         window->context.wgl.handle = wglCreateContext(window->context.wgl.dc); | ||||
|         if (!window->context.wgl.handle) | ||||
|         { | ||||
|             _glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE, | ||||
|                                  "WGL: Failed to create OpenGL context"); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         if (share) | ||||
|         { | ||||
|             if (!wglShareLists(share, window->context.wgl.handle)) | ||||
|             { | ||||
|                 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                                      "WGL: Failed to enable sharing with specified OpenGL context"); | ||||
|                 return GLFW_FALSE; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     window->context.makeCurrent = makeContextCurrentWGL; | ||||
|     window->context.swapBuffers = swapBuffersWGL; | ||||
|     window->context.swapInterval = swapIntervalWGL; | ||||
|     window->context.extensionSupported = extensionSupportedWGL; | ||||
|     window->context.getProcAddress = getProcAddressWGL; | ||||
|     window->context.destroy = destroyContextWGL; | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| #undef setAttrib | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|  | ||||
|     if (window->context.source != GLFW_NATIVE_CONTEXT_API) | ||||
|     { | ||||
|         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     return window->context.wgl.handle; | ||||
| } | ||||
|  | ||||
							
								
								
									
										158
									
								
								deps/glfw/src/wgl_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								deps/glfw/src/wgl_context.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 WGL - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 | ||||
| #define WGL_SUPPORT_OPENGL_ARB 0x2010 | ||||
| #define WGL_DRAW_TO_WINDOW_ARB 0x2001 | ||||
| #define WGL_PIXEL_TYPE_ARB 0x2013 | ||||
| #define WGL_TYPE_RGBA_ARB 0x202b | ||||
| #define WGL_ACCELERATION_ARB 0x2003 | ||||
| #define WGL_NO_ACCELERATION_ARB 0x2025 | ||||
| #define WGL_RED_BITS_ARB 0x2015 | ||||
| #define WGL_RED_SHIFT_ARB 0x2016 | ||||
| #define WGL_GREEN_BITS_ARB 0x2017 | ||||
| #define WGL_GREEN_SHIFT_ARB 0x2018 | ||||
| #define WGL_BLUE_BITS_ARB 0x2019 | ||||
| #define WGL_BLUE_SHIFT_ARB 0x201a | ||||
| #define WGL_ALPHA_BITS_ARB 0x201b | ||||
| #define WGL_ALPHA_SHIFT_ARB 0x201c | ||||
| #define WGL_ACCUM_BITS_ARB 0x201d | ||||
| #define WGL_ACCUM_RED_BITS_ARB 0x201e | ||||
| #define WGL_ACCUM_GREEN_BITS_ARB 0x201f | ||||
| #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 | ||||
| #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 | ||||
| #define WGL_DEPTH_BITS_ARB 0x2022 | ||||
| #define WGL_STENCIL_BITS_ARB 0x2023 | ||||
| #define WGL_AUX_BUFFERS_ARB 0x2024 | ||||
| #define WGL_STEREO_ARB 0x2012 | ||||
| #define WGL_DOUBLE_BUFFER_ARB 0x2011 | ||||
| #define WGL_SAMPLES_ARB 0x2042 | ||||
| #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9 | ||||
| #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 | ||||
| #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 | ||||
| #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 | ||||
| #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 | ||||
| #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 | ||||
| #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 | ||||
| #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 | ||||
| #define WGL_CONTEXT_FLAGS_ARB 0x2094 | ||||
| #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 | ||||
| #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 | ||||
| #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 | ||||
| #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 | ||||
| #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 | ||||
| #define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 | ||||
| #define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 | ||||
| #define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 | ||||
| #define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3 | ||||
| #define WGL_COLORSPACE_EXT 0x309d | ||||
| #define WGL_COLORSPACE_SRGB_EXT 0x3089 | ||||
|  | ||||
| #define ERROR_INVALID_VERSION_ARB 0x2095 | ||||
| #define ERROR_INVALID_PROFILE_ARB 0x2096 | ||||
| #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 | ||||
|  | ||||
| // WGL extension pointer typedefs | ||||
| typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int); | ||||
| typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*); | ||||
| typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void); | ||||
| typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC); | ||||
| typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*); | ||||
| #define wglSwapIntervalEXT _glfw.wgl.SwapIntervalEXT | ||||
| #define wglGetPixelFormatAttribivARB _glfw.wgl.GetPixelFormatAttribivARB | ||||
| #define wglGetExtensionsStringEXT _glfw.wgl.GetExtensionsStringEXT | ||||
| #define wglGetExtensionsStringARB _glfw.wgl.GetExtensionsStringARB | ||||
| #define wglCreateContextAttribsARB _glfw.wgl.CreateContextAttribsARB | ||||
|  | ||||
| // opengl32.dll function pointer typedefs | ||||
| typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC); | ||||
| typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC); | ||||
| typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR); | ||||
| typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void); | ||||
| typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void); | ||||
| typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC); | ||||
| typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC); | ||||
| #define wglCreateContext _glfw.wgl.CreateContext | ||||
| #define wglDeleteContext _glfw.wgl.DeleteContext | ||||
| #define wglGetProcAddress _glfw.wgl.GetProcAddress | ||||
| #define wglGetCurrentDC _glfw.wgl.GetCurrentDC | ||||
| #define wglGetCurrentContext _glfw.wgl.GetCurrentContext | ||||
| #define wglMakeCurrent _glfw.wgl.MakeCurrent | ||||
| #define wglShareLists _glfw.wgl.ShareLists | ||||
|  | ||||
| #define _GLFW_PLATFORM_CONTEXT_STATE            _GLFWcontextWGL wgl | ||||
| #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE    _GLFWlibraryWGL wgl | ||||
|  | ||||
|  | ||||
| // WGL-specific per-context data | ||||
| // | ||||
| typedef struct _GLFWcontextWGL | ||||
| { | ||||
|     HDC       dc; | ||||
|     HGLRC     handle; | ||||
|     int       interval; | ||||
| } _GLFWcontextWGL; | ||||
|  | ||||
| // WGL-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryWGL | ||||
| { | ||||
|     HINSTANCE                           instance; | ||||
|     PFN_wglCreateContext                CreateContext; | ||||
|     PFN_wglDeleteContext                DeleteContext; | ||||
|     PFN_wglGetProcAddress               GetProcAddress; | ||||
|     PFN_wglGetCurrentDC                 GetCurrentDC; | ||||
|     PFN_wglGetCurrentContext            GetCurrentContext; | ||||
|     PFN_wglMakeCurrent                  MakeCurrent; | ||||
|     PFN_wglShareLists                   ShareLists; | ||||
|  | ||||
|     PFNWGLSWAPINTERVALEXTPROC           SwapIntervalEXT; | ||||
|     PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB; | ||||
|     PFNWGLGETEXTENSIONSSTRINGEXTPROC    GetExtensionsStringEXT; | ||||
|     PFNWGLGETEXTENSIONSSTRINGARBPROC    GetExtensionsStringARB; | ||||
|     PFNWGLCREATECONTEXTATTRIBSARBPROC   CreateContextAttribsARB; | ||||
|     GLFWbool                            EXT_swap_control; | ||||
|     GLFWbool                            EXT_colorspace; | ||||
|     GLFWbool                            ARB_multisample; | ||||
|     GLFWbool                            ARB_framebuffer_sRGB; | ||||
|     GLFWbool                            EXT_framebuffer_sRGB; | ||||
|     GLFWbool                            ARB_pixel_format; | ||||
|     GLFWbool                            ARB_create_context; | ||||
|     GLFWbool                            ARB_create_context_profile; | ||||
|     GLFWbool                            EXT_create_context_es2_profile; | ||||
|     GLFWbool                            ARB_create_context_robustness; | ||||
|     GLFWbool                            ARB_create_context_no_error; | ||||
|     GLFWbool                            ARB_context_flush_control; | ||||
| } _GLFWlibraryWGL; | ||||
|  | ||||
|  | ||||
| GLFWbool _glfwInitWGL(void); | ||||
| void _glfwTerminateWGL(void); | ||||
| GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, | ||||
|                                const _GLFWctxconfig* ctxconfig, | ||||
|                                const _GLFWfbconfig* fbconfig); | ||||
|  | ||||
							
								
								
									
										623
									
								
								deps/glfw/src/win32_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										623
									
								
								deps/glfw/src/win32_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,623 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Win32 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <malloc.h> | ||||
|  | ||||
| static const GUID _glfw_GUID_DEVINTERFACE_HID = | ||||
|     {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}}; | ||||
|  | ||||
| #define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID | ||||
|  | ||||
| #if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) | ||||
|  | ||||
| #if defined(_GLFW_BUILD_DLL) | ||||
|  #pragma message("These symbols must be exported by the executable and have no effect in a DLL") | ||||
| #endif | ||||
|  | ||||
| // Executables (but not DLLs) exporting this symbol with this value will be | ||||
| // automatically directed to the high-performance GPU on Nvidia Optimus systems | ||||
| // with up-to-date drivers | ||||
| // | ||||
| __declspec(dllexport) DWORD NvOptimusEnablement = 1; | ||||
|  | ||||
| // Executables (but not DLLs) exporting this symbol with this value will be | ||||
| // automatically directed to the high-performance GPU on AMD PowerXpress systems | ||||
| // with up-to-date drivers | ||||
| // | ||||
| __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; | ||||
|  | ||||
| #endif // _GLFW_USE_HYBRID_HPG | ||||
|  | ||||
| #if defined(_GLFW_BUILD_DLL) | ||||
|  | ||||
| // GLFW DLL entry point | ||||
| // | ||||
| BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) | ||||
| { | ||||
|     return TRUE; | ||||
| } | ||||
|  | ||||
| #endif // _GLFW_BUILD_DLL | ||||
|  | ||||
| // Load necessary libraries (DLLs) | ||||
| // | ||||
| static GLFWbool loadLibraries(void) | ||||
| { | ||||
|     _glfw.win32.user32.instance = LoadLibraryA("user32.dll"); | ||||
|     if (!_glfw.win32.user32.instance) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "Win32: Failed to load user32.dll"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     _glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware) | ||||
|         GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); | ||||
|     _glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx) | ||||
|         GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); | ||||
|     _glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling) | ||||
|         GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling"); | ||||
|     _glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext) | ||||
|         GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext"); | ||||
|     _glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow) | ||||
|         GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow"); | ||||
|     _glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi) | ||||
|         GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi"); | ||||
|  | ||||
|     _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll"); | ||||
|     if (_glfw.win32.dinput8.instance) | ||||
|     { | ||||
|         _glfw.win32.dinput8.Create = (PFN_DirectInput8Create) | ||||
|             GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create"); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         int i; | ||||
|         const char* names[] = | ||||
|         { | ||||
|             "xinput1_4.dll", | ||||
|             "xinput1_3.dll", | ||||
|             "xinput9_1_0.dll", | ||||
|             "xinput1_2.dll", | ||||
|             "xinput1_1.dll", | ||||
|             NULL | ||||
|         }; | ||||
|  | ||||
|         for (i = 0;  names[i];  i++) | ||||
|         { | ||||
|             _glfw.win32.xinput.instance = LoadLibraryA(names[i]); | ||||
|             if (_glfw.win32.xinput.instance) | ||||
|             { | ||||
|                 _glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities) | ||||
|                     GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities"); | ||||
|                 _glfw.win32.xinput.GetState = (PFN_XInputGetState) | ||||
|                     GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState"); | ||||
|  | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll"); | ||||
|     if (_glfw.win32.dwmapi.instance) | ||||
|     { | ||||
|         _glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled) | ||||
|             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); | ||||
|         _glfw.win32.dwmapi.Flush = (PFN_DwmFlush) | ||||
|             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush"); | ||||
|         _glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow) | ||||
|             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); | ||||
|         _glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor) | ||||
|             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor"); | ||||
|     } | ||||
|  | ||||
|     _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); | ||||
|     if (_glfw.win32.shcore.instance) | ||||
|     { | ||||
|         _glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness) | ||||
|             GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness"); | ||||
|         _glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor) | ||||
|             GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor"); | ||||
|     } | ||||
|  | ||||
|     _glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll"); | ||||
|     if (_glfw.win32.ntdll.instance) | ||||
|     { | ||||
|         _glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo) | ||||
|             GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo"); | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| // Unload used libraries (DLLs) | ||||
| // | ||||
| static void freeLibraries(void) | ||||
| { | ||||
|     if (_glfw.win32.xinput.instance) | ||||
|         FreeLibrary(_glfw.win32.xinput.instance); | ||||
|  | ||||
|     if (_glfw.win32.dinput8.instance) | ||||
|         FreeLibrary(_glfw.win32.dinput8.instance); | ||||
|  | ||||
|     if (_glfw.win32.user32.instance) | ||||
|         FreeLibrary(_glfw.win32.user32.instance); | ||||
|  | ||||
|     if (_glfw.win32.dwmapi.instance) | ||||
|         FreeLibrary(_glfw.win32.dwmapi.instance); | ||||
|  | ||||
|     if (_glfw.win32.shcore.instance) | ||||
|         FreeLibrary(_glfw.win32.shcore.instance); | ||||
|  | ||||
|     if (_glfw.win32.ntdll.instance) | ||||
|         FreeLibrary(_glfw.win32.ntdll.instance); | ||||
| } | ||||
|  | ||||
| // Create key code translation tables | ||||
| // | ||||
| static void createKeyTables(void) | ||||
| { | ||||
|     int scancode; | ||||
|  | ||||
|     memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes)); | ||||
|     memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes)); | ||||
|  | ||||
|     _glfw.win32.keycodes[0x00B] = GLFW_KEY_0; | ||||
|     _glfw.win32.keycodes[0x002] = GLFW_KEY_1; | ||||
|     _glfw.win32.keycodes[0x003] = GLFW_KEY_2; | ||||
|     _glfw.win32.keycodes[0x004] = GLFW_KEY_3; | ||||
|     _glfw.win32.keycodes[0x005] = GLFW_KEY_4; | ||||
|     _glfw.win32.keycodes[0x006] = GLFW_KEY_5; | ||||
|     _glfw.win32.keycodes[0x007] = GLFW_KEY_6; | ||||
|     _glfw.win32.keycodes[0x008] = GLFW_KEY_7; | ||||
|     _glfw.win32.keycodes[0x009] = GLFW_KEY_8; | ||||
|     _glfw.win32.keycodes[0x00A] = GLFW_KEY_9; | ||||
|     _glfw.win32.keycodes[0x01E] = GLFW_KEY_A; | ||||
|     _glfw.win32.keycodes[0x030] = GLFW_KEY_B; | ||||
|     _glfw.win32.keycodes[0x02E] = GLFW_KEY_C; | ||||
|     _glfw.win32.keycodes[0x020] = GLFW_KEY_D; | ||||
|     _glfw.win32.keycodes[0x012] = GLFW_KEY_E; | ||||
|     _glfw.win32.keycodes[0x021] = GLFW_KEY_F; | ||||
|     _glfw.win32.keycodes[0x022] = GLFW_KEY_G; | ||||
|     _glfw.win32.keycodes[0x023] = GLFW_KEY_H; | ||||
|     _glfw.win32.keycodes[0x017] = GLFW_KEY_I; | ||||
|     _glfw.win32.keycodes[0x024] = GLFW_KEY_J; | ||||
|     _glfw.win32.keycodes[0x025] = GLFW_KEY_K; | ||||
|     _glfw.win32.keycodes[0x026] = GLFW_KEY_L; | ||||
|     _glfw.win32.keycodes[0x032] = GLFW_KEY_M; | ||||
|     _glfw.win32.keycodes[0x031] = GLFW_KEY_N; | ||||
|     _glfw.win32.keycodes[0x018] = GLFW_KEY_O; | ||||
|     _glfw.win32.keycodes[0x019] = GLFW_KEY_P; | ||||
|     _glfw.win32.keycodes[0x010] = GLFW_KEY_Q; | ||||
|     _glfw.win32.keycodes[0x013] = GLFW_KEY_R; | ||||
|     _glfw.win32.keycodes[0x01F] = GLFW_KEY_S; | ||||
|     _glfw.win32.keycodes[0x014] = GLFW_KEY_T; | ||||
|     _glfw.win32.keycodes[0x016] = GLFW_KEY_U; | ||||
|     _glfw.win32.keycodes[0x02F] = GLFW_KEY_V; | ||||
|     _glfw.win32.keycodes[0x011] = GLFW_KEY_W; | ||||
|     _glfw.win32.keycodes[0x02D] = GLFW_KEY_X; | ||||
|     _glfw.win32.keycodes[0x015] = GLFW_KEY_Y; | ||||
|     _glfw.win32.keycodes[0x02C] = GLFW_KEY_Z; | ||||
|  | ||||
|     _glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE; | ||||
|     _glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH; | ||||
|     _glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA; | ||||
|     _glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL; | ||||
|     _glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT; | ||||
|     _glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET; | ||||
|     _glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS; | ||||
|     _glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD; | ||||
|     _glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET; | ||||
|     _glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON; | ||||
|     _glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH; | ||||
|     _glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2; | ||||
|  | ||||
|     _glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE; | ||||
|     _glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE; | ||||
|     _glfw.win32.keycodes[0x14F] = GLFW_KEY_END; | ||||
|     _glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER; | ||||
|     _glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE; | ||||
|     _glfw.win32.keycodes[0x147] = GLFW_KEY_HOME; | ||||
|     _glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT; | ||||
|     _glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU; | ||||
|     _glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN; | ||||
|     _glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP; | ||||
|     _glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE; | ||||
|     _glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE; | ||||
|     _glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE; | ||||
|     _glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB; | ||||
|     _glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK; | ||||
|     _glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK; | ||||
|     _glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK; | ||||
|     _glfw.win32.keycodes[0x03B] = GLFW_KEY_F1; | ||||
|     _glfw.win32.keycodes[0x03C] = GLFW_KEY_F2; | ||||
|     _glfw.win32.keycodes[0x03D] = GLFW_KEY_F3; | ||||
|     _glfw.win32.keycodes[0x03E] = GLFW_KEY_F4; | ||||
|     _glfw.win32.keycodes[0x03F] = GLFW_KEY_F5; | ||||
|     _glfw.win32.keycodes[0x040] = GLFW_KEY_F6; | ||||
|     _glfw.win32.keycodes[0x041] = GLFW_KEY_F7; | ||||
|     _glfw.win32.keycodes[0x042] = GLFW_KEY_F8; | ||||
|     _glfw.win32.keycodes[0x043] = GLFW_KEY_F9; | ||||
|     _glfw.win32.keycodes[0x044] = GLFW_KEY_F10; | ||||
|     _glfw.win32.keycodes[0x057] = GLFW_KEY_F11; | ||||
|     _glfw.win32.keycodes[0x058] = GLFW_KEY_F12; | ||||
|     _glfw.win32.keycodes[0x064] = GLFW_KEY_F13; | ||||
|     _glfw.win32.keycodes[0x065] = GLFW_KEY_F14; | ||||
|     _glfw.win32.keycodes[0x066] = GLFW_KEY_F15; | ||||
|     _glfw.win32.keycodes[0x067] = GLFW_KEY_F16; | ||||
|     _glfw.win32.keycodes[0x068] = GLFW_KEY_F17; | ||||
|     _glfw.win32.keycodes[0x069] = GLFW_KEY_F18; | ||||
|     _glfw.win32.keycodes[0x06A] = GLFW_KEY_F19; | ||||
|     _glfw.win32.keycodes[0x06B] = GLFW_KEY_F20; | ||||
|     _glfw.win32.keycodes[0x06C] = GLFW_KEY_F21; | ||||
|     _glfw.win32.keycodes[0x06D] = GLFW_KEY_F22; | ||||
|     _glfw.win32.keycodes[0x06E] = GLFW_KEY_F23; | ||||
|     _glfw.win32.keycodes[0x076] = GLFW_KEY_F24; | ||||
|     _glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT; | ||||
|     _glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL; | ||||
|     _glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT; | ||||
|     _glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER; | ||||
|     _glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN; | ||||
|     _glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT; | ||||
|     _glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL; | ||||
|     _glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT; | ||||
|     _glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER; | ||||
|     _glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN; | ||||
|     _glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT; | ||||
|     _glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT; | ||||
|     _glfw.win32.keycodes[0x148] = GLFW_KEY_UP; | ||||
|  | ||||
|     _glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0; | ||||
|     _glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1; | ||||
|     _glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2; | ||||
|     _glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3; | ||||
|     _glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4; | ||||
|     _glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5; | ||||
|     _glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6; | ||||
|     _glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7; | ||||
|     _glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8; | ||||
|     _glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9; | ||||
|     _glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD; | ||||
|     _glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL; | ||||
|     _glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE; | ||||
|     _glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER; | ||||
|     _glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL; | ||||
|     _glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY; | ||||
|     _glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT; | ||||
|  | ||||
|     for (scancode = 0;  scancode < 512;  scancode++) | ||||
|     { | ||||
|         if (_glfw.win32.keycodes[scancode] > 0) | ||||
|             _glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Creates a dummy window for behind-the-scenes work | ||||
| // | ||||
| static GLFWbool createHelperWindow(void) | ||||
| { | ||||
|     MSG msg; | ||||
|  | ||||
|     _glfw.win32.helperWindowHandle = | ||||
|         CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, | ||||
|                         _GLFW_WNDCLASSNAME, | ||||
|                         L"GLFW message window", | ||||
|                         WS_CLIPSIBLINGS | WS_CLIPCHILDREN, | ||||
|                         0, 0, 1, 1, | ||||
|                         NULL, NULL, | ||||
|                         GetModuleHandleW(NULL), | ||||
|                         NULL); | ||||
|  | ||||
|     if (!_glfw.win32.helperWindowHandle) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "Win32: Failed to create helper window"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     // HACK: The command to the first ShowWindow call is ignored if the parent | ||||
|     //       process passed along a STARTUPINFO, so clear that with a no-op call | ||||
|     ShowWindow(_glfw.win32.helperWindowHandle, SW_HIDE); | ||||
|  | ||||
|     // Register for HID device notifications | ||||
|     { | ||||
|         DEV_BROADCAST_DEVICEINTERFACE_W dbi; | ||||
|         ZeroMemory(&dbi, sizeof(dbi)); | ||||
|         dbi.dbcc_size = sizeof(dbi); | ||||
|         dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; | ||||
|         dbi.dbcc_classguid = GUID_DEVINTERFACE_HID; | ||||
|  | ||||
|         _glfw.win32.deviceNotificationHandle = | ||||
|             RegisterDeviceNotificationW(_glfw.win32.helperWindowHandle, | ||||
|                                         (DEV_BROADCAST_HDR*) &dbi, | ||||
|                                         DEVICE_NOTIFY_WINDOW_HANDLE); | ||||
|     } | ||||
|  | ||||
|     while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE)) | ||||
|     { | ||||
|         TranslateMessage(&msg); | ||||
|         DispatchMessageW(&msg); | ||||
|     } | ||||
|  | ||||
|    return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Returns a wide string version of the specified UTF-8 string | ||||
| // | ||||
| WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source) | ||||
| { | ||||
|     WCHAR* target; | ||||
|     int count; | ||||
|  | ||||
|     count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0); | ||||
|     if (!count) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "Win32: Failed to convert string from UTF-8"); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     target = calloc(count, sizeof(WCHAR)); | ||||
|  | ||||
|     if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count)) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "Win32: Failed to convert string from UTF-8"); | ||||
|         free(target); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     return target; | ||||
| } | ||||
|  | ||||
| // Returns a UTF-8 string version of the specified wide string | ||||
| // | ||||
| char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source) | ||||
| { | ||||
|     char* target; | ||||
|     int size; | ||||
|  | ||||
|     size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL); | ||||
|     if (!size) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "Win32: Failed to convert string to UTF-8"); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     target = calloc(size, 1); | ||||
|  | ||||
|     if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL)) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "Win32: Failed to convert string to UTF-8"); | ||||
|         free(target); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     return target; | ||||
| } | ||||
|  | ||||
| // Reports the specified error, appending information about the last Win32 error | ||||
| // | ||||
| void _glfwInputErrorWin32(int error, const char* description) | ||||
| { | ||||
|     WCHAR buffer[_GLFW_MESSAGE_SIZE] = L""; | ||||
|     char message[_GLFW_MESSAGE_SIZE] = ""; | ||||
|  | ||||
|     FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | | ||||
|                        FORMAT_MESSAGE_IGNORE_INSERTS | | ||||
|                        FORMAT_MESSAGE_MAX_WIDTH_MASK, | ||||
|                    NULL, | ||||
|                    GetLastError() & 0xffff, | ||||
|                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||
|                    buffer, | ||||
|                    sizeof(buffer) / sizeof(WCHAR), | ||||
|                    NULL); | ||||
|     WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL); | ||||
|  | ||||
|     _glfwInputError(error, "%s: %s", description, message); | ||||
| } | ||||
|  | ||||
| // Updates key names according to the current keyboard layout | ||||
| // | ||||
| void _glfwUpdateKeyNamesWin32(void) | ||||
| { | ||||
|     int key; | ||||
|     BYTE state[256] = {0}; | ||||
|  | ||||
|     memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames)); | ||||
|  | ||||
|     for (key = GLFW_KEY_SPACE;  key <= GLFW_KEY_LAST;  key++) | ||||
|     { | ||||
|         UINT vk; | ||||
|         int scancode, length; | ||||
|         WCHAR chars[16]; | ||||
|  | ||||
|         scancode = _glfw.win32.scancodes[key]; | ||||
|         if (scancode == -1) | ||||
|             continue; | ||||
|  | ||||
|         if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) | ||||
|         { | ||||
|             const UINT vks[] = { | ||||
|                 VK_NUMPAD0,  VK_NUMPAD1,  VK_NUMPAD2, VK_NUMPAD3, | ||||
|                 VK_NUMPAD4,  VK_NUMPAD5,  VK_NUMPAD6, VK_NUMPAD7, | ||||
|                 VK_NUMPAD8,  VK_NUMPAD9,  VK_DECIMAL, VK_DIVIDE, | ||||
|                 VK_MULTIPLY, VK_SUBTRACT, VK_ADD | ||||
|             }; | ||||
|  | ||||
|             vk = vks[key - GLFW_KEY_KP_0]; | ||||
|         } | ||||
|         else | ||||
|             vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK); | ||||
|  | ||||
|         length = ToUnicode(vk, scancode, state, | ||||
|                            chars, sizeof(chars) / sizeof(WCHAR), | ||||
|                            0); | ||||
|  | ||||
|         if (length == -1) | ||||
|         { | ||||
|             length = ToUnicode(vk, scancode, state, | ||||
|                                chars, sizeof(chars) / sizeof(WCHAR), | ||||
|                                0); | ||||
|         } | ||||
|  | ||||
|         if (length < 1) | ||||
|             continue; | ||||
|  | ||||
|         WideCharToMultiByte(CP_UTF8, 0, chars, 1, | ||||
|                             _glfw.win32.keynames[key], | ||||
|                             sizeof(_glfw.win32.keynames[key]), | ||||
|                             NULL, NULL); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h | ||||
| // | ||||
| BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp) | ||||
| { | ||||
|     OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp }; | ||||
|     DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; | ||||
|     ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); | ||||
|     cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); | ||||
|     cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); | ||||
|     // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the | ||||
|     //       latter lies unless the user knew to embed a non-default manifest | ||||
|     //       announcing support for Windows 10 via supportedOS GUID | ||||
|     return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; | ||||
| } | ||||
|  | ||||
| // Checks whether we are on at least the specified build of Windows 10 | ||||
| // | ||||
| BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build) | ||||
| { | ||||
|     OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build }; | ||||
|     DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER; | ||||
|     ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); | ||||
|     cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); | ||||
|     cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL); | ||||
|     // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the | ||||
|     //       latter lies unless the user knew to embed a non-default manifest | ||||
|     //       announcing support for Windows 10 via supportedOS GUID | ||||
|     return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformInit(void) | ||||
| { | ||||
|     // To make SetForegroundWindow work as we want, we need to fiddle | ||||
|     // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early | ||||
|     // as possible in the hope of still being the foreground process) | ||||
|     SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, | ||||
|                           &_glfw.win32.foregroundLockTimeout, 0); | ||||
|     SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0), | ||||
|                           SPIF_SENDCHANGE); | ||||
|  | ||||
|     if (!loadLibraries()) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     createKeyTables(); | ||||
|     _glfwUpdateKeyNamesWin32(); | ||||
|  | ||||
|     if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32()) | ||||
|         SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); | ||||
|     else if (IsWindows8Point1OrGreater()) | ||||
|         SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); | ||||
|     else if (IsWindowsVistaOrGreater()) | ||||
|         SetProcessDPIAware(); | ||||
|  | ||||
|     if (!_glfwRegisterWindowClassWin32()) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     if (!createHelperWindow()) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     _glfwInitTimerWin32(); | ||||
|     _glfwInitJoysticksWin32(); | ||||
|  | ||||
|     _glfwPollMonitorsWin32(); | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformTerminate(void) | ||||
| { | ||||
|     if (_glfw.win32.deviceNotificationHandle) | ||||
|         UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); | ||||
|  | ||||
|     if (_glfw.win32.helperWindowHandle) | ||||
|         DestroyWindow(_glfw.win32.helperWindowHandle); | ||||
|  | ||||
|     _glfwUnregisterWindowClassWin32(); | ||||
|  | ||||
|     // Restore previous foreground lock timeout system setting | ||||
|     SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, | ||||
|                           UIntToPtr(_glfw.win32.foregroundLockTimeout), | ||||
|                           SPIF_SENDCHANGE); | ||||
|  | ||||
|     free(_glfw.win32.clipboardString); | ||||
|     free(_glfw.win32.rawInput); | ||||
|  | ||||
|     _glfwTerminateWGL(); | ||||
|     _glfwTerminateEGL(); | ||||
|  | ||||
|     _glfwTerminateJoysticksWin32(); | ||||
|  | ||||
|     freeLibraries(); | ||||
| } | ||||
|  | ||||
| const char* _glfwPlatformGetVersionString(void) | ||||
| { | ||||
|     return _GLFW_VERSION_NUMBER " Win32 WGL EGL OSMesa" | ||||
| #if defined(__MINGW32__) | ||||
|         " MinGW" | ||||
| #elif defined(_MSC_VER) | ||||
|         " VisualC" | ||||
| #endif | ||||
| #if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) | ||||
|         " hybrid-GPU" | ||||
| #endif | ||||
| #if defined(_GLFW_BUILD_DLL) | ||||
|         " DLL" | ||||
| #endif | ||||
|         ; | ||||
| } | ||||
|  | ||||
							
								
								
									
										755
									
								
								deps/glfw/src/win32_joystick.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										755
									
								
								deps/glfw/src/win32_joystick.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,755 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Win32 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <math.h> | ||||
|  | ||||
| #define _GLFW_TYPE_AXIS     0 | ||||
| #define _GLFW_TYPE_SLIDER   1 | ||||
| #define _GLFW_TYPE_BUTTON   2 | ||||
| #define _GLFW_TYPE_POV      3 | ||||
|  | ||||
| // Data produced with DirectInput device object enumeration | ||||
| // | ||||
| typedef struct _GLFWobjenumWin32 | ||||
| { | ||||
|     IDirectInputDevice8W*   device; | ||||
|     _GLFWjoyobjectWin32*    objects; | ||||
|     int                     objectCount; | ||||
|     int                     axisCount; | ||||
|     int                     sliderCount; | ||||
|     int                     buttonCount; | ||||
|     int                     povCount; | ||||
| } _GLFWobjenumWin32; | ||||
|  | ||||
| // Define local copies of the necessary GUIDs | ||||
| // | ||||
| static const GUID _glfw_IID_IDirectInput8W = | ||||
|     {0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}}; | ||||
| static const GUID _glfw_GUID_XAxis = | ||||
|     {0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
| static const GUID _glfw_GUID_YAxis = | ||||
|     {0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
| static const GUID _glfw_GUID_ZAxis = | ||||
|     {0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
| static const GUID _glfw_GUID_RxAxis = | ||||
|     {0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
| static const GUID _glfw_GUID_RyAxis = | ||||
|     {0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
| static const GUID _glfw_GUID_RzAxis = | ||||
|     {0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
| static const GUID _glfw_GUID_Slider = | ||||
|     {0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
| static const GUID _glfw_GUID_POV = | ||||
|     {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}}; | ||||
|  | ||||
| #define IID_IDirectInput8W _glfw_IID_IDirectInput8W | ||||
| #define GUID_XAxis _glfw_GUID_XAxis | ||||
| #define GUID_YAxis _glfw_GUID_YAxis | ||||
| #define GUID_ZAxis _glfw_GUID_ZAxis | ||||
| #define GUID_RxAxis _glfw_GUID_RxAxis | ||||
| #define GUID_RyAxis _glfw_GUID_RyAxis | ||||
| #define GUID_RzAxis _glfw_GUID_RzAxis | ||||
| #define GUID_Slider _glfw_GUID_Slider | ||||
| #define GUID_POV _glfw_GUID_POV | ||||
|  | ||||
| // Object data array for our clone of c_dfDIJoystick | ||||
| // Generated with https://github.com/elmindreda/c_dfDIJoystick2 | ||||
| // | ||||
| static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] = | ||||
| { | ||||
|     { &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, | ||||
|     { &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
|     { NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, | ||||
| }; | ||||
|  | ||||
| // Our clone of c_dfDIJoystick | ||||
| // | ||||
| static const DIDATAFORMAT _glfwDataFormat = | ||||
| { | ||||
|     sizeof(DIDATAFORMAT), | ||||
|     sizeof(DIOBJECTDATAFORMAT), | ||||
|     DIDFT_ABSAXIS, | ||||
|     sizeof(DIJOYSTATE), | ||||
|     sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT), | ||||
|     _glfwObjectDataFormats | ||||
| }; | ||||
|  | ||||
| // Returns a description fitting the specified XInput capabilities | ||||
| // | ||||
| static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic) | ||||
| { | ||||
|     switch (xic->SubType) | ||||
|     { | ||||
|         case XINPUT_DEVSUBTYPE_WHEEL: | ||||
|             return "XInput Wheel"; | ||||
|         case XINPUT_DEVSUBTYPE_ARCADE_STICK: | ||||
|             return "XInput Arcade Stick"; | ||||
|         case XINPUT_DEVSUBTYPE_FLIGHT_STICK: | ||||
|             return "XInput Flight Stick"; | ||||
|         case XINPUT_DEVSUBTYPE_DANCE_PAD: | ||||
|             return "XInput Dance Pad"; | ||||
|         case XINPUT_DEVSUBTYPE_GUITAR: | ||||
|             return "XInput Guitar"; | ||||
|         case XINPUT_DEVSUBTYPE_DRUM_KIT: | ||||
|             return "XInput Drum Kit"; | ||||
|         case XINPUT_DEVSUBTYPE_GAMEPAD: | ||||
|         { | ||||
|             if (xic->Flags & XINPUT_CAPS_WIRELESS) | ||||
|                 return "Wireless Xbox Controller"; | ||||
|             else | ||||
|                 return "Xbox Controller"; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return "Unknown XInput Device"; | ||||
| } | ||||
|  | ||||
| // Lexically compare device objects | ||||
| // | ||||
| static int compareJoystickObjects(const void* first, const void* second) | ||||
| { | ||||
|     const _GLFWjoyobjectWin32* fo = first; | ||||
|     const _GLFWjoyobjectWin32* so = second; | ||||
|  | ||||
|     if (fo->type != so->type) | ||||
|         return fo->type - so->type; | ||||
|  | ||||
|     return fo->offset - so->offset; | ||||
| } | ||||
|  | ||||
| // Checks whether the specified device supports XInput | ||||
| // Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom | ||||
| // | ||||
| static GLFWbool supportsXInput(const GUID* guid) | ||||
| { | ||||
|     UINT i, count = 0; | ||||
|     RAWINPUTDEVICELIST* ridl; | ||||
|     GLFWbool result = GLFW_FALSE; | ||||
|  | ||||
|     if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0) | ||||
|         return GLFW_FALSE; | ||||
|  | ||||
|     ridl = calloc(count, sizeof(RAWINPUTDEVICELIST)); | ||||
|  | ||||
|     if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1) | ||||
|     { | ||||
|         free(ridl); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     for (i = 0;  i < count;  i++) | ||||
|     { | ||||
|         RID_DEVICE_INFO rdi; | ||||
|         char name[256]; | ||||
|         UINT size; | ||||
|  | ||||
|         if (ridl[i].dwType != RIM_TYPEHID) | ||||
|             continue; | ||||
|  | ||||
|         ZeroMemory(&rdi, sizeof(rdi)); | ||||
|         rdi.cbSize = sizeof(rdi); | ||||
|         size = sizeof(rdi); | ||||
|  | ||||
|         if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice, | ||||
|                                          RIDI_DEVICEINFO, | ||||
|                                          &rdi, &size) == -1) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1) | ||||
|             continue; | ||||
|  | ||||
|         memset(name, 0, sizeof(name)); | ||||
|         size = sizeof(name); | ||||
|  | ||||
|         if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice, | ||||
|                                          RIDI_DEVICENAME, | ||||
|                                          name, &size) == -1) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         name[sizeof(name) - 1] = '\0'; | ||||
|         if (strstr(name, "IG_")) | ||||
|         { | ||||
|             result = GLFW_TRUE; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     free(ridl); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| // Frees all resources associated with the specified joystick | ||||
| // | ||||
| static void closeJoystick(_GLFWjoystick* js) | ||||
| { | ||||
|     if (js->win32.device) | ||||
|     { | ||||
|         IDirectInputDevice8_Unacquire(js->win32.device); | ||||
|         IDirectInputDevice8_Release(js->win32.device); | ||||
|     } | ||||
|  | ||||
|     free(js->win32.objects); | ||||
|  | ||||
|     _glfwFreeJoystick(js); | ||||
|     _glfwInputJoystick(js, GLFW_DISCONNECTED); | ||||
| } | ||||
|  | ||||
| // DirectInput device object enumeration callback | ||||
| // Insights gleaned from SDL | ||||
| // | ||||
| static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi, | ||||
|                                           void* user) | ||||
| { | ||||
|     _GLFWobjenumWin32* data = user; | ||||
|     _GLFWjoyobjectWin32* object = data->objects + data->objectCount; | ||||
|  | ||||
|     if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS) | ||||
|     { | ||||
|         DIPROPRANGE dipr; | ||||
|  | ||||
|         if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0) | ||||
|             object->offset = DIJOFS_SLIDER(data->sliderCount); | ||||
|         else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0) | ||||
|             object->offset = DIJOFS_X; | ||||
|         else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0) | ||||
|             object->offset = DIJOFS_Y; | ||||
|         else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0) | ||||
|             object->offset = DIJOFS_Z; | ||||
|         else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0) | ||||
|             object->offset = DIJOFS_RX; | ||||
|         else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0) | ||||
|             object->offset = DIJOFS_RY; | ||||
|         else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0) | ||||
|             object->offset = DIJOFS_RZ; | ||||
|         else | ||||
|             return DIENUM_CONTINUE; | ||||
|  | ||||
|         ZeroMemory(&dipr, sizeof(dipr)); | ||||
|         dipr.diph.dwSize = sizeof(dipr); | ||||
|         dipr.diph.dwHeaderSize = sizeof(dipr.diph); | ||||
|         dipr.diph.dwObj = doi->dwType; | ||||
|         dipr.diph.dwHow = DIPH_BYID; | ||||
|         dipr.lMin = -32768; | ||||
|         dipr.lMax =  32767; | ||||
|  | ||||
|         if (FAILED(IDirectInputDevice8_SetProperty(data->device, | ||||
|                                                    DIPROP_RANGE, | ||||
|                                                    &dipr.diph))) | ||||
|         { | ||||
|             return DIENUM_CONTINUE; | ||||
|         } | ||||
|  | ||||
|         if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0) | ||||
|         { | ||||
|             object->type = _GLFW_TYPE_SLIDER; | ||||
|             data->sliderCount++; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             object->type = _GLFW_TYPE_AXIS; | ||||
|             data->axisCount++; | ||||
|         } | ||||
|     } | ||||
|     else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON) | ||||
|     { | ||||
|         object->offset = DIJOFS_BUTTON(data->buttonCount); | ||||
|         object->type = _GLFW_TYPE_BUTTON; | ||||
|         data->buttonCount++; | ||||
|     } | ||||
|     else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV) | ||||
|     { | ||||
|         object->offset = DIJOFS_POV(data->povCount); | ||||
|         object->type = _GLFW_TYPE_POV; | ||||
|         data->povCount++; | ||||
|     } | ||||
|  | ||||
|     data->objectCount++; | ||||
|     return DIENUM_CONTINUE; | ||||
| } | ||||
|  | ||||
| // DirectInput device enumeration callback | ||||
| // | ||||
| static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) | ||||
| { | ||||
|     int jid = 0; | ||||
|     DIDEVCAPS dc; | ||||
|     DIPROPDWORD dipd; | ||||
|     IDirectInputDevice8* device; | ||||
|     _GLFWobjenumWin32 data; | ||||
|     _GLFWjoystick* js; | ||||
|     char guid[33]; | ||||
|     char name[256]; | ||||
|  | ||||
|     for (jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|     { | ||||
|         js = _glfw.joysticks + jid; | ||||
|         if (js->present) | ||||
|         { | ||||
|             if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0) | ||||
|                 return DIENUM_CONTINUE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (supportsXInput(&di->guidProduct)) | ||||
|         return DIENUM_CONTINUE; | ||||
|  | ||||
|     if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api, | ||||
|                                           &di->guidInstance, | ||||
|                                           &device, | ||||
|                                           NULL))) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device"); | ||||
|         return DIENUM_CONTINUE; | ||||
|     } | ||||
|  | ||||
|     if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat))) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Win32: Failed to set device data format"); | ||||
|  | ||||
|         IDirectInputDevice8_Release(device); | ||||
|         return DIENUM_CONTINUE; | ||||
|     } | ||||
|  | ||||
|     ZeroMemory(&dc, sizeof(dc)); | ||||
|     dc.dwSize = sizeof(dc); | ||||
|  | ||||
|     if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc))) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Win32: Failed to query device capabilities"); | ||||
|  | ||||
|         IDirectInputDevice8_Release(device); | ||||
|         return DIENUM_CONTINUE; | ||||
|     } | ||||
|  | ||||
|     ZeroMemory(&dipd, sizeof(dipd)); | ||||
|     dipd.diph.dwSize = sizeof(dipd); | ||||
|     dipd.diph.dwHeaderSize = sizeof(dipd.diph); | ||||
|     dipd.diph.dwHow = DIPH_DEVICE; | ||||
|     dipd.dwData = DIPROPAXISMODE_ABS; | ||||
|  | ||||
|     if (FAILED(IDirectInputDevice8_SetProperty(device, | ||||
|                                                DIPROP_AXISMODE, | ||||
|                                                &dipd.diph))) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Win32: Failed to set device axis mode"); | ||||
|  | ||||
|         IDirectInputDevice8_Release(device); | ||||
|         return DIENUM_CONTINUE; | ||||
|     } | ||||
|  | ||||
|     memset(&data, 0, sizeof(data)); | ||||
|     data.device = device; | ||||
|     data.objects = calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs, | ||||
|                           sizeof(_GLFWjoyobjectWin32)); | ||||
|  | ||||
|     if (FAILED(IDirectInputDevice8_EnumObjects(device, | ||||
|                                                deviceObjectCallback, | ||||
|                                                &data, | ||||
|                                                DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV))) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Win32: Failed to enumerate device objects"); | ||||
|  | ||||
|         IDirectInputDevice8_Release(device); | ||||
|         free(data.objects); | ||||
|         return DIENUM_CONTINUE; | ||||
|     } | ||||
|  | ||||
|     qsort(data.objects, data.objectCount, | ||||
|           sizeof(_GLFWjoyobjectWin32), | ||||
|           compareJoystickObjects); | ||||
|  | ||||
|     if (!WideCharToMultiByte(CP_UTF8, 0, | ||||
|                              di->tszInstanceName, -1, | ||||
|                              name, sizeof(name), | ||||
|                              NULL, NULL)) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Win32: Failed to convert joystick name to UTF-8"); | ||||
|  | ||||
|         IDirectInputDevice8_Release(device); | ||||
|         free(data.objects); | ||||
|         return DIENUM_STOP; | ||||
|     } | ||||
|  | ||||
|     // Generate a joystick GUID that matches the SDL 2.0.5+ one | ||||
|     if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0) | ||||
|     { | ||||
|         sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000", | ||||
|                 (uint8_t) di->guidProduct.Data1, | ||||
|                 (uint8_t) (di->guidProduct.Data1 >> 8), | ||||
|                 (uint8_t) (di->guidProduct.Data1 >> 16), | ||||
|                 (uint8_t) (di->guidProduct.Data1 >> 24)); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00", | ||||
|                 name[0], name[1], name[2], name[3], | ||||
|                 name[4], name[5], name[6], name[7], | ||||
|                 name[8], name[9], name[10]); | ||||
|     } | ||||
|  | ||||
|     js = _glfwAllocJoystick(name, guid, | ||||
|                             data.axisCount + data.sliderCount, | ||||
|                             data.buttonCount, | ||||
|                             data.povCount); | ||||
|     if (!js) | ||||
|     { | ||||
|         IDirectInputDevice8_Release(device); | ||||
|         free(data.objects); | ||||
|         return DIENUM_STOP; | ||||
|     } | ||||
|  | ||||
|     js->win32.device = device; | ||||
|     js->win32.guid = di->guidInstance; | ||||
|     js->win32.objects = data.objects; | ||||
|     js->win32.objectCount = data.objectCount; | ||||
|  | ||||
|     _glfwInputJoystick(js, GLFW_CONNECTED); | ||||
|     return DIENUM_CONTINUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialize joystick interface | ||||
| // | ||||
| void _glfwInitJoysticksWin32(void) | ||||
| { | ||||
|     if (_glfw.win32.dinput8.instance) | ||||
|     { | ||||
|         if (FAILED(DirectInput8Create(GetModuleHandle(NULL), | ||||
|                                       DIRECTINPUT_VERSION, | ||||
|                                       &IID_IDirectInput8W, | ||||
|                                       (void**) &_glfw.win32.dinput8.api, | ||||
|                                       NULL))) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "Win32: Failed to create interface"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _glfwDetectJoystickConnectionWin32(); | ||||
| } | ||||
|  | ||||
| // Close all opened joystick handles | ||||
| // | ||||
| void _glfwTerminateJoysticksWin32(void) | ||||
| { | ||||
|     int jid; | ||||
|  | ||||
|     for (jid = GLFW_JOYSTICK_1;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|         closeJoystick(_glfw.joysticks + jid); | ||||
|  | ||||
|     if (_glfw.win32.dinput8.api) | ||||
|         IDirectInput8_Release(_glfw.win32.dinput8.api); | ||||
| } | ||||
|  | ||||
| // Checks for new joysticks after DBT_DEVICEARRIVAL | ||||
| // | ||||
| void _glfwDetectJoystickConnectionWin32(void) | ||||
| { | ||||
|     if (_glfw.win32.xinput.instance) | ||||
|     { | ||||
|         DWORD index; | ||||
|  | ||||
|         for (index = 0;  index < XUSER_MAX_COUNT;  index++) | ||||
|         { | ||||
|             int jid; | ||||
|             char guid[33]; | ||||
|             XINPUT_CAPABILITIES xic; | ||||
|             _GLFWjoystick* js; | ||||
|  | ||||
|             for (jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|             { | ||||
|                 if (_glfw.joysticks[jid].present && | ||||
|                     _glfw.joysticks[jid].win32.device == NULL && | ||||
|                     _glfw.joysticks[jid].win32.index == index) | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (jid <= GLFW_JOYSTICK_LAST) | ||||
|                 continue; | ||||
|  | ||||
|             if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS) | ||||
|                 continue; | ||||
|  | ||||
|             // Generate a joystick GUID that matches the SDL 2.0.5+ one | ||||
|             sprintf(guid, "78696e707574%02x000000000000000000", | ||||
|                     xic.SubType & 0xff); | ||||
|  | ||||
|             js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1); | ||||
|             if (!js) | ||||
|                 continue; | ||||
|  | ||||
|             js->win32.index = index; | ||||
|  | ||||
|             _glfwInputJoystick(js, GLFW_CONNECTED); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (_glfw.win32.dinput8.api) | ||||
|     { | ||||
|         if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api, | ||||
|                                              DI8DEVCLASS_GAMECTRL, | ||||
|                                              deviceCallback, | ||||
|                                              NULL, | ||||
|                                              DIEDFL_ALLDEVICES))) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "Failed to enumerate DirectInput8 devices"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE | ||||
| // | ||||
| void _glfwDetectJoystickDisconnectionWin32(void) | ||||
| { | ||||
|     int jid; | ||||
|  | ||||
|     for (jid = 0;  jid <= GLFW_JOYSTICK_LAST;  jid++) | ||||
|     { | ||||
|         _GLFWjoystick* js = _glfw.joysticks + jid; | ||||
|         if (js->present) | ||||
|             _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) | ||||
| { | ||||
|     if (js->win32.device) | ||||
|     { | ||||
|         int i, ai = 0, bi = 0, pi = 0; | ||||
|         HRESULT result; | ||||
|         DIJOYSTATE state; | ||||
|  | ||||
|         IDirectInputDevice8_Poll(js->win32.device); | ||||
|         result = IDirectInputDevice8_GetDeviceState(js->win32.device, | ||||
|                                                     sizeof(state), | ||||
|                                                     &state); | ||||
|         if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST) | ||||
|         { | ||||
|             IDirectInputDevice8_Acquire(js->win32.device); | ||||
|             IDirectInputDevice8_Poll(js->win32.device); | ||||
|             result = IDirectInputDevice8_GetDeviceState(js->win32.device, | ||||
|                                                         sizeof(state), | ||||
|                                                         &state); | ||||
|         } | ||||
|  | ||||
|         if (FAILED(result)) | ||||
|         { | ||||
|             closeJoystick(js); | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         if (mode == _GLFW_POLL_PRESENCE) | ||||
|             return GLFW_TRUE; | ||||
|  | ||||
|         for (i = 0;  i < js->win32.objectCount;  i++) | ||||
|         { | ||||
|             const void* data = (char*) &state + js->win32.objects[i].offset; | ||||
|  | ||||
|             switch (js->win32.objects[i].type) | ||||
|             { | ||||
|                 case _GLFW_TYPE_AXIS: | ||||
|                 case _GLFW_TYPE_SLIDER: | ||||
|                 { | ||||
|                     const float value = (*((LONG*) data) + 0.5f) / 32767.5f; | ||||
|                     _glfwInputJoystickAxis(js, ai, value); | ||||
|                     ai++; | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 case _GLFW_TYPE_BUTTON: | ||||
|                 { | ||||
|                     const char value = (*((BYTE*) data) & 0x80) != 0; | ||||
|                     _glfwInputJoystickButton(js, bi, value); | ||||
|                     bi++; | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 case _GLFW_TYPE_POV: | ||||
|                 { | ||||
|                     const int states[9] = | ||||
|                     { | ||||
|                         GLFW_HAT_UP, | ||||
|                         GLFW_HAT_RIGHT_UP, | ||||
|                         GLFW_HAT_RIGHT, | ||||
|                         GLFW_HAT_RIGHT_DOWN, | ||||
|                         GLFW_HAT_DOWN, | ||||
|                         GLFW_HAT_LEFT_DOWN, | ||||
|                         GLFW_HAT_LEFT, | ||||
|                         GLFW_HAT_LEFT_UP, | ||||
|                         GLFW_HAT_CENTERED | ||||
|                     }; | ||||
|  | ||||
|                     // Screams of horror are appropriate at this point | ||||
|                     int stateIndex = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES); | ||||
|                     if (stateIndex < 0 || stateIndex > 8) | ||||
|                         stateIndex = 8; | ||||
|  | ||||
|                     _glfwInputJoystickHat(js, pi, states[stateIndex]); | ||||
|                     pi++; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         int i, dpad = 0; | ||||
|         DWORD result; | ||||
|         XINPUT_STATE xis; | ||||
|         const WORD buttons[10] = | ||||
|         { | ||||
|             XINPUT_GAMEPAD_A, | ||||
|             XINPUT_GAMEPAD_B, | ||||
|             XINPUT_GAMEPAD_X, | ||||
|             XINPUT_GAMEPAD_Y, | ||||
|             XINPUT_GAMEPAD_LEFT_SHOULDER, | ||||
|             XINPUT_GAMEPAD_RIGHT_SHOULDER, | ||||
|             XINPUT_GAMEPAD_BACK, | ||||
|             XINPUT_GAMEPAD_START, | ||||
|             XINPUT_GAMEPAD_LEFT_THUMB, | ||||
|             XINPUT_GAMEPAD_RIGHT_THUMB | ||||
|         }; | ||||
|  | ||||
|         result = XInputGetState(js->win32.index, &xis); | ||||
|         if (result != ERROR_SUCCESS) | ||||
|         { | ||||
|             if (result == ERROR_DEVICE_NOT_CONNECTED) | ||||
|                 closeJoystick(js); | ||||
|  | ||||
|             return GLFW_FALSE; | ||||
|         } | ||||
|  | ||||
|         if (mode == _GLFW_POLL_PRESENCE) | ||||
|             return GLFW_TRUE; | ||||
|  | ||||
|         _glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f); | ||||
|         _glfwInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f); | ||||
|         _glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f); | ||||
|         _glfwInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f); | ||||
|         _glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f); | ||||
|         _glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f); | ||||
|  | ||||
|         for (i = 0;  i < 10;  i++) | ||||
|         { | ||||
|             const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0; | ||||
|             _glfwInputJoystickButton(js, i, value); | ||||
|         } | ||||
|  | ||||
|         if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) | ||||
|             dpad |= GLFW_HAT_UP; | ||||
|         if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) | ||||
|             dpad |= GLFW_HAT_RIGHT; | ||||
|         if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) | ||||
|             dpad |= GLFW_HAT_DOWN; | ||||
|         if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) | ||||
|             dpad |= GLFW_HAT_LEFT; | ||||
|  | ||||
|         _glfwInputJoystickHat(js, 0, dpad); | ||||
|     } | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformUpdateGamepadGUID(char* guid) | ||||
| { | ||||
|     if (strcmp(guid + 20, "504944564944") == 0) | ||||
|     { | ||||
|         char original[33]; | ||||
|         strncpy(original, guid, sizeof(original) - 1); | ||||
|         sprintf(guid, "03000000%.4s0000%.4s000000000000", | ||||
|                 original, original + 4); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										57
									
								
								deps/glfw/src/win32_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								deps/glfw/src/win32_joystick.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Win32 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #define _GLFW_PLATFORM_JOYSTICK_STATE         _GLFWjoystickWin32 win32 | ||||
| #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; } | ||||
|  | ||||
| #define _GLFW_PLATFORM_MAPPING_NAME "Windows" | ||||
| #define GLFW_BUILD_WIN32_MAPPINGS | ||||
|  | ||||
| // Joystick element (axis, button or slider) | ||||
| // | ||||
| typedef struct _GLFWjoyobjectWin32 | ||||
| { | ||||
|     int                     offset; | ||||
|     int                     type; | ||||
| } _GLFWjoyobjectWin32; | ||||
|  | ||||
| // Win32-specific per-joystick data | ||||
| // | ||||
| typedef struct _GLFWjoystickWin32 | ||||
| { | ||||
|     _GLFWjoyobjectWin32*    objects; | ||||
|     int                     objectCount; | ||||
|     IDirectInputDevice8W*   device; | ||||
|     DWORD                   index; | ||||
|     GUID                    guid; | ||||
| } _GLFWjoystickWin32; | ||||
|  | ||||
|  | ||||
| void _glfwInitJoysticksWin32(void); | ||||
| void _glfwTerminateJoysticksWin32(void); | ||||
| void _glfwDetectJoystickConnectionWin32(void); | ||||
| void _glfwDetectJoystickDisconnectionWin32(void); | ||||
|  | ||||
							
								
								
									
										548
									
								
								deps/glfw/src/win32_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										548
									
								
								deps/glfw/src/win32_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,548 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Win32 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <limits.h> | ||||
| #include <malloc.h> | ||||
| #include <wchar.h> | ||||
|  | ||||
|  | ||||
| // Callback for EnumDisplayMonitors in createMonitor | ||||
| // | ||||
| static BOOL CALLBACK monitorCallback(HMONITOR handle, | ||||
|                                      HDC dc, | ||||
|                                      RECT* rect, | ||||
|                                      LPARAM data) | ||||
| { | ||||
|     MONITORINFOEXW mi; | ||||
|     ZeroMemory(&mi, sizeof(mi)); | ||||
|     mi.cbSize = sizeof(mi); | ||||
|  | ||||
|     if (GetMonitorInfoW(handle, (MONITORINFO*) &mi)) | ||||
|     { | ||||
|         _GLFWmonitor* monitor = (_GLFWmonitor*) data; | ||||
|         if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0) | ||||
|             monitor->win32.handle = handle; | ||||
|     } | ||||
|  | ||||
|     return TRUE; | ||||
| } | ||||
|  | ||||
| // Create monitor from an adapter and (optionally) a display | ||||
| // | ||||
| static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter, | ||||
|                                    DISPLAY_DEVICEW* display) | ||||
| { | ||||
|     _GLFWmonitor* monitor; | ||||
|     int widthMM, heightMM; | ||||
|     char* name; | ||||
|     HDC dc; | ||||
|     DEVMODEW dm; | ||||
|     RECT rect; | ||||
|  | ||||
|     if (display) | ||||
|         name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString); | ||||
|     else | ||||
|         name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString); | ||||
|     if (!name) | ||||
|         return NULL; | ||||
|  | ||||
|     ZeroMemory(&dm, sizeof(dm)); | ||||
|     dm.dmSize = sizeof(dm); | ||||
|     EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm); | ||||
|  | ||||
|     dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL); | ||||
|  | ||||
|     if (IsWindows8Point1OrGreater()) | ||||
|     { | ||||
|         widthMM  = GetDeviceCaps(dc, HORZSIZE); | ||||
|         heightMM = GetDeviceCaps(dc, VERTSIZE); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         widthMM  = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX)); | ||||
|         heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY)); | ||||
|     } | ||||
|  | ||||
|     DeleteDC(dc); | ||||
|  | ||||
|     monitor = _glfwAllocMonitor(name, widthMM, heightMM); | ||||
|     free(name); | ||||
|  | ||||
|     if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED) | ||||
|         monitor->win32.modesPruned = GLFW_TRUE; | ||||
|  | ||||
|     wcscpy(monitor->win32.adapterName, adapter->DeviceName); | ||||
|     WideCharToMultiByte(CP_UTF8, 0, | ||||
|                         adapter->DeviceName, -1, | ||||
|                         monitor->win32.publicAdapterName, | ||||
|                         sizeof(monitor->win32.publicAdapterName), | ||||
|                         NULL, NULL); | ||||
|  | ||||
|     if (display) | ||||
|     { | ||||
|         wcscpy(monitor->win32.displayName, display->DeviceName); | ||||
|         WideCharToMultiByte(CP_UTF8, 0, | ||||
|                             display->DeviceName, -1, | ||||
|                             monitor->win32.publicDisplayName, | ||||
|                             sizeof(monitor->win32.publicDisplayName), | ||||
|                             NULL, NULL); | ||||
|     } | ||||
|  | ||||
|     rect.left   = dm.dmPosition.x; | ||||
|     rect.top    = dm.dmPosition.y; | ||||
|     rect.right  = dm.dmPosition.x + dm.dmPelsWidth; | ||||
|     rect.bottom = dm.dmPosition.y + dm.dmPelsHeight; | ||||
|  | ||||
|     EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor); | ||||
|     return monitor; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Poll for changes in the set of connected monitors | ||||
| // | ||||
| void _glfwPollMonitorsWin32(void) | ||||
| { | ||||
|     int i, disconnectedCount; | ||||
|     _GLFWmonitor** disconnected = NULL; | ||||
|     DWORD adapterIndex, displayIndex; | ||||
|     DISPLAY_DEVICEW adapter, display; | ||||
|     _GLFWmonitor* monitor; | ||||
|  | ||||
|     disconnectedCount = _glfw.monitorCount; | ||||
|     if (disconnectedCount) | ||||
|     { | ||||
|         disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); | ||||
|         memcpy(disconnected, | ||||
|                _glfw.monitors, | ||||
|                _glfw.monitorCount * sizeof(_GLFWmonitor*)); | ||||
|     } | ||||
|  | ||||
|     for (adapterIndex = 0;  ;  adapterIndex++) | ||||
|     { | ||||
|         int type = _GLFW_INSERT_LAST; | ||||
|  | ||||
|         ZeroMemory(&adapter, sizeof(adapter)); | ||||
|         adapter.cb = sizeof(adapter); | ||||
|  | ||||
|         if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0)) | ||||
|             break; | ||||
|  | ||||
|         if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE)) | ||||
|             continue; | ||||
|  | ||||
|         if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) | ||||
|             type = _GLFW_INSERT_FIRST; | ||||
|  | ||||
|         for (displayIndex = 0;  ;  displayIndex++) | ||||
|         { | ||||
|             ZeroMemory(&display, sizeof(display)); | ||||
|             display.cb = sizeof(display); | ||||
|  | ||||
|             if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0)) | ||||
|                 break; | ||||
|  | ||||
|             if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE)) | ||||
|                 continue; | ||||
|  | ||||
|             for (i = 0;  i < disconnectedCount;  i++) | ||||
|             { | ||||
|                 if (disconnected[i] && | ||||
|                     wcscmp(disconnected[i]->win32.displayName, | ||||
|                            display.DeviceName) == 0) | ||||
|                 { | ||||
|                     disconnected[i] = NULL; | ||||
|                     // handle may have changed, update | ||||
|                     EnumDisplayMonitors(NULL, NULL, monitorCallback, (LPARAM) _glfw.monitors[i]); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (i < disconnectedCount) | ||||
|                 continue; | ||||
|  | ||||
|             monitor = createMonitor(&adapter, &display); | ||||
|             if (!monitor) | ||||
|             { | ||||
|                 free(disconnected); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             _glfwInputMonitor(monitor, GLFW_CONNECTED, type); | ||||
|  | ||||
|             type = _GLFW_INSERT_LAST; | ||||
|         } | ||||
|  | ||||
|         // HACK: If an active adapter does not have any display devices | ||||
|         //       (as sometimes happens), add it directly as a monitor | ||||
|         if (displayIndex == 0) | ||||
|         { | ||||
|             for (i = 0;  i < disconnectedCount;  i++) | ||||
|             { | ||||
|                 if (disconnected[i] && | ||||
|                     wcscmp(disconnected[i]->win32.adapterName, | ||||
|                            adapter.DeviceName) == 0) | ||||
|                 { | ||||
|                     disconnected[i] = NULL; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (i < disconnectedCount) | ||||
|                 continue; | ||||
|  | ||||
|             monitor = createMonitor(&adapter, NULL); | ||||
|             if (!monitor) | ||||
|             { | ||||
|                 free(disconnected); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             _glfwInputMonitor(monitor, GLFW_CONNECTED, type); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     for (i = 0;  i < disconnectedCount;  i++) | ||||
|     { | ||||
|         if (disconnected[i]) | ||||
|             _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); | ||||
|     } | ||||
|  | ||||
|     free(disconnected); | ||||
| } | ||||
|  | ||||
| // Change the current video mode | ||||
| // | ||||
| void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired) | ||||
| { | ||||
|     GLFWvidmode current; | ||||
|     const GLFWvidmode* best; | ||||
|     DEVMODEW dm; | ||||
|     LONG result; | ||||
|  | ||||
|     best = _glfwChooseVideoMode(monitor, desired); | ||||
|     _glfwPlatformGetVideoMode(monitor, ¤t); | ||||
|     if (_glfwCompareVideoModes(¤t, best) == 0) | ||||
|         return; | ||||
|  | ||||
|     ZeroMemory(&dm, sizeof(dm)); | ||||
|     dm.dmSize = sizeof(dm); | ||||
|     dm.dmFields           = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | | ||||
|                             DM_DISPLAYFREQUENCY; | ||||
|     dm.dmPelsWidth        = best->width; | ||||
|     dm.dmPelsHeight       = best->height; | ||||
|     dm.dmBitsPerPel       = best->redBits + best->greenBits + best->blueBits; | ||||
|     dm.dmDisplayFrequency = best->refreshRate; | ||||
|  | ||||
|     if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24) | ||||
|         dm.dmBitsPerPel = 32; | ||||
|  | ||||
|     result = ChangeDisplaySettingsExW(monitor->win32.adapterName, | ||||
|                                       &dm, | ||||
|                                       NULL, | ||||
|                                       CDS_FULLSCREEN, | ||||
|                                       NULL); | ||||
|     if (result == DISP_CHANGE_SUCCESSFUL) | ||||
|         monitor->win32.modeChanged = GLFW_TRUE; | ||||
|     else | ||||
|     { | ||||
|         const char* description = "Unknown error"; | ||||
|  | ||||
|         if (result == DISP_CHANGE_BADDUALVIEW) | ||||
|             description = "The system uses DualView"; | ||||
|         else if (result == DISP_CHANGE_BADFLAGS) | ||||
|             description = "Invalid flags"; | ||||
|         else if (result == DISP_CHANGE_BADMODE) | ||||
|             description = "Graphics mode not supported"; | ||||
|         else if (result == DISP_CHANGE_BADPARAM) | ||||
|             description = "Invalid parameter"; | ||||
|         else if (result == DISP_CHANGE_FAILED) | ||||
|             description = "Graphics mode failed"; | ||||
|         else if (result == DISP_CHANGE_NOTUPDATED) | ||||
|             description = "Failed to write to registry"; | ||||
|         else if (result == DISP_CHANGE_RESTART) | ||||
|             description = "Computer restart required"; | ||||
|  | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Win32: Failed to set video mode: %s", | ||||
|                         description); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Restore the previously saved (original) video mode | ||||
| // | ||||
| void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor) | ||||
| { | ||||
|     if (monitor->win32.modeChanged) | ||||
|     { | ||||
|         ChangeDisplaySettingsExW(monitor->win32.adapterName, | ||||
|                                  NULL, NULL, CDS_FULLSCREEN, NULL); | ||||
|         monitor->win32.modeChanged = GLFW_FALSE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale) | ||||
| { | ||||
|     UINT xdpi, ydpi; | ||||
|  | ||||
|     if (xscale) | ||||
|         *xscale = 0.f; | ||||
|     if (yscale) | ||||
|         *yscale = 0.f; | ||||
|  | ||||
|     if (IsWindows8Point1OrGreater()) | ||||
|     { | ||||
|         if (GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi) != S_OK) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query monitor DPI"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         const HDC dc = GetDC(NULL); | ||||
|         xdpi = GetDeviceCaps(dc, LOGPIXELSX); | ||||
|         ydpi = GetDeviceCaps(dc, LOGPIXELSY); | ||||
|         ReleaseDC(NULL, dc); | ||||
|     } | ||||
|  | ||||
|     if (xscale) | ||||
|         *xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI; | ||||
|     if (yscale) | ||||
|         *yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) | ||||
| { | ||||
|     DEVMODEW dm; | ||||
|     ZeroMemory(&dm, sizeof(dm)); | ||||
|     dm.dmSize = sizeof(dm); | ||||
|  | ||||
|     EnumDisplaySettingsExW(monitor->win32.adapterName, | ||||
|                            ENUM_CURRENT_SETTINGS, | ||||
|                            &dm, | ||||
|                            EDS_ROTATEDMODE); | ||||
|  | ||||
|     if (xpos) | ||||
|         *xpos = dm.dmPosition.x; | ||||
|     if (ypos) | ||||
|         *ypos = dm.dmPosition.y; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, | ||||
|                                          float* xscale, float* yscale) | ||||
| { | ||||
|     _glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, | ||||
|                                      int* xpos, int* ypos, | ||||
|                                      int* width, int* height) | ||||
| { | ||||
|     MONITORINFO mi = { sizeof(mi) }; | ||||
|     GetMonitorInfo(monitor->win32.handle, &mi); | ||||
|  | ||||
|     if (xpos) | ||||
|         *xpos = mi.rcWork.left; | ||||
|     if (ypos) | ||||
|         *ypos = mi.rcWork.top; | ||||
|     if (width) | ||||
|         *width = mi.rcWork.right - mi.rcWork.left; | ||||
|     if (height) | ||||
|         *height = mi.rcWork.bottom - mi.rcWork.top; | ||||
| } | ||||
|  | ||||
| GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) | ||||
| { | ||||
|     int modeIndex = 0, size = 0; | ||||
|     GLFWvidmode* result = NULL; | ||||
|  | ||||
|     *count = 0; | ||||
|  | ||||
|     for (;;) | ||||
|     { | ||||
|         int i; | ||||
|         GLFWvidmode mode; | ||||
|         DEVMODEW dm; | ||||
|  | ||||
|         ZeroMemory(&dm, sizeof(dm)); | ||||
|         dm.dmSize = sizeof(dm); | ||||
|  | ||||
|         if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm)) | ||||
|             break; | ||||
|  | ||||
|         modeIndex++; | ||||
|  | ||||
|         // Skip modes with less than 15 BPP | ||||
|         if (dm.dmBitsPerPel < 15) | ||||
|             continue; | ||||
|  | ||||
|         mode.width  = dm.dmPelsWidth; | ||||
|         mode.height = dm.dmPelsHeight; | ||||
|         mode.refreshRate = dm.dmDisplayFrequency; | ||||
|         _glfwSplitBPP(dm.dmBitsPerPel, | ||||
|                       &mode.redBits, | ||||
|                       &mode.greenBits, | ||||
|                       &mode.blueBits); | ||||
|  | ||||
|         for (i = 0;  i < *count;  i++) | ||||
|         { | ||||
|             if (_glfwCompareVideoModes(result + i, &mode) == 0) | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         // Skip duplicate modes | ||||
|         if (i < *count) | ||||
|             continue; | ||||
|  | ||||
|         if (monitor->win32.modesPruned) | ||||
|         { | ||||
|             // Skip modes not supported by the connected displays | ||||
|             if (ChangeDisplaySettingsExW(monitor->win32.adapterName, | ||||
|                                          &dm, | ||||
|                                          NULL, | ||||
|                                          CDS_TEST, | ||||
|                                          NULL) != DISP_CHANGE_SUCCESSFUL) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (*count == size) | ||||
|         { | ||||
|             size += 128; | ||||
|             result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode)); | ||||
|         } | ||||
|  | ||||
|         (*count)++; | ||||
|         result[*count - 1] = mode; | ||||
|     } | ||||
|  | ||||
|     if (!*count) | ||||
|     { | ||||
|         // HACK: Report the current mode if no valid modes were found | ||||
|         result = calloc(1, sizeof(GLFWvidmode)); | ||||
|         _glfwPlatformGetVideoMode(monitor, result); | ||||
|         *count = 1; | ||||
|     } | ||||
|  | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) | ||||
| { | ||||
|     DEVMODEW dm; | ||||
|     ZeroMemory(&dm, sizeof(dm)); | ||||
|     dm.dmSize = sizeof(dm); | ||||
|  | ||||
|     EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm); | ||||
|  | ||||
|     mode->width  = dm.dmPelsWidth; | ||||
|     mode->height = dm.dmPelsHeight; | ||||
|     mode->refreshRate = dm.dmDisplayFrequency; | ||||
|     _glfwSplitBPP(dm.dmBitsPerPel, | ||||
|                   &mode->redBits, | ||||
|                   &mode->greenBits, | ||||
|                   &mode->blueBits); | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) | ||||
| { | ||||
|     HDC dc; | ||||
|     WORD values[3][256]; | ||||
|  | ||||
|     dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL); | ||||
|     GetDeviceGammaRamp(dc, values); | ||||
|     DeleteDC(dc); | ||||
|  | ||||
|     _glfwAllocGammaArrays(ramp, 256); | ||||
|  | ||||
|     memcpy(ramp->red,   values[0], sizeof(values[0])); | ||||
|     memcpy(ramp->green, values[1], sizeof(values[1])); | ||||
|     memcpy(ramp->blue,  values[2], sizeof(values[2])); | ||||
|  | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) | ||||
| { | ||||
|     HDC dc; | ||||
|     WORD values[3][256]; | ||||
|  | ||||
|     if (ramp->size != 256) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Win32: Gamma ramp size must be 256"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     memcpy(values[0], ramp->red,   sizeof(values[0])); | ||||
|     memcpy(values[1], ramp->green, sizeof(values[1])); | ||||
|     memcpy(values[2], ramp->blue,  sizeof(values[2])); | ||||
|  | ||||
|     dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL); | ||||
|     SetDeviceGammaRamp(dc, values); | ||||
|     DeleteDC(dc); | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|     return monitor->win32.publicAdapterName; | ||||
| } | ||||
|  | ||||
| GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|     return monitor->win32.publicDisplayName; | ||||
| } | ||||
|  | ||||
							
								
								
									
										452
									
								
								deps/glfw/src/win32_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										452
									
								
								deps/glfw/src/win32_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,452 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Win32 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| // We don't need all the fancy stuff | ||||
| #ifndef NOMINMAX | ||||
|  #define NOMINMAX | ||||
| #endif | ||||
|  | ||||
| #ifndef VC_EXTRALEAN | ||||
|  #define VC_EXTRALEAN | ||||
| #endif | ||||
|  | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
|  #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
|  | ||||
| // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for | ||||
| // example to allow applications to correctly declare a GL_KHR_debug callback) | ||||
| // but windows.h assumes no one will define APIENTRY before it does | ||||
| #undef APIENTRY | ||||
|  | ||||
| // GLFW on Windows is Unicode only and does not work in MBCS mode | ||||
| #ifndef UNICODE | ||||
|  #define UNICODE | ||||
| #endif | ||||
|  | ||||
| // GLFW requires Windows XP or later | ||||
| #if WINVER < 0x0501 | ||||
|  #undef WINVER | ||||
|  #define WINVER 0x0501 | ||||
| #endif | ||||
| #if _WIN32_WINNT < 0x0501 | ||||
|  #undef _WIN32_WINNT | ||||
|  #define _WIN32_WINNT 0x0501 | ||||
| #endif | ||||
|  | ||||
| // GLFW uses DirectInput8 interfaces | ||||
| #define DIRECTINPUT_VERSION 0x0800 | ||||
|  | ||||
| // GLFW uses OEM cursor resources | ||||
| #define OEMRESOURCE | ||||
|  | ||||
| #include <wctype.h> | ||||
| #include <windows.h> | ||||
| #include <dinput.h> | ||||
| #include <xinput.h> | ||||
| #include <dbt.h> | ||||
|  | ||||
| // HACK: Define macros that some windows.h variants don't | ||||
| #ifndef WM_MOUSEHWHEEL | ||||
|  #define WM_MOUSEHWHEEL 0x020E | ||||
| #endif | ||||
| #ifndef WM_DWMCOMPOSITIONCHANGED | ||||
|  #define WM_DWMCOMPOSITIONCHANGED 0x031E | ||||
| #endif | ||||
| #ifndef WM_DWMCOLORIZATIONCOLORCHANGED | ||||
|  #define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 | ||||
| #endif | ||||
| #ifndef WM_COPYGLOBALDATA | ||||
|  #define WM_COPYGLOBALDATA 0x0049 | ||||
| #endif | ||||
| #ifndef WM_UNICHAR | ||||
|  #define WM_UNICHAR 0x0109 | ||||
| #endif | ||||
| #ifndef UNICODE_NOCHAR | ||||
|  #define UNICODE_NOCHAR 0xFFFF | ||||
| #endif | ||||
| #ifndef WM_DPICHANGED | ||||
|  #define WM_DPICHANGED 0x02E0 | ||||
| #endif | ||||
| #ifndef GET_XBUTTON_WPARAM | ||||
|  #define GET_XBUTTON_WPARAM(w) (HIWORD(w)) | ||||
| #endif | ||||
| #ifndef EDS_ROTATEDMODE | ||||
|  #define EDS_ROTATEDMODE 0x00000004 | ||||
| #endif | ||||
| #ifndef DISPLAY_DEVICE_ACTIVE | ||||
|  #define DISPLAY_DEVICE_ACTIVE 0x00000001 | ||||
| #endif | ||||
| #ifndef _WIN32_WINNT_WINBLUE | ||||
|  #define _WIN32_WINNT_WINBLUE 0x0603 | ||||
| #endif | ||||
| #ifndef _WIN32_WINNT_WIN8 | ||||
|  #define _WIN32_WINNT_WIN8 0x0602 | ||||
| #endif | ||||
| #ifndef WM_GETDPISCALEDSIZE | ||||
|  #define WM_GETDPISCALEDSIZE 0x02e4 | ||||
| #endif | ||||
| #ifndef USER_DEFAULT_SCREEN_DPI | ||||
|  #define USER_DEFAULT_SCREEN_DPI 96 | ||||
| #endif | ||||
| #ifndef OCR_HAND | ||||
|  #define OCR_HAND 32649 | ||||
| #endif | ||||
|  | ||||
| #if WINVER < 0x0601 | ||||
| typedef struct | ||||
| { | ||||
|     DWORD cbSize; | ||||
|     DWORD ExtStatus; | ||||
| } CHANGEFILTERSTRUCT; | ||||
| #ifndef MSGFLT_ALLOW | ||||
|  #define MSGFLT_ALLOW 1 | ||||
| #endif | ||||
| #endif /*Windows 7*/ | ||||
|  | ||||
| #if WINVER < 0x0600 | ||||
| #define DWM_BB_ENABLE 0x00000001 | ||||
| #define DWM_BB_BLURREGION 0x00000002 | ||||
| typedef struct | ||||
| { | ||||
|     DWORD dwFlags; | ||||
|     BOOL fEnable; | ||||
|     HRGN hRgnBlur; | ||||
|     BOOL fTransitionOnMaximized; | ||||
| } DWM_BLURBEHIND; | ||||
| #else | ||||
|  #include <dwmapi.h> | ||||
| #endif /*Windows Vista*/ | ||||
|  | ||||
| #ifndef DPI_ENUMS_DECLARED | ||||
| typedef enum | ||||
| { | ||||
|     PROCESS_DPI_UNAWARE = 0, | ||||
|     PROCESS_SYSTEM_DPI_AWARE = 1, | ||||
|     PROCESS_PER_MONITOR_DPI_AWARE = 2 | ||||
| } PROCESS_DPI_AWARENESS; | ||||
| typedef enum | ||||
| { | ||||
|     MDT_EFFECTIVE_DPI = 0, | ||||
|     MDT_ANGULAR_DPI = 1, | ||||
|     MDT_RAW_DPI = 2, | ||||
|     MDT_DEFAULT = MDT_EFFECTIVE_DPI | ||||
| } MONITOR_DPI_TYPE; | ||||
| #endif /*DPI_ENUMS_DECLARED*/ | ||||
|  | ||||
| #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 | ||||
| #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4) | ||||
| #endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/ | ||||
|  | ||||
| // HACK: Define versionhelpers.h functions manually as MinGW lacks the header | ||||
| #define IsWindowsXPOrGreater()                                 \ | ||||
|     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP),   \ | ||||
|                                         LOBYTE(_WIN32_WINNT_WINXP), 0) | ||||
| #define IsWindowsVistaOrGreater()                                     \ | ||||
|     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA),   \ | ||||
|                                         LOBYTE(_WIN32_WINNT_VISTA), 0) | ||||
| #define IsWindows7OrGreater()                                         \ | ||||
|     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7),    \ | ||||
|                                         LOBYTE(_WIN32_WINNT_WIN7), 0) | ||||
| #define IsWindows8OrGreater()                                         \ | ||||
|     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8),    \ | ||||
|                                         LOBYTE(_WIN32_WINNT_WIN8), 0) | ||||
| #define IsWindows8Point1OrGreater()                                   \ | ||||
|     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \ | ||||
|                                         LOBYTE(_WIN32_WINNT_WINBLUE), 0) | ||||
|  | ||||
| #define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \ | ||||
|     _glfwIsWindows10BuildOrGreaterWin32(14393) | ||||
| #define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \ | ||||
|     _glfwIsWindows10BuildOrGreaterWin32(15063) | ||||
|  | ||||
| // HACK: Define macros that some xinput.h variants don't | ||||
| #ifndef XINPUT_CAPS_WIRELESS | ||||
|  #define XINPUT_CAPS_WIRELESS 0x0002 | ||||
| #endif | ||||
| #ifndef XINPUT_DEVSUBTYPE_WHEEL | ||||
|  #define XINPUT_DEVSUBTYPE_WHEEL 0x02 | ||||
| #endif | ||||
| #ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK | ||||
|  #define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03 | ||||
| #endif | ||||
| #ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK | ||||
|  #define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04 | ||||
| #endif | ||||
| #ifndef XINPUT_DEVSUBTYPE_DANCE_PAD | ||||
|  #define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05 | ||||
| #endif | ||||
| #ifndef XINPUT_DEVSUBTYPE_GUITAR | ||||
|  #define XINPUT_DEVSUBTYPE_GUITAR 0x06 | ||||
| #endif | ||||
| #ifndef XINPUT_DEVSUBTYPE_DRUM_KIT | ||||
|  #define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08 | ||||
| #endif | ||||
| #ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD | ||||
|  #define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13 | ||||
| #endif | ||||
| #ifndef XUSER_MAX_COUNT | ||||
|  #define XUSER_MAX_COUNT 4 | ||||
| #endif | ||||
|  | ||||
| // HACK: Define macros that some dinput.h variants don't | ||||
| #ifndef DIDFT_OPTIONAL | ||||
|  #define DIDFT_OPTIONAL 0x80000000 | ||||
| #endif | ||||
|  | ||||
| // xinput.dll function pointer typedefs | ||||
| typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*); | ||||
| typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*); | ||||
| #define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities | ||||
| #define XInputGetState _glfw.win32.xinput.GetState | ||||
|  | ||||
| // dinput8.dll function pointer typedefs | ||||
| typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN); | ||||
| #define DirectInput8Create _glfw.win32.dinput8.Create | ||||
|  | ||||
| // user32.dll function pointer typedefs | ||||
| typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void); | ||||
| typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*); | ||||
| typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND); | ||||
| typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE); | ||||
| typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND); | ||||
| typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT); | ||||
| #define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_ | ||||
| #define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_ | ||||
| #define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_ | ||||
| #define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_ | ||||
| #define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_ | ||||
| #define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_ | ||||
|  | ||||
| // dwmapi.dll function pointer typedefs | ||||
| typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*); | ||||
| typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID); | ||||
| typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*); | ||||
| typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*); | ||||
| #define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled | ||||
| #define DwmFlush _glfw.win32.dwmapi.Flush | ||||
| #define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow | ||||
| #define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor | ||||
|  | ||||
| // shcore.dll function pointer typedefs | ||||
| typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); | ||||
| typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*); | ||||
| #define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_ | ||||
| #define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_ | ||||
|  | ||||
| // ntdll.dll function pointer typedefs | ||||
| typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG); | ||||
| #define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_ | ||||
|  | ||||
| typedef VkFlags VkWin32SurfaceCreateFlagsKHR; | ||||
|  | ||||
| typedef struct VkWin32SurfaceCreateInfoKHR | ||||
| { | ||||
|     VkStructureType                 sType; | ||||
|     const void*                     pNext; | ||||
|     VkWin32SurfaceCreateFlagsKHR    flags; | ||||
|     HINSTANCE                       hinstance; | ||||
|     HWND                            hwnd; | ||||
| } VkWin32SurfaceCreateInfoKHR; | ||||
|  | ||||
| typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); | ||||
| typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t); | ||||
|  | ||||
| #include "win32_joystick.h" | ||||
| #include "wgl_context.h" | ||||
| #include "egl_context.h" | ||||
| #include "osmesa_context.h" | ||||
|  | ||||
| #if !defined(_GLFW_WNDCLASSNAME) | ||||
|  #define _GLFW_WNDCLASSNAME L"GLFW30" | ||||
| #endif | ||||
|  | ||||
| #define _glfw_dlopen(name) LoadLibraryA(name) | ||||
| #define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) | ||||
| #define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) | ||||
|  | ||||
| #define _GLFW_EGL_NATIVE_WINDOW  ((EGLNativeWindowType) window->win32.handle) | ||||
| #define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY | ||||
|  | ||||
| #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowWin32  win32 | ||||
| #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 | ||||
| #define _GLFW_PLATFORM_LIBRARY_TIMER_STATE  _GLFWtimerWin32   win32 | ||||
| #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorWin32 win32 | ||||
| #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorWin32  win32 | ||||
| #define _GLFW_PLATFORM_TLS_STATE            _GLFWtlsWin32     win32 | ||||
| #define _GLFW_PLATFORM_MUTEX_STATE          _GLFWmutexWin32   win32 | ||||
|  | ||||
|  | ||||
| // Win32-specific per-window data | ||||
| // | ||||
| typedef struct _GLFWwindowWin32 | ||||
| { | ||||
|     HWND                handle; | ||||
|     HICON               bigIcon; | ||||
|     HICON               smallIcon; | ||||
|  | ||||
|     GLFWbool            cursorTracked; | ||||
|     GLFWbool            frameAction; | ||||
|     GLFWbool            iconified; | ||||
|     GLFWbool            maximized; | ||||
|     // Whether to enable framebuffer transparency on DWM | ||||
|     GLFWbool            transparent; | ||||
|     GLFWbool            scaleToMonitor; | ||||
|  | ||||
|     // Cached size used to filter out duplicate events | ||||
|     int                 width, height; | ||||
|  | ||||
|     // The last received cursor position, regardless of source | ||||
|     int                 lastCursorPosX, lastCursorPosY; | ||||
|     // The last recevied high surrogate when decoding pairs of UTF-16 messages | ||||
|     WCHAR               highSurrogate; | ||||
| } _GLFWwindowWin32; | ||||
|  | ||||
| // Win32-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryWin32 | ||||
| { | ||||
|     HWND                helperWindowHandle; | ||||
|     HDEVNOTIFY          deviceNotificationHandle; | ||||
|     DWORD               foregroundLockTimeout; | ||||
|     int                 acquiredMonitorCount; | ||||
|     char*               clipboardString; | ||||
|     short int           keycodes[512]; | ||||
|     short int           scancodes[GLFW_KEY_LAST + 1]; | ||||
|     char                keynames[GLFW_KEY_LAST + 1][5]; | ||||
|     // Where to place the cursor when re-enabled | ||||
|     double              restoreCursorPosX, restoreCursorPosY; | ||||
|     // The window whose disabled cursor mode is active | ||||
|     _GLFWwindow*        disabledCursorWindow; | ||||
|     RAWINPUT*           rawInput; | ||||
|     int                 rawInputSize; | ||||
|     UINT                mouseTrailSize; | ||||
|  | ||||
|     struct { | ||||
|         HINSTANCE                       instance; | ||||
|         PFN_DirectInput8Create          Create; | ||||
|         IDirectInput8W*                 api; | ||||
|     } dinput8; | ||||
|  | ||||
|     struct { | ||||
|         HINSTANCE                       instance; | ||||
|         PFN_XInputGetCapabilities       GetCapabilities; | ||||
|         PFN_XInputGetState              GetState; | ||||
|     } xinput; | ||||
|  | ||||
|     struct { | ||||
|         HINSTANCE                       instance; | ||||
|         PFN_SetProcessDPIAware          SetProcessDPIAware_; | ||||
|         PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_; | ||||
|         PFN_EnableNonClientDpiScaling   EnableNonClientDpiScaling_; | ||||
|         PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_; | ||||
|         PFN_GetDpiForWindow             GetDpiForWindow_; | ||||
|         PFN_AdjustWindowRectExForDpi    AdjustWindowRectExForDpi_; | ||||
|     } user32; | ||||
|  | ||||
|     struct { | ||||
|         HINSTANCE                       instance; | ||||
|         PFN_DwmIsCompositionEnabled     IsCompositionEnabled; | ||||
|         PFN_DwmFlush                    Flush; | ||||
|         PFN_DwmEnableBlurBehindWindow   EnableBlurBehindWindow; | ||||
|         PFN_DwmGetColorizationColor     GetColorizationColor; | ||||
|     } dwmapi; | ||||
|  | ||||
|     struct { | ||||
|         HINSTANCE                       instance; | ||||
|         PFN_SetProcessDpiAwareness      SetProcessDpiAwareness_; | ||||
|         PFN_GetDpiForMonitor            GetDpiForMonitor_; | ||||
|     } shcore; | ||||
|  | ||||
|     struct { | ||||
|         HINSTANCE                       instance; | ||||
|         PFN_RtlVerifyVersionInfo        RtlVerifyVersionInfo_; | ||||
|     } ntdll; | ||||
| } _GLFWlibraryWin32; | ||||
|  | ||||
| // Win32-specific per-monitor data | ||||
| // | ||||
| typedef struct _GLFWmonitorWin32 | ||||
| { | ||||
|     HMONITOR            handle; | ||||
|     // This size matches the static size of DISPLAY_DEVICE.DeviceName | ||||
|     WCHAR               adapterName[32]; | ||||
|     WCHAR               displayName[32]; | ||||
|     char                publicAdapterName[32]; | ||||
|     char                publicDisplayName[32]; | ||||
|     GLFWbool            modesPruned; | ||||
|     GLFWbool            modeChanged; | ||||
| } _GLFWmonitorWin32; | ||||
|  | ||||
| // Win32-specific per-cursor data | ||||
| // | ||||
| typedef struct _GLFWcursorWin32 | ||||
| { | ||||
|     HCURSOR             handle; | ||||
| } _GLFWcursorWin32; | ||||
|  | ||||
| // Win32-specific global timer data | ||||
| // | ||||
| typedef struct _GLFWtimerWin32 | ||||
| { | ||||
|     uint64_t            frequency; | ||||
| } _GLFWtimerWin32; | ||||
|  | ||||
| // Win32-specific thread local storage data | ||||
| // | ||||
| typedef struct _GLFWtlsWin32 | ||||
| { | ||||
|     GLFWbool            allocated; | ||||
|     DWORD               index; | ||||
| } _GLFWtlsWin32; | ||||
|  | ||||
| // Win32-specific mutex data | ||||
| // | ||||
| typedef struct _GLFWmutexWin32 | ||||
| { | ||||
|     GLFWbool            allocated; | ||||
|     CRITICAL_SECTION    section; | ||||
| } _GLFWmutexWin32; | ||||
|  | ||||
|  | ||||
| GLFWbool _glfwRegisterWindowClassWin32(void); | ||||
| void _glfwUnregisterWindowClassWin32(void); | ||||
|  | ||||
| WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source); | ||||
| char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source); | ||||
| BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp); | ||||
| BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build); | ||||
| void _glfwInputErrorWin32(int error, const char* description); | ||||
| void _glfwUpdateKeyNamesWin32(void); | ||||
|  | ||||
| void _glfwInitTimerWin32(void); | ||||
|  | ||||
| void _glfwPollMonitorsWin32(void); | ||||
| void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired); | ||||
| void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor); | ||||
| void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale); | ||||
|  | ||||
							
								
								
									
										99
									
								
								deps/glfw/src/win32_thread.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								deps/glfw/src/win32_thread.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Win32 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls) | ||||
| { | ||||
|     assert(tls->win32.allocated == GLFW_FALSE); | ||||
|  | ||||
|     tls->win32.index = TlsAlloc(); | ||||
|     if (tls->win32.index == TLS_OUT_OF_INDEXES) | ||||
|     { | ||||
|         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, | ||||
|                              "Win32: Failed to allocate TLS index"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
|  | ||||
|     tls->win32.allocated = GLFW_TRUE; | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformDestroyTls(_GLFWtls* tls) | ||||
| { | ||||
|     if (tls->win32.allocated) | ||||
|         TlsFree(tls->win32.index); | ||||
|     memset(tls, 0, sizeof(_GLFWtls)); | ||||
| } | ||||
|  | ||||
| void* _glfwPlatformGetTls(_GLFWtls* tls) | ||||
| { | ||||
|     assert(tls->win32.allocated == GLFW_TRUE); | ||||
|     return TlsGetValue(tls->win32.index); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetTls(_GLFWtls* tls, void* value) | ||||
| { | ||||
|     assert(tls->win32.allocated == GLFW_TRUE); | ||||
|     TlsSetValue(tls->win32.index, value); | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     assert(mutex->win32.allocated == GLFW_FALSE); | ||||
|     InitializeCriticalSection(&mutex->win32.section); | ||||
|     return mutex->win32.allocated = GLFW_TRUE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformDestroyMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     if (mutex->win32.allocated) | ||||
|         DeleteCriticalSection(&mutex->win32.section); | ||||
|     memset(mutex, 0, sizeof(_GLFWmutex)); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformLockMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     assert(mutex->win32.allocated == GLFW_TRUE); | ||||
|     EnterCriticalSection(&mutex->win32.section); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformUnlockMutex(_GLFWmutex* mutex) | ||||
| { | ||||
|     assert(mutex->win32.allocated == GLFW_TRUE); | ||||
|     LeaveCriticalSection(&mutex->win32.section); | ||||
| } | ||||
|  | ||||
							
								
								
									
										60
									
								
								deps/glfw/src/win32_time.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								deps/glfw/src/win32_time.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Win32 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // Please use C89 style variable declarations in this file because VS 2010 | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Initialise timer | ||||
| // | ||||
| void _glfwInitTimerWin32(void) | ||||
| { | ||||
|     QueryPerformanceFrequency((LARGE_INTEGER*) &_glfw.timer.win32.frequency); | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| uint64_t _glfwPlatformGetTimerValue(void) | ||||
| { | ||||
|     uint64_t value; | ||||
|     QueryPerformanceCounter((LARGE_INTEGER*) &value); | ||||
|     return value; | ||||
| } | ||||
|  | ||||
| uint64_t _glfwPlatformGetTimerFrequency(void) | ||||
| { | ||||
|     return _glfw.timer.win32.frequency; | ||||
| } | ||||
|  | ||||
							
								
								
									
										2295
									
								
								deps/glfw/src/win32_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2295
									
								
								deps/glfw/src/win32_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1104
									
								
								deps/glfw/src/window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1104
									
								
								deps/glfw/src/window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1327
									
								
								deps/glfw/src/wl_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1327
									
								
								deps/glfw/src/wl_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										231
									
								
								deps/glfw/src/wl_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								deps/glfw/src/wl_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Wayland - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include <math.h> | ||||
|  | ||||
|  | ||||
| static void outputHandleGeometry(void* data, | ||||
|                                  struct wl_output* output, | ||||
|                                  int32_t x, | ||||
|                                  int32_t y, | ||||
|                                  int32_t physicalWidth, | ||||
|                                  int32_t physicalHeight, | ||||
|                                  int32_t subpixel, | ||||
|                                  const char* make, | ||||
|                                  const char* model, | ||||
|                                  int32_t transform) | ||||
| { | ||||
|     struct _GLFWmonitor *monitor = data; | ||||
|  | ||||
|     monitor->wl.x = x; | ||||
|     monitor->wl.y = y; | ||||
|     monitor->widthMM = physicalWidth; | ||||
|     monitor->heightMM = physicalHeight; | ||||
|  | ||||
|     snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model); | ||||
| } | ||||
|  | ||||
| static void outputHandleMode(void* data, | ||||
|                              struct wl_output* output, | ||||
|                              uint32_t flags, | ||||
|                              int32_t width, | ||||
|                              int32_t height, | ||||
|                              int32_t refresh) | ||||
| { | ||||
|     struct _GLFWmonitor *monitor = data; | ||||
|     GLFWvidmode mode; | ||||
|  | ||||
|     mode.width = width; | ||||
|     mode.height = height; | ||||
|     mode.redBits = 8; | ||||
|     mode.greenBits = 8; | ||||
|     mode.blueBits = 8; | ||||
|     mode.refreshRate = (int) round(refresh / 1000.0); | ||||
|  | ||||
|     monitor->modeCount++; | ||||
|     monitor->modes = | ||||
|         realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode)); | ||||
|     monitor->modes[monitor->modeCount - 1] = mode; | ||||
|  | ||||
|     if (flags & WL_OUTPUT_MODE_CURRENT) | ||||
|         monitor->wl.currentMode = monitor->modeCount - 1; | ||||
| } | ||||
|  | ||||
| static void outputHandleDone(void* data, struct wl_output* output) | ||||
| { | ||||
|     struct _GLFWmonitor *monitor = data; | ||||
|  | ||||
|     if (monitor->widthMM <= 0 || monitor->heightMM <= 0) | ||||
|     { | ||||
|         // If Wayland does not provide a physical size, assume the default 96 DPI | ||||
|         const GLFWvidmode* mode = &monitor->modes[monitor->wl.currentMode]; | ||||
|         monitor->widthMM  = (int) (mode->width * 25.4f / 96.f); | ||||
|         monitor->heightMM = (int) (mode->height * 25.4f / 96.f); | ||||
|     } | ||||
|  | ||||
|     _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST); | ||||
| } | ||||
|  | ||||
| static void outputHandleScale(void* data, | ||||
|                               struct wl_output* output, | ||||
|                               int32_t factor) | ||||
| { | ||||
|     struct _GLFWmonitor *monitor = data; | ||||
|  | ||||
|     monitor->wl.scale = factor; | ||||
| } | ||||
|  | ||||
| static const struct wl_output_listener outputListener = { | ||||
|     outputHandleGeometry, | ||||
|     outputHandleMode, | ||||
|     outputHandleDone, | ||||
|     outputHandleScale, | ||||
| }; | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void _glfwAddOutputWayland(uint32_t name, uint32_t version) | ||||
| { | ||||
|     _GLFWmonitor *monitor; | ||||
|     struct wl_output *output; | ||||
|  | ||||
|     if (version < 2) | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "Wayland: Unsupported output interface version"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     // The actual name of this output will be set in the geometry handler. | ||||
|     monitor = _glfwAllocMonitor("", 0, 0); | ||||
|  | ||||
|     output = wl_registry_bind(_glfw.wl.registry, | ||||
|                               name, | ||||
|                               &wl_output_interface, | ||||
|                               2); | ||||
|     if (!output) | ||||
|     { | ||||
|         _glfwFreeMonitor(monitor); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     monitor->wl.scale = 1; | ||||
|     monitor->wl.output = output; | ||||
|     monitor->wl.name = name; | ||||
|  | ||||
|     wl_output_add_listener(output, &outputListener, monitor); | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) | ||||
| { | ||||
|     if (monitor->wl.output) | ||||
|         wl_output_destroy(monitor->wl.output); | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) | ||||
| { | ||||
|     if (xpos) | ||||
|         *xpos = monitor->wl.x; | ||||
|     if (ypos) | ||||
|         *ypos = monitor->wl.y; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, | ||||
|                                          float* xscale, float* yscale) | ||||
| { | ||||
|     if (xscale) | ||||
|         *xscale = (float) monitor->wl.scale; | ||||
|     if (yscale) | ||||
|         *yscale = (float) monitor->wl.scale; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, | ||||
|                                      int* xpos, int* ypos, | ||||
|                                      int* width, int* height) | ||||
| { | ||||
|     if (xpos) | ||||
|         *xpos = monitor->wl.x; | ||||
|     if (ypos) | ||||
|         *ypos = monitor->wl.y; | ||||
|     if (width) | ||||
|         *width = monitor->modes[monitor->wl.currentMode].width; | ||||
|     if (height) | ||||
|         *height = monitor->modes[monitor->wl.currentMode].height; | ||||
| } | ||||
|  | ||||
| GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) | ||||
| { | ||||
|     *found = monitor->modeCount; | ||||
|     return monitor->modes; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) | ||||
| { | ||||
|     *mode = monitor->modes[monitor->wl.currentMode]; | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) | ||||
| { | ||||
|     _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                     "Wayland: Gamma ramp access is not available"); | ||||
|     return GLFW_FALSE; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, | ||||
|                                const GLFWgammaramp* ramp) | ||||
| { | ||||
|     _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                     "Wayland: Gamma ramp access is not available"); | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(NULL); | ||||
|     return monitor->wl.output; | ||||
| } | ||||
|  | ||||
							
								
								
									
										355
									
								
								deps/glfw/src/wl_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										355
									
								
								deps/glfw/src/wl_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,355 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Wayland - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #include <wayland-client.h> | ||||
| #include <xkbcommon/xkbcommon.h> | ||||
| #ifdef HAVE_XKBCOMMON_COMPOSE_H | ||||
| #include <xkbcommon/xkbcommon-compose.h> | ||||
| #endif | ||||
| #include <dlfcn.h> | ||||
|  | ||||
| typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; | ||||
|  | ||||
| typedef struct VkWaylandSurfaceCreateInfoKHR | ||||
| { | ||||
|     VkStructureType                 sType; | ||||
|     const void*                     pNext; | ||||
|     VkWaylandSurfaceCreateFlagsKHR  flags; | ||||
|     struct wl_display*              display; | ||||
|     struct wl_surface*              surface; | ||||
| } VkWaylandSurfaceCreateInfoKHR; | ||||
|  | ||||
| typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); | ||||
| typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*); | ||||
|  | ||||
| #include "posix_thread.h" | ||||
| #include "posix_time.h" | ||||
| #ifdef __linux__ | ||||
| #include "linux_joystick.h" | ||||
| #else | ||||
| #include "null_joystick.h" | ||||
| #endif | ||||
| #include "xkb_unicode.h" | ||||
| #include "egl_context.h" | ||||
| #include "osmesa_context.h" | ||||
|  | ||||
| #include "wayland-xdg-shell-client-protocol.h" | ||||
| #include "wayland-xdg-decoration-client-protocol.h" | ||||
| #include "wayland-viewporter-client-protocol.h" | ||||
| #include "wayland-relative-pointer-unstable-v1-client-protocol.h" | ||||
| #include "wayland-pointer-constraints-unstable-v1-client-protocol.h" | ||||
| #include "wayland-idle-inhibit-unstable-v1-client-protocol.h" | ||||
|  | ||||
| #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) | ||||
| #define _glfw_dlclose(handle) dlclose(handle) | ||||
| #define _glfw_dlsym(handle, name) dlsym(handle, name) | ||||
|  | ||||
| #define _GLFW_EGL_NATIVE_WINDOW         ((EGLNativeWindowType) window->wl.native) | ||||
| #define _GLFW_EGL_NATIVE_DISPLAY        ((EGLNativeDisplayType) _glfw.wl.display) | ||||
|  | ||||
| #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowWayland  wl | ||||
| #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl | ||||
| #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorWayland wl | ||||
| #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorWayland  wl | ||||
|  | ||||
| #define _GLFW_PLATFORM_CONTEXT_STATE         struct { int dummyContext; } | ||||
| #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; } | ||||
|  | ||||
| struct wl_cursor_image { | ||||
|     uint32_t width; | ||||
|     uint32_t height; | ||||
|     uint32_t hotspot_x; | ||||
|     uint32_t hotspot_y; | ||||
|     uint32_t delay; | ||||
| }; | ||||
| struct wl_cursor { | ||||
|     unsigned int image_count; | ||||
|     struct wl_cursor_image** images; | ||||
|     char* name; | ||||
| }; | ||||
| typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*); | ||||
| typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*); | ||||
| typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*); | ||||
| typedef struct wl_buffer* (* PFN_wl_cursor_image_get_buffer)(struct wl_cursor_image*); | ||||
| #define wl_cursor_theme_load _glfw.wl.cursor.theme_load | ||||
| #define wl_cursor_theme_destroy _glfw.wl.cursor.theme_destroy | ||||
| #define wl_cursor_theme_get_cursor _glfw.wl.cursor.theme_get_cursor | ||||
| #define wl_cursor_image_get_buffer _glfw.wl.cursor.image_get_buffer | ||||
|  | ||||
| typedef struct wl_egl_window* (* PFN_wl_egl_window_create)(struct wl_surface*, int, int); | ||||
| typedef void (* PFN_wl_egl_window_destroy)(struct wl_egl_window*); | ||||
| typedef void (* PFN_wl_egl_window_resize)(struct wl_egl_window*, int, int, int, int); | ||||
| #define wl_egl_window_create _glfw.wl.egl.window_create | ||||
| #define wl_egl_window_destroy _glfw.wl.egl.window_destroy | ||||
| #define wl_egl_window_resize _glfw.wl.egl.window_resize | ||||
|  | ||||
| typedef struct xkb_context* (* PFN_xkb_context_new)(enum xkb_context_flags); | ||||
| typedef void (* PFN_xkb_context_unref)(struct xkb_context*); | ||||
| typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags); | ||||
| typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*); | ||||
| typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*); | ||||
| typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t); | ||||
| typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*); | ||||
| typedef void (* PFN_xkb_state_unref)(struct xkb_state*); | ||||
| typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**); | ||||
| typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); | ||||
| typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component); | ||||
| #define xkb_context_new _glfw.wl.xkb.context_new | ||||
| #define xkb_context_unref _glfw.wl.xkb.context_unref | ||||
| #define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string | ||||
| #define xkb_keymap_unref _glfw.wl.xkb.keymap_unref | ||||
| #define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index | ||||
| #define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats | ||||
| #define xkb_state_new _glfw.wl.xkb.state_new | ||||
| #define xkb_state_unref _glfw.wl.xkb.state_unref | ||||
| #define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms | ||||
| #define xkb_state_update_mask _glfw.wl.xkb.state_update_mask | ||||
| #define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods | ||||
|  | ||||
| #ifdef HAVE_XKBCOMMON_COMPOSE_H | ||||
| typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags); | ||||
| typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*); | ||||
| typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags); | ||||
| typedef void (* PFN_xkb_compose_state_unref)(struct xkb_compose_state*); | ||||
| typedef enum xkb_compose_feed_result (* PFN_xkb_compose_state_feed)(struct xkb_compose_state*, xkb_keysym_t); | ||||
| typedef enum xkb_compose_status (* PFN_xkb_compose_state_get_status)(struct xkb_compose_state*); | ||||
| typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_state*); | ||||
| #define xkb_compose_table_new_from_locale _glfw.wl.xkb.compose_table_new_from_locale | ||||
| #define xkb_compose_table_unref _glfw.wl.xkb.compose_table_unref | ||||
| #define xkb_compose_state_new _glfw.wl.xkb.compose_state_new | ||||
| #define xkb_compose_state_unref _glfw.wl.xkb.compose_state_unref | ||||
| #define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed | ||||
| #define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status | ||||
| #define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym | ||||
| #endif | ||||
|  | ||||
| #define _GLFW_DECORATION_WIDTH 4 | ||||
| #define _GLFW_DECORATION_TOP 24 | ||||
| #define _GLFW_DECORATION_VERTICAL (_GLFW_DECORATION_TOP + _GLFW_DECORATION_WIDTH) | ||||
| #define _GLFW_DECORATION_HORIZONTAL (2 * _GLFW_DECORATION_WIDTH) | ||||
|  | ||||
| typedef enum _GLFWdecorationSideWayland | ||||
| { | ||||
|     mainWindow, | ||||
|     topDecoration, | ||||
|     leftDecoration, | ||||
|     rightDecoration, | ||||
|     bottomDecoration, | ||||
| } _GLFWdecorationSideWayland; | ||||
|  | ||||
| typedef struct _GLFWdecorationWayland | ||||
| { | ||||
|     struct wl_surface*          surface; | ||||
|     struct wl_subsurface*       subsurface; | ||||
|     struct wp_viewport*         viewport; | ||||
| } _GLFWdecorationWayland; | ||||
|  | ||||
| // Wayland-specific per-window data | ||||
| // | ||||
| typedef struct _GLFWwindowWayland | ||||
| { | ||||
|     int                         width, height; | ||||
|     GLFWbool                    visible; | ||||
|     GLFWbool                    maximized; | ||||
|     GLFWbool                    hovered; | ||||
|     GLFWbool                    transparent; | ||||
|     struct wl_surface*          surface; | ||||
|     struct wl_egl_window*       native; | ||||
|     struct wl_shell_surface*    shellSurface; | ||||
|     struct wl_callback*         callback; | ||||
|  | ||||
|     struct { | ||||
|         struct xdg_surface*     surface; | ||||
|         struct xdg_toplevel*    toplevel; | ||||
|         struct zxdg_toplevel_decoration_v1* decoration; | ||||
|     } xdg; | ||||
|  | ||||
|     _GLFWcursor*                currentCursor; | ||||
|     double                      cursorPosX, cursorPosY; | ||||
|  | ||||
|     char*                       title; | ||||
|  | ||||
|     // We need to track the monitors the window spans on to calculate the | ||||
|     // optimal scaling factor. | ||||
|     int                         scale; | ||||
|     _GLFWmonitor**              monitors; | ||||
|     int                         monitorsCount; | ||||
|     int                         monitorsSize; | ||||
|  | ||||
|     struct { | ||||
|         struct zwp_relative_pointer_v1*    relativePointer; | ||||
|         struct zwp_locked_pointer_v1*      lockedPointer; | ||||
|     } pointerLock; | ||||
|  | ||||
|     struct zwp_idle_inhibitor_v1*          idleInhibitor; | ||||
|  | ||||
|     GLFWbool                    wasFullscreen; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool                           serverSide; | ||||
|         struct wl_buffer*                  buffer; | ||||
|         _GLFWdecorationWayland             top, left, right, bottom; | ||||
|         int                                focus; | ||||
|     } decorations; | ||||
| } _GLFWwindowWayland; | ||||
|  | ||||
| // Wayland-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryWayland | ||||
| { | ||||
|     struct wl_display*          display; | ||||
|     struct wl_registry*         registry; | ||||
|     struct wl_compositor*       compositor; | ||||
|     struct wl_subcompositor*    subcompositor; | ||||
|     struct wl_shell*            shell; | ||||
|     struct wl_shm*              shm; | ||||
|     struct wl_seat*             seat; | ||||
|     struct wl_pointer*          pointer; | ||||
|     struct wl_keyboard*         keyboard; | ||||
|     struct wl_data_device_manager*          dataDeviceManager; | ||||
|     struct wl_data_device*      dataDevice; | ||||
|     struct wl_data_offer*       dataOffer; | ||||
|     struct wl_data_source*      dataSource; | ||||
|     struct xdg_wm_base*         wmBase; | ||||
|     struct zxdg_decoration_manager_v1*      decorationManager; | ||||
|     struct wp_viewporter*       viewporter; | ||||
|     struct zwp_relative_pointer_manager_v1* relativePointerManager; | ||||
|     struct zwp_pointer_constraints_v1*      pointerConstraints; | ||||
|     struct zwp_idle_inhibit_manager_v1*     idleInhibitManager; | ||||
|  | ||||
|     int                         compositorVersion; | ||||
|     int                         seatVersion; | ||||
|  | ||||
|     struct wl_cursor_theme*     cursorTheme; | ||||
|     struct wl_cursor_theme*     cursorThemeHiDPI; | ||||
|     struct wl_surface*          cursorSurface; | ||||
|     const char*                 cursorPreviousName; | ||||
|     int                         cursorTimerfd; | ||||
|     uint32_t                    serial; | ||||
|     uint32_t                    pointerEnterSerial; | ||||
|  | ||||
|     int32_t                     keyboardRepeatRate; | ||||
|     int32_t                     keyboardRepeatDelay; | ||||
|     int                         keyboardLastKey; | ||||
|     int                         keyboardLastScancode; | ||||
|     char*                       clipboardString; | ||||
|     size_t                      clipboardSize; | ||||
|     char*                       clipboardSendString; | ||||
|     size_t                      clipboardSendSize; | ||||
|     int                         timerfd; | ||||
|     short int                   keycodes[256]; | ||||
|     short int                   scancodes[GLFW_KEY_LAST + 1]; | ||||
|  | ||||
|     struct { | ||||
|         void*                   handle; | ||||
|         struct xkb_context*     context; | ||||
|         struct xkb_keymap*      keymap; | ||||
|         struct xkb_state*       state; | ||||
|  | ||||
| #ifdef HAVE_XKBCOMMON_COMPOSE_H | ||||
|         struct xkb_compose_state* composeState; | ||||
| #endif | ||||
|  | ||||
|         xkb_mod_mask_t          controlMask; | ||||
|         xkb_mod_mask_t          altMask; | ||||
|         xkb_mod_mask_t          shiftMask; | ||||
|         xkb_mod_mask_t          superMask; | ||||
|         xkb_mod_mask_t          capsLockMask; | ||||
|         xkb_mod_mask_t          numLockMask; | ||||
|         unsigned int            modifiers; | ||||
|  | ||||
|         PFN_xkb_context_new context_new; | ||||
|         PFN_xkb_context_unref context_unref; | ||||
|         PFN_xkb_keymap_new_from_string keymap_new_from_string; | ||||
|         PFN_xkb_keymap_unref keymap_unref; | ||||
|         PFN_xkb_keymap_mod_get_index keymap_mod_get_index; | ||||
|         PFN_xkb_keymap_key_repeats keymap_key_repeats; | ||||
|         PFN_xkb_state_new state_new; | ||||
|         PFN_xkb_state_unref state_unref; | ||||
|         PFN_xkb_state_key_get_syms state_key_get_syms; | ||||
|         PFN_xkb_state_update_mask state_update_mask; | ||||
|         PFN_xkb_state_serialize_mods state_serialize_mods; | ||||
|  | ||||
| #ifdef HAVE_XKBCOMMON_COMPOSE_H | ||||
|         PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; | ||||
|         PFN_xkb_compose_table_unref compose_table_unref; | ||||
|         PFN_xkb_compose_state_new compose_state_new; | ||||
|         PFN_xkb_compose_state_unref compose_state_unref; | ||||
|         PFN_xkb_compose_state_feed compose_state_feed; | ||||
|         PFN_xkb_compose_state_get_status compose_state_get_status; | ||||
|         PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym; | ||||
| #endif | ||||
|     } xkb; | ||||
|  | ||||
|     _GLFWwindow*                pointerFocus; | ||||
|     _GLFWwindow*                keyboardFocus; | ||||
|  | ||||
|     struct { | ||||
|         void*                   handle; | ||||
|  | ||||
|         PFN_wl_cursor_theme_load theme_load; | ||||
|         PFN_wl_cursor_theme_destroy theme_destroy; | ||||
|         PFN_wl_cursor_theme_get_cursor theme_get_cursor; | ||||
|         PFN_wl_cursor_image_get_buffer image_get_buffer; | ||||
|     } cursor; | ||||
|  | ||||
|     struct { | ||||
|         void*                   handle; | ||||
|  | ||||
|         PFN_wl_egl_window_create window_create; | ||||
|         PFN_wl_egl_window_destroy window_destroy; | ||||
|         PFN_wl_egl_window_resize window_resize; | ||||
|     } egl; | ||||
| } _GLFWlibraryWayland; | ||||
|  | ||||
| // Wayland-specific per-monitor data | ||||
| // | ||||
| typedef struct _GLFWmonitorWayland | ||||
| { | ||||
|     struct wl_output*           output; | ||||
|     uint32_t                    name; | ||||
|     int                         currentMode; | ||||
|  | ||||
|     int                         x; | ||||
|     int                         y; | ||||
|     int                         scale; | ||||
| } _GLFWmonitorWayland; | ||||
|  | ||||
| // Wayland-specific per-cursor data | ||||
| // | ||||
| typedef struct _GLFWcursorWayland | ||||
| { | ||||
|     struct wl_cursor*           cursor; | ||||
|     struct wl_cursor*           cursorHiDPI; | ||||
|     struct wl_buffer*           buffer; | ||||
|     int                         width, height; | ||||
|     int                         xhot, yhot; | ||||
|     int                         currentImage; | ||||
| } _GLFWcursorWayland; | ||||
|  | ||||
|  | ||||
| void _glfwAddOutputWayland(uint32_t name, uint32_t version); | ||||
|  | ||||
							
								
								
									
										1903
									
								
								deps/glfw/src/wl_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1903
									
								
								deps/glfw/src/wl_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1211
									
								
								deps/glfw/src/x11_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1211
									
								
								deps/glfw/src/x11_init.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										614
									
								
								deps/glfw/src/x11_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										614
									
								
								deps/glfw/src/x11_monitor.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,614 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 X11 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| #include <limits.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <math.h> | ||||
|  | ||||
|  | ||||
| // Check whether the display mode should be included in enumeration | ||||
| // | ||||
| static GLFWbool modeIsGood(const XRRModeInfo* mi) | ||||
| { | ||||
|     return (mi->modeFlags & RR_Interlace) == 0; | ||||
| } | ||||
|  | ||||
| // Calculates the refresh rate, in Hz, from the specified RandR mode info | ||||
| // | ||||
| static int calculateRefreshRate(const XRRModeInfo* mi) | ||||
| { | ||||
|     if (mi->hTotal && mi->vTotal) | ||||
|         return (int) round((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal)); | ||||
|     else | ||||
|         return 0; | ||||
| } | ||||
|  | ||||
| // Returns the mode info for a RandR mode XID | ||||
| // | ||||
| static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id) | ||||
| { | ||||
|     for (int i = 0;  i < sr->nmode;  i++) | ||||
|     { | ||||
|         if (sr->modes[i].id == id) | ||||
|             return sr->modes + i; | ||||
|     } | ||||
|  | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| // Convert RandR mode info to GLFW video mode | ||||
| // | ||||
| static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi, | ||||
|                                        const XRRCrtcInfo* ci) | ||||
| { | ||||
|     GLFWvidmode mode; | ||||
|  | ||||
|     if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) | ||||
|     { | ||||
|         mode.width  = mi->height; | ||||
|         mode.height = mi->width; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mode.width  = mi->width; | ||||
|         mode.height = mi->height; | ||||
|     } | ||||
|  | ||||
|     mode.refreshRate = calculateRefreshRate(mi); | ||||
|  | ||||
|     _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), | ||||
|                   &mode.redBits, &mode.greenBits, &mode.blueBits); | ||||
|  | ||||
|     return mode; | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Poll for changes in the set of connected monitors | ||||
| // | ||||
| void _glfwPollMonitorsX11(void) | ||||
| { | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) | ||||
|     { | ||||
|         int disconnectedCount, screenCount = 0; | ||||
|         _GLFWmonitor** disconnected = NULL; | ||||
|         XineramaScreenInfo* screens = NULL; | ||||
|         XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, | ||||
|                                                               _glfw.x11.root); | ||||
|         RROutput primary = XRRGetOutputPrimary(_glfw.x11.display, | ||||
|                                                _glfw.x11.root); | ||||
|  | ||||
|         if (_glfw.x11.xinerama.available) | ||||
|             screens = XineramaQueryScreens(_glfw.x11.display, &screenCount); | ||||
|  | ||||
|         disconnectedCount = _glfw.monitorCount; | ||||
|         if (disconnectedCount) | ||||
|         { | ||||
|             disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); | ||||
|             memcpy(disconnected, | ||||
|                    _glfw.monitors, | ||||
|                    _glfw.monitorCount * sizeof(_GLFWmonitor*)); | ||||
|         } | ||||
|  | ||||
|         for (int i = 0;  i < sr->noutput;  i++) | ||||
|         { | ||||
|             int j, type, widthMM, heightMM; | ||||
|  | ||||
|             XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]); | ||||
|             if (oi->connection != RR_Connected || oi->crtc == None) | ||||
|             { | ||||
|                 XRRFreeOutputInfo(oi); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             for (j = 0;  j < disconnectedCount;  j++) | ||||
|             { | ||||
|                 if (disconnected[j] && | ||||
|                     disconnected[j]->x11.output == sr->outputs[i]) | ||||
|                 { | ||||
|                     disconnected[j] = NULL; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (j < disconnectedCount) | ||||
|             { | ||||
|                 XRRFreeOutputInfo(oi); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc); | ||||
|             if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) | ||||
|             { | ||||
|                 widthMM  = oi->mm_height; | ||||
|                 heightMM = oi->mm_width; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 widthMM  = oi->mm_width; | ||||
|                 heightMM = oi->mm_height; | ||||
|             } | ||||
|  | ||||
|             if (widthMM <= 0 || heightMM <= 0) | ||||
|             { | ||||
|                 // HACK: If RandR does not provide a physical size, assume the | ||||
|                 //       X11 default 96 DPI and calculate from the CRTC viewport | ||||
|                 // NOTE: These members are affected by rotation, unlike the mode | ||||
|                 //       info and output info members | ||||
|                 widthMM  = (int) (ci->width * 25.4f / 96.f); | ||||
|                 heightMM = (int) (ci->height * 25.4f / 96.f); | ||||
|             } | ||||
|  | ||||
|             _GLFWmonitor* monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM); | ||||
|             monitor->x11.output = sr->outputs[i]; | ||||
|             monitor->x11.crtc   = oi->crtc; | ||||
|  | ||||
|             for (j = 0;  j < screenCount;  j++) | ||||
|             { | ||||
|                 if (screens[j].x_org == ci->x && | ||||
|                     screens[j].y_org == ci->y && | ||||
|                     screens[j].width == ci->width && | ||||
|                     screens[j].height == ci->height) | ||||
|                 { | ||||
|                     monitor->x11.index = j; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (monitor->x11.output == primary) | ||||
|                 type = _GLFW_INSERT_FIRST; | ||||
|             else | ||||
|                 type = _GLFW_INSERT_LAST; | ||||
|  | ||||
|             _glfwInputMonitor(monitor, GLFW_CONNECTED, type); | ||||
|  | ||||
|             XRRFreeOutputInfo(oi); | ||||
|             XRRFreeCrtcInfo(ci); | ||||
|         } | ||||
|  | ||||
|         XRRFreeScreenResources(sr); | ||||
|  | ||||
|         if (screens) | ||||
|             XFree(screens); | ||||
|  | ||||
|         for (int i = 0;  i < disconnectedCount;  i++) | ||||
|         { | ||||
|             if (disconnected[i]) | ||||
|                 _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); | ||||
|         } | ||||
|  | ||||
|         free(disconnected); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         const int widthMM = DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen); | ||||
|         const int heightMM = DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen); | ||||
|  | ||||
|         _glfwInputMonitor(_glfwAllocMonitor("Display", widthMM, heightMM), | ||||
|                           GLFW_CONNECTED, | ||||
|                           _GLFW_INSERT_FIRST); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Set the current video mode for the specified monitor | ||||
| // | ||||
| void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired) | ||||
| { | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) | ||||
|     { | ||||
|         GLFWvidmode current; | ||||
|         RRMode native = None; | ||||
|  | ||||
|         const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired); | ||||
|         _glfwPlatformGetVideoMode(monitor, ¤t); | ||||
|         if (_glfwCompareVideoModes(¤t, best) == 0) | ||||
|             return; | ||||
|  | ||||
|         XRRScreenResources* sr = | ||||
|             XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); | ||||
|         XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); | ||||
|         XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); | ||||
|  | ||||
|         for (int i = 0;  i < oi->nmode;  i++) | ||||
|         { | ||||
|             const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); | ||||
|             if (!modeIsGood(mi)) | ||||
|                 continue; | ||||
|  | ||||
|             const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); | ||||
|             if (_glfwCompareVideoModes(best, &mode) == 0) | ||||
|             { | ||||
|                 native = mi->id; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (native) | ||||
|         { | ||||
|             if (monitor->x11.oldMode == None) | ||||
|                 monitor->x11.oldMode = ci->mode; | ||||
|  | ||||
|             XRRSetCrtcConfig(_glfw.x11.display, | ||||
|                              sr, monitor->x11.crtc, | ||||
|                              CurrentTime, | ||||
|                              ci->x, ci->y, | ||||
|                              native, | ||||
|                              ci->rotation, | ||||
|                              ci->outputs, | ||||
|                              ci->noutput); | ||||
|         } | ||||
|  | ||||
|         XRRFreeOutputInfo(oi); | ||||
|         XRRFreeCrtcInfo(ci); | ||||
|         XRRFreeScreenResources(sr); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Restore the saved (original) video mode for the specified monitor | ||||
| // | ||||
| void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor) | ||||
| { | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) | ||||
|     { | ||||
|         if (monitor->x11.oldMode == None) | ||||
|             return; | ||||
|  | ||||
|         XRRScreenResources* sr = | ||||
|             XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); | ||||
|         XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); | ||||
|  | ||||
|         XRRSetCrtcConfig(_glfw.x11.display, | ||||
|                          sr, monitor->x11.crtc, | ||||
|                          CurrentTime, | ||||
|                          ci->x, ci->y, | ||||
|                          monitor->x11.oldMode, | ||||
|                          ci->rotation, | ||||
|                          ci->outputs, | ||||
|                          ci->noutput); | ||||
|  | ||||
|         XRRFreeCrtcInfo(ci); | ||||
|         XRRFreeScreenResources(sr); | ||||
|  | ||||
|         monitor->x11.oldMode = None; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW platform API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) | ||||
| { | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) | ||||
| { | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) | ||||
|     { | ||||
|         XRRScreenResources* sr = | ||||
|             XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); | ||||
|         XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); | ||||
|  | ||||
|         if (ci) | ||||
|         { | ||||
|             if (xpos) | ||||
|                 *xpos = ci->x; | ||||
|             if (ypos) | ||||
|                 *ypos = ci->y; | ||||
|  | ||||
|             XRRFreeCrtcInfo(ci); | ||||
|         } | ||||
|  | ||||
|         XRRFreeScreenResources(sr); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, | ||||
|                                          float* xscale, float* yscale) | ||||
| { | ||||
|     if (xscale) | ||||
|         *xscale = _glfw.x11.contentScaleX; | ||||
|     if (yscale) | ||||
|         *yscale = _glfw.x11.contentScaleY; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height) | ||||
| { | ||||
|     int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0; | ||||
|  | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) | ||||
|     { | ||||
|         XRRScreenResources* sr = | ||||
|             XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); | ||||
|         XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); | ||||
|  | ||||
|         areaX = ci->x; | ||||
|         areaY = ci->y; | ||||
|  | ||||
|         const XRRModeInfo* mi = getModeInfo(sr, ci->mode); | ||||
|  | ||||
|         if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) | ||||
|         { | ||||
|             areaWidth  = mi->height; | ||||
|             areaHeight = mi->width; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             areaWidth  = mi->width; | ||||
|             areaHeight = mi->height; | ||||
|         } | ||||
|  | ||||
|         XRRFreeCrtcInfo(ci); | ||||
|         XRRFreeScreenResources(sr); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         areaWidth  = DisplayWidth(_glfw.x11.display, _glfw.x11.screen); | ||||
|         areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen); | ||||
|     } | ||||
|  | ||||
|     if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP) | ||||
|     { | ||||
|         Atom* extents = NULL; | ||||
|         Atom* desktop = NULL; | ||||
|         const unsigned long extentCount = | ||||
|             _glfwGetWindowPropertyX11(_glfw.x11.root, | ||||
|                                       _glfw.x11.NET_WORKAREA, | ||||
|                                       XA_CARDINAL, | ||||
|                                       (unsigned char**) &extents); | ||||
|  | ||||
|         if (_glfwGetWindowPropertyX11(_glfw.x11.root, | ||||
|                                       _glfw.x11.NET_CURRENT_DESKTOP, | ||||
|                                       XA_CARDINAL, | ||||
|                                       (unsigned char**) &desktop) > 0) | ||||
|         { | ||||
|             if (extentCount >= 4 && *desktop < extentCount / 4) | ||||
|             { | ||||
|                 const int globalX = extents[*desktop * 4 + 0]; | ||||
|                 const int globalY = extents[*desktop * 4 + 1]; | ||||
|                 const int globalWidth  = extents[*desktop * 4 + 2]; | ||||
|                 const int globalHeight = extents[*desktop * 4 + 3]; | ||||
|  | ||||
|                 if (areaX < globalX) | ||||
|                 { | ||||
|                     areaWidth -= globalX - areaX; | ||||
|                     areaX = globalX; | ||||
|                 } | ||||
|  | ||||
|                 if (areaY < globalY) | ||||
|                 { | ||||
|                     areaHeight -= globalY - areaY; | ||||
|                     areaY = globalY; | ||||
|                 } | ||||
|  | ||||
|                 if (areaX + areaWidth > globalX + globalWidth) | ||||
|                     areaWidth = globalX - areaX + globalWidth; | ||||
|                 if (areaY + areaHeight > globalY + globalHeight) | ||||
|                     areaHeight = globalY - areaY + globalHeight; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (extents) | ||||
|             XFree(extents); | ||||
|         if (desktop) | ||||
|             XFree(desktop); | ||||
|     } | ||||
|  | ||||
|     if (xpos) | ||||
|         *xpos = areaX; | ||||
|     if (ypos) | ||||
|         *ypos = areaY; | ||||
|     if (width) | ||||
|         *width = areaWidth; | ||||
|     if (height) | ||||
|         *height = areaHeight; | ||||
| } | ||||
|  | ||||
| GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) | ||||
| { | ||||
|     GLFWvidmode* result; | ||||
|  | ||||
|     *count = 0; | ||||
|  | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) | ||||
|     { | ||||
|         XRRScreenResources* sr = | ||||
|             XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); | ||||
|         XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); | ||||
|         XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); | ||||
|  | ||||
|         result = calloc(oi->nmode, sizeof(GLFWvidmode)); | ||||
|  | ||||
|         for (int i = 0;  i < oi->nmode;  i++) | ||||
|         { | ||||
|             const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); | ||||
|             if (!modeIsGood(mi)) | ||||
|                 continue; | ||||
|  | ||||
|             const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); | ||||
|             int j; | ||||
|  | ||||
|             for (j = 0;  j < *count;  j++) | ||||
|             { | ||||
|                 if (_glfwCompareVideoModes(result + j, &mode) == 0) | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|             // Skip duplicate modes | ||||
|             if (j < *count) | ||||
|                 continue; | ||||
|  | ||||
|             (*count)++; | ||||
|             result[*count - 1] = mode; | ||||
|         } | ||||
|  | ||||
|         XRRFreeOutputInfo(oi); | ||||
|         XRRFreeCrtcInfo(ci); | ||||
|         XRRFreeScreenResources(sr); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         *count = 1; | ||||
|         result = calloc(1, sizeof(GLFWvidmode)); | ||||
|         _glfwPlatformGetVideoMode(monitor, result); | ||||
|     } | ||||
|  | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) | ||||
| { | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) | ||||
|     { | ||||
|         XRRScreenResources* sr = | ||||
|             XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); | ||||
|         XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); | ||||
|  | ||||
|         if (ci) | ||||
|         { | ||||
|             const XRRModeInfo* mi = getModeInfo(sr, ci->mode); | ||||
|             if (mi)  // mi can be NULL if the monitor has been disconnected | ||||
|                 *mode = vidmodeFromModeInfo(mi, ci); | ||||
|  | ||||
|             XRRFreeCrtcInfo(ci); | ||||
|         } | ||||
|  | ||||
|         XRRFreeScreenResources(sr); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mode->width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen); | ||||
|         mode->height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen); | ||||
|         mode->refreshRate = 0; | ||||
|  | ||||
|         _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), | ||||
|                       &mode->redBits, &mode->greenBits, &mode->blueBits); | ||||
|     } | ||||
| } | ||||
|  | ||||
| GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) | ||||
| { | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) | ||||
|     { | ||||
|         const size_t size = XRRGetCrtcGammaSize(_glfw.x11.display, | ||||
|                                                 monitor->x11.crtc); | ||||
|         XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display, | ||||
|                                               monitor->x11.crtc); | ||||
|  | ||||
|         _glfwAllocGammaArrays(ramp, size); | ||||
|  | ||||
|         memcpy(ramp->red,   gamma->red,   size * sizeof(unsigned short)); | ||||
|         memcpy(ramp->green, gamma->green, size * sizeof(unsigned short)); | ||||
|         memcpy(ramp->blue,  gamma->blue,  size * sizeof(unsigned short)); | ||||
|  | ||||
|         XRRFreeGamma(gamma); | ||||
|         return GLFW_TRUE; | ||||
|     } | ||||
|     else if (_glfw.x11.vidmode.available) | ||||
|     { | ||||
|         int size; | ||||
|         XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size); | ||||
|  | ||||
|         _glfwAllocGammaArrays(ramp, size); | ||||
|  | ||||
|         XF86VidModeGetGammaRamp(_glfw.x11.display, | ||||
|                                 _glfw.x11.screen, | ||||
|                                 ramp->size, ramp->red, ramp->green, ramp->blue); | ||||
|         return GLFW_TRUE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "X11: Gamma ramp access not supported by server"); | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) | ||||
| { | ||||
|     if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) | ||||
|     { | ||||
|         if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size) | ||||
|         { | ||||
|             _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                             "X11: Gamma ramp size must match current ramp size"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size); | ||||
|  | ||||
|         memcpy(gamma->red,   ramp->red,   ramp->size * sizeof(unsigned short)); | ||||
|         memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short)); | ||||
|         memcpy(gamma->blue,  ramp->blue,  ramp->size * sizeof(unsigned short)); | ||||
|  | ||||
|         XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma); | ||||
|         XRRFreeGamma(gamma); | ||||
|     } | ||||
|     else if (_glfw.x11.vidmode.available) | ||||
|     { | ||||
|         XF86VidModeSetGammaRamp(_glfw.x11.display, | ||||
|                                 _glfw.x11.screen, | ||||
|                                 ramp->size, | ||||
|                                 (unsigned short*) ramp->red, | ||||
|                                 (unsigned short*) ramp->green, | ||||
|                                 (unsigned short*) ramp->blue); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                         "X11: Gamma ramp access not supported by server"); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                        GLFW native API                       ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(None); | ||||
|     return monitor->x11.crtc; | ||||
| } | ||||
|  | ||||
| GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) | ||||
| { | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) handle; | ||||
|     _GLFW_REQUIRE_INIT_OR_RETURN(None); | ||||
|     return monitor->x11.output; | ||||
| } | ||||
|  | ||||
							
								
								
									
										447
									
								
								deps/glfw/src/x11_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										447
									
								
								deps/glfw/src/x11_platform.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,447 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 X11 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| #include <unistd.h> | ||||
| #include <signal.h> | ||||
| #include <stdint.h> | ||||
| #include <dlfcn.h> | ||||
|  | ||||
| #include <X11/Xlib.h> | ||||
| #include <X11/keysym.h> | ||||
| #include <X11/Xatom.h> | ||||
| #include <X11/Xcursor/Xcursor.h> | ||||
|  | ||||
| // The XRandR extension provides mode setting and gamma control | ||||
| #include <X11/extensions/Xrandr.h> | ||||
|  | ||||
| // The Xkb extension provides improved keyboard support | ||||
| #include <X11/XKBlib.h> | ||||
|  | ||||
| // The Xinerama extension provides legacy monitor indices | ||||
| #include <X11/extensions/Xinerama.h> | ||||
|  | ||||
| // The XInput extension provides raw mouse motion input | ||||
| #include <X11/extensions/XInput2.h> | ||||
|  | ||||
| typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int); | ||||
| typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*); | ||||
| typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*); | ||||
| typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*); | ||||
| typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*); | ||||
| typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc); | ||||
| typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc); | ||||
| typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc); | ||||
| typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput); | ||||
| typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window); | ||||
| typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window); | ||||
| typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*); | ||||
| typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*); | ||||
| typedef void (* PFN_XRRSelectInput)(Display*,Window,int); | ||||
| typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int); | ||||
| typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*); | ||||
| typedef int (* PFN_XRRUpdateConfiguration)(XEvent*); | ||||
| #define XRRAllocGamma _glfw.x11.randr.AllocGamma | ||||
| #define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo | ||||
| #define XRRFreeGamma _glfw.x11.randr.FreeGamma | ||||
| #define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo | ||||
| #define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources | ||||
| #define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma | ||||
| #define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize | ||||
| #define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo | ||||
| #define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo | ||||
| #define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary | ||||
| #define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent | ||||
| #define XRRQueryExtension _glfw.x11.randr.QueryExtension | ||||
| #define XRRQueryVersion _glfw.x11.randr.QueryVersion | ||||
| #define XRRSelectInput _glfw.x11.randr.SelectInput | ||||
| #define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig | ||||
| #define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma | ||||
| #define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration | ||||
|  | ||||
| typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int); | ||||
| typedef void (* PFN_XcursorImageDestroy)(XcursorImage*); | ||||
| typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*); | ||||
| #define XcursorImageCreate _glfw.x11.xcursor.ImageCreate | ||||
| #define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy | ||||
| #define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor | ||||
|  | ||||
| typedef Bool (* PFN_XineramaIsActive)(Display*); | ||||
| typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*); | ||||
| typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*); | ||||
| #define XineramaIsActive _glfw.x11.xinerama.IsActive | ||||
| #define XineramaQueryExtension _glfw.x11.xinerama.QueryExtension | ||||
| #define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens | ||||
|  | ||||
| typedef XID xcb_window_t; | ||||
| typedef XID xcb_visualid_t; | ||||
| typedef struct xcb_connection_t xcb_connection_t; | ||||
| typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*); | ||||
| #define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection | ||||
|  | ||||
| typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*); | ||||
| typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*); | ||||
| typedef Bool (* PFN_XF86VidModeSetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*); | ||||
| typedef Bool (* PFN_XF86VidModeGetGammaRampSize)(Display*,int,int*); | ||||
| #define XF86VidModeQueryExtension _glfw.x11.vidmode.QueryExtension | ||||
| #define XF86VidModeGetGammaRamp _glfw.x11.vidmode.GetGammaRamp | ||||
| #define XF86VidModeSetGammaRamp _glfw.x11.vidmode.SetGammaRamp | ||||
| #define XF86VidModeGetGammaRampSize _glfw.x11.vidmode.GetGammaRampSize | ||||
|  | ||||
| typedef Status (* PFN_XIQueryVersion)(Display*,int*,int*); | ||||
| typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int); | ||||
| #define XIQueryVersion _glfw.x11.xi.QueryVersion | ||||
| #define XISelectEvents _glfw.x11.xi.SelectEvents | ||||
|  | ||||
| typedef Bool (* PFN_XRenderQueryExtension)(Display*,int*,int*); | ||||
| typedef Status (* PFN_XRenderQueryVersion)(Display*dpy,int*,int*); | ||||
| typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const*); | ||||
| #define XRenderQueryExtension _glfw.x11.xrender.QueryExtension | ||||
| #define XRenderQueryVersion _glfw.x11.xrender.QueryVersion | ||||
| #define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat | ||||
|  | ||||
| typedef VkFlags VkXlibSurfaceCreateFlagsKHR; | ||||
| typedef VkFlags VkXcbSurfaceCreateFlagsKHR; | ||||
|  | ||||
| typedef struct VkXlibSurfaceCreateInfoKHR | ||||
| { | ||||
|     VkStructureType             sType; | ||||
|     const void*                 pNext; | ||||
|     VkXlibSurfaceCreateFlagsKHR flags; | ||||
|     Display*                    dpy; | ||||
|     Window                      window; | ||||
| } VkXlibSurfaceCreateInfoKHR; | ||||
|  | ||||
| typedef struct VkXcbSurfaceCreateInfoKHR | ||||
| { | ||||
|     VkStructureType             sType; | ||||
|     const void*                 pNext; | ||||
|     VkXcbSurfaceCreateFlagsKHR  flags; | ||||
|     xcb_connection_t*           connection; | ||||
|     xcb_window_t                window; | ||||
| } VkXcbSurfaceCreateInfoKHR; | ||||
|  | ||||
| typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); | ||||
| typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID); | ||||
| typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); | ||||
| typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t); | ||||
|  | ||||
| #include "posix_thread.h" | ||||
| #include "posix_time.h" | ||||
| #include "xkb_unicode.h" | ||||
| #include "glx_context.h" | ||||
| #include "egl_context.h" | ||||
| #include "osmesa_context.h" | ||||
| #if defined(__linux__) | ||||
| #include "linux_joystick.h" | ||||
| #else | ||||
| #include "null_joystick.h" | ||||
| #endif | ||||
|  | ||||
| #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) | ||||
| #define _glfw_dlclose(handle) dlclose(handle) | ||||
| #define _glfw_dlsym(handle, name) dlsym(handle, name) | ||||
|  | ||||
| #define _GLFW_EGL_NATIVE_WINDOW  ((EGLNativeWindowType) window->x11.handle) | ||||
| #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display) | ||||
|  | ||||
| #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowX11  x11 | ||||
| #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 | ||||
| #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorX11 x11 | ||||
| #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorX11  x11 | ||||
|  | ||||
|  | ||||
| // X11-specific per-window data | ||||
| // | ||||
| typedef struct _GLFWwindowX11 | ||||
| { | ||||
|     Colormap        colormap; | ||||
|     Window          handle; | ||||
|     Window          parent; | ||||
|     XIC             ic; | ||||
|  | ||||
|     GLFWbool        overrideRedirect; | ||||
|     GLFWbool        iconified; | ||||
|     GLFWbool        maximized; | ||||
|  | ||||
|     // Whether the visual supports framebuffer transparency | ||||
|     GLFWbool        transparent; | ||||
|  | ||||
|     // Cached position and size used to filter out duplicate events | ||||
|     int             width, height; | ||||
|     int             xpos, ypos; | ||||
|  | ||||
|     // The last received cursor position, regardless of source | ||||
|     int             lastCursorPosX, lastCursorPosY; | ||||
|     // The last position the cursor was warped to by GLFW | ||||
|     int             warpCursorPosX, warpCursorPosY; | ||||
|  | ||||
|     // The time of the last KeyPress event per keycode, for discarding | ||||
|     // duplicate key events generated for some keys by ibus | ||||
|     Time            keyPressTimes[256]; | ||||
| } _GLFWwindowX11; | ||||
|  | ||||
| // X11-specific global data | ||||
| // | ||||
| typedef struct _GLFWlibraryX11 | ||||
| { | ||||
|     Display*        display; | ||||
|     int             screen; | ||||
|     Window          root; | ||||
|  | ||||
|     // System content scale | ||||
|     float           contentScaleX, contentScaleY; | ||||
|     // Helper window for IPC | ||||
|     Window          helperWindowHandle; | ||||
|     // Invisible cursor for hidden cursor mode | ||||
|     Cursor          hiddenCursorHandle; | ||||
|     // Context for mapping window XIDs to _GLFWwindow pointers | ||||
|     XContext        context; | ||||
|     // XIM input method | ||||
|     XIM             im; | ||||
|     // Most recent error code received by X error handler | ||||
|     int             errorCode; | ||||
|     // Primary selection string (while the primary selection is owned) | ||||
|     char*           primarySelectionString; | ||||
|     // Clipboard string (while the selection is owned) | ||||
|     char*           clipboardString; | ||||
|     // Key name string | ||||
|     char            keynames[GLFW_KEY_LAST + 1][5]; | ||||
|     // X11 keycode to GLFW key LUT | ||||
|     short int       keycodes[256]; | ||||
|     // GLFW key to X11 keycode LUT | ||||
|     short int       scancodes[GLFW_KEY_LAST + 1]; | ||||
|     // Where to place the cursor when re-enabled | ||||
|     double          restoreCursorPosX, restoreCursorPosY; | ||||
|     // The window whose disabled cursor mode is active | ||||
|     _GLFWwindow*    disabledCursorWindow; | ||||
|  | ||||
|     // Window manager atoms | ||||
|     Atom            NET_SUPPORTED; | ||||
|     Atom            NET_SUPPORTING_WM_CHECK; | ||||
|     Atom            WM_PROTOCOLS; | ||||
|     Atom            WM_STATE; | ||||
|     Atom            WM_DELETE_WINDOW; | ||||
|     Atom            NET_WM_NAME; | ||||
|     Atom            NET_WM_ICON_NAME; | ||||
|     Atom            NET_WM_ICON; | ||||
|     Atom            NET_WM_PID; | ||||
|     Atom            NET_WM_PING; | ||||
|     Atom            NET_WM_WINDOW_TYPE; | ||||
|     Atom            NET_WM_WINDOW_TYPE_NORMAL; | ||||
|     Atom            NET_WM_STATE; | ||||
|     Atom            NET_WM_STATE_ABOVE; | ||||
|     Atom            NET_WM_STATE_FULLSCREEN; | ||||
|     Atom            NET_WM_STATE_MAXIMIZED_VERT; | ||||
|     Atom            NET_WM_STATE_MAXIMIZED_HORZ; | ||||
|     Atom            NET_WM_STATE_DEMANDS_ATTENTION; | ||||
|     Atom            NET_WM_BYPASS_COMPOSITOR; | ||||
|     Atom            NET_WM_FULLSCREEN_MONITORS; | ||||
|     Atom            NET_WM_WINDOW_OPACITY; | ||||
|     Atom            NET_WM_CM_Sx; | ||||
|     Atom            NET_WORKAREA; | ||||
|     Atom            NET_CURRENT_DESKTOP; | ||||
|     Atom            NET_ACTIVE_WINDOW; | ||||
|     Atom            NET_FRAME_EXTENTS; | ||||
|     Atom            NET_REQUEST_FRAME_EXTENTS; | ||||
|     Atom            MOTIF_WM_HINTS; | ||||
|  | ||||
|     // Xdnd (drag and drop) atoms | ||||
|     Atom            XdndAware; | ||||
|     Atom            XdndEnter; | ||||
|     Atom            XdndPosition; | ||||
|     Atom            XdndStatus; | ||||
|     Atom            XdndActionCopy; | ||||
|     Atom            XdndDrop; | ||||
|     Atom            XdndFinished; | ||||
|     Atom            XdndSelection; | ||||
|     Atom            XdndTypeList; | ||||
|     Atom            text_uri_list; | ||||
|  | ||||
|     // Selection (clipboard) atoms | ||||
|     Atom            TARGETS; | ||||
|     Atom            MULTIPLE; | ||||
|     Atom            INCR; | ||||
|     Atom            CLIPBOARD; | ||||
|     Atom            PRIMARY; | ||||
|     Atom            CLIPBOARD_MANAGER; | ||||
|     Atom            SAVE_TARGETS; | ||||
|     Atom            NULL_; | ||||
|     Atom            UTF8_STRING; | ||||
|     Atom            COMPOUND_STRING; | ||||
|     Atom            ATOM_PAIR; | ||||
|     Atom            GLFW_SELECTION; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool    available; | ||||
|         void*       handle; | ||||
|         int         eventBase; | ||||
|         int         errorBase; | ||||
|         int         major; | ||||
|         int         minor; | ||||
|         GLFWbool    gammaBroken; | ||||
|         GLFWbool    monitorBroken; | ||||
|         PFN_XRRAllocGamma AllocGamma; | ||||
|         PFN_XRRFreeCrtcInfo FreeCrtcInfo; | ||||
|         PFN_XRRFreeGamma FreeGamma; | ||||
|         PFN_XRRFreeOutputInfo FreeOutputInfo; | ||||
|         PFN_XRRFreeScreenResources FreeScreenResources; | ||||
|         PFN_XRRGetCrtcGamma GetCrtcGamma; | ||||
|         PFN_XRRGetCrtcGammaSize GetCrtcGammaSize; | ||||
|         PFN_XRRGetCrtcInfo GetCrtcInfo; | ||||
|         PFN_XRRGetOutputInfo GetOutputInfo; | ||||
|         PFN_XRRGetOutputPrimary GetOutputPrimary; | ||||
|         PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent; | ||||
|         PFN_XRRQueryExtension QueryExtension; | ||||
|         PFN_XRRQueryVersion QueryVersion; | ||||
|         PFN_XRRSelectInput SelectInput; | ||||
|         PFN_XRRSetCrtcConfig SetCrtcConfig; | ||||
|         PFN_XRRSetCrtcGamma SetCrtcGamma; | ||||
|         PFN_XRRUpdateConfiguration UpdateConfiguration; | ||||
|     } randr; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool     available; | ||||
|         GLFWbool     detectable; | ||||
|         int          majorOpcode; | ||||
|         int          eventBase; | ||||
|         int          errorBase; | ||||
|         int          major; | ||||
|         int          minor; | ||||
|         unsigned int group; | ||||
|     } xkb; | ||||
|  | ||||
|     struct { | ||||
|         int         count; | ||||
|         int         timeout; | ||||
|         int         interval; | ||||
|         int         blanking; | ||||
|         int         exposure; | ||||
|     } saver; | ||||
|  | ||||
|     struct { | ||||
|         int         version; | ||||
|         Window      source; | ||||
|         Atom        format; | ||||
|     } xdnd; | ||||
|  | ||||
|     struct { | ||||
|         void*       handle; | ||||
|         PFN_XcursorImageCreate ImageCreate; | ||||
|         PFN_XcursorImageDestroy ImageDestroy; | ||||
|         PFN_XcursorImageLoadCursor ImageLoadCursor; | ||||
|     } xcursor; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool    available; | ||||
|         void*       handle; | ||||
|         int         major; | ||||
|         int         minor; | ||||
|         PFN_XineramaIsActive IsActive; | ||||
|         PFN_XineramaQueryExtension QueryExtension; | ||||
|         PFN_XineramaQueryScreens QueryScreens; | ||||
|     } xinerama; | ||||
|  | ||||
|     struct { | ||||
|         void*       handle; | ||||
|         PFN_XGetXCBConnection GetXCBConnection; | ||||
|     } x11xcb; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool    available; | ||||
|         void*       handle; | ||||
|         int         eventBase; | ||||
|         int         errorBase; | ||||
|         PFN_XF86VidModeQueryExtension QueryExtension; | ||||
|         PFN_XF86VidModeGetGammaRamp GetGammaRamp; | ||||
|         PFN_XF86VidModeSetGammaRamp SetGammaRamp; | ||||
|         PFN_XF86VidModeGetGammaRampSize GetGammaRampSize; | ||||
|     } vidmode; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool    available; | ||||
|         void*       handle; | ||||
|         int         majorOpcode; | ||||
|         int         eventBase; | ||||
|         int         errorBase; | ||||
|         int         major; | ||||
|         int         minor; | ||||
|         PFN_XIQueryVersion QueryVersion; | ||||
|         PFN_XISelectEvents SelectEvents; | ||||
|     } xi; | ||||
|  | ||||
|     struct { | ||||
|         GLFWbool    available; | ||||
|         void*       handle; | ||||
|         int         major; | ||||
|         int         minor; | ||||
|         int         eventBase; | ||||
|         int         errorBase; | ||||
|         PFN_XRenderQueryExtension QueryExtension; | ||||
|         PFN_XRenderQueryVersion QueryVersion; | ||||
|         PFN_XRenderFindVisualFormat FindVisualFormat; | ||||
|     } xrender; | ||||
| } _GLFWlibraryX11; | ||||
|  | ||||
| // X11-specific per-monitor data | ||||
| // | ||||
| typedef struct _GLFWmonitorX11 | ||||
| { | ||||
|     RROutput        output; | ||||
|     RRCrtc          crtc; | ||||
|     RRMode          oldMode; | ||||
|  | ||||
|     // Index of corresponding Xinerama screen, | ||||
|     // for EWMH full screen window placement | ||||
|     int             index; | ||||
| } _GLFWmonitorX11; | ||||
|  | ||||
| // X11-specific per-cursor data | ||||
| // | ||||
| typedef struct _GLFWcursorX11 | ||||
| { | ||||
|     Cursor handle; | ||||
| } _GLFWcursorX11; | ||||
|  | ||||
|  | ||||
| void _glfwPollMonitorsX11(void); | ||||
| void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired); | ||||
| void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor); | ||||
|  | ||||
| Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot); | ||||
|  | ||||
| unsigned long _glfwGetWindowPropertyX11(Window window, | ||||
|                                         Atom property, | ||||
|                                         Atom type, | ||||
|                                         unsigned char** value); | ||||
| GLFWbool _glfwIsVisualTransparentX11(Visual* visual); | ||||
|  | ||||
| void _glfwGrabErrorHandlerX11(void); | ||||
| void _glfwReleaseErrorHandlerX11(void); | ||||
| void _glfwInputErrorX11(int error, const char* message); | ||||
|  | ||||
| void _glfwPushSelectionToManagerX11(void); | ||||
|  | ||||
							
								
								
									
										3194
									
								
								deps/glfw/src/x11_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3194
									
								
								deps/glfw/src/x11_window.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										942
									
								
								deps/glfw/src/xkb_unicode.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										942
									
								
								deps/glfw/src/xkb_unicode.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,942 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 X11 - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2002-2006 Marcus Geelnard | ||||
| // Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
| // It is fine to use C99 in this file because it will not be built with VS | ||||
| //======================================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Marcus: This code was originally written by Markus G. Kuhn. | ||||
|  * I have made some slight changes (trimmed it down a bit from >60 KB to | ||||
|  * 20 KB), but the functionality is the same. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * This module converts keysym values into the corresponding ISO 10646 | ||||
|  * (UCS, Unicode) values. | ||||
|  * | ||||
|  * The array keysymtab[] contains pairs of X11 keysym values for graphical | ||||
|  * characters and the corresponding Unicode value. The function | ||||
|  * _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary | ||||
|  * search, therefore keysymtab[] must remain SORTED by keysym value. | ||||
|  * | ||||
|  * We allow to represent any UCS character in the range U-00000000 to | ||||
|  * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. | ||||
|  * This admittedly does not cover the entire 31-bit space of UCS, but | ||||
|  * it does cover all of the characters up to U-10FFFF, which can be | ||||
|  * represented by UTF-16, and more, and it is very unlikely that higher | ||||
|  * UCS codes will ever be assigned by ISO. So to get Unicode character | ||||
|  * U+ABCD you can directly use keysym 0x0100abcd. | ||||
|  * | ||||
|  * Original author: Markus G. Kuhn <mkuhn@acm.org>, University of | ||||
|  *                  Cambridge, April 2001 | ||||
|  * | ||||
|  * Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing | ||||
|  * an initial draft of the mapping table. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| //************************************************************************ | ||||
| //****                KeySym to Unicode mapping table                 **** | ||||
| //************************************************************************ | ||||
|  | ||||
| static const struct codepair { | ||||
|   unsigned short keysym; | ||||
|   unsigned short ucs; | ||||
| } keysymtab[] = { | ||||
|   { 0x01a1, 0x0104 }, | ||||
|   { 0x01a2, 0x02d8 }, | ||||
|   { 0x01a3, 0x0141 }, | ||||
|   { 0x01a5, 0x013d }, | ||||
|   { 0x01a6, 0x015a }, | ||||
|   { 0x01a9, 0x0160 }, | ||||
|   { 0x01aa, 0x015e }, | ||||
|   { 0x01ab, 0x0164 }, | ||||
|   { 0x01ac, 0x0179 }, | ||||
|   { 0x01ae, 0x017d }, | ||||
|   { 0x01af, 0x017b }, | ||||
|   { 0x01b1, 0x0105 }, | ||||
|   { 0x01b2, 0x02db }, | ||||
|   { 0x01b3, 0x0142 }, | ||||
|   { 0x01b5, 0x013e }, | ||||
|   { 0x01b6, 0x015b }, | ||||
|   { 0x01b7, 0x02c7 }, | ||||
|   { 0x01b9, 0x0161 }, | ||||
|   { 0x01ba, 0x015f }, | ||||
|   { 0x01bb, 0x0165 }, | ||||
|   { 0x01bc, 0x017a }, | ||||
|   { 0x01bd, 0x02dd }, | ||||
|   { 0x01be, 0x017e }, | ||||
|   { 0x01bf, 0x017c }, | ||||
|   { 0x01c0, 0x0154 }, | ||||
|   { 0x01c3, 0x0102 }, | ||||
|   { 0x01c5, 0x0139 }, | ||||
|   { 0x01c6, 0x0106 }, | ||||
|   { 0x01c8, 0x010c }, | ||||
|   { 0x01ca, 0x0118 }, | ||||
|   { 0x01cc, 0x011a }, | ||||
|   { 0x01cf, 0x010e }, | ||||
|   { 0x01d0, 0x0110 }, | ||||
|   { 0x01d1, 0x0143 }, | ||||
|   { 0x01d2, 0x0147 }, | ||||
|   { 0x01d5, 0x0150 }, | ||||
|   { 0x01d8, 0x0158 }, | ||||
|   { 0x01d9, 0x016e }, | ||||
|   { 0x01db, 0x0170 }, | ||||
|   { 0x01de, 0x0162 }, | ||||
|   { 0x01e0, 0x0155 }, | ||||
|   { 0x01e3, 0x0103 }, | ||||
|   { 0x01e5, 0x013a }, | ||||
|   { 0x01e6, 0x0107 }, | ||||
|   { 0x01e8, 0x010d }, | ||||
|   { 0x01ea, 0x0119 }, | ||||
|   { 0x01ec, 0x011b }, | ||||
|   { 0x01ef, 0x010f }, | ||||
|   { 0x01f0, 0x0111 }, | ||||
|   { 0x01f1, 0x0144 }, | ||||
|   { 0x01f2, 0x0148 }, | ||||
|   { 0x01f5, 0x0151 }, | ||||
|   { 0x01f8, 0x0159 }, | ||||
|   { 0x01f9, 0x016f }, | ||||
|   { 0x01fb, 0x0171 }, | ||||
|   { 0x01fe, 0x0163 }, | ||||
|   { 0x01ff, 0x02d9 }, | ||||
|   { 0x02a1, 0x0126 }, | ||||
|   { 0x02a6, 0x0124 }, | ||||
|   { 0x02a9, 0x0130 }, | ||||
|   { 0x02ab, 0x011e }, | ||||
|   { 0x02ac, 0x0134 }, | ||||
|   { 0x02b1, 0x0127 }, | ||||
|   { 0x02b6, 0x0125 }, | ||||
|   { 0x02b9, 0x0131 }, | ||||
|   { 0x02bb, 0x011f }, | ||||
|   { 0x02bc, 0x0135 }, | ||||
|   { 0x02c5, 0x010a }, | ||||
|   { 0x02c6, 0x0108 }, | ||||
|   { 0x02d5, 0x0120 }, | ||||
|   { 0x02d8, 0x011c }, | ||||
|   { 0x02dd, 0x016c }, | ||||
|   { 0x02de, 0x015c }, | ||||
|   { 0x02e5, 0x010b }, | ||||
|   { 0x02e6, 0x0109 }, | ||||
|   { 0x02f5, 0x0121 }, | ||||
|   { 0x02f8, 0x011d }, | ||||
|   { 0x02fd, 0x016d }, | ||||
|   { 0x02fe, 0x015d }, | ||||
|   { 0x03a2, 0x0138 }, | ||||
|   { 0x03a3, 0x0156 }, | ||||
|   { 0x03a5, 0x0128 }, | ||||
|   { 0x03a6, 0x013b }, | ||||
|   { 0x03aa, 0x0112 }, | ||||
|   { 0x03ab, 0x0122 }, | ||||
|   { 0x03ac, 0x0166 }, | ||||
|   { 0x03b3, 0x0157 }, | ||||
|   { 0x03b5, 0x0129 }, | ||||
|   { 0x03b6, 0x013c }, | ||||
|   { 0x03ba, 0x0113 }, | ||||
|   { 0x03bb, 0x0123 }, | ||||
|   { 0x03bc, 0x0167 }, | ||||
|   { 0x03bd, 0x014a }, | ||||
|   { 0x03bf, 0x014b }, | ||||
|   { 0x03c0, 0x0100 }, | ||||
|   { 0x03c7, 0x012e }, | ||||
|   { 0x03cc, 0x0116 }, | ||||
|   { 0x03cf, 0x012a }, | ||||
|   { 0x03d1, 0x0145 }, | ||||
|   { 0x03d2, 0x014c }, | ||||
|   { 0x03d3, 0x0136 }, | ||||
|   { 0x03d9, 0x0172 }, | ||||
|   { 0x03dd, 0x0168 }, | ||||
|   { 0x03de, 0x016a }, | ||||
|   { 0x03e0, 0x0101 }, | ||||
|   { 0x03e7, 0x012f }, | ||||
|   { 0x03ec, 0x0117 }, | ||||
|   { 0x03ef, 0x012b }, | ||||
|   { 0x03f1, 0x0146 }, | ||||
|   { 0x03f2, 0x014d }, | ||||
|   { 0x03f3, 0x0137 }, | ||||
|   { 0x03f9, 0x0173 }, | ||||
|   { 0x03fd, 0x0169 }, | ||||
|   { 0x03fe, 0x016b }, | ||||
|   { 0x047e, 0x203e }, | ||||
|   { 0x04a1, 0x3002 }, | ||||
|   { 0x04a2, 0x300c }, | ||||
|   { 0x04a3, 0x300d }, | ||||
|   { 0x04a4, 0x3001 }, | ||||
|   { 0x04a5, 0x30fb }, | ||||
|   { 0x04a6, 0x30f2 }, | ||||
|   { 0x04a7, 0x30a1 }, | ||||
|   { 0x04a8, 0x30a3 }, | ||||
|   { 0x04a9, 0x30a5 }, | ||||
|   { 0x04aa, 0x30a7 }, | ||||
|   { 0x04ab, 0x30a9 }, | ||||
|   { 0x04ac, 0x30e3 }, | ||||
|   { 0x04ad, 0x30e5 }, | ||||
|   { 0x04ae, 0x30e7 }, | ||||
|   { 0x04af, 0x30c3 }, | ||||
|   { 0x04b0, 0x30fc }, | ||||
|   { 0x04b1, 0x30a2 }, | ||||
|   { 0x04b2, 0x30a4 }, | ||||
|   { 0x04b3, 0x30a6 }, | ||||
|   { 0x04b4, 0x30a8 }, | ||||
|   { 0x04b5, 0x30aa }, | ||||
|   { 0x04b6, 0x30ab }, | ||||
|   { 0x04b7, 0x30ad }, | ||||
|   { 0x04b8, 0x30af }, | ||||
|   { 0x04b9, 0x30b1 }, | ||||
|   { 0x04ba, 0x30b3 }, | ||||
|   { 0x04bb, 0x30b5 }, | ||||
|   { 0x04bc, 0x30b7 }, | ||||
|   { 0x04bd, 0x30b9 }, | ||||
|   { 0x04be, 0x30bb }, | ||||
|   { 0x04bf, 0x30bd }, | ||||
|   { 0x04c0, 0x30bf }, | ||||
|   { 0x04c1, 0x30c1 }, | ||||
|   { 0x04c2, 0x30c4 }, | ||||
|   { 0x04c3, 0x30c6 }, | ||||
|   { 0x04c4, 0x30c8 }, | ||||
|   { 0x04c5, 0x30ca }, | ||||
|   { 0x04c6, 0x30cb }, | ||||
|   { 0x04c7, 0x30cc }, | ||||
|   { 0x04c8, 0x30cd }, | ||||
|   { 0x04c9, 0x30ce }, | ||||
|   { 0x04ca, 0x30cf }, | ||||
|   { 0x04cb, 0x30d2 }, | ||||
|   { 0x04cc, 0x30d5 }, | ||||
|   { 0x04cd, 0x30d8 }, | ||||
|   { 0x04ce, 0x30db }, | ||||
|   { 0x04cf, 0x30de }, | ||||
|   { 0x04d0, 0x30df }, | ||||
|   { 0x04d1, 0x30e0 }, | ||||
|   { 0x04d2, 0x30e1 }, | ||||
|   { 0x04d3, 0x30e2 }, | ||||
|   { 0x04d4, 0x30e4 }, | ||||
|   { 0x04d5, 0x30e6 }, | ||||
|   { 0x04d6, 0x30e8 }, | ||||
|   { 0x04d7, 0x30e9 }, | ||||
|   { 0x04d8, 0x30ea }, | ||||
|   { 0x04d9, 0x30eb }, | ||||
|   { 0x04da, 0x30ec }, | ||||
|   { 0x04db, 0x30ed }, | ||||
|   { 0x04dc, 0x30ef }, | ||||
|   { 0x04dd, 0x30f3 }, | ||||
|   { 0x04de, 0x309b }, | ||||
|   { 0x04df, 0x309c }, | ||||
|   { 0x05ac, 0x060c }, | ||||
|   { 0x05bb, 0x061b }, | ||||
|   { 0x05bf, 0x061f }, | ||||
|   { 0x05c1, 0x0621 }, | ||||
|   { 0x05c2, 0x0622 }, | ||||
|   { 0x05c3, 0x0623 }, | ||||
|   { 0x05c4, 0x0624 }, | ||||
|   { 0x05c5, 0x0625 }, | ||||
|   { 0x05c6, 0x0626 }, | ||||
|   { 0x05c7, 0x0627 }, | ||||
|   { 0x05c8, 0x0628 }, | ||||
|   { 0x05c9, 0x0629 }, | ||||
|   { 0x05ca, 0x062a }, | ||||
|   { 0x05cb, 0x062b }, | ||||
|   { 0x05cc, 0x062c }, | ||||
|   { 0x05cd, 0x062d }, | ||||
|   { 0x05ce, 0x062e }, | ||||
|   { 0x05cf, 0x062f }, | ||||
|   { 0x05d0, 0x0630 }, | ||||
|   { 0x05d1, 0x0631 }, | ||||
|   { 0x05d2, 0x0632 }, | ||||
|   { 0x05d3, 0x0633 }, | ||||
|   { 0x05d4, 0x0634 }, | ||||
|   { 0x05d5, 0x0635 }, | ||||
|   { 0x05d6, 0x0636 }, | ||||
|   { 0x05d7, 0x0637 }, | ||||
|   { 0x05d8, 0x0638 }, | ||||
|   { 0x05d9, 0x0639 }, | ||||
|   { 0x05da, 0x063a }, | ||||
|   { 0x05e0, 0x0640 }, | ||||
|   { 0x05e1, 0x0641 }, | ||||
|   { 0x05e2, 0x0642 }, | ||||
|   { 0x05e3, 0x0643 }, | ||||
|   { 0x05e4, 0x0644 }, | ||||
|   { 0x05e5, 0x0645 }, | ||||
|   { 0x05e6, 0x0646 }, | ||||
|   { 0x05e7, 0x0647 }, | ||||
|   { 0x05e8, 0x0648 }, | ||||
|   { 0x05e9, 0x0649 }, | ||||
|   { 0x05ea, 0x064a }, | ||||
|   { 0x05eb, 0x064b }, | ||||
|   { 0x05ec, 0x064c }, | ||||
|   { 0x05ed, 0x064d }, | ||||
|   { 0x05ee, 0x064e }, | ||||
|   { 0x05ef, 0x064f }, | ||||
|   { 0x05f0, 0x0650 }, | ||||
|   { 0x05f1, 0x0651 }, | ||||
|   { 0x05f2, 0x0652 }, | ||||
|   { 0x06a1, 0x0452 }, | ||||
|   { 0x06a2, 0x0453 }, | ||||
|   { 0x06a3, 0x0451 }, | ||||
|   { 0x06a4, 0x0454 }, | ||||
|   { 0x06a5, 0x0455 }, | ||||
|   { 0x06a6, 0x0456 }, | ||||
|   { 0x06a7, 0x0457 }, | ||||
|   { 0x06a8, 0x0458 }, | ||||
|   { 0x06a9, 0x0459 }, | ||||
|   { 0x06aa, 0x045a }, | ||||
|   { 0x06ab, 0x045b }, | ||||
|   { 0x06ac, 0x045c }, | ||||
|   { 0x06ae, 0x045e }, | ||||
|   { 0x06af, 0x045f }, | ||||
|   { 0x06b0, 0x2116 }, | ||||
|   { 0x06b1, 0x0402 }, | ||||
|   { 0x06b2, 0x0403 }, | ||||
|   { 0x06b3, 0x0401 }, | ||||
|   { 0x06b4, 0x0404 }, | ||||
|   { 0x06b5, 0x0405 }, | ||||
|   { 0x06b6, 0x0406 }, | ||||
|   { 0x06b7, 0x0407 }, | ||||
|   { 0x06b8, 0x0408 }, | ||||
|   { 0x06b9, 0x0409 }, | ||||
|   { 0x06ba, 0x040a }, | ||||
|   { 0x06bb, 0x040b }, | ||||
|   { 0x06bc, 0x040c }, | ||||
|   { 0x06be, 0x040e }, | ||||
|   { 0x06bf, 0x040f }, | ||||
|   { 0x06c0, 0x044e }, | ||||
|   { 0x06c1, 0x0430 }, | ||||
|   { 0x06c2, 0x0431 }, | ||||
|   { 0x06c3, 0x0446 }, | ||||
|   { 0x06c4, 0x0434 }, | ||||
|   { 0x06c5, 0x0435 }, | ||||
|   { 0x06c6, 0x0444 }, | ||||
|   { 0x06c7, 0x0433 }, | ||||
|   { 0x06c8, 0x0445 }, | ||||
|   { 0x06c9, 0x0438 }, | ||||
|   { 0x06ca, 0x0439 }, | ||||
|   { 0x06cb, 0x043a }, | ||||
|   { 0x06cc, 0x043b }, | ||||
|   { 0x06cd, 0x043c }, | ||||
|   { 0x06ce, 0x043d }, | ||||
|   { 0x06cf, 0x043e }, | ||||
|   { 0x06d0, 0x043f }, | ||||
|   { 0x06d1, 0x044f }, | ||||
|   { 0x06d2, 0x0440 }, | ||||
|   { 0x06d3, 0x0441 }, | ||||
|   { 0x06d4, 0x0442 }, | ||||
|   { 0x06d5, 0x0443 }, | ||||
|   { 0x06d6, 0x0436 }, | ||||
|   { 0x06d7, 0x0432 }, | ||||
|   { 0x06d8, 0x044c }, | ||||
|   { 0x06d9, 0x044b }, | ||||
|   { 0x06da, 0x0437 }, | ||||
|   { 0x06db, 0x0448 }, | ||||
|   { 0x06dc, 0x044d }, | ||||
|   { 0x06dd, 0x0449 }, | ||||
|   { 0x06de, 0x0447 }, | ||||
|   { 0x06df, 0x044a }, | ||||
|   { 0x06e0, 0x042e }, | ||||
|   { 0x06e1, 0x0410 }, | ||||
|   { 0x06e2, 0x0411 }, | ||||
|   { 0x06e3, 0x0426 }, | ||||
|   { 0x06e4, 0x0414 }, | ||||
|   { 0x06e5, 0x0415 }, | ||||
|   { 0x06e6, 0x0424 }, | ||||
|   { 0x06e7, 0x0413 }, | ||||
|   { 0x06e8, 0x0425 }, | ||||
|   { 0x06e9, 0x0418 }, | ||||
|   { 0x06ea, 0x0419 }, | ||||
|   { 0x06eb, 0x041a }, | ||||
|   { 0x06ec, 0x041b }, | ||||
|   { 0x06ed, 0x041c }, | ||||
|   { 0x06ee, 0x041d }, | ||||
|   { 0x06ef, 0x041e }, | ||||
|   { 0x06f0, 0x041f }, | ||||
|   { 0x06f1, 0x042f }, | ||||
|   { 0x06f2, 0x0420 }, | ||||
|   { 0x06f3, 0x0421 }, | ||||
|   { 0x06f4, 0x0422 }, | ||||
|   { 0x06f5, 0x0423 }, | ||||
|   { 0x06f6, 0x0416 }, | ||||
|   { 0x06f7, 0x0412 }, | ||||
|   { 0x06f8, 0x042c }, | ||||
|   { 0x06f9, 0x042b }, | ||||
|   { 0x06fa, 0x0417 }, | ||||
|   { 0x06fb, 0x0428 }, | ||||
|   { 0x06fc, 0x042d }, | ||||
|   { 0x06fd, 0x0429 }, | ||||
|   { 0x06fe, 0x0427 }, | ||||
|   { 0x06ff, 0x042a }, | ||||
|   { 0x07a1, 0x0386 }, | ||||
|   { 0x07a2, 0x0388 }, | ||||
|   { 0x07a3, 0x0389 }, | ||||
|   { 0x07a4, 0x038a }, | ||||
|   { 0x07a5, 0x03aa }, | ||||
|   { 0x07a7, 0x038c }, | ||||
|   { 0x07a8, 0x038e }, | ||||
|   { 0x07a9, 0x03ab }, | ||||
|   { 0x07ab, 0x038f }, | ||||
|   { 0x07ae, 0x0385 }, | ||||
|   { 0x07af, 0x2015 }, | ||||
|   { 0x07b1, 0x03ac }, | ||||
|   { 0x07b2, 0x03ad }, | ||||
|   { 0x07b3, 0x03ae }, | ||||
|   { 0x07b4, 0x03af }, | ||||
|   { 0x07b5, 0x03ca }, | ||||
|   { 0x07b6, 0x0390 }, | ||||
|   { 0x07b7, 0x03cc }, | ||||
|   { 0x07b8, 0x03cd }, | ||||
|   { 0x07b9, 0x03cb }, | ||||
|   { 0x07ba, 0x03b0 }, | ||||
|   { 0x07bb, 0x03ce }, | ||||
|   { 0x07c1, 0x0391 }, | ||||
|   { 0x07c2, 0x0392 }, | ||||
|   { 0x07c3, 0x0393 }, | ||||
|   { 0x07c4, 0x0394 }, | ||||
|   { 0x07c5, 0x0395 }, | ||||
|   { 0x07c6, 0x0396 }, | ||||
|   { 0x07c7, 0x0397 }, | ||||
|   { 0x07c8, 0x0398 }, | ||||
|   { 0x07c9, 0x0399 }, | ||||
|   { 0x07ca, 0x039a }, | ||||
|   { 0x07cb, 0x039b }, | ||||
|   { 0x07cc, 0x039c }, | ||||
|   { 0x07cd, 0x039d }, | ||||
|   { 0x07ce, 0x039e }, | ||||
|   { 0x07cf, 0x039f }, | ||||
|   { 0x07d0, 0x03a0 }, | ||||
|   { 0x07d1, 0x03a1 }, | ||||
|   { 0x07d2, 0x03a3 }, | ||||
|   { 0x07d4, 0x03a4 }, | ||||
|   { 0x07d5, 0x03a5 }, | ||||
|   { 0x07d6, 0x03a6 }, | ||||
|   { 0x07d7, 0x03a7 }, | ||||
|   { 0x07d8, 0x03a8 }, | ||||
|   { 0x07d9, 0x03a9 }, | ||||
|   { 0x07e1, 0x03b1 }, | ||||
|   { 0x07e2, 0x03b2 }, | ||||
|   { 0x07e3, 0x03b3 }, | ||||
|   { 0x07e4, 0x03b4 }, | ||||
|   { 0x07e5, 0x03b5 }, | ||||
|   { 0x07e6, 0x03b6 }, | ||||
|   { 0x07e7, 0x03b7 }, | ||||
|   { 0x07e8, 0x03b8 }, | ||||
|   { 0x07e9, 0x03b9 }, | ||||
|   { 0x07ea, 0x03ba }, | ||||
|   { 0x07eb, 0x03bb }, | ||||
|   { 0x07ec, 0x03bc }, | ||||
|   { 0x07ed, 0x03bd }, | ||||
|   { 0x07ee, 0x03be }, | ||||
|   { 0x07ef, 0x03bf }, | ||||
|   { 0x07f0, 0x03c0 }, | ||||
|   { 0x07f1, 0x03c1 }, | ||||
|   { 0x07f2, 0x03c3 }, | ||||
|   { 0x07f3, 0x03c2 }, | ||||
|   { 0x07f4, 0x03c4 }, | ||||
|   { 0x07f5, 0x03c5 }, | ||||
|   { 0x07f6, 0x03c6 }, | ||||
|   { 0x07f7, 0x03c7 }, | ||||
|   { 0x07f8, 0x03c8 }, | ||||
|   { 0x07f9, 0x03c9 }, | ||||
|   { 0x08a1, 0x23b7 }, | ||||
|   { 0x08a2, 0x250c }, | ||||
|   { 0x08a3, 0x2500 }, | ||||
|   { 0x08a4, 0x2320 }, | ||||
|   { 0x08a5, 0x2321 }, | ||||
|   { 0x08a6, 0x2502 }, | ||||
|   { 0x08a7, 0x23a1 }, | ||||
|   { 0x08a8, 0x23a3 }, | ||||
|   { 0x08a9, 0x23a4 }, | ||||
|   { 0x08aa, 0x23a6 }, | ||||
|   { 0x08ab, 0x239b }, | ||||
|   { 0x08ac, 0x239d }, | ||||
|   { 0x08ad, 0x239e }, | ||||
|   { 0x08ae, 0x23a0 }, | ||||
|   { 0x08af, 0x23a8 }, | ||||
|   { 0x08b0, 0x23ac }, | ||||
|   { 0x08bc, 0x2264 }, | ||||
|   { 0x08bd, 0x2260 }, | ||||
|   { 0x08be, 0x2265 }, | ||||
|   { 0x08bf, 0x222b }, | ||||
|   { 0x08c0, 0x2234 }, | ||||
|   { 0x08c1, 0x221d }, | ||||
|   { 0x08c2, 0x221e }, | ||||
|   { 0x08c5, 0x2207 }, | ||||
|   { 0x08c8, 0x223c }, | ||||
|   { 0x08c9, 0x2243 }, | ||||
|   { 0x08cd, 0x21d4 }, | ||||
|   { 0x08ce, 0x21d2 }, | ||||
|   { 0x08cf, 0x2261 }, | ||||
|   { 0x08d6, 0x221a }, | ||||
|   { 0x08da, 0x2282 }, | ||||
|   { 0x08db, 0x2283 }, | ||||
|   { 0x08dc, 0x2229 }, | ||||
|   { 0x08dd, 0x222a }, | ||||
|   { 0x08de, 0x2227 }, | ||||
|   { 0x08df, 0x2228 }, | ||||
|   { 0x08ef, 0x2202 }, | ||||
|   { 0x08f6, 0x0192 }, | ||||
|   { 0x08fb, 0x2190 }, | ||||
|   { 0x08fc, 0x2191 }, | ||||
|   { 0x08fd, 0x2192 }, | ||||
|   { 0x08fe, 0x2193 }, | ||||
|   { 0x09e0, 0x25c6 }, | ||||
|   { 0x09e1, 0x2592 }, | ||||
|   { 0x09e2, 0x2409 }, | ||||
|   { 0x09e3, 0x240c }, | ||||
|   { 0x09e4, 0x240d }, | ||||
|   { 0x09e5, 0x240a }, | ||||
|   { 0x09e8, 0x2424 }, | ||||
|   { 0x09e9, 0x240b }, | ||||
|   { 0x09ea, 0x2518 }, | ||||
|   { 0x09eb, 0x2510 }, | ||||
|   { 0x09ec, 0x250c }, | ||||
|   { 0x09ed, 0x2514 }, | ||||
|   { 0x09ee, 0x253c }, | ||||
|   { 0x09ef, 0x23ba }, | ||||
|   { 0x09f0, 0x23bb }, | ||||
|   { 0x09f1, 0x2500 }, | ||||
|   { 0x09f2, 0x23bc }, | ||||
|   { 0x09f3, 0x23bd }, | ||||
|   { 0x09f4, 0x251c }, | ||||
|   { 0x09f5, 0x2524 }, | ||||
|   { 0x09f6, 0x2534 }, | ||||
|   { 0x09f7, 0x252c }, | ||||
|   { 0x09f8, 0x2502 }, | ||||
|   { 0x0aa1, 0x2003 }, | ||||
|   { 0x0aa2, 0x2002 }, | ||||
|   { 0x0aa3, 0x2004 }, | ||||
|   { 0x0aa4, 0x2005 }, | ||||
|   { 0x0aa5, 0x2007 }, | ||||
|   { 0x0aa6, 0x2008 }, | ||||
|   { 0x0aa7, 0x2009 }, | ||||
|   { 0x0aa8, 0x200a }, | ||||
|   { 0x0aa9, 0x2014 }, | ||||
|   { 0x0aaa, 0x2013 }, | ||||
|   { 0x0aae, 0x2026 }, | ||||
|   { 0x0aaf, 0x2025 }, | ||||
|   { 0x0ab0, 0x2153 }, | ||||
|   { 0x0ab1, 0x2154 }, | ||||
|   { 0x0ab2, 0x2155 }, | ||||
|   { 0x0ab3, 0x2156 }, | ||||
|   { 0x0ab4, 0x2157 }, | ||||
|   { 0x0ab5, 0x2158 }, | ||||
|   { 0x0ab6, 0x2159 }, | ||||
|   { 0x0ab7, 0x215a }, | ||||
|   { 0x0ab8, 0x2105 }, | ||||
|   { 0x0abb, 0x2012 }, | ||||
|   { 0x0abc, 0x2329 }, | ||||
|   { 0x0abe, 0x232a }, | ||||
|   { 0x0ac3, 0x215b }, | ||||
|   { 0x0ac4, 0x215c }, | ||||
|   { 0x0ac5, 0x215d }, | ||||
|   { 0x0ac6, 0x215e }, | ||||
|   { 0x0ac9, 0x2122 }, | ||||
|   { 0x0aca, 0x2613 }, | ||||
|   { 0x0acc, 0x25c1 }, | ||||
|   { 0x0acd, 0x25b7 }, | ||||
|   { 0x0ace, 0x25cb }, | ||||
|   { 0x0acf, 0x25af }, | ||||
|   { 0x0ad0, 0x2018 }, | ||||
|   { 0x0ad1, 0x2019 }, | ||||
|   { 0x0ad2, 0x201c }, | ||||
|   { 0x0ad3, 0x201d }, | ||||
|   { 0x0ad4, 0x211e }, | ||||
|   { 0x0ad6, 0x2032 }, | ||||
|   { 0x0ad7, 0x2033 }, | ||||
|   { 0x0ad9, 0x271d }, | ||||
|   { 0x0adb, 0x25ac }, | ||||
|   { 0x0adc, 0x25c0 }, | ||||
|   { 0x0add, 0x25b6 }, | ||||
|   { 0x0ade, 0x25cf }, | ||||
|   { 0x0adf, 0x25ae }, | ||||
|   { 0x0ae0, 0x25e6 }, | ||||
|   { 0x0ae1, 0x25ab }, | ||||
|   { 0x0ae2, 0x25ad }, | ||||
|   { 0x0ae3, 0x25b3 }, | ||||
|   { 0x0ae4, 0x25bd }, | ||||
|   { 0x0ae5, 0x2606 }, | ||||
|   { 0x0ae6, 0x2022 }, | ||||
|   { 0x0ae7, 0x25aa }, | ||||
|   { 0x0ae8, 0x25b2 }, | ||||
|   { 0x0ae9, 0x25bc }, | ||||
|   { 0x0aea, 0x261c }, | ||||
|   { 0x0aeb, 0x261e }, | ||||
|   { 0x0aec, 0x2663 }, | ||||
|   { 0x0aed, 0x2666 }, | ||||
|   { 0x0aee, 0x2665 }, | ||||
|   { 0x0af0, 0x2720 }, | ||||
|   { 0x0af1, 0x2020 }, | ||||
|   { 0x0af2, 0x2021 }, | ||||
|   { 0x0af3, 0x2713 }, | ||||
|   { 0x0af4, 0x2717 }, | ||||
|   { 0x0af5, 0x266f }, | ||||
|   { 0x0af6, 0x266d }, | ||||
|   { 0x0af7, 0x2642 }, | ||||
|   { 0x0af8, 0x2640 }, | ||||
|   { 0x0af9, 0x260e }, | ||||
|   { 0x0afa, 0x2315 }, | ||||
|   { 0x0afb, 0x2117 }, | ||||
|   { 0x0afc, 0x2038 }, | ||||
|   { 0x0afd, 0x201a }, | ||||
|   { 0x0afe, 0x201e }, | ||||
|   { 0x0ba3, 0x003c }, | ||||
|   { 0x0ba6, 0x003e }, | ||||
|   { 0x0ba8, 0x2228 }, | ||||
|   { 0x0ba9, 0x2227 }, | ||||
|   { 0x0bc0, 0x00af }, | ||||
|   { 0x0bc2, 0x22a5 }, | ||||
|   { 0x0bc3, 0x2229 }, | ||||
|   { 0x0bc4, 0x230a }, | ||||
|   { 0x0bc6, 0x005f }, | ||||
|   { 0x0bca, 0x2218 }, | ||||
|   { 0x0bcc, 0x2395 }, | ||||
|   { 0x0bce, 0x22a4 }, | ||||
|   { 0x0bcf, 0x25cb }, | ||||
|   { 0x0bd3, 0x2308 }, | ||||
|   { 0x0bd6, 0x222a }, | ||||
|   { 0x0bd8, 0x2283 }, | ||||
|   { 0x0bda, 0x2282 }, | ||||
|   { 0x0bdc, 0x22a2 }, | ||||
|   { 0x0bfc, 0x22a3 }, | ||||
|   { 0x0cdf, 0x2017 }, | ||||
|   { 0x0ce0, 0x05d0 }, | ||||
|   { 0x0ce1, 0x05d1 }, | ||||
|   { 0x0ce2, 0x05d2 }, | ||||
|   { 0x0ce3, 0x05d3 }, | ||||
|   { 0x0ce4, 0x05d4 }, | ||||
|   { 0x0ce5, 0x05d5 }, | ||||
|   { 0x0ce6, 0x05d6 }, | ||||
|   { 0x0ce7, 0x05d7 }, | ||||
|   { 0x0ce8, 0x05d8 }, | ||||
|   { 0x0ce9, 0x05d9 }, | ||||
|   { 0x0cea, 0x05da }, | ||||
|   { 0x0ceb, 0x05db }, | ||||
|   { 0x0cec, 0x05dc }, | ||||
|   { 0x0ced, 0x05dd }, | ||||
|   { 0x0cee, 0x05de }, | ||||
|   { 0x0cef, 0x05df }, | ||||
|   { 0x0cf0, 0x05e0 }, | ||||
|   { 0x0cf1, 0x05e1 }, | ||||
|   { 0x0cf2, 0x05e2 }, | ||||
|   { 0x0cf3, 0x05e3 }, | ||||
|   { 0x0cf4, 0x05e4 }, | ||||
|   { 0x0cf5, 0x05e5 }, | ||||
|   { 0x0cf6, 0x05e6 }, | ||||
|   { 0x0cf7, 0x05e7 }, | ||||
|   { 0x0cf8, 0x05e8 }, | ||||
|   { 0x0cf9, 0x05e9 }, | ||||
|   { 0x0cfa, 0x05ea }, | ||||
|   { 0x0da1, 0x0e01 }, | ||||
|   { 0x0da2, 0x0e02 }, | ||||
|   { 0x0da3, 0x0e03 }, | ||||
|   { 0x0da4, 0x0e04 }, | ||||
|   { 0x0da5, 0x0e05 }, | ||||
|   { 0x0da6, 0x0e06 }, | ||||
|   { 0x0da7, 0x0e07 }, | ||||
|   { 0x0da8, 0x0e08 }, | ||||
|   { 0x0da9, 0x0e09 }, | ||||
|   { 0x0daa, 0x0e0a }, | ||||
|   { 0x0dab, 0x0e0b }, | ||||
|   { 0x0dac, 0x0e0c }, | ||||
|   { 0x0dad, 0x0e0d }, | ||||
|   { 0x0dae, 0x0e0e }, | ||||
|   { 0x0daf, 0x0e0f }, | ||||
|   { 0x0db0, 0x0e10 }, | ||||
|   { 0x0db1, 0x0e11 }, | ||||
|   { 0x0db2, 0x0e12 }, | ||||
|   { 0x0db3, 0x0e13 }, | ||||
|   { 0x0db4, 0x0e14 }, | ||||
|   { 0x0db5, 0x0e15 }, | ||||
|   { 0x0db6, 0x0e16 }, | ||||
|   { 0x0db7, 0x0e17 }, | ||||
|   { 0x0db8, 0x0e18 }, | ||||
|   { 0x0db9, 0x0e19 }, | ||||
|   { 0x0dba, 0x0e1a }, | ||||
|   { 0x0dbb, 0x0e1b }, | ||||
|   { 0x0dbc, 0x0e1c }, | ||||
|   { 0x0dbd, 0x0e1d }, | ||||
|   { 0x0dbe, 0x0e1e }, | ||||
|   { 0x0dbf, 0x0e1f }, | ||||
|   { 0x0dc0, 0x0e20 }, | ||||
|   { 0x0dc1, 0x0e21 }, | ||||
|   { 0x0dc2, 0x0e22 }, | ||||
|   { 0x0dc3, 0x0e23 }, | ||||
|   { 0x0dc4, 0x0e24 }, | ||||
|   { 0x0dc5, 0x0e25 }, | ||||
|   { 0x0dc6, 0x0e26 }, | ||||
|   { 0x0dc7, 0x0e27 }, | ||||
|   { 0x0dc8, 0x0e28 }, | ||||
|   { 0x0dc9, 0x0e29 }, | ||||
|   { 0x0dca, 0x0e2a }, | ||||
|   { 0x0dcb, 0x0e2b }, | ||||
|   { 0x0dcc, 0x0e2c }, | ||||
|   { 0x0dcd, 0x0e2d }, | ||||
|   { 0x0dce, 0x0e2e }, | ||||
|   { 0x0dcf, 0x0e2f }, | ||||
|   { 0x0dd0, 0x0e30 }, | ||||
|   { 0x0dd1, 0x0e31 }, | ||||
|   { 0x0dd2, 0x0e32 }, | ||||
|   { 0x0dd3, 0x0e33 }, | ||||
|   { 0x0dd4, 0x0e34 }, | ||||
|   { 0x0dd5, 0x0e35 }, | ||||
|   { 0x0dd6, 0x0e36 }, | ||||
|   { 0x0dd7, 0x0e37 }, | ||||
|   { 0x0dd8, 0x0e38 }, | ||||
|   { 0x0dd9, 0x0e39 }, | ||||
|   { 0x0dda, 0x0e3a }, | ||||
|   { 0x0ddf, 0x0e3f }, | ||||
|   { 0x0de0, 0x0e40 }, | ||||
|   { 0x0de1, 0x0e41 }, | ||||
|   { 0x0de2, 0x0e42 }, | ||||
|   { 0x0de3, 0x0e43 }, | ||||
|   { 0x0de4, 0x0e44 }, | ||||
|   { 0x0de5, 0x0e45 }, | ||||
|   { 0x0de6, 0x0e46 }, | ||||
|   { 0x0de7, 0x0e47 }, | ||||
|   { 0x0de8, 0x0e48 }, | ||||
|   { 0x0de9, 0x0e49 }, | ||||
|   { 0x0dea, 0x0e4a }, | ||||
|   { 0x0deb, 0x0e4b }, | ||||
|   { 0x0dec, 0x0e4c }, | ||||
|   { 0x0ded, 0x0e4d }, | ||||
|   { 0x0df0, 0x0e50 }, | ||||
|   { 0x0df1, 0x0e51 }, | ||||
|   { 0x0df2, 0x0e52 }, | ||||
|   { 0x0df3, 0x0e53 }, | ||||
|   { 0x0df4, 0x0e54 }, | ||||
|   { 0x0df5, 0x0e55 }, | ||||
|   { 0x0df6, 0x0e56 }, | ||||
|   { 0x0df7, 0x0e57 }, | ||||
|   { 0x0df8, 0x0e58 }, | ||||
|   { 0x0df9, 0x0e59 }, | ||||
|   { 0x0ea1, 0x3131 }, | ||||
|   { 0x0ea2, 0x3132 }, | ||||
|   { 0x0ea3, 0x3133 }, | ||||
|   { 0x0ea4, 0x3134 }, | ||||
|   { 0x0ea5, 0x3135 }, | ||||
|   { 0x0ea6, 0x3136 }, | ||||
|   { 0x0ea7, 0x3137 }, | ||||
|   { 0x0ea8, 0x3138 }, | ||||
|   { 0x0ea9, 0x3139 }, | ||||
|   { 0x0eaa, 0x313a }, | ||||
|   { 0x0eab, 0x313b }, | ||||
|   { 0x0eac, 0x313c }, | ||||
|   { 0x0ead, 0x313d }, | ||||
|   { 0x0eae, 0x313e }, | ||||
|   { 0x0eaf, 0x313f }, | ||||
|   { 0x0eb0, 0x3140 }, | ||||
|   { 0x0eb1, 0x3141 }, | ||||
|   { 0x0eb2, 0x3142 }, | ||||
|   { 0x0eb3, 0x3143 }, | ||||
|   { 0x0eb4, 0x3144 }, | ||||
|   { 0x0eb5, 0x3145 }, | ||||
|   { 0x0eb6, 0x3146 }, | ||||
|   { 0x0eb7, 0x3147 }, | ||||
|   { 0x0eb8, 0x3148 }, | ||||
|   { 0x0eb9, 0x3149 }, | ||||
|   { 0x0eba, 0x314a }, | ||||
|   { 0x0ebb, 0x314b }, | ||||
|   { 0x0ebc, 0x314c }, | ||||
|   { 0x0ebd, 0x314d }, | ||||
|   { 0x0ebe, 0x314e }, | ||||
|   { 0x0ebf, 0x314f }, | ||||
|   { 0x0ec0, 0x3150 }, | ||||
|   { 0x0ec1, 0x3151 }, | ||||
|   { 0x0ec2, 0x3152 }, | ||||
|   { 0x0ec3, 0x3153 }, | ||||
|   { 0x0ec4, 0x3154 }, | ||||
|   { 0x0ec5, 0x3155 }, | ||||
|   { 0x0ec6, 0x3156 }, | ||||
|   { 0x0ec7, 0x3157 }, | ||||
|   { 0x0ec8, 0x3158 }, | ||||
|   { 0x0ec9, 0x3159 }, | ||||
|   { 0x0eca, 0x315a }, | ||||
|   { 0x0ecb, 0x315b }, | ||||
|   { 0x0ecc, 0x315c }, | ||||
|   { 0x0ecd, 0x315d }, | ||||
|   { 0x0ece, 0x315e }, | ||||
|   { 0x0ecf, 0x315f }, | ||||
|   { 0x0ed0, 0x3160 }, | ||||
|   { 0x0ed1, 0x3161 }, | ||||
|   { 0x0ed2, 0x3162 }, | ||||
|   { 0x0ed3, 0x3163 }, | ||||
|   { 0x0ed4, 0x11a8 }, | ||||
|   { 0x0ed5, 0x11a9 }, | ||||
|   { 0x0ed6, 0x11aa }, | ||||
|   { 0x0ed7, 0x11ab }, | ||||
|   { 0x0ed8, 0x11ac }, | ||||
|   { 0x0ed9, 0x11ad }, | ||||
|   { 0x0eda, 0x11ae }, | ||||
|   { 0x0edb, 0x11af }, | ||||
|   { 0x0edc, 0x11b0 }, | ||||
|   { 0x0edd, 0x11b1 }, | ||||
|   { 0x0ede, 0x11b2 }, | ||||
|   { 0x0edf, 0x11b3 }, | ||||
|   { 0x0ee0, 0x11b4 }, | ||||
|   { 0x0ee1, 0x11b5 }, | ||||
|   { 0x0ee2, 0x11b6 }, | ||||
|   { 0x0ee3, 0x11b7 }, | ||||
|   { 0x0ee4, 0x11b8 }, | ||||
|   { 0x0ee5, 0x11b9 }, | ||||
|   { 0x0ee6, 0x11ba }, | ||||
|   { 0x0ee7, 0x11bb }, | ||||
|   { 0x0ee8, 0x11bc }, | ||||
|   { 0x0ee9, 0x11bd }, | ||||
|   { 0x0eea, 0x11be }, | ||||
|   { 0x0eeb, 0x11bf }, | ||||
|   { 0x0eec, 0x11c0 }, | ||||
|   { 0x0eed, 0x11c1 }, | ||||
|   { 0x0eee, 0x11c2 }, | ||||
|   { 0x0eef, 0x316d }, | ||||
|   { 0x0ef0, 0x3171 }, | ||||
|   { 0x0ef1, 0x3178 }, | ||||
|   { 0x0ef2, 0x317f }, | ||||
|   { 0x0ef3, 0x3181 }, | ||||
|   { 0x0ef4, 0x3184 }, | ||||
|   { 0x0ef5, 0x3186 }, | ||||
|   { 0x0ef6, 0x318d }, | ||||
|   { 0x0ef7, 0x318e }, | ||||
|   { 0x0ef8, 0x11eb }, | ||||
|   { 0x0ef9, 0x11f0 }, | ||||
|   { 0x0efa, 0x11f9 }, | ||||
|   { 0x0eff, 0x20a9 }, | ||||
|   { 0x13a4, 0x20ac }, | ||||
|   { 0x13bc, 0x0152 }, | ||||
|   { 0x13bd, 0x0153 }, | ||||
|   { 0x13be, 0x0178 }, | ||||
|   { 0x20ac, 0x20ac }, | ||||
|   { 0xfe50,    '`' }, | ||||
|   { 0xfe51, 0x00b4 }, | ||||
|   { 0xfe52,    '^' }, | ||||
|   { 0xfe53,    '~' }, | ||||
|   { 0xfe54, 0x00af }, | ||||
|   { 0xfe55, 0x02d8 }, | ||||
|   { 0xfe56, 0x02d9 }, | ||||
|   { 0xfe57, 0x00a8 }, | ||||
|   { 0xfe58, 0x02da }, | ||||
|   { 0xfe59, 0x02dd }, | ||||
|   { 0xfe5a, 0x02c7 }, | ||||
|   { 0xfe5b, 0x00b8 }, | ||||
|   { 0xfe5c, 0x02db }, | ||||
|   { 0xfe5d, 0x037a }, | ||||
|   { 0xfe5e, 0x309b }, | ||||
|   { 0xfe5f, 0x309c }, | ||||
|   { 0xfe63,    '/' }, | ||||
|   { 0xfe64, 0x02bc }, | ||||
|   { 0xfe65, 0x02bd }, | ||||
|   { 0xfe66, 0x02f5 }, | ||||
|   { 0xfe67, 0x02f3 }, | ||||
|   { 0xfe68, 0x02cd }, | ||||
|   { 0xfe69, 0xa788 }, | ||||
|   { 0xfe6a, 0x02f7 }, | ||||
|   { 0xfe6e,    ',' }, | ||||
|   { 0xfe6f, 0x00a4 }, | ||||
|   { 0xfe80,    'a' }, // XK_dead_a | ||||
|   { 0xfe81,    'A' }, // XK_dead_A | ||||
|   { 0xfe82,    'e' }, // XK_dead_e | ||||
|   { 0xfe83,    'E' }, // XK_dead_E | ||||
|   { 0xfe84,    'i' }, // XK_dead_i | ||||
|   { 0xfe85,    'I' }, // XK_dead_I | ||||
|   { 0xfe86,    'o' }, // XK_dead_o | ||||
|   { 0xfe87,    'O' }, // XK_dead_O | ||||
|   { 0xfe88,    'u' }, // XK_dead_u | ||||
|   { 0xfe89,    'U' }, // XK_dead_U | ||||
|   { 0xfe8a, 0x0259 }, | ||||
|   { 0xfe8b, 0x018f }, | ||||
|   { 0xfe8c, 0x00b5 }, | ||||
|   { 0xfe90,    '_' }, | ||||
|   { 0xfe91, 0x02c8 }, | ||||
|   { 0xfe92, 0x02cc }, | ||||
|   { 0xff80 /*XKB_KEY_KP_Space*/,     ' ' }, | ||||
|   { 0xff95 /*XKB_KEY_KP_7*/, 0x0037 }, | ||||
|   { 0xff96 /*XKB_KEY_KP_4*/, 0x0034 }, | ||||
|   { 0xff97 /*XKB_KEY_KP_8*/, 0x0038 }, | ||||
|   { 0xff98 /*XKB_KEY_KP_6*/, 0x0036 }, | ||||
|   { 0xff99 /*XKB_KEY_KP_2*/, 0x0032 }, | ||||
|   { 0xff9a /*XKB_KEY_KP_9*/, 0x0039 }, | ||||
|   { 0xff9b /*XKB_KEY_KP_3*/, 0x0033 }, | ||||
|   { 0xff9c /*XKB_KEY_KP_1*/, 0x0031 }, | ||||
|   { 0xff9d /*XKB_KEY_KP_5*/, 0x0035 }, | ||||
|   { 0xff9e /*XKB_KEY_KP_0*/, 0x0030 }, | ||||
|   { 0xffaa /*XKB_KEY_KP_Multiply*/,  '*' }, | ||||
|   { 0xffab /*XKB_KEY_KP_Add*/,       '+' }, | ||||
|   { 0xffac /*XKB_KEY_KP_Separator*/, ',' }, | ||||
|   { 0xffad /*XKB_KEY_KP_Subtract*/,  '-' }, | ||||
|   { 0xffae /*XKB_KEY_KP_Decimal*/,   '.' }, | ||||
|   { 0xffaf /*XKB_KEY_KP_Divide*/,    '/' }, | ||||
|   { 0xffb0 /*XKB_KEY_KP_0*/, 0x0030 }, | ||||
|   { 0xffb1 /*XKB_KEY_KP_1*/, 0x0031 }, | ||||
|   { 0xffb2 /*XKB_KEY_KP_2*/, 0x0032 }, | ||||
|   { 0xffb3 /*XKB_KEY_KP_3*/, 0x0033 }, | ||||
|   { 0xffb4 /*XKB_KEY_KP_4*/, 0x0034 }, | ||||
|   { 0xffb5 /*XKB_KEY_KP_5*/, 0x0035 }, | ||||
|   { 0xffb6 /*XKB_KEY_KP_6*/, 0x0036 }, | ||||
|   { 0xffb7 /*XKB_KEY_KP_7*/, 0x0037 }, | ||||
|   { 0xffb8 /*XKB_KEY_KP_8*/, 0x0038 }, | ||||
|   { 0xffb9 /*XKB_KEY_KP_9*/, 0x0039 }, | ||||
|   { 0xffbd /*XKB_KEY_KP_Equal*/,     '=' } | ||||
| }; | ||||
|  | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
| //////                       GLFW internal API                      ////// | ||||
| ////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Convert XKB KeySym to Unicode | ||||
| // | ||||
| long _glfwKeySym2Unicode(unsigned int keysym) | ||||
| { | ||||
|     int min = 0; | ||||
|     int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; | ||||
|     int mid; | ||||
|  | ||||
|     // First check for Latin-1 characters (1:1 mapping) | ||||
|     if ((keysym >= 0x0020 && keysym <= 0x007e) || | ||||
|         (keysym >= 0x00a0 && keysym <= 0x00ff)) | ||||
|     { | ||||
|         return keysym; | ||||
|     } | ||||
|  | ||||
|     // Also check for directly encoded 24-bit UCS characters | ||||
|     if ((keysym & 0xff000000) == 0x01000000) | ||||
|         return keysym & 0x00ffffff; | ||||
|  | ||||
|     // Binary search in table | ||||
|     while (max >= min) | ||||
|     { | ||||
|         mid = (min + max) / 2; | ||||
|         if (keysymtab[mid].keysym < keysym) | ||||
|             min = mid + 1; | ||||
|         else if (keysymtab[mid].keysym > keysym) | ||||
|             max = mid - 1; | ||||
|         else | ||||
|             return keysymtab[mid].ucs; | ||||
|     } | ||||
|  | ||||
|     // No matching Unicode value found | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
							
								
								
									
										28
									
								
								deps/glfw/src/xkb_unicode.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								deps/glfw/src/xkb_unicode.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| //======================================================================== | ||||
| // GLFW 3.3 Linux - www.glfw.org | ||||
| //------------------------------------------------------------------------ | ||||
| // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> | ||||
| // | ||||
| // This software is provided 'as-is', without any express or implied | ||||
| // warranty. In no event will the authors be held liable for any damages | ||||
| // arising from the use of this software. | ||||
| // | ||||
| // Permission is granted to anyone to use this software for any purpose, | ||||
| // including commercial applications, and to alter it and redistribute it | ||||
| // freely, subject to the following restrictions: | ||||
| // | ||||
| // 1. The origin of this software must not be misrepresented; you must not | ||||
| //    claim that you wrote the original software. If you use this software | ||||
| //    in a product, an acknowledgment in the product documentation would | ||||
| //    be appreciated but is not required. | ||||
| // | ||||
| // 2. Altered source versions must be plainly marked as such, and must not | ||||
| //    be misrepresented as being the original software. | ||||
| // | ||||
| // 3. This notice may not be removed or altered from any source | ||||
| //    distribution. | ||||
| // | ||||
| //======================================================================== | ||||
|  | ||||
| long _glfwKeySym2Unicode(unsigned int keysym); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user