From b43c122dd194d74996d76c574a46d4bc23d6c7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 5 Apr 2022 19:54:09 +0200 Subject: [PATCH 001/207] Start 3.3.8 --- CMakeLists.txt | 2 +- README.md | 28 +--------------------------- include/GLFW/glfw3.h | 2 +- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78b38e4f..75069161 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR) -project(GLFW VERSION 3.3.7 LANGUAGES C) +project(GLFW VERSION 3.3.8 LANGUAGES C) set(CMAKE_LEGACY_CYGWIN_WIN32 OFF) diff --git a/README.md b/README.md index cc2667e2..7c59dea9 100644 --- a/README.md +++ b/README.md @@ -123,33 +123,7 @@ information on what to include when reporting a bug. ## Changelog - - [Win32] Bugfix: A window created maximized and undecorated would cover the whole - monitor (#1806) - - [Win32] Bugfix: The default restored window position was lost when creating a maximized - window - - [Win32] Bugfix: `glfwMaximizeWindow` would make a hidden window visible - - [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003) - - [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences - - [X11] Bugfix: Waiting for events would fail if file descriptor was too large - (#2024) - - [X11] Bugfix: Joystick events could lead to busy-waiting (#1872) - - [X11] Bugfix: `glfwWaitEvents*` did not continue for joystick events - - [X11] Bugfix: `glfwPostEmptyEvent` could be ignored due to race condition - (#379,#1281,#1285,#2033) - - [X11] Bugfix: Dynamic loading on NetBSD failed due to soname differences - - [X11] Bugfix: Left shift of int constant relied on undefined behavior (#1951) - - [Wayland] Added support for key names via xkbcommon - - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) - - [Wayland] Bugfix: Activating a window would emit two input focus events - - [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus - - [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731) - - [Wayland] Bugfix: A key being repeated was not released when window lost focus - - [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event - - [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE` - - [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN` - - [Wayland] Bugfix: Text input did not repeat along with key repeat - - [Wayland] Bugfix: `glfwPostEmptyEvent` sometimes had no effect (#1520,#1521) - - [GLX] Bugfix: Context creation failed if GLX 1.4 was not exported by GLX library +There is nothing here yet. ## Contact diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index d074de12..cd019a79 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -299,7 +299,7 @@ extern "C" { * release is made that does not contain any API changes. * @ingroup init */ -#define GLFW_VERSION_REVISION 7 +#define GLFW_VERSION_REVISION 8 /*! @} */ /*! @brief One. From 3006c02bc20ce746b6e2a1387305acfada37a1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 14 Mar 2022 16:01:34 +0100 Subject: [PATCH 002/207] Add shared min and max functions for int (cherry picked from commit 3ee5031fd7dcac5ecb7387d3dd73195f03e87398) --- src/init.c | 10 ++++++++++ src/internal.h | 2 ++ src/win32_window.c | 9 +++------ src/wl_init.c | 9 ++------- src/wl_window.c | 6 +----- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/init.c b/src/init.c index 758c1094..76397c41 100644 --- a/src/init.c +++ b/src/init.c @@ -150,6 +150,16 @@ char* _glfw_strdup(const char* source) return result; } +int _glfw_min(int a, int b) +{ + return a < b ? a : b; +} + +int _glfw_max(int a, int b) +{ + return a > b ? a : b; +} + float _glfw_fminf(float a, float b) { if (a != a) diff --git a/src/internal.h b/src/internal.h index 561f4c18..69d6a19a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -777,6 +777,8 @@ const char* _glfwGetVulkanResultString(VkResult result); size_t _glfwEncodeUTF8(char* s, uint32_t codepoint); char* _glfw_strdup(const char* source); +int _glfw_min(int a, int b); +int _glfw_max(int a, int b); float _glfw_fminf(float a, float b); float _glfw_fmaxf(float a, float b); diff --git a/src/win32_window.c b/src/win32_window.c index 12f5900b..507f3663 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -504,10 +504,8 @@ static void maximizeWindowManually(_GLFWwindow* window) if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) { - if (rect.right - rect.left > window->maxwidth) - rect.right = rect.left + window->maxwidth; - if (rect.bottom - rect.top > window->maxheight) - rect.bottom = rect.top + window->maxheight; + rect.right = _glfw_min(rect.right, rect.left + window->maxwidth); + rect.bottom = _glfw_min(rect.bottom, rect.top + window->maxheight); } style = GetWindowLongW(window->win32.handle, GWL_STYLE); @@ -530,8 +528,7 @@ static void maximizeWindowManually(_GLFWwindow* window) OffsetRect(&rect, 0, GetSystemMetrics(SM_CYCAPTION)); } - if (rect.bottom > mi.rcWork.bottom) - rect.bottom = mi.rcWork.bottom; + rect.bottom = _glfw_min(rect.bottom, mi.rcWork.bottom); } SetWindowPos(window->win32.handle, HWND_TOP, diff --git a/src/wl_init.c b/src/wl_init.c index 0ec99106..679baeb8 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -43,11 +43,6 @@ #include -static inline int min(int n1, int n2) -{ - return n1 < n2 ? n1 : n2; -} - static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, int* which) { @@ -784,7 +779,7 @@ static void registryHandleGlobal(void* data, { if (strcmp(interface, "wl_compositor") == 0) { - _glfw.wl.compositorVersion = min(3, version); + _glfw.wl.compositorVersion = _glfw_min(3, version); _glfw.wl.compositor = wl_registry_bind(registry, name, &wl_compositor_interface, _glfw.wl.compositorVersion); @@ -812,7 +807,7 @@ static void registryHandleGlobal(void* data, { if (!_glfw.wl.seat) { - _glfw.wl.seatVersion = min(4, version); + _glfw.wl.seatVersion = _glfw_min(4, version); _glfw.wl.seat = wl_registry_bind(registry, name, &wl_seat_interface, _glfw.wl.seatVersion); diff --git a/src/wl_window.c b/src/wl_window.c index 0b78e34f..a8c35208 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -460,11 +460,7 @@ static void checkScaleChange(_GLFWwindow* window) int maxScale = 1; for (int i = 0; i < window->wl.monitorsCount; i++) - { - const int scale = window->wl.monitors[i]->wl.scale; - if (maxScale < scale) - maxScale = scale; - } + maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale); // Only change the framebuffer size if the scale changed. if (window->wl.scale != maxScale) From e7a81f8aaab94424ac2650c779cb13aec648e7e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 15 Mar 2022 17:51:57 +0100 Subject: [PATCH 003/207] Fix GLAPIENTRY redefinition warning On a Unix system, if you define GLFW_INCLUDE_NONE and GLFW_EXPOSE_NATIVE_GLX, then include glfw3.h and glfw3native.h, you will get a redefinition warning for GLAPIENTRY. The glfw3.h header defines GLAPIENTRY as a service for OpenGL related headers that assume it's already defined. However, glx.h includes gl.h, which defines GLAPIENTRY unconditionally. If not for Hyrum's law, the better solution would have been not to define GLAPIENTRY if GLFW_INCLUDE_NONE is defined. Fixes #2010 This is adapted to 3.3-stable from 535c3ce63240ee91f998219b35dc82abef545c3d and ce85c7dcaf48be96870f2d8fec1d78b0b7d744c7. --- include/GLFW/glfw3.h | 1 + include/GLFW/glfw3native.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index cd019a79..f7ab3828 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -5900,6 +5900,7 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window */ #ifndef GLAPIENTRY #define GLAPIENTRY APIENTRY + #define GLFW_GLAPIENTRY_DEFINED #endif /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index fe74c733..212a458b 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -111,12 +111,28 @@ extern "C" { /* NSGL is declared by Cocoa.h */ #endif #if defined(GLFW_EXPOSE_NATIVE_GLX) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, glx.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif #include #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) #include #endif #if defined(GLFW_EXPOSE_NATIVE_OSMESA) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, osmesa.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif #include #endif From c2188e2d0aab7c97de7b749e131521df5b4f5ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 15 Mar 2022 17:59:57 +0100 Subject: [PATCH 004/207] Fix accidental C99 in C89 header (cherry picked from commit add0521efb1fc0e95082716748b7aad837753fba) --- include/GLFW/glfw3native.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 212a458b..f666df2b 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -82,9 +82,10 @@ extern "C" { *************************************************************************/ #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) - // 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 + /* 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 + */ #if defined(GLFW_APIENTRY_DEFINED) #undef APIENTRY #undef GLFW_APIENTRY_DEFINED From 32df2ed7161d21242b9ebd10c3542f98f71210e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 15 Mar 2022 19:12:29 +0100 Subject: [PATCH 005/207] Win32: Fix scancode and key for Alt+PrtSc events Alt+PrtSc emits a different scancode than just PrtSc. Since the GLFW API assumes each key corresponds to only one scancode, this cannot be added to the keycodes array. Instead we replace the scancode at the point of entry. Fixes #1993 (cherry picked from commit 03cfe957e739e41cdfd66b554c076b5b31f48c1e) --- CONTRIBUTORS.md | 1 + README.md | 3 ++- src/win32_window.c | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0bc0cd29..44f57a38 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -69,6 +69,7 @@ video tutorials. - Ryan C. Gordon - Stephen Gowen - Kovid Goyal + - Kevin Grandemange - Eloi Marín Gratacós - Stefan Gustavson - Andrew Gutekanst diff --git a/README.md b/README.md index 7c59dea9..0f200688 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,8 @@ information on what to include when reporting a bug. ## Changelog -There is nothing here yet. + - [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different + scancode than `PrtSc` (#1993) ## Contact diff --git a/src/win32_window.c b/src/win32_window.c index 507f3663..194d3ac9 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -748,6 +748,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC); } + // HACK: Alt+PrtSc has a different scancode than just PrtSc + if (scancode == 0x54) + scancode = 0x137; + key = _glfw.win32.keycodes[scancode]; // The Ctrl keys require special handling From c2ccf6f919760ba414c025d1d09fd02a9e11f949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 15 Mar 2022 19:22:21 +0100 Subject: [PATCH 006/207] Win32: Fix glfwGetKeyScancode for GLFW_KEY_PAUSE The bug described in 03cfe957e739e41cdfd66b554c076b5b31f48c1e was already present for another key where modifiers changes its scancode. Related to #1993 (cherry picked from commit 8d9231fe5ec82c3a0a7bddfcd3a409759a7a45d8) --- README.md | 2 ++ src/win32_init.c | 1 - src/win32_window.c | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f200688..67771e76 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ information on what to include when reporting a bug. - [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different scancode than `PrtSc` (#1993) + - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not + match event scancode (#1993) ## Contact diff --git a/src/win32_init.c b/src/win32_init.c index 4923b266..9adf1ae9 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -254,7 +254,6 @@ static void createKeyTables(void) _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; diff --git a/src/win32_window.c b/src/win32_window.c index 194d3ac9..446d07f4 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -752,6 +752,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (scancode == 0x54) scancode = 0x137; + // HACK: Ctrl+Pause has a different scancode than just Pause + if (scancode == 0x146) + scancode = 0x45; + key = _glfw.win32.keycodes[scancode]; // The Ctrl keys require special handling From 802882f7cbf4c4902932a7582bd3dc6743d006d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 15 Mar 2022 21:22:49 +0100 Subject: [PATCH 007/207] Add checks for some invalid values to public API There were no checks for invalid values or asserts for all invalid NULL pointers to glfwSetWindowIcon or glfwCreateCursor. Fixes #1862 (cherry picked from commit 66a4882eb14344115e9cda9f8c0f0c5d0362ca6e) --- CONTRIBUTORS.md | 1 + include/GLFW/glfw3.h | 8 ++++---- src/input.c | 7 +++++++ src/window.c | 21 +++++++++++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 44f57a38..95674b37 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -83,6 +83,7 @@ video tutorials. - Paul Holden - Warren Hu - Charles Huber + - Brent Huisman - illustris - InKryption - IntellectualKitty diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index f7ab3828..8e27e2ea 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -2808,8 +2808,8 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * @param[in] images The images to create the icon from. This is ignored if * count is zero. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. @@ -4441,8 +4441,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); * @return The handle of the created cursor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. diff --git a/src/input.c b/src/input.c index 0673d86b..186322e5 100644 --- a/src/input.c +++ b/src/input.c @@ -743,9 +743,16 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) _GLFWcursor* cursor; assert(image != NULL); + assert(image->pixels != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + if (image->width <= 0 || image->height <= 0) + { + _glfwInputError(GLFW_INVALID_VALUE, "Invalid image dimensions for cursor"); + return NULL; + } + cursor = calloc(1, sizeof(_GLFWcursor)); cursor->next = _glfw.cursorListHead; _glfw.cursorListHead = cursor; diff --git a/src/window.c b/src/window.c index b87a2609..1fd9c6a0 100644 --- a/src/window.c +++ b/src/window.c @@ -504,12 +504,33 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, int count, const GLFWimage* images) { + int i; _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); assert(count >= 0); assert(count == 0 || images != NULL); _GLFW_REQUIRE_INIT(); + + if (count < 0) + { + _glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon"); + return; + } + + for (i = 0; i < count; i++) + { + assert(images[i].pixels != NULL); + + if (images[i].width <= 0 || images[i].height <= 0) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Invalid image dimensions for window icon"); + return; + } + } + _glfwPlatformSetWindowIcon(window, count, images); } From de550b60e51e5efee72fea95047f6659b3c9def3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 17 Mar 2022 23:54:39 +0100 Subject: [PATCH 008/207] Win32: Fix using executable instance and not ours Operations that take an instance handle should be passed the handle of whatever module we are inside instead of blindly passing the handle of the executable. This commit makes GLFW retrieve its own instance on initialization. This makes the most difference for window classes, which are per-instance. Using the executable instance led to name conflicts if there were several copies of GLFW in a single process. Note that having this is still a bad idea unless you know what things to avoid, and those things are mostly platform-specific. This is partly because the library wasn't designed for it and partly because it needs to save, update and restore various per-process and per-session settings like current context and video mode. However, multiple simultaneous copies of GLFW in a single Win32 process should now at least initialize, like is already the case on other platforms. Fixes #469 Fixes #1296 Fixes #1395 Related to #927 Related to #1885 (cherry picked from commit 07a5518c3e42f4412a5d9fa8620950d8f5041e28) --- CONTRIBUTORS.md | 2 ++ README.md | 1 + src/win32_init.c | 12 +++++++++++- src/win32_joystick.c | 2 +- src/win32_platform.h | 1 + src/win32_window.c | 8 ++++---- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 95674b37..db771860 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -89,6 +89,7 @@ video tutorials. - IntellectualKitty - Aaron Jacobs - Erik S. V. Jansson + - jjYBdx4IL - Toni Jovanoski - Arseny Kapoulkine - Cem Karan @@ -203,6 +204,7 @@ video tutorials. - TTK-Bandit - Sergey Tikhomirov - Arthur Tombs + - TronicLabs - Ioannis Tsakpinis - Samuli Tuomola - Matthew Turner diff --git a/README.md b/README.md index 67771e76..74f5a081 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ information on what to include when reporting a bug. scancode than `PrtSc` (#1993) - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not match event scancode (#1993) + - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) ## Contact diff --git a/src/win32_init.c b/src/win32_init.c index 9adf1ae9..880837f6 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -72,6 +72,16 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) // static GLFWbool loadLibraries(void) { + if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (const WCHAR*) &_glfw, + (HMODULE*) &_glfw.win32.instance)) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to retrieve own module handle"); + return GLFW_FALSE; + } + _glfw.win32.user32.instance = LoadLibraryA("user32.dll"); if (!_glfw.win32.user32.instance) { @@ -335,7 +345,7 @@ static GLFWbool createHelperWindow(void) WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 1, 1, NULL, NULL, - GetModuleHandleW(NULL), + _glfw.win32.instance, NULL); if (!_glfw.win32.helperWindowHandle) diff --git a/src/win32_joystick.c b/src/win32_joystick.c index f54d5704..613587bf 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -497,7 +497,7 @@ void _glfwInitJoysticksWin32(void) { if (_glfw.win32.dinput8.instance) { - if (FAILED(DirectInput8Create(GetModuleHandleW(NULL), + if (FAILED(DirectInput8Create(_glfw.win32.instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, (void**) &_glfw.win32.dinput8.api, diff --git a/src/win32_platform.h b/src/win32_platform.h index 92d43d07..bf703d7e 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -334,6 +334,7 @@ typedef struct _GLFWwindowWin32 // typedef struct _GLFWlibraryWin32 { + HINSTANCE instance; HWND helperWindowHandle; HDEVNOTIFY deviceNotificationHandle; DWORD foregroundLockTimeout; diff --git a/src/win32_window.c b/src/win32_window.c index 446d07f4..46d671fa 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1317,7 +1317,7 @@ static int createNativeWindow(_GLFWwindow* window, fullWidth, fullHeight, NULL, // No parent window NULL, // No window menu - GetModuleHandleW(NULL), + _glfw.win32.instance, (LPVOID) wndconfig); free(wideTitle); @@ -1429,7 +1429,7 @@ GLFWbool _glfwRegisterWindowClassWin32(void) wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) windowProc; - wc.hInstance = GetModuleHandleW(NULL); + wc.hInstance = _glfw.win32.instance; wc.hCursor = LoadCursorW(NULL, IDC_ARROW); wc.lpszClassName = _GLFW_WNDCLASSNAME; @@ -1459,7 +1459,7 @@ GLFWbool _glfwRegisterWindowClassWin32(void) // void _glfwUnregisterWindowClassWin32(void) { - UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL)); + UnregisterClassW(_GLFW_WNDCLASSNAME, _glfw.win32.instance); } @@ -2348,7 +2348,7 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, memset(&sci, 0, sizeof(sci)); sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - sci.hinstance = GetModuleHandleW(NULL); + sci.hinstance = _glfw.win32.instance; sci.hwnd = window->win32.handle; err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface); From 307ccd68a5a934beecd700c148473ac3c218a746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 18 Mar 2022 00:31:34 +0100 Subject: [PATCH 009/207] Cocoa: Fix AirPlay causing harmless init error Emitting an error for one specific type of failure in retrieving the correct name for a display is not very useful, especially when initialization is otherwise unaffected. There should be a path for information like that but this isn't it. Fixes #1791 (cherry picked from commit 955fbd9d265fa95adf9cb94896eb9a516aa50420) --- CONTRIBUTORS.md | 1 + README.md | 1 + src/cocoa_monitor.m | 4 ---- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index db771860..f346bffe 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -88,6 +88,7 @@ video tutorials. - InKryption - IntellectualKitty - Aaron Jacobs + - JannikGM - Erik S. V. Jansson - jjYBdx4IL - Toni Jovanoski diff --git a/README.md b/README.md index 74f5a081..e8c1d56d 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ information on what to include when reporting a bug. - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not match event scancode (#1993) - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) + - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) ## Contact diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index dadae30b..7769bb7e 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -98,11 +98,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen) 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)); From 8897c8a1cb7fed20789e4d054295220b9c1b3348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 22 Mar 2022 20:11:42 +0100 Subject: [PATCH 010/207] POSIX: Fix data type of return values (cherry picked from commit 554cbdb205d71ab09873f887bb75a8a7d3731a0c) --- src/x11_window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index ce089d0d..646fbdab 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -164,7 +164,7 @@ static void writeEmptyEvent(void) for (;;) { const char byte = 0; - const int result = write(_glfw.x11.emptyEventPipe[1], &byte, 1); + const ssize_t result = write(_glfw.x11.emptyEventPipe[1], &byte, 1); if (result == 1 || (result == -1 && errno != EINTR)) break; } @@ -177,7 +177,7 @@ static void drainEmptyEvents(void) for (;;) { char dummy[64]; - const int result = read(_glfw.x11.emptyEventPipe[0], dummy, sizeof(dummy)); + const ssize_t result = read(_glfw.x11.emptyEventPipe[0], dummy, sizeof(dummy)); if (result == -1 && errno != EINTR) break; } From f93751ce68c732a4d2cf08958b0b67faaa8d106d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 21 Mar 2022 23:19:06 +0100 Subject: [PATCH 011/207] Fix missing newline (cherry picked from commit 920d110b6c7de21bc1ff60fab62350cbc80bd76f) --- src/input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input.c b/src/input.c index 186322e5..f6c1ed79 100644 --- a/src/input.c +++ b/src/input.c @@ -1372,3 +1372,4 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void) _GLFW_REQUIRE_INIT_OR_RETURN(0); return _glfwPlatformGetTimerFrequency(); } + From 22f718dcf4f2561f5cd41eaaf33762ec7a5880a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 22 Mar 2022 18:46:57 +0100 Subject: [PATCH 012/207] Wayland: Fix handling of clipboard set to self Passing any part of the result of glfwGetClipboardString to glfwSetClipboardString would result in, at best, a use-after-free error. (cherry picked from commit 9c95cfb9f1cdf073856e5b479447f5fca6492cd9) --- README.md | 2 ++ src/wl_window.c | 20 +++++++++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e8c1d56d..75d09bb9 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,8 @@ information on what to include when reporting a bug. match event scancode (#1993) - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) + - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of + `glfwGetClipboardString` ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index a8c35208..0bea8974 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1798,20 +1798,18 @@ void _glfwPlatformSetClipboardString(const char* string) _glfw.wl.dataSource = NULL; } - if (_glfw.wl.clipboardSendString) + char* copy = _glfw_strdup(string); + if (!copy) { - free(_glfw.wl.clipboardSendString); - _glfw.wl.clipboardSendString = NULL; - } - - _glfw.wl.clipboardSendString = strdup(string); - if (!_glfw.wl.clipboardSendString) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Impossible to allocate clipboard string"); + _glfwInputError(GLFW_OUT_OF_MEMORY, + "Wayland: Failed to allocate clipboard string"); return; } - _glfw.wl.clipboardSendSize = strlen(string); + + free(_glfw.wl.clipboardSendString); + _glfw.wl.clipboardSendString = copy; + + _glfw.wl.clipboardSendSize = strlen(_glfw.wl.clipboardSendString); _glfw.wl.dataSource = wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager); if (!_glfw.wl.dataSource) From 53bd67ccfe11265a5d7c5eb1c145c5a764395d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 22 Mar 2022 18:55:31 +0100 Subject: [PATCH 013/207] Wayland: Fix double free on data source error If data source creation fails, the string containing the data for it would be freed a second time during termination. (cherry picked from commit b386371f57ba45e6ef15d16e994c6fbe71437427) --- README.md | 1 + src/wl_window.c | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 75d09bb9..d406c878 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` + - [Wayland] Bugfix: Data source creation error would cause double free at termination ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index 0bea8974..e425da78 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1817,6 +1817,7 @@ void _glfwPlatformSetClipboardString(const char* string) _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Impossible to create clipboard source"); free(_glfw.wl.clipboardSendString); + _glfw.wl.clipboardSendString = NULL; return; } wl_data_source_add_listener(_glfw.wl.dataSource, From 2430d6b7f76e1e6db7a8d35f78125e68afc025e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 22 Mar 2022 19:04:29 +0100 Subject: [PATCH 014/207] Wayland: Remove superfluous global struct member It seems unlikely that strlen will be a bottleneck when sending clipboard contents. (cherry picked from commit 738b1c73b5433c0a3c76f2b14728a5c0ba515643) --- src/wl_platform.h | 1 - src/wl_window.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index dab4c0a5..aaf767c3 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -258,7 +258,6 @@ typedef struct _GLFWlibraryWayland char* clipboardString; size_t clipboardSize; char* clipboardSendString; - size_t clipboardSendSize; int timerfd; short int keycodes[256]; short int scancodes[GLFW_KEY_LAST + 1]; diff --git a/src/wl_window.c b/src/wl_window.c index e425da78..ee4a26f6 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1726,7 +1726,7 @@ static void dataSourceHandleSend(void* data, int fd) { const char* string = _glfw.wl.clipboardSendString; - size_t len = _glfw.wl.clipboardSendSize; + size_t len = strlen(string); int ret; if (_glfw.wl.dataSource != dataSource) @@ -1809,7 +1809,6 @@ void _glfwPlatformSetClipboardString(const char* string) free(_glfw.wl.clipboardSendString); _glfw.wl.clipboardSendString = copy; - _glfw.wl.clipboardSendSize = strlen(_glfw.wl.clipboardSendString); _glfw.wl.dataSource = wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager); if (!_glfw.wl.dataSource) From 25db8f801475d1d90664077db8390fe573d28e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 22 Mar 2022 19:23:25 +0100 Subject: [PATCH 015/207] Wayland: Fix partial writes of clipboard string The string pointer used to write the contents of our clipboard data offer was never updated, causing it to repeat parts of the beginning of the string until the correct number of bytes had been written. (cherry picked from commit 4c110bba41b0df8a3b295fdd5e4e95aed6615001) --- README.md | 1 + src/wl_window.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d406c878..4231914f 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` - [Wayland] Bugfix: Data source creation error would cause double free at termination + - [Wayland] Bugfix: Partial writes of clipboard string would cause beginning to repeat ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index ee4a26f6..ae24626b 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1725,7 +1725,7 @@ static void dataSourceHandleSend(void* data, const char* mimeType, int fd) { - const char* string = _glfw.wl.clipboardSendString; + char* string = _glfw.wl.clipboardSendString; size_t len = strlen(string); int ret; @@ -1765,6 +1765,7 @@ static void dataSourceHandleSend(void* data, return; } len -= ret; + string += ret; } close(fd); } From 32bedd9a9495047340eca45f54a2861b8d5c7f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 22 Mar 2022 19:30:43 +0100 Subject: [PATCH 016/207] Wayland: Fix phrasing of error messages This is adapted to 3.3-stable from 2d45681bc354a50e616082ea37c765c062a1fc09. --- src/wl_init.c | 12 ++++++------ src/wl_window.c | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 679baeb8..54b76743 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -147,7 +147,7 @@ static void setCursor(_GLFWwindow* window, const char* name) if (!cursor) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Standard cursor not found"); + "Wayland: Standard cursor shape unavailable"); return; } // TODO: handle animated cursors too. @@ -1040,7 +1040,7 @@ int _glfwPlatformInit(void) if (!_glfw.wl.cursor.handle) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to open libwayland-cursor"); + "Wayland: Failed to load libwayland-cursor"); return GLFW_FALSE; } @@ -1057,7 +1057,7 @@ int _glfwPlatformInit(void) if (!_glfw.wl.egl.handle) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to open libwayland-egl"); + "Wayland: Failed to load libwayland-egl"); return GLFW_FALSE; } @@ -1072,7 +1072,7 @@ int _glfwPlatformInit(void) if (!_glfw.wl.xkb.handle) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to open libxkbcommon"); + "Wayland: Failed to load libxkbcommon"); return GLFW_FALSE; } @@ -1173,7 +1173,7 @@ int _glfwPlatformInit(void) if (!_glfw.wl.cursorTheme) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Unable to load default cursor theme"); + "Wayland: Failed to load default cursor theme"); return GLFW_FALSE; } // If this happens to be NULL, we just fallback to the scale=1 version. @@ -1196,7 +1196,7 @@ int _glfwPlatformInit(void) if (!_glfw.wl.clipboardString) { _glfwInputError(GLFW_OUT_OF_MEMORY, - "Wayland: Unable to allocate clipboard memory"); + "Wayland: Failed to allocate clipboard memory"); return GLFW_FALSE; } } diff --git a/src/wl_window.c b/src/wl_window.c index ae24626b..5deeac4d 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -209,7 +209,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) if (fd < 0) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Creating a buffer file for %d B failed: %s", + "Wayland: Failed to create buffer file of size %d: %s", length, strerror(errno)); return NULL; } @@ -218,7 +218,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) if (data == MAP_FAILED) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: mmap failed: %s", strerror(errno)); + "Wayland: Failed to map file: %s", strerror(errno)); close(fd); return NULL; } @@ -526,7 +526,7 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable) _glfw.wl.idleInhibitManager, window->wl.surface); if (!window->wl.idleInhibitor) _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Idle inhibitor creation failed"); + "Wayland: Failed to create idle inhibitor"); } else if (!enable && window->wl.idleInhibitor) { @@ -719,7 +719,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) if (!window->wl.xdg.surface) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: xdg-surface creation failed"); + "Wayland: Failed to create xdg-surface for window"); return GLFW_FALSE; } @@ -731,7 +731,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) if (!window->wl.xdg.toplevel) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: xdg-toplevel creation failed"); + "Wayland: Failed to create xdg-toplevel for window"); return GLFW_FALSE; } @@ -1815,7 +1815,7 @@ void _glfwPlatformSetClipboardString(const char* string) if (!_glfw.wl.dataSource) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Impossible to create clipboard source"); + "Wayland: Failed to create clipboard data source"); free(_glfw.wl.clipboardSendString); _glfw.wl.clipboardSendString = NULL; return; @@ -1837,7 +1837,7 @@ static GLFWbool growClipboardString(void) if (!clipboard) { _glfwInputError(GLFW_OUT_OF_MEMORY, - "Wayland: Impossible to grow clipboard string"); + "Wayland: Failed to grow clipboard string"); return GLFW_FALSE; } _glfw.wl.clipboardString = clipboard; @@ -1854,7 +1854,7 @@ const char* _glfwPlatformGetClipboardString(void) if (!_glfw.wl.dataOffer) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "No clipboard data has been sent yet"); + "Wayland: No clipboard data available"); return NULL; } @@ -1863,7 +1863,7 @@ const char* _glfwPlatformGetClipboardString(void) { // TODO: also report errno maybe? _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Impossible to create clipboard pipe fds"); + "Wayland: Failed to create clipboard pipe fds"); return NULL; } @@ -1896,7 +1896,7 @@ const char* _glfwPlatformGetClipboardString(void) { // TODO: also report errno maybe. _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Impossible to read from clipboard fd"); + "Wayland: Failed to read from clipboard fd"); close(fds[0]); return NULL; } From 1ee540bf48618e83f093b6f9e30b9ced24c9edb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 23 Mar 2022 18:52:06 +0100 Subject: [PATCH 017/207] Wayland: Rename data transfer parameters No rationale beyond personal preference. (cherry picked from commit ba11e60859c22132cb6c11f570f5341fa38ef856) --- src/wl_init.c | 22 +++++++++++----------- src/wl_window.c | 14 +++++++------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 54b76743..7024cfba 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -697,7 +697,7 @@ static const struct wl_seat_listener seatListener = { }; static void dataOfferHandleOffer(void* data, - struct wl_data_offer* dataOffer, + struct wl_data_offer* offer, const char* mimeType) { } @@ -707,33 +707,33 @@ static const struct wl_data_offer_listener dataOfferListener = { }; static void dataDeviceHandleDataOffer(void* data, - struct wl_data_device* dataDevice, - struct wl_data_offer* id) + struct wl_data_device* device, + struct wl_data_offer* offer) { if (_glfw.wl.dataOffer) wl_data_offer_destroy(_glfw.wl.dataOffer); - _glfw.wl.dataOffer = id; + _glfw.wl.dataOffer = offer; wl_data_offer_add_listener(_glfw.wl.dataOffer, &dataOfferListener, NULL); } static void dataDeviceHandleEnter(void* data, - struct wl_data_device* dataDevice, + struct wl_data_device* device, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, - struct wl_data_offer *id) + struct wl_data_offer *offer) { } static void dataDeviceHandleLeave(void* data, - struct wl_data_device* dataDevice) + struct wl_data_device* device) { } static void dataDeviceHandleMotion(void* data, - struct wl_data_device* dataDevice, + struct wl_data_device* device, uint32_t time, wl_fixed_t x, wl_fixed_t y) @@ -741,13 +741,13 @@ static void dataDeviceHandleMotion(void* data, } static void dataDeviceHandleDrop(void* data, - struct wl_data_device* dataDevice) + struct wl_data_device* device) { } static void dataDeviceHandleSelection(void* data, - struct wl_data_device* dataDevice, - struct wl_data_offer* id) + struct wl_data_device* device, + struct wl_data_offer* offer) { } diff --git a/src/wl_window.c b/src/wl_window.c index 5deeac4d..1359d588 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1709,10 +1709,10 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) } static void dataSourceHandleTarget(void* data, - struct wl_data_source* dataSource, + struct wl_data_source* source, const char* mimeType) { - if (_glfw.wl.dataSource != dataSource) + if (_glfw.wl.dataSource != source) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unknown clipboard data source"); @@ -1721,7 +1721,7 @@ static void dataSourceHandleTarget(void* data, } static void dataSourceHandleSend(void* data, - struct wl_data_source* dataSource, + struct wl_data_source* source, const char* mimeType, int fd) { @@ -1729,7 +1729,7 @@ static void dataSourceHandleSend(void* data, size_t len = strlen(string); int ret; - if (_glfw.wl.dataSource != dataSource) + if (_glfw.wl.dataSource != source) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unknown clipboard data source"); @@ -1771,11 +1771,11 @@ static void dataSourceHandleSend(void* data, } static void dataSourceHandleCancelled(void* data, - struct wl_data_source* dataSource) + struct wl_data_source* source) { - wl_data_source_destroy(dataSource); + wl_data_source_destroy(source); - if (_glfw.wl.dataSource != dataSource) + if (_glfw.wl.dataSource != source) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unknown clipboard data source"); From 3599fe4a7836e04607aee4e16fa50b24101d3da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 23 Mar 2022 18:55:22 +0100 Subject: [PATCH 018/207] Wayland: Clean up pointer declarations Adapt style to match the rest of the project. (cherry picked from commit 45061750236007f8eaa782a9a8d12ff44733b68a) --- src/wl_init.c | 14 +++++++------- src/wl_monitor.c | 12 ++++++------ src/wl_platform.h | 1 - src/wl_window.c | 14 +++++++------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 7024cfba..730ddb43 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -720,10 +720,10 @@ static void dataDeviceHandleDataOffer(void* data, static void dataDeviceHandleEnter(void* data, struct wl_data_device* device, uint32_t serial, - struct wl_surface *surface, + struct wl_surface* surface, wl_fixed_t x, wl_fixed_t y, - struct wl_data_offer *offer) + struct wl_data_offer* offer) { } @@ -864,8 +864,8 @@ static void registryHandleGlobal(void* data, } } -static void registryHandleGlobalRemove(void *data, - struct wl_registry *registry, +static void registryHandleGlobalRemove(void* data, + struct wl_registry* registry, uint32_t name) { int i; @@ -1030,9 +1030,9 @@ static void createKeyTables(void) int _glfwPlatformInit(void) { - const char *cursorTheme; - const char *cursorSizeStr; - char *cursorSizeEnd; + const char* cursorTheme; + const char* cursorSizeStr; + char* cursorSizeEnd; long cursorSizeLong; int cursorSize; diff --git a/src/wl_monitor.c b/src/wl_monitor.c index d1448a24..68da1026 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -46,7 +46,7 @@ static void outputHandleGeometry(void* data, const char* model, int32_t transform) { - struct _GLFWmonitor *monitor = data; + struct _GLFWmonitor* monitor = data; monitor->wl.x = x; monitor->wl.y = y; @@ -63,7 +63,7 @@ static void outputHandleMode(void* data, int32_t height, int32_t refresh) { - struct _GLFWmonitor *monitor = data; + struct _GLFWmonitor* monitor = data; GLFWvidmode mode; mode.width = width; @@ -84,7 +84,7 @@ static void outputHandleMode(void* data, static void outputHandleDone(void* data, struct wl_output* output) { - struct _GLFWmonitor *monitor = data; + struct _GLFWmonitor* monitor = data; if (monitor->widthMM <= 0 || monitor->heightMM <= 0) { @@ -101,7 +101,7 @@ static void outputHandleScale(void* data, struct wl_output* output, int32_t factor) { - struct _GLFWmonitor *monitor = data; + struct _GLFWmonitor* monitor = data; monitor->wl.scale = factor; } @@ -120,8 +120,8 @@ static const struct wl_output_listener outputListener = { void _glfwAddOutputWayland(uint32_t name, uint32_t version) { - _GLFWmonitor *monitor; - struct wl_output *output; + _GLFWmonitor* monitor; + struct wl_output* output; if (version < 2) { diff --git a/src/wl_platform.h b/src/wl_platform.h index aaf767c3..2385402e 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -347,7 +347,6 @@ typedef struct _GLFWcursorWayland int currentImage; } _GLFWcursorWayland; - void _glfwAddOutputWayland(uint32_t name, uint32_t version); GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode); diff --git a/src/wl_window.c b/src/wl_window.c index 1359d588..cb2e2237 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -471,9 +471,9 @@ static void checkScaleChange(_GLFWwindow* window) } } -static void surfaceHandleEnter(void *data, - struct wl_surface *surface, - struct wl_output *output) +static void surfaceHandleEnter(void* data, + struct wl_surface* surface, + struct wl_output* output) { _GLFWwindow* window = data; _GLFWmonitor* monitor = wl_output_get_user_data(output); @@ -491,9 +491,9 @@ static void surfaceHandleEnter(void *data, checkScaleChange(window); } -static void surfaceHandleLeave(void *data, - struct wl_surface *surface, - struct wl_output *output) +static void surfaceHandleLeave(void* data, + struct wl_surface* surface, + struct wl_output* output) { _GLFWwindow* window = data; _GLFWmonitor* monitor = wl_output_get_user_data(output); @@ -1371,7 +1371,7 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) { } -void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) +void _glfwPlatformSetRawMouseMotion(_GLFWwindow* window, GLFWbool enabled) { // This is handled in relativePointerHandleRelativeMotion } From f51ec79951d5d1d92106661fde40150c1e6434f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 23 Mar 2022 18:58:08 +0100 Subject: [PATCH 019/207] Wayland: Rename listener user data parameters (cherry picked from commit a4460b694e512e6f4b485055832792d3c22ccbe1) --- src/wl_init.c | 46 +++++++++++++++++++++++----------------------- src/wl_monitor.c | 16 ++++++++-------- src/wl_window.c | 36 ++++++++++++++++++------------------ 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 730ddb43..b7b1188d 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -77,7 +77,7 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, return window; } -static void pointerHandleEnter(void* data, +static void pointerHandleEnter(void* userData, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface, @@ -108,7 +108,7 @@ static void pointerHandleEnter(void* data, _glfwInputCursorEnter(window, GLFW_TRUE); } -static void pointerHandleLeave(void* data, +static void pointerHandleLeave(void* userData, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface) @@ -171,7 +171,7 @@ static void setCursor(_GLFWwindow* window, const char* name) _glfw.wl.cursorPreviousName = name; } -static void pointerHandleMotion(void* data, +static void pointerHandleMotion(void* userData, struct wl_pointer* pointer, uint32_t time, wl_fixed_t sx, @@ -230,7 +230,7 @@ static void pointerHandleMotion(void* data, setCursor(window, cursorName); } -static void pointerHandleButton(void* data, +static void pointerHandleButton(void* userData, struct wl_pointer* pointer, uint32_t serial, uint32_t time, @@ -326,7 +326,7 @@ static void pointerHandleButton(void* data, _glfw.wl.xkb.modifiers); } -static void pointerHandleAxis(void* data, +static void pointerHandleAxis(void* userData, struct wl_pointer* pointer, uint32_t time, uint32_t axis, @@ -361,7 +361,7 @@ static const struct wl_pointer_listener pointerListener = { pointerHandleAxis, }; -static void keyboardHandleKeymap(void* data, +static void keyboardHandleKeymap(void* userData, struct wl_keyboard* keyboard, uint32_t format, int fd, @@ -457,7 +457,7 @@ static void keyboardHandleKeymap(void* data, 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2"); } -static void keyboardHandleEnter(void* data, +static void keyboardHandleEnter(void* userData, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface, @@ -480,7 +480,7 @@ static void keyboardHandleEnter(void* data, _glfwInputWindowFocus(window, GLFW_TRUE); } -static void keyboardHandleLeave(void* data, +static void keyboardHandleLeave(void* userData, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface) @@ -546,7 +546,7 @@ GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode) return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); } -static void keyboardHandleKey(void* data, +static void keyboardHandleKey(void* userData, struct wl_keyboard* keyboard, uint32_t serial, uint32_t time, @@ -587,7 +587,7 @@ static void keyboardHandleKey(void* data, timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); } -static void keyboardHandleModifiers(void* data, +static void keyboardHandleModifiers(void* userData, struct wl_keyboard* keyboard, uint32_t serial, uint32_t modsDepressed, @@ -634,7 +634,7 @@ static void keyboardHandleModifiers(void* data, } #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION -static void keyboardHandleRepeatInfo(void* data, +static void keyboardHandleRepeatInfo(void* userData, struct wl_keyboard* keyboard, int32_t rate, int32_t delay) @@ -658,7 +658,7 @@ static const struct wl_keyboard_listener keyboardListener = { #endif }; -static void seatHandleCapabilities(void* data, +static void seatHandleCapabilities(void* userData, struct wl_seat* seat, enum wl_seat_capability caps) { @@ -685,7 +685,7 @@ static void seatHandleCapabilities(void* data, } } -static void seatHandleName(void* data, +static void seatHandleName(void* userData, struct wl_seat* seat, const char* name) { @@ -696,7 +696,7 @@ static const struct wl_seat_listener seatListener = { seatHandleName, }; -static void dataOfferHandleOffer(void* data, +static void dataOfferHandleOffer(void* userData, struct wl_data_offer* offer, const char* mimeType) { @@ -706,7 +706,7 @@ static const struct wl_data_offer_listener dataOfferListener = { dataOfferHandleOffer, }; -static void dataDeviceHandleDataOffer(void* data, +static void dataDeviceHandleDataOffer(void* userData, struct wl_data_device* device, struct wl_data_offer* offer) { @@ -717,7 +717,7 @@ static void dataDeviceHandleDataOffer(void* data, wl_data_offer_add_listener(_glfw.wl.dataOffer, &dataOfferListener, NULL); } -static void dataDeviceHandleEnter(void* data, +static void dataDeviceHandleEnter(void* userData, struct wl_data_device* device, uint32_t serial, struct wl_surface* surface, @@ -727,12 +727,12 @@ static void dataDeviceHandleEnter(void* data, { } -static void dataDeviceHandleLeave(void* data, +static void dataDeviceHandleLeave(void* userData, struct wl_data_device* device) { } -static void dataDeviceHandleMotion(void* data, +static void dataDeviceHandleMotion(void* userData, struct wl_data_device* device, uint32_t time, wl_fixed_t x, @@ -740,12 +740,12 @@ static void dataDeviceHandleMotion(void* data, { } -static void dataDeviceHandleDrop(void* data, +static void dataDeviceHandleDrop(void* userData, struct wl_data_device* device) { } -static void dataDeviceHandleSelection(void* data, +static void dataDeviceHandleSelection(void* userData, struct wl_data_device* device, struct wl_data_offer* offer) { @@ -760,7 +760,7 @@ static const struct wl_data_device_listener dataDeviceListener = { dataDeviceHandleSelection, }; -static void wmBaseHandlePing(void* data, +static void wmBaseHandlePing(void* userData, struct xdg_wm_base* wmBase, uint32_t serial) { @@ -771,7 +771,7 @@ static const struct xdg_wm_base_listener wmBaseListener = { wmBaseHandlePing }; -static void registryHandleGlobal(void* data, +static void registryHandleGlobal(void* userData, struct wl_registry* registry, uint32_t name, const char* interface, @@ -864,7 +864,7 @@ static void registryHandleGlobal(void* data, } } -static void registryHandleGlobalRemove(void* data, +static void registryHandleGlobalRemove(void* userData, struct wl_registry* registry, uint32_t name) { diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 68da1026..f4009c34 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -35,7 +35,7 @@ #include -static void outputHandleGeometry(void* data, +static void outputHandleGeometry(void* userData, struct wl_output* output, int32_t x, int32_t y, @@ -46,7 +46,7 @@ static void outputHandleGeometry(void* data, const char* model, int32_t transform) { - struct _GLFWmonitor* monitor = data; + struct _GLFWmonitor* monitor = userData; monitor->wl.x = x; monitor->wl.y = y; @@ -56,14 +56,14 @@ static void outputHandleGeometry(void* data, snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model); } -static void outputHandleMode(void* data, +static void outputHandleMode(void* userData, struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { - struct _GLFWmonitor* monitor = data; + struct _GLFWmonitor* monitor = userData; GLFWvidmode mode; mode.width = width; @@ -82,9 +82,9 @@ static void outputHandleMode(void* data, monitor->wl.currentMode = monitor->modeCount - 1; } -static void outputHandleDone(void* data, struct wl_output* output) +static void outputHandleDone(void* userData, struct wl_output* output) { - struct _GLFWmonitor* monitor = data; + struct _GLFWmonitor* monitor = userData; if (monitor->widthMM <= 0 || monitor->heightMM <= 0) { @@ -97,11 +97,11 @@ static void outputHandleDone(void* data, struct wl_output* output) _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST); } -static void outputHandleScale(void* data, +static void outputHandleScale(void* userData, struct wl_output* output, int32_t factor) { - struct _GLFWmonitor* monitor = data; + struct _GLFWmonitor* monitor = userData; monitor->wl.scale = factor; } diff --git a/src/wl_window.c b/src/wl_window.c index cb2e2237..d0eef535 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -379,11 +379,11 @@ static void destroyDecorations(_GLFWwindow* window) destroyDecoration(&window->wl.decorations.bottom); } -static void xdgDecorationHandleConfigure(void* data, +static void xdgDecorationHandleConfigure(void* userData, struct zxdg_toplevel_decoration_v1* decoration, uint32_t mode) { - _GLFWwindow* window = data; + _GLFWwindow* window = userData; window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); @@ -471,11 +471,11 @@ static void checkScaleChange(_GLFWwindow* window) } } -static void surfaceHandleEnter(void* data, +static void surfaceHandleEnter(void* userData, struct wl_surface* surface, struct wl_output* output) { - _GLFWwindow* window = data; + _GLFWwindow* window = userData; _GLFWmonitor* monitor = wl_output_get_user_data(output); if (window->wl.monitorsCount + 1 > window->wl.monitorsSize) @@ -491,11 +491,11 @@ static void surfaceHandleEnter(void* data, checkScaleChange(window); } -static void surfaceHandleLeave(void* data, +static void surfaceHandleLeave(void* userData, struct wl_surface* surface, struct wl_output* output) { - _GLFWwindow* window = data; + _GLFWwindow* window = userData; _GLFWmonitor* monitor = wl_output_get_user_data(output); GLFWbool found; int i; @@ -604,13 +604,13 @@ static GLFWbool createShellSurface(_GLFWwindow* window) return GLFW_TRUE; } -static void xdgToplevelHandleConfigure(void* data, +static void xdgToplevelHandleConfigure(void* userData, struct xdg_toplevel* toplevel, int32_t width, int32_t height, struct wl_array* states) { - _GLFWwindow* window = data; + _GLFWwindow* window = userData; float aspectRatio; float targetRatio; uint32_t* state; @@ -668,10 +668,10 @@ static void xdgToplevelHandleConfigure(void* data, window->wl.wasFullscreen = GLFW_TRUE; } -static void xdgToplevelHandleClose(void* data, +static void xdgToplevelHandleClose(void* userData, struct xdg_toplevel* toplevel) { - _GLFWwindow* window = data; + _GLFWwindow* window = userData; _glfwInputWindowCloseRequest(window); } @@ -680,7 +680,7 @@ static const struct xdg_toplevel_listener xdgToplevelListener = { xdgToplevelHandleClose }; -static void xdgSurfaceHandleConfigure(void* data, +static void xdgSurfaceHandleConfigure(void* userData, struct xdg_surface* surface, uint32_t serial) { @@ -1541,7 +1541,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) wl_buffer_destroy(cursor->wl.buffer); } -static void relativePointerHandleRelativeMotion(void* data, +static void relativePointerHandleRelativeMotion(void* userData, struct zwp_relative_pointer_v1* pointer, uint32_t timeHi, uint32_t timeLo, @@ -1550,7 +1550,7 @@ static void relativePointerHandleRelativeMotion(void* data, wl_fixed_t dxUnaccel, wl_fixed_t dyUnaccel) { - _GLFWwindow* window = data; + _GLFWwindow* window = userData; double xpos = window->virtualCursorPosX; double ypos = window->virtualCursorPosY; @@ -1575,7 +1575,7 @@ static const struct zwp_relative_pointer_v1_listener relativePointerListener = { relativePointerHandleRelativeMotion }; -static void lockedPointerHandleLocked(void* data, +static void lockedPointerHandleLocked(void* userData, struct zwp_locked_pointer_v1* lockedPointer) { } @@ -1596,7 +1596,7 @@ static void unlockPointer(_GLFWwindow* window) static void lockPointer(_GLFWwindow* window); -static void lockedPointerHandleUnlocked(void* data, +static void lockedPointerHandleUnlocked(void* userData, struct zwp_locked_pointer_v1* lockedPointer) { } @@ -1708,7 +1708,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) } } -static void dataSourceHandleTarget(void* data, +static void dataSourceHandleTarget(void* userData, struct wl_data_source* source, const char* mimeType) { @@ -1720,7 +1720,7 @@ static void dataSourceHandleTarget(void* data, } } -static void dataSourceHandleSend(void* data, +static void dataSourceHandleSend(void* userData, struct wl_data_source* source, const char* mimeType, int fd) @@ -1770,7 +1770,7 @@ static void dataSourceHandleSend(void* data, close(fd); } -static void dataSourceHandleCancelled(void* data, +static void dataSourceHandleCancelled(void* userData, struct wl_data_source* source) { wl_data_source_destroy(source); From 75b27849f69694ec7f0542cb3e912ec571c7b86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 23 Mar 2022 20:08:12 +0100 Subject: [PATCH 020/207] Wayland: Fix error paths not closing sending fd Whatever error happens on our end, we should still close the fd so the other end can move on. (cherry picked from commit 990dc4b3888bbaffdc7c3da65ab6c2f8d24285d4) --- README.md | 1 + src/wl_window.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 4231914f..582500c7 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ information on what to include when reporting a bug. `glfwGetClipboardString` - [Wayland] Bugfix: Data source creation error would cause double free at termination - [Wayland] Bugfix: Partial writes of clipboard string would cause beginning to repeat + - [Wayland] Bugfix: Some errors would cause clipboard string transfer to hang ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index d0eef535..497b00dd 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1733,6 +1733,7 @@ static void dataSourceHandleSend(void* userData, { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unknown clipboard data source"); + close(fd); return; } @@ -1740,6 +1741,7 @@ static void dataSourceHandleSend(void* userData, { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Copy requested from an invalid string"); + close(fd); return; } From c89899a428d03f8f24d2ebd636b383b866641ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 14:51:24 +0100 Subject: [PATCH 021/207] Wayland: Return our clipboard without roundtrips (cherry picked from commit 89d3ea8d691016306ca23f26d1dc11e9f51baea2) --- src/wl_window.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 497b00dd..997baa18 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1860,6 +1860,9 @@ const char* _glfwPlatformGetClipboardString(void) return NULL; } + if (_glfw.wl.dataSource) + return _glfw.wl.clipboardSendString; + ret = pipe2(fds, O_CLOEXEC); if (ret < 0) { @@ -1870,10 +1873,9 @@ const char* _glfwPlatformGetClipboardString(void) } wl_data_offer_receive(_glfw.wl.dataOffer, "text/plain;charset=utf-8", fds[1]); - close(fds[1]); - // XXX: this is a huge hack, this function shouldn’t be synchronous! - handleEvents(NULL); + flushDisplay(); + close(fds[1]); for (;;) { From a31c648127bcbd856661d5f31bcca7a61aaa7f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 23 Mar 2022 19:58:33 +0100 Subject: [PATCH 022/207] Wayland: Improve handling of pending data offers The code assumed that all data offers were selections that supported plaintext UTF-8. The initial data offer events are now handled almost tolerably. Only selection data offers are used for clipboard string and only if they provide plaintext UTF-8. Drag and drop data offers are now rejected as soon as they enter a surface. Related to #2040 (cherry picked from commit 8d87be1268869af69d59400a1b0403e9ecbc5c0c) --- README.md | 2 ++ src/wl_init.c | 72 +++++++++++++++++++++++++++++++++++++++++------ src/wl_platform.h | 14 +++++++-- src/wl_window.c | 30 ++++++++++---------- 4 files changed, 93 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 582500c7..d97f71d6 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,8 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Data source creation error would cause double free at termination - [Wayland] Bugfix: Partial writes of clipboard string would cause beginning to repeat - [Wayland] Bugfix: Some errors would cause clipboard string transfer to hang + - [Wayland] Bugfix: Drag and drop data was misinterpreted as clipboard string + - [Wayland] Bugfix: MIME type matching was not performed for clipboard string ## Contact diff --git a/src/wl_init.c b/src/wl_init.c index b7b1188d..fb874ba6 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -700,6 +700,16 @@ static void dataOfferHandleOffer(void* userData, struct wl_data_offer* offer, const char* mimeType) { + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + { + if (_glfw.wl.offers[i].offer == offer) + { + if (strcmp(mimeType, "text/plain;charset=utf-8") == 0) + _glfw.wl.offers[i].text_plain_utf8 = GLFW_TRUE; + + break; + } + } } static const struct wl_data_offer_listener dataOfferListener = { @@ -710,11 +720,19 @@ static void dataDeviceHandleDataOffer(void* userData, struct wl_data_device* device, struct wl_data_offer* offer) { - if (_glfw.wl.dataOffer) - wl_data_offer_destroy(_glfw.wl.dataOffer); + _GLFWofferWayland* offers = + realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1); + if (!offers) + { + _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); + return; + } - _glfw.wl.dataOffer = offer; - wl_data_offer_add_listener(_glfw.wl.dataOffer, &dataOfferListener, NULL); + _glfw.wl.offers = offers; + _glfw.wl.offerCount++; + + _glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { offer }; + wl_data_offer_add_listener(offer, &dataOfferListener, NULL); } static void dataDeviceHandleEnter(void* userData, @@ -725,6 +743,19 @@ static void dataDeviceHandleEnter(void* userData, wl_fixed_t y, struct wl_data_offer* offer) { + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + { + if (_glfw.wl.offers[i].offer == offer) + { + _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; + _glfw.wl.offerCount--; + + // We don't yet handle drag and drop + wl_data_offer_accept(offer, serial, NULL); + wl_data_offer_destroy(offer); + break; + } + } } static void dataDeviceHandleLeave(void* userData, @@ -749,6 +780,26 @@ static void dataDeviceHandleSelection(void* userData, struct wl_data_device* device, struct wl_data_offer* offer) { + if (_glfw.wl.selectionOffer) + { + wl_data_offer_destroy(_glfw.wl.selectionOffer); + _glfw.wl.selectionOffer = NULL; + } + + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + { + if (_glfw.wl.offers[i].offer == offer) + { + if (_glfw.wl.offers[i].text_plain_utf8) + _glfw.wl.selectionOffer = offer; + else + wl_data_offer_destroy(offer); + + _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; + _glfw.wl.offerCount--; + break; + } + } } static const struct wl_data_device_listener dataDeviceListener = { @@ -1240,6 +1291,11 @@ void _glfwPlatformTerminate(void) _glfw.wl.cursor.handle = NULL; } + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + wl_data_offer_destroy(_glfw.wl.offers[i].offer); + + free(_glfw.wl.offers); + if (_glfw.wl.cursorSurface) wl_surface_destroy(_glfw.wl.cursorSurface); if (_glfw.wl.subcompositor) @@ -1256,12 +1312,12 @@ void _glfwPlatformTerminate(void) zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager); if (_glfw.wl.wmBase) xdg_wm_base_destroy(_glfw.wl.wmBase); - if (_glfw.wl.dataSource) - wl_data_source_destroy(_glfw.wl.dataSource); + if (_glfw.wl.selectionOffer) + wl_data_offer_destroy(_glfw.wl.selectionOffer); + if (_glfw.wl.selectionSource) + wl_data_source_destroy(_glfw.wl.selectionSource); if (_glfw.wl.dataDevice) wl_data_device_destroy(_glfw.wl.dataDevice); - if (_glfw.wl.dataOffer) - wl_data_offer_destroy(_glfw.wl.dataOffer); if (_glfw.wl.dataDeviceManager) wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager); if (_glfw.wl.pointer) diff --git a/src/wl_platform.h b/src/wl_platform.h index 2385402e..31aa0fc7 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -167,6 +167,12 @@ typedef struct _GLFWdecorationWayland struct wp_viewport* viewport; } _GLFWdecorationWayland; +typedef struct _GLFWofferWayland +{ + struct wl_data_offer* offer; + GLFWbool text_plain_utf8; +} _GLFWofferWayland; + // Wayland-specific per-window data // typedef struct _GLFWwindowWayland @@ -231,8 +237,6 @@ typedef struct _GLFWlibraryWayland 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; @@ -240,6 +244,12 @@ typedef struct _GLFWlibraryWayland struct zwp_pointer_constraints_v1* pointerConstraints; struct zwp_idle_inhibit_manager_v1* idleInhibitManager; + _GLFWofferWayland* offers; + unsigned int offerCount; + + struct wl_data_offer* selectionOffer; + struct wl_data_source* selectionSource; + int compositorVersion; int seatVersion; diff --git a/src/wl_window.c b/src/wl_window.c index 997baa18..98f2891c 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1712,7 +1712,7 @@ static void dataSourceHandleTarget(void* userData, struct wl_data_source* source, const char* mimeType) { - if (_glfw.wl.dataSource != source) + if (_glfw.wl.selectionSource != source) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unknown clipboard data source"); @@ -1729,7 +1729,7 @@ static void dataSourceHandleSend(void* userData, size_t len = strlen(string); int ret; - if (_glfw.wl.dataSource != source) + if (_glfw.wl.selectionSource != source) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unknown clipboard data source"); @@ -1777,14 +1777,14 @@ static void dataSourceHandleCancelled(void* userData, { wl_data_source_destroy(source); - if (_glfw.wl.dataSource != source) + if (_glfw.wl.selectionSource != source) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unknown clipboard data source"); return; } - _glfw.wl.dataSource = NULL; + _glfw.wl.selectionSource = NULL; } static const struct wl_data_source_listener dataSourceListener = { @@ -1795,10 +1795,10 @@ static const struct wl_data_source_listener dataSourceListener = { void _glfwPlatformSetClipboardString(const char* string) { - if (_glfw.wl.dataSource) + if (_glfw.wl.selectionSource) { - wl_data_source_destroy(_glfw.wl.dataSource); - _glfw.wl.dataSource = NULL; + wl_data_source_destroy(_glfw.wl.selectionSource); + _glfw.wl.selectionSource = NULL; } char* copy = _glfw_strdup(string); @@ -1812,9 +1812,9 @@ void _glfwPlatformSetClipboardString(const char* string) free(_glfw.wl.clipboardSendString); _glfw.wl.clipboardSendString = copy; - _glfw.wl.dataSource = + _glfw.wl.selectionSource = wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager); - if (!_glfw.wl.dataSource) + if (!_glfw.wl.selectionSource) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create clipboard data source"); @@ -1822,12 +1822,12 @@ void _glfwPlatformSetClipboardString(const char* string) _glfw.wl.clipboardSendString = NULL; return; } - wl_data_source_add_listener(_glfw.wl.dataSource, + wl_data_source_add_listener(_glfw.wl.selectionSource, &dataSourceListener, NULL); - wl_data_source_offer(_glfw.wl.dataSource, "text/plain;charset=utf-8"); + wl_data_source_offer(_glfw.wl.selectionSource, "text/plain;charset=utf-8"); wl_data_device_set_selection(_glfw.wl.dataDevice, - _glfw.wl.dataSource, + _glfw.wl.selectionSource, _glfw.wl.serial); } @@ -1853,14 +1853,14 @@ const char* _glfwPlatformGetClipboardString(void) int ret; size_t len = 0; - if (!_glfw.wl.dataOffer) + if (!_glfw.wl.selectionOffer) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "Wayland: No clipboard data available"); return NULL; } - if (_glfw.wl.dataSource) + if (_glfw.wl.selectionSource) return _glfw.wl.clipboardSendString; ret = pipe2(fds, O_CLOEXEC); @@ -1872,7 +1872,7 @@ const char* _glfwPlatformGetClipboardString(void) return NULL; } - wl_data_offer_receive(_glfw.wl.dataOffer, "text/plain;charset=utf-8", fds[1]); + wl_data_offer_receive(_glfw.wl.selectionOffer, "text/plain;charset=utf-8", fds[1]); flushDisplay(); close(fds[1]); From 857fae4920b3fa86e5f8fada2437bf9ee1279d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 18:02:48 +0100 Subject: [PATCH 023/207] Wayland: Simplify clipboard string allocation (cherry picked from commit 46511652726afdaf3d92173f8f14d900f1f75994) --- src/wl_init.c | 10 -------- src/wl_platform.h | 1 - src/wl_window.c | 59 ++++++++++++++++++++--------------------------- 3 files changed, 25 insertions(+), 45 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index fb874ba6..3ee46825 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -1241,15 +1241,6 @@ int _glfwPlatformInit(void) wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager, _glfw.wl.seat); wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL); - - _glfw.wl.clipboardSize = 4096; - _glfw.wl.clipboardString = calloc(_glfw.wl.clipboardSize, 1); - if (!_glfw.wl.clipboardString) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, - "Wayland: Failed to allocate clipboard memory"); - return GLFW_FALSE; - } } return GLFW_TRUE; @@ -1346,7 +1337,6 @@ void _glfwPlatformTerminate(void) close(_glfw.wl.cursorTimerfd); free(_glfw.wl.clipboardString); - free(_glfw.wl.clipboardSendString); } const char* _glfwPlatformGetVersionString(void) diff --git a/src/wl_platform.h b/src/wl_platform.h index 31aa0fc7..4b97813b 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -267,7 +267,6 @@ typedef struct _GLFWlibraryWayland int keyboardLastScancode; char* clipboardString; size_t clipboardSize; - char* clipboardSendString; int timerfd; short int keycodes[256]; short int scancodes[GLFW_KEY_LAST + 1]; diff --git a/src/wl_window.c b/src/wl_window.c index 98f2891c..1ecaccbd 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1725,7 +1725,7 @@ static void dataSourceHandleSend(void* userData, const char* mimeType, int fd) { - char* string = _glfw.wl.clipboardSendString; + char* string = _glfw.wl.clipboardString; size_t len = strlen(string); int ret; @@ -1801,16 +1801,23 @@ void _glfwPlatformSetClipboardString(const char* string) _glfw.wl.selectionSource = NULL; } - char* copy = _glfw_strdup(string); - if (!copy) + const size_t requiredSize = strlen(string) + 1; + if (requiredSize > _glfw.wl.clipboardSize) { - _glfwInputError(GLFW_OUT_OF_MEMORY, - "Wayland: Failed to allocate clipboard string"); - return; + free(_glfw.wl.clipboardString); + _glfw.wl.clipboardString = calloc(requiredSize, 1); + if (!_glfw.wl.clipboardString) + { + _glfwInputError(GLFW_OUT_OF_MEMORY, + "Wayland: Failed to allocate clipboard string"); + return; + } + + _glfw.wl.clipboardSize = requiredSize; } - free(_glfw.wl.clipboardSendString); - _glfw.wl.clipboardSendString = copy; + // The argument may be a substring of the clipboard string + memmove(_glfw.wl.clipboardString, string, requiredSize); _glfw.wl.selectionSource = wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager); @@ -1818,8 +1825,6 @@ void _glfwPlatformSetClipboardString(const char* string) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create clipboard data source"); - free(_glfw.wl.clipboardSendString); - _glfw.wl.clipboardSendString = NULL; return; } wl_data_source_add_listener(_glfw.wl.selectionSource, @@ -1831,22 +1836,6 @@ void _glfwPlatformSetClipboardString(const char* string) _glfw.wl.serial); } -static GLFWbool growClipboardString(void) -{ - char* clipboard = _glfw.wl.clipboardString; - - clipboard = realloc(clipboard, _glfw.wl.clipboardSize * 2); - if (!clipboard) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, - "Wayland: Failed to grow clipboard string"); - return GLFW_FALSE; - } - _glfw.wl.clipboardString = clipboard; - _glfw.wl.clipboardSize = _glfw.wl.clipboardSize * 2; - return GLFW_TRUE; -} - const char* _glfwPlatformGetClipboardString(void) { int fds[2]; @@ -1861,7 +1850,7 @@ const char* _glfwPlatformGetClipboardString(void) } if (_glfw.wl.selectionSource) - return _glfw.wl.clipboardSendString; + return _glfw.wl.clipboardString; ret = pipe2(fds, O_CLOEXEC); if (ret < 0) @@ -1881,13 +1870,20 @@ const char* _glfwPlatformGetClipboardString(void) { // Grow the clipboard if we need to paste something bigger, there is no // shrink operation yet. - if (len + 4096 > _glfw.wl.clipboardSize) + const size_t requiredSize = len + 4096 + 1; + if (requiredSize > _glfw.wl.clipboardSize) { - if (!growClipboardString()) + char* string = realloc(_glfw.wl.clipboardString, requiredSize); + if (!string) { + _glfwInputError(GLFW_OUT_OF_MEMORY, + "Wayland: Failed to grow clipboard string"); close(fds[0]); return NULL; } + + _glfw.wl.clipboardString = string; + _glfw.wl.clipboardSize = requiredSize; } // Then read from the fd to the clipboard, handling all known errors. @@ -1907,11 +1903,6 @@ const char* _glfwPlatformGetClipboardString(void) len += ret; } close(fds[0]); - if (len + 1 > _glfw.wl.clipboardSize) - { - if (!growClipboardString()) - return NULL; - } _glfw.wl.clipboardString[len] = '\0'; return _glfw.wl.clipboardString; } From 915e43885c50958bdd2dd74e93e59f7dd1c77813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 19:04:15 +0100 Subject: [PATCH 024/207] Wayland: Clean up clipboard reading (cherry picked from commit c13213533241d7bbf53da89641a8fe6c71d53c0e) --- src/wl_window.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 1ecaccbd..24434fa5 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1838,10 +1838,6 @@ void _glfwPlatformSetClipboardString(const char* string) const char* _glfwPlatformGetClipboardString(void) { - int fds[2]; - int ret; - size_t len = 0; - if (!_glfw.wl.selectionOffer) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, @@ -1852,8 +1848,9 @@ const char* _glfwPlatformGetClipboardString(void) if (_glfw.wl.selectionSource) return _glfw.wl.clipboardString; - ret = pipe2(fds, O_CLOEXEC); - if (ret < 0) + int fds[2]; + + if (pipe2(fds, O_CLOEXEC) == -1) { // TODO: also report errno maybe? _glfwInputError(GLFW_PLATFORM_ERROR, @@ -1866,11 +1863,14 @@ const char* _glfwPlatformGetClipboardString(void) flushDisplay(); close(fds[1]); + size_t length = 0; + for (;;) { // Grow the clipboard if we need to paste something bigger, there is no // shrink operation yet. - const size_t requiredSize = len + 4096 + 1; + const size_t readSize = 4096; + const size_t requiredSize = length + readSize + 1; if (requiredSize > _glfw.wl.clipboardSize) { char* string = realloc(_glfw.wl.clipboardString, requiredSize); @@ -1887,23 +1887,27 @@ const char* _glfwPlatformGetClipboardString(void) } // Then read from the fd to the clipboard, handling all known errors. - ret = read(fds[0], _glfw.wl.clipboardString + len, 4096); - if (ret == 0) + const ssize_t result = read(fds[0], _glfw.wl.clipboardString + length, readSize); + if (result == 0) break; - if (ret == -1 && errno == EINTR) - continue; - if (ret == -1) + else if (result == -1) { + if (errno == EINTR) + continue; + // TODO: also report errno maybe. _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to read from clipboard fd"); close(fds[0]); return NULL; } - len += ret; + + length += result; } + close(fds[0]); - _glfw.wl.clipboardString[len] = '\0'; + + _glfw.wl.clipboardString[length] = '\0'; return _glfw.wl.clipboardString; } From f145e1f930b467c7d8ff6cc0771c289f09bad094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 19:04:58 +0100 Subject: [PATCH 025/207] Wayland: Add strerror output to error descriptions (cherry picked from commit e0889736fd603d163d87eef9426e4e4ebc68b60d) --- src/wl_window.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 24434fa5..690e69e2 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1760,9 +1760,9 @@ static void dataSourceHandleSend(void* userData, continue; if (ret == -1) { - // TODO: also report errno maybe. _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Error while writing the clipboard"); + "Wayland: Error while writing the clipboard: %s", + strerror(errno)); close(fd); return; } @@ -1852,9 +1852,9 @@ const char* _glfwPlatformGetClipboardString(void) if (pipe2(fds, O_CLOEXEC) == -1) { - // TODO: also report errno maybe? _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to create clipboard pipe fds"); + "Wayland: Failed to create clipboard pipe: %s", + strerror(errno)); return NULL; } @@ -1895,9 +1895,9 @@ const char* _glfwPlatformGetClipboardString(void) if (errno == EINTR) continue; - // TODO: also report errno maybe. _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to read from clipboard fd"); + "Wayland: Failed to read from clipboard pipe: %s", + strerror(errno)); close(fds[0]); return NULL; } From ea1b6b963810d4371c459ef3bd1ef940b4508ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 20:17:32 +0100 Subject: [PATCH 026/207] Move URI list parsing to shared code This will soon be used by the Wayland backend. (cherry picked from commit ad4a9e42f0b43994149d590bc08bb4845ba2b86f) --- src/init.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/internal.h | 1 + src/x11_window.c | 53 +----------------------------------------------- 3 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/init.c b/src/init.c index 76397c41..cfdd512d 100644 --- a/src/init.c +++ b/src/init.c @@ -142,6 +142,59 @@ size_t _glfwEncodeUTF8(char* s, uint32_t codepoint) return count; } +// Splits and translates a text/uri-list into separate file paths +// NOTE: This function destroys the provided string +// +char** _glfwParseUriList(char* text, int* count) +{ + const char* prefix = "file://"; + char** paths = NULL; + char* line; + + *count = 0; + + while ((line = strtok(text, "\r\n"))) + { + char* path; + + text = NULL; + + if (line[0] == '#') + continue; + + if (strncmp(line, prefix, strlen(prefix)) == 0) + { + line += strlen(prefix); + // TODO: Validate hostname + while (*line != '/') + line++; + } + + (*count)++; + + path = calloc(strlen(line) + 1, 1); + paths = realloc(paths, *count * sizeof(char*)); + paths[*count - 1] = path; + + while (*line) + { + if (line[0] == '%' && line[1] && line[2]) + { + const char digits[3] = { line[1], line[2], '\0' }; + *path = (char) strtol(digits, NULL, 16); + line += 2; + } + else + *path = *line; + + path++; + line++; + } + } + + return paths; +} + char* _glfw_strdup(const char* source) { const size_t length = strlen(source); diff --git a/src/internal.h b/src/internal.h index 69d6a19a..3e9283a3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -775,6 +775,7 @@ void _glfwTerminateVulkan(void); const char* _glfwGetVulkanResultString(VkResult result); size_t _glfwEncodeUTF8(char* s, uint32_t codepoint); +char** _glfwParseUriList(char* text, int* count); char* _glfw_strdup(const char* source); int _glfw_min(int a, int b); diff --git a/src/x11_window.c b/src/x11_window.c index 646fbdab..47ffef82 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -458,57 +458,6 @@ static void updateWindowMode(_GLFWwindow* window) } } -// Splits and translates a text/uri-list into separate file paths -// NOTE: This function destroys the provided string -// -static char** parseUriList(char* text, int* count) -{ - const char* prefix = "file://"; - char** paths = NULL; - char* line; - - *count = 0; - - while ((line = strtok(text, "\r\n"))) - { - text = NULL; - - if (line[0] == '#') - continue; - - if (strncmp(line, prefix, strlen(prefix)) == 0) - { - line += strlen(prefix); - // TODO: Validate hostname - while (*line != '/') - line++; - } - - (*count)++; - - char* path = calloc(strlen(line) + 1, 1); - paths = realloc(paths, *count * sizeof(char*)); - paths[*count - 1] = path; - - while (*line) - { - if (line[0] == '%' && line[1] && line[2]) - { - const char digits[3] = { line[1], line[2], '\0' }; - *path = strtol(digits, NULL, 16); - line += 2; - } - else - *path = *line; - - path++; - line++; - } - } - - return paths; -} - // Decode a Unicode code point from a UTF-8 stream // Based on cutef8 by Jeff Bezanson (Public Domain) // @@ -1808,7 +1757,7 @@ static void processEvent(XEvent *event) if (result) { int i, count; - char** paths = parseUriList(data, &count); + char** paths = _glfwParseUriList(data, &count); _glfwInputDrop(window, count, (const char**) paths); From 4d68daedc91b04a1185b2a8c431e9446a24075cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 20:34:04 +0100 Subject: [PATCH 027/207] Wayland: Clean up clipboard writing (cherry picked from commit 34418951ccc3eeb3380cd3c93b5d4cf357151cbe) --- src/wl_window.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 690e69e2..3ac00fbd 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1725,10 +1725,6 @@ static void dataSourceHandleSend(void* userData, const char* mimeType, int fd) { - char* string = _glfw.wl.clipboardString; - size_t len = strlen(string); - int ret; - if (_glfw.wl.selectionSource != source) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -1737,6 +1733,7 @@ static void dataSourceHandleSend(void* userData, return; } + char* string = _glfw.wl.clipboardString; if (!string) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -1753,22 +1750,26 @@ static void dataSourceHandleSend(void* userData, return; } - while (len > 0) + size_t length = strlen(string); + + while (length > 0) { - ret = write(fd, string, len); - if (ret == -1 && errno == EINTR) - continue; - if (ret == -1) + const ssize_t result = write(fd, string, length); + if (result == -1) { + if (errno == EINTR) + continue; + _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Error while writing the clipboard: %s", strerror(errno)); - close(fd); - return; + break; } - len -= ret; - string += ret; + + length -= result; + string += result; } + close(fd); } From 9e852ec39e504e2280afc4db893a5731f3abfb72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 20:45:00 +0100 Subject: [PATCH 028/207] Wayland: Remove error reporting of external bugs Not sure that GLFW should be reporting that another client has made an invalid receive request. (cherry picked from commit 8d216054ad89ecd1030fe066a42d80a9d2765216) --- src/wl_window.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 3ac00fbd..da7b271e 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1725,10 +1725,10 @@ static void dataSourceHandleSend(void* userData, const char* mimeType, int fd) { - if (_glfw.wl.selectionSource != source) + // Ignore it if this is an outdated or invalid request + if (_glfw.wl.selectionSource != source || + strcmp(mimeType, "text/plain;charset=utf-8") != 0) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Unknown clipboard data source"); close(fd); return; } @@ -1742,14 +1742,6 @@ static void dataSourceHandleSend(void* userData, return; } - if (strcmp(mimeType, "text/plain;charset=utf-8") != 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Wrong MIME type asked from clipboard"); - close(fd); - return; - } - size_t length = strlen(string); while (length > 0) @@ -1779,11 +1771,7 @@ static void dataSourceHandleCancelled(void* userData, wl_data_source_destroy(source); if (_glfw.wl.selectionSource != source) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Unknown clipboard data source"); return; - } _glfw.wl.selectionSource = NULL; } From c0c0d172a1958bd962e67fb295bc4e7dd1b08db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 24 Mar 2022 21:24:34 +0100 Subject: [PATCH 029/207] Wayland: Remove check for error that cannot happen Famous last words. (cherry picked from commit 967282c2e664ccaaa074590491108d9100b51123) --- src/wl_window.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index da7b271e..2c367ace 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1734,14 +1734,6 @@ static void dataSourceHandleSend(void* userData, } char* string = _glfw.wl.clipboardString; - if (!string) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Copy requested from an invalid string"); - close(fd); - return; - } - size_t length = strlen(string); while (length > 0) From 4d0e98d90c65945a14658f632dbb1f51c71cb69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 9 Jun 2022 19:26:42 +0200 Subject: [PATCH 030/207] Wayland: Move window related code to window module The Wayland backend was the only one where half the window and input related code was in the init module. As those bits want to share more utility code with the window module, the interface between them grows. To prevent that, this gathers nearly all window and input related code into the window module. This is adapted to 3.3-stable from b7a3af9b795912d80f9efc57bbaa0977acaee4a9. --- src/wl_init.c | 774 +-------------------------------------------- src/wl_platform.h | 3 + src/wl_window.c | 780 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 785 insertions(+), 772 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 3ee46825..3e1e3faa 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -30,7 +30,6 @@ #include "internal.h" -#include #include #include #include @@ -42,775 +41,6 @@ #include #include - -static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, - int* which) -{ - int focus; - _GLFWwindow* window = _glfw.windowListHead; - if (!which) - which = &focus; - while (window) - { - if (surface == window->wl.decorations.top.surface) - { - *which = topDecoration; - break; - } - if (surface == window->wl.decorations.left.surface) - { - *which = leftDecoration; - break; - } - if (surface == window->wl.decorations.right.surface) - { - *which = rightDecoration; - break; - } - if (surface == window->wl.decorations.bottom.surface) - { - *which = bottomDecoration; - break; - } - window = window->next; - } - return window; -} - -static void pointerHandleEnter(void* userData, - struct wl_pointer* pointer, - uint32_t serial, - struct wl_surface* surface, - wl_fixed_t sx, - wl_fixed_t sy) -{ - // Happens in the case we just destroyed the surface. - if (!surface) - return; - - int focus = 0; - _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, &focus); - if (!window) - return; - } - - window->wl.decorations.focus = focus; - _glfw.wl.serial = serial; - _glfw.wl.pointerEnterSerial = serial; - _glfw.wl.pointerFocus = window; - - window->wl.hovered = GLFW_TRUE; - - _glfwPlatformSetCursor(window, window->wl.currentCursor); - _glfwInputCursorEnter(window, GLFW_TRUE); -} - -static void pointerHandleLeave(void* userData, - struct wl_pointer* pointer, - uint32_t serial, - struct wl_surface* surface) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - - if (!window) - return; - - window->wl.hovered = GLFW_FALSE; - - _glfw.wl.serial = serial; - _glfw.wl.pointerFocus = NULL; - _glfwInputCursorEnter(window, GLFW_FALSE); - _glfw.wl.cursorPreviousName = NULL; -} - -static void setCursor(_GLFWwindow* window, const char* name) -{ - struct wl_buffer* buffer; - struct wl_cursor* cursor; - struct wl_cursor_image* image; - struct wl_surface* surface = _glfw.wl.cursorSurface; - struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; - int scale = 1; - - if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI) - { - // We only support up to scale=2 for now, since libwayland-cursor - // requires us to load a different theme for each size. - scale = 2; - theme = _glfw.wl.cursorThemeHiDPI; - } - - cursor = wl_cursor_theme_get_cursor(theme, name); - if (!cursor) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Standard cursor shape unavailable"); - return; - } - // TODO: handle animated cursors too. - image = cursor->images[0]; - - if (!image) - return; - - buffer = wl_cursor_image_get_buffer(image); - if (!buffer) - return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, - surface, - image->hotspot_x / scale, - image->hotspot_y / scale); - wl_surface_set_buffer_scale(surface, scale); - wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); - wl_surface_commit(surface); - _glfw.wl.cursorPreviousName = name; -} - -static void pointerHandleMotion(void* userData, - struct wl_pointer* pointer, - uint32_t time, - wl_fixed_t sx, - wl_fixed_t sy) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - const char* cursorName = NULL; - double x, y; - - if (!window) - return; - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - return; - x = wl_fixed_to_double(sx); - y = wl_fixed_to_double(sy); - window->wl.cursorPosX = x; - window->wl.cursorPosY = y; - - switch (window->wl.decorations.focus) - { - case mainWindow: - _glfwInputCursorPos(window, x, y); - _glfw.wl.cursorPreviousName = NULL; - return; - case topDecoration: - if (y < _GLFW_DECORATION_WIDTH) - cursorName = "n-resize"; - else - cursorName = "left_ptr"; - break; - case leftDecoration: - if (y < _GLFW_DECORATION_WIDTH) - cursorName = "nw-resize"; - else - cursorName = "w-resize"; - break; - case rightDecoration: - if (y < _GLFW_DECORATION_WIDTH) - cursorName = "ne-resize"; - else - cursorName = "e-resize"; - break; - case bottomDecoration: - if (x < _GLFW_DECORATION_WIDTH) - cursorName = "sw-resize"; - else if (x > window->wl.width + _GLFW_DECORATION_WIDTH) - cursorName = "se-resize"; - else - cursorName = "s-resize"; - break; - default: - assert(0); - } - if (_glfw.wl.cursorPreviousName != cursorName) - setCursor(window, cursorName); -} - -static void pointerHandleButton(void* userData, - struct wl_pointer* pointer, - uint32_t serial, - uint32_t time, - uint32_t button, - uint32_t state) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - int glfwButton; - - // Both xdg-shell and wl_shell use the same values. - uint32_t edges = WL_SHELL_SURFACE_RESIZE_NONE; - - if (!window) - return; - if (button == BTN_LEFT) - { - switch (window->wl.decorations.focus) - { - case mainWindow: - break; - case topDecoration: - if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_TOP; - else - { - if (window->wl.xdg.toplevel) - xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); - else - wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, serial); - } - break; - case leftDecoration: - if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_TOP_LEFT; - else - edges = WL_SHELL_SURFACE_RESIZE_LEFT; - break; - case rightDecoration: - if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_TOP_RIGHT; - else - edges = WL_SHELL_SURFACE_RESIZE_RIGHT; - break; - case bottomDecoration: - if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT; - else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT; - else - edges = WL_SHELL_SURFACE_RESIZE_BOTTOM; - break; - default: - assert(0); - } - if (edges != WL_SHELL_SURFACE_RESIZE_NONE) - { - if (window->wl.xdg.toplevel) - xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, - serial, edges); - else - wl_shell_surface_resize(window->wl.shellSurface, _glfw.wl.seat, - serial, edges); - return; - } - } - else if (button == BTN_RIGHT) - { - if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel) - { - xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, - _glfw.wl.seat, serial, - window->wl.cursorPosX, - window->wl.cursorPosY); - return; - } - } - - // Don’t pass the button to the user if it was related to a decoration. - if (window->wl.decorations.focus != mainWindow) - return; - - _glfw.wl.serial = serial; - - /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev - * codes. */ - glfwButton = button - BTN_LEFT; - - _glfwInputMouseClick(window, - glfwButton, - state == WL_POINTER_BUTTON_STATE_PRESSED - ? GLFW_PRESS - : GLFW_RELEASE, - _glfw.wl.xkb.modifiers); -} - -static void pointerHandleAxis(void* userData, - struct wl_pointer* pointer, - uint32_t time, - uint32_t axis, - wl_fixed_t value) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - double x = 0.0, y = 0.0; - // Wayland scroll events are in pointer motion coordinate space (think two - // finger scroll). The factor 10 is commonly used to convert to "scroll - // step means 1.0. - const double scrollFactor = 1.0 / 10.0; - - if (!window) - return; - - assert(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL || - axis == WL_POINTER_AXIS_VERTICAL_SCROLL); - - if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) - x = -wl_fixed_to_double(value) * scrollFactor; - else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) - y = -wl_fixed_to_double(value) * scrollFactor; - - _glfwInputScroll(window, x, y); -} - -static const struct wl_pointer_listener pointerListener = { - pointerHandleEnter, - pointerHandleLeave, - pointerHandleMotion, - pointerHandleButton, - pointerHandleAxis, -}; - -static void keyboardHandleKeymap(void* userData, - struct wl_keyboard* keyboard, - uint32_t format, - int fd, - uint32_t size) -{ - struct xkb_keymap* keymap; - struct xkb_state* state; - struct xkb_compose_table* composeTable; - struct xkb_compose_state* composeState; - char* mapStr; - const char* locale; - - if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) - { - close(fd); - return; - } - - mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - if (mapStr == MAP_FAILED) { - close(fd); - return; - } - - keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context, - mapStr, - XKB_KEYMAP_FORMAT_TEXT_V1, - 0); - munmap(mapStr, size); - close(fd); - - if (!keymap) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to compile keymap"); - return; - } - - state = xkb_state_new(keymap); - if (!state) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to create XKB state"); - xkb_keymap_unref(keymap); - return; - } - - // Look up the preferred locale, falling back to "C" as default. - locale = getenv("LC_ALL"); - if (!locale) - locale = getenv("LC_CTYPE"); - if (!locale) - locale = getenv("LANG"); - if (!locale) - locale = "C"; - - composeTable = - xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale, - XKB_COMPOSE_COMPILE_NO_FLAGS); - if (composeTable) - { - composeState = - xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS); - xkb_compose_table_unref(composeTable); - if (composeState) - _glfw.wl.xkb.composeState = composeState; - else - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to create XKB compose state"); - } - else - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to create XKB compose table"); - } - - xkb_keymap_unref(_glfw.wl.xkb.keymap); - xkb_state_unref(_glfw.wl.xkb.state); - _glfw.wl.xkb.keymap = keymap; - _glfw.wl.xkb.state = state; - - _glfw.wl.xkb.controlMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control"); - _glfw.wl.xkb.altMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1"); - _glfw.wl.xkb.shiftMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift"); - _glfw.wl.xkb.superMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4"); - _glfw.wl.xkb.capsLockMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock"); - _glfw.wl.xkb.numLockMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2"); -} - -static void keyboardHandleEnter(void* userData, - struct wl_keyboard* keyboard, - uint32_t serial, - struct wl_surface* surface, - struct wl_array* keys) -{ - // Happens in the case we just destroyed the surface. - if (!surface) - return; - - _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, NULL); - if (!window) - return; - } - - _glfw.wl.serial = serial; - _glfw.wl.keyboardFocus = window; - _glfwInputWindowFocus(window, GLFW_TRUE); -} - -static void keyboardHandleLeave(void* userData, - struct wl_keyboard* keyboard, - uint32_t serial, - struct wl_surface* surface) -{ - _GLFWwindow* window = _glfw.wl.keyboardFocus; - - if (!window) - return; - - struct itimerspec timer = {}; - timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); - - _glfw.wl.serial = serial; - _glfw.wl.keyboardFocus = NULL; - _glfwInputWindowFocus(window, GLFW_FALSE); -} - -static int translateKey(uint32_t scancode) -{ - if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) - return _glfw.wl.keycodes[scancode]; - - return GLFW_KEY_UNKNOWN; -} - -static xkb_keysym_t composeSymbol(xkb_keysym_t sym) -{ - if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState) - return sym; - if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym) - != XKB_COMPOSE_FEED_ACCEPTED) - return sym; - switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState)) - { - case XKB_COMPOSE_COMPOSED: - return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState); - case XKB_COMPOSE_COMPOSING: - case XKB_COMPOSE_CANCELLED: - return XKB_KEY_NoSymbol; - case XKB_COMPOSE_NOTHING: - default: - return sym; - } -} - -GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode) -{ - const xkb_keysym_t* keysyms; - const xkb_keycode_t keycode = scancode + 8; - - if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) - { - const xkb_keysym_t keysym = composeSymbol(keysyms[0]); - const uint32_t codepoint = _glfwKeySym2Unicode(keysym); - if (codepoint != GLFW_INVALID_CODEPOINT) - { - const int mods = _glfw.wl.xkb.modifiers; - const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); - _glfwInputChar(window, codepoint, mods, plain); - } - } - - return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); -} - -static void keyboardHandleKey(void* userData, - struct wl_keyboard* keyboard, - uint32_t serial, - uint32_t time, - uint32_t scancode, - uint32_t state) -{ - _GLFWwindow* window = _glfw.wl.keyboardFocus; - if (!window) - return; - - const int key = translateKey(scancode); - const int action = - state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; - - _glfw.wl.serial = serial; - _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); - - struct itimerspec timer = {}; - - if (action == GLFW_PRESS) - { - const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode); - - if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) - { - _glfw.wl.keyboardLastKey = key; - _glfw.wl.keyboardLastScancode = scancode; - if (_glfw.wl.keyboardRepeatRate > 1) - timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate; - else - timer.it_interval.tv_sec = 1; - - timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000; - timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000; - } - } - - timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); -} - -static void keyboardHandleModifiers(void* userData, - struct wl_keyboard* keyboard, - uint32_t serial, - uint32_t modsDepressed, - uint32_t modsLatched, - uint32_t modsLocked, - uint32_t group) -{ - _glfw.wl.serial = serial; - - if (!_glfw.wl.xkb.keymap) - return; - - xkb_state_update_mask(_glfw.wl.xkb.state, - modsDepressed, - modsLatched, - modsLocked, - 0, - 0, - group); - - const xkb_mod_mask_t mask = - xkb_state_serialize_mods(_glfw.wl.xkb.state, - XKB_STATE_MODS_DEPRESSED | - XKB_STATE_LAYOUT_DEPRESSED | - XKB_STATE_MODS_LATCHED | - XKB_STATE_LAYOUT_LATCHED); - - unsigned int mods = 0; - - if (mask & _glfw.wl.xkb.controlMask) - mods |= GLFW_MOD_CONTROL; - if (mask & _glfw.wl.xkb.altMask) - mods |= GLFW_MOD_ALT; - if (mask & _glfw.wl.xkb.shiftMask) - mods |= GLFW_MOD_SHIFT; - if (mask & _glfw.wl.xkb.superMask) - mods |= GLFW_MOD_SUPER; - if (mask & _glfw.wl.xkb.capsLockMask) - mods |= GLFW_MOD_CAPS_LOCK; - if (mask & _glfw.wl.xkb.numLockMask) - mods |= GLFW_MOD_NUM_LOCK; - - _glfw.wl.xkb.modifiers = mods; -} - -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION -static void keyboardHandleRepeatInfo(void* userData, - struct wl_keyboard* keyboard, - int32_t rate, - int32_t delay) -{ - if (keyboard != _glfw.wl.keyboard) - return; - - _glfw.wl.keyboardRepeatRate = rate; - _glfw.wl.keyboardRepeatDelay = delay; -} -#endif - -static const struct wl_keyboard_listener keyboardListener = { - keyboardHandleKeymap, - keyboardHandleEnter, - keyboardHandleLeave, - keyboardHandleKey, - keyboardHandleModifiers, -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION - keyboardHandleRepeatInfo, -#endif -}; - -static void seatHandleCapabilities(void* userData, - struct wl_seat* seat, - enum wl_seat_capability caps) -{ - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer) - { - _glfw.wl.pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL); - } - else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer) - { - wl_pointer_destroy(_glfw.wl.pointer); - _glfw.wl.pointer = NULL; - } - - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard) - { - _glfw.wl.keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL); - } - else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard) - { - wl_keyboard_destroy(_glfw.wl.keyboard); - _glfw.wl.keyboard = NULL; - } -} - -static void seatHandleName(void* userData, - struct wl_seat* seat, - const char* name) -{ -} - -static const struct wl_seat_listener seatListener = { - seatHandleCapabilities, - seatHandleName, -}; - -static void dataOfferHandleOffer(void* userData, - struct wl_data_offer* offer, - const char* mimeType) -{ - for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) - { - if (_glfw.wl.offers[i].offer == offer) - { - if (strcmp(mimeType, "text/plain;charset=utf-8") == 0) - _glfw.wl.offers[i].text_plain_utf8 = GLFW_TRUE; - - break; - } - } -} - -static const struct wl_data_offer_listener dataOfferListener = { - dataOfferHandleOffer, -}; - -static void dataDeviceHandleDataOffer(void* userData, - struct wl_data_device* device, - struct wl_data_offer* offer) -{ - _GLFWofferWayland* offers = - realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1); - if (!offers) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); - return; - } - - _glfw.wl.offers = offers; - _glfw.wl.offerCount++; - - _glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { offer }; - wl_data_offer_add_listener(offer, &dataOfferListener, NULL); -} - -static void dataDeviceHandleEnter(void* userData, - struct wl_data_device* device, - uint32_t serial, - struct wl_surface* surface, - wl_fixed_t x, - wl_fixed_t y, - struct wl_data_offer* offer) -{ - for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) - { - if (_glfw.wl.offers[i].offer == offer) - { - _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; - _glfw.wl.offerCount--; - - // We don't yet handle drag and drop - wl_data_offer_accept(offer, serial, NULL); - wl_data_offer_destroy(offer); - break; - } - } -} - -static void dataDeviceHandleLeave(void* userData, - struct wl_data_device* device) -{ -} - -static void dataDeviceHandleMotion(void* userData, - struct wl_data_device* device, - uint32_t time, - wl_fixed_t x, - wl_fixed_t y) -{ -} - -static void dataDeviceHandleDrop(void* userData, - struct wl_data_device* device) -{ -} - -static void dataDeviceHandleSelection(void* userData, - struct wl_data_device* device, - struct wl_data_offer* offer) -{ - if (_glfw.wl.selectionOffer) - { - wl_data_offer_destroy(_glfw.wl.selectionOffer); - _glfw.wl.selectionOffer = NULL; - } - - for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) - { - if (_glfw.wl.offers[i].offer == offer) - { - if (_glfw.wl.offers[i].text_plain_utf8) - _glfw.wl.selectionOffer = offer; - else - wl_data_offer_destroy(offer); - - _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; - _glfw.wl.offerCount--; - break; - } - } -} - -static const struct wl_data_device_listener dataDeviceListener = { - dataDeviceHandleDataOffer, - dataDeviceHandleEnter, - dataDeviceHandleLeave, - dataDeviceHandleMotion, - dataDeviceHandleDrop, - dataDeviceHandleSelection, -}; - static void wmBaseHandlePing(void* userData, struct xdg_wm_base* wmBase, uint32_t serial) @@ -862,7 +92,7 @@ static void registryHandleGlobal(void* userData, _glfw.wl.seat = wl_registry_bind(registry, name, &wl_seat_interface, _glfw.wl.seatVersion); - wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL); + _glfwAddSeatListenerWayland(_glfw.wl.seat); } } else if (strcmp(interface, "wl_data_device_manager") == 0) @@ -1240,7 +470,7 @@ int _glfwPlatformInit(void) _glfw.wl.dataDevice = wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager, _glfw.wl.seat); - wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL); + _glfwAddDataDeviceListenerWayland(_glfw.wl.dataDevice); } return GLFW_TRUE; diff --git a/src/wl_platform.h b/src/wl_platform.h index 4b97813b..080f8e4a 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -359,3 +359,6 @@ typedef struct _GLFWcursorWayland void _glfwAddOutputWayland(uint32_t name, uint32_t version); GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode); +void _glfwAddSeatListenerWayland(struct wl_seat* seat); +void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device); + diff --git a/src/wl_window.c b/src/wl_window.c index 2c367ace..cc8fd35f 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -974,6 +975,774 @@ static void handleEvents(double* timeout) } } +static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, + int* which) +{ + int focus; + _GLFWwindow* window = _glfw.windowListHead; + if (!which) + which = &focus; + while (window) + { + if (surface == window->wl.decorations.top.surface) + { + *which = topDecoration; + break; + } + if (surface == window->wl.decorations.left.surface) + { + *which = leftDecoration; + break; + } + if (surface == window->wl.decorations.right.surface) + { + *which = rightDecoration; + break; + } + if (surface == window->wl.decorations.bottom.surface) + { + *which = bottomDecoration; + break; + } + window = window->next; + } + return window; +} + +static void pointerHandleEnter(void* userData, + struct wl_pointer* pointer, + uint32_t serial, + struct wl_surface* surface, + wl_fixed_t sx, + wl_fixed_t sy) +{ + // Happens in the case we just destroyed the surface. + if (!surface) + return; + + int focus = 0; + _GLFWwindow* window = wl_surface_get_user_data(surface); + if (!window) + { + window = findWindowFromDecorationSurface(surface, &focus); + if (!window) + return; + } + + window->wl.decorations.focus = focus; + _glfw.wl.serial = serial; + _glfw.wl.pointerEnterSerial = serial; + _glfw.wl.pointerFocus = window; + + window->wl.hovered = GLFW_TRUE; + + _glfwPlatformSetCursor(window, window->wl.currentCursor); + _glfwInputCursorEnter(window, GLFW_TRUE); +} + +static void pointerHandleLeave(void* userData, + struct wl_pointer* pointer, + uint32_t serial, + struct wl_surface* surface) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + + if (!window) + return; + + window->wl.hovered = GLFW_FALSE; + + _glfw.wl.serial = serial; + _glfw.wl.pointerFocus = NULL; + _glfwInputCursorEnter(window, GLFW_FALSE); + _glfw.wl.cursorPreviousName = NULL; +} + +static void setCursor(_GLFWwindow* window, const char* name) +{ + struct wl_buffer* buffer; + struct wl_cursor* cursor; + struct wl_cursor_image* image; + struct wl_surface* surface = _glfw.wl.cursorSurface; + struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; + int scale = 1; + + if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI) + { + // We only support up to scale=2 for now, since libwayland-cursor + // requires us to load a different theme for each size. + scale = 2; + theme = _glfw.wl.cursorThemeHiDPI; + } + + cursor = wl_cursor_theme_get_cursor(theme, name); + if (!cursor) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Standard cursor shape unavailable"); + return; + } + // TODO: handle animated cursors too. + image = cursor->images[0]; + + if (!image) + return; + + buffer = wl_cursor_image_get_buffer(image); + if (!buffer) + return; + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, + surface, + image->hotspot_x / scale, + image->hotspot_y / scale); + wl_surface_set_buffer_scale(surface, scale); + wl_surface_attach(surface, buffer, 0, 0); + wl_surface_damage(surface, 0, 0, + image->width, image->height); + wl_surface_commit(surface); + _glfw.wl.cursorPreviousName = name; +} + +static void pointerHandleMotion(void* userData, + struct wl_pointer* pointer, + uint32_t time, + wl_fixed_t sx, + wl_fixed_t sy) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + const char* cursorName = NULL; + double x, y; + + if (!window) + return; + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + return; + x = wl_fixed_to_double(sx); + y = wl_fixed_to_double(sy); + window->wl.cursorPosX = x; + window->wl.cursorPosY = y; + + switch (window->wl.decorations.focus) + { + case mainWindow: + _glfwInputCursorPos(window, x, y); + _glfw.wl.cursorPreviousName = NULL; + return; + case topDecoration: + if (y < _GLFW_DECORATION_WIDTH) + cursorName = "n-resize"; + else + cursorName = "left_ptr"; + break; + case leftDecoration: + if (y < _GLFW_DECORATION_WIDTH) + cursorName = "nw-resize"; + else + cursorName = "w-resize"; + break; + case rightDecoration: + if (y < _GLFW_DECORATION_WIDTH) + cursorName = "ne-resize"; + else + cursorName = "e-resize"; + break; + case bottomDecoration: + if (x < _GLFW_DECORATION_WIDTH) + cursorName = "sw-resize"; + else if (x > window->wl.width + _GLFW_DECORATION_WIDTH) + cursorName = "se-resize"; + else + cursorName = "s-resize"; + break; + default: + assert(0); + } + if (_glfw.wl.cursorPreviousName != cursorName) + setCursor(window, cursorName); +} + +static void pointerHandleButton(void* userData, + struct wl_pointer* pointer, + uint32_t serial, + uint32_t time, + uint32_t button, + uint32_t state) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + int glfwButton; + + // Both xdg-shell and wl_shell use the same values. + uint32_t edges = WL_SHELL_SURFACE_RESIZE_NONE; + + if (!window) + return; + if (button == BTN_LEFT) + { + switch (window->wl.decorations.focus) + { + case mainWindow: + break; + case topDecoration: + if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) + edges = WL_SHELL_SURFACE_RESIZE_TOP; + else + { + if (window->wl.xdg.toplevel) + xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); + else + wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, serial); + } + break; + case leftDecoration: + if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) + edges = WL_SHELL_SURFACE_RESIZE_TOP_LEFT; + else + edges = WL_SHELL_SURFACE_RESIZE_LEFT; + break; + case rightDecoration: + if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) + edges = WL_SHELL_SURFACE_RESIZE_TOP_RIGHT; + else + edges = WL_SHELL_SURFACE_RESIZE_RIGHT; + break; + case bottomDecoration: + if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH) + edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT; + else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH) + edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT; + else + edges = WL_SHELL_SURFACE_RESIZE_BOTTOM; + break; + default: + assert(0); + } + if (edges != WL_SHELL_SURFACE_RESIZE_NONE) + { + if (window->wl.xdg.toplevel) + xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, + serial, edges); + else + wl_shell_surface_resize(window->wl.shellSurface, _glfw.wl.seat, + serial, edges); + return; + } + } + else if (button == BTN_RIGHT) + { + if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel) + { + xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, + _glfw.wl.seat, serial, + window->wl.cursorPosX, + window->wl.cursorPosY); + return; + } + } + + // Don’t pass the button to the user if it was related to a decoration. + if (window->wl.decorations.focus != mainWindow) + return; + + _glfw.wl.serial = serial; + + /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev + * codes. */ + glfwButton = button - BTN_LEFT; + + _glfwInputMouseClick(window, + glfwButton, + state == WL_POINTER_BUTTON_STATE_PRESSED + ? GLFW_PRESS + : GLFW_RELEASE, + _glfw.wl.xkb.modifiers); +} + +static void pointerHandleAxis(void* userData, + struct wl_pointer* pointer, + uint32_t time, + uint32_t axis, + wl_fixed_t value) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + double x = 0.0, y = 0.0; + // Wayland scroll events are in pointer motion coordinate space (think two + // finger scroll). The factor 10 is commonly used to convert to "scroll + // step means 1.0. + const double scrollFactor = 1.0 / 10.0; + + if (!window) + return; + + assert(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL || + axis == WL_POINTER_AXIS_VERTICAL_SCROLL); + + if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) + x = -wl_fixed_to_double(value) * scrollFactor; + else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) + y = -wl_fixed_to_double(value) * scrollFactor; + + _glfwInputScroll(window, x, y); +} + +static const struct wl_pointer_listener pointerListener = { + pointerHandleEnter, + pointerHandleLeave, + pointerHandleMotion, + pointerHandleButton, + pointerHandleAxis, +}; + +static void keyboardHandleKeymap(void* userData, + struct wl_keyboard* keyboard, + uint32_t format, + int fd, + uint32_t size) +{ + struct xkb_keymap* keymap; + struct xkb_state* state; + struct xkb_compose_table* composeTable; + struct xkb_compose_state* composeState; + char* mapStr; + const char* locale; + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) + { + close(fd); + return; + } + + mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (mapStr == MAP_FAILED) { + close(fd); + return; + } + + keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context, + mapStr, + XKB_KEYMAP_FORMAT_TEXT_V1, + 0); + munmap(mapStr, size); + close(fd); + + if (!keymap) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to compile keymap"); + return; + } + + state = xkb_state_new(keymap); + if (!state) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create XKB state"); + xkb_keymap_unref(keymap); + return; + } + + // Look up the preferred locale, falling back to "C" as default. + locale = getenv("LC_ALL"); + if (!locale) + locale = getenv("LC_CTYPE"); + if (!locale) + locale = getenv("LANG"); + if (!locale) + locale = "C"; + + composeTable = + xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale, + XKB_COMPOSE_COMPILE_NO_FLAGS); + if (composeTable) + { + composeState = + xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS); + xkb_compose_table_unref(composeTable); + if (composeState) + _glfw.wl.xkb.composeState = composeState; + else + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create XKB compose state"); + } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create XKB compose table"); + } + + xkb_keymap_unref(_glfw.wl.xkb.keymap); + xkb_state_unref(_glfw.wl.xkb.state); + _glfw.wl.xkb.keymap = keymap; + _glfw.wl.xkb.state = state; + + _glfw.wl.xkb.controlMask = + 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control"); + _glfw.wl.xkb.altMask = + 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1"); + _glfw.wl.xkb.shiftMask = + 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift"); + _glfw.wl.xkb.superMask = + 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4"); + _glfw.wl.xkb.capsLockMask = + 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock"); + _glfw.wl.xkb.numLockMask = + 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2"); +} + +static void keyboardHandleEnter(void* userData, + struct wl_keyboard* keyboard, + uint32_t serial, + struct wl_surface* surface, + struct wl_array* keys) +{ + // Happens in the case we just destroyed the surface. + if (!surface) + return; + + _GLFWwindow* window = wl_surface_get_user_data(surface); + if (!window) + { + window = findWindowFromDecorationSurface(surface, NULL); + if (!window) + return; + } + + _glfw.wl.serial = serial; + _glfw.wl.keyboardFocus = window; + _glfwInputWindowFocus(window, GLFW_TRUE); +} + +static void keyboardHandleLeave(void* userData, + struct wl_keyboard* keyboard, + uint32_t serial, + struct wl_surface* surface) +{ + _GLFWwindow* window = _glfw.wl.keyboardFocus; + + if (!window) + return; + + struct itimerspec timer = {}; + timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); + + _glfw.wl.serial = serial; + _glfw.wl.keyboardFocus = NULL; + _glfwInputWindowFocus(window, GLFW_FALSE); +} + +static int translateKey(uint32_t scancode) +{ + if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) + return _glfw.wl.keycodes[scancode]; + + return GLFW_KEY_UNKNOWN; +} + +static xkb_keysym_t composeSymbol(xkb_keysym_t sym) +{ + if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState) + return sym; + if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym) + != XKB_COMPOSE_FEED_ACCEPTED) + return sym; + switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState)) + { + case XKB_COMPOSE_COMPOSED: + return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState); + case XKB_COMPOSE_COMPOSING: + case XKB_COMPOSE_CANCELLED: + return XKB_KEY_NoSymbol; + case XKB_COMPOSE_NOTHING: + default: + return sym; + } +} + +GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode) +{ + const xkb_keysym_t* keysyms; + const xkb_keycode_t keycode = scancode + 8; + + if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) + { + const xkb_keysym_t keysym = composeSymbol(keysyms[0]); + const uint32_t codepoint = _glfwKeySym2Unicode(keysym); + if (codepoint != GLFW_INVALID_CODEPOINT) + { + const int mods = _glfw.wl.xkb.modifiers; + const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); + _glfwInputChar(window, codepoint, mods, plain); + } + } + + return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); +} + +static void keyboardHandleKey(void* userData, + struct wl_keyboard* keyboard, + uint32_t serial, + uint32_t time, + uint32_t scancode, + uint32_t state) +{ + _GLFWwindow* window = _glfw.wl.keyboardFocus; + if (!window) + return; + + const int key = translateKey(scancode); + const int action = + state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; + + _glfw.wl.serial = serial; + _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); + + struct itimerspec timer = {}; + + if (action == GLFW_PRESS) + { + const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode); + + if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) + { + _glfw.wl.keyboardLastKey = key; + _glfw.wl.keyboardLastScancode = scancode; + if (_glfw.wl.keyboardRepeatRate > 1) + timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate; + else + timer.it_interval.tv_sec = 1; + + timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000; + timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000; + } + } + + timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); +} + +static void keyboardHandleModifiers(void* userData, + struct wl_keyboard* keyboard, + uint32_t serial, + uint32_t modsDepressed, + uint32_t modsLatched, + uint32_t modsLocked, + uint32_t group) +{ + _glfw.wl.serial = serial; + + if (!_glfw.wl.xkb.keymap) + return; + + xkb_state_update_mask(_glfw.wl.xkb.state, + modsDepressed, + modsLatched, + modsLocked, + 0, + 0, + group); + + const xkb_mod_mask_t mask = + xkb_state_serialize_mods(_glfw.wl.xkb.state, + XKB_STATE_MODS_DEPRESSED | + XKB_STATE_LAYOUT_DEPRESSED | + XKB_STATE_MODS_LATCHED | + XKB_STATE_LAYOUT_LATCHED); + + unsigned int mods = 0; + + if (mask & _glfw.wl.xkb.controlMask) + mods |= GLFW_MOD_CONTROL; + if (mask & _glfw.wl.xkb.altMask) + mods |= GLFW_MOD_ALT; + if (mask & _glfw.wl.xkb.shiftMask) + mods |= GLFW_MOD_SHIFT; + if (mask & _glfw.wl.xkb.superMask) + mods |= GLFW_MOD_SUPER; + if (mask & _glfw.wl.xkb.capsLockMask) + mods |= GLFW_MOD_CAPS_LOCK; + if (mask & _glfw.wl.xkb.numLockMask) + mods |= GLFW_MOD_NUM_LOCK; + + _glfw.wl.xkb.modifiers = mods; +} + +#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION +static void keyboardHandleRepeatInfo(void* userData, + struct wl_keyboard* keyboard, + int32_t rate, + int32_t delay) +{ + if (keyboard != _glfw.wl.keyboard) + return; + + _glfw.wl.keyboardRepeatRate = rate; + _glfw.wl.keyboardRepeatDelay = delay; +} +#endif + +static const struct wl_keyboard_listener keyboardListener = { + keyboardHandleKeymap, + keyboardHandleEnter, + keyboardHandleLeave, + keyboardHandleKey, + keyboardHandleModifiers, +#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION + keyboardHandleRepeatInfo, +#endif +}; + +static void seatHandleCapabilities(void* userData, + struct wl_seat* seat, + enum wl_seat_capability caps) +{ + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer) + { + _glfw.wl.pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL); + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer) + { + wl_pointer_destroy(_glfw.wl.pointer); + _glfw.wl.pointer = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard) + { + _glfw.wl.keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL); + } + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard) + { + wl_keyboard_destroy(_glfw.wl.keyboard); + _glfw.wl.keyboard = NULL; + } +} + +static void seatHandleName(void* userData, + struct wl_seat* seat, + const char* name) +{ +} + +static const struct wl_seat_listener seatListener = { + seatHandleCapabilities, + seatHandleName, +}; + +static void dataOfferHandleOffer(void* userData, + struct wl_data_offer* offer, + const char* mimeType) +{ + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + { + if (_glfw.wl.offers[i].offer == offer) + { + if (strcmp(mimeType, "text/plain;charset=utf-8") == 0) + _glfw.wl.offers[i].text_plain_utf8 = GLFW_TRUE; + + break; + } + } +} + +static const struct wl_data_offer_listener dataOfferListener = { + dataOfferHandleOffer, +}; + +static void dataDeviceHandleDataOffer(void* userData, + struct wl_data_device* device, + struct wl_data_offer* offer) +{ + _GLFWofferWayland* offers = + realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1); + if (!offers) + { + _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); + return; + } + + _glfw.wl.offers = offers; + _glfw.wl.offerCount++; + + _glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { offer }; + wl_data_offer_add_listener(offer, &dataOfferListener, NULL); +} + +static void dataDeviceHandleEnter(void* userData, + struct wl_data_device* device, + uint32_t serial, + struct wl_surface* surface, + wl_fixed_t x, + wl_fixed_t y, + struct wl_data_offer* offer) +{ + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + { + if (_glfw.wl.offers[i].offer == offer) + { + _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; + _glfw.wl.offerCount--; + + // We don't yet handle drag and drop + wl_data_offer_accept(offer, serial, NULL); + wl_data_offer_destroy(offer); + break; + } + } +} + +static void dataDeviceHandleLeave(void* userData, + struct wl_data_device* device) +{ +} + +static void dataDeviceHandleMotion(void* userData, + struct wl_data_device* device, + uint32_t time, + wl_fixed_t x, + wl_fixed_t y) +{ +} + +static void dataDeviceHandleDrop(void* userData, + struct wl_data_device* device) +{ +} + +static void dataDeviceHandleSelection(void* userData, + struct wl_data_device* device, + struct wl_data_offer* offer) +{ + if (_glfw.wl.selectionOffer) + { + wl_data_offer_destroy(_glfw.wl.selectionOffer); + _glfw.wl.selectionOffer = NULL; + } + + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + { + if (_glfw.wl.offers[i].offer == offer) + { + if (_glfw.wl.offers[i].text_plain_utf8) + _glfw.wl.selectionOffer = offer; + else + wl_data_offer_destroy(offer); + + _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; + _glfw.wl.offerCount--; + break; + } + } +} + +static const struct wl_data_device_listener dataDeviceListener = { + dataDeviceHandleDataOffer, + dataDeviceHandleEnter, + dataDeviceHandleLeave, + dataDeviceHandleMotion, + dataDeviceHandleDrop, + dataDeviceHandleSelection, +}; + // Translates a GLFW standard cursor to a theme cursor name // static char *translateCursorShape(int shape) @@ -996,6 +1765,17 @@ static char *translateCursorShape(int shape) return NULL; } +void _glfwAddSeatListenerWayland(struct wl_seat* seat) +{ + wl_seat_add_listener(seat, &seatListener, NULL); +} + +void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device) +{ + wl_data_device_add_listener(device, &dataDeviceListener, NULL); +} + + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// From 50d5de7cd4dbe2d72ed5a5142ec138cbf7c12f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 29 Mar 2022 19:00:18 +0200 Subject: [PATCH 031/207] Wayland: Make data offer reading a generic utility This will be needed for drag and drop reception as well. (cherry picked from commit f010335b8cad7937397fcbfd252033899327b551) --- src/wl_platform.h | 1 - src/wl_window.c | 147 +++++++++++++++++++++++----------------------- 2 files changed, 73 insertions(+), 75 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 080f8e4a..afaf1ee5 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -266,7 +266,6 @@ typedef struct _GLFWlibraryWayland int keyboardLastKey; int keyboardLastScancode; char* clipboardString; - size_t clipboardSize; int timerfd; short int keycodes[256]; short int scancodes[GLFW_KEY_LAST + 1]; diff --git a/src/wl_window.c b/src/wl_window.c index cc8fd35f..031943b7 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -975,6 +975,70 @@ static void handleEvents(double* timeout) } } +// Reads the specified data offer as the specified MIME type +// +static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mimeType) +{ + int fds[2]; + + if (pipe2(fds, O_CLOEXEC) == -1) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create pipe for data offer: %s", + strerror(errno)); + return NULL; + } + + wl_data_offer_receive(offer, mimeType, fds[1]); + flushDisplay(); + close(fds[1]); + + char* string = NULL; + size_t size = 0; + size_t length = 0; + + for (;;) + { + const size_t readSize = 4096; + const size_t requiredSize = length + readSize + 1; + if (requiredSize > size) + { + char* longer = realloc(string, requiredSize); + if (!longer) + { + _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); + close(fds[0]); + return NULL; + } + + string = longer; + size = requiredSize; + } + + const ssize_t result = read(fds[0], string + length, readSize); + if (result == 0) + break; + else if (result == -1) + { + if (errno == EINTR) + continue; + + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to read from data offer pipe: %s", + strerror(errno)); + close(fds[0]); + return NULL; + } + + length += result; + } + + close(fds[0]); + + string[length] = '\0'; + return string; +} + static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, int* which) { @@ -2562,23 +2626,15 @@ void _glfwPlatformSetClipboardString(const char* string) _glfw.wl.selectionSource = NULL; } - const size_t requiredSize = strlen(string) + 1; - if (requiredSize > _glfw.wl.clipboardSize) + char* copy = _glfw_strdup(string); + if (!copy) { - free(_glfw.wl.clipboardString); - _glfw.wl.clipboardString = calloc(requiredSize, 1); - if (!_glfw.wl.clipboardString) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, - "Wayland: Failed to allocate clipboard string"); - return; - } - - _glfw.wl.clipboardSize = requiredSize; + _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); + return; } - // The argument may be a substring of the clipboard string - memmove(_glfw.wl.clipboardString, string, requiredSize); + free(_glfw.wl.clipboardString); + _glfw.wl.clipboardString = copy; _glfw.wl.selectionSource = wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager); @@ -2609,66 +2665,9 @@ const char* _glfwPlatformGetClipboardString(void) if (_glfw.wl.selectionSource) return _glfw.wl.clipboardString; - int fds[2]; - - if (pipe2(fds, O_CLOEXEC) == -1) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to create clipboard pipe: %s", - strerror(errno)); - return NULL; - } - - wl_data_offer_receive(_glfw.wl.selectionOffer, "text/plain;charset=utf-8", fds[1]); - - flushDisplay(); - close(fds[1]); - - size_t length = 0; - - for (;;) - { - // Grow the clipboard if we need to paste something bigger, there is no - // shrink operation yet. - const size_t readSize = 4096; - const size_t requiredSize = length + readSize + 1; - if (requiredSize > _glfw.wl.clipboardSize) - { - char* string = realloc(_glfw.wl.clipboardString, requiredSize); - if (!string) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, - "Wayland: Failed to grow clipboard string"); - close(fds[0]); - return NULL; - } - - _glfw.wl.clipboardString = string; - _glfw.wl.clipboardSize = requiredSize; - } - - // Then read from the fd to the clipboard, handling all known errors. - const ssize_t result = read(fds[0], _glfw.wl.clipboardString + length, readSize); - if (result == 0) - break; - else if (result == -1) - { - if (errno == EINTR) - continue; - - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to read from clipboard pipe: %s", - strerror(errno)); - close(fds[0]); - return NULL; - } - - length += result; - } - - close(fds[0]); - - _glfw.wl.clipboardString[length] = '\0'; + free(_glfw.wl.clipboardString); + _glfw.wl.clipboardString = + readDataOfferAsString(_glfw.wl.selectionOffer, "text/plain;charset=utf-8"); return _glfw.wl.clipboardString; } From 2b504e41d54bc4f423aac380ee0ddce09ad9c9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 31 Mar 2022 22:17:08 +0200 Subject: [PATCH 032/207] Wayland: Clean up listener struct initialization Adapt style to match the rest of the project. (cherry picked from commit 0f38382e25f484a8da2660f606c30b32a51b600e) --- src/wl_init.c | 6 ++++-- src/wl_monitor.c | 3 ++- src/wl_window.c | 32 +++++++++++++++++++++----------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 3e1e3faa..df760524 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -48,7 +48,8 @@ static void wmBaseHandlePing(void* userData, xdg_wm_base_pong(wmBase, serial); } -static const struct xdg_wm_base_listener wmBaseListener = { +static const struct xdg_wm_base_listener wmBaseListener = +{ wmBaseHandlePing }; @@ -164,7 +165,8 @@ static void registryHandleGlobalRemove(void* userData, } -static const struct wl_registry_listener registryListener = { +static const struct wl_registry_listener registryListener = +{ registryHandleGlobal, registryHandleGlobalRemove }; diff --git a/src/wl_monitor.c b/src/wl_monitor.c index f4009c34..3c2ebc55 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -106,7 +106,8 @@ static void outputHandleScale(void* userData, monitor->wl.scale = factor; } -static const struct wl_output_listener outputListener = { +static const struct wl_output_listener outputListener = +{ outputHandleGeometry, outputHandleMode, outputHandleDone, diff --git a/src/wl_window.c b/src/wl_window.c index 031943b7..ab274996 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -392,7 +392,8 @@ static void xdgDecorationHandleConfigure(void* userData, createDecorations(window); } -static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = { +static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = +{ xdgDecorationHandleConfigure, }; @@ -676,7 +677,8 @@ static void xdgToplevelHandleClose(void* userData, _glfwInputWindowCloseRequest(window); } -static const struct xdg_toplevel_listener xdgToplevelListener = { +static const struct xdg_toplevel_listener xdgToplevelListener = +{ xdgToplevelHandleConfigure, xdgToplevelHandleClose }; @@ -1349,7 +1351,8 @@ static void pointerHandleAxis(void* userData, _glfwInputScroll(window, x, y); } -static const struct wl_pointer_listener pointerListener = { +static const struct wl_pointer_listener pointerListener = +{ pointerHandleEnter, pointerHandleLeave, pointerHandleMotion, @@ -1643,7 +1646,8 @@ static void keyboardHandleRepeatInfo(void* userData, } #endif -static const struct wl_keyboard_listener keyboardListener = { +static const struct wl_keyboard_listener keyboardListener = +{ keyboardHandleKeymap, keyboardHandleEnter, keyboardHandleLeave, @@ -1687,7 +1691,8 @@ static void seatHandleName(void* userData, { } -static const struct wl_seat_listener seatListener = { +static const struct wl_seat_listener seatListener = +{ seatHandleCapabilities, seatHandleName, }; @@ -1708,8 +1713,9 @@ static void dataOfferHandleOffer(void* userData, } } -static const struct wl_data_offer_listener dataOfferListener = { - dataOfferHandleOffer, +static const struct wl_data_offer_listener dataOfferListener = +{ + dataOfferHandleOffer }; static void dataDeviceHandleDataOffer(void* userData, @@ -1798,7 +1804,8 @@ static void dataDeviceHandleSelection(void* userData, } } -static const struct wl_data_device_listener dataDeviceListener = { +const struct wl_data_device_listener dataDeviceListener = +{ dataDeviceHandleDataOffer, dataDeviceHandleEnter, dataDeviceHandleLeave, @@ -2415,7 +2422,8 @@ static void relativePointerHandleRelativeMotion(void* userData, _glfwInputCursorPos(window, xpos, ypos); } -static const struct zwp_relative_pointer_v1_listener relativePointerListener = { +static const struct zwp_relative_pointer_v1_listener relativePointerListener = +{ relativePointerHandleRelativeMotion }; @@ -2445,7 +2453,8 @@ static void lockedPointerHandleUnlocked(void* userData, { } -static const struct zwp_locked_pointer_v1_listener lockedPointerListener = { +static const struct zwp_locked_pointer_v1_listener lockedPointerListener = +{ lockedPointerHandleLocked, lockedPointerHandleUnlocked }; @@ -2612,7 +2621,8 @@ static void dataSourceHandleCancelled(void* userData, _glfw.wl.selectionSource = NULL; } -static const struct wl_data_source_listener dataSourceListener = { +static const struct wl_data_source_listener dataSourceListener = +{ dataSourceHandleTarget, dataSourceHandleSend, dataSourceHandleCancelled, From 05422e2824c94358aae6fe1a4becedc0a654a150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 31 Mar 2022 19:56:48 +0200 Subject: [PATCH 033/207] Wayland: Add support for file drop events This adds support for file path drop events in text/uri-list format. It is based on work by Pilzschaf in #2040. Closes #2040 (cherry picked from commit 4cb36872a5fe448c205d0b46f0e8c8b57530cfe0) --- CONTRIBUTORS.md | 1 + README.md | 1 + src/wl_init.c | 2 ++ src/wl_platform.h | 5 +++++ src/wl_window.c | 57 +++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f346bffe..5a1b1dcb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -158,6 +158,7 @@ video tutorials. - Orson Peters - Emmanuel Gil Peyrot - Cyril Pichard + - Pilzschaf - Keith Pitt - Stanislav Podgorskiy - Konstantin Podsvirov diff --git a/README.md b/README.md index d97f71d6..8fea84b8 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ information on what to include when reporting a bug. match event scancode (#1993) - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) + - [Wayland] Added support for file path drop events (#2040) - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` - [Wayland] Bugfix: Data source creation error would cause double free at termination diff --git a/src/wl_init.c b/src/wl_init.c index df760524..ad10aa60 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -537,6 +537,8 @@ void _glfwPlatformTerminate(void) xdg_wm_base_destroy(_glfw.wl.wmBase); if (_glfw.wl.selectionOffer) wl_data_offer_destroy(_glfw.wl.selectionOffer); + if (_glfw.wl.dragOffer) + wl_data_offer_destroy(_glfw.wl.dragOffer); if (_glfw.wl.selectionSource) wl_data_source_destroy(_glfw.wl.selectionSource); if (_glfw.wl.dataDevice) diff --git a/src/wl_platform.h b/src/wl_platform.h index afaf1ee5..824efc72 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -171,6 +171,7 @@ typedef struct _GLFWofferWayland { struct wl_data_offer* offer; GLFWbool text_plain_utf8; + GLFWbool text_uri_list; } _GLFWofferWayland; // Wayland-specific per-window data @@ -250,6 +251,10 @@ typedef struct _GLFWlibraryWayland struct wl_data_offer* selectionOffer; struct wl_data_source* selectionSource; + struct wl_data_offer* dragOffer; + _GLFWwindow* dragFocus; + uint32_t dragSerial; + int compositorVersion; int seatVersion; diff --git a/src/wl_window.c b/src/wl_window.c index ab274996..b15fd16a 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1707,6 +1707,8 @@ static void dataOfferHandleOffer(void* userData, { if (strcmp(mimeType, "text/plain;charset=utf-8") == 0) _glfw.wl.offers[i].text_plain_utf8 = GLFW_TRUE; + else if (strcmp(mimeType, "text/uri-list") == 0) + _glfw.wl.offers[i].text_uri_list = GLFW_TRUE; break; } @@ -1745,24 +1747,53 @@ static void dataDeviceHandleEnter(void* userData, wl_fixed_t y, struct wl_data_offer* offer) { + if (_glfw.wl.dragOffer) + { + wl_data_offer_destroy(_glfw.wl.dragOffer); + _glfw.wl.dragOffer = NULL; + _glfw.wl.dragFocus = NULL; + } + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) { if (_glfw.wl.offers[i].offer == offer) { + _GLFWwindow* window = NULL; + + if (surface) + window = wl_surface_get_user_data(surface); + + if (window && _glfw.wl.offers[i].text_uri_list) + { + _glfw.wl.dragOffer = offer; + _glfw.wl.dragFocus = window; + _glfw.wl.dragSerial = serial; + } + _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; _glfw.wl.offerCount--; - - // We don't yet handle drag and drop - wl_data_offer_accept(offer, serial, NULL); - wl_data_offer_destroy(offer); break; } } + + if (_glfw.wl.dragOffer) + wl_data_offer_accept(offer, serial, "text/uri-list"); + else + { + wl_data_offer_accept(offer, serial, NULL); + wl_data_offer_destroy(offer); + } } static void dataDeviceHandleLeave(void* userData, struct wl_data_device* device) { + if (_glfw.wl.dragOffer) + { + wl_data_offer_destroy(_glfw.wl.dragOffer); + _glfw.wl.dragOffer = NULL; + _glfw.wl.dragFocus = NULL; + } } static void dataDeviceHandleMotion(void* userData, @@ -1776,6 +1807,24 @@ static void dataDeviceHandleMotion(void* userData, static void dataDeviceHandleDrop(void* userData, struct wl_data_device* device) { + if (!_glfw.wl.dragOffer) + return; + + char* string = readDataOfferAsString(_glfw.wl.dragOffer, "text/uri-list"); + if (string) + { + int count; + char** paths = _glfwParseUriList(string, &count); + if (paths) + _glfwInputDrop(_glfw.wl.dragFocus, count, (const char**) paths); + + for (int i = 0; i < count; i++) + free(paths[i]); + + free(paths); + } + + free(string); } static void dataDeviceHandleSelection(void* userData, From 4143d9622847105f67fac7aad41bdbba197c585f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 8 Apr 2022 18:22:39 +0200 Subject: [PATCH 034/207] Fix glfwMakeContextCurrent using uninitialized TLS Issue reported by danhambleton on the GLFW forum: https://discourse.glfw.org/t/posix-thread-local-storage-tls-error-when-making-context-current/2034 (cherry picked from commit f843d533335db275e0b014311cd7163a2a003b03) --- CONTRIBUTORS.md | 1 + README.md | 1 + src/context.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 5a1b1dcb..36a040e2 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -43,6 +43,7 @@ video tutorials. - Noel Cower - CuriouserThing - Jason Daly + - danhambleton - Jarrod Davis - Olivier Delannoy - Paul R. Deppe diff --git a/README.md b/README.md index 8fea84b8..1d16c6a4 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ information on what to include when reporting a bug. ## Changelog + - Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization - [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different scancode than `PrtSc` (#1993) - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not diff --git a/src/context.c b/src/context.c index b3c78e80..d86e0fae 100644 --- a/src/context.c +++ b/src/context.c @@ -609,10 +609,12 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot); + _GLFWwindow* previous; _GLFW_REQUIRE_INIT(); + previous = _glfwPlatformGetTls(&_glfw.contextSlot); + if (window && window->context.client == GLFW_NO_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, From af612103d035b5d99c1d45e3d7b430d3661d310c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Apr 2022 15:37:31 +0200 Subject: [PATCH 035/207] Fix order of error checks in glfwSetGammaRamp Initialization should be checked before arguments. (cherry picked from commit 29523dbfbfe097bec9ae3a5ec08b08915e1e4a59) --- README.md | 1 + src/monitor.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d16c6a4..524debe1 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ information on what to include when reporting a bug. ## Changelog - Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization + - Bugfix: `glfwSetGammaRamp` could emit `GLFW_INVALID_VALUE` before initialization - [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different scancode than `PrtSc` (#1993) - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not diff --git a/src/monitor.c b/src/monitor.c index 73411412..2601d11b 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -521,6 +521,8 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) assert(ramp->green != NULL); assert(ramp->blue != NULL); + _GLFW_REQUIRE_INIT(); + if (ramp->size <= 0) { _glfwInputError(GLFW_INVALID_VALUE, @@ -529,8 +531,6 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) return; } - _GLFW_REQUIRE_INIT(); - if (!monitor->originalRamp.size) { if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) From 3d9d4e311c58bf159100491a5efa2f7dcc1f19c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 28 Apr 2022 21:12:36 +0200 Subject: [PATCH 036/207] Win32: Fix OSMesa library not being unloaded (cherry picked from commit 10e9033a29ba088275da4363cd2d821ca577416a) --- README.md | 1 + src/win32_init.c | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 524debe1..ef2543ac 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ information on what to include when reporting a bug. - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not match event scancode (#1993) - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) + - [Win32] Bugfix: The OSMesa library was not unloaded on termination - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Wayland] Added support for file path drop events (#2040) - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of diff --git a/src/win32_init.c b/src/win32_init.c index 880837f6..18f60d38 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -610,6 +610,7 @@ void _glfwPlatformTerminate(void) _glfwTerminateWGL(); _glfwTerminateEGL(); + _glfwTerminateOSMesa(); _glfwTerminateJoysticksWin32(); From 6d08e52bcf52bb842539de616b384d0f76adffd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 28 Apr 2022 21:14:11 +0200 Subject: [PATCH 037/207] Cocoa: Fix EGL and OSMesa not being unloaded (cherry picked from commit 89514cf0fc33aed4db1310a57cc7436999492d14) --- README.md | 1 + src/cocoa_init.m | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index ef2543ac..275b6327 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ information on what to include when reporting a bug. - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) - [Win32] Bugfix: The OSMesa library was not unloaded on termination - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) + - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination - [Wayland] Added support for file path drop events (#2040) - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 209639e2..0d323d6b 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -607,6 +607,8 @@ void _glfwPlatformTerminate(void) free(_glfw.ns.clipboardString); _glfwTerminateNSGL(); + _glfwTerminateEGL(); + _glfwTerminateOSMesa(); _glfwTerminateJoysticksNS(); } // autoreleasepool From 6dd9bf0befaef2db4f2e569fb9a7c04932b32b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 28 Apr 2022 21:16:06 +0200 Subject: [PATCH 038/207] Wayland: Fix OSMesa library not being unloaded (cherry picked from commit 2d281d7928552c15ea2bc6dd185f7d7a780b1917) --- README.md | 1 + src/wl_init.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 275b6327..dc051fd2 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Some errors would cause clipboard string transfer to hang - [Wayland] Bugfix: Drag and drop data was misinterpreted as clipboard string - [Wayland] Bugfix: MIME type matching was not performed for clipboard string + - [Wayland] Bugfix: The OSMesa library was not unloaded on termination ## Contact diff --git a/src/wl_init.c b/src/wl_init.c index ad10aa60..9126ec06 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -484,6 +484,8 @@ void _glfwPlatformTerminate(void) _glfwTerminateJoysticksLinux(); #endif _glfwTerminateEGL(); + _glfwTerminateOSMesa(); + if (_glfw.wl.egl.handle) { _glfw_dlclose(_glfw.wl.egl.handle); From 53d40878c85b6f2fee506d682083b06a4ba037af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 28 Apr 2022 21:17:39 +0200 Subject: [PATCH 039/207] X11: Fix OSMesa library not being unloaded (cherry picked from commit a8d8b760fb6bffb9c7f65297a0bc3d6bf6b54262) --- README.md | 1 + src/x11_init.c | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index dc051fd2..0e18c811 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ information on what to include when reporting a bug. - [Win32] Bugfix: The OSMesa library was not unloaded on termination - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination + - [X11] Bugfix: The OSMesa libray was not unloaded on termination - [Wayland] Added support for file path drop events (#2040) - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` diff --git a/src/x11_init.c b/src/x11_init.c index 4fd9587e..8dd433f1 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -1235,6 +1235,7 @@ void _glfwPlatformTerminate(void) _glfw.x11.xi.handle = NULL; } + _glfwTerminateOSMesa(); // NOTE: These need to be unloaded after XCloseDisplay, as they register // cleanup callbacks that get called by that function _glfwTerminateEGL(); From 0052ddc5e3d37ccec3ec30f3c74afd90f92b55d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 18 Apr 2022 23:09:00 +0200 Subject: [PATCH 040/207] Update stb_image_write.h to version 1.16 (cherry picked from commit 82ccbb3ef02201498cbf5952083de47989e05978) --- deps/stb_image_write.h | 930 +++++++++++++++++++++++++++++++++++------ 1 file changed, 803 insertions(+), 127 deletions(-) diff --git a/deps/stb_image_write.h b/deps/stb_image_write.h index 4319c0de..e4b32ed1 100644 --- a/deps/stb_image_write.h +++ b/deps/stb_image_write.h @@ -1,5 +1,5 @@ -/* stb_image_write - v1.02 - public domain - http://nothings.org/stb/stb_image_write.h - writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015 +/* stb_image_write - v1.16 - public domain - http://nothings.org/stb + writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 no warranty implied; use at your own risk Before #including, @@ -12,41 +12,64 @@ ABOUT: - This header file is a library for writing images to C stdio. It could be - adapted to write to memory or a general streaming interface; let me know. + This header file is a library for writing images to C stdio or a callback. The PNG output is not optimal; it is 20-50% larger than the file - written by a decent optimizing implementation. This library is designed - for source code compactness and simplicity, not optimal image file size - or run-time performance. + written by a decent optimizing implementation; though providing a custom + zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. + This library is designed for source code compactness and simplicity, + not optimal image file size or run-time performance. BUILDING: You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace malloc,realloc,free. - You can define STBIW_MEMMOVE() to replace memmove() + You can #define STBIW_MEMMOVE() to replace memmove() + You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function + for PNG compression (instead of the builtin one), it must have the following signature: + unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); + The returned data will be freed with STBIW_FREE() (free() by default), + so it must be heap allocated with STBIW_MALLOC() (malloc() by default), + +UNICODE: + + If compiling for Windows and you wish to use Unicode filenames, compile + with + #define STBIW_WINDOWS_UTF8 + and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert + Windows wchar_t filenames to utf8. USAGE: - There are four functions, one for each image file format: + There are five functions, one for each image file format: int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); - There are also four equivalent functions that use an arbitrary write function. You are + void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically + + There are also five equivalent functions that use an arbitrary write function. You are expected to open/close your file-equivalent before and after calling these: int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); where the callback is: void stbi_write_func(void *context, void *data, int size); + You can configure it with these global variables: + int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE + int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression + int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode + + You can define STBI_WRITE_NO_STDIO to disable the file variant of these functions, so the library will not use stdio.h at all. However, this will also disable HDR writing, because it requires stdio for formatted output. @@ -73,6 +96,9 @@ USAGE: writer, both because it is in BGR order and because it may have padding at the end of the line.) + PNG allows you to set the deflate compression level by setting the global + variable 'stbi_write_png_compression_level' (it defaults to 8). + HDR expects linear float data. Since the format is always 32-bit rgb(e) data, alpha (if provided) is discarded, and for monochrome data it is replicated across all three channels. @@ -80,20 +106,23 @@ USAGE: TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed data, set the global variable 'stbi_write_tga_with_rle' to 0. + JPEG does ignore alpha channels in input data; quality is between 1 and 100. + Higher quality looks better but results in a bigger image. + JPEG baseline (no JPEG progressive). + CREDITS: - PNG/BMP/TGA - Sean Barrett - HDR - Baldur Karlsson - TGA monochrome: - Jean-Sebastien Guay - misc enhancements: - Tim Kelsey - TGA RLE - Alan Hickman - initial file IO callback implementation - Emmanuel Julien + + Sean Barrett - PNG/BMP/TGA + Baldur Karlsson - HDR + Jean-Sebastien Guay - TGA monochrome + Tim Kelsey - misc enhancements + Alan Hickman - TGA RLE + Emmanuel Julien - initial file IO callback implementation + Jon Olick - original jo_jpeg.cpp code + Daniel Gibson - integrate JPEG, allow external zlib + Aarni Koskela - allow choosing PNG filter + bugfixes: github:Chribba Guillaume Chereau @@ -103,27 +132,44 @@ CREDITS: Jonas Karlsson Filip Wasil Thatcher Ulrich - + github:poppolopoppo + Patrick Boettcher + github:xeekworx + Cap Petschulat + Simon Rodriguez + Ivan Tikhonov + github:ignotion + Adam Schackart + Andrew Kensler + LICENSE -This software is dual-licensed to the public domain and under the following -license: you are granted a perpetual, irrevocable license to copy, modify, -publish, and distribute this file as you see fit. + See end of file for license information. */ #ifndef INCLUDE_STB_IMAGE_WRITE_H #define INCLUDE_STB_IMAGE_WRITE_H +#include + +// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline' +#ifndef STBIWDEF +#ifdef STB_IMAGE_WRITE_STATIC +#define STBIWDEF static +#else #ifdef __cplusplus -extern "C" { +#define STBIWDEF extern "C" +#else +#define STBIWDEF extern +#endif +#endif #endif -#ifdef STB_IMAGE_WRITE_STATIC -#define STBIWDEF static -#else -#define STBIWDEF extern -extern int stbi_write_tga_with_rle; +#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations +STBIWDEF int stbi_write_tga_with_rle; +STBIWDEF int stbi_write_png_compression_level; +STBIWDEF int stbi_write_force_png_filter; #endif #ifndef STBI_WRITE_NO_STDIO @@ -131,6 +177,11 @@ STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); + +#ifdef STBIW_WINDOWS_UTF8 +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif #endif typedef void stbi_write_func(void *context, void *data, int size); @@ -139,10 +190,9 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); -#ifdef __cplusplus -} -#endif +STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); #endif//INCLUDE_STB_IMAGE_WRITE_H @@ -197,10 +247,29 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) +#ifdef STB_IMAGE_WRITE_STATIC +static int stbi_write_png_compression_level = 8; +static int stbi_write_tga_with_rle = 1; +static int stbi_write_force_png_filter = -1; +#else +int stbi_write_png_compression_level = 8; +int stbi_write_tga_with_rle = 1; +int stbi_write_force_png_filter = -1; +#endif + +static int stbi__flip_vertically_on_write = 0; + +STBIWDEF void stbi_flip_vertically_on_write(int flag) +{ + stbi__flip_vertically_on_write = flag; +} + typedef struct { stbi_write_func *func; void *context; + unsigned char buffer[64]; + int buf_used; } stbi__write_context; // initialize a callback-based context @@ -217,9 +286,52 @@ static void stbi__stdio_write(void *context, void *data, int size) fwrite(data,1,size,(FILE*) context); } +#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) +#ifdef __cplusplus +#define STBIW_EXTERN extern "C" +#else +#define STBIW_EXTERN extern +#endif +STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); + +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbiw__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) + return 0; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + static int stbi__start_write_file(stbi__write_context *s, const char *filename) { - FILE *f = fopen(filename, "wb"); + FILE *f = stbiw__fopen(filename, "wb"); stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); return f != NULL; } @@ -234,12 +346,6 @@ static void stbi__end_write_file(stbi__write_context *s) typedef unsigned int stbiw_uint32; typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; -#ifdef STB_IMAGE_WRITE_STATIC -static int stbi_write_tga_with_rle = 1; -#else -int stbi_write_tga_with_rle = 1; -#endif - static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) { while (*fmt) { @@ -277,11 +383,36 @@ static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) va_end(v); } +static void stbiw__write_flush(stbi__write_context *s) +{ + if (s->buf_used) { + s->func(s->context, &s->buffer, s->buf_used); + s->buf_used = 0; + } +} + +static void stbiw__putc(stbi__write_context *s, unsigned char c) +{ + s->func(s->context, &c, 1); +} + +static void stbiw__write1(stbi__write_context *s, unsigned char a) +{ + if ((size_t)s->buf_used + 1 > sizeof(s->buffer)) + stbiw__write_flush(s); + s->buffer[s->buf_used++] = a; +} + static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) { - unsigned char arr[3]; - arr[0] = a, arr[1] = b, arr[2] = c; - s->func(s->context, arr, 3); + int n; + if ((size_t)s->buf_used + 3 > sizeof(s->buffer)) + stbiw__write_flush(s); + n = s->buf_used; + s->buf_used = n+3; + s->buffer[n+0] = a; + s->buffer[n+1] = b; + s->buffer[n+2] = c; } static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) @@ -290,17 +421,15 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in int k; if (write_alpha < 0) - s->func(s->context, &d[comp - 1], 1); + stbiw__write1(s, d[comp - 1]); switch (comp) { + case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case case 1: - s->func(s->context,d,1); - break; - case 2: if (expand_mono) stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp else - s->func(s->context, d, 1); // monochrome TGA + stbiw__write1(s, d[0]); // monochrome TGA break; case 4: if (!write_alpha) { @@ -316,7 +445,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in break; } if (write_alpha > 0) - s->func(s->context, &d[comp - 1], 1); + stbiw__write1(s, d[comp - 1]); } static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) @@ -327,16 +456,21 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i if (y <= 0) return; - if (vdir < 0) - j_end = -1, j = y-1; - else - j_end = y, j = 0; + if (stbi__flip_vertically_on_write) + vdir *= -1; + + if (vdir < 0) { + j_end = -1; j = y-1; + } else { + j_end = y; j = 0; + } for (; j != j_end; j += vdir) { for (i=0; i < x; ++i) { unsigned char *d = (unsigned char *) data + (j*x+i)*comp; stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); } + stbiw__write_flush(s); s->func(s->context, &zero, scanline_pad); } } @@ -357,16 +491,27 @@ static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) { - int pad = (-x*3) & 3; - return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, - "11 4 22 4" "4 44 22 444444", - 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header - 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header + if (comp != 4) { + // write RGB bitmap + int pad = (-x*3) & 3; + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header + } else { + // RGBA bitmaps need a v4 header + // use BI_BITFIELDS mode with 32bpp and alpha mask + // (straight BI_RGB with alpha mask doesn't work in most readers) + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0, + "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444", + 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header + 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header + } } STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) { - stbi__write_context s; + stbi__write_context s = { 0 }; stbi__start_write_callbacks(&s, func, context); return stbi_write_bmp_core(&s, x, y, comp, data); } @@ -374,7 +519,7 @@ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, #ifndef STBI_WRITE_NO_STDIO STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) { - stbi__write_context s; + stbi__write_context s = { 0 }; if (stbi__start_write_file(&s,filename)) { int r = stbi_write_bmp_core(&s, x, y, comp, data); stbi__end_write_file(&s); @@ -398,11 +543,21 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); } else { int i,j,k; + int jend, jdir; stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); - for (j = y - 1; j >= 0; --j) { - unsigned char *row = (unsigned char *) data + j * x * comp; + if (stbi__flip_vertically_on_write) { + j = 0; + jend = y; + jdir = 1; + } else { + j = y-1; + jend = -1; + jdir = -1; + } + for (; j != jend; j += jdir) { + unsigned char *row = (unsigned char *) data + j * x * comp; int len; for (i = 0; i < x; i += len) { @@ -437,32 +592,33 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v if (diff) { unsigned char header = STBIW_UCHAR(len - 1); - s->func(s->context, &header, 1); + stbiw__write1(s, header); for (k = 0; k < len; ++k) { stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); } } else { unsigned char header = STBIW_UCHAR(len - 129); - s->func(s->context, &header, 1); + stbiw__write1(s, header); stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); } } } + stbiw__write_flush(s); } return 1; } -int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) { - stbi__write_context s; + stbi__write_context s = { 0 }; stbi__start_write_callbacks(&s, func, context); return stbi_write_tga_core(&s, x, y, comp, (void *) data); } #ifndef STBI_WRITE_NO_STDIO -int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) { - stbi__write_context s; + stbi__write_context s = { 0 }; if (stbi__start_write_file(&s,filename)) { int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); stbi__end_write_file(&s); @@ -475,11 +631,12 @@ int stbi_write_tga(char const *filename, int x, int y, int comp, const void *dat // ************************************************************************************************* // Radiance RGBE HDR writer // by Baldur Karlsson -#ifndef STBI_WRITE_NO_STDIO #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) -void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) +#ifndef STBI_WRITE_NO_STDIO + +static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) { int exponent; float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); @@ -496,7 +653,7 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) } } -void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) +static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) { unsigned char lengthbyte = STBIW_UCHAR(length+128); STBIW_ASSERT(length+128 <= 255); @@ -504,7 +661,7 @@ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char dat s->func(s->context, &databyte, 1); } -void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) +static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) { unsigned char lengthbyte = STBIW_UCHAR(length); STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code @@ -512,7 +669,7 @@ void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *d s->func(s->context, data, length); } -void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) +static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) { unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; unsigned char rgbe[4]; @@ -613,26 +770,30 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; s->func(s->context, header, sizeof(header)-1); +#ifdef __STDC_LIB_EXT1__ + len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#else len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#endif s->func(s->context, buffer, len); for(i=0; i < y; i++) - stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x); + stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)); STBIW_FREE(scratch); return 1; } } -int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) { - stbi__write_context s; + stbi__write_context s = { 0 }; stbi__start_write_callbacks(&s, func, context); return stbi_write_hdr_core(&s, x, y, comp, (float *) data); } -int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) +STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) { - stbi__write_context s; + stbi__write_context s = { 0 }; if (stbi__start_write_file(&s,filename)) { int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); stbi__end_write_file(&s); @@ -648,8 +809,9 @@ int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *da // PNG writer // +#ifndef STBIW_ZLIB_COMPRESS // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() -#define stbiw__sbraw(a) ((int *) (a) - 2) +#define stbiw__sbraw(a) ((int *) (void *) (a) - 2) #define stbiw__sbm(a) stbiw__sbraw(a)[0] #define stbiw__sbn(a) stbiw__sbraw(a)[1] @@ -728,8 +890,14 @@ static unsigned int stbiw__zhash(unsigned char *data) #define stbiw__ZHASH 16384 -unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +#endif // STBIW_ZLIB_COMPRESS + +STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) { +#ifdef STBIW_ZLIB_COMPRESS + // user provided a zlib compress implementation, use that + return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality); +#else // use builtin static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; @@ -737,7 +905,9 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l unsigned int bitbuf=0; int i,j, bitcount=0; unsigned char *out = NULL; - unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**)); + unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**)); + if (hash_table == NULL) + return NULL; if (quality < 5) quality = 5; stbiw__sbpush(out, 0x78); // DEFLATE 32K window @@ -758,7 +928,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l for (j=0; j < n; ++j) { if (hlist[j]-data > i-32768) { // if entry lies within window int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); - if (d >= best) best=d,bestloc=hlist[j]; + if (d >= best) { best=d; bestloc=hlist[j]; } } } // when hash table entry is too long, delete half the entries @@ -811,14 +981,31 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l (void) stbiw__sbfree(hash_table[i]); STBIW_FREE(hash_table); + // store uncompressed instead if compression was worse + if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) { + stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1 + for (j = 0; j < data_len;) { + int blocklen = data_len - j; + if (blocklen > 32767) blocklen = 32767; + stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression + stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN + stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN + stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8)); + memcpy(out+stbiw__sbn(out), data+j, blocklen); + stbiw__sbn(out) += blocklen; + j += blocklen; + } + } + { // compute adler32 on input unsigned int s1=1, s2=0; int blocklen = (int) (data_len % 5552); j=0; while (j < data_len) { - for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; - s1 %= 65521, s2 %= 65521; + for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; } + s1 %= 65521; s2 %= 65521; j += blocklen; blocklen = 5552; } @@ -831,10 +1018,14 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l // make returned pointer freeable STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); return (unsigned char *) stbiw__sbraw(out); +#endif // STBIW_ZLIB_COMPRESS } static unsigned int stbiw__crc32(unsigned char *buffer, int len) { +#ifdef STBIW_CRC32 + return STBIW_CRC32(buffer, len); +#else static unsigned int crc_table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, @@ -876,6 +1067,7 @@ static unsigned int stbiw__crc32(unsigned char *buffer, int len) for (i=0; i < len; ++i) crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; return ~crc; +#endif } #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) @@ -896,61 +1088,92 @@ static unsigned char stbiw__paeth(int a, int b, int c) return STBIW_UCHAR(c); } -unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +// @OPTIMIZE: provide an option that always forces left-predict or paeth predict +static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer) { + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = (y != 0) ? mapping : firstmap; + int i; + int type = mymap[filter_type]; + unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); + int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes; + + if (type==0) { + memcpy(line_buffer, z, width*n); + return; + } + + // first loop isn't optimized since it's just one pixel + for (i = 0; i < n; ++i) { + switch (type) { + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + } + switch (type) { + case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break; + case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break; + case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break; + case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; + } +} + +STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int force_filter = stbi_write_force_png_filter; int ctype[5] = { -1, 0, 4, 2, 6 }; unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; unsigned char *out,*o, *filt, *zlib; signed char *line_buffer; - int i,j,k,p,zlen; + int j,zlen; if (stride_bytes == 0) stride_bytes = x * n; + if (force_filter >= 5) { + force_filter = -1; + } + filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } for (j=0; j < y; ++j) { - static int mapping[] = { 0,1,2,3,4 }; - static int firstmap[] = { 0,1,0,5,6 }; - int *mymap = j ? mapping : firstmap; - int best = 0, bestval = 0x7fffffff; - for (p=0; p < 2; ++p) { - for (k= p?best:0; k < 5; ++k) { - int type = mymap[k],est=0; - unsigned char *z = pixels + stride_bytes*j; - for (i=0; i < n; ++i) - switch (type) { - case 0: line_buffer[i] = z[i]; break; - case 1: line_buffer[i] = z[i]; break; - case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; - case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break; - case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break; - case 5: line_buffer[i] = z[i]; break; - case 6: line_buffer[i] = z[i]; break; - } - for (i=n; i < x*n; ++i) { - switch (type) { - case 0: line_buffer[i] = z[i]; break; - case 1: line_buffer[i] = z[i] - z[i-n]; break; - case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; - case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break; - case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break; - case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break; - case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; - } - } - if (p) break; - for (i=0; i < x*n; ++i) + int filter_type; + if (force_filter > -1) { + filter_type = force_filter; + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer); + } else { // Estimate the best filter by running through all of them: + int best_filter = 0, best_filter_val = 0x7fffffff, est, i; + for (filter_type = 0; filter_type < 5; filter_type++) { + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer); + + // Estimate the entropy of the line using this filter; the less, the better. + est = 0; + for (i = 0; i < x*n; ++i) { est += abs((signed char) line_buffer[i]); - if (est < bestval) { bestval = est; best = k; } + } + if (est < best_filter_val) { + best_filter_val = est; + best_filter = filter_type; + } + } + if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer); + filter_type = best_filter; } } - // when we get here, best contains the filter type, and line_buffer contains the data - filt[j*(x*n+1)] = (unsigned char) best; + // when we get here, filter_type contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) filter_type; STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); } STBIW_FREE(line_buffer); - zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level); STBIW_FREE(filt); if (!zlib) return 0; @@ -993,9 +1216,10 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const { FILE *f; int len; - unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); if (png == NULL) return 0; - f = fopen(filename, "wb"); + + f = stbiw__fopen(filename, "wb"); if (!f) { STBIW_FREE(png); return 0; } fwrite(png, 1, len, f); fclose(f); @@ -1007,16 +1231,426 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) { int len; - unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); if (png == NULL) return 0; func(context, png, len); STBIW_FREE(png); return 1; } + +/* *************************************************************************** + * + * JPEG writer + * + * This is based on Jon Olick's jo_jpeg.cpp: + * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html + */ + +static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, + 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; + +static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { + int bitBuf = *bitBufP, bitCnt = *bitCntP; + bitCnt += bs[1]; + bitBuf |= bs[0] << (24 - bitCnt); + while(bitCnt >= 8) { + unsigned char c = (bitBuf >> 16) & 255; + stbiw__putc(s, c); + if(c == 255) { + stbiw__putc(s, 0); + } + bitBuf <<= 8; + bitCnt -= 8; + } + *bitBufP = bitBuf; + *bitCntP = bitCnt; +} + +static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { + float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; + float z1, z2, z3, z4, z5, z11, z13; + + float tmp0 = d0 + d7; + float tmp7 = d0 - d7; + float tmp1 = d1 + d6; + float tmp6 = d1 - d6; + float tmp2 = d2 + d5; + float tmp5 = d2 - d5; + float tmp3 = d3 + d4; + float tmp4 = d3 - d4; + + // Even part + float tmp10 = tmp0 + tmp3; // phase 2 + float tmp13 = tmp0 - tmp3; + float tmp11 = tmp1 + tmp2; + float tmp12 = tmp1 - tmp2; + + d0 = tmp10 + tmp11; // phase 3 + d4 = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781f; // c4 + d2 = tmp13 + z1; // phase 5 + d6 = tmp13 - z1; + + // Odd part + tmp10 = tmp4 + tmp5; // phase 2 + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + // The rotator is modified from fig 4-8 to avoid extra negations. + z5 = (tmp10 - tmp12) * 0.382683433f; // c6 + z2 = tmp10 * 0.541196100f + z5; // c2-c6 + z4 = tmp12 * 1.306562965f + z5; // c2+c6 + z3 = tmp11 * 0.707106781f; // c4 + + z11 = tmp7 + z3; // phase 5 + z13 = tmp7 - z3; + + *d5p = z13 + z2; // phase 6 + *d3p = z13 - z2; + *d1p = z11 + z4; + *d7p = z11 - z4; + + *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; +} + +static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { + int tmp1 = val < 0 ? -val : val; + val = val < 0 ? val-1 : val; + bits[1] = 1; + while(tmp1 >>= 1) { + ++bits[1]; + } + bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { + } + // end0pos = first element in reverse order !=0 + if(end0pos == 0) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + return DU[0]; + } + for(i = 1; i <= end0pos; ++i) { + int startpos = i; + int nrzeroes; + unsigned short bits[2]; + for (; DU[i]==0 && i<=end0pos; ++i) { + } + nrzeroes = i-startpos; + if ( nrzeroes >= 16 ) { + int lng = nrzeroes>>4; + int nrmarker; + for (nrmarker=1; nrmarker <= lng; ++nrmarker) + stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); + nrzeroes &= 15; + } + stbiw__jpg_calcBits(DU[i], bits); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); + } + if(end0pos != 63) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + } + return DU[0]; +} + +static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { + // Constants that don't pollute global namespace + static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; + static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; + static const unsigned char std_ac_luminance_values[] = { + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; + static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; + static const unsigned char std_ac_chrominance_values[] = { + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + // Huffman tables + static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; + static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; + static const unsigned short YAC_HT[256][2] = { + {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const unsigned short UVAC_HT[256][2] = { + {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, + 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; + static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; + static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, + 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; + + int row, col, i, k, subsample; + float fdtbl_Y[64], fdtbl_UV[64]; + unsigned char YTable[64], UVTable[64]; + + if(!data || !width || !height || comp > 4 || comp < 1) { + return 0; + } + + quality = quality ? quality : 90; + subsample = quality <= 90 ? 1 : 0; + quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; + quality = quality < 50 ? 5000 / quality : 200 - quality * 2; + + for(i = 0; i < 64; ++i) { + int uvti, yti = (YQT[i]*quality+50)/100; + YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); + uvti = (UVQT[i]*quality+50)/100; + UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); + } + + for(row = 0, k = 0; row < 8; ++row) { + for(col = 0; col < 8; ++col, ++k) { + fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + } + } + + // Write Headers + { + static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; + static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; + const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width), + 3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; + s->func(s->context, (void*)head0, sizeof(head0)); + s->func(s->context, (void*)YTable, sizeof(YTable)); + stbiw__putc(s, 1); + s->func(s->context, UVTable, sizeof(UVTable)); + s->func(s->context, (void*)head1, sizeof(head1)); + s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); + s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); + stbiw__putc(s, 0x10); // HTYACinfo + s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); + s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); + stbiw__putc(s, 1); // HTUDCinfo + s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); + stbiw__putc(s, 0x11); // HTUACinfo + s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); + s->func(s->context, (void*)head2, sizeof(head2)); + } + + // Encode 8x8 macroblocks + { + static const unsigned short fillBits[] = {0x7F, 7}; + int DCY=0, DCU=0, DCV=0; + int bitBuf=0, bitCnt=0; + // comp == 2 is grey+alpha (alpha is ignored) + int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; + const unsigned char *dataR = (const unsigned char *)data; + const unsigned char *dataG = dataR + ofsG; + const unsigned char *dataB = dataR + ofsB; + int x, y, pos; + if(subsample) { + for(y = 0; y < height; y += 16) { + for(x = 0; x < width; x += 16) { + float Y[256], U[256], V[256]; + for(row = y, pos = 0; row < y+16; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+16; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + + // subsample U,V + { + float subU[64], subV[64]; + int yy, xx; + for(yy = 0, pos = 0; yy < 8; ++yy) { + for(xx = 0; xx < 8; ++xx, ++pos) { + int j = yy*32+xx*2; + subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f; + subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f; + } + } + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + } else { + for(y = 0; y < height; y += 8) { + for(x = 0; x < width; x += 8) { + float Y[64], U[64], V[64]; + for(row = y, pos = 0; row < y+8; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+8; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + + // Do the bit alignment of the EOI marker + stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); + } + + // EOI + stbiw__putc(s, 0xFF); + stbiw__putc(s, 0xD9); + + return 1; +} + +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); +} + + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + #endif // STB_IMAGE_WRITE_IMPLEMENTATION /* Revision history + 1.16 (2021-07-11) + make Deflate code emit uncompressed blocks when it would otherwise expand + support writing BMPs with alpha channel + 1.15 (2020-07-13) unknown + 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels + 1.13 + 1.12 + 1.11 (2019-08-11) + + 1.10 (2019-02-07) + support utf8 filenames in Windows; fix warnings and platform ifdefs + 1.09 (2018-02-11) + fix typo in zlib quality API, improve STB_I_W_STATIC in C++ + 1.08 (2018-01-29) + add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter + 1.07 (2017-07-24) + doc fix + 1.06 (2017-07-23) + writing JPEG (using Jon Olick's code) + 1.05 ??? + 1.04 (2017-03-03) + monochrome BMP expansion + 1.03 ??? 1.02 (2016-04-02) avoid allocating large structures on the stack 1.01 (2016-01-16) @@ -1035,7 +1669,7 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, add HDR output fix monochrome BMP 0.95 (2014-08-17) - add monochrome TGA output + add monochrome TGA output 0.94 (2014-05-31) rename private functions to avoid conflicts with stb_image.h 0.93 (2014-05-27) @@ -1046,3 +1680,45 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, first public release 0.90 first internal release */ + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ From bf5529512c23d2f10b9cbd4cd2f9eb60bf3e37a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 18 Apr 2022 23:10:04 +0200 Subject: [PATCH 041/207] Document delayed initialization of EGL display (cherry picked from commit 06089a91a644b1f1c44465c95ff6cc002792556b) --- include/GLFW/glfw3native.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index f666df2b..a43d6425 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -492,6 +492,9 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * + * @remark Because EGL is initialized on demand, this function will return + * `EGL_NO_DISPLAY` until the first context has been created via EGL. + * * @thread_safety This function may be called from any thread. Access is not * synchronized. * From 946312fe938bc65093b9b648ec6f0c790f351f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 18 Apr 2022 23:21:40 +0200 Subject: [PATCH 042/207] X11: Fix returned clipboard string freed too early The clipboard string should not be freed on SelectionClear. The user may have received it from glfwGetClipboardString and it should remain valid until the next call to a public clipboard string function. (cherry picked from commit f60547ac80602955fe0af1ab05fd3f6ed5941e6b) --- src/x11_window.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 47ffef82..fc081486 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -929,20 +929,6 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request) return None; } -static void handleSelectionClear(XEvent* event) -{ - if (event->xselectionclear.selection == _glfw.x11.PRIMARY) - { - free(_glfw.x11.primarySelectionString); - _glfw.x11.primarySelectionString = NULL; - } - else - { - free(_glfw.x11.clipboardString); - _glfw.x11.clipboardString = NULL; - } -} - static void handleSelectionRequest(XEvent* event) { const XSelectionRequestEvent* request = &event->xselectionrequest; @@ -1236,12 +1222,7 @@ static void processEvent(XEvent *event) return; } - if (event->type == SelectionClear) - { - handleSelectionClear(event); - return; - } - else if (event->type == SelectionRequest) + if (event->type == SelectionRequest) { handleSelectionRequest(event); return; @@ -1946,10 +1927,6 @@ void _glfwPushSelectionToManagerX11(void) handleSelectionRequest(&event); break; - case SelectionClear: - handleSelectionClear(&event); - break; - case SelectionNotify: { if (event.xselection.target == _glfw.x11.SAVE_TARGETS) From 65b8c4a46b104b2e36ce5dcc8561dc3a96a22012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 18 Apr 2022 23:22:25 +0200 Subject: [PATCH 043/207] X11: Fix segfault on malformed INCR response The code assumed that at least some data would be received via the INCR mechanism and that, as a result, the string buffer would be allocated. Bug found by Clang static analysis. (cherry picked from commit 23e6e8e4b7ffe8f7604bd4f6ad1b183d0927bfe2) --- README.md | 1 + src/x11_window.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0e18c811..bcd2d70d 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,7 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination - [X11] Bugfix: The OSMesa libray was not unloaded on termination + - [X11] Bugfix: A malformed response during selection transfer could cause a segfault - [Wayland] Added support for file path drop events (#2040) - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` diff --git a/src/x11_window.c b/src/x11_window.c index fc081486..331652ec 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1049,13 +1049,16 @@ static const char* getSelectionString(Atom selection) if (!itemCount) { - if (targets[i] == XA_STRING) + if (string) { - *selectionString = convertLatin1toUTF8(string); - free(string); + if (targets[i] == XA_STRING) + { + *selectionString = convertLatin1toUTF8(string); + free(string); + } + else + *selectionString = string; } - else - *selectionString = string; break; } From af9eb79de421a7a2bc2838c449d719c56491d8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 18 Apr 2022 23:35:08 +0200 Subject: [PATCH 044/207] Move CODEOWNERS to .github directory This slightly de-clutters a directory mostly intended for human-readable documentation. (cherry picked from commit d3c2121221f7bcd9cce2e164acfbdee8820aec06) --- {docs => .github}/CODEOWNERS | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {docs => .github}/CODEOWNERS (100%) diff --git a/docs/CODEOWNERS b/.github/CODEOWNERS similarity index 100% rename from docs/CODEOWNERS rename to .github/CODEOWNERS From 1b3b2108e3254aee0bad699449e6079d8ebe0e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 6 Apr 2022 19:02:52 +0200 Subject: [PATCH 045/207] Win32: Remove superfluous cast (cherry picked from commit 80e31ce9e1e75f51f9cf0af61c9163474675439a) --- src/win32_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32_window.c b/src/win32_window.c index 46d671fa..b6defbaa 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1428,7 +1428,7 @@ GLFWbool _glfwRegisterWindowClassWin32(void) ZeroMemory(&wc, sizeof(wc)); wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) windowProc; + wc.lpfnWndProc = windowProc; wc.hInstance = _glfw.win32.instance; wc.hCursor = LoadCursorW(NULL, IDC_ARROW); wc.lpszClassName = _GLFW_WNDCLASSNAME; From c8be8606f0d4f1a7574dfca932327c302d101820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 6 Apr 2022 23:21:28 +0200 Subject: [PATCH 046/207] Win32: Fix message reported by VS 2022 (cherry picked from commit acf0c10e7aa946b8f1555c78d812528e22e39dc4) --- src/win32_joystick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32_joystick.c b/src/win32_joystick.c index 613587bf..67e3465c 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -609,7 +609,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) { int i, ai = 0, bi = 0, pi = 0; HRESULT result; - DIJOYSTATE state; + DIJOYSTATE state = {0}; IDirectInputDevice8_Poll(js->win32.device); result = IDirectInputDevice8_GetDeviceState(js->win32.device, From b9ea733ca8c4dff613210fbbb6b9a5899486b2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 6 Apr 2022 21:13:48 +0200 Subject: [PATCH 047/207] Move last bits of window setup to platform code This avoids glfwCreateWindow emitting GLFW_PLATFORM_ERROR on Wayland because shared code was calling unimplemented or unavailable platform functions during final setup. It also makes it consistent with the final setup of full screen windows. This is adapted to 3.3-stable from 09653b8c5490ebb605933537e897587c9129f159. --- README.md | 1 + src/cocoa_window.m | 15 +++++++++++++++ src/null_window.c | 3 +++ src/win32_window.c | 15 +++++++++++++++ src/window.c | 24 ------------------------ src/wl_window.c | 3 +++ src/x11_window.c | 15 +++++++++++++++ 7 files changed, 52 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index bcd2d70d..7f7c49d0 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Drag and drop data was misinterpreted as clipboard string - [Wayland] Bugfix: MIME type matching was not performed for clipboard string - [Wayland] Bugfix: The OSMesa library was not unloaded on termination + - [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_PLATFORM_ERROR` ## Contact diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 15f9c40e..16198949 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -934,6 +934,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) return GLFW_FALSE; } + + if (!_glfwRefreshContextAttribs(window, ctxconfig)) + return GLFW_FALSE; } if (window->monitor) @@ -941,6 +944,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, _glfwPlatformShowWindow(window); _glfwPlatformFocusWindow(window); acquireMonitor(window); + + if (wndconfig->centerCursor) + _glfwCenterCursorInContentArea(window); + } + else + { + if (wndconfig->visible) + { + _glfwPlatformShowWindow(window); + if (wndconfig->focused) + _glfwPlatformFocusWindow(window); + } } return GLFW_TRUE; diff --git a/src/null_window.c b/src/null_window.c index 045c76a2..e61c2bdd 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -67,6 +67,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, _glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available"); return GLFW_FALSE; } + + if (!_glfwRefreshContextAttribs(window, ctxconfig)) + return GLFW_FALSE; } return GLFW_TRUE; diff --git a/src/win32_window.c b/src/win32_window.c index b6defbaa..ca0f355d 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1498,6 +1498,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) return GLFW_FALSE; } + + if (!_glfwRefreshContextAttribs(window, ctxconfig)) + return GLFW_FALSE; } if (window->monitor) @@ -1506,6 +1509,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, _glfwPlatformFocusWindow(window); acquireMonitor(window); fitToMonitor(window); + + if (wndconfig->centerCursor) + _glfwCenterCursorInContentArea(window); + } + else + { + if (wndconfig->visible) + { + _glfwPlatformShowWindow(window); + if (wndconfig->focused) + _glfwPlatformFocusWindow(window); + } } return GLFW_TRUE; diff --git a/src/window.c b/src/window.c index 1fd9c6a0..5d80e436 100644 --- a/src/window.c +++ b/src/window.c @@ -221,30 +221,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, return NULL; } - if (ctxconfig.client != GLFW_NO_API) - { - if (!_glfwRefreshContextAttribs(window, &ctxconfig)) - { - glfwDestroyWindow((GLFWwindow*) window); - return NULL; - } - } - - if (window->monitor) - { - if (wndconfig.centerCursor) - _glfwCenterCursorInContentArea(window); - } - else - { - if (wndconfig.visible) - { - _glfwPlatformShowWindow(window); - if (wndconfig.focused) - _glfwPlatformFocusWindow(window); - } - } - return (GLFWwindow*) window; } diff --git a/src/wl_window.c b/src/wl_window.c index b15fd16a..7f2d7e67 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1925,6 +1925,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) return GLFW_FALSE; } + + if (!_glfwRefreshContextAttribs(window, ctxconfig)) + return GLFW_FALSE; } return GLFW_TRUE; diff --git a/src/x11_window.c b/src/x11_window.c index 331652ec..ddda48d7 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2013,6 +2013,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) return GLFW_FALSE; } + + if (!_glfwRefreshContextAttribs(window, ctxconfig)) + return GLFW_FALSE; } if (window->monitor) @@ -2020,6 +2023,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, _glfwPlatformShowWindow(window); updateWindowMode(window); acquireMonitor(window); + + if (wndconfig->centerCursor) + _glfwCenterCursorInContentArea(window); + } + else + { + if (wndconfig->visible) + { + _glfwPlatformShowWindow(window); + if (wndconfig->focused) + _glfwPlatformFocusWindow(window); + } } XFlush(_glfw.x11.display); From f001aa34902b694f24fa2b9e431f73fafc1eff10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Apr 2022 17:35:50 +0200 Subject: [PATCH 048/207] Fix and clarify comments for GLFWAPI (cherry picked from commit 685de9089f13dab9e284d00aaca24e68947f5bed) --- include/GLFW/glfw3.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 8e27e2ea..ba55b6e2 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -262,13 +262,12 @@ extern "C" { /* We are building GLFW as a Win32 DLL */ #define GLFWAPI __declspec(dllexport) #elif defined(_WIN32) && defined(GLFW_DLL) - /* We are calling GLFW as a Win32 DLL */ + /* We are calling a GLFW Win32 DLL */ #define GLFWAPI __declspec(dllimport) #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) - /* We are building GLFW as a shared / dynamic library */ + /* We are building GLFW as a Unix shared library */ #define GLFWAPI __attribute__((visibility("default"))) #else - /* We are building or calling GLFW as a static library */ #define GLFWAPI #endif From f4e36e53897f14afa257f6d2eed7793366fd2251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Apr 2022 21:22:24 +0200 Subject: [PATCH 049/207] Win32: Make monitor area retrieval more consistent The rest of this file uses GetMonitorInfoW to retrieve this information. (cherry picked from commit 7dfd84c458dfa12b351c932b8281b13faf7b50b9) --- src/win32_window.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index ca0f355d..7a32bf8c 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1280,15 +1280,16 @@ static int createNativeWindow(_GLFWwindow* window, if (window->monitor) { - GLFWvidmode mode; + MONITORINFO mi = { sizeof(mi) }; + GetMonitorInfoW(window->monitor->win32.handle, &mi); // NOTE: This window placement is temporary and approximate, as the // correct position and size cannot be known until the monitor // video mode has been picked in _glfwSetVideoModeWin32 - _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); - _glfwPlatformGetVideoMode(window->monitor, &mode); - fullWidth = mode.width; - fullHeight = mode.height; + xpos = mi.rcMonitor.left; + ypos = mi.rcMonitor.top; + fullWidth = mi.rcMonitor.right - mi.rcMonitor.left; + fullHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; } else { From 2a6d25d1aa11c70cf03e5721105beb5f3cc78e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 5 May 2022 21:47:34 +0200 Subject: [PATCH 050/207] Win32: Add comment clarifying use of ToUnicode Fixes #2100 (cherry picked from commit 62e175ef9fae75335575964c845a302447c012c7) --- src/win32_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/win32_init.c b/src/win32_init.c index 18f60d38..885f32fa 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -503,6 +503,8 @@ void _glfwUpdateKeyNamesWin32(void) if (length == -1) { + // This is a dead key, so we need a second simulated key press + // to make it output its own character (usually a diacritic) length = ToUnicode(vk, scancode, state, chars, sizeof(chars) / sizeof(WCHAR), 0); From 6de6446acac88f5f8e7c1574e27a22acffcbce53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 8 Jun 2022 19:14:13 +0200 Subject: [PATCH 051/207] Wayland: Fix missing lock key modifier bits The modifier bits for lock keys were only set when the corresponding key was reported as held down or latched, but not when it was released and locked. (cherry picked from commit e9c58bc1815656403b736000469f2ae5d2f0303a) --- README.md | 1 + src/wl_init.c | 4 +-- src/wl_platform.h | 18 ++++++------- src/wl_window.c | 66 +++++++++++++++++++++++++++++------------------ 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 7f7c49d0..61b20c71 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: MIME type matching was not performed for clipboard string - [Wayland] Bugfix: The OSMesa library was not unloaded on termination - [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_PLATFORM_ERROR` + - [Wayland] Bugfix: Lock key modifier bits were only set when lock keys were pressed ## Contact diff --git a/src/wl_init.c b/src/wl_init.c index 9126ec06..fffaba3d 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -381,10 +381,10 @@ int _glfwPlatformInit(void) _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_syms"); _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask) _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_update_mask"); - _glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods) - _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_serialize_mods"); _glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout) _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_layout"); + _glfw.wl.xkb.state_mod_index_is_active = (PFN_xkb_state_mod_index_is_active) + _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_mod_index_is_active"); _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale) _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale"); diff --git a/src/wl_platform.h b/src/wl_platform.h index 824efc72..5530b7aa 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -115,8 +115,8 @@ 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); typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t); +typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,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 @@ -128,8 +128,8 @@ typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xk #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 #define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout +#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active 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*); @@ -283,12 +283,12 @@ typedef struct _GLFWlibraryWayland struct xkb_state* state; struct xkb_compose_state* composeState; - 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; + xkb_mod_index_t controlIndex; + xkb_mod_index_t altIndex; + xkb_mod_index_t shiftIndex; + xkb_mod_index_t superIndex; + xkb_mod_index_t capsLockIndex; + xkb_mod_index_t numLockIndex; unsigned int modifiers; PFN_xkb_context_new context_new; @@ -302,8 +302,8 @@ typedef struct _GLFWlibraryWayland 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; PFN_xkb_state_key_get_layout state_key_get_layout; + PFN_xkb_state_mod_index_is_active state_mod_index_is_active; PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; PFN_xkb_compose_table_unref compose_table_unref; diff --git a/src/wl_window.c b/src/wl_window.c index 7f2d7e67..a6b19eb0 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1442,18 +1442,12 @@ static void keyboardHandleKeymap(void* userData, _glfw.wl.xkb.keymap = keymap; _glfw.wl.xkb.state = state; - _glfw.wl.xkb.controlMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control"); - _glfw.wl.xkb.altMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1"); - _glfw.wl.xkb.shiftMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift"); - _glfw.wl.xkb.superMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4"); - _glfw.wl.xkb.capsLockMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock"); - _glfw.wl.xkb.numLockMask = - 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2"); + _glfw.wl.xkb.controlIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control"); + _glfw.wl.xkb.altIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1"); + _glfw.wl.xkb.shiftIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift"); + _glfw.wl.xkb.superIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4"); + _glfw.wl.xkb.capsLockIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock"); + _glfw.wl.xkb.numLockIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2"); } static void keyboardHandleEnter(void* userData, @@ -1607,27 +1601,49 @@ static void keyboardHandleModifiers(void* userData, 0, group); - const xkb_mod_mask_t mask = - xkb_state_serialize_mods(_glfw.wl.xkb.state, - XKB_STATE_MODS_DEPRESSED | - XKB_STATE_LAYOUT_DEPRESSED | - XKB_STATE_MODS_LATCHED | - XKB_STATE_LAYOUT_LATCHED); - unsigned int mods = 0; - if (mask & _glfw.wl.xkb.controlMask) + if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, + _glfw.wl.xkb.controlIndex, + XKB_STATE_MODS_EFFECTIVE) == 1) + { mods |= GLFW_MOD_CONTROL; - if (mask & _glfw.wl.xkb.altMask) + } + + if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, + _glfw.wl.xkb.altIndex, + XKB_STATE_MODS_EFFECTIVE) == 1) + { mods |= GLFW_MOD_ALT; - if (mask & _glfw.wl.xkb.shiftMask) + } + + if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, + _glfw.wl.xkb.shiftIndex, + XKB_STATE_MODS_EFFECTIVE) == 1) + { mods |= GLFW_MOD_SHIFT; - if (mask & _glfw.wl.xkb.superMask) + } + + if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, + _glfw.wl.xkb.superIndex, + XKB_STATE_MODS_EFFECTIVE) == 1) + { mods |= GLFW_MOD_SUPER; - if (mask & _glfw.wl.xkb.capsLockMask) + } + + if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, + _glfw.wl.xkb.capsLockIndex, + XKB_STATE_MODS_EFFECTIVE) == 1) + { mods |= GLFW_MOD_CAPS_LOCK; - if (mask & _glfw.wl.xkb.numLockMask) + } + + if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, + _glfw.wl.xkb.numLockIndex, + XKB_STATE_MODS_EFFECTIVE) == 1) + { mods |= GLFW_MOD_NUM_LOCK; + } _glfw.wl.xkb.modifiers = mods; } From 416f7828ffe1cb23406ca7223dc06a5d150e3e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 5 May 2022 22:23:12 +0200 Subject: [PATCH 052/207] Fix joystick user pointer NULL during disconnect The joystick code did not distinguish between the allocation status of the GLFW joystick object and whether it is connection to an OS level joystick object. These are now tracked separately. Fixes #2092 This is adapted to 3.3-stable from 2c204ab52ecaa51bfd32b777aef715dae937f009 and fd7e737216dfdcecd4522b7d8c8dd2439d3dac3b. --- CONTRIBUTORS.md | 1 + README.md | 1 + src/cocoa_joystick.m | 15 ++++++++------- src/input.c | 35 ++++++++++++++++++++--------------- src/internal.h | 3 ++- src/linux_joystick.c | 8 ++++---- src/win32_joystick.c | 10 +++++----- 7 files changed, 41 insertions(+), 32 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 36a040e2..41efe310 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -136,6 +136,7 @@ video tutorials. - Kenneth Miller - Bruce Mitchener - Jack Moffitt + - Ravi Mohan - Jeff Molofee - Alexander Monakov - Pierre Morel diff --git a/README.md b/README.md index 61b20c71..26a6092a 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ information on what to include when reporting a bug. - Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization - Bugfix: `glfwSetGammaRamp` could emit `GLFW_INVALID_VALUE` before initialization + - Bugfix: `glfwGetJoystickUserPointer` returned `NULL` during disconnection (#2092) - [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different scancode than `PrtSc` (#1993) - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 2c8d82d9..3d306777 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -98,8 +98,7 @@ static void closeJoystick(_GLFWjoystick* js) { int i; - if (!js->present) - return; + _glfwInputJoystick(js, GLFW_DISCONNECTED); for (i = 0; i < CFArrayGetCount(js->ns.axes); i++) free((void*) CFArrayGetValueAtIndex(js->ns.axes, i)); @@ -114,7 +113,6 @@ static void closeJoystick(_GLFWjoystick* js) CFRelease(js->ns.hats); _glfwFreeJoystick(js); - _glfwInputJoystick(js, GLFW_DISCONNECTED); } // Callback for user-initiated joystick addition @@ -294,9 +292,9 @@ static void removeCallback(void* context, for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (_glfw.joysticks[jid].ns.device == device) + if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device) { - closeJoystick(_glfw.joysticks + jid); + closeJoystick(&_glfw.joysticks[jid]); break; } } @@ -392,7 +390,10 @@ void _glfwTerminateJoysticksNS(void) int jid; for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - closeJoystick(_glfw.joysticks + jid); + { + if (_glfw.joysticks[jid].connected) + closeJoystick(&_glfw.joysticks[jid]); + } CFRelease(_glfw.ns.hidManager); _glfw.ns.hidManager = NULL; @@ -470,7 +471,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) } } - return js->present; + return js->connected; } void _glfwPlatformUpdateGamepadGUID(char* guid) diff --git a/src/input.c b/src/input.c index f6c1ed79..7ea1222c 100644 --- a/src/input.c +++ b/src/input.c @@ -360,6 +360,11 @@ void _glfwInputJoystick(_GLFWjoystick* js, int event) { const int jid = (int) (js - _glfw.joysticks); + if (event == GLFW_CONNECTED) + js->connected = GLFW_TRUE; + else if (event == GLFW_DISCONNECTED) + js->connected = GLFW_FALSE; + if (_glfw.callbacks.joystick) _glfw.callbacks.joystick(jid, event); } @@ -415,7 +420,7 @@ void _glfwInitGamepadMappings(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) js->mapping = findValidMapping(js); } } @@ -433,7 +438,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (!_glfw.joysticks[jid].present) + if (!_glfw.joysticks[jid].allocated) break; } @@ -441,7 +446,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, return NULL; js = _glfw.joysticks + jid; - js->present = GLFW_TRUE; + js->allocated = GLFW_TRUE; js->axes = calloc(axisCount, sizeof(float)); js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1); js->hats = calloc(hatCount, 1); @@ -944,7 +949,7 @@ GLFWAPI int glfwJoystickPresent(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return GLFW_FALSE; return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); @@ -969,7 +974,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES)) @@ -998,7 +1003,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) @@ -1031,7 +1036,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) @@ -1057,7 +1062,7 @@ GLFWAPI const char* glfwGetJoystickName(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1082,7 +1087,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1101,7 +1106,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer) _GLFW_REQUIRE_INIT(); js = _glfw.joysticks + jid; - if (!js->present) + if (!js->allocated) return; js->userPointer = pointer; @@ -1117,7 +1122,7 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); js = _glfw.joysticks + jid; - if (!js->present) + if (!js->allocated) return NULL; return js->userPointer; @@ -1183,7 +1188,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) js->mapping = findValidMapping(js); } @@ -1206,7 +1211,7 @@ GLFWAPI int glfwJoystickIsGamepad(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return GLFW_FALSE; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1231,7 +1236,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1263,7 +1268,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return GLFW_FALSE; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL)) diff --git a/src/internal.h b/src/internal.h index 3e9283a3..7734caa3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -478,7 +478,8 @@ struct _GLFWmapping // struct _GLFWjoystick { - GLFWbool present; + GLFWbool allocated; + GLFWbool connected; float* axes; int axisCount; unsigned char* buttons; diff --git a/src/linux_joystick.c b/src/linux_joystick.c index 5a3b806c..0894a726 100644 --- a/src/linux_joystick.c +++ b/src/linux_joystick.c @@ -128,7 +128,7 @@ static GLFWbool openJoystickDevice(const char* path) { for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (!_glfw.joysticks[jid].present) + if (!_glfw.joysticks[jid].connected) continue; if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) return GLFW_FALSE; @@ -245,9 +245,9 @@ static GLFWbool openJoystickDevice(const char* path) // static void closeJoystick(_GLFWjoystick* js) { + _glfwInputJoystick(js, GLFW_DISCONNECTED); close(js->linjs.fd); _glfwFreeJoystick(js); - _glfwInputJoystick(js, GLFW_DISCONNECTED); } // Lexically compare joysticks by name; used by qsort @@ -329,7 +329,7 @@ void _glfwTerminateJoysticksLinux(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) closeJoystick(js); } @@ -424,7 +424,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) handleAbsEvent(js, e.code, e.value); } - return js->present; + return js->connected; } void _glfwPlatformUpdateGamepadGUID(char* guid) diff --git a/src/win32_joystick.c b/src/win32_joystick.c index 67e3465c..f471f0a9 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -256,6 +256,8 @@ static GLFWbool supportsXInput(const GUID* guid) // static void closeJoystick(_GLFWjoystick* js) { + _glfwInputJoystick(js, GLFW_DISCONNECTED); + if (js->win32.device) { IDirectInputDevice8_Unacquire(js->win32.device); @@ -263,9 +265,7 @@ static void closeJoystick(_GLFWjoystick* js) } free(js->win32.objects); - _glfwFreeJoystick(js); - _glfwInputJoystick(js, GLFW_DISCONNECTED); } // DirectInput device object enumeration callback @@ -357,7 +357,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) { if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0) return DIENUM_CONTINUE; @@ -541,7 +541,7 @@ void _glfwDetectJoystickConnectionWin32(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (_glfw.joysticks[jid].present && + if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].win32.device == NULL && _glfw.joysticks[jid].win32.index == index) { @@ -593,7 +593,7 @@ void _glfwDetectJoystickDisconnectionWin32(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); } } From 631da8cc2fe01f74271a9230d101ab56a66234ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 25 May 2022 19:43:55 +0200 Subject: [PATCH 053/207] X11: Fix previous error handler not being restored GLFW did not restore the previous Xlib error handler when removing its own, instead resetting to the default handler. This commit saves and restores the previous error handler. None of this is thread-safe or could ever be. Fixes #2108 (cherry picked from commit 26920a1a38d7c4c5b7908cf2e04b750d941f1faa) --- README.md | 1 + src/x11_init.c | 7 +++++-- src/x11_platform.h | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 26a6092a..6005f81b 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination - [X11] Bugfix: The OSMesa libray was not unloaded on termination - [X11] Bugfix: A malformed response during selection transfer could cause a segfault + - [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108) - [Wayland] Added support for file path drop events (#2040) - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` diff --git a/src/x11_init.c b/src/x11_init.c index 8dd433f1..6049904a 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -39,6 +39,7 @@ #include #include #include +#include // Translate the X11 KeySyms for a key to a GLFW key code @@ -1022,8 +1023,9 @@ static int errorHandler(Display *display, XErrorEvent* event) // void _glfwGrabErrorHandlerX11(void) { + assert(_glfw.x11.errorHandler == NULL); _glfw.x11.errorCode = Success; - XSetErrorHandler(errorHandler); + _glfw.x11.errorHandler = XSetErrorHandler(errorHandler); } // Clears the X error handler callback @@ -1032,7 +1034,8 @@ void _glfwReleaseErrorHandlerX11(void) { // Synchronize to make sure all commands are processed XSync(_glfw.x11.display, False); - XSetErrorHandler(NULL); + XSetErrorHandler(_glfw.x11.errorHandler); + _glfw.x11.errorHandler = NULL; } // Reports the specified error, appending information about the last X error diff --git a/src/x11_platform.h b/src/x11_platform.h index 30c73a88..03ff9d24 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -222,6 +222,8 @@ typedef struct _GLFWlibraryX11 XContext context; // XIM input method XIM im; + // The previous X error handler, to be restored later + XErrorHandler errorHandler; // Most recent error code received by X error handler int errorCode; // Primary selection string (while the primary selection is owned) From b86fcd7cd0c36e1b7e487b700f7477cbe29ddbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 2 Jun 2022 21:25:15 +0200 Subject: [PATCH 054/207] Cocoa: Use system header to declare id type Related to #1348 (cherry picked from commit edec334b32458df9ced9d84a39c3cd4b757597bb) --- include/GLFW/glfw3native.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index a43d6425..ba595212 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -96,7 +96,7 @@ extern "C" { #import #else #include - typedef void* id; + #include #endif #elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) #include From aa1efada5262365ec997935d4be517eb433ba60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 18 Apr 2022 23:09:47 +0200 Subject: [PATCH 055/207] Add support for GLFW_NATIVE_INCLUDE_NONE macro By default, the glfw3native.h header will include the platform-specific headers necessary for the return types of GLFW native access functions. Sometimes it is preferrable to declare those types This commit adds support for the GLFW_NATIVE_INCLUDE_NONE macro, which when defined disables the inclusion of all platform-specific headers. Fixes #1348 (cherry picked from commit 05f6c13d119ea2662c97527d2421fb4cffd3dbfc) --- README.md | 1 + include/GLFW/glfw3native.h | 118 +++++++++++++++++++++---------------- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 6005f81b..0331fcd8 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ information on what to include when reporting a bug. ## Changelog + - Added `GLFW_NATIVE_INCLUDE_NONE` for disabling inclusion of native headers (#1348) - Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization - Bugfix: `glfwSetGammaRamp` could emit `GLFW_INVALID_VALUE` before initialization - Bugfix: `glfwGetJoystickUserPointer` returned `NULL` during disconnection (#2092) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index ba595212..7be0227d 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -74,6 +74,16 @@ extern "C" { * and which platform-specific headers to include. It is then up your (by * definition platform-specific) code to handle which of these should be * defined. + * + * If you do not want the platform-specific headers to be included, define + * `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header. + * + * @code + * #define GLFW_EXPOSE_NATIVE_WIN32 + * #define GLFW_EXPOSE_NATIVE_WGL + * #define GLFW_NATIVE_INCLUDE_NONE + * #include + * @endcode */ @@ -81,61 +91,65 @@ extern "C" { * System headers and types *************************************************************************/ -#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) - /* 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 - */ - #if defined(GLFW_APIENTRY_DEFINED) - #undef APIENTRY - #undef GLFW_APIENTRY_DEFINED - #endif - #include -#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) - #if defined(__OBJC__) - #import - #else - #include - #include - #endif -#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) - #include - #include -#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) - #include -#endif +#if !defined(GLFW_NATIVE_INCLUDE_NONE) -#if defined(GLFW_EXPOSE_NATIVE_WGL) - /* WGL is declared by windows.h */ -#endif -#if defined(GLFW_EXPOSE_NATIVE_NSGL) - /* NSGL is declared by Cocoa.h */ -#endif -#if defined(GLFW_EXPOSE_NATIVE_GLX) - /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by - * default it also acts as an OpenGL header - * However, glx.h will include gl.h, which will define it unconditionally - */ - #if defined(GLFW_GLAPIENTRY_DEFINED) - #undef GLAPIENTRY - #undef GLFW_GLAPIENTRY_DEFINED + #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) + /* 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 + */ + #if defined(GLFW_APIENTRY_DEFINED) + #undef APIENTRY + #undef GLFW_APIENTRY_DEFINED + #endif + #include + #elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) + #if defined(__OBJC__) + #import + #else + #include + #include + #endif + #elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) + #include + #include + #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #include #endif - #include -#endif -#if defined(GLFW_EXPOSE_NATIVE_EGL) - #include -#endif -#if defined(GLFW_EXPOSE_NATIVE_OSMESA) - /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by - * default it also acts as an OpenGL header - * However, osmesa.h will include gl.h, which will define it unconditionally - */ - #if defined(GLFW_GLAPIENTRY_DEFINED) - #undef GLAPIENTRY - #undef GLFW_GLAPIENTRY_DEFINED + + #if defined(GLFW_EXPOSE_NATIVE_WGL) + /* WGL is declared by windows.h */ #endif - #include -#endif + #if defined(GLFW_EXPOSE_NATIVE_NSGL) + /* NSGL is declared by Cocoa.h */ + #endif + #if defined(GLFW_EXPOSE_NATIVE_GLX) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, glx.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif + #include + #endif + #if defined(GLFW_EXPOSE_NATIVE_EGL) + #include + #endif + #if defined(GLFW_EXPOSE_NATIVE_OSMESA) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, osmesa.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif + #include + #endif + +#endif /*GLFW_NATIVE_INCLUDE_NONE*/ /************************************************************************* From 3ec59687f1c1e9eecd5b19eba927502ee4f7fada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 00:14:05 +0200 Subject: [PATCH 056/207] Add credit Related to #2108 (cherry picked from commit d3ede7b6847b66cf30b067214b2b4b126d4c729b) --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 41efe310..bd16bbd3 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -169,6 +169,7 @@ video tutorials. - Pablo Prietz - przemekmirek - pthom + - Martin Pulec - Guillaume Racicot - Philip Rideout - Eddie Ringle From 9f8ec8341132caf683269518bdba8c29658a277c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 16 Jun 2022 13:32:31 +0200 Subject: [PATCH 057/207] Wayland: Cleanup (cherry picked from commit 523fdf50c14210e03434648ee45bade9067fd41c) --- src/wl_window.c | 58 ++++++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index a6b19eb0..81cc3cc6 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1601,51 +1601,31 @@ static void keyboardHandleModifiers(void* userData, 0, group); - unsigned int mods = 0; + _glfw.wl.xkb.modifiers = 0; - if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, - _glfw.wl.xkb.controlIndex, - XKB_STATE_MODS_EFFECTIVE) == 1) + struct { - mods |= GLFW_MOD_CONTROL; - } - - if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, - _glfw.wl.xkb.altIndex, - XKB_STATE_MODS_EFFECTIVE) == 1) + xkb_mod_index_t index; + unsigned int bit; + } modifiers[] = { - mods |= GLFW_MOD_ALT; - } + { _glfw.wl.xkb.controlIndex, GLFW_MOD_CONTROL }, + { _glfw.wl.xkb.altIndex, GLFW_MOD_ALT }, + { _glfw.wl.xkb.shiftIndex, GLFW_MOD_SHIFT }, + { _glfw.wl.xkb.superIndex, GLFW_MOD_SUPER }, + { _glfw.wl.xkb.capsLockIndex, GLFW_MOD_CAPS_LOCK }, + { _glfw.wl.xkb.numLockIndex, GLFW_MOD_NUM_LOCK } + }; - if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, - _glfw.wl.xkb.shiftIndex, - XKB_STATE_MODS_EFFECTIVE) == 1) + for (size_t i = 0; i < sizeof(modifiers) / sizeof(modifiers[0]); i++) { - mods |= GLFW_MOD_SHIFT; + if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, + modifiers[i].index, + XKB_STATE_MODS_EFFECTIVE) == 1) + { + _glfw.wl.xkb.modifiers |= modifiers[i].bit; + } } - - if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, - _glfw.wl.xkb.superIndex, - XKB_STATE_MODS_EFFECTIVE) == 1) - { - mods |= GLFW_MOD_SUPER; - } - - if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, - _glfw.wl.xkb.capsLockIndex, - XKB_STATE_MODS_EFFECTIVE) == 1) - { - mods |= GLFW_MOD_CAPS_LOCK; - } - - if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state, - _glfw.wl.xkb.numLockIndex, - XKB_STATE_MODS_EFFECTIVE) == 1) - { - mods |= GLFW_MOD_NUM_LOCK; - } - - _glfw.wl.xkb.modifiers = mods; } #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION From 581fed38be15576f830e3a95e64f09adf62af477 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 12 Jul 2022 15:24:52 +0200 Subject: [PATCH 058/207] Wayland: Remove support for wl_shell This is adapted to 3.3-stable from 599fb3de348f73134b4e9d2ee5cabc62ca0b84ab and 27295b508ffd098de8673bfe5f7f4154235cb1cc. --- README.md | 1 + docs/compat.dox | 6 +- docs/news.dox | 7 ++ include/GLFW/glfw3.h | 8 +- src/wl_init.c | 14 +-- src/wl_platform.h | 2 - src/wl_window.c | 225 ++++++------------------------------------- 7 files changed, 48 insertions(+), 215 deletions(-) diff --git a/README.md b/README.md index 0331fcd8..9212eeac 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ information on what to include when reporting a bug. - [X11] Bugfix: A malformed response during selection transfer could cause a segfault - [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108) - [Wayland] Added support for file path drop events (#2040) + - [Wayland] Removed support for the deprecated wl\_shell protocol - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` - [Wayland] Bugfix: Data source creation error would cause double free at termination diff --git a/docs/compat.dox b/docs/compat.dox index fea7ab18..0b7c4b0b 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -104,11 +104,7 @@ has been configured in the compositor. GLFW uses the [xdg-shell protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml) to provide better window management. This protocol is part of -wayland-protocols 1.12, and mandatory at build time. If the running compositor -does not support this protocol, the older [wl_shell -interface](https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml#n972) -will be used instead. This will result in a worse integration with the -desktop, especially on tiling compositors. +wayland-protocols 1.12, and mandatory at build time. GLFW uses the [relative pointer protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml) diff --git a/docs/news.dox b/docs/news.dox index b5421c1a..1f016d39 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -378,6 +378,13 @@ Existing projects and makefiles that set the `LIB_SUFFIX` option will use the suffix chosen by the GNUInstallDirs package and the option will be ignored. +@subsubsection wl_shell_33 Support for the wl_shell protocol + +Support for the wl_shell protocol has been removed and GLFW now only supports +the XDG-Shell protocol. If your Wayland compositor does not support XDG-Shell +then GLFW will fail to initialize. + + @subsubsection mir_removed_33 Mir support The experimental Mir support has been completely removed as the Mir project has diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index ba55b6e2..e178eb5e 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3226,10 +3226,6 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland There is no concept of iconification in wl_shell, this - * function will emit @ref GLFW_PLATFORM_ERROR when using this deprecated - * protocol. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify @@ -3809,8 +3805,8 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @remark @wayland The wl_shell protocol has no concept of iconification, - * this callback will never be called when using this deprecated protocol. + * @remark @wayland The XDG-shell protocol has no event for iconification, so + * this callback will never be called. * * @thread_safety This function must only be called from the main thread. * diff --git a/src/wl_init.c b/src/wl_init.c index fffaba3d..3bd0db69 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -76,11 +76,6 @@ static void registryHandleGlobal(void* userData, _glfw.wl.shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); } - else if (strcmp(interface, "wl_shell") == 0) - { - _glfw.wl.shell = - wl_registry_bind(registry, name, &wl_shell_interface, 1); - } else if (strcmp(interface, "wl_output") == 0) { _glfwAddOutputWayland(name, version); @@ -439,6 +434,13 @@ int _glfwPlatformInit(void) if (_glfw.wl.seatVersion >= 4) _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + if (!_glfw.wl.wmBase) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to find xdg-shell in your compositor"); + return GLFW_FALSE; + } + if (_glfw.wl.pointer && _glfw.wl.shm) { cursorTheme = getenv("XCURSOR_THEME"); @@ -529,8 +531,6 @@ void _glfwPlatformTerminate(void) wl_compositor_destroy(_glfw.wl.compositor); if (_glfw.wl.shm) wl_shm_destroy(_glfw.wl.shm); - if (_glfw.wl.shell) - wl_shell_destroy(_glfw.wl.shell); if (_glfw.wl.viewporter) wp_viewporter_destroy(_glfw.wl.viewporter); if (_glfw.wl.decorationManager) diff --git a/src/wl_platform.h b/src/wl_platform.h index 5530b7aa..c4e2db2d 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -185,7 +185,6 @@ typedef struct _GLFWwindowWayland GLFWbool transparent; struct wl_surface* surface; struct wl_egl_window* native; - struct wl_shell_surface* shellSurface; struct wl_callback* callback; struct { @@ -231,7 +230,6 @@ typedef struct _GLFWlibraryWayland 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; diff --git a/src/wl_window.c b/src/wl_window.c index 81cc3cc6..139ab4b9 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -43,72 +43,6 @@ #include #include -static void shellSurfaceHandlePing(void* data, - struct wl_shell_surface* shellSurface, - uint32_t serial) -{ - wl_shell_surface_pong(shellSurface, serial); -} - -static void shellSurfaceHandleConfigure(void* data, - struct wl_shell_surface* shellSurface, - uint32_t edges, - int32_t width, - int32_t height) -{ - _GLFWwindow* window = data; - float aspectRatio; - float targetRatio; - - if (!window->monitor) - { - if (_glfw.wl.viewporter && window->decorated) - { - width -= _GLFW_DECORATION_HORIZONTAL; - height -= _GLFW_DECORATION_VERTICAL; - } - if (width < 1) - width = 1; - if (height < 1) - height = 1; - - if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) - { - aspectRatio = (float)width / (float)height; - targetRatio = (float)window->numer / (float)window->denom; - if (aspectRatio < targetRatio) - height = width / targetRatio; - else if (aspectRatio > targetRatio) - width = height * targetRatio; - } - - if (window->minwidth != GLFW_DONT_CARE && width < window->minwidth) - width = window->minwidth; - else if (window->maxwidth != GLFW_DONT_CARE && width > window->maxwidth) - width = window->maxwidth; - - if (window->minheight != GLFW_DONT_CARE && height < window->minheight) - height = window->minheight; - else if (window->maxheight != GLFW_DONT_CARE && height > window->maxheight) - height = window->maxheight; - } - - _glfwInputWindowSize(window, width, height); - _glfwPlatformSetWindowSize(window, width, height); - _glfwInputWindowDamage(window); -} - -static void shellSurfaceHandlePopupDone(void* data, - struct wl_shell_surface* shellSurface) -{ -} - -static const struct wl_shell_surface_listener shellSurfaceListener = { - shellSurfaceHandlePing, - shellSurfaceHandleConfigure, - shellSurfaceHandlePopupDone -}; - static int createTmpfileCloexec(char* tmpname) { int fd; @@ -546,66 +480,12 @@ static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, window->wl.xdg.toplevel, monitor->wl.output); } - else if (window->wl.shellSurface) - { - wl_shell_surface_set_fullscreen( - window->wl.shellSurface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - refreshRate * 1000, // Convert Hz to mHz. - monitor->wl.output); - } + setIdleInhibitor(window, GLFW_TRUE); if (!window->wl.decorations.serverSide) destroyDecorations(window); } -static GLFWbool createShellSurface(_GLFWwindow* window) -{ - if (!_glfw.wl.shell) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: wl_shell protocol not available"); - return GLFW_FALSE; - } - - window->wl.shellSurface = wl_shell_get_shell_surface(_glfw.wl.shell, - window->wl.surface); - if (!window->wl.shellSurface) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Shell surface creation failed"); - return GLFW_FALSE; - } - - wl_shell_surface_add_listener(window->wl.shellSurface, - &shellSurfaceListener, - window); - - if (window->wl.title) - wl_shell_surface_set_title(window->wl.shellSurface, window->wl.title); - - if (window->monitor) - { - setFullscreen(window, window->monitor, 0); - } - else if (window->wl.maximized) - { - wl_shell_surface_set_maximized(window->wl.shellSurface, NULL); - setIdleInhibitor(window, GLFW_FALSE); - createDecorations(window); - } - else - { - wl_shell_surface_set_toplevel(window->wl.shellSurface); - setIdleInhibitor(window, GLFW_FALSE); - createDecorations(window); - } - - wl_surface_commit(window->wl.surface); - - return GLFW_TRUE; -} - static void xdgToplevelHandleConfigure(void* userData, struct xdg_toplevel* toplevel, int32_t width, @@ -1238,8 +1118,7 @@ static void pointerHandleButton(void* userData, _GLFWwindow* window = _glfw.wl.pointerFocus; int glfwButton; - // Both xdg-shell and wl_shell use the same values. - uint32_t edges = WL_SHELL_SURFACE_RESIZE_NONE; + uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE; if (!window) return; @@ -1251,46 +1130,39 @@ static void pointerHandleButton(void* userData, break; case topDecoration: if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_TOP; + edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP; else { - if (window->wl.xdg.toplevel) - xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); - else - wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, serial); + xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); } break; case leftDecoration: if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_TOP_LEFT; + edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; else - edges = WL_SHELL_SURFACE_RESIZE_LEFT; + edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; break; case rightDecoration: if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_TOP_RIGHT; + edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; else - edges = WL_SHELL_SURFACE_RESIZE_RIGHT; + edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; break; case bottomDecoration: if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT; + edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH) - edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT; + edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; else - edges = WL_SHELL_SURFACE_RESIZE_BOTTOM; + edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; break; default: assert(0); } - if (edges != WL_SHELL_SURFACE_RESIZE_NONE) + if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE) { - if (window->wl.xdg.toplevel) - xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, - serial, edges); - else - wl_shell_surface_resize(window->wl.shellSurface, _glfw.wl.seat, - serial, edges); + xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, + serial, edges); return; } } @@ -1958,9 +1830,6 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->wl.native) wl_egl_window_destroy(window->wl.native); - if (window->wl.shellSurface) - wl_shell_surface_destroy(window->wl.shellSurface); - if (window->wl.xdg.toplevel) xdg_toplevel_destroy(window->wl.xdg.toplevel); @@ -1981,8 +1850,6 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) window->wl.title = _glfw_strdup(title); if (window->wl.xdg.toplevel) xdg_toplevel_set_title(window->wl.xdg.toplevel, title); - else if (window->wl.shellSurface) - wl_shell_surface_set_title(window->wl.shellSurface, title); } void _glfwPlatformSetWindowIcon(_GLFWwindow* window, @@ -2028,23 +1895,15 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight) { - if (_glfw.wl.wmBase) + if (window->wl.xdg.toplevel) { - if (window->wl.xdg.toplevel) - { - if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) - minwidth = minheight = 0; - if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE) - maxwidth = maxheight = 0; - xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); - xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); - wl_surface_commit(window->wl.surface); - } - } - else - { - // TODO: find out how to trigger a resize. - // The actual limits are checked in the wl_shell_surface::configure handler. + if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) + minwidth = minheight = 0; + if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE) + maxwidth = maxheight = 0; + xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); + xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); + wl_surface_commit(window->wl.surface); } } @@ -2052,7 +1911,7 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) { // TODO: find out how to trigger a resize. - // The actual limits are checked in the wl_shell_surface::configure handler. + // The actual limits are checked in the xdg_toplevel::configure handler. } void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, @@ -2093,16 +1952,8 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, void _glfwPlatformIconifyWindow(_GLFWwindow* window) { - if (_glfw.wl.wmBase) - { - if (window->wl.xdg.toplevel) - xdg_toplevel_set_minimized(window->wl.xdg.toplevel); - } - else - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Iconify window not supported on wl_shell"); - } + if (window->wl.xdg.toplevel) + xdg_toplevel_set_minimized(window->wl.xdg.toplevel); } void _glfwPlatformRestoreWindow(_GLFWwindow* window) @@ -2116,11 +1967,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) // There is no way to unset minimized, or even to know if we are // minimized, so there is nothing to do here. } - else if (window->wl.shellSurface) - { - if (window->monitor || window->wl.maximized) - wl_shell_surface_set_toplevel(window->wl.shellSurface); - } + _glfwInputWindowMonitor(window, NULL); window->wl.maximized = GLFW_FALSE; } @@ -2131,11 +1978,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) { xdg_toplevel_set_maximized(window->wl.xdg.toplevel); } - else if (window->wl.shellSurface) - { - // Let the compositor select the best output. - wl_shell_surface_set_maximized(window->wl.shellSurface, NULL); - } + window->wl.maximized = GLFW_TRUE; } @@ -2145,13 +1988,8 @@ void _glfwPlatformShowWindow(_GLFWwindow* window) { // NOTE: The XDG/shell surface is created here so command-line applications // with off-screen windows do not appear in for example the Unity dock - if (_glfw.wl.wmBase) - { - if (!window->wl.xdg.toplevel) - createXdgSurface(window); - } - else if (!window->wl.shellSurface) - createShellSurface(window); + if (!window->wl.xdg.toplevel) + createXdgSurface(window); window->wl.visible = GLFW_TRUE; _glfwInputWindowDamage(window); @@ -2195,8 +2033,6 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, { if (window->wl.xdg.toplevel) xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel); - else if (window->wl.shellSurface) - wl_shell_surface_set_toplevel(window->wl.shellSurface); setIdleInhibitor(window, GLFW_FALSE); if (!_glfw.wl.decorationManager) createDecorations(window); @@ -2211,8 +2047,7 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowIconified(_GLFWwindow* window) { - // wl_shell doesn't have any iconified concept, and xdg-shell doesn’t give - // any way to request whether a surface is iconified. + // xdg-shell doesn’t give any way to request whether a surface is iconified return GLFW_FALSE; } From dea602623d672b918e0845320de5f8304a0a1211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 9 Jun 2022 21:31:44 +0200 Subject: [PATCH 059/207] Wayland: Fix behavior of leaving full screen mode These changes make GLFW fullscreen more consistent, but unfortunately also make GLFW even more oblivious to user-initiated XDG shell fullscreen changes. Fixes #1995 (cherry picked from commit ddd087d6627d19655d78196b5836c1d090b59506) --- CONTRIBUTORS.md | 1 + README.md | 4 +++ src/wl_platform.h | 3 +-- src/wl_window.c | 62 ++++++++++++++++++++++++++++------------------- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index bd16bbd3..b39b44b8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -156,6 +156,7 @@ video tutorials. - Christopher Pelloux - Arturo J. Pérez - Vladimir Perminov + - Olivier Perret - Anthony Pesch - Orson Peters - Emmanuel Gil Peyrot diff --git a/README.md b/README.md index 9212eeac..c1b9b2c4 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,10 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: The OSMesa library was not unloaded on termination - [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_PLATFORM_ERROR` - [Wayland] Bugfix: Lock key modifier bits were only set when lock keys were pressed + - [Wayland] Bugfix: A window leaving full screen mode would be iconified (#1995) + - [Wayland] Bugfix: A window leaving full screen mode ignored its desired size + - [Wayland] Bugfix: `glfwSetWindowMonitor` did not update windowed mode size + - [Wayland] Bugfix: `glfwRestoreWindow` would make a full screen window windowed ## Contact diff --git a/src/wl_platform.h b/src/wl_platform.h index c4e2db2d..618b9dbb 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -181,6 +181,7 @@ typedef struct _GLFWwindowWayland int width, height; GLFWbool visible; GLFWbool maximized; + GLFWbool activated; GLFWbool hovered; GLFWbool transparent; struct wl_surface* surface; @@ -212,8 +213,6 @@ typedef struct _GLFWwindowWayland struct zwp_idle_inhibitor_v1* idleInhibitor; - GLFWbool wasFullscreen; - struct { GLFWbool serverSide; struct wl_buffer* buffer; diff --git a/src/wl_window.c b/src/wl_window.c index 139ab4b9..b35b7319 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -471,21 +471,35 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable) } } -static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, - int refreshRate) +// Make the specified window and its video mode active on its monitor +// +static void acquireMonitor(_GLFWwindow* window) { if (window->wl.xdg.toplevel) { - xdg_toplevel_set_fullscreen( - window->wl.xdg.toplevel, - monitor->wl.output); + xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, + window->monitor->wl.output); } setIdleInhibitor(window, GLFW_TRUE); + if (!window->wl.decorations.serverSide) destroyDecorations(window); } +// Remove the window and restore the original video mode +// +static void releaseMonitor(_GLFWwindow* window) +{ + if (window->wl.xdg.toplevel) + xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel); + + setIdleInhibitor(window, GLFW_FALSE); + + if (!_glfw.wl.decorationManager) + createDecorations(window); +} + static void xdgToplevelHandleConfigure(void* userData, struct xdg_toplevel* toplevel, int32_t width, @@ -538,16 +552,13 @@ static void xdgToplevelHandleConfigure(void* userData, _glfwInputWindowDamage(window); } - if (window->wl.wasFullscreen && window->autoIconify) + if (window->wl.activated && !activated) { - if (!activated || !fullscreen) - { + if (window->monitor && window->autoIconify) _glfwPlatformIconifyWindow(window); - window->wl.wasFullscreen = GLFW_FALSE; - } } - if (fullscreen && activated) - window->wl.wasFullscreen = GLFW_TRUE; + + window->wl.activated = activated; } static void xdgToplevelHandleClose(void* userData, @@ -1960,15 +1971,12 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) { if (window->wl.xdg.toplevel) { - if (window->monitor) - xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel); if (window->wl.maximized) xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); // There is no way to unset minimized, or even to know if we are // minimized, so there is nothing to do here. } - _glfwInputWindowMonitor(window, NULL); window->wl.maximized = GLFW_FALSE; } @@ -2025,19 +2033,23 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, int width, int height, int refreshRate) { - if (monitor) + if (window->monitor == monitor) { - setFullscreen(window, monitor, refreshRate); - } - else - { - if (window->wl.xdg.toplevel) - xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel); - setIdleInhibitor(window, GLFW_FALSE); - if (!_glfw.wl.decorationManager) - createDecorations(window); + if (!monitor) + _glfwPlatformSetWindowSize(window, width, height); + + return; } + + if (window->monitor) + releaseMonitor(window); + _glfwInputWindowMonitor(window, monitor); + + if (window->monitor) + acquireMonitor(window); + else + _glfwPlatformSetWindowSize(window, width, height); } int _glfwPlatformWindowFocused(_GLFWwindow* window) From 562eca6f28005c65ee3cc6551148fc0a08c5d556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 13:29:24 +0200 Subject: [PATCH 060/207] Wayland: Fix maximization by user being ignored The internal maximization state was not updated when an event was received that the user had changed the maximization state of a window, and no maximization events were emitted. This affected both the GLFW_MAXIMIZED attribute and glfwRestoreWindow. (cherry picked from commit f39ffefb6a754677305efab556216f99f90c778a) --- README.md | 3 +++ src/wl_window.c | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c1b9b2c4..881a7bb4 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,9 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: A window leaving full screen mode ignored its desired size - [Wayland] Bugfix: `glfwSetWindowMonitor` did not update windowed mode size - [Wayland] Bugfix: `glfwRestoreWindow` would make a full screen window windowed + - [Wayland] Bugfix: A window maximized or restored by the user would enter an + inconsistent state + - [Wayland] Bugfix: Window maximization events were not emitted ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index b35b7319..e86f69b7 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -558,7 +558,13 @@ static void xdgToplevelHandleConfigure(void* userData, _glfwPlatformIconifyWindow(window); } + if (window->wl.maximized && !maximized) + _glfwInputWindowMaximize(window, GLFW_FALSE); + else if (maximized && !window->wl.maximized) + _glfwInputWindowMaximize(window, GLFW_TRUE); + window->wl.activated = activated; + window->wl.maximized = maximized; } static void xdgToplevelHandleClose(void* userData, @@ -1976,18 +1982,12 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) // There is no way to unset minimized, or even to know if we are // minimized, so there is nothing to do here. } - - window->wl.maximized = GLFW_FALSE; } void _glfwPlatformMaximizeWindow(_GLFWwindow* window) { if (window->wl.xdg.toplevel) - { xdg_toplevel_set_maximized(window->wl.xdg.toplevel); - } - - window->wl.maximized = GLFW_TRUE; } void _glfwPlatformShowWindow(_GLFWwindow* window) From 15050f5711027cc891fcb491da14a5a811eb0081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 19 Jun 2022 18:30:03 +0200 Subject: [PATCH 061/207] Wayland: Fix missing fullscreen code path glfwRestoreWindow assumed it was only called in windowed mode. (cherry picked from commit fdc72edf8177f74b9565094559ebd0a717af93a0) --- README.md | 1 + src/wl_window.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 881a7bb4..b50afcd6 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: A window maximized or restored by the user would enter an inconsistent state - [Wayland] Bugfix: Window maximization events were not emitted + - [Wayland] Bugfix: `glfwRestoreWindow` assumed it was always in windowed mode ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index e86f69b7..da63170d 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1975,13 +1975,21 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window) void _glfwPlatformRestoreWindow(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->monitor) { - if (window->wl.maximized) - xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); // There is no way to unset minimized, or even to know if we are // minimized, so there is nothing to do here. } + else + { + // We assume we are not minimized and acto only on maximization + + if (window->wl.xdg.toplevel) + { + if (window->wl.maximized) + xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); + } + } } void _glfwPlatformMaximizeWindow(_GLFWwindow* window) From 589385aada2a09f4a0b85db407a88a8211254781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 14:10:25 +0200 Subject: [PATCH 062/207] Wayland: Fix glfwSetWindowSize resizing fs windows glfwSetWindowSize would change the size of fullscreen mode windows as if they were windowed mode. (cherry picked from commit 6857995498d6628b3052b547ecd7cdecfee342d6) --- README.md | 1 + src/wl_window.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b50afcd6..d51894ad 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ information on what to include when reporting a bug. inconsistent state - [Wayland] Bugfix: Window maximization events were not emitted - [Wayland] Bugfix: `glfwRestoreWindow` assumed it was always in windowed mode + - [Wayland] Bugfix: `glfwSetWindowSize` would resize a full screen window ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index da63170d..c8a69291 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -548,7 +548,9 @@ static void xdgToplevelHandleConfigure(void* userData, } _glfwInputWindowSize(window, width, height); - _glfwPlatformSetWindowSize(window, width, height); + window->wl.width = width; + window->wl.height = height; + resizeWindow(window); _glfwInputWindowDamage(window); } @@ -1903,9 +1905,16 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { - window->wl.width = width; - window->wl.height = height; - resizeWindow(window); + if (window->monitor) + { + // Video mode setting is not available on Wayland + } + else + { + window->wl.width = width; + window->wl.height = height; + resizeWindow(window); + } } void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, From 608007673fb8ffb440e5678da357e9909be6da23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 14:19:13 +0200 Subject: [PATCH 063/207] Wayland: Fix duplicate window content scale events The window content scale event was emitted every time the window content area was resized, even if its scale had not changed. (cherry picked from commit 0b76e3a6f158549b96d1ae3424f094c63177b2ce) --- README.md | 2 ++ src/wl_window.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d51894ad..cac5bc79 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,8 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Window maximization events were not emitted - [Wayland] Bugfix: `glfwRestoreWindow` assumed it was always in windowed mode - [Wayland] Bugfix: `glfwSetWindowSize` would resize a full screen window + - [Wayland] Bugfix: A window content scale event would be emitted every time + the window resized ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index c8a69291..d8fb0c90 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -356,7 +356,6 @@ static void resizeWindow(_GLFWwindow* window) if (!window->wl.transparent) setOpaqueRegion(window); _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); - _glfwInputWindowContentScale(window, scale, scale); if (!window->wl.decorations.top.surface) return; @@ -403,6 +402,7 @@ static void checkScaleChange(_GLFWwindow* window) { window->wl.scale = maxScale; wl_surface_set_buffer_scale(window->wl.surface, maxScale); + _glfwInputWindowContentScale(window, maxScale, maxScale); resizeWindow(window); } } From 1c4284e44923d7c5a6b361e34efb770e724d0e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 15:45:07 +0200 Subject: [PATCH 064/207] Wayland: Fix glfwInit closing stdin on failure If platform initialization failed before either timer fd member had been set to -1 or a valid fd, termination would close stdin. (cherry picked from commit 3bbb41eacc294d3030303eabfd16f66d452e9a72) --- README.md | 1 + src/wl_init.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cac5bc79..b041f2e7 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: `glfwSetWindowSize` would resize a full screen window - [Wayland] Bugfix: A window content scale event would be emitted every time the window resized + - [Wayland] Bugfix: If `glfwInit` failed it would close stdin ## Contact diff --git a/src/wl_init.c b/src/wl_init.c index 3bd0db69..25d2cb2f 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -314,6 +314,10 @@ int _glfwPlatformInit(void) long cursorSizeLong; int cursorSize; + // These must be set before any failure checks + _glfw.wl.timerfd = -1; + _glfw.wl.cursorTimerfd = -1; + _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0"); if (!_glfw.wl.cursor.handle) { @@ -430,7 +434,6 @@ int _glfwPlatformInit(void) _glfwInitTimerPOSIX(); - _glfw.wl.timerfd = -1; if (_glfw.wl.seatVersion >= 4) _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); From 1ad9c2d5ddc4b8e38b86b4410beab495fc473076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 17 Jun 2022 20:16:34 +0200 Subject: [PATCH 065/207] Wayland: Cleanup (cherry picked from commit 98c9961f3265c1a926e16ff454274e75eda377f2) --- src/wl_monitor.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 3c2ebc55..f11fb874 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -121,9 +121,6 @@ static const struct wl_output_listener outputListener = void _glfwAddOutputWayland(uint32_t name, uint32_t version) { - _GLFWmonitor* monitor; - struct wl_output* output; - if (version < 2) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -131,19 +128,15 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t 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); + struct wl_output* output = wl_registry_bind(_glfw.wl.registry, + name, + &wl_output_interface, + 2); if (!output) - { - _glfwFreeMonitor(monitor); return; - } + // The actual name of this output will be set in the geometry handler + _GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0); monitor->wl.scale = 1; monitor->wl.output = output; monitor->wl.name = name; From 51018f19d0a07b609058644cb0673ad8e85dab33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 15:46:24 +0200 Subject: [PATCH 066/207] Wayland: Use named constants for version checks The wayland-scanner output provides really nice, self-documenting version macros, so we should use them whenever possible. (cherry picked from commit ed39ff43f969b54ba4659293dfaf4d6948f07fed) --- src/wl_init.c | 4 +++- src/wl_window.c | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 25d2cb2f..95fd064d 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -434,8 +434,10 @@ int _glfwPlatformInit(void) _glfwInitTimerPOSIX(); - if (_glfw.wl.seatVersion >= 4) +#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION + if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); +#endif if (!_glfw.wl.wmBase) { diff --git a/src/wl_window.c b/src/wl_window.c index d8fb0c90..3578568f 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -387,8 +387,7 @@ static void resizeWindow(_GLFWwindow* window) static void checkScaleChange(_GLFWwindow* window) { - // Check if we will be able to set the buffer scale or not. - if (_glfw.wl.compositorVersion < 3) + if (_glfw.wl.compositorVersion < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) return; // Get the scale factor from the highest scale monitor. From ebe2b648eae186da302a6645e6358e9e3c84ab87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 18:36:16 +0200 Subject: [PATCH 067/207] Wayland: Add tracking of XDG fullscreen state (cherry picked from commit afb127769a5a39246ae80e2489f0d4cf43a32fbb) --- src/wl_platform.h | 1 + src/wl_window.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 618b9dbb..b8e94295 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -182,6 +182,7 @@ typedef struct _GLFWwindowWayland GLFWbool visible; GLFWbool maximized; GLFWbool activated; + GLFWbool fullscreen; GLFWbool hovered; GLFWbool transparent; struct wl_surface* surface; diff --git a/src/wl_window.c b/src/wl_window.c index 3578568f..b798ec64 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -564,8 +564,9 @@ static void xdgToplevelHandleConfigure(void* userData, else if (maximized && !window->wl.maximized) _glfwInputWindowMaximize(window, GLFW_TRUE); - window->wl.activated = activated; - window->wl.maximized = maximized; + window->wl.activated = activated; + window->wl.maximized = maximized; + window->wl.fullscreen = fullscreen; } static void xdgToplevelHandleClose(void* userData, From e894bf71a26115b03b916ebd99d6f56ccc7fa336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 18:38:06 +0200 Subject: [PATCH 068/207] Wayland: Fix resize events before ack_configure The surface was resized and the size event was emitted before we had sent xdg_surface::ack_configure. If user code then called some GLFW function that commited the surface, those changes would all get applied to the wrong configure event. This postpones size changes until after the ack. (cherry picked from commit e33db6d7aa2b62072f312bd7b723efecf5b7c9ac) --- src/wl_platform.h | 4 +++ src/wl_window.c | 62 +++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index b8e94295..72a695d0 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -189,6 +189,10 @@ typedef struct _GLFWwindowWayland struct wl_egl_window* native; struct wl_callback* callback; + struct { + int width, height; + } pending; + struct { struct xdg_surface* surface; struct xdg_toplevel* toplevel; diff --git a/src/wl_window.c b/src/wl_window.c index b798ec64..6010531b 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -506,8 +506,6 @@ static void xdgToplevelHandleConfigure(void* userData, struct wl_array* states) { _GLFWwindow* window = userData; - float aspectRatio; - float targetRatio; uint32_t* state; GLFWbool maximized = GLFW_FALSE; GLFWbool fullscreen = GLFW_FALSE; @@ -531,28 +529,6 @@ static void xdgToplevelHandleConfigure(void* userData, } } - if (width != 0 && height != 0) - { - if (!maximized && !fullscreen) - { - if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) - { - aspectRatio = (float)width / (float)height; - targetRatio = (float)window->numer / (float)window->denom; - if (aspectRatio < targetRatio) - height = width / targetRatio; - else if (aspectRatio > targetRatio) - width = height * targetRatio; - } - } - - _glfwInputWindowSize(window, width, height); - window->wl.width = width; - window->wl.height = height; - resizeWindow(window); - _glfwInputWindowDamage(window); - } - if (window->wl.activated && !activated) { if (window->monitor && window->autoIconify) @@ -567,6 +543,17 @@ static void xdgToplevelHandleConfigure(void* userData, window->wl.activated = activated; window->wl.maximized = maximized; window->wl.fullscreen = fullscreen; + + if (width && height) + { + window->wl.pending.width = width; + window->wl.pending.height = height; + } + else + { + window->wl.pending.width = window->wl.width; + window->wl.pending.height = window->wl.height; + } } static void xdgToplevelHandleClose(void* userData, @@ -586,7 +573,34 @@ static void xdgSurfaceHandleConfigure(void* userData, struct xdg_surface* surface, uint32_t serial) { + _GLFWwindow* window = userData; + int width = window->wl.pending.width; + int height = window->wl.pending.height; + xdg_surface_ack_configure(surface, serial); + + if (!window->wl.maximized && !window->wl.fullscreen) + { + if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) + { + const float aspectRatio = (float) width / (float) height; + const float targetRatio = (float) window->numer / (float) window->denom; + if (aspectRatio < targetRatio) + height = width / targetRatio; + else if (aspectRatio > targetRatio) + width = height * targetRatio; + } + } + + if (width != window->wl.width || height != window->wl.height) + { + window->wl.width = width; + window->wl.height = height; + resizeWindow(window); + + _glfwInputWindowSize(window, width, height); + _glfwInputWindowDamage(window); + } } static const struct xdg_surface_listener xdgSurfaceListener = { From 5feaa33529882aa427272bd520a866013c846d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 18:51:57 +0200 Subject: [PATCH 069/207] Wayland: Remove superfluous comments These are just repeating parts of the identifier. (cherry picked from commit 2877fea550038d73a8d04feb38af6ca4e4c3a5b6) --- src/wl_window.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 6010531b..1c4ec760 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -360,24 +360,20 @@ static void resizeWindow(_GLFWwindow* window) if (!window->wl.decorations.top.surface) return; - // Top decoration. wp_viewport_set_destination(window->wl.decorations.top.viewport, window->wl.width, _GLFW_DECORATION_TOP); wl_surface_commit(window->wl.decorations.top.surface); - // Left decoration. wp_viewport_set_destination(window->wl.decorations.left.viewport, _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); wl_surface_commit(window->wl.decorations.left.surface); - // Right decoration. wl_subsurface_set_position(window->wl.decorations.right.subsurface, window->wl.width, -_GLFW_DECORATION_TOP); wp_viewport_set_destination(window->wl.decorations.right.viewport, _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); wl_surface_commit(window->wl.decorations.right.surface); - // Bottom decoration. wl_subsurface_set_position(window->wl.decorations.bottom.subsurface, -_GLFW_DECORATION_WIDTH, window->wl.height); wp_viewport_set_destination(window->wl.decorations.bottom.viewport, From f454410b793acec2a40329157b73e484356e2728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 18:53:22 +0200 Subject: [PATCH 070/207] Wayland: Cleanup (cherry picked from commit 040712ce99ea787a85ae68b75fa452ee817274b8) --- src/wl_window.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 1c4ec760..149a58db 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -443,7 +443,8 @@ static void surfaceHandleLeave(void* userData, checkScaleChange(window); } -static const struct wl_surface_listener surfaceListener = { +static const struct wl_surface_listener surfaceListener = +{ surfaceHandleEnter, surfaceHandleLeave }; @@ -599,7 +600,8 @@ static void xdgSurfaceHandleConfigure(void* userData, } } -static const struct xdg_surface_listener xdgSurfaceListener = { +static const struct xdg_surface_listener xdgSurfaceListener = +{ xdgSurfaceHandleConfigure }; From 941744a59a58a8ebb4c49446d4ae8bdbb5899de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 12 Jun 2022 18:47:30 +0200 Subject: [PATCH 071/207] Wayland: Remove unused code path (cherry picked from commit 75295f48781fb2209f4d7cb1a021b299f338996a) --- src/wl_window.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 149a58db..a1351532 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -233,12 +233,10 @@ static GLFWbool waitForData(struct pollfd* fds, nfds_t count, double* timeout) static void createDecoration(_GLFWdecorationWayland* decoration, struct wl_surface* parent, - struct wl_buffer* buffer, GLFWbool opaque, + struct wl_buffer* buffer, int x, int y, int width, int height) { - struct wl_region* region; - decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor); decoration->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, @@ -249,23 +247,17 @@ static void createDecoration(_GLFWdecorationWayland* decoration, wp_viewport_set_destination(decoration->viewport, width, height); wl_surface_attach(decoration->surface, buffer, 0, 0); - if (opaque) - { - region = wl_compositor_create_region(_glfw.wl.compositor); - wl_region_add(region, 0, 0, width, height); - wl_surface_set_opaque_region(decoration->surface, region); - wl_surface_commit(decoration->surface); - wl_region_destroy(region); - } - else - wl_surface_commit(decoration->surface); + struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor); + wl_region_add(region, 0, 0, width, height); + wl_surface_set_opaque_region(decoration->surface, region); + wl_surface_commit(decoration->surface); + wl_region_destroy(region); } static void createDecorations(_GLFWwindow* window) { unsigned char data[] = { 224, 224, 224, 255 }; const GLFWimage image = { 1, 1, data }; - GLFWbool opaque = (data[3] == 255); if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide) return; @@ -276,19 +268,19 @@ static void createDecorations(_GLFWwindow* window) return; createDecoration(&window->wl.decorations.top, window->wl.surface, - window->wl.decorations.buffer, opaque, + window->wl.decorations.buffer, 0, -_GLFW_DECORATION_TOP, window->wl.width, _GLFW_DECORATION_TOP); createDecoration(&window->wl.decorations.left, window->wl.surface, - window->wl.decorations.buffer, opaque, + window->wl.decorations.buffer, -_GLFW_DECORATION_WIDTH, -_GLFW_DECORATION_TOP, _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); createDecoration(&window->wl.decorations.right, window->wl.surface, - window->wl.decorations.buffer, opaque, + window->wl.decorations.buffer, window->wl.width, -_GLFW_DECORATION_TOP, _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); createDecoration(&window->wl.decorations.bottom, window->wl.surface, - window->wl.decorations.buffer, opaque, + window->wl.decorations.buffer, -_GLFW_DECORATION_WIDTH, window->wl.height, window->wl.width + _GLFW_DECORATION_HORIZONTAL, _GLFW_DECORATION_WIDTH); } From 4ba12082397a0ea8b65303ac120d5ab746d4cb79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 16 Jun 2022 01:35:59 +0200 Subject: [PATCH 072/207] Wayland: Rename window frame size constants (cherry picked from commit 24cdc5afda8f36981eb46ae5c8189478774a325f) --- src/wl_platform.h | 5 ---- src/wl_window.c | 59 +++++++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 72a695d0..9616dd7f 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -146,11 +146,6 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st #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 -#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, diff --git a/src/wl_window.c b/src/wl_window.c index a1351532..d0239ed4 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -43,6 +43,9 @@ #include #include +#define GLFW_BORDER_SIZE 4 +#define GLFW_CAPTION_HEIGHT 24 + static int createTmpfileCloexec(char* tmpname) { int fd; @@ -269,20 +272,20 @@ static void createDecorations(_GLFWwindow* window) createDecoration(&window->wl.decorations.top, window->wl.surface, window->wl.decorations.buffer, - 0, -_GLFW_DECORATION_TOP, - window->wl.width, _GLFW_DECORATION_TOP); + 0, -GLFW_CAPTION_HEIGHT, + window->wl.width, GLFW_CAPTION_HEIGHT); createDecoration(&window->wl.decorations.left, window->wl.surface, window->wl.decorations.buffer, - -_GLFW_DECORATION_WIDTH, -_GLFW_DECORATION_TOP, - _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); + -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); createDecoration(&window->wl.decorations.right, window->wl.surface, window->wl.decorations.buffer, - window->wl.width, -_GLFW_DECORATION_TOP, - _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); + window->wl.width, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); createDecoration(&window->wl.decorations.bottom, window->wl.surface, window->wl.decorations.buffer, - -_GLFW_DECORATION_WIDTH, window->wl.height, - window->wl.width + _GLFW_DECORATION_HORIZONTAL, _GLFW_DECORATION_WIDTH); + -GLFW_BORDER_SIZE, window->wl.height, + window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); } static void destroyDecoration(_GLFWdecorationWayland* decoration) @@ -353,23 +356,23 @@ static void resizeWindow(_GLFWwindow* window) return; wp_viewport_set_destination(window->wl.decorations.top.viewport, - window->wl.width, _GLFW_DECORATION_TOP); + window->wl.width, GLFW_CAPTION_HEIGHT); wl_surface_commit(window->wl.decorations.top.surface); wp_viewport_set_destination(window->wl.decorations.left.viewport, - _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); wl_surface_commit(window->wl.decorations.left.surface); wl_subsurface_set_position(window->wl.decorations.right.subsurface, - window->wl.width, -_GLFW_DECORATION_TOP); + window->wl.width, -GLFW_CAPTION_HEIGHT); wp_viewport_set_destination(window->wl.decorations.right.viewport, - _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP); + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); wl_surface_commit(window->wl.decorations.right.surface); wl_subsurface_set_position(window->wl.decorations.bottom.subsurface, - -_GLFW_DECORATION_WIDTH, window->wl.height); + -GLFW_BORDER_SIZE, window->wl.height); wp_viewport_set_destination(window->wl.decorations.bottom.viewport, - window->wl.width + _GLFW_DECORATION_HORIZONTAL, _GLFW_DECORATION_WIDTH); + window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); wl_surface_commit(window->wl.decorations.bottom.surface); } @@ -1099,27 +1102,27 @@ static void pointerHandleMotion(void* userData, _glfw.wl.cursorPreviousName = NULL; return; case topDecoration: - if (y < _GLFW_DECORATION_WIDTH) + if (y < GLFW_BORDER_SIZE) cursorName = "n-resize"; else cursorName = "left_ptr"; break; case leftDecoration: - if (y < _GLFW_DECORATION_WIDTH) + if (y < GLFW_BORDER_SIZE) cursorName = "nw-resize"; else cursorName = "w-resize"; break; case rightDecoration: - if (y < _GLFW_DECORATION_WIDTH) + if (y < GLFW_BORDER_SIZE) cursorName = "ne-resize"; else cursorName = "e-resize"; break; case bottomDecoration: - if (x < _GLFW_DECORATION_WIDTH) + if (x < GLFW_BORDER_SIZE) cursorName = "sw-resize"; - else if (x > window->wl.width + _GLFW_DECORATION_WIDTH) + else if (x > window->wl.width + GLFW_BORDER_SIZE) cursorName = "se-resize"; else cursorName = "s-resize"; @@ -1152,7 +1155,7 @@ static void pointerHandleButton(void* userData, case mainWindow: break; case topDecoration: - if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) + if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP; else { @@ -1160,21 +1163,21 @@ static void pointerHandleButton(void* userData, } break; case leftDecoration: - if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) + if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; break; case rightDecoration: - if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) + if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; break; case bottomDecoration: - if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH) + if (window->wl.cursorPosX < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; - else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH) + else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; @@ -1961,13 +1964,13 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, if (window->decorated && !window->monitor && !window->wl.decorations.serverSide) { if (top) - *top = _GLFW_DECORATION_TOP; + *top = GLFW_CAPTION_HEIGHT; if (left) - *left = _GLFW_DECORATION_WIDTH; + *left = GLFW_BORDER_SIZE; if (right) - *right = _GLFW_DECORATION_WIDTH; + *right = GLFW_BORDER_SIZE; if (bottom) - *bottom = _GLFW_DECORATION_WIDTH; + *bottom = GLFW_BORDER_SIZE; } } From cdbcb8c5a7e94b84ae5afda174676f3fb5b50795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 16 Jun 2022 01:36:55 +0200 Subject: [PATCH 073/207] Wayland: Fix erratic fallback decoration behavior The handler for xdg_toplevel::configure treated the provided size as the content area size when instead it is the size of the bounding rectangle of the wl_surface and all its subsurfaces. This caused the fallback decorations to try positioning themselves outside themselves, causing feedback loops during interactive resizing. Fixes #1991 Fixes #2115 Closes #2127 Related to #1914 (cherry picked from commit 0f5b095042842006747f8dc04aded64ea3e05d2a) --- CONTRIBUTORS.md | 2 ++ README.md | 2 ++ src/wl_window.c | 13 +++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b39b44b8..98cc39a8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -23,6 +23,7 @@ video tutorials. - Waris Boonyasiriwat - Kyle Brenneman - Rok Breulj + - TheBrokenRail - Kai Burjack - Martin Capitanio - Nicolas Caramelli @@ -143,6 +144,7 @@ video tutorials. - Jon Morton - Pierre Moulon - Martins Mozeiko + - James Murphy - Julian Møller - ndogxj - Kristian Nielsen diff --git a/README.md b/README.md index b041f2e7..476c4fe0 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,8 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: A window content scale event would be emitted every time the window resized - [Wayland] Bugfix: If `glfwInit` failed it would close stdin + - [Wayland] Bugfix: Manual resizing with fallback decorations behaved erratically + (#1991,#2115,#2127) ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index d0239ed4..f9045cf9 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -538,8 +538,17 @@ static void xdgToplevelHandleConfigure(void* userData, if (width && height) { - window->wl.pending.width = width; - window->wl.pending.height = height; + if (window->wl.decorations.top.surface) + { + window->wl.pending.width = _glfw_max(0, width - GLFW_BORDER_SIZE * 2); + window->wl.pending.height = + _glfw_max(0, height - GLFW_BORDER_SIZE - GLFW_CAPTION_HEIGHT); + } + else + { + window->wl.pending.width = width; + window->wl.pending.height = height; + } } else { From fead23153e70febdaa2c1acdd70c018f069bfb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 12 Jun 2022 21:36:26 +0200 Subject: [PATCH 074/207] Wayland: Fix size limits for fallback decorations The size limits set on our XDG surface did not include the sizes of the fallback decorations on all sides, when in use. This led to its content area being too small. Related to #2127 (cherry picked from commit a7b6f355008237c28faad86c2188cc5f132aec64) --- README.md | 1 + src/wl_window.c | 53 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 476c4fe0..8de71cc2 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: If `glfwInit` failed it would close stdin - [Wayland] Bugfix: Manual resizing with fallback decorations behaved erratically (#1991,#2115,#2127) + - [Wayland] Bugfix: Size limits included frame size for fallback decorations ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index f9045cf9..4a925c82 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -660,13 +660,6 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) if (window->wl.title) xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title); - if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) - xdg_toplevel_set_min_size(window->wl.xdg.toplevel, - window->minwidth, window->minheight); - if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) - xdg_toplevel_set_max_size(window->wl.xdg.toplevel, - window->maxwidth, window->maxheight); - if (window->monitor) { xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, @@ -685,6 +678,34 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) setXdgDecorations(window); } + if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) + { + int minwidth = window->minwidth; + int minheight = window->minheight; + + if (window->wl.decorations.top.surface) + { + minwidth += GLFW_BORDER_SIZE * 2; + minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + + xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); + } + + if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) + { + int maxwidth = window->maxwidth; + int maxheight = window->maxheight; + + if (window->wl.decorations.top.surface) + { + maxwidth += GLFW_BORDER_SIZE * 2; + maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + + xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); + } + wl_surface_commit(window->wl.surface); wl_display_roundtrip(_glfw.wl.display); @@ -1941,8 +1962,26 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, { if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) minwidth = minheight = 0; + else + { + if (window->wl.decorations.top.surface) + { + minwidth += GLFW_BORDER_SIZE * 2; + minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + } + if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE) maxwidth = maxheight = 0; + else + { + if (window->wl.decorations.top.surface) + { + maxwidth += GLFW_BORDER_SIZE * 2; + maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + } + xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); wl_surface_commit(window->wl.surface); From 8de0c1cdc129b560735db32577933d8839f2fabd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 12 Jun 2022 23:16:16 +0200 Subject: [PATCH 075/207] Wayland: Cleanup (cherry picked from commit 18df0baea60ed17d744eb4b714b8b9363776c0cf) --- src/wl_window.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 4a925c82..79655e77 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -666,14 +666,11 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) window->monitor->wl.output); setIdleInhibitor(window, GLFW_TRUE); } - else if (window->wl.maximized) - { - xdg_toplevel_set_maximized(window->wl.xdg.toplevel); - setIdleInhibitor(window, GLFW_FALSE); - setXdgDecorations(window); - } else { + if (window->wl.maximized) + xdg_toplevel_set_maximized(window->wl.xdg.toplevel); + setIdleInhibitor(window, GLFW_FALSE); setXdgDecorations(window); } From e04a7d152acd81389af702aac06a1ae573da0196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 13 Jun 2022 15:12:52 +0200 Subject: [PATCH 076/207] Wayland: Remove duplicate fullscreen check This check is already performed in shared code. (cherry picked from commit c28d420060a60d579e15afb812d5bd054891179a) --- src/wl_window.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 79655e77..cc948114 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2161,13 +2161,10 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) { - if (!window->monitor) - { - if (enabled) - createDecorations(window); - else - destroyDecorations(window); - } + if (enabled) + createDecorations(window); + else + destroyDecorations(window); } void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) From 8b26801a304fb08dd3aaf0eb8e655820f91b66db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 13 Jun 2022 19:37:34 +0200 Subject: [PATCH 077/207] Wayland: Fix toggling of server-side decorations This is a temporary local fix to have updates to GLFW_DECORATED mostly work as intended. The whole decoration state machine needs to be restructured, but not by this commit. (cherry picked from commit 229d628ec47073c3778ba2e37c02c8d94140be77) --- README.md | 2 ++ src/wl_window.c | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8de71cc2..0ecbcab3 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,8 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Manual resizing with fallback decorations behaved erratically (#1991,#2115,#2127) - [Wayland] Bugfix: Size limits included frame size for fallback decorations + - [Wayland] Bugfix: Updating `GLFW_DECORATED` had no effect on server-side + decorations ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index cc948114..ef5e7a02 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2161,10 +2161,24 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) { - if (enabled) - createDecorations(window); + if (window->wl.xdg.decoration) + { + uint32_t mode; + + if (enabled) + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; + else + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + + zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); + } else - destroyDecorations(window); + { + if (enabled) + createDecorations(window); + else + destroyDecorations(window); + } } void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) From 2529e663d7be39dfbd8defc7f2f0148bea4ea17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 14 Jun 2022 18:12:49 +0200 Subject: [PATCH 078/207] Wayland: Cleanup (cherry picked from commit 33d37782c6551fe67c553dd077ad7ee79f1b76f4) --- src/wl_init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 95fd064d..e041d261 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -146,11 +146,10 @@ static void registryHandleGlobalRemove(void* userData, uint32_t name) { int i; - _GLFWmonitor* monitor; for (i = 0; i < _glfw.monitorCount; ++i) { - monitor = _glfw.monitors[i]; + _GLFWmonitor* monitor = _glfw.monitors[i]; if (monitor->wl.name == name) { _glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0); From 50ea41cb04a865392f3cbe358b2eb29c5cb9eeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 14 Jun 2022 18:20:56 +0200 Subject: [PATCH 079/207] Wayland: Add support for wl_output::name We now use wl_output::name as the GLFW monitor name, on compositors that provide this event. (cherry picked from commit 209f6cf0935412e067e6595790cf3d3d5866923d) --- README.md | 1 + src/wl_monitor.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ecbcab3..5437853a 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ information on what to include when reporting a bug. - [X11] Bugfix: A malformed response during selection transfer could cause a segfault - [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108) - [Wayland] Added support for file path drop events (#2040) + - [Wayland] Added support for more human-readable monitor names where available - [Wayland] Removed support for the deprecated wl\_shell protocol - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of `glfwGetClipboardString` diff --git a/src/wl_monitor.c b/src/wl_monitor.c index f11fb874..52cab9ad 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -53,7 +53,8 @@ static void outputHandleGeometry(void* userData, monitor->widthMM = physicalWidth; monitor->heightMM = physicalHeight; - snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model); + if (strlen(monitor->name) == 0) + snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model); } static void outputHandleMode(void* userData, @@ -106,12 +107,33 @@ static void outputHandleScale(void* userData, monitor->wl.scale = factor; } +#ifdef WL_OUTPUT_NAME_SINCE_VERSION + +void outputHandleName(void* userData, struct wl_output* wl_output, const char* name) +{ + struct _GLFWmonitor* monitor = userData; + + strncpy(monitor->name, name, sizeof(monitor->name) - 1); +} + +void outputHandleDescription(void* userData, + struct wl_output* wl_output, + const char* description) +{ +} + +#endif // WL_OUTPUT_NAME_SINCE_VERSION + static const struct wl_output_listener outputListener = { outputHandleGeometry, outputHandleMode, outputHandleDone, outputHandleScale, +#ifdef WL_OUTPUT_NAME_SINCE_VERSION + outputHandleName, + outputHandleDescription, +#endif }; @@ -128,10 +150,16 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) return; } +#ifdef WL_OUTPUT_NAME_SINCE_VERSION + version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION); +#else + version = 2; +#endif + struct wl_output* output = wl_registry_bind(_glfw.wl.registry, name, &wl_output_interface, - 2); + version); if (!output) return; From 557da4cdc4a6606ea75fd88dd5f41a74b8ba1217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 14 Jun 2022 18:44:24 +0200 Subject: [PATCH 080/207] Wayland: Fix duplicate monitor connection events GLFW would report a monitor as connected each time its wl_output received an update, for example if its scale changed. This would also cause the monitor to be added to the monitor array again, causing glfwTerminate to segfault when it attempted to destroy its already destroyed wl_output. (cherry picked from commit c3ad3d49ed8b436582a6fbba1c3e64f97087e362) --- README.md | 4 ++++ src/wl_monitor.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/README.md b/README.md index 5437853a..f86a7482 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,10 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Size limits included frame size for fallback decorations - [Wayland] Bugfix: Updating `GLFW_DECORATED` had no effect on server-side decorations + - [Wayland] Bugfix: A monitor would be reported as connected again if its scale + changed + - [Wayland] Bugfix: `glfwTerminate` would segfault if any monitor had changed + scale ## Contact diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 52cab9ad..5c97577e 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -95,6 +95,12 @@ static void outputHandleDone(void* userData, struct wl_output* output) monitor->heightMM = (int) (mode->height * 25.4f / 96.f); } + for (int i = 0; i < _glfw.monitorCount; i++) + { + if (_glfw.monitors[i] == monitor) + return; + } + _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST); } From 48e0e0acf5b4e0a94280e1cd4919dd76e5ed57f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 14 Jun 2022 18:46:47 +0200 Subject: [PATCH 081/207] Wayland: Fix reporting of monitor scale changes Content scale events would be emitted when a window surface entered or left an output, but not when one of a window's current outputs had its scale changed. (cherry picked from commit e37ba80b1343f46d1b380fd3b9816e1260d8ee0a) --- README.md | 2 ++ src/wl_monitor.c | 12 ++++++++++++ src/wl_platform.h | 1 + src/wl_window.c | 6 +++--- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f86a7482..d93ca6e6 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,8 @@ information on what to include when reporting a bug. changed - [Wayland] Bugfix: `glfwTerminate` would segfault if any monitor had changed scale + - [Wayland] Bugfix: Window content scale events were not emitted when monitor + scale changed ## Contact diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 5c97577e..99de8933 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -111,6 +111,18 @@ static void outputHandleScale(void* userData, struct _GLFWmonitor* monitor = userData; monitor->wl.scale = factor; + + for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) + { + for (int i = 0; i < window->wl.monitorsCount; i++) + { + if (window->wl.monitors[i] == monitor) + { + _glfwUpdateContentScaleWayland(window); + break; + } + } + } } #ifdef WL_OUTPUT_NAME_SINCE_VERSION diff --git a/src/wl_platform.h b/src/wl_platform.h index 9616dd7f..288cf145 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -358,6 +358,7 @@ typedef struct _GLFWcursorWayland } _GLFWcursorWayland; void _glfwAddOutputWayland(uint32_t name, uint32_t version); +void _glfwUpdateContentScaleWayland(_GLFWwindow* window); GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode); void _glfwAddSeatListenerWayland(struct wl_seat* seat); diff --git a/src/wl_window.c b/src/wl_window.c index ef5e7a02..996bac8b 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -376,7 +376,7 @@ static void resizeWindow(_GLFWwindow* window) wl_surface_commit(window->wl.decorations.bottom.surface); } -static void checkScaleChange(_GLFWwindow* window) +void _glfwUpdateContentScaleWayland(_GLFWwindow* window) { if (_glfw.wl.compositorVersion < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) return; @@ -414,7 +414,7 @@ static void surfaceHandleEnter(void* userData, window->wl.monitors[window->wl.monitorsCount++] = monitor; - checkScaleChange(window); + _glfwUpdateContentScaleWayland(window); } static void surfaceHandleLeave(void* userData, @@ -435,7 +435,7 @@ static void surfaceHandleLeave(void* userData, } window->wl.monitors[--window->wl.monitorsCount] = NULL; - checkScaleChange(window); + _glfwUpdateContentScaleWayland(window); } static const struct wl_surface_listener surfaceListener = From 6b9087c5755bd0a00f439c0bf4b50fdfc905c377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 14 Jun 2022 20:37:31 +0200 Subject: [PATCH 082/207] Wayland: Fix error from glfwSetWindowAspectRatio The aspect ratio was applied during resize but any call to glfwSetWindowAspectRatio emitted a GLFW_FEATURE_UNIMPLEMENTED error. (cherry picked from commit 91f18fb57697c57bf9da64ad546eed5c60518618) --- README.md | 2 ++ src/wl_window.c | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d93ca6e6..bd3c4fc0 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,8 @@ information on what to include when reporting a bug. scale - [Wayland] Bugfix: Window content scale events were not emitted when monitor scale changed + - [Wayland] Bugfix: `glfwSetWindowAspectRatio` reported an error instead of + applying the specified ratio ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index 996bac8b..a693bc08 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1988,8 +1988,20 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) { - // TODO: find out how to trigger a resize. - // The actual limits are checked in the xdg_toplevel::configure handler. + if (window->wl.maximized || window->wl.fullscreen) + return; + + if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) + { + const float aspectRatio = (float) window->wl.width / (float) window->wl.height; + const float targetRatio = (float) numer / (float) denom; + if (aspectRatio < targetRatio) + window->wl.height = window->wl.width / targetRatio; + else if (aspectRatio > targetRatio) + window->wl.width = window->wl.height * targetRatio; + + resizeWindow(window); + } } void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, From 35fd90aff12191ae6aee2afe4b3908bd1fb43513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 14 Jun 2022 22:22:49 +0200 Subject: [PATCH 083/207] Wayland: Cleanup Make Wayland code use 'native' in the same senses as the rest of GLFW. (cherry picked from commit 5002522f7340e2ffb5fae07690b6091cb13ee960) --- src/wl_platform.h | 7 +++++-- src/wl_window.c | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 288cf145..222519b9 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -65,7 +65,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR #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_WINDOW ((EGLNativeWindowType) window->wl.egl.window) #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display) #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl @@ -181,9 +181,12 @@ typedef struct _GLFWwindowWayland GLFWbool hovered; GLFWbool transparent; struct wl_surface* surface; - struct wl_egl_window* native; struct wl_callback* callback; + struct { + struct wl_egl_window* window; + } egl; + struct { int width, height; } pending; diff --git a/src/wl_window.c b/src/wl_window.c index a693bc08..286caa56 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -347,7 +347,7 @@ static void resizeWindow(_GLFWwindow* window) int scale = window->wl.scale; int scaledWidth = window->wl.width * scale; int scaledHeight = window->wl.height * scale; - wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0); + wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0); if (!window->wl.transparent) setOpaqueRegion(window); _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); @@ -709,9 +709,9 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) return GLFW_TRUE; } -static GLFWbool createSurface(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWfbconfig* fbconfig) +static GLFWbool createNativeSurface(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) { window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor); if (!window->wl.surface) @@ -723,10 +723,10 @@ static GLFWbool createSurface(_GLFWwindow* window, wl_surface_set_user_data(window->wl.surface, window); - window->wl.native = wl_egl_window_create(window->wl.surface, - wndconfig->width, - wndconfig->height); - if (!window->wl.native) + window->wl.egl.window = wl_egl_window_create(window->wl.surface, + wndconfig->width, + wndconfig->height); + if (!window->wl.egl.window) return GLFW_FALSE; window->wl.width = wndconfig->width; @@ -1826,7 +1826,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) { - if (!createSurface(window, wndconfig, fbconfig)) + if (!createNativeSurface(window, wndconfig, fbconfig)) return GLFW_FALSE; if (ctxconfig->client != GLFW_NO_API) @@ -1880,8 +1880,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->wl.decorations.buffer) wl_buffer_destroy(window->wl.decorations.buffer); - if (window->wl.native) - wl_egl_window_destroy(window->wl.native); + if (window->wl.egl.window) + wl_egl_window_destroy(window->wl.egl.window); if (window->wl.xdg.toplevel) xdg_toplevel_destroy(window->wl.xdg.toplevel); From 498a4d0635ad91b3d8db553066b8fec09fdb34b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 14 Jun 2022 22:28:05 +0200 Subject: [PATCH 084/207] Wayland: Fix missing error reporting (cherry picked from commit 9ad9f5c52a9e89c598d39ffaa918106c1a096e7f) --- src/wl_window.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wl_window.c b/src/wl_window.c index 286caa56..da830dde 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -715,7 +715,10 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, { window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor); if (!window->wl.surface) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create window surface"); return GLFW_FALSE; + } wl_surface_add_listener(window->wl.surface, &surfaceListener, @@ -727,7 +730,10 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, wndconfig->width, wndconfig->height); if (!window->wl.egl.window) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create EGL window"); return GLFW_FALSE; + } window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; From e79d6fe40a83c897323ab48367dd5b26a9120353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 15 Jun 2022 17:57:54 +0200 Subject: [PATCH 085/207] Wayland: Fix events emitted before ack_configure Window iconfication and maximization events were being emitted before xdg_surface::configure, making it possible for user code to indirectly commit surface changes from those event callbacks before xdg_surface::ack_configure. This postpones those events until after the ack has been sent. (cherry picked from commit 85f5a51912c3329137377cd2ba0f0a7a34887ed7) --- src/wl_platform.h | 4 ++++ src/wl_window.c | 51 ++++++++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 222519b9..66c5886b 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -189,6 +189,10 @@ typedef struct _GLFWwindowWayland struct { int width, height; + GLFWbool maximized; + GLFWbool iconified; + GLFWbool activated; + GLFWbool fullscreen; } pending; struct { diff --git a/src/wl_window.c b/src/wl_window.c index da830dde..bb65e2b3 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -499,43 +499,29 @@ static void xdgToplevelHandleConfigure(void* userData, { _GLFWwindow* window = userData; uint32_t* state; - GLFWbool maximized = GLFW_FALSE; - GLFWbool fullscreen = GLFW_FALSE; - GLFWbool activated = GLFW_FALSE; + + window->wl.pending.activated = GLFW_FALSE; + window->wl.pending.maximized = GLFW_FALSE; + window->wl.pending.fullscreen = GLFW_FALSE; wl_array_for_each(state, states) { switch (*state) { case XDG_TOPLEVEL_STATE_MAXIMIZED: - maximized = GLFW_TRUE; + window->wl.pending.maximized = GLFW_TRUE; break; case XDG_TOPLEVEL_STATE_FULLSCREEN: - fullscreen = GLFW_TRUE; + window->wl.pending.fullscreen = GLFW_TRUE; break; case XDG_TOPLEVEL_STATE_RESIZING: break; case XDG_TOPLEVEL_STATE_ACTIVATED: - activated = GLFW_TRUE; + window->wl.pending.activated = GLFW_TRUE; break; } } - if (window->wl.activated && !activated) - { - if (window->monitor && window->autoIconify) - _glfwPlatformIconifyWindow(window); - } - - if (window->wl.maximized && !maximized) - _glfwInputWindowMaximize(window, GLFW_FALSE); - else if (maximized && !window->wl.maximized) - _glfwInputWindowMaximize(window, GLFW_TRUE); - - window->wl.activated = activated; - window->wl.maximized = maximized; - window->wl.fullscreen = fullscreen; - if (width && height) { if (window->wl.decorations.top.surface) @@ -575,11 +561,30 @@ static void xdgSurfaceHandleConfigure(void* userData, uint32_t serial) { _GLFWwindow* window = userData; - int width = window->wl.pending.width; - int height = window->wl.pending.height; xdg_surface_ack_configure(surface, serial); + if (window->wl.activated != window->wl.pending.activated) + { + window->wl.activated = window->wl.pending.activated; + if (!window->wl.activated) + { + if (window->monitor && window->autoIconify) + xdg_toplevel_set_minimized(window->wl.xdg.toplevel); + } + } + + if (window->wl.maximized != window->wl.pending.maximized) + { + window->wl.maximized = window->wl.pending.maximized; + _glfwInputWindowMaximize(window, window->wl.maximized); + } + + window->wl.fullscreen = window->wl.pending.fullscreen; + + int width = window->wl.pending.width; + int height = window->wl.pending.height; + if (!window->wl.maximized && !window->wl.fullscreen) { if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) From a0259b94264f9d267c7f5da56f63632c26562c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 15 Jun 2022 18:20:16 +0200 Subject: [PATCH 086/207] Wayland: Fix maximized state lost while hidden If a window was created as maximized, or created as hidden and then iconified or maximized before first being shown, that state was lost and the window was shown as restored. (cherry picked from commit 77819c0c549fa9c1aa40ff74289bd7cfae61f296) --- README.md | 2 ++ src/wl_window.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bd3c4fc0..d83c4b50 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,8 @@ information on what to include when reporting a bug. scale changed - [Wayland] Bugfix: `glfwSetWindowAspectRatio` reported an error instead of applying the specified ratio + - [Wayland] Bugfix: `GLFW_MAXIMIZED` window hint had no effect + - [Wayland] Bugfix: `glfwRestoreWindow` had no effect before first show ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index bb65e2b3..187e9c36 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -745,6 +745,8 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, window->wl.scale = 1; window->wl.title = _glfw_strdup(wndconfig->title); + window->wl.maximized = wndconfig->maximized; + window->wl.transparent = fbconfig->transparent; if (!window->wl.transparent) setOpaqueRegion(window); @@ -2068,10 +2070,12 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) { // We assume we are not minimized and acto only on maximization - if (window->wl.xdg.toplevel) + if (window->wl.maximized) { - if (window->wl.maximized) + if (window->wl.xdg.toplevel) xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); + else + window->wl.maximized = GLFW_FALSE; } } } @@ -2080,6 +2084,8 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) { if (window->wl.xdg.toplevel) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); + else + window->wl.maximized = GLFW_TRUE; } void _glfwPlatformShowWindow(_GLFWwindow* window) From 593b85380eccb0e3e4285c085bdbfe82a09cc7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 15 Jun 2022 20:16:40 +0200 Subject: [PATCH 087/207] Wayland: Remove function only called once (cherry picked from commit 0cd1916de39b67878ae178f211921e5606c4485d) --- src/wl_window.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 187e9c36..c297d7a4 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -614,27 +614,6 @@ static const struct xdg_surface_listener xdgSurfaceListener = xdgSurfaceHandleConfigure }; -static void setXdgDecorations(_GLFWwindow* window) -{ - if (_glfw.wl.decorationManager) - { - window->wl.xdg.decoration = - zxdg_decoration_manager_v1_get_toplevel_decoration( - _glfw.wl.decorationManager, window->wl.xdg.toplevel); - zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, - &xdgDecorationListener, - window); - zxdg_toplevel_decoration_v1_set_mode( - window->wl.xdg.decoration, - ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - } - else - { - window->wl.decorations.serverSide = GLFW_FALSE; - createDecorations(window); - } -} - static GLFWbool createXdgSurface(_GLFWwindow* window) { window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase, @@ -677,7 +656,24 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); setIdleInhibitor(window, GLFW_FALSE); - setXdgDecorations(window); + + if (_glfw.wl.decorationManager) + { + window->wl.xdg.decoration = + zxdg_decoration_manager_v1_get_toplevel_decoration( + _glfw.wl.decorationManager, window->wl.xdg.toplevel); + zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, + &xdgDecorationListener, + window); + zxdg_toplevel_decoration_v1_set_mode( + window->wl.xdg.decoration, + ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + } + else + { + window->wl.decorations.serverSide = GLFW_FALSE; + createDecorations(window); + } } if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) From fae1d349d33d818433baf9de55e4c494e0aac178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 20 Jun 2022 00:27:04 +0200 Subject: [PATCH 088/207] Wayland: Rename fallback decoration functions We are soon going to have three kinds of decorations; XDG, libdecor and our last resort fallback ones. (cherry picked from commit eb9c3bee71edd2f72cf212105cb8a9ff5c77a673) --- src/wl_window.c | 70 ++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index c297d7a4..e54419fb 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -234,11 +234,11 @@ static GLFWbool waitForData(struct pollfd* fds, nfds_t count, double* timeout) } } -static void createDecoration(_GLFWdecorationWayland* decoration, - struct wl_surface* parent, - struct wl_buffer* buffer, - int x, int y, - int width, int height) +static void createFallbackDecoration(_GLFWdecorationWayland* decoration, + struct wl_surface* parent, + struct wl_buffer* buffer, + int x, int y, + int width, int height) { decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor); decoration->subsurface = @@ -257,7 +257,7 @@ static void createDecoration(_GLFWdecorationWayland* decoration, wl_region_destroy(region); } -static void createDecorations(_GLFWwindow* window) +static void createFallbackDecorations(_GLFWwindow* window) { unsigned char data[] = { 224, 224, 224, 255 }; const GLFWimage image = { 1, 1, data }; @@ -270,25 +270,25 @@ static void createDecorations(_GLFWwindow* window) if (!window->wl.decorations.buffer) return; - createDecoration(&window->wl.decorations.top, window->wl.surface, - window->wl.decorations.buffer, - 0, -GLFW_CAPTION_HEIGHT, - window->wl.width, GLFW_CAPTION_HEIGHT); - createDecoration(&window->wl.decorations.left, window->wl.surface, - window->wl.decorations.buffer, - -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createDecoration(&window->wl.decorations.right, window->wl.surface, - window->wl.decorations.buffer, - window->wl.width, -GLFW_CAPTION_HEIGHT, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createDecoration(&window->wl.decorations.bottom, window->wl.surface, - window->wl.decorations.buffer, - -GLFW_BORDER_SIZE, window->wl.height, - window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); + createFallbackDecoration(&window->wl.decorations.top, window->wl.surface, + window->wl.decorations.buffer, + 0, -GLFW_CAPTION_HEIGHT, + window->wl.width, GLFW_CAPTION_HEIGHT); + createFallbackDecoration(&window->wl.decorations.left, window->wl.surface, + window->wl.decorations.buffer, + -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); + createFallbackDecoration(&window->wl.decorations.right, window->wl.surface, + window->wl.decorations.buffer, + window->wl.width, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); + createFallbackDecoration(&window->wl.decorations.bottom, window->wl.surface, + window->wl.decorations.buffer, + -GLFW_BORDER_SIZE, window->wl.height, + window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); } -static void destroyDecoration(_GLFWdecorationWayland* decoration) +static void destroyFallbackDecoration(_GLFWdecorationWayland* decoration) { if (decoration->subsurface) wl_subsurface_destroy(decoration->subsurface); @@ -301,12 +301,12 @@ static void destroyDecoration(_GLFWdecorationWayland* decoration) decoration->viewport = NULL; } -static void destroyDecorations(_GLFWwindow* window) +static void destroyFallbackDecorations(_GLFWwindow* window) { - destroyDecoration(&window->wl.decorations.top); - destroyDecoration(&window->wl.decorations.left); - destroyDecoration(&window->wl.decorations.right); - destroyDecoration(&window->wl.decorations.bottom); + destroyFallbackDecoration(&window->wl.decorations.top); + destroyFallbackDecoration(&window->wl.decorations.left); + destroyFallbackDecoration(&window->wl.decorations.right); + destroyFallbackDecoration(&window->wl.decorations.bottom); } static void xdgDecorationHandleConfigure(void* userData, @@ -318,7 +318,7 @@ static void xdgDecorationHandleConfigure(void* userData, window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); if (!window->wl.decorations.serverSide) - createDecorations(window); + createFallbackDecorations(window); } static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = @@ -475,7 +475,7 @@ static void acquireMonitor(_GLFWwindow* window) setIdleInhibitor(window, GLFW_TRUE); if (!window->wl.decorations.serverSide) - destroyDecorations(window); + destroyFallbackDecorations(window); } // Remove the window and restore the original video mode @@ -488,7 +488,7 @@ static void releaseMonitor(_GLFWwindow* window) setIdleInhibitor(window, GLFW_FALSE); if (!_glfw.wl.decorationManager) - createDecorations(window); + createFallbackDecorations(window); } static void xdgToplevelHandleConfigure(void* userData, @@ -672,7 +672,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) else { window->wl.decorations.serverSide = GLFW_FALSE; - createDecorations(window); + createFallbackDecorations(window); } } @@ -1882,7 +1882,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->context.destroy) window->context.destroy(window); - destroyDecorations(window); + destroyFallbackDecorations(window); if (window->wl.xdg.decoration) zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration); @@ -2200,9 +2200,9 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) else { if (enabled) - createDecorations(window); + createFallbackDecorations(window); else - destroyDecorations(window); + destroyFallbackDecorations(window); } } From c807f386c28738edd330ccb6f81431e9e1b7c5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 20 Jun 2022 00:43:24 +0200 Subject: [PATCH 089/207] Wayland: Fix mapping failure on wlroots compositor When showing a window that had already been shown once (and so already had its shell objects), GLFW would attach a new buffer and commit it before waiting for the next configure event. This was a violation of the XDG shell protocol. This was allowed to work as intended on GNOME and KDE without error. However wlroots based compositors would (correctly) emit an error. Unfortunately, I haven't been able to find a way to get both KDE, GNOME and Sway to send the configure event we need in order to map the wl_surface again while keeping our existing shell objects, so with this commit we now create them for each call to glfwShowWindow and destroy them for each call to glfwHideWindow. Fixes #1268 (cherry picked from commit 83a134a92fa8642fe50c6e9b2400044e442d038a) --- README.md | 2 ++ src/wl_window.c | 52 +++++++++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d83c4b50..6b789908 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,8 @@ information on what to include when reporting a bug. applying the specified ratio - [Wayland] Bugfix: `GLFW_MAXIMIZED` window hint had no effect - [Wayland] Bugfix: `glfwRestoreWindow` had no effect before first show + - [Wayland] Bugfix: Hiding and then showing a window caused program abort on + wlroots compositors (#1268) ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index e54419fb..6d301da8 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -605,6 +605,14 @@ static void xdgSurfaceHandleConfigure(void* userData, resizeWindow(window); _glfwInputWindowSize(window, width, height); + + if (window->wl.visible) + _glfwInputWindowDamage(window); + } + + if (!window->wl.visible) + { + window->wl.visible = GLFW_TRUE; _glfwInputWindowDamage(window); } } @@ -614,7 +622,7 @@ static const struct xdg_surface_listener xdgSurfaceListener = xdgSurfaceHandleConfigure }; -static GLFWbool createXdgSurface(_GLFWwindow* window) +static GLFWbool createShellObjects(_GLFWwindow* window) { window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase, window->wl.surface); @@ -710,6 +718,24 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) return GLFW_TRUE; } +static void destroyShellObjects(_GLFWwindow* window) +{ + destroyFallbackDecorations(window); + + if (window->wl.xdg.decoration) + zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration); + + if (window->wl.xdg.toplevel) + xdg_toplevel_destroy(window->wl.xdg.toplevel); + + if (window->wl.xdg.surface) + xdg_surface_destroy(window->wl.xdg.surface); + + window->wl.xdg.decoration = NULL; + window->wl.xdg.toplevel = NULL; + window->wl.xdg.surface = NULL; +} + static GLFWbool createNativeSurface(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) @@ -749,10 +775,8 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, if (window->monitor || wndconfig->visible) { - if (!createXdgSurface(window)) + if (!createShellObjects(window)) return GLFW_FALSE; - - window->wl.visible = GLFW_TRUE; } return GLFW_TRUE; @@ -1882,9 +1906,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->context.destroy) window->context.destroy(window); - destroyFallbackDecorations(window); - if (window->wl.xdg.decoration) - zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration); + destroyShellObjects(window); if (window->wl.decorations.buffer) wl_buffer_destroy(window->wl.decorations.buffer); @@ -1892,12 +1914,6 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->wl.egl.window) wl_egl_window_destroy(window->wl.egl.window); - if (window->wl.xdg.toplevel) - xdg_toplevel_destroy(window->wl.xdg.toplevel); - - if (window->wl.xdg.surface) - xdg_surface_destroy(window->wl.xdg.surface); - if (window->wl.surface) wl_surface_destroy(window->wl.surface); @@ -2086,15 +2102,11 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window) { - if (!window->wl.visible) + if (!window->wl.xdg.toplevel) { // NOTE: The XDG/shell surface is created here so command-line applications // with off-screen windows do not appear in for example the Unity dock - if (!window->wl.xdg.toplevel) - createXdgSurface(window); - - window->wl.visible = GLFW_TRUE; - _glfwInputWindowDamage(window); + createShellObjects(window); } } @@ -2103,6 +2115,8 @@ void _glfwPlatformHideWindow(_GLFWwindow* window) if (window->wl.visible) { window->wl.visible = GLFW_FALSE; + destroyShellObjects(window); + wl_surface_attach(window->wl.surface, NULL, 0, 0); wl_surface_commit(window->wl.surface); } From 4c7f6ada0c4dd6fbe30cc1579d31ad077eedb093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 20 Jun 2022 22:20:56 +0200 Subject: [PATCH 090/207] Wayland: Store and act on XDG decoration mode Refer to the XDG decoration mode (or the lack of one) directly instead of setting a boolean in a struct meant for the fallback decorations. This makes things a bit more verbose but is in preparation for a refactoring of all decoration paths. (cherry picked from commit 2df0ce07faead09b1d305d30cf68d95c1145c37c) --- src/wl_platform.h | 2 +- src/wl_window.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 66c5886b..bd59fcd1 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -199,6 +199,7 @@ typedef struct _GLFWwindowWayland struct xdg_surface* surface; struct xdg_toplevel* toplevel; struct zxdg_toplevel_decoration_v1* decoration; + uint32_t decorationMode; } xdg; _GLFWcursor* currentCursor; @@ -221,7 +222,6 @@ typedef struct _GLFWwindowWayland struct zwp_idle_inhibitor_v1* idleInhibitor; struct { - GLFWbool serverSide; struct wl_buffer* buffer; _GLFWdecorationWayland top, left, right, bottom; int focus; diff --git a/src/wl_window.c b/src/wl_window.c index 6d301da8..a95c37ba 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -262,7 +262,7 @@ static void createFallbackDecorations(_GLFWwindow* window) unsigned char data[] = { 224, 224, 224, 255 }; const GLFWimage image = { 1, 1, data }; - if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide) + if (!_glfw.wl.viewporter || !window->decorated) return; if (!window->wl.decorations.buffer) @@ -315,9 +315,9 @@ static void xdgDecorationHandleConfigure(void* userData, { _GLFWwindow* window = userData; - window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + window->wl.xdg.decorationMode = mode; - if (!window->wl.decorations.serverSide) + if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) createFallbackDecorations(window); } @@ -474,7 +474,7 @@ static void acquireMonitor(_GLFWwindow* window) setIdleInhibitor(window, GLFW_TRUE); - if (!window->wl.decorations.serverSide) + if (window->wl.decorations.top.surface) destroyFallbackDecorations(window); } @@ -487,7 +487,7 @@ static void releaseMonitor(_GLFWwindow* window) setIdleInhibitor(window, GLFW_FALSE); - if (!_glfw.wl.decorationManager) + if (window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) createFallbackDecorations(window); } @@ -678,10 +678,7 @@ static GLFWbool createShellObjects(_GLFWwindow* window) ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); } else - { - window->wl.decorations.serverSide = GLFW_FALSE; createFallbackDecorations(window); - } } if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) @@ -732,6 +729,7 @@ static void destroyShellObjects(_GLFWwindow* window) xdg_surface_destroy(window->wl.xdg.surface); window->wl.xdg.decoration = NULL; + window->wl.xdg.decorationMode = 0; window->wl.xdg.toplevel = NULL; window->wl.xdg.surface = NULL; } @@ -2043,7 +2041,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom) { - if (window->decorated && !window->monitor && !window->wl.decorations.serverSide) + if (window->decorated && !window->monitor && window->wl.decorations.top.surface) { if (top) *top = GLFW_CAPTION_HEIGHT; From 8f9ddfe3c275dbb69e15f8d1cc163a6a3b728634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 20 Jun 2022 22:21:41 +0200 Subject: [PATCH 091/207] Wayland: Fix map before XDG decoration configure If the xdg_toplevel has a decoration, we need to wait for its first configure event as well before we are allowed to attach the first buffer. It seems racy to assume that this will always happen inside the first surface configure sequence, so this commit makes that condition explicit. This may turn out to have been overly defensive. (cherry picked from commit 3203599cac774c4aa48dc17eb963f4a90c6d70ff) --- src/wl_window.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index a95c37ba..459f4b5b 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -612,8 +612,13 @@ static void xdgSurfaceHandleConfigure(void* userData, if (!window->wl.visible) { - window->wl.visible = GLFW_TRUE; - _glfwInputWindowDamage(window); + // Allow the window to be mapped only if it either has no XDG + // decorations or they have already received a configure event + if (!window->wl.xdg.decoration || window->wl.xdg.decorationMode) + { + window->wl.visible = GLFW_TRUE; + _glfwInputWindowDamage(window); + } } } From 17959aad33a75e050f606cc49b8ac6eaaa005399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 20 Jun 2022 22:36:23 +0200 Subject: [PATCH 092/207] Wayland: Fix GLFW_DECORATED for XDG decorations On a compositor that supports server-side decorations, they were always enabled in windowed mode, even if GLFW_DECORATED was cleared. (cherry picked from commit f35e2274cbf253b659e9847354fe72d7b45dcc9a) --- README.md | 2 ++ src/wl_window.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6b789908..527947a8 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,8 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: `glfwRestoreWindow` had no effect before first show - [Wayland] Bugfix: Hiding and then showing a window caused program abort on wlroots compositors (#1268) + - [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG + decorations ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index 459f4b5b..a98b62ca 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -678,9 +678,15 @@ static GLFWbool createShellObjects(_GLFWwindow* window) zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, &xdgDecorationListener, window); - zxdg_toplevel_decoration_v1_set_mode( - window->wl.xdg.decoration, - ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + + uint32_t mode; + + if (window->decorated) + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; + else + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + + zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); } else createFallbackDecorations(window); From aef1d4584fadd2254de5f714a8e0815d0bd905c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 20 Jun 2022 22:48:35 +0200 Subject: [PATCH 093/207] Wayland: Fix transition to server-side decorations (cherry picked from commit 29b7669bc6a42de729a59abc96ce8849654751c7) --- src/wl_window.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wl_window.c b/src/wl_window.c index a98b62ca..d11e5f93 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -319,6 +319,8 @@ static void xdgDecorationHandleConfigure(void* userData, if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) createFallbackDecorations(window); + else + destroyFallbackDecorations(window); } static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = From 7b65ecf77c6980d8d9a39bb38dad688cf4dac86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 20 Jun 2022 22:57:18 +0200 Subject: [PATCH 094/207] Wayland: Use enum type to store enum value (cherry picked from commit 80dc0533cf7234517328537a54b7675f0588713c) --- src/wl_platform.h | 2 +- src/wl_window.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index bd59fcd1..2146e2ad 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -224,7 +224,7 @@ typedef struct _GLFWwindowWayland struct { struct wl_buffer* buffer; _GLFWdecorationWayland top, left, right, bottom; - int focus; + _GLFWdecorationSideWayland focus; } decorations; } _GLFWwindowWayland; diff --git a/src/wl_window.c b/src/wl_window.c index d11e5f93..84d371c2 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1019,9 +1019,9 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime } static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, - int* which) + _GLFWdecorationSideWayland* which) { - int focus; + _GLFWdecorationSideWayland focus; _GLFWwindow* window = _glfw.windowListHead; if (!which) which = &focus; @@ -1063,7 +1063,7 @@ static void pointerHandleEnter(void* userData, if (!surface) return; - int focus = 0; + _GLFWdecorationSideWayland focus = mainWindow; _GLFWwindow* window = wl_surface_get_user_data(surface); if (!window) { From 75b37bd2d7238aa4c43cae1a8c80ae6784de9383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 15:23:32 +0200 Subject: [PATCH 095/207] Wayland: Rename function to its purpose (cherry picked from commit 47193f15de529b6e7c182168b1c17f29bda9de4b) --- src/wl_window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 84d371c2..56622ba1 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -329,7 +329,7 @@ static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = }; // Makes the surface considered as XRGB instead of ARGB. -static void setOpaqueRegion(_GLFWwindow* window) +static void setContentAreaOpaque(_GLFWwindow* window) { struct wl_region* region; @@ -351,7 +351,7 @@ static void resizeWindow(_GLFWwindow* window) int scaledHeight = window->wl.height * scale; wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0); if (!window->wl.transparent) - setOpaqueRegion(window); + setContentAreaOpaque(window); _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); if (!window->wl.decorations.top.surface) @@ -782,7 +782,7 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, window->wl.transparent = fbconfig->transparent; if (!window->wl.transparent) - setOpaqueRegion(window); + setContentAreaOpaque(window); if (window->monitor || wndconfig->visible) { From 1ac6fbc49999bb80820ad6906e71a1b7d6a61a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 17:37:37 +0200 Subject: [PATCH 096/207] Wayland: Remove premature surface commit calls Note that the handling of configure events, acks and commits is still not ideal. This is just a small step in, hopefully, a good direction. Fullscreen toggling via glfwSetWindowMonitor now works on Weston, but mostly incidentally. (cherry picked from commit be7f4513c05a45e6252f940408e139741a462986) --- src/wl_window.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 56622ba1..b11dd02d 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -339,7 +339,6 @@ static void setContentAreaOpaque(_GLFWwindow* window) wl_region_add(region, 0, 0, window->wl.width, window->wl.height); wl_surface_set_opaque_region(window->wl.surface, region); - wl_surface_commit(window->wl.surface); wl_region_destroy(region); } @@ -2296,7 +2295,6 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) zwp_locked_pointer_v1_set_cursor_position_hint( window->wl.pointerLock.lockedPointer, wl_fixed_from_double(x), wl_fixed_from_double(y)); - wl_surface_commit(window->wl.surface); } } From 758d4b1987148c5b73dcff3267a2b6102e90a563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 19:37:35 +0200 Subject: [PATCH 097/207] Wayland: Make function behavior match name The logic that checks the decorated attribute belongs on the outside along with other related checks (fullscreen, monitor, decoration mode). (cherry picked from commit c4fbe80d90ac7f4bd2fc0f02afccdc4d45489cbf) --- src/wl_window.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index b11dd02d..482d90c6 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -262,7 +262,7 @@ static void createFallbackDecorations(_GLFWwindow* window) unsigned char data[] = { 224, 224, 224, 255 }; const GLFWimage image = { 1, 1, data }; - if (!_glfw.wl.viewporter || !window->decorated) + if (!_glfw.wl.viewporter) return; if (!window->wl.decorations.buffer) @@ -318,7 +318,10 @@ static void xdgDecorationHandleConfigure(void* userData, window->wl.xdg.decorationMode = mode; if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) - createFallbackDecorations(window); + { + if (window->decorated) + createFallbackDecorations(window); + } else destroyFallbackDecorations(window); } @@ -489,7 +492,10 @@ static void releaseMonitor(_GLFWwindow* window) setIdleInhibitor(window, GLFW_FALSE); if (window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) - createFallbackDecorations(window); + { + if (window->decorated) + createFallbackDecorations(window); + } } static void xdgToplevelHandleConfigure(void* userData, @@ -690,7 +696,10 @@ static GLFWbool createShellObjects(_GLFWwindow* window) zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); } else - createFallbackDecorations(window); + { + if (window->decorated) + createFallbackDecorations(window); + } } if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) From be333cf0fdaf9a4ce690905a210044210911f3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 19:48:28 +0200 Subject: [PATCH 098/207] Wayland: Cleanup This moves what is effectively showing the window to where that is done on other platforms, i.e. last in the platform CreateWindow function. (cherry picked from commit 74b4ceb8354bbe3eb4d225bcc07c4ed4023ca1f2) --- src/wl_window.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 482d90c6..fd625dbe 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -792,12 +792,6 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, if (!window->wl.transparent) setContentAreaOpaque(window); - if (window->monitor || wndconfig->visible) - { - if (!createShellObjects(window)) - return GLFW_FALSE; - } - return GLFW_TRUE; } @@ -1903,6 +1897,12 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, return GLFW_FALSE; } + if (window->monitor || wndconfig->visible) + { + if (!createShellObjects(window)) + return GLFW_FALSE; + } + return GLFW_TRUE; } From e541b7969ace57dbb448ae6adff02bd0a726ade4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 19:52:39 +0200 Subject: [PATCH 099/207] Wayland: Only create EGL window if using EGL (cherry picked from commit d578c2ddfeb6a31c532ddc29de289762745548d2) --- src/wl_window.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index fd625dbe..907ce70a 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -351,7 +351,9 @@ static void resizeWindow(_GLFWwindow* window) int scale = window->wl.scale; int scaledWidth = window->wl.width * scale; int scaledHeight = window->wl.height * scale; - wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0); + + if (window->wl.egl.window) + wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0); if (!window->wl.transparent) setContentAreaOpaque(window); _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); @@ -772,15 +774,6 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, wl_surface_set_user_data(window->wl.surface, window); - window->wl.egl.window = wl_egl_window_create(window->wl.surface, - wndconfig->width, - wndconfig->height); - if (!window->wl.egl.window) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create EGL window"); - return GLFW_FALSE; - } - window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; window->wl.scale = 1; @@ -1880,6 +1873,16 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, if (ctxconfig->source == GLFW_EGL_CONTEXT_API || ctxconfig->source == GLFW_NATIVE_CONTEXT_API) { + window->wl.egl.window = wl_egl_window_create(window->wl.surface, + wndconfig->width, + wndconfig->height); + if (!window->wl.egl.window) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create EGL window"); + return GLFW_FALSE; + } + if (!_glfwInitEGL()) return GLFW_FALSE; if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) From 0cd8813e82003abbd265018707a018babb19f576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 20:50:48 +0200 Subject: [PATCH 100/207] Wayland: Do not decorate fullscreen windows If a fullscreen window with GLFW_DECORATED set had its XDG decorations changed to client mode by the compositor, it would seemingly receive GLFW fallback decorations as if it was windowed mode. This is possibly related to #2001. (cherry picked from commit da6713cd096a40a4512f468b34c189017e73f987) --- src/wl_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wl_window.c b/src/wl_window.c index 907ce70a..6c925a65 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -319,7 +319,7 @@ static void xdgDecorationHandleConfigure(void* userData, if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) { - if (window->decorated) + if (window->decorated && !window->monitor) createFallbackDecorations(window); } else From 70a024232a40df0690c22631bc36268a0000b577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Jun 2022 21:11:10 +0200 Subject: [PATCH 101/207] Cocoa: Disable macOS fullscreen when non-resizable Windows with GLFW_RESIZABLE set to false should not be resizable by the user. This is adapted to 3.3-stable from 98d6e8485b327288f5b53e59e6cc2267e28376bd and 36f0bf00a92b15e301bb28e840a4361e0b74b123. --- README.md | 1 + src/cocoa_window.m | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/README.md b/README.md index 527947a8..47f04aa0 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ information on what to include when reporting a bug. match event scancode (#1993) - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) - [Win32] Bugfix: The OSMesa library was not unloaded on termination + - [Cocoa] Disabled macOS fullscreen when `GLFW_RESIZABLE` is false - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination - [X11] Bugfix: The OSMesa libray was not unloaded on termination diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 16198949..f66ade50 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -31,6 +31,10 @@ #include #include +// HACK: This enum value is missing from framework headers on OS X 10.11 despite +// having been (according to documentation) added in Mac OS X 10.7 +#define NSWindowCollectionBehaviorFullScreenNone (1 << 9) + // Returns the style mask corresponding to the window settings // static NSUInteger getStyleMask(_GLFWwindow* window) @@ -837,6 +841,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, NSWindowCollectionBehaviorManaged; [window->ns.object setCollectionBehavior:behavior]; } + else + { + const NSWindowCollectionBehavior behavior = + NSWindowCollectionBehaviorFullScreenNone; + [window->ns.object setCollectionBehavior:behavior]; + } if (wndconfig->floating) [window->ns.object setLevel:NSFloatingWindowLevel]; @@ -1299,6 +1309,20 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, else [window->ns.object setLevel:NSNormalWindowLevel]; + if (window->resizable) + { + const NSWindowCollectionBehavior behavior = + NSWindowCollectionBehaviorFullScreenPrimary | + NSWindowCollectionBehaviorManaged; + [window->ns.object setCollectionBehavior:behavior]; + } + else + { + const NSWindowCollectionBehavior behavior = + NSWindowCollectionBehaviorFullScreenNone; + [window->ns.object setCollectionBehavior:behavior]; + } + [window->ns.object setHasShadow:YES]; // HACK: Clearing NSWindowStyleMaskTitled resets and disables the window // title property but the miniwindow title property is unaffected @@ -1364,7 +1388,23 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) { @autoreleasepool { + [window->ns.object setStyleMask:getStyleMask(window)]; + + if (enabled) + { + const NSWindowCollectionBehavior behavior = + NSWindowCollectionBehaviorFullScreenPrimary | + NSWindowCollectionBehaviorManaged; + [window->ns.object setCollectionBehavior:behavior]; + } + else + { + const NSWindowCollectionBehavior behavior = + NSWindowCollectionBehaviorFullScreenNone; + [window->ns.object setCollectionBehavior:behavior]; + } + } // autoreleasepool } From e50ee39eac430af865c92cda61c1ea21d19189d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Jun 2022 22:08:52 +0200 Subject: [PATCH 102/207] Cocoa: Fix GLFW_MAXIMIZED for nonresizable windows The reasoning here is that glfwRestoreWindow will change nothing for a windowed non-resizable window on Cocoa, and silently refusing to maximize seems slightly more like something other platforms would do. This is possibly either the right thing to do or the wrong one. (cherry picked from commit 6f8ec4075be53b17c08cfe4f83f02157cc7bcc12) --- README.md | 1 + src/cocoa_window.m | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 47f04aa0..9b5cfe5d 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ information on what to include when reporting a bug. - [Cocoa] Disabled macOS fullscreen when `GLFW_RESIZABLE` is false - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination + - [Cocoa] Bugfix: `GLFW_MAXIMIZED` was always true when `GLFW_RESIZABLE` was false - [X11] Bugfix: The OSMesa libray was not unloaded on termination - [X11] Bugfix: A malformed response during selection transfer could cause a segfault - [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index f66ade50..42a8f74e 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1356,7 +1356,12 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window) int _glfwPlatformWindowMaximized(_GLFWwindow* window) { @autoreleasepool { - return [window->ns.object isZoomed]; + + if (window->resizable) + return [window->ns.object isZoomed]; + else + return GLFW_FALSE; + } // autoreleasepool } From 9950cc52df60c21eda0896ff14b2357fe1f7b114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 1 Jul 2022 18:19:19 +0200 Subject: [PATCH 103/207] Cocoa: Fix clearing of unrelated window style bits Whenever GLFW changed the window style mask, a new mask was created from scratch based on the attributes set on the GLFW window object. This caused us to potentially clear unrelated window style bits. This was always wrong but became a critical issue when Cocoa began throwing an exception if an application cleared the NSWindowStyleMaskFullScreen while the window is in macOS fullscreen. This commit reworks all style mask editing so it only changes the relevant bits, preserving all others. This is only a narrow bug fix to prevent crashes, intended for the stable branch. Our interaction with macOS fullscreen is still very poor. The next step after this is a set of patches that improve the interaction between the current API and macOS fullscreen. Fixes #1886 Fixes #2110 (cherry picked from commit 0d599026d04ddcc2695ae938fc1864523dab7a34) --- CONTRIBUTORS.md | 2 ++ README.md | 4 +++ src/cocoa_window.m | 80 +++++++++++++++++++++++++++++++--------------- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 98cc39a8..bf94a7fb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -83,6 +83,7 @@ video tutorials. - heromyth - Lucas Hinderberger - Paul Holden + - Hajime Hoshi - Warren Hu - Charles Huber - Brent Huisman @@ -147,6 +148,7 @@ video tutorials. - James Murphy - Julian Møller - ndogxj + - F. Nedelec - Kristian Nielsen - Kamil Nowakowski - onox diff --git a/README.md b/README.md index 9b5cfe5d..24260eba 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,10 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination - [Cocoa] Bugfix: `GLFW_MAXIMIZED` was always true when `GLFW_RESIZABLE` was false + - [Cocoa] Bugfix: Changing `GLFW_DECORATED` in macOS fullscreen would abort + application (#1886) + - [Cocoa] Bugfix: Setting a monitor from macOS fullscreen would abort + application (#2110) - [X11] Bugfix: The OSMesa libray was not unloaded on termination - [X11] Bugfix: A malformed response during selection transfer could cause a segfault - [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 42a8f74e..bbab6c4f 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -35,26 +35,6 @@ // having been (according to documentation) added in Mac OS X 10.7 #define NSWindowCollectionBehaviorFullScreenNone (1 << 9) -// Returns the style mask corresponding to the window settings -// -static NSUInteger getStyleMask(_GLFWwindow* window) -{ - NSUInteger styleMask = NSWindowStyleMaskMiniaturizable; - - if (window->monitor || !window->decorated) - styleMask |= NSWindowStyleMaskBorderless; - else - { - styleMask |= NSWindowStyleMaskTitled | - NSWindowStyleMaskClosable; - - if (window->resizable) - styleMask |= NSWindowStyleMaskResizable; - } - - return styleMask; -} - // Returns whether the cursor is in the content area of the specified window // static GLFWbool cursorInContentArea(_GLFWwindow* window) @@ -813,9 +793,21 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, else contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height); + NSUInteger styleMask = NSWindowStyleMaskMiniaturizable; + + if (window->monitor || !window->decorated) + styleMask |= NSWindowStyleMaskBorderless; + else + { + styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable); + + if (window->resizable) + styleMask |= NSWindowStyleMaskResizable; + } + window->ns.object = [[GLFWWindow alloc] initWithContentRect:contentRect - styleMask:getStyleMask(window) + styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]; @@ -1244,9 +1236,10 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, { const NSRect contentRect = NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), width, height); + const NSUInteger styleMask = [window->ns.object styleMask]; const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect - styleMask:getStyleMask(window)]; + styleMask:styleMask]; [window->ns.object setFrame:frameRect display:YES]; } @@ -1263,7 +1256,27 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, // TODO: Solve this in a less terrible way _glfwPlatformPollEvents(); - const NSUInteger styleMask = getStyleMask(window); + NSUInteger styleMask = [window->ns.object styleMask]; + + if (window->monitor) + { + styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable); + styleMask |= NSWindowStyleMaskBorderless; + } + else + { + if (window->decorated) + { + styleMask &= ~NSWindowStyleMaskBorderless; + styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable); + } + + if (window->resizable) + styleMask |= NSWindowStyleMaskResizable; + else + styleMask &= ~NSWindowStyleMaskResizable; + } + [window->ns.object setStyleMask:styleMask]; // HACK: Changing the style mask can cause the first responder to be cleared [window->ns.object makeFirstResponder:window->ns.view]; @@ -1394,10 +1407,10 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) { @autoreleasepool { - [window->ns.object setStyleMask:getStyleMask(window)]; - + const NSUInteger styleMask = [window->ns.object styleMask]; if (enabled) { + [window->ns.object setStyleMask:(styleMask | NSWindowStyleMaskResizable)]; const NSWindowCollectionBehavior behavior = NSWindowCollectionBehaviorFullScreenPrimary | NSWindowCollectionBehaviorManaged; @@ -1405,6 +1418,7 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) } else { + [window->ns.object setStyleMask:(styleMask & ~NSWindowStyleMaskResizable)]; const NSWindowCollectionBehavior behavior = NSWindowCollectionBehaviorFullScreenNone; [window->ns.object setCollectionBehavior:behavior]; @@ -1416,8 +1430,22 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) { @autoreleasepool { - [window->ns.object setStyleMask:getStyleMask(window)]; + + NSUInteger styleMask = [window->ns.object styleMask]; + if (enabled) + { + styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable); + styleMask &= ~NSWindowStyleMaskBorderless; + } + else + { + styleMask |= NSWindowStyleMaskBorderless; + styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable); + } + + [window->ns.object setStyleMask:styleMask]; [window->ns.object makeFirstResponder:window->ns.view]; + } // autoreleasepool } From 2568d703cd27f524a4c2bc264a9ba7401c078e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 23:27:23 +0200 Subject: [PATCH 104/207] Update glad to include Vulkan 1.3 --- deps/glad/vk_platform.h | 20 +- deps/glad/vulkan.h | 2736 ++++++++++++++++++++++++++++++++++----- deps/glad_vulkan.c | 556 +++++--- 3 files changed, 2736 insertions(+), 576 deletions(-) diff --git a/deps/glad/vk_platform.h b/deps/glad/vk_platform.h index d7d22e1e..277e96a0 100644 --- a/deps/glad/vk_platform.h +++ b/deps/glad/vk_platform.h @@ -2,19 +2,9 @@ /* File: vk_platform.h */ /* */ /* -** Copyright (c) 2014-2017 The Khronos Group Inc. +** Copyright 2014-2022 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ @@ -52,7 +42,7 @@ extern "C" #define VKAPI_CALL __stdcall #define VKAPI_PTR VKAPI_CALL #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error "Vulkan isn't supported for the 'armeabi' NDK ABI" + #error "Vulkan is not supported for the 'armeabi' NDK ABI" #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) /* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */ /* calling convention, i.e. float parameters are passed in registers. This */ @@ -68,7 +58,9 @@ extern "C" #define VKAPI_PTR #endif -#include +#if !defined(VK_NO_STDDEF_H) + #include +#endif /* !defined(VK_NO_STDDEF_H) */ #if !defined(VK_NO_STDINT_H) #if defined(_MSC_VER) && (_MSC_VER < 1600) diff --git a/deps/glad/vulkan.h b/deps/glad/vulkan.h index 6bace71d..39288ee0 100644 --- a/deps/glad/vulkan.h +++ b/deps/glad/vulkan.h @@ -1,26 +1,27 @@ /** - * Loader generated by glad 2.0.0-beta on Sun Apr 14 17:03:38 2019 + * Loader generated by glad 2.0.0-beta on Wed Jul 13 21:24:58 2022 * * Generator: C/C++ * Specification: vk - * Extensions: 3 + * Extensions: 4 * * APIs: - * - vulkan=1.1 + * - vulkan=1.3 * * Options: - * - MX_GLOBAL = False - * - LOADER = False * - ALIAS = False - * - HEADER_ONLY = False * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = False * - MX = False + * - MX_GLOBAL = False + * - ON_DEMAND = False * * Commandline: - * --api='vulkan=1.1' --extensions='VK_EXT_debug_report,VK_KHR_surface,VK_KHR_swapchain' c + * --api='vulkan=1.3' --extensions='VK_EXT_debug_report,VK_KHR_portability_enumeration,VK_KHR_surface,VK_KHR_swapchain' c * * Online: - * http://glad.sh/#api=vulkan%3D1.1&extensions=VK_EXT_debug_report%2CVK_KHR_surface%2CVK_KHR_swapchain&generator=c&options= + * http://glad.sh/#api=vulkan%3D1.3&extensions=VK_EXT_debug_report%2CVK_KHR_portability_enumeration%2CVK_KHR_surface%2CVK_KHR_swapchain&generator=c&options= * */ @@ -28,12 +29,12 @@ #define GLAD_VULKAN_H_ #ifdef VULKAN_H_ - #error header already included (API: vulkan), remove previous include! + #error header already included (API: vulkan), remove previous include! #endif #define VULKAN_H_ 1 #ifdef VULKAN_CORE_H_ - #error header already included (API: vulkan), remove previous include! + #error header already included (API: vulkan), remove previous include! #endif #define VULKAN_CORE_H_ 1 @@ -142,15 +143,16 @@ extern "C" { #define GLAPIENTRY GLAD_API_PTR #endif - #define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) +#define GLAD_GENERATOR_VERSION "2.0.0-beta" + typedef void (*GLADapiproc)(void); typedef GLADapiproc (*GLADloadfunc)(const char *name); -typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); @@ -159,21 +161,25 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define VK_ATTACHMENT_UNUSED (~0U) #define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" -#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 9 +#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 10 #define VK_FALSE 0 +#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration" +#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1 #define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" #define VK_KHR_SURFACE_SPEC_VERSION 25 #define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" #define VK_KHR_SWAPCHAIN_SPEC_VERSION 70 -#define VK_LOD_CLAMP_NONE 1000.0f +#define VK_LOD_CLAMP_NONE 1000.0F #define VK_LUID_SIZE 8 #define VK_MAX_DESCRIPTION_SIZE 256 #define VK_MAX_DEVICE_GROUP_SIZE 32 +#define VK_MAX_DRIVER_INFO_SIZE 256 +#define VK_MAX_DRIVER_NAME_SIZE 256 #define VK_MAX_EXTENSION_NAME_SIZE 256 #define VK_MAX_MEMORY_HEAPS 16 #define VK_MAX_MEMORY_TYPES 32 #define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 -#define VK_QUEUE_FAMILY_EXTERNAL (~0U-1) +#define VK_QUEUE_FAMILY_EXTERNAL (~1U) #define VK_QUEUE_FAMILY_IGNORED (~0U) #define VK_REMAINING_ARRAY_LAYERS (~0U) #define VK_REMAINING_MIP_LEVELS (~0U) @@ -183,29 +189,65 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define VK_WHOLE_SIZE (~0ULL) -#include +#include "vk_platform.h" +/* DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead. */ #define VK_MAKE_VERSION(major, minor, patch) \ - (((major) << 22) | ((minor) << 12) | (patch)) + ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) +/* DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. */ #define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) -#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) -#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) +/* DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead. */ +#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) +/* DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead. */ +#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) +#define VK_MAKE_API_VERSION(variant, major, minor, patch) \ + ((((uint32_t)(variant)) << 29) | (((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) +#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29) +#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU) +#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) +#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) /* DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. */ /*#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 */ /* Vulkan 1.0 version number */ -#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)/* Patch version should always be set to 0 */ +#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)/* Patch version should always be set to 0 */ /* Vulkan 1.1 version number */ -#define VK_API_VERSION_1_1 VK_MAKE_VERSION(1, 1, 0)/* Patch version should always be set to 0 */ +#define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)/* Patch version should always be set to 0 */ +/* Vulkan 1.2 version number */ +#define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0)/* Patch version should always be set to 0 */ +/* Vulkan 1.3 version number */ +#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)/* Patch version should always be set to 0 */ /* Version of this file */ -#define VK_HEADER_VERSION 106 +#define VK_HEADER_VERSION 220 +/* Complete version of this file */ +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; -#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE) -#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#ifndef VK_USE_64_BIT_PTR_DEFINES + #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define VK_USE_64_BIT_PTR_DEFINES 1 + #else + #define VK_USE_64_BIT_PTR_DEFINES 0 + #endif +#endif +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)) + #define VK_NULL_HANDLE nullptr + #else + #define VK_NULL_HANDLE ((void*)0) + #endif + #else + #define VK_NULL_HANDLE 0ULL + #endif +#endif +#ifndef VK_NULL_HANDLE + #define VK_NULL_HANDLE 0 +#endif +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; -#else + #else #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; + #endif #endif -#endif -#define VK_NULL_HANDLE 0 @@ -241,17 +283,21 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) typedef enum VkAttachmentLoadOp { VK_ATTACHMENT_LOAD_OP_LOAD = 0, VK_ATTACHMENT_LOAD_OP_CLEAR = 1, - VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2 + VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, + VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentLoadOp; typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, - VK_ATTACHMENT_STORE_OP_DONT_CARE = 1 + VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, + VK_ATTACHMENT_STORE_OP_NONE = 1000301000, + VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentStoreOp; typedef enum VkBlendFactor { VK_BLEND_FACTOR_ZERO = 0, @@ -272,14 +318,16 @@ typedef enum VkBlendFactor { VK_BLEND_FACTOR_SRC1_COLOR = 15, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, VK_BLEND_FACTOR_SRC1_ALPHA = 17, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18 + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, + VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF } VkBlendFactor; typedef enum VkBlendOp { VK_BLEND_OP_ADD = 0, VK_BLEND_OP_SUBTRACT = 1, VK_BLEND_OP_REVERSE_SUBTRACT = 2, VK_BLEND_OP_MIN = 3, - VK_BLEND_OP_MAX = 4 + VK_BLEND_OP_MAX = 4, + VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF } VkBlendOp; typedef enum VkBorderColor { VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, @@ -287,21 +335,45 @@ typedef enum VkBorderColor { VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, - VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5 + VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, + VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF } VkBorderColor; - +typedef enum VkFramebufferCreateFlagBits { + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 1, + VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFramebufferCreateFlagBits; typedef enum VkPipelineCacheHeaderVersion { - VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1 + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF } VkPipelineCacheHeaderVersion; - +typedef enum VkPipelineCacheCreateFlagBits { + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 1, + VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheCreateFlagBits; +typedef enum VkPipelineShaderStageCreateFlagBits { + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 1, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 2, + VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineShaderStageCreateFlagBits; +typedef enum VkDescriptorSetLayoutCreateFlagBits { + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 2, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorSetLayoutCreateFlagBits; +typedef enum VkInstanceCreateFlagBits { + VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 1, + VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkInstanceCreateFlagBits; typedef enum VkDeviceQueueCreateFlagBits { - VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 1 + VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 1, + VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDeviceQueueCreateFlagBits; typedef enum VkBufferCreateFlagBits { VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 1, VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 2, VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 4, - VK_BUFFER_CREATE_PROTECTED_BIT = 8 + VK_BUFFER_CREATE_PROTECTED_BIT = 8, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 16, + VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferCreateFlagBits; typedef enum VkBufferUsageFlagBits { VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 1, @@ -312,13 +384,16 @@ typedef enum VkBufferUsageFlagBits { VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 32, VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 64, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 128, - VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 256 + VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 256, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 131072, + VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferUsageFlagBits; typedef enum VkColorComponentFlagBits { VK_COLOR_COMPONENT_R_BIT = 1, VK_COLOR_COMPONENT_G_BIT = 2, VK_COLOR_COMPONENT_B_BIT = 4, - VK_COLOR_COMPONENT_A_BIT = 8 + VK_COLOR_COMPONENT_A_BIT = 8, + VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkColorComponentFlagBits; typedef enum VkComponentSwizzle { VK_COMPONENT_SWIZZLE_IDENTITY = 0, @@ -327,27 +402,33 @@ typedef enum VkComponentSwizzle { VK_COMPONENT_SWIZZLE_R = 3, VK_COMPONENT_SWIZZLE_G = 4, VK_COMPONENT_SWIZZLE_B = 5, - VK_COMPONENT_SWIZZLE_A = 6 + VK_COMPONENT_SWIZZLE_A = 6, + VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF } VkComponentSwizzle; typedef enum VkCommandPoolCreateFlagBits { VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 1, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 2, - VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 4 + VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 4, + VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkCommandPoolCreateFlagBits; typedef enum VkCommandPoolResetFlagBits { - VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 1 + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 1, + VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkCommandPoolResetFlagBits; typedef enum VkCommandBufferResetFlagBits { - VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 1 + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 1, + VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkCommandBufferResetFlagBits; typedef enum VkCommandBufferLevel { VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, - VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1 + VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, + VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF } VkCommandBufferLevel; typedef enum VkCommandBufferUsageFlagBits { VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 1, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 2, - VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 4 + VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 4, + VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkCommandBufferUsageFlagBits; typedef enum VkCompareOp { VK_COMPARE_OP_NEVER = 0, @@ -357,13 +438,15 @@ typedef enum VkCompareOp { VK_COMPARE_OP_GREATER = 4, VK_COMPARE_OP_NOT_EQUAL = 5, VK_COMPARE_OP_GREATER_OR_EQUAL = 6, - VK_COMPARE_OP_ALWAYS = 7 + VK_COMPARE_OP_ALWAYS = 7, + VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF } VkCompareOp; typedef enum VkCullModeFlagBits { VK_CULL_MODE_NONE = 0, VK_CULL_MODE_FRONT_BIT = 1, VK_CULL_MODE_BACK_BIT = 2, - VK_CULL_MODE_FRONT_AND_BACK = 0x00000003 + VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, + VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkCullModeFlagBits; typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_SAMPLER = 0, @@ -376,7 +459,9 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, - VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10 + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000, + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorType; typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT = 0, @@ -388,15 +473,32 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, - VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1) + VK_DYNAMIC_STATE_CULL_MODE = 1000267000, + VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010, + VK_DYNAMIC_STATE_STENCIL_OP = 1000267011, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, + VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } VkDynamicState; typedef enum VkFenceCreateFlagBits { - VK_FENCE_CREATE_SIGNALED_BIT = 1 + VK_FENCE_CREATE_SIGNALED_BIT = 1, + VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkFenceCreateFlagBits; typedef enum VkPolygonMode { VK_POLYGON_MODE_FILL = 0, VK_POLYGON_MODE_LINE = 1, - VK_POLYGON_MODE_POINT = 2 + VK_POLYGON_MODE_POINT = 2, + VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF } VkPolygonMode; typedef enum VkFormat { VK_FORMAT_UNDEFINED = 0, @@ -617,7 +719,28 @@ typedef enum VkFormat { VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030, VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033 + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003, + VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000, + VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, + VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 1, @@ -641,11 +764,14 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 1048576, VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 2097152, VK_FORMAT_FEATURE_DISJOINT_BIT = 4194304, - VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 8388608 + VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 8388608, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 65536, + VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkFormatFeatureFlagBits; typedef enum VkFrontFace { VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, - VK_FRONT_FACE_CLOCKWISE = 1 + VK_FRONT_FACE_CLOCKWISE = 1, + VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF } VkFrontFace; typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_COLOR_BIT = 1, @@ -654,7 +780,9 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_METADATA_BIT = 8, VK_IMAGE_ASPECT_PLANE_0_BIT = 16, VK_IMAGE_ASPECT_PLANE_1_BIT = 32, - VK_IMAGE_ASPECT_PLANE_2_BIT = 64 + VK_IMAGE_ASPECT_PLANE_2_BIT = 64, + VK_IMAGE_ASPECT_NONE = 0, + VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageAspectFlagBits; typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 1, @@ -668,7 +796,8 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 128, VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 256, VK_IMAGE_CREATE_PROTECTED_BIT = 2048, - VK_IMAGE_CREATE_DISJOINT_BIT = 512 + VK_IMAGE_CREATE_DISJOINT_BIT = 512, + VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageCreateFlagBits; typedef enum VkImageLayout { VK_IMAGE_LAYOUT_UNDEFINED = 0, @@ -682,16 +811,25 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_PREINITIALIZED = 8, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002 + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF } VkImageLayout; typedef enum VkImageTiling { VK_IMAGE_TILING_OPTIMAL = 0, - VK_IMAGE_TILING_LINEAR = 1 + VK_IMAGE_TILING_LINEAR = 1, + VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF } VkImageTiling; typedef enum VkImageType { VK_IMAGE_TYPE_1D = 0, VK_IMAGE_TYPE_2D = 1, - VK_IMAGE_TYPE_3D = 2 + VK_IMAGE_TYPE_3D = 2, + VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkImageType; typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 1, @@ -701,9 +839,9 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 16, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 32, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 64, - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 128 + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 128, + VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; - typedef enum VkImageViewType { VK_IMAGE_VIEW_TYPE_1D = 0, VK_IMAGE_VIEW_TYPE_2D = 1, @@ -711,15 +849,18 @@ typedef enum VkImageViewType { VK_IMAGE_VIEW_TYPE_CUBE = 3, VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, - VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6 + VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, + VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF } VkImageViewType; typedef enum VkSharingMode { VK_SHARING_MODE_EXCLUSIVE = 0, - VK_SHARING_MODE_CONCURRENT = 1 + VK_SHARING_MODE_CONCURRENT = 1, + VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF } VkSharingMode; typedef enum VkIndexType { VK_INDEX_TYPE_UINT16 = 0, - VK_INDEX_TYPE_UINT32 = 1 + VK_INDEX_TYPE_UINT32 = 1, + VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF } VkIndexType; typedef enum VkLogicOp { VK_LOGIC_OP_CLEAR = 0, @@ -737,11 +878,13 @@ typedef enum VkLogicOp { VK_LOGIC_OP_COPY_INVERTED = 12, VK_LOGIC_OP_OR_INVERTED = 13, VK_LOGIC_OP_NAND = 14, - VK_LOGIC_OP_SET = 15 + VK_LOGIC_OP_SET = 15, + VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF } VkLogicOp; typedef enum VkMemoryHeapFlagBits { VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 1, - VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 2 + VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 2, + VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkMemoryHeapFlagBits; typedef enum VkAccessFlagBits { VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 1, @@ -760,7 +903,9 @@ typedef enum VkAccessFlagBits { VK_ACCESS_HOST_READ_BIT = 8192, VK_ACCESS_HOST_WRITE_BIT = 16384, VK_ACCESS_MEMORY_READ_BIT = 32768, - VK_ACCESS_MEMORY_WRITE_BIT = 65536 + VK_ACCESS_MEMORY_WRITE_BIT = 65536, + VK_ACCESS_NONE = 0, + VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAccessFlagBits; typedef enum VkMemoryPropertyFlagBits { VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 1, @@ -768,25 +913,32 @@ typedef enum VkMemoryPropertyFlagBits { VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 4, VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 8, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 16, - VK_MEMORY_PROPERTY_PROTECTED_BIT = 32 + VK_MEMORY_PROPERTY_PROTECTED_BIT = 32, + VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkMemoryPropertyFlagBits; typedef enum VkPhysicalDeviceType { VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, - VK_PHYSICAL_DEVICE_TYPE_CPU = 4 + VK_PHYSICAL_DEVICE_TYPE_CPU = 4, + VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkPhysicalDeviceType; typedef enum VkPipelineBindPoint { VK_PIPELINE_BIND_POINT_GRAPHICS = 0, - VK_PIPELINE_BIND_POINT_COMPUTE = 1 + VK_PIPELINE_BIND_POINT_COMPUTE = 1, + VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF } VkPipelineBindPoint; typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 1, VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 2, VK_PIPELINE_CREATE_DERIVATIVE_BIT = 4, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 8, - VK_PIPELINE_CREATE_DISPATCH_BASE = 16 + VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 16, + VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 256, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 512, + VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCreateFlagBits; typedef enum VkPrimitiveTopology { VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, @@ -799,10 +951,12 @@ typedef enum VkPrimitiveTopology { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, - VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10 + VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, + VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF } VkPrimitiveTopology; typedef enum VkQueryControlFlagBits { - VK_QUERY_CONTROL_PRECISE_BIT = 1 + VK_QUERY_CONTROL_PRECISE_BIT = 1, + VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueryControlFlagBits; typedef enum VkQueryPipelineStatisticFlagBits { VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 1, @@ -815,29 +969,34 @@ typedef enum VkQueryPipelineStatisticFlagBits { VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 128, VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 256, VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 512, - VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 1024 + VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 1024, + VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueryPipelineStatisticFlagBits; typedef enum VkQueryResultFlagBits { VK_QUERY_RESULT_64_BIT = 1, VK_QUERY_RESULT_WAIT_BIT = 2, VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 4, - VK_QUERY_RESULT_PARTIAL_BIT = 8 + VK_QUERY_RESULT_PARTIAL_BIT = 8, + VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueryResultFlagBits; typedef enum VkQueryType { VK_QUERY_TYPE_OCCLUSION = 0, VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, - VK_QUERY_TYPE_TIMESTAMP = 2 + VK_QUERY_TYPE_TIMESTAMP = 2, + VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF } VkQueryType; typedef enum VkQueueFlagBits { VK_QUEUE_GRAPHICS_BIT = 1, VK_QUEUE_COMPUTE_BIT = 2, VK_QUEUE_TRANSFER_BIT = 4, VK_QUEUE_SPARSE_BINDING_BIT = 8, - VK_QUEUE_PROTECTED_BIT = 16 + VK_QUEUE_PROTECTED_BIT = 16, + VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueueFlagBits; typedef enum VkSubpassContents { VK_SUBPASS_CONTENTS_INLINE = 0, - VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1 + VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, + VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF } VkSubpassContents; typedef enum VkResult { VK_SUCCESS = 0, @@ -858,13 +1017,18 @@ typedef enum VkResult { VK_ERROR_TOO_MANY_OBJECTS = -10, VK_ERROR_FORMAT_NOT_SUPPORTED = -11, VK_ERROR_FRAGMENTED_POOL = -12, + VK_ERROR_UNKNOWN = -13, VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, + VK_ERROR_FRAGMENTATION = -1000161000, + VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + VK_PIPELINE_COMPILE_REQUIRED = 1000297000, VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, VK_ERROR_OUT_OF_DATE_KHR = -1000001004, - VK_ERROR_VALIDATION_FAILED_EXT = -1000011001 + VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, + VK_RESULT_MAX_ENUM = 0x7FFFFFFF } VkResult; typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_VERTEX_BIT = 1, @@ -874,15 +1038,19 @@ typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_FRAGMENT_BIT = 16, VK_SHADER_STAGE_COMPUTE_BIT = 32, VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, - VK_SHADER_STAGE_ALL = 0x7FFFFFFF + VK_SHADER_STAGE_ALL = 0x7FFFFFFF, + VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkShaderStageFlagBits; typedef enum VkSparseMemoryBindFlagBits { - VK_SPARSE_MEMORY_BIND_METADATA_BIT = 1 + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 1, + VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSparseMemoryBindFlagBits; typedef enum VkStencilFaceFlagBits { VK_STENCIL_FACE_FRONT_BIT = 1, VK_STENCIL_FACE_BACK_BIT = 2, - VK_STENCIL_FRONT_AND_BACK = 0x00000003 + VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003, + VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK, + VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkStencilFaceFlagBits; typedef enum VkStencilOp { VK_STENCIL_OP_KEEP = 0, @@ -892,7 +1060,8 @@ typedef enum VkStencilOp { VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, VK_STENCIL_OP_INVERT = 5, VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, - VK_STENCIL_OP_DECREMENT_AND_WRAP = 7 + VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, + VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF } VkStencilOp; typedef enum VkStructureType { VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, @@ -1011,6 +1180,108 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002, + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, + VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004, + VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001, + VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, + VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, + VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, + VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, @@ -1020,35 +1291,43 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, - VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT + VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; typedef enum VkSystemAllocationScope { VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, - VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4 + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, + VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF } VkSystemAllocationScope; typedef enum VkInternalAllocationType { - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0 + VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, + VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF } VkInternalAllocationType; typedef enum VkSamplerAddressMode { VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3 + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF } VkSamplerAddressMode; typedef enum VkFilter { VK_FILTER_NEAREST = 0, - VK_FILTER_LINEAR = 1 + VK_FILTER_LINEAR = 1, + VK_FILTER_MAX_ENUM = 0x7FFFFFFF } VkFilter; typedef enum VkSamplerMipmapMode { VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, - VK_SAMPLER_MIPMAP_MODE_LINEAR = 1 + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF } VkSamplerMipmapMode; typedef enum VkVertexInputRate { VK_VERTEX_INPUT_RATE_VERTEX = 0, - VK_VERTEX_INPUT_RATE_INSTANCE = 1 + VK_VERTEX_INPUT_RATE_INSTANCE = 1, + VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF } VkVertexInputRate; typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 1, @@ -1067,12 +1346,15 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 8192, VK_PIPELINE_STAGE_HOST_BIT = 16384, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 32768, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 65536 + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 65536, + VK_PIPELINE_STAGE_NONE = 0, + VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef enum VkSparseImageFormatFlagBits { VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 1, VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 2, - VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 4 + VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 4, + VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSparseImageFormatFlagBits; typedef enum VkSampleCountFlagBits { VK_SAMPLE_COUNT_1_BIT = 1, @@ -1081,18 +1363,23 @@ typedef enum VkSampleCountFlagBits { VK_SAMPLE_COUNT_8_BIT = 8, VK_SAMPLE_COUNT_16_BIT = 16, VK_SAMPLE_COUNT_32_BIT = 32, - VK_SAMPLE_COUNT_64_BIT = 64 + VK_SAMPLE_COUNT_64_BIT = 64, + VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSampleCountFlagBits; typedef enum VkAttachmentDescriptionFlagBits { - VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 1 + VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 1, + VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAttachmentDescriptionFlagBits; typedef enum VkDescriptorPoolCreateFlagBits { - VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 1 + VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 1, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 2, + VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorPoolCreateFlagBits; typedef enum VkDependencyFlagBits { VK_DEPENDENCY_BY_REGION_BIT = 1, VK_DEPENDENCY_DEVICE_GROUP_BIT = 4, - VK_DEPENDENCY_VIEW_LOCAL_BIT = 2 + VK_DEPENDENCY_VIEW_LOCAL_BIT = 2, + VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDependencyFlagBits; typedef enum VkObjectType { VK_OBJECT_TYPE_UNKNOWN = 0, @@ -1123,33 +1410,252 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_COMMAND_POOL = 25, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, - VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000 + VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, + VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } VkObjectType; +typedef enum VkEventCreateFlagBits { + VK_EVENT_CREATE_DEVICE_ONLY_BIT = 1, + VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkEventCreateFlagBits; typedef enum VkDescriptorUpdateTemplateType { - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0 + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorUpdateTemplateType; - typedef enum VkPointClippingBehavior { VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0, - VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1 + VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, + VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF } VkPointClippingBehavior; +typedef enum VkResolveModeFlagBits { + VK_RESOLVE_MODE_NONE = 0, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 1, + VK_RESOLVE_MODE_AVERAGE_BIT = 2, + VK_RESOLVE_MODE_MIN_BIT = 4, + VK_RESOLVE_MODE_MAX_BIT = 8, + VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkResolveModeFlagBits; +typedef enum VkDescriptorBindingFlagBits { + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 1, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 2, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 4, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 8, + VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorBindingFlagBits; +typedef enum VkSemaphoreType { + VK_SEMAPHORE_TYPE_BINARY = 0, + VK_SEMAPHORE_TYPE_TIMELINE = 1, + VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreType; +typedef enum VkPipelineCreationFeedbackFlagBits { + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 1, + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 2, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 4, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, + VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreationFeedbackFlagBits; +typedef enum VkSemaphoreWaitFlagBits { + VK_SEMAPHORE_WAIT_ANY_BIT = 1, + VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreWaitFlagBits; +typedef enum VkToolPurposeFlagBits { + VK_TOOL_PURPOSE_VALIDATION_BIT = 1, + VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT, + VK_TOOL_PURPOSE_PROFILING_BIT = 2, + VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT, + VK_TOOL_PURPOSE_TRACING_BIT = 4, + VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 8, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 16, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT, + VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkToolPurposeFlagBits; +typedef uint64_t VkAccessFlagBits2; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 1; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 1; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 2; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 2; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 4; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 4; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 8; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 8; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 16; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 16; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 32; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 32; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 64; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 64; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 128; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 128; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 256; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 256; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 512; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 512; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 1024; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 1024; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 2048; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 2048; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 4096; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 4096; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 8192; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 8192; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 16384; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 16384; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 32768; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 32768; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 65536; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 65536; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 4294967296; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 4294967296; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 8589934592; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 8589934592; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 17179869184; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 17179869184; + +typedef uint64_t VkPipelineStageFlagBits2; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 1; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 1; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 2; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 2; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 4; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 4; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 8; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 8; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 16; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 16; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 32; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 32; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 64; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 64; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 128; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 128; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 256; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 256; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 512; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 512; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 1024; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 1024; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 2048; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 2048; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 4096; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 4096; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 4096; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 4096; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 8192; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 8192; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 16384; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 16384; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 32768; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 32768; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 65536; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 65536; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 4294967296; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 4294967296; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 8589934592; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 8589934592; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 17179869184; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 17179869184; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 34359738368; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 34359738368; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 68719476736; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 68719476736; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 137438953472; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 137438953472; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 274877906944; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 274877906944; + +typedef uint64_t VkFormatFeatureFlagBits2; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 1; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 1; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 2; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 2; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 4; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 4; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 8; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 8; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 16; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 16; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 32; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 32; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 64; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 64; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 128; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 128; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 256; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 256; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 512; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 512; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 1024; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 1024; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 2048; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 2048; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 4096; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 4096; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 8192; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 8192; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 16384; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 16384; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 32768; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 32768; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 65536; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 65536; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 131072; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 131072; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 262144; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 262144; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 524288; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 524288; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 1048576; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 1048576; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 2097152; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 2097152; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 4194304; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 4194304; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 8388608; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 8388608; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 2147483648; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 2147483648; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 4294967296; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 4294967296; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 8589934592; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 8589934592; + +typedef enum VkRenderingFlagBits { + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 1, + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, + VK_RENDERING_SUSPENDING_BIT = 2, + VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, + VK_RENDERING_RESUMING_BIT = 4, + VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, + VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderingFlagBits; typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, - VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF } VkColorSpaceKHR; typedef enum VkCompositeAlphaFlagBitsKHR { VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 1, VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 2, VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 4, - VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 8 + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 8, + VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkCompositeAlphaFlagBitsKHR; typedef enum VkPresentModeKHR { VK_PRESENT_MODE_IMMEDIATE_KHR = 0, VK_PRESENT_MODE_MAILBOX_KHR = 1, VK_PRESENT_MODE_FIFO_KHR = 2, - VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3 + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF } VkPresentModeKHR; typedef enum VkSurfaceTransformFlagBitsKHR { VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 1, @@ -1160,14 +1666,16 @@ typedef enum VkSurfaceTransformFlagBitsKHR { VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 32, VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 64, VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 128, - VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 256 + VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 256, + VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSurfaceTransformFlagBitsKHR; typedef enum VkDebugReportFlagBitsEXT { VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 1, VK_DEBUG_REPORT_WARNING_BIT_EXT = 2, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 4, VK_DEBUG_REPORT_ERROR_BIT_EXT = 8, - VK_DEBUG_REPORT_DEBUG_BIT_EXT = 16 + VK_DEBUG_REPORT_DEBUG_BIT_EXT = 16, + VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugReportFlagBitsEXT; typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, @@ -1202,12 +1710,11 @@ typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, - VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31, - VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000 + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, + VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugReportObjectTypeEXT; typedef enum VkExternalMemoryHandleTypeFlagBits { VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 1, @@ -1216,58 +1723,73 @@ typedef enum VkExternalMemoryHandleTypeFlagBits { VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 8, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 16, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 32, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 64 + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 64, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkExternalMemoryHandleTypeFlagBits; typedef enum VkExternalMemoryFeatureFlagBits { VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT = 1, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT = 2, - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 4 + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 4, + VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkExternalMemoryFeatureFlagBits; typedef enum VkExternalSemaphoreHandleTypeFlagBits { VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 1, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 2, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 4, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 8, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 16 + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 16, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkExternalSemaphoreHandleTypeFlagBits; typedef enum VkExternalSemaphoreFeatureFlagBits { VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT = 1, - VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 2 + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 2, + VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkExternalSemaphoreFeatureFlagBits; typedef enum VkSemaphoreImportFlagBits { - VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 1 + VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 1, + VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSemaphoreImportFlagBits; typedef enum VkExternalFenceHandleTypeFlagBits { VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT = 1, VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 2, VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 4, - VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 8 + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 8, + VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkExternalFenceHandleTypeFlagBits; typedef enum VkExternalFenceFeatureFlagBits { VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT = 1, - VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 2 + VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 2, + VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkExternalFenceFeatureFlagBits; typedef enum VkFenceImportFlagBits { - VK_FENCE_IMPORT_TEMPORARY_BIT = 1 + VK_FENCE_IMPORT_TEMPORARY_BIT = 1, + VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkFenceImportFlagBits; typedef enum VkPeerMemoryFeatureFlagBits { VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 1, VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 2, VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 4, - VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 8 + VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 8, + VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPeerMemoryFeatureFlagBits; typedef enum VkMemoryAllocateFlagBits { - VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 1 + VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 1, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 2, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 4, + VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkMemoryAllocateFlagBits; typedef enum VkDeviceGroupPresentModeFlagBitsKHR { VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 1, VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 2, VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 4, - VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 8 + VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 8, + VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkDeviceGroupPresentModeFlagBitsKHR; typedef enum VkSwapchainCreateFlagBitsKHR { VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 1, - VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 2 + VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 2, + VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSwapchainCreateFlagBitsKHR; typedef enum VkSubgroupFeatureFlagBits { VK_SUBGROUP_FEATURE_BASIC_BIT = 1, @@ -1277,32 +1799,84 @@ typedef enum VkSubgroupFeatureFlagBits { VK_SUBGROUP_FEATURE_SHUFFLE_BIT = 16, VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 32, VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 64, - VK_SUBGROUP_FEATURE_QUAD_BIT = 128 + VK_SUBGROUP_FEATURE_QUAD_BIT = 128, + VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubgroupFeatureFlagBits; typedef enum VkTessellationDomainOrigin { VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, - VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1 + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, + VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF } VkTessellationDomainOrigin; typedef enum VkSamplerYcbcrModelConversion { VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1, VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2, VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4 + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF } VkSamplerYcbcrModelConversion; typedef enum VkSamplerYcbcrRange { VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, - VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1 + VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, + VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF } VkSamplerYcbcrRange; typedef enum VkChromaLocation { VK_CHROMA_LOCATION_COSITED_EVEN = 0, - VK_CHROMA_LOCATION_MIDPOINT = 1 + VK_CHROMA_LOCATION_MIDPOINT = 1, + VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF } VkChromaLocation; +typedef enum VkSamplerReductionMode { + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0, + VK_SAMPLER_REDUCTION_MODE_MIN = 1, + VK_SAMPLER_REDUCTION_MODE_MAX = 2, + VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerReductionMode; +typedef enum VkShaderFloatControlsIndependence { + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF +} VkShaderFloatControlsIndependence; +typedef enum VkSubmitFlagBits { + VK_SUBMIT_PROTECTED_BIT = 1, + VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT, + VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubmitFlagBits; typedef enum VkVendorId { VK_VENDOR_ID_VIV = 0x10001, VK_VENDOR_ID_VSI = 0x10002, - VK_VENDOR_ID_KAZAN = 0x10003 + VK_VENDOR_ID_KAZAN = 0x10003, + VK_VENDOR_ID_CODEPLAY = 0x10004, + VK_VENDOR_ID_MESA = 0x10005, + VK_VENDOR_ID_POCL = 0x10006, + VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF } VkVendorId; +typedef enum VkDriverId { + VK_DRIVER_ID_AMD_PROPRIETARY = 1, + VK_DRIVER_ID_AMD_OPEN_SOURCE = 2, + VK_DRIVER_ID_MESA_RADV = 3, + VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8, + VK_DRIVER_ID_ARM_PROPRIETARY = 9, + VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10, + VK_DRIVER_ID_GGP_PROPRIETARY = 11, + VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12, + VK_DRIVER_ID_MESA_LLVMPIPE = 13, + VK_DRIVER_ID_MOLTENVK = 14, + VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, + VK_DRIVER_ID_JUICE_PROPRIETARY = 16, + VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17, + VK_DRIVER_ID_MESA_TURNIP = 18, + VK_DRIVER_ID_MESA_V3DV = 19, + VK_DRIVER_ID_MESA_PANVK = 20, + VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, + VK_DRIVER_ID_MESA_VENUS = 22, + VK_DRIVER_ID_MESA_DOZEN = 23, + VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF +} VkDriverId; typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( void* pUserData, size_t size, @@ -1332,28 +1906,34 @@ typedef struct VkBaseOutStructure { VkStructureType sType; struct VkBaseOutStructure * pNext; } VkBaseOutStructure; + typedef struct VkBaseInStructure { VkStructureType sType; const struct VkBaseInStructure * pNext; } VkBaseInStructure; + typedef struct VkOffset2D { int32_t x; int32_t y; } VkOffset2D; + typedef struct VkOffset3D { int32_t x; int32_t y; int32_t z; } VkOffset3D; + typedef struct VkExtent2D { uint32_t width; uint32_t height; } VkExtent2D; + typedef struct VkExtent3D { uint32_t width; uint32_t height; uint32_t depth; } VkExtent3D; + typedef struct VkViewport { float x; float y; @@ -1362,31 +1942,37 @@ typedef struct VkViewport { float minDepth; float maxDepth; } VkViewport; + typedef struct VkRect2D { VkOffset2D offset; VkExtent2D extent; } VkRect2D; + typedef struct VkClearRect { VkRect2D rect; uint32_t baseArrayLayer; uint32_t layerCount; } VkClearRect; + typedef struct VkComponentMapping { VkComponentSwizzle r; VkComponentSwizzle g; VkComponentSwizzle b; VkComponentSwizzle a; } VkComponentMapping; + typedef struct VkExtensionProperties { char extensionName [ VK_MAX_EXTENSION_NAME_SIZE ]; uint32_t specVersion; } VkExtensionProperties; + typedef struct VkLayerProperties { char layerName [ VK_MAX_EXTENSION_NAME_SIZE ]; uint32_t specVersion; uint32_t implementationVersion; char description [ VK_MAX_DESCRIPTION_SIZE ]; } VkLayerProperties; + typedef struct VkApplicationInfo { VkStructureType sType; const void * pNext; @@ -1396,6 +1982,7 @@ typedef struct VkApplicationInfo { uint32_t engineVersion; uint32_t apiVersion; } VkApplicationInfo; + typedef struct VkAllocationCallbacks { void * pUserData; PFN_vkAllocationFunction pfnAllocation; @@ -1404,11 +1991,13 @@ typedef struct VkAllocationCallbacks { PFN_vkInternalAllocationNotification pfnInternalAllocation; PFN_vkInternalFreeNotification pfnInternalFree; } VkAllocationCallbacks; + typedef struct VkDescriptorImageInfo { VkSampler sampler; VkImageView imageView; VkImageLayout imageLayout; } VkDescriptorImageInfo; + typedef struct VkCopyDescriptorSet { VkStructureType sType; const void * pNext; @@ -1420,10 +2009,12 @@ typedef struct VkCopyDescriptorSet { uint32_t dstArrayElement; uint32_t descriptorCount; } VkCopyDescriptorSet; + typedef struct VkDescriptorPoolSize { VkDescriptorType type; uint32_t descriptorCount; } VkDescriptorPoolSize; + typedef struct VkDescriptorSetAllocateInfo { VkStructureType sType; const void * pNext; @@ -1431,28 +2022,33 @@ typedef struct VkDescriptorSetAllocateInfo { uint32_t descriptorSetCount; const VkDescriptorSetLayout * pSetLayouts; } VkDescriptorSetAllocateInfo; + typedef struct VkSpecializationMapEntry { uint32_t constantID; uint32_t offset; size_t size; } VkSpecializationMapEntry; + typedef struct VkSpecializationInfo { uint32_t mapEntryCount; const VkSpecializationMapEntry * pMapEntries; size_t dataSize; const void * pData; } VkSpecializationInfo; + typedef struct VkVertexInputBindingDescription { uint32_t binding; uint32_t stride; VkVertexInputRate inputRate; } VkVertexInputBindingDescription; + typedef struct VkVertexInputAttributeDescription { uint32_t location; uint32_t binding; VkFormat format; uint32_t offset; } VkVertexInputAttributeDescription; + typedef struct VkStencilOpState { VkStencilOp failOp; VkStencilOp passOp; @@ -1462,6 +2058,15 @@ typedef struct VkStencilOpState { uint32_t writeMask; uint32_t reference; } VkStencilOpState; + +typedef struct VkPipelineCacheHeaderVersionOne { + uint32_t headerSize; + VkPipelineCacheHeaderVersion headerVersion; + uint32_t vendorID; + uint32_t deviceID; + uint8_t pipelineCacheUUID [ VK_UUID_SIZE ]; +} VkPipelineCacheHeaderVersionOne; + typedef struct VkCommandBufferAllocateInfo { VkStructureType sType; const void * pNext; @@ -1469,29 +2074,35 @@ typedef struct VkCommandBufferAllocateInfo { VkCommandBufferLevel level; uint32_t commandBufferCount; } VkCommandBufferAllocateInfo; + typedef union VkClearColorValue { float float32 [4]; int32_t int32 [4]; uint32_t uint32 [4]; } VkClearColorValue; + typedef struct VkClearDepthStencilValue { float depth; uint32_t stencil; } VkClearDepthStencilValue; + typedef union VkClearValue { VkClearColorValue color; VkClearDepthStencilValue depthStencil; } VkClearValue; + typedef struct VkAttachmentReference { uint32_t attachment; VkImageLayout layout; } VkAttachmentReference; + typedef struct VkDrawIndirectCommand { uint32_t vertexCount; uint32_t instanceCount; uint32_t firstVertex; uint32_t firstInstance; } VkDrawIndirectCommand; + typedef struct VkDrawIndexedIndirectCommand { uint32_t indexCount; uint32_t instanceCount; @@ -1499,15 +2110,18 @@ typedef struct VkDrawIndexedIndirectCommand { int32_t vertexOffset; uint32_t firstInstance; } VkDrawIndexedIndirectCommand; + typedef struct VkDispatchIndirectCommand { uint32_t x; uint32_t y; uint32_t z; } VkDispatchIndirectCommand; + typedef struct VkSurfaceFormatKHR { VkFormat format; VkColorSpaceKHR colorSpace; } VkSurfaceFormatKHR; + typedef struct VkPresentInfoKHR { VkStructureType sType; const void * pNext; @@ -1518,27 +2132,54 @@ typedef struct VkPresentInfoKHR { const uint32_t * pImageIndices; VkResult * pResults; } VkPresentInfoKHR; + +typedef struct VkDevicePrivateDataCreateInfo { + VkStructureType sType; + const void * pNext; + uint32_t privateDataSlotRequestCount; +} VkDevicePrivateDataCreateInfo; + +typedef struct VkConformanceVersion { + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t patch; +} VkConformanceVersion; + +typedef struct VkPhysicalDeviceDriverProperties { + VkStructureType sType; + void * pNext; + VkDriverId driverID; + char driverName [ VK_MAX_DRIVER_NAME_SIZE ]; + char driverInfo [ VK_MAX_DRIVER_INFO_SIZE ]; + VkConformanceVersion conformanceVersion; +} VkPhysicalDeviceDriverProperties; + typedef struct VkPhysicalDeviceExternalImageFormatInfo { VkStructureType sType; const void * pNext; VkExternalMemoryHandleTypeFlagBits handleType; } VkPhysicalDeviceExternalImageFormatInfo; + typedef struct VkPhysicalDeviceExternalSemaphoreInfo { VkStructureType sType; const void * pNext; VkExternalSemaphoreHandleTypeFlagBits handleType; } VkPhysicalDeviceExternalSemaphoreInfo; + typedef struct VkPhysicalDeviceExternalFenceInfo { VkStructureType sType; const void * pNext; VkExternalFenceHandleTypeFlagBits handleType; } VkPhysicalDeviceExternalFenceInfo; + typedef struct VkPhysicalDeviceMultiviewProperties { VkStructureType sType; void * pNext; uint32_t maxMultiviewViewCount; uint32_t maxMultiviewInstanceIndex; } VkPhysicalDeviceMultiviewProperties; + typedef struct VkRenderPassMultiviewCreateInfo { VkStructureType sType; const void * pNext; @@ -1549,12 +2190,14 @@ typedef struct VkRenderPassMultiviewCreateInfo { uint32_t correlationMaskCount; const uint32_t * pCorrelationMasks; } VkRenderPassMultiviewCreateInfo; + typedef struct VkBindBufferMemoryDeviceGroupInfo { VkStructureType sType; const void * pNext; uint32_t deviceIndexCount; const uint32_t * pDeviceIndices; } VkBindBufferMemoryDeviceGroupInfo; + typedef struct VkBindImageMemoryDeviceGroupInfo { VkStructureType sType; const void * pNext; @@ -1563,6 +2206,7 @@ typedef struct VkBindImageMemoryDeviceGroupInfo { uint32_t splitInstanceBindRegionCount; const VkRect2D * pSplitInstanceBindRegions; } VkBindImageMemoryDeviceGroupInfo; + typedef struct VkDeviceGroupRenderPassBeginInfo { VkStructureType sType; const void * pNext; @@ -1570,11 +2214,13 @@ typedef struct VkDeviceGroupRenderPassBeginInfo { uint32_t deviceRenderAreaCount; const VkRect2D * pDeviceRenderAreas; } VkDeviceGroupRenderPassBeginInfo; + typedef struct VkDeviceGroupCommandBufferBeginInfo { VkStructureType sType; const void * pNext; uint32_t deviceMask; } VkDeviceGroupCommandBufferBeginInfo; + typedef struct VkDeviceGroupSubmitInfo { VkStructureType sType; const void * pNext; @@ -1585,23 +2231,27 @@ typedef struct VkDeviceGroupSubmitInfo { uint32_t signalSemaphoreCount; const uint32_t * pSignalSemaphoreDeviceIndices; } VkDeviceGroupSubmitInfo; + typedef struct VkDeviceGroupBindSparseInfo { VkStructureType sType; const void * pNext; uint32_t resourceDeviceIndex; uint32_t memoryDeviceIndex; } VkDeviceGroupBindSparseInfo; + typedef struct VkImageSwapchainCreateInfoKHR { VkStructureType sType; const void * pNext; VkSwapchainKHR swapchain; } VkImageSwapchainCreateInfoKHR; + typedef struct VkBindImageMemorySwapchainInfoKHR { VkStructureType sType; const void * pNext; VkSwapchainKHR swapchain; uint32_t imageIndex; } VkBindImageMemorySwapchainInfoKHR; + typedef struct VkAcquireNextImageInfoKHR { VkStructureType sType; const void * pNext; @@ -1611,6 +2261,7 @@ typedef struct VkAcquireNextImageInfoKHR { VkFence fence; uint32_t deviceMask; } VkAcquireNextImageInfoKHR; + typedef struct VkDeviceGroupPresentInfoKHR { VkStructureType sType; const void * pNext; @@ -1618,12 +2269,14 @@ typedef struct VkDeviceGroupPresentInfoKHR { const uint32_t * pDeviceMasks; VkDeviceGroupPresentModeFlagBitsKHR mode; } VkDeviceGroupPresentInfoKHR; + typedef struct VkDeviceGroupDeviceCreateInfo { VkStructureType sType; const void * pNext; uint32_t physicalDeviceCount; const VkPhysicalDevice * pPhysicalDevices; } VkDeviceGroupDeviceCreateInfo; + typedef struct VkDescriptorUpdateTemplateEntry { uint32_t dstBinding; uint32_t dstArrayElement; @@ -1632,61 +2285,243 @@ typedef struct VkDescriptorUpdateTemplateEntry { size_t offset; size_t stride; } VkDescriptorUpdateTemplateEntry; + typedef struct VkBufferMemoryRequirementsInfo2 { VkStructureType sType; const void * pNext; VkBuffer buffer; } VkBufferMemoryRequirementsInfo2; + typedef struct VkImageMemoryRequirementsInfo2 { VkStructureType sType; const void * pNext; VkImage image; } VkImageMemoryRequirementsInfo2; + typedef struct VkImageSparseMemoryRequirementsInfo2 { VkStructureType sType; const void * pNext; VkImage image; } VkImageSparseMemoryRequirementsInfo2; + typedef struct VkPhysicalDevicePointClippingProperties { VkStructureType sType; void * pNext; - VkPointClippingBehavior pointClippingBehavior; + VkPointClippingBehavior pointClippingBehavior; } VkPhysicalDevicePointClippingProperties; + typedef struct VkMemoryDedicatedAllocateInfo { VkStructureType sType; const void * pNext; VkImage image; VkBuffer buffer; } VkMemoryDedicatedAllocateInfo; + typedef struct VkPipelineTessellationDomainOriginStateCreateInfo { VkStructureType sType; const void * pNext; VkTessellationDomainOrigin domainOrigin; } VkPipelineTessellationDomainOriginStateCreateInfo; + typedef struct VkSamplerYcbcrConversionInfo { VkStructureType sType; const void * pNext; VkSamplerYcbcrConversion conversion; } VkSamplerYcbcrConversionInfo; + typedef struct VkBindImagePlaneMemoryInfo { VkStructureType sType; const void * pNext; VkImageAspectFlagBits planeAspect; } VkBindImagePlaneMemoryInfo; + typedef struct VkImagePlaneMemoryRequirementsInfo { VkStructureType sType; const void * pNext; VkImageAspectFlagBits planeAspect; } VkImagePlaneMemoryRequirementsInfo; + typedef struct VkSamplerYcbcrConversionImageFormatProperties { VkStructureType sType; void * pNext; uint32_t combinedImageSamplerDescriptorCount; } VkSamplerYcbcrConversionImageFormatProperties; + +typedef struct VkSamplerReductionModeCreateInfo { + VkStructureType sType; + const void * pNext; + VkSamplerReductionMode reductionMode; +} VkSamplerReductionModeCreateInfo; + +typedef struct VkPhysicalDeviceInlineUniformBlockProperties { + VkStructureType sType; + void * pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockProperties; + +typedef struct VkWriteDescriptorSetInlineUniformBlock { + VkStructureType sType; + const void * pNext; + uint32_t dataSize; + const void * pData; +} VkWriteDescriptorSetInlineUniformBlock; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { + VkStructureType sType; + const void * pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfo; + +typedef struct VkImageFormatListCreateInfo { + VkStructureType sType; + const void * pNext; + uint32_t viewFormatCount; + const VkFormat * pViewFormats; +} VkImageFormatListCreateInfo; + +typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo { + VkStructureType sType; + const void * pNext; + uint32_t descriptorSetCount; + const uint32_t * pDescriptorCounts; +} VkDescriptorSetVariableDescriptorCountAllocateInfo; + +typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport { + VkStructureType sType; + void * pNext; + uint32_t maxVariableDescriptorCount; +} VkDescriptorSetVariableDescriptorCountLayoutSupport; + +typedef struct VkSubpassBeginInfo { + VkStructureType sType; + const void * pNext; + VkSubpassContents contents; +} VkSubpassBeginInfo; + +typedef struct VkSubpassEndInfo { + VkStructureType sType; + const void * pNext; +} VkSubpassEndInfo; + +typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { + VkStructureType sType; + void * pNext; + uint64_t maxTimelineSemaphoreValueDifference; +} VkPhysicalDeviceTimelineSemaphoreProperties; + +typedef struct VkSemaphoreTypeCreateInfo { + VkStructureType sType; + const void * pNext; + VkSemaphoreType semaphoreType; + uint64_t initialValue; +} VkSemaphoreTypeCreateInfo; + +typedef struct VkTimelineSemaphoreSubmitInfo { + VkStructureType sType; + const void * pNext; + uint32_t waitSemaphoreValueCount; + const uint64_t * pWaitSemaphoreValues; + uint32_t signalSemaphoreValueCount; + const uint64_t * pSignalSemaphoreValues; +} VkTimelineSemaphoreSubmitInfo; + +typedef struct VkSemaphoreSignalInfo { + VkStructureType sType; + const void * pNext; + VkSemaphore semaphore; + uint64_t value; +} VkSemaphoreSignalInfo; + +typedef struct VkBufferDeviceAddressInfo { + VkStructureType sType; + const void * pNext; + VkBuffer buffer; +} VkBufferDeviceAddressInfo; + +typedef struct VkBufferOpaqueCaptureAddressCreateInfo { + VkStructureType sType; + const void * pNext; + uint64_t opaqueCaptureAddress; +} VkBufferOpaqueCaptureAddressCreateInfo; + +typedef struct VkRenderPassAttachmentBeginInfo { + VkStructureType sType; + const void * pNext; + uint32_t attachmentCount; + const VkImageView * pAttachments; +} VkRenderPassAttachmentBeginInfo; + +typedef struct VkAttachmentReferenceStencilLayout { + VkStructureType sType; + void * pNext; + VkImageLayout stencilLayout; +} VkAttachmentReferenceStencilLayout; + +typedef struct VkAttachmentDescriptionStencilLayout { + VkStructureType sType; + void * pNext; + VkImageLayout stencilInitialLayout; + VkImageLayout stencilFinalLayout; +} VkAttachmentDescriptionStencilLayout; + +typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { + VkStructureType sType; + void * pNext; + uint32_t requiredSubgroupSize; +} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; + +typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { + VkStructureType sType; + const void * pNext; + uint64_t opaqueCaptureAddress; +} VkMemoryOpaqueCaptureAddressAllocateInfo; + +typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { + VkStructureType sType; + const void * pNext; + VkDeviceMemory memory; +} VkDeviceMemoryOpaqueCaptureAddressInfo; + +typedef struct VkCommandBufferSubmitInfo { + VkStructureType sType; + const void * pNext; + VkCommandBuffer commandBuffer; + uint32_t deviceMask; +} VkCommandBufferSubmitInfo; + +typedef struct VkPipelineRenderingCreateInfo { + VkStructureType sType; + const void * pNext; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat * pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkPipelineRenderingCreateInfo; + +typedef struct VkRenderingAttachmentInfo { + VkStructureType sType; + const void * pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkResolveModeFlagBits resolveMode; + VkImageView resolveImageView; + VkImageLayout resolveImageLayout; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkClearValue clearValue; +} VkRenderingAttachmentInfo; + typedef uint32_t VkSampleMask; typedef uint32_t VkBool32; typedef uint32_t VkFlags; +typedef uint64_t VkFlags64; typedef uint64_t VkDeviceSize; +typedef uint64_t VkDeviceAddress; typedef VkFlags VkFramebufferCreateFlags; typedef VkFlags VkQueryPoolCreateFlags; typedef VkFlags VkRenderPassCreateFlags; @@ -1746,7 +2581,14 @@ typedef VkFlags VkDescriptorPoolCreateFlags; typedef VkFlags VkDescriptorPoolResetFlags; typedef VkFlags VkDependencyFlags; typedef VkFlags VkSubgroupFeatureFlags; +typedef VkFlags VkPrivateDataSlotCreateFlags; typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; +typedef VkFlags VkPipelineCreationFeedbackFlags; +typedef VkFlags VkSemaphoreWaitFlags; +typedef VkFlags64 VkAccessFlags2; +typedef VkFlags64 VkPipelineStageFlags2; +typedef VkFlags64 VkFormatFeatureFlags2; +typedef VkFlags VkRenderingFlags; typedef VkFlags VkCompositeAlphaFlagsKHR; typedef VkFlags VkSurfaceTransformFlagsKHR; typedef VkFlags VkSwapchainCreateFlagsKHR; @@ -1763,6 +2605,10 @@ typedef VkFlags VkSemaphoreImportFlags; typedef VkFlags VkExternalFenceHandleTypeFlags; typedef VkFlags VkExternalFenceFeatureFlags; typedef VkFlags VkFenceImportFlags; +typedef VkFlags VkDescriptorBindingFlags; +typedef VkFlags VkResolveModeFlags; +typedef VkFlags VkToolPurposeFlags; +typedef VkFlags VkSubmitFlags; typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, @@ -1780,6 +2626,7 @@ typedef struct VkDeviceQueueCreateInfo { uint32_t queueCount; const float * pQueuePriorities; } VkDeviceQueueCreateInfo; + typedef struct VkInstanceCreateInfo { VkStructureType sType; const void * pNext; @@ -1790,28 +2637,33 @@ typedef struct VkInstanceCreateInfo { uint32_t enabledExtensionCount; const char * const* ppEnabledExtensionNames; } VkInstanceCreateInfo; + typedef struct VkQueueFamilyProperties { VkQueueFlags queueFlags; uint32_t queueCount; uint32_t timestampValidBits; VkExtent3D minImageTransferGranularity; } VkQueueFamilyProperties; + typedef struct VkMemoryAllocateInfo { VkStructureType sType; const void * pNext; VkDeviceSize allocationSize; uint32_t memoryTypeIndex; } VkMemoryAllocateInfo; + typedef struct VkMemoryRequirements { VkDeviceSize size; VkDeviceSize alignment; uint32_t memoryTypeBits; } VkMemoryRequirements; + typedef struct VkSparseImageFormatProperties { - VkImageAspectFlags aspectMask; - VkExtent3D imageGranularity; + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; VkSparseImageFormatFlags flags; } VkSparseImageFormatProperties; + typedef struct VkSparseImageMemoryRequirements { VkSparseImageFormatProperties formatProperties; uint32_t imageMipTailFirstLod; @@ -1819,14 +2671,17 @@ typedef struct VkSparseImageMemoryRequirements { VkDeviceSize imageMipTailOffset; VkDeviceSize imageMipTailStride; } VkSparseImageMemoryRequirements; + typedef struct VkMemoryType { VkMemoryPropertyFlags propertyFlags; uint32_t heapIndex; } VkMemoryType; + typedef struct VkMemoryHeap { VkDeviceSize size; VkMemoryHeapFlags flags; } VkMemoryHeap; + typedef struct VkMappedMemoryRange { VkStructureType sType; const void * pNext; @@ -1834,11 +2689,13 @@ typedef struct VkMappedMemoryRange { VkDeviceSize offset; VkDeviceSize size; } VkMappedMemoryRange; + typedef struct VkFormatProperties { VkFormatFeatureFlags linearTilingFeatures; VkFormatFeatureFlags optimalTilingFeatures; VkFormatFeatureFlags bufferFeatures; } VkFormatProperties; + typedef struct VkImageFormatProperties { VkExtent3D maxExtent; uint32_t maxMipLevels; @@ -1846,11 +2703,13 @@ typedef struct VkImageFormatProperties { VkSampleCountFlags sampleCounts; VkDeviceSize maxResourceSize; } VkImageFormatProperties; + typedef struct VkDescriptorBufferInfo { VkBuffer buffer; VkDeviceSize offset; VkDeviceSize range; } VkDescriptorBufferInfo; + typedef struct VkWriteDescriptorSet { VkStructureType sType; const void * pNext; @@ -1863,6 +2722,7 @@ typedef struct VkWriteDescriptorSet { const VkDescriptorBufferInfo * pBufferInfo; const VkBufferView * pTexelBufferView; } VkWriteDescriptorSet; + typedef struct VkBufferCreateInfo { VkStructureType sType; const void * pNext; @@ -1873,6 +2733,7 @@ typedef struct VkBufferCreateInfo { uint32_t queueFamilyIndexCount; const uint32_t * pQueueFamilyIndices; } VkBufferCreateInfo; + typedef struct VkBufferViewCreateInfo { VkStructureType sType; const void * pNext; @@ -1882,17 +2743,20 @@ typedef struct VkBufferViewCreateInfo { VkDeviceSize offset; VkDeviceSize range; } VkBufferViewCreateInfo; + typedef struct VkImageSubresource { VkImageAspectFlags aspectMask; uint32_t mipLevel; uint32_t arrayLayer; } VkImageSubresource; + typedef struct VkImageSubresourceLayers { VkImageAspectFlags aspectMask; uint32_t mipLevel; uint32_t baseArrayLayer; uint32_t layerCount; } VkImageSubresourceLayers; + typedef struct VkImageSubresourceRange { VkImageAspectFlags aspectMask; uint32_t baseMipLevel; @@ -1900,12 +2764,14 @@ typedef struct VkImageSubresourceRange { uint32_t baseArrayLayer; uint32_t layerCount; } VkImageSubresourceRange; + typedef struct VkMemoryBarrier { VkStructureType sType; const void * pNext; VkAccessFlags srcAccessMask; VkAccessFlags dstAccessMask; } VkMemoryBarrier; + typedef struct VkBufferMemoryBarrier { VkStructureType sType; const void * pNext; @@ -1917,6 +2783,7 @@ typedef struct VkBufferMemoryBarrier { VkDeviceSize offset; VkDeviceSize size; } VkBufferMemoryBarrier; + typedef struct VkImageMemoryBarrier { VkStructureType sType; const void * pNext; @@ -1929,6 +2796,7 @@ typedef struct VkImageMemoryBarrier { VkImage image; VkImageSubresourceRange subresourceRange; } VkImageMemoryBarrier; + typedef struct VkImageCreateInfo { VkStructureType sType; const void * pNext; @@ -1946,6 +2814,7 @@ typedef struct VkImageCreateInfo { const uint32_t * pQueueFamilyIndices; VkImageLayout initialLayout; } VkImageCreateInfo; + typedef struct VkSubresourceLayout { VkDeviceSize offset; VkDeviceSize size; @@ -1953,6 +2822,7 @@ typedef struct VkSubresourceLayout { VkDeviceSize arrayPitch; VkDeviceSize depthPitch; } VkSubresourceLayout; + typedef struct VkImageViewCreateInfo { VkStructureType sType; const void * pNext; @@ -1963,11 +2833,13 @@ typedef struct VkImageViewCreateInfo { VkComponentMapping components; VkImageSubresourceRange subresourceRange; } VkImageViewCreateInfo; + typedef struct VkBufferCopy { VkDeviceSize srcOffset; VkDeviceSize dstOffset; VkDeviceSize size; } VkBufferCopy; + typedef struct VkSparseMemoryBind { VkDeviceSize resourceOffset; VkDeviceSize size; @@ -1975,6 +2847,7 @@ typedef struct VkSparseMemoryBind { VkDeviceSize memoryOffset; VkSparseMemoryBindFlags flags; } VkSparseMemoryBind; + typedef struct VkSparseImageMemoryBind { VkImageSubresource subresource; VkOffset3D offset; @@ -1983,21 +2856,25 @@ typedef struct VkSparseImageMemoryBind { VkDeviceSize memoryOffset; VkSparseMemoryBindFlags flags; } VkSparseImageMemoryBind; + typedef struct VkSparseBufferMemoryBindInfo { VkBuffer buffer; uint32_t bindCount; const VkSparseMemoryBind * pBinds; } VkSparseBufferMemoryBindInfo; + typedef struct VkSparseImageOpaqueMemoryBindInfo { VkImage image; uint32_t bindCount; const VkSparseMemoryBind * pBinds; } VkSparseImageOpaqueMemoryBindInfo; + typedef struct VkSparseImageMemoryBindInfo { VkImage image; uint32_t bindCount; const VkSparseImageMemoryBind * pBinds; } VkSparseImageMemoryBindInfo; + typedef struct VkBindSparseInfo { VkStructureType sType; const void * pNext; @@ -2012,6 +2889,7 @@ typedef struct VkBindSparseInfo { uint32_t signalSemaphoreCount; const VkSemaphore * pSignalSemaphores; } VkBindSparseInfo; + typedef struct VkImageCopy { VkImageSubresourceLayers srcSubresource; VkOffset3D srcOffset; @@ -2019,12 +2897,14 @@ typedef struct VkImageCopy { VkOffset3D dstOffset; VkExtent3D extent; } VkImageCopy; + typedef struct VkImageBlit { VkImageSubresourceLayers srcSubresource; VkOffset3D srcOffsets [2]; VkImageSubresourceLayers dstSubresource; VkOffset3D dstOffsets [2]; } VkImageBlit; + typedef struct VkBufferImageCopy { VkDeviceSize bufferOffset; uint32_t bufferRowLength; @@ -2033,6 +2913,7 @@ typedef struct VkBufferImageCopy { VkOffset3D imageOffset; VkExtent3D imageExtent; } VkBufferImageCopy; + typedef struct VkImageResolve { VkImageSubresourceLayers srcSubresource; VkOffset3D srcOffset; @@ -2040,6 +2921,7 @@ typedef struct VkImageResolve { VkOffset3D dstOffset; VkExtent3D extent; } VkImageResolve; + typedef struct VkShaderModuleCreateInfo { VkStructureType sType; const void * pNext; @@ -2047,6 +2929,7 @@ typedef struct VkShaderModuleCreateInfo { size_t codeSize; const uint32_t * pCode; } VkShaderModuleCreateInfo; + typedef struct VkDescriptorSetLayoutBinding { uint32_t binding; VkDescriptorType descriptorType; @@ -2054,6 +2937,7 @@ typedef struct VkDescriptorSetLayoutBinding { VkShaderStageFlags stageFlags; const VkSampler * pImmutableSamplers; } VkDescriptorSetLayoutBinding; + typedef struct VkDescriptorSetLayoutCreateInfo { VkStructureType sType; const void * pNext; @@ -2061,6 +2945,7 @@ typedef struct VkDescriptorSetLayoutCreateInfo { uint32_t bindingCount; const VkDescriptorSetLayoutBinding * pBindings; } VkDescriptorSetLayoutCreateInfo; + typedef struct VkDescriptorPoolCreateInfo { VkStructureType sType; const void * pNext; @@ -2069,6 +2954,7 @@ typedef struct VkDescriptorPoolCreateInfo { uint32_t poolSizeCount; const VkDescriptorPoolSize * pPoolSizes; } VkDescriptorPoolCreateInfo; + typedef struct VkPipelineShaderStageCreateInfo { VkStructureType sType; const void * pNext; @@ -2078,6 +2964,7 @@ typedef struct VkPipelineShaderStageCreateInfo { const char * pName; const VkSpecializationInfo * pSpecializationInfo; } VkPipelineShaderStageCreateInfo; + typedef struct VkComputePipelineCreateInfo { VkStructureType sType; const void * pNext; @@ -2087,6 +2974,7 @@ typedef struct VkComputePipelineCreateInfo { VkPipeline basePipelineHandle; int32_t basePipelineIndex; } VkComputePipelineCreateInfo; + typedef struct VkPipelineVertexInputStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2096,6 +2984,7 @@ typedef struct VkPipelineVertexInputStateCreateInfo { uint32_t vertexAttributeDescriptionCount; const VkVertexInputAttributeDescription * pVertexAttributeDescriptions; } VkPipelineVertexInputStateCreateInfo; + typedef struct VkPipelineInputAssemblyStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2103,12 +2992,14 @@ typedef struct VkPipelineInputAssemblyStateCreateInfo { VkPrimitiveTopology topology; VkBool32 primitiveRestartEnable; } VkPipelineInputAssemblyStateCreateInfo; + typedef struct VkPipelineTessellationStateCreateInfo { VkStructureType sType; const void * pNext; VkPipelineTessellationStateCreateFlags flags; uint32_t patchControlPoints; } VkPipelineTessellationStateCreateInfo; + typedef struct VkPipelineViewportStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2118,6 +3009,7 @@ typedef struct VkPipelineViewportStateCreateInfo { uint32_t scissorCount; const VkRect2D * pScissors; } VkPipelineViewportStateCreateInfo; + typedef struct VkPipelineRasterizationStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2133,6 +3025,7 @@ typedef struct VkPipelineRasterizationStateCreateInfo { float depthBiasSlopeFactor; float lineWidth; } VkPipelineRasterizationStateCreateInfo; + typedef struct VkPipelineMultisampleStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2144,6 +3037,7 @@ typedef struct VkPipelineMultisampleStateCreateInfo { VkBool32 alphaToCoverageEnable; VkBool32 alphaToOneEnable; } VkPipelineMultisampleStateCreateInfo; + typedef struct VkPipelineColorBlendAttachmentState { VkBool32 blendEnable; VkBlendFactor srcColorBlendFactor; @@ -2154,6 +3048,7 @@ typedef struct VkPipelineColorBlendAttachmentState { VkBlendOp alphaBlendOp; VkColorComponentFlags colorWriteMask; } VkPipelineColorBlendAttachmentState; + typedef struct VkPipelineColorBlendStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2164,6 +3059,7 @@ typedef struct VkPipelineColorBlendStateCreateInfo { const VkPipelineColorBlendAttachmentState * pAttachments; float blendConstants [4]; } VkPipelineColorBlendStateCreateInfo; + typedef struct VkPipelineDynamicStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2171,6 +3067,7 @@ typedef struct VkPipelineDynamicStateCreateInfo { uint32_t dynamicStateCount; const VkDynamicState * pDynamicStates; } VkPipelineDynamicStateCreateInfo; + typedef struct VkPipelineDepthStencilStateCreateInfo { VkStructureType sType; const void * pNext; @@ -2185,6 +3082,7 @@ typedef struct VkPipelineDepthStencilStateCreateInfo { float minDepthBounds; float maxDepthBounds; } VkPipelineDepthStencilStateCreateInfo; + typedef struct VkGraphicsPipelineCreateInfo { VkStructureType sType; const void * pNext; @@ -2206,6 +3104,7 @@ typedef struct VkGraphicsPipelineCreateInfo { VkPipeline basePipelineHandle; int32_t basePipelineIndex; } VkGraphicsPipelineCreateInfo; + typedef struct VkPipelineCacheCreateInfo { VkStructureType sType; const void * pNext; @@ -2213,11 +3112,13 @@ typedef struct VkPipelineCacheCreateInfo { size_t initialDataSize; const void * pInitialData; } VkPipelineCacheCreateInfo; + typedef struct VkPushConstantRange { VkShaderStageFlags stageFlags; uint32_t offset; uint32_t size; } VkPushConstantRange; + typedef struct VkPipelineLayoutCreateInfo { VkStructureType sType; const void * pNext; @@ -2227,6 +3128,7 @@ typedef struct VkPipelineLayoutCreateInfo { uint32_t pushConstantRangeCount; const VkPushConstantRange * pPushConstantRanges; } VkPipelineLayoutCreateInfo; + typedef struct VkSamplerCreateInfo { VkStructureType sType; const void * pNext; @@ -2247,12 +3149,14 @@ typedef struct VkSamplerCreateInfo { VkBorderColor borderColor; VkBool32 unnormalizedCoordinates; } VkSamplerCreateInfo; + typedef struct VkCommandPoolCreateInfo { VkStructureType sType; const void * pNext; VkCommandPoolCreateFlags flags; uint32_t queueFamilyIndex; } VkCommandPoolCreateInfo; + typedef struct VkCommandBufferInheritanceInfo { VkStructureType sType; const void * pNext; @@ -2263,12 +3167,14 @@ typedef struct VkCommandBufferInheritanceInfo { VkQueryControlFlags queryFlags; VkQueryPipelineStatisticFlags pipelineStatistics; } VkCommandBufferInheritanceInfo; + typedef struct VkCommandBufferBeginInfo { VkStructureType sType; const void * pNext; VkCommandBufferUsageFlags flags; const VkCommandBufferInheritanceInfo * pInheritanceInfo; } VkCommandBufferBeginInfo; + typedef struct VkRenderPassBeginInfo { VkStructureType sType; const void * pNext; @@ -2278,11 +3184,13 @@ typedef struct VkRenderPassBeginInfo { uint32_t clearValueCount; const VkClearValue * pClearValues; } VkRenderPassBeginInfo; + typedef struct VkClearAttachment { VkImageAspectFlags aspectMask; uint32_t colorAttachment; VkClearValue clearValue; } VkClearAttachment; + typedef struct VkAttachmentDescription { VkAttachmentDescriptionFlags flags; VkFormat format; @@ -2294,6 +3202,7 @@ typedef struct VkAttachmentDescription { VkImageLayout initialLayout; VkImageLayout finalLayout; } VkAttachmentDescription; + typedef struct VkSubpassDescription { VkSubpassDescriptionFlags flags; VkPipelineBindPoint pipelineBindPoint; @@ -2306,6 +3215,7 @@ typedef struct VkSubpassDescription { uint32_t preserveAttachmentCount; const uint32_t * pPreserveAttachments; } VkSubpassDescription; + typedef struct VkSubpassDependency { uint32_t srcSubpass; uint32_t dstSubpass; @@ -2315,10 +3225,11 @@ typedef struct VkSubpassDependency { VkAccessFlags dstAccessMask; VkDependencyFlags dependencyFlags; } VkSubpassDependency; + typedef struct VkRenderPassCreateInfo { VkStructureType sType; const void * pNext; - VkRenderPassCreateFlags flags; + VkRenderPassCreateFlags flags; uint32_t attachmentCount; const VkAttachmentDescription * pAttachments; uint32_t subpassCount; @@ -2326,16 +3237,19 @@ typedef struct VkRenderPassCreateInfo { uint32_t dependencyCount; const VkSubpassDependency * pDependencies; } VkRenderPassCreateInfo; + typedef struct VkEventCreateInfo { VkStructureType sType; const void * pNext; VkEventCreateFlags flags; } VkEventCreateInfo; + typedef struct VkFenceCreateInfo { VkStructureType sType; const void * pNext; VkFenceCreateFlags flags; } VkFenceCreateInfo; + typedef struct VkPhysicalDeviceFeatures { VkBool32 robustBufferAccess; VkBool32 fullDrawIndexUint32; @@ -2393,13 +3307,15 @@ typedef struct VkPhysicalDeviceFeatures { VkBool32 variableMultisampleRate; VkBool32 inheritedQueries; } VkPhysicalDeviceFeatures; + typedef struct VkPhysicalDeviceSparseProperties { - VkBool32 residencyStandard2DBlockShape; - VkBool32 residencyStandard2DMultisampleBlockShape; - VkBool32 residencyStandard3DBlockShape; - VkBool32 residencyAlignedMipSize; - VkBool32 residencyNonResidentStrict; + VkBool32 residencyStandard2DBlockShape; + VkBool32 residencyStandard2DMultisampleBlockShape; + VkBool32 residencyStandard3DBlockShape; + VkBool32 residencyAlignedMipSize; + VkBool32 residencyNonResidentStrict; } VkPhysicalDeviceSparseProperties; + typedef struct VkPhysicalDeviceLimits { uint32_t maxImageDimension1D; uint32_t maxImageDimension2D; @@ -2456,28 +3372,28 @@ typedef struct VkPhysicalDeviceLimits { uint32_t maxComputeWorkGroupCount [3]; uint32_t maxComputeWorkGroupInvocations; uint32_t maxComputeWorkGroupSize [3]; - uint32_t subPixelPrecisionBits; - uint32_t subTexelPrecisionBits; - uint32_t mipmapPrecisionBits; + uint32_t subPixelPrecisionBits; + uint32_t subTexelPrecisionBits; + uint32_t mipmapPrecisionBits; uint32_t maxDrawIndexedIndexValue; uint32_t maxDrawIndirectCount; float maxSamplerLodBias; float maxSamplerAnisotropy; uint32_t maxViewports; uint32_t maxViewportDimensions [2]; - float viewportBoundsRange [2]; - uint32_t viewportSubPixelBits; - size_t minMemoryMapAlignment; - VkDeviceSize minTexelBufferOffsetAlignment; - VkDeviceSize minUniformBufferOffsetAlignment; - VkDeviceSize minStorageBufferOffsetAlignment; + float viewportBoundsRange [2]; + uint32_t viewportSubPixelBits; + size_t minMemoryMapAlignment; + VkDeviceSize minTexelBufferOffsetAlignment; + VkDeviceSize minUniformBufferOffsetAlignment; + VkDeviceSize minStorageBufferOffsetAlignment; int32_t minTexelOffset; uint32_t maxTexelOffset; int32_t minTexelGatherOffset; uint32_t maxTexelGatherOffset; float minInterpolationOffset; float maxInterpolationOffset; - uint32_t subPixelInterpolationOffsetBits; + uint32_t subPixelInterpolationOffsetBits; uint32_t maxFramebufferWidth; uint32_t maxFramebufferHeight; uint32_t maxFramebufferLayers; @@ -2492,27 +3408,29 @@ typedef struct VkPhysicalDeviceLimits { VkSampleCountFlags sampledImageStencilSampleCounts; VkSampleCountFlags storageImageSampleCounts; uint32_t maxSampleMaskWords; - VkBool32 timestampComputeAndGraphics; - float timestampPeriod; + VkBool32 timestampComputeAndGraphics; + float timestampPeriod; uint32_t maxClipDistances; uint32_t maxCullDistances; uint32_t maxCombinedClipAndCullDistances; uint32_t discreteQueuePriorities; - float pointSizeRange [2]; - float lineWidthRange [2]; - float pointSizeGranularity; - float lineWidthGranularity; - VkBool32 strictLines; - VkBool32 standardSampleLocations; - VkDeviceSize optimalBufferCopyOffsetAlignment; - VkDeviceSize optimalBufferCopyRowPitchAlignment; - VkDeviceSize nonCoherentAtomSize; + float pointSizeRange [2]; + float lineWidthRange [2]; + float pointSizeGranularity; + float lineWidthGranularity; + VkBool32 strictLines; + VkBool32 standardSampleLocations; + VkDeviceSize optimalBufferCopyOffsetAlignment; + VkDeviceSize optimalBufferCopyRowPitchAlignment; + VkDeviceSize nonCoherentAtomSize; } VkPhysicalDeviceLimits; + typedef struct VkSemaphoreCreateInfo { VkStructureType sType; const void * pNext; VkSemaphoreCreateFlags flags; } VkSemaphoreCreateInfo; + typedef struct VkQueryPoolCreateInfo { VkStructureType sType; const void * pNext; @@ -2521,17 +3439,19 @@ typedef struct VkQueryPoolCreateInfo { uint32_t queryCount; VkQueryPipelineStatisticFlags pipelineStatistics; } VkQueryPoolCreateInfo; + typedef struct VkFramebufferCreateInfo { VkStructureType sType; const void * pNext; VkFramebufferCreateFlags flags; - VkRenderPass renderPass; + VkRenderPass renderPass; uint32_t attachmentCount; const VkImageView * pAttachments; uint32_t width; uint32_t height; uint32_t layers; } VkFramebufferCreateInfo; + typedef struct VkSubmitInfo { VkStructureType sType; const void * pNext; @@ -2543,6 +3463,7 @@ typedef struct VkSubmitInfo { uint32_t signalSemaphoreCount; const VkSemaphore * pSignalSemaphores; } VkSubmitInfo; + typedef struct VkSurfaceCapabilitiesKHR { uint32_t minImageCount; uint32_t maxImageCount; @@ -2555,6 +3476,7 @@ typedef struct VkSurfaceCapabilitiesKHR { VkCompositeAlphaFlagsKHR supportedCompositeAlpha; VkImageUsageFlags supportedUsageFlags; } VkSurfaceCapabilitiesKHR; + typedef struct VkSwapchainCreateInfoKHR { VkStructureType sType; const void * pNext; @@ -2575,6 +3497,7 @@ typedef struct VkSwapchainCreateInfoKHR { VkBool32 clipped; VkSwapchainKHR oldSwapchain; } VkSwapchainCreateInfoKHR; + typedef struct VkDebugReportCallbackCreateInfoEXT { VkStructureType sType; const void * pNext; @@ -2582,21 +3505,37 @@ typedef struct VkDebugReportCallbackCreateInfoEXT { PFN_vkDebugReportCallbackEXT pfnCallback; void * pUserData; } VkDebugReportCallbackCreateInfoEXT; + +typedef struct VkPrivateDataSlotCreateInfo { + VkStructureType sType; + const void * pNext; + VkPrivateDataSlotCreateFlags flags; +} VkPrivateDataSlotCreateInfo; + +typedef struct VkPhysicalDevicePrivateDataFeatures { + VkStructureType sType; + void * pNext; + VkBool32 privateData; +} VkPhysicalDevicePrivateDataFeatures; + typedef struct VkPhysicalDeviceFeatures2 { VkStructureType sType; void * pNext; VkPhysicalDeviceFeatures features; } VkPhysicalDeviceFeatures2; + typedef struct VkFormatProperties2 { VkStructureType sType; void * pNext; VkFormatProperties formatProperties; } VkFormatProperties2; + typedef struct VkImageFormatProperties2 { VkStructureType sType; void * pNext; VkImageFormatProperties imageFormatProperties; } VkImageFormatProperties2; + typedef struct VkPhysicalDeviceImageFormatInfo2 { VkStructureType sType; const void * pNext; @@ -2606,16 +3545,19 @@ typedef struct VkPhysicalDeviceImageFormatInfo2 { VkImageUsageFlags usage; VkImageCreateFlags flags; } VkPhysicalDeviceImageFormatInfo2; + typedef struct VkQueueFamilyProperties2 { VkStructureType sType; void * pNext; - VkQueueFamilyProperties queueFamilyProperties; + VkQueueFamilyProperties queueFamilyProperties; } VkQueueFamilyProperties2; + typedef struct VkSparseImageFormatProperties2 { VkStructureType sType; void * pNext; - VkSparseImageFormatProperties properties; + VkSparseImageFormatProperties properties; } VkSparseImageFormatProperties2; + typedef struct VkPhysicalDeviceSparseImageFormatInfo2 { VkStructureType sType; const void * pNext; @@ -2625,23 +3567,28 @@ typedef struct VkPhysicalDeviceSparseImageFormatInfo2 { VkImageUsageFlags usage; VkImageTiling tiling; } VkPhysicalDeviceSparseImageFormatInfo2; + typedef struct VkPhysicalDeviceVariablePointersFeatures { VkStructureType sType; void * pNext; VkBool32 variablePointersStorageBuffer; VkBool32 variablePointers; } VkPhysicalDeviceVariablePointersFeatures; -typedef struct VkPhysicalDeviceVariablePointerFeatures VkPhysicalDeviceVariablePointerFeatures; + +typedef struct VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeatures; + typedef struct VkExternalMemoryProperties { VkExternalMemoryFeatureFlags externalMemoryFeatures; VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes; VkExternalMemoryHandleTypeFlags compatibleHandleTypes; } VkExternalMemoryProperties; + typedef struct VkExternalImageFormatProperties { VkStructureType sType; void * pNext; VkExternalMemoryProperties externalMemoryProperties; } VkExternalImageFormatProperties; + typedef struct VkPhysicalDeviceExternalBufferInfo { VkStructureType sType; const void * pNext; @@ -2649,35 +3596,41 @@ typedef struct VkPhysicalDeviceExternalBufferInfo { VkBufferUsageFlags usage; VkExternalMemoryHandleTypeFlagBits handleType; } VkPhysicalDeviceExternalBufferInfo; + typedef struct VkExternalBufferProperties { VkStructureType sType; void * pNext; VkExternalMemoryProperties externalMemoryProperties; } VkExternalBufferProperties; + typedef struct VkPhysicalDeviceIDProperties { VkStructureType sType; void * pNext; - uint8_t deviceUUID [ VK_UUID_SIZE ]; - uint8_t driverUUID [ VK_UUID_SIZE ]; - uint8_t deviceLUID [ VK_LUID_SIZE ]; - uint32_t deviceNodeMask; - VkBool32 deviceLUIDValid; + uint8_t deviceUUID [ VK_UUID_SIZE ]; + uint8_t driverUUID [ VK_UUID_SIZE ]; + uint8_t deviceLUID [ VK_LUID_SIZE ]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; } VkPhysicalDeviceIDProperties; + typedef struct VkExternalMemoryImageCreateInfo { VkStructureType sType; const void * pNext; VkExternalMemoryHandleTypeFlags handleTypes; } VkExternalMemoryImageCreateInfo; + typedef struct VkExternalMemoryBufferCreateInfo { VkStructureType sType; const void * pNext; VkExternalMemoryHandleTypeFlags handleTypes; } VkExternalMemoryBufferCreateInfo; + typedef struct VkExportMemoryAllocateInfo { VkStructureType sType; const void * pNext; VkExternalMemoryHandleTypeFlags handleTypes; } VkExportMemoryAllocateInfo; + typedef struct VkExternalSemaphoreProperties { VkStructureType sType; void * pNext; @@ -2685,11 +3638,13 @@ typedef struct VkExternalSemaphoreProperties { VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes; VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures; } VkExternalSemaphoreProperties; + typedef struct VkExportSemaphoreCreateInfo { VkStructureType sType; const void * pNext; VkExternalSemaphoreHandleTypeFlags handleTypes; } VkExportSemaphoreCreateInfo; + typedef struct VkExternalFenceProperties { VkStructureType sType; void * pNext; @@ -2697,11 +3652,13 @@ typedef struct VkExternalFenceProperties { VkExternalFenceHandleTypeFlags compatibleHandleTypes; VkExternalFenceFeatureFlags externalFenceFeatures; } VkExternalFenceProperties; + typedef struct VkExportFenceCreateInfo { VkStructureType sType; const void * pNext; VkExternalFenceHandleTypeFlags handleTypes; } VkExportFenceCreateInfo; + typedef struct VkPhysicalDeviceMultiviewFeatures { VkStructureType sType; void * pNext; @@ -2709,6 +3666,7 @@ typedef struct VkPhysicalDeviceMultiviewFeatures { VkBool32 multiviewGeometryShader; VkBool32 multiviewTessellationShader; } VkPhysicalDeviceMultiviewFeatures; + typedef struct VkPhysicalDeviceGroupProperties { VkStructureType sType; void * pNext; @@ -2716,12 +3674,14 @@ typedef struct VkPhysicalDeviceGroupProperties { VkPhysicalDevice physicalDevices [ VK_MAX_DEVICE_GROUP_SIZE ]; VkBool32 subsetAllocation; } VkPhysicalDeviceGroupProperties; + typedef struct VkMemoryAllocateFlagsInfo { VkStructureType sType; const void * pNext; VkMemoryAllocateFlags flags; uint32_t deviceMask; } VkMemoryAllocateFlagsInfo; + typedef struct VkBindBufferMemoryInfo { VkStructureType sType; const void * pNext; @@ -2729,6 +3689,7 @@ typedef struct VkBindBufferMemoryInfo { VkDeviceMemory memory; VkDeviceSize memoryOffset; } VkBindBufferMemoryInfo; + typedef struct VkBindImageMemoryInfo { VkStructureType sType; const void * pNext; @@ -2736,17 +3697,20 @@ typedef struct VkBindImageMemoryInfo { VkDeviceMemory memory; VkDeviceSize memoryOffset; } VkBindImageMemoryInfo; + typedef struct VkDeviceGroupPresentCapabilitiesKHR { VkStructureType sType; - const void * pNext; + void * pNext; uint32_t presentMask [ VK_MAX_DEVICE_GROUP_SIZE ]; VkDeviceGroupPresentModeFlagsKHR modes; } VkDeviceGroupPresentCapabilitiesKHR; + typedef struct VkDeviceGroupSwapchainCreateInfoKHR { VkStructureType sType; const void * pNext; VkDeviceGroupPresentModeFlagsKHR modes; } VkDeviceGroupSwapchainCreateInfoKHR; + typedef struct VkDescriptorUpdateTemplateCreateInfo { VkStructureType sType; const void * pNext; @@ -2759,17 +3723,20 @@ typedef struct VkDescriptorUpdateTemplateCreateInfo { VkPipelineLayout pipelineLayout; uint32_t set; } VkDescriptorUpdateTemplateCreateInfo; + typedef struct VkInputAttachmentAspectReference { uint32_t subpass; uint32_t inputAttachmentIndex; VkImageAspectFlags aspectMask; } VkInputAttachmentAspectReference; + typedef struct VkRenderPassInputAttachmentAspectCreateInfo { VkStructureType sType; const void * pNext; uint32_t aspectReferenceCount; const VkInputAttachmentAspectReference * pAspectReferences; } VkRenderPassInputAttachmentAspectCreateInfo; + typedef struct VkPhysicalDevice16BitStorageFeatures { VkStructureType sType; void * pNext; @@ -2778,36 +3745,60 @@ typedef struct VkPhysicalDevice16BitStorageFeatures { VkBool32 storagePushConstant16; VkBool32 storageInputOutput16; } VkPhysicalDevice16BitStorageFeatures; + typedef struct VkPhysicalDeviceSubgroupProperties { VkStructureType sType; void * pNext; - uint32_t subgroupSize; + uint32_t subgroupSize; VkShaderStageFlags supportedStages; VkSubgroupFeatureFlags supportedOperations; VkBool32 quadOperationsInAllStages; } VkPhysicalDeviceSubgroupProperties; + +typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { + VkStructureType sType; + void * pNext; + VkBool32 shaderSubgroupExtendedTypes; +} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; + +typedef struct VkDeviceBufferMemoryRequirements { + VkStructureType sType; + const void * pNext; + const VkBufferCreateInfo * pCreateInfo; +} VkDeviceBufferMemoryRequirements; + +typedef struct VkDeviceImageMemoryRequirements { + VkStructureType sType; + const void * pNext; + const VkImageCreateInfo * pCreateInfo; + VkImageAspectFlagBits planeAspect; +} VkDeviceImageMemoryRequirements; + typedef struct VkMemoryRequirements2 { VkStructureType sType; void * pNext; VkMemoryRequirements memoryRequirements; } VkMemoryRequirements2; -typedef struct VkMemoryRequirements2KHR VkMemoryRequirements2KHR; + typedef struct VkSparseImageMemoryRequirements2 { VkStructureType sType; void * pNext; VkSparseImageMemoryRequirements memoryRequirements; } VkSparseImageMemoryRequirements2; + typedef struct VkMemoryDedicatedRequirements { VkStructureType sType; void * pNext; VkBool32 prefersDedicatedAllocation; VkBool32 requiresDedicatedAllocation; } VkMemoryDedicatedRequirements; + typedef struct VkImageViewUsageCreateInfo { VkStructureType sType; const void * pNext; VkImageUsageFlags usage; } VkImageViewUsageCreateInfo; + typedef struct VkSamplerYcbcrConversionCreateInfo { VkStructureType sType; const void * pNext; @@ -2820,26 +3811,31 @@ typedef struct VkSamplerYcbcrConversionCreateInfo { VkFilter chromaFilter; VkBool32 forceExplicitReconstruction; } VkSamplerYcbcrConversionCreateInfo; + typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures { VkStructureType sType; void * pNext; VkBool32 samplerYcbcrConversion; } VkPhysicalDeviceSamplerYcbcrConversionFeatures; + typedef struct VkProtectedSubmitInfo { VkStructureType sType; const void * pNext; VkBool32 protectedSubmit; } VkProtectedSubmitInfo; + typedef struct VkPhysicalDeviceProtectedMemoryFeatures { VkStructureType sType; void * pNext; VkBool32 protectedMemory; } VkPhysicalDeviceProtectedMemoryFeatures; + typedef struct VkPhysicalDeviceProtectedMemoryProperties { VkStructureType sType; void * pNext; VkBool32 protectedNoFault; } VkPhysicalDeviceProtectedMemoryProperties; + typedef struct VkDeviceQueueInfo2 { VkStructureType sType; const void * pNext; @@ -2847,23 +3843,887 @@ typedef struct VkDeviceQueueInfo2 { uint32_t queueFamilyIndex; uint32_t queueIndex; } VkDeviceQueueInfo2; + +typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { + VkStructureType sType; + void * pNext; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; +} VkPhysicalDeviceSamplerFilterMinmaxProperties; + +typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { + VkStructureType sType; + void * pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeatures; + typedef struct VkPhysicalDeviceMaintenance3Properties { VkStructureType sType; void * pNext; uint32_t maxPerSetDescriptors; VkDeviceSize maxMemoryAllocationSize; } VkPhysicalDeviceMaintenance3Properties; + +typedef struct VkPhysicalDeviceMaintenance4Features { + VkStructureType sType; + void * pNext; + VkBool32 maintenance4; +} VkPhysicalDeviceMaintenance4Features; + +typedef struct VkPhysicalDeviceMaintenance4Properties { + VkStructureType sType; + void * pNext; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceMaintenance4Properties; + typedef struct VkDescriptorSetLayoutSupport { VkStructureType sType; void * pNext; VkBool32 supported; } VkDescriptorSetLayoutSupport; + typedef struct VkPhysicalDeviceShaderDrawParametersFeatures { VkStructureType sType; void * pNext; VkBool32 shaderDrawParameters; } VkPhysicalDeviceShaderDrawParametersFeatures; -typedef struct VkPhysicalDeviceShaderDrawParameterFeatures VkPhysicalDeviceShaderDrawParameterFeatures; + +typedef struct VkPhysicalDeviceShaderDrawParametersFeatures VkPhysicalDeviceShaderDrawParameterFeatures; + +typedef struct VkPhysicalDeviceShaderFloat16Int8Features { + VkStructureType sType; + void * pNext; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; +} VkPhysicalDeviceShaderFloat16Int8Features; + +typedef struct VkPhysicalDeviceFloatControlsProperties { + VkStructureType sType; + void * pNext; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; +} VkPhysicalDeviceFloatControlsProperties; + +typedef struct VkPhysicalDeviceHostQueryResetFeatures { + VkStructureType sType; + void * pNext; + VkBool32 hostQueryReset; +} VkPhysicalDeviceHostQueryResetFeatures; + +typedef struct VkPhysicalDeviceDescriptorIndexingFeatures { + VkStructureType sType; + void * pNext; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; +} VkPhysicalDeviceDescriptorIndexingFeatures; + +typedef struct VkPhysicalDeviceDescriptorIndexingProperties { + VkStructureType sType; + void * pNext; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; +} VkPhysicalDeviceDescriptorIndexingProperties; + +typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo { + VkStructureType sType; + const void * pNext; + uint32_t bindingCount; + const VkDescriptorBindingFlags * pBindingFlags; +} VkDescriptorSetLayoutBindingFlagsCreateInfo; + +typedef struct VkAttachmentDescription2 { + VkStructureType sType; + const void * pNext; + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription2; + +typedef struct VkAttachmentReference2 { + VkStructureType sType; + const void * pNext; + uint32_t attachment; + VkImageLayout layout; + VkImageAspectFlags aspectMask; +} VkAttachmentReference2; + +typedef struct VkSubpassDescription2 { + VkStructureType sType; + const void * pNext; + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t viewMask; + uint32_t inputAttachmentCount; + const VkAttachmentReference2 * pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference2 * pColorAttachments; + const VkAttachmentReference2 * pResolveAttachments; + const VkAttachmentReference2 * pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t * pPreserveAttachments; +} VkSubpassDescription2; + +typedef struct VkSubpassDependency2 { + VkStructureType sType; + const void * pNext; + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; + int32_t viewOffset; +} VkSubpassDependency2; + +typedef struct VkRenderPassCreateInfo2 { + VkStructureType sType; + const void * pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription2 * pAttachments; + uint32_t subpassCount; + const VkSubpassDescription2 * pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency2 * pDependencies; + uint32_t correlatedViewMaskCount; + const uint32_t * pCorrelatedViewMasks; +} VkRenderPassCreateInfo2; + +typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { + VkStructureType sType; + void * pNext; + VkBool32 timelineSemaphore; +} VkPhysicalDeviceTimelineSemaphoreFeatures; + +typedef struct VkSemaphoreWaitInfo { + VkStructureType sType; + const void * pNext; + VkSemaphoreWaitFlags flags; + uint32_t semaphoreCount; + const VkSemaphore * pSemaphores; + const uint64_t * pValues; +} VkSemaphoreWaitInfo; + +typedef struct VkPhysicalDevice8BitStorageFeatures { + VkStructureType sType; + void * pNext; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; +} VkPhysicalDevice8BitStorageFeatures; + +typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { + VkStructureType sType; + void * pNext; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; +} VkPhysicalDeviceVulkanMemoryModelFeatures; + +typedef struct VkPhysicalDeviceShaderAtomicInt64Features { + VkStructureType sType; + void * pNext; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; +} VkPhysicalDeviceShaderAtomicInt64Features; + +typedef struct VkPhysicalDeviceDepthStencilResolveProperties { + VkStructureType sType; + void * pNext; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; +} VkPhysicalDeviceDepthStencilResolveProperties; + +typedef struct VkSubpassDescriptionDepthStencilResolve { + VkStructureType sType; + const void * pNext; + VkResolveModeFlagBits depthResolveMode; + VkResolveModeFlagBits stencilResolveMode; + const VkAttachmentReference2 * pDepthStencilResolveAttachment; +} VkSubpassDescriptionDepthStencilResolve; + +typedef struct VkImageStencilUsageCreateInfo { + VkStructureType sType; + const void * pNext; + VkImageUsageFlags stencilUsage; +} VkImageStencilUsageCreateInfo; + +typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { + VkStructureType sType; + void * pNext; + VkBool32 scalarBlockLayout; +} VkPhysicalDeviceScalarBlockLayoutFeatures; + +typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { + VkStructureType sType; + void * pNext; + VkBool32 uniformBufferStandardLayout; +} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; + +typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { + VkStructureType sType; + void * pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferDeviceAddressFeatures; + +typedef struct VkPhysicalDeviceImagelessFramebufferFeatures { + VkStructureType sType; + void * pNext; + VkBool32 imagelessFramebuffer; +} VkPhysicalDeviceImagelessFramebufferFeatures; + +typedef struct VkFramebufferAttachmentImageInfo { + VkStructureType sType; + const void * pNext; + VkImageCreateFlags flags; + VkImageUsageFlags usage; + uint32_t width; + uint32_t height; + uint32_t layerCount; + uint32_t viewFormatCount; + const VkFormat * pViewFormats; +} VkFramebufferAttachmentImageInfo; + +typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { + VkStructureType sType; + void * pNext; + VkBool32 textureCompressionASTC_HDR; +} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; + +typedef struct VkPipelineCreationFeedback { + VkPipelineCreationFeedbackFlags flags; + uint64_t duration; +} VkPipelineCreationFeedback; + +typedef struct VkPipelineCreationFeedbackCreateInfo { + VkStructureType sType; + const void * pNext; + VkPipelineCreationFeedback * pPipelineCreationFeedback; + uint32_t pipelineStageCreationFeedbackCount; + VkPipelineCreationFeedback * pPipelineStageCreationFeedbacks; +} VkPipelineCreationFeedbackCreateInfo; + +typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures { + VkStructureType sType; + void * pNext; + VkBool32 separateDepthStencilLayouts; +} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures; + +typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { + VkStructureType sType; + void * pNext; + VkBool32 shaderDemoteToHelperInvocation; +} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; + +typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { + VkStructureType sType; + void * pNext; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; +} VkPhysicalDeviceTexelBufferAlignmentProperties; + +typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { + VkStructureType sType; + void * pNext; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; +} VkPhysicalDeviceSubgroupSizeControlFeatures; + +typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { + VkStructureType sType; + void * pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; +} VkPhysicalDeviceSubgroupSizeControlProperties; + +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { + VkStructureType sType; + void * pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeatures; + +typedef struct VkPhysicalDeviceVulkan11Features { + VkStructureType sType; + void * pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; + VkBool32 protectedMemory; + VkBool32 samplerYcbcrConversion; + VkBool32 shaderDrawParameters; +} VkPhysicalDeviceVulkan11Features; + +typedef struct VkPhysicalDeviceVulkan11Properties { + VkStructureType sType; + void * pNext; + uint8_t deviceUUID [ VK_UUID_SIZE ]; + uint8_t driverUUID [ VK_UUID_SIZE ]; + uint8_t deviceLUID [ VK_LUID_SIZE ]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; + uint32_t subgroupSize; + VkShaderStageFlags subgroupSupportedStages; + VkSubgroupFeatureFlags subgroupSupportedOperations; + VkBool32 subgroupQuadOperationsInAllStages; + VkPointClippingBehavior pointClippingBehavior; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; + VkBool32 protectedNoFault; + uint32_t maxPerSetDescriptors; + VkDeviceSize maxMemoryAllocationSize; +} VkPhysicalDeviceVulkan11Properties; + +typedef struct VkPhysicalDeviceVulkan12Features { + VkStructureType sType; + void * pNext; + VkBool32 samplerMirrorClampToEdge; + VkBool32 drawIndirectCount; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; + VkBool32 descriptorIndexing; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; + VkBool32 samplerFilterMinmax; + VkBool32 scalarBlockLayout; + VkBool32 imagelessFramebuffer; + VkBool32 uniformBufferStandardLayout; + VkBool32 shaderSubgroupExtendedTypes; + VkBool32 separateDepthStencilLayouts; + VkBool32 hostQueryReset; + VkBool32 timelineSemaphore; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; + VkBool32 shaderOutputViewportIndex; + VkBool32 shaderOutputLayer; + VkBool32 subgroupBroadcastDynamicId; +} VkPhysicalDeviceVulkan12Features; + +typedef struct VkPhysicalDeviceVulkan12Properties { + VkStructureType sType; + void * pNext; + VkDriverId driverID; + char driverName [ VK_MAX_DRIVER_NAME_SIZE ]; + char driverInfo [ VK_MAX_DRIVER_INFO_SIZE ]; + VkConformanceVersion conformanceVersion; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; + uint64_t maxTimelineSemaphoreValueDifference; + VkSampleCountFlags framebufferIntegerColorSampleCounts; +} VkPhysicalDeviceVulkan12Properties; + +typedef struct VkPhysicalDeviceVulkan13Features { + VkStructureType sType; + void * pNext; + VkBool32 robustImageAccess; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; + VkBool32 pipelineCreationCacheControl; + VkBool32 privateData; + VkBool32 shaderDemoteToHelperInvocation; + VkBool32 shaderTerminateInvocation; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; + VkBool32 synchronization2; + VkBool32 textureCompressionASTC_HDR; + VkBool32 shaderZeroInitializeWorkgroupMemory; + VkBool32 dynamicRendering; + VkBool32 shaderIntegerDotProduct; + VkBool32 maintenance4; +} VkPhysicalDeviceVulkan13Features; + +typedef struct VkPhysicalDeviceVulkan13Properties { + VkStructureType sType; + void * pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; + uint32_t maxInlineUniformTotalSize; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceVulkan13Properties; + +typedef struct VkPhysicalDeviceToolProperties { + VkStructureType sType; + void * pNext; + char name [ VK_MAX_EXTENSION_NAME_SIZE ]; + char version [ VK_MAX_EXTENSION_NAME_SIZE ]; + VkToolPurposeFlags purposes; + char description [ VK_MAX_DESCRIPTION_SIZE ]; + char layer [ VK_MAX_EXTENSION_NAME_SIZE ]; +} VkPhysicalDeviceToolProperties; + +typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { + VkStructureType sType; + void * pNext; + VkBool32 shaderZeroInitializeWorkgroupMemory; +} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; + +typedef struct VkPhysicalDeviceImageRobustnessFeatures { + VkStructureType sType; + void * pNext; + VkBool32 robustImageAccess; +} VkPhysicalDeviceImageRobustnessFeatures; + +typedef struct VkBufferCopy2 { + VkStructureType sType; + const void * pNext; + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy2; + +typedef struct VkImageCopy2 { + VkStructureType sType; + const void * pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy2; + +typedef struct VkImageBlit2 { + VkStructureType sType; + const void * pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets [2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets [2]; +} VkImageBlit2; + +typedef struct VkBufferImageCopy2 { + VkStructureType sType; + const void * pNext; + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy2; + +typedef struct VkImageResolve2 { + VkStructureType sType; + const void * pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve2; + +typedef struct VkCopyBufferInfo2 { + VkStructureType sType; + const void * pNext; + VkBuffer srcBuffer; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferCopy2 * pRegions; +} VkCopyBufferInfo2; + +typedef struct VkCopyImageInfo2 { + VkStructureType sType; + const void * pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2 * pRegions; +} VkCopyImageInfo2; + +typedef struct VkBlitImageInfo2 { + VkStructureType sType; + const void * pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageBlit2 * pRegions; + VkFilter filter; +} VkBlitImageInfo2; + +typedef struct VkCopyBufferToImageInfo2 { + VkStructureType sType; + const void * pNext; + VkBuffer srcBuffer; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkBufferImageCopy2 * pRegions; +} VkCopyBufferToImageInfo2; + +typedef struct VkCopyImageToBufferInfo2 { + VkStructureType sType; + const void * pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferImageCopy2 * pRegions; +} VkCopyImageToBufferInfo2; + +typedef struct VkResolveImageInfo2 { + VkStructureType sType; + const void * pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageResolve2 * pRegions; +} VkResolveImageInfo2; + +typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { + VkStructureType sType; + void * pNext; + VkBool32 shaderTerminateInvocation; +} VkPhysicalDeviceShaderTerminateInvocationFeatures; + +typedef struct VkMemoryBarrier2 { + VkStructureType sType; + const void * pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; +} VkMemoryBarrier2; + +typedef struct VkImageMemoryBarrier2 { + VkStructureType sType; + const void * pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier2; + +typedef struct VkBufferMemoryBarrier2 { + VkStructureType sType; + const void * pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier2; + +typedef struct VkDependencyInfo { + VkStructureType sType; + const void * pNext; + VkDependencyFlags dependencyFlags; + uint32_t memoryBarrierCount; + const VkMemoryBarrier2 * pMemoryBarriers; + uint32_t bufferMemoryBarrierCount; + const VkBufferMemoryBarrier2 * pBufferMemoryBarriers; + uint32_t imageMemoryBarrierCount; + const VkImageMemoryBarrier2 * pImageMemoryBarriers; +} VkDependencyInfo; + +typedef struct VkSemaphoreSubmitInfo { + VkStructureType sType; + const void * pNext; + VkSemaphore semaphore; + uint64_t value; + VkPipelineStageFlags2 stageMask; + uint32_t deviceIndex; +} VkSemaphoreSubmitInfo; + +typedef struct VkSubmitInfo2 { + VkStructureType sType; + const void * pNext; + VkSubmitFlags flags; + uint32_t waitSemaphoreInfoCount; + const VkSemaphoreSubmitInfo * pWaitSemaphoreInfos; + uint32_t commandBufferInfoCount; + const VkCommandBufferSubmitInfo * pCommandBufferInfos; + uint32_t signalSemaphoreInfoCount; + const VkSemaphoreSubmitInfo * pSignalSemaphoreInfos; +} VkSubmitInfo2; + +typedef struct VkPhysicalDeviceSynchronization2Features { + VkStructureType sType; + void * pNext; + VkBool32 synchronization2; +} VkPhysicalDeviceSynchronization2Features; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { + VkStructureType sType; + void * pNext; + VkBool32 shaderIntegerDotProduct; +} VkPhysicalDeviceShaderIntegerDotProductFeatures; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { + VkStructureType sType; + void * pNext; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; +} VkPhysicalDeviceShaderIntegerDotProductProperties; + +typedef struct VkFormatProperties3 { + VkStructureType sType; + void * pNext; + VkFormatFeatureFlags2 linearTilingFeatures; + VkFormatFeatureFlags2 optimalTilingFeatures; + VkFormatFeatureFlags2 bufferFeatures; +} VkFormatProperties3; + +typedef struct VkRenderingInfo { + VkStructureType sType; + const void * pNext; + VkRenderingFlags flags; + VkRect2D renderArea; + uint32_t layerCount; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkRenderingAttachmentInfo * pColorAttachments; + const VkRenderingAttachmentInfo * pDepthAttachment; + const VkRenderingAttachmentInfo * pStencilAttachment; +} VkRenderingInfo; + +typedef struct VkPhysicalDeviceDynamicRenderingFeatures { + VkStructureType sType; + void * pNext; + VkBool32 dynamicRendering; +} VkPhysicalDeviceDynamicRenderingFeatures; + +typedef struct VkCommandBufferInheritanceRenderingInfo { + VkStructureType sType; + const void * pNext; + VkRenderingFlags flags; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat * pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; + VkSampleCountFlagBits rasterizationSamples; +} VkCommandBufferInheritanceRenderingInfo; + typedef struct VkPhysicalDeviceProperties { uint32_t apiVersion; uint32_t driverVersion; @@ -2875,6 +4735,7 @@ typedef struct VkPhysicalDeviceProperties { VkPhysicalDeviceLimits limits; VkPhysicalDeviceSparseProperties sparseProperties; } VkPhysicalDeviceProperties; + typedef struct VkDeviceCreateInfo { VkStructureType sType; const void * pNext; @@ -2887,218 +4748,285 @@ typedef struct VkDeviceCreateInfo { const char * const* ppEnabledExtensionNames; const VkPhysicalDeviceFeatures * pEnabledFeatures; } VkDeviceCreateInfo; + typedef struct VkPhysicalDeviceMemoryProperties { uint32_t memoryTypeCount; VkMemoryType memoryTypes [ VK_MAX_MEMORY_TYPES ]; uint32_t memoryHeapCount; VkMemoryHeap memoryHeaps [ VK_MAX_MEMORY_HEAPS ]; } VkPhysicalDeviceMemoryProperties; + typedef struct VkPhysicalDeviceProperties2 { VkStructureType sType; void * pNext; VkPhysicalDeviceProperties properties; } VkPhysicalDeviceProperties2; + typedef struct VkPhysicalDeviceMemoryProperties2 { VkStructureType sType; void * pNext; VkPhysicalDeviceMemoryProperties memoryProperties; } VkPhysicalDeviceMemoryProperties2; +typedef struct VkFramebufferAttachmentsCreateInfo { + VkStructureType sType; + const void * pNext; + uint32_t attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfo * pAttachmentImageInfos; +} VkFramebufferAttachmentsCreateInfo; + + #define VK_VERSION_1_0 1 GLAD_API_CALL int GLAD_VK_VERSION_1_0; #define VK_VERSION_1_1 1 GLAD_API_CALL int GLAD_VK_VERSION_1_1; +#define VK_VERSION_1_2 1 +GLAD_API_CALL int GLAD_VK_VERSION_1_2; +#define VK_VERSION_1_3 1 +GLAD_API_CALL int GLAD_VK_VERSION_1_3; #define VK_EXT_debug_report 1 GLAD_API_CALL int GLAD_VK_EXT_debug_report; +#define VK_KHR_portability_enumeration 1 +GLAD_API_CALL int GLAD_VK_KHR_portability_enumeration; #define VK_KHR_surface 1 GLAD_API_CALL int GLAD_VK_KHR_surface; #define VK_KHR_swapchain 1 GLAD_API_CALL int GLAD_VK_KHR_swapchain; -typedef VkResult (GLAD_API_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR * pAcquireInfo, uint32_t * pImageIndex); -typedef VkResult (GLAD_API_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t * pImageIndex); -typedef VkResult (GLAD_API_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo * pAllocateInfo, VkCommandBuffer * pCommandBuffers); -typedef VkResult (GLAD_API_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo * pAllocateInfo, VkDescriptorSet * pDescriptorSets); -typedef VkResult (GLAD_API_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo * pAllocateInfo, const VkAllocationCallbacks * pAllocator, VkDeviceMemory * pMemory); -typedef VkResult (GLAD_API_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo * pBeginInfo); -typedef VkResult (GLAD_API_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef VkResult (GLAD_API_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo * pBindInfos); -typedef VkResult (GLAD_API_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef VkResult (GLAD_API_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo * pBindInfos); -typedef void (GLAD_API_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); -typedef void (GLAD_API_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo * pRenderPassBegin, VkSubpassContents contents); -typedef void (GLAD_API_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t * pDynamicOffsets); -typedef void (GLAD_API_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); -typedef void (GLAD_API_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); -typedef void (GLAD_API_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer * pBuffers, const VkDeviceSize * pOffsets); -typedef void (GLAD_API_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit * pRegions, VkFilter filter); -typedef void (GLAD_API_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment * pAttachments, uint32_t rectCount, const VkClearRect * pRects); -typedef void (GLAD_API_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue * pColor, uint32_t rangeCount, const VkImageSubresourceRange * pRanges); -typedef void (GLAD_API_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue * pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange * pRanges); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); -typedef void (GLAD_API_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef void (GLAD_API_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef void (GLAD_API_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); -typedef void (GLAD_API_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (GLAD_API_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); -typedef void (GLAD_API_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); -typedef void (GLAD_API_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers); -typedef void (GLAD_API_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); -typedef void (GLAD_API_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); -typedef void (GLAD_API_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers); -typedef void (GLAD_API_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void * pValues); -typedef void (GLAD_API_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (GLAD_API_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); -typedef void (GLAD_API_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve * pRegions); -typedef void (GLAD_API_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants [4]); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); -typedef void (GLAD_API_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); -typedef void (GLAD_API_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D * pScissors); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); -typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); -typedef void (GLAD_API_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport * pViewports); -typedef void (GLAD_API_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void * pData); -typedef void (GLAD_API_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent * pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers); -typedef void (GLAD_API_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkBuffer * pBuffer); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkBufferView * pView); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkCommandPool * pCommandPool); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks * pAllocator, VkPipeline * pPipelines); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDebugReportCallbackEXT * pCallback); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorPool * pDescriptorPool); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorSetLayout * pSetLayout); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDevice * pDevice); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkEvent * pEvent); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFence * pFence); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFramebuffer * pFramebuffer); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks * pAllocator, VkPipeline * pPipelines); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImage * pImage); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImageView * pView); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkInstance * pInstance); -typedef VkResult (GLAD_API_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPipelineCache * pPipelineCache); -typedef VkResult (GLAD_API_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPipelineLayout * pPipelineLayout); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkQueryPool * pQueryPool); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkRenderPass * pRenderPass); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSampler * pSampler); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSamplerYcbcrConversion * pYcbcrConversion); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSemaphore * pSemaphore); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkShaderModule * pShaderModule); -typedef VkResult (GLAD_API_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSwapchainKHR * pSwapchain); -typedef void (GLAD_API_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char * pLayerPrefix, const char * pMessage); -typedef void (GLAD_API_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks * pAllocator); -typedef VkResult (GLAD_API_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); -typedef VkResult (GLAD_API_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char * pLayerName, uint32_t * pPropertyCount, VkExtensionProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t * pPropertyCount, VkLayerProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char * pLayerName, uint32_t * pPropertyCount, VkExtensionProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t * pPropertyCount, VkLayerProperties * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t * pApiVersion); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t * pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t * pPhysicalDeviceCount, VkPhysicalDevice * pPhysicalDevices); -typedef VkResult (GLAD_API_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges); -typedef void (GLAD_API_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers); -typedef VkResult (GLAD_API_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets); -typedef void (GLAD_API_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks * pAllocator); -typedef void (GLAD_API_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2 * pInfo, VkMemoryRequirements2 * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo * pCreateInfo, VkDescriptorSetLayoutSupport * pSupport); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags * pPeerMemoryFeatures); -typedef VkResult (GLAD_API_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities); -typedef VkResult (GLAD_API_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR * pModes); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize * pCommittedMemoryInBytes); -typedef PFN_vkVoidFunction (GLAD_API_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char * pName); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue * pQueue); -typedef void (GLAD_API_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2 * pQueueInfo, VkQueue * pQueue); -typedef VkResult (GLAD_API_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); -typedef VkResult (GLAD_API_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); -typedef void (GLAD_API_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2 * pInfo, VkMemoryRequirements2 * pMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements * pSparseMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2 * pInfo, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements); -typedef void (GLAD_API_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource * pSubresource, VkSubresourceLayout * pLayout); -typedef PFN_vkVoidFunction (GLAD_API_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char * pName); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo, VkExternalBufferProperties * pExternalBufferProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo, VkExternalFenceProperties * pExternalFenceProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo, VkExternalSemaphoreProperties * pExternalSemaphoreProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures * pFeatures); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 * pFeatures); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties * pFormatProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2 * pFormatProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties * pImageFormatProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo, VkImageFormatProperties2 * pImageFormatProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties * pMemoryProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 * pMemoryProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pRectCount, VkRect2D * pRects); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties * pProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 * pProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t * pQueueFamilyPropertyCount, VkQueueFamilyProperties * pQueueFamilyProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice physicalDevice, uint32_t * pQueueFamilyPropertyCount, VkQueueFamilyProperties2 * pQueueFamilyProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t * pPropertyCount, VkSparseImageFormatProperties * pProperties); -typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo, uint32_t * pPropertyCount, VkSparseImageFormatProperties2 * pProperties); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR * pSurfaceCapabilities); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pSurfaceFormatCount, VkSurfaceFormatKHR * pSurfaceFormats); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pPresentModeCount, VkPresentModeKHR * pPresentModes); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 * pSupported); -typedef VkResult (GLAD_API_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t * pDataSize, void * pData); -typedef VkResult (GLAD_API_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void * pData, VkDeviceSize stride, VkQueryResultFlags flags); -typedef void (GLAD_API_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D * pGranularity); -typedef VkResult (GLAD_API_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t * pSwapchainImageCount, VkImage * pSwapchainImages); -typedef VkResult (GLAD_API_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges); -typedef VkResult (GLAD_API_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void ** ppData); -typedef VkResult (GLAD_API_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache * pSrcCaches); -typedef VkResult (GLAD_API_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo * pBindInfo, VkFence fence); -typedef VkResult (GLAD_API_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR * pPresentInfo); -typedef VkResult (GLAD_API_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo * pSubmits, VkFence fence); -typedef VkResult (GLAD_API_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); -typedef VkResult (GLAD_API_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); -typedef VkResult (GLAD_API_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); -typedef VkResult (GLAD_API_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); -typedef VkResult (GLAD_API_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); -typedef VkResult (GLAD_API_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence * pFences); -typedef VkResult (GLAD_API_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); -typedef void (GLAD_API_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); -typedef void (GLAD_API_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); -typedef void (GLAD_API_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void * pData); -typedef void (GLAD_API_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet * pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet * pDescriptorCopies); -typedef VkResult (GLAD_API_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence * pFences, VkBool32 waitAll, uint64_t timeout); +typedef VkResult (GLAD_API_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR * pAcquireInfo, uint32_t * pImageIndex); +typedef VkResult (GLAD_API_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t * pImageIndex); +typedef VkResult (GLAD_API_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo * pAllocateInfo, VkCommandBuffer * pCommandBuffers); +typedef VkResult (GLAD_API_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo * pAllocateInfo, VkDescriptorSet * pDescriptorSets); +typedef VkResult (GLAD_API_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo * pAllocateInfo, const VkAllocationCallbacks * pAllocator, VkDeviceMemory * pMemory); +typedef VkResult (GLAD_API_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo * pBeginInfo); +typedef VkResult (GLAD_API_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef VkResult (GLAD_API_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo * pBindInfos); +typedef VkResult (GLAD_API_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef VkResult (GLAD_API_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo * pBindInfos); +typedef void (GLAD_API_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); +typedef void (GLAD_API_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo * pRenderPassBegin, VkSubpassContents contents); +typedef void (GLAD_API_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo * pRenderPassBegin, const VkSubpassBeginInfo * pSubpassBeginInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo * pRenderingInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t * pDynamicOffsets); +typedef void (GLAD_API_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); +typedef void (GLAD_API_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +typedef void (GLAD_API_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer * pBuffers, const VkDeviceSize * pOffsets); +typedef void (GLAD_API_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer * pBuffers, const VkDeviceSize * pOffsets, const VkDeviceSize * pSizes, const VkDeviceSize * pStrides); +typedef void (GLAD_API_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit * pRegions, VkFilter filter); +typedef void (GLAD_API_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2 * pBlitImageInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment * pAttachments, uint32_t rectCount, const VkClearRect * pRects); +typedef void (GLAD_API_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue * pColor, uint32_t rangeCount, const VkImageSubresourceRange * pRanges); +typedef void (GLAD_API_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue * pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange * pRanges); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy * pRegions); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2 * pCopyBufferInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy * pRegions); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2 * pCopyBufferToImageInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy * pRegions); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2 * pCopyImageInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy * pRegions); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2 * pCopyImageToBufferInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); +typedef void (GLAD_API_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef void (GLAD_API_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef void (GLAD_API_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); +typedef void (GLAD_API_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); +typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); +typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (GLAD_API_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (GLAD_API_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); +typedef void (GLAD_API_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); +typedef void (GLAD_API_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo * pSubpassEndInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer); +typedef void (GLAD_API_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers); +typedef void (GLAD_API_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); +typedef void (GLAD_API_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); +typedef void (GLAD_API_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo * pSubpassBeginInfo, const VkSubpassEndInfo * pSubpassEndInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers); +typedef void (GLAD_API_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo * pDependencyInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void * pValues); +typedef void (GLAD_API_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (GLAD_API_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (GLAD_API_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef void (GLAD_API_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve * pRegions); +typedef void (GLAD_API_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2 * pResolveImageInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants [4]); +typedef void (GLAD_API_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +typedef void (GLAD_API_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask); +typedef void (GLAD_API_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (GLAD_API_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo * pDependencyInfo); +typedef void (GLAD_API_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); +typedef void (GLAD_API_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); +typedef void (GLAD_API_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); +typedef void (GLAD_API_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +typedef void (GLAD_API_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +typedef void (GLAD_API_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D * pScissors); +typedef void (GLAD_API_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D * pScissors); +typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); +typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); +typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); +typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +typedef void (GLAD_API_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); +typedef void (GLAD_API_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport * pViewports); +typedef void (GLAD_API_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport * pViewports); +typedef void (GLAD_API_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void * pData); +typedef void (GLAD_API_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent * pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers); +typedef void (GLAD_API_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent * pEvents, const VkDependencyInfo * pDependencyInfos); +typedef void (GLAD_API_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); +typedef void (GLAD_API_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkBuffer * pBuffer); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkBufferView * pView); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkCommandPool * pCommandPool); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks * pAllocator, VkPipeline * pPipelines); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDebugReportCallbackEXT * pCallback); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorPool * pDescriptorPool); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorSetLayout * pSetLayout); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDevice * pDevice); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkEvent * pEvent); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFence * pFence); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFramebuffer * pFramebuffer); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks * pAllocator, VkPipeline * pPipelines); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImage * pImage); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImageView * pView); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkInstance * pInstance); +typedef VkResult (GLAD_API_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPipelineCache * pPipelineCache); +typedef VkResult (GLAD_API_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPipelineLayout * pPipelineLayout); +typedef VkResult (GLAD_API_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPrivateDataSlot * pPrivateDataSlot); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkQueryPool * pQueryPool); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkRenderPass * pRenderPass); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2 * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkRenderPass * pRenderPass); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSampler * pSampler); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSamplerYcbcrConversion * pYcbcrConversion); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSemaphore * pSemaphore); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkShaderModule * pShaderModule); +typedef VkResult (GLAD_API_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSwapchainKHR * pSwapchain); +typedef void (GLAD_API_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char * pLayerPrefix, const char * pMessage); +typedef void (GLAD_API_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks * pAllocator); +typedef void (GLAD_API_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks * pAllocator); +typedef VkResult (GLAD_API_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); +typedef VkResult (GLAD_API_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); +typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char * pLayerName, uint32_t * pPropertyCount, VkExtensionProperties * pProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t * pPropertyCount, VkLayerProperties * pProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char * pLayerName, uint32_t * pPropertyCount, VkExtensionProperties * pProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t * pPropertyCount, VkLayerProperties * pProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t * pApiVersion); +typedef VkResult (GLAD_API_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t * pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t * pPhysicalDeviceCount, VkPhysicalDevice * pPhysicalDevices); +typedef VkResult (GLAD_API_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges); +typedef void (GLAD_API_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers); +typedef VkResult (GLAD_API_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets); +typedef void (GLAD_API_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks * pAllocator); +typedef VkDeviceAddress (GLAD_API_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo * pInfo); +typedef void (GLAD_API_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements * pMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2 * pInfo, VkMemoryRequirements2 * pMemoryRequirements); +typedef uint64_t (GLAD_API_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo * pInfo); +typedef void (GLAD_API_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo * pCreateInfo, VkDescriptorSetLayoutSupport * pSupport); +typedef void (GLAD_API_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements * pInfo, VkMemoryRequirements2 * pMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags * pPeerMemoryFeatures); +typedef VkResult (GLAD_API_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities); +typedef VkResult (GLAD_API_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR * pModes); +typedef void (GLAD_API_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements * pInfo, VkMemoryRequirements2 * pMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements * pInfo, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize * pCommittedMemoryInBytes); +typedef uint64_t (GLAD_API_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo * pInfo); +typedef PFN_vkVoidFunction (GLAD_API_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char * pName); +typedef void (GLAD_API_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue * pQueue); +typedef void (GLAD_API_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2 * pQueueInfo, VkQueue * pQueue); +typedef VkResult (GLAD_API_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); +typedef VkResult (GLAD_API_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); +typedef void (GLAD_API_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements * pMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2 * pInfo, VkMemoryRequirements2 * pMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements * pSparseMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2 * pInfo, uint32_t * pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements); +typedef void (GLAD_API_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource * pSubresource, VkSubresourceLayout * pLayout); +typedef PFN_vkVoidFunction (GLAD_API_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char * pName); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo, VkExternalBufferProperties * pExternalBufferProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo, VkExternalFenceProperties * pExternalFenceProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo, VkExternalSemaphoreProperties * pExternalSemaphoreProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures * pFeatures); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 * pFeatures); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties * pFormatProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2 * pFormatProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties * pImageFormatProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo, VkImageFormatProperties2 * pImageFormatProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties * pMemoryProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 * pMemoryProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pRectCount, VkRect2D * pRects); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties * pProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 * pProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t * pQueueFamilyPropertyCount, VkQueueFamilyProperties * pQueueFamilyProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice physicalDevice, uint32_t * pQueueFamilyPropertyCount, VkQueueFamilyProperties2 * pQueueFamilyProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t * pPropertyCount, VkSparseImageFormatProperties * pProperties); +typedef void (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo, uint32_t * pPropertyCount, VkSparseImageFormatProperties2 * pProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR * pSurfaceCapabilities); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pSurfaceFormatCount, VkSurfaceFormatKHR * pSurfaceFormats); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t * pPresentModeCount, VkPresentModeKHR * pPresentModes); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 * pSupported); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t * pToolCount, VkPhysicalDeviceToolProperties * pToolProperties); +typedef VkResult (GLAD_API_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t * pDataSize, void * pData); +typedef void (GLAD_API_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t * pData); +typedef VkResult (GLAD_API_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void * pData, VkDeviceSize stride, VkQueryResultFlags flags); +typedef void (GLAD_API_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D * pGranularity); +typedef VkResult (GLAD_API_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t * pValue); +typedef VkResult (GLAD_API_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t * pSwapchainImageCount, VkImage * pSwapchainImages); +typedef VkResult (GLAD_API_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges); +typedef VkResult (GLAD_API_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void ** ppData); +typedef VkResult (GLAD_API_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache * pSrcCaches); +typedef VkResult (GLAD_API_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo * pBindInfo, VkFence fence); +typedef VkResult (GLAD_API_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR * pPresentInfo); +typedef VkResult (GLAD_API_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo * pSubmits, VkFence fence); +typedef VkResult (GLAD_API_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 * pSubmits, VkFence fence); +typedef VkResult (GLAD_API_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); +typedef VkResult (GLAD_API_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); +typedef VkResult (GLAD_API_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); +typedef VkResult (GLAD_API_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); +typedef VkResult (GLAD_API_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); +typedef VkResult (GLAD_API_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence * pFences); +typedef void (GLAD_API_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef VkResult (GLAD_API_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); +typedef VkResult (GLAD_API_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef VkResult (GLAD_API_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo * pSignalInfo); +typedef void (GLAD_API_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); +typedef void (GLAD_API_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); +typedef void (GLAD_API_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void * pData); +typedef void (GLAD_API_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet * pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet * pDescriptorCopies); +typedef VkResult (GLAD_API_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence * pFences, VkBool32 waitAll, uint64_t timeout); +typedef VkResult (GLAD_API_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo * pWaitInfo, uint64_t timeout); GLAD_API_CALL PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR; #define vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR @@ -3124,6 +5052,10 @@ GLAD_API_CALL PFN_vkCmdBeginQuery glad_vkCmdBeginQuery; #define vkCmdBeginQuery glad_vkCmdBeginQuery GLAD_API_CALL PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass; #define vkCmdBeginRenderPass glad_vkCmdBeginRenderPass +GLAD_API_CALL PFN_vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2; +#define vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2 +GLAD_API_CALL PFN_vkCmdBeginRendering glad_vkCmdBeginRendering; +#define vkCmdBeginRendering glad_vkCmdBeginRendering GLAD_API_CALL PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets; #define vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets GLAD_API_CALL PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer; @@ -3132,8 +5064,12 @@ GLAD_API_CALL PFN_vkCmdBindPipeline glad_vkCmdBindPipeline; #define vkCmdBindPipeline glad_vkCmdBindPipeline GLAD_API_CALL PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers; #define vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers +GLAD_API_CALL PFN_vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2; +#define vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2 GLAD_API_CALL PFN_vkCmdBlitImage glad_vkCmdBlitImage; #define vkCmdBlitImage glad_vkCmdBlitImage +GLAD_API_CALL PFN_vkCmdBlitImage2 glad_vkCmdBlitImage2; +#define vkCmdBlitImage2 glad_vkCmdBlitImage2 GLAD_API_CALL PFN_vkCmdClearAttachments glad_vkCmdClearAttachments; #define vkCmdClearAttachments glad_vkCmdClearAttachments GLAD_API_CALL PFN_vkCmdClearColorImage glad_vkCmdClearColorImage; @@ -3142,12 +5078,20 @@ GLAD_API_CALL PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage; #define vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage GLAD_API_CALL PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer; #define vkCmdCopyBuffer glad_vkCmdCopyBuffer +GLAD_API_CALL PFN_vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2; +#define vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2 GLAD_API_CALL PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage; #define vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage +GLAD_API_CALL PFN_vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2; +#define vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2 GLAD_API_CALL PFN_vkCmdCopyImage glad_vkCmdCopyImage; #define vkCmdCopyImage glad_vkCmdCopyImage +GLAD_API_CALL PFN_vkCmdCopyImage2 glad_vkCmdCopyImage2; +#define vkCmdCopyImage2 glad_vkCmdCopyImage2 GLAD_API_CALL PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer; #define vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer +GLAD_API_CALL PFN_vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2; +#define vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2 GLAD_API_CALL PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults; #define vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults GLAD_API_CALL PFN_vkCmdDispatch glad_vkCmdDispatch; @@ -3162,56 +5106,106 @@ GLAD_API_CALL PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed; #define vkCmdDrawIndexed glad_vkCmdDrawIndexed GLAD_API_CALL PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect; #define vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect +GLAD_API_CALL PFN_vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount; +#define vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount GLAD_API_CALL PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect; #define vkCmdDrawIndirect glad_vkCmdDrawIndirect +GLAD_API_CALL PFN_vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount; +#define vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount GLAD_API_CALL PFN_vkCmdEndQuery glad_vkCmdEndQuery; #define vkCmdEndQuery glad_vkCmdEndQuery GLAD_API_CALL PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass; #define vkCmdEndRenderPass glad_vkCmdEndRenderPass +GLAD_API_CALL PFN_vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2; +#define vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2 +GLAD_API_CALL PFN_vkCmdEndRendering glad_vkCmdEndRendering; +#define vkCmdEndRendering glad_vkCmdEndRendering GLAD_API_CALL PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands; #define vkCmdExecuteCommands glad_vkCmdExecuteCommands GLAD_API_CALL PFN_vkCmdFillBuffer glad_vkCmdFillBuffer; #define vkCmdFillBuffer glad_vkCmdFillBuffer GLAD_API_CALL PFN_vkCmdNextSubpass glad_vkCmdNextSubpass; #define vkCmdNextSubpass glad_vkCmdNextSubpass +GLAD_API_CALL PFN_vkCmdNextSubpass2 glad_vkCmdNextSubpass2; +#define vkCmdNextSubpass2 glad_vkCmdNextSubpass2 GLAD_API_CALL PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier; #define vkCmdPipelineBarrier glad_vkCmdPipelineBarrier +GLAD_API_CALL PFN_vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2; +#define vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2 GLAD_API_CALL PFN_vkCmdPushConstants glad_vkCmdPushConstants; #define vkCmdPushConstants glad_vkCmdPushConstants GLAD_API_CALL PFN_vkCmdResetEvent glad_vkCmdResetEvent; #define vkCmdResetEvent glad_vkCmdResetEvent +GLAD_API_CALL PFN_vkCmdResetEvent2 glad_vkCmdResetEvent2; +#define vkCmdResetEvent2 glad_vkCmdResetEvent2 GLAD_API_CALL PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool; #define vkCmdResetQueryPool glad_vkCmdResetQueryPool GLAD_API_CALL PFN_vkCmdResolveImage glad_vkCmdResolveImage; #define vkCmdResolveImage glad_vkCmdResolveImage +GLAD_API_CALL PFN_vkCmdResolveImage2 glad_vkCmdResolveImage2; +#define vkCmdResolveImage2 glad_vkCmdResolveImage2 GLAD_API_CALL PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants; #define vkCmdSetBlendConstants glad_vkCmdSetBlendConstants +GLAD_API_CALL PFN_vkCmdSetCullMode glad_vkCmdSetCullMode; +#define vkCmdSetCullMode glad_vkCmdSetCullMode GLAD_API_CALL PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias; #define vkCmdSetDepthBias glad_vkCmdSetDepthBias +GLAD_API_CALL PFN_vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable; +#define vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable GLAD_API_CALL PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds; #define vkCmdSetDepthBounds glad_vkCmdSetDepthBounds +GLAD_API_CALL PFN_vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable; +#define vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable +GLAD_API_CALL PFN_vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp; +#define vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp +GLAD_API_CALL PFN_vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable; +#define vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable +GLAD_API_CALL PFN_vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable; +#define vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable GLAD_API_CALL PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask; #define vkCmdSetDeviceMask glad_vkCmdSetDeviceMask GLAD_API_CALL PFN_vkCmdSetEvent glad_vkCmdSetEvent; #define vkCmdSetEvent glad_vkCmdSetEvent +GLAD_API_CALL PFN_vkCmdSetEvent2 glad_vkCmdSetEvent2; +#define vkCmdSetEvent2 glad_vkCmdSetEvent2 +GLAD_API_CALL PFN_vkCmdSetFrontFace glad_vkCmdSetFrontFace; +#define vkCmdSetFrontFace glad_vkCmdSetFrontFace GLAD_API_CALL PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth; #define vkCmdSetLineWidth glad_vkCmdSetLineWidth +GLAD_API_CALL PFN_vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable; +#define vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable +GLAD_API_CALL PFN_vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology; +#define vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology +GLAD_API_CALL PFN_vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable; +#define vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable GLAD_API_CALL PFN_vkCmdSetScissor glad_vkCmdSetScissor; #define vkCmdSetScissor glad_vkCmdSetScissor +GLAD_API_CALL PFN_vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount; +#define vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount GLAD_API_CALL PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask; #define vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask +GLAD_API_CALL PFN_vkCmdSetStencilOp glad_vkCmdSetStencilOp; +#define vkCmdSetStencilOp glad_vkCmdSetStencilOp GLAD_API_CALL PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference; #define vkCmdSetStencilReference glad_vkCmdSetStencilReference +GLAD_API_CALL PFN_vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable; +#define vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable GLAD_API_CALL PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask; #define vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask GLAD_API_CALL PFN_vkCmdSetViewport glad_vkCmdSetViewport; #define vkCmdSetViewport glad_vkCmdSetViewport +GLAD_API_CALL PFN_vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount; +#define vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount GLAD_API_CALL PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer; #define vkCmdUpdateBuffer glad_vkCmdUpdateBuffer GLAD_API_CALL PFN_vkCmdWaitEvents glad_vkCmdWaitEvents; #define vkCmdWaitEvents glad_vkCmdWaitEvents +GLAD_API_CALL PFN_vkCmdWaitEvents2 glad_vkCmdWaitEvents2; +#define vkCmdWaitEvents2 glad_vkCmdWaitEvents2 GLAD_API_CALL PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp; #define vkCmdWriteTimestamp glad_vkCmdWriteTimestamp +GLAD_API_CALL PFN_vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2; +#define vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2 GLAD_API_CALL PFN_vkCreateBuffer glad_vkCreateBuffer; #define vkCreateBuffer glad_vkCreateBuffer GLAD_API_CALL PFN_vkCreateBufferView glad_vkCreateBufferView; @@ -3248,10 +5242,14 @@ GLAD_API_CALL PFN_vkCreatePipelineCache glad_vkCreatePipelineCache; #define vkCreatePipelineCache glad_vkCreatePipelineCache GLAD_API_CALL PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout; #define vkCreatePipelineLayout glad_vkCreatePipelineLayout +GLAD_API_CALL PFN_vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot; +#define vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot GLAD_API_CALL PFN_vkCreateQueryPool glad_vkCreateQueryPool; #define vkCreateQueryPool glad_vkCreateQueryPool GLAD_API_CALL PFN_vkCreateRenderPass glad_vkCreateRenderPass; #define vkCreateRenderPass glad_vkCreateRenderPass +GLAD_API_CALL PFN_vkCreateRenderPass2 glad_vkCreateRenderPass2; +#define vkCreateRenderPass2 glad_vkCreateRenderPass2 GLAD_API_CALL PFN_vkCreateSampler glad_vkCreateSampler; #define vkCreateSampler glad_vkCreateSampler GLAD_API_CALL PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion; @@ -3298,6 +5296,8 @@ GLAD_API_CALL PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache; #define vkDestroyPipelineCache glad_vkDestroyPipelineCache GLAD_API_CALL PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout; #define vkDestroyPipelineLayout glad_vkDestroyPipelineLayout +GLAD_API_CALL PFN_vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot; +#define vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot GLAD_API_CALL PFN_vkDestroyQueryPool glad_vkDestroyQueryPool; #define vkDestroyQueryPool glad_vkDestroyQueryPool GLAD_API_CALL PFN_vkDestroyRenderPass glad_vkDestroyRenderPass; @@ -3340,20 +5340,32 @@ GLAD_API_CALL PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets; #define vkFreeDescriptorSets glad_vkFreeDescriptorSets GLAD_API_CALL PFN_vkFreeMemory glad_vkFreeMemory; #define vkFreeMemory glad_vkFreeMemory +GLAD_API_CALL PFN_vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress; +#define vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress GLAD_API_CALL PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements; #define vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements GLAD_API_CALL PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2; #define vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 +GLAD_API_CALL PFN_vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress; +#define vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress GLAD_API_CALL PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport; #define vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport +GLAD_API_CALL PFN_vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements; +#define vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements GLAD_API_CALL PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures; #define vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures GLAD_API_CALL PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR; #define vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR GLAD_API_CALL PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR; #define vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR +GLAD_API_CALL PFN_vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements; +#define vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements +GLAD_API_CALL PFN_vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements; +#define vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements GLAD_API_CALL PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment; #define vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment +GLAD_API_CALL PFN_vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress; +#define vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress GLAD_API_CALL PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr; #define vkGetDeviceProcAddr glad_vkGetDeviceProcAddr GLAD_API_CALL PFN_vkGetDeviceQueue glad_vkGetDeviceQueue; @@ -3420,12 +5432,18 @@ GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDe #define vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR; #define vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR +GLAD_API_CALL PFN_vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties; +#define vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties GLAD_API_CALL PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData; #define vkGetPipelineCacheData glad_vkGetPipelineCacheData +GLAD_API_CALL PFN_vkGetPrivateData glad_vkGetPrivateData; +#define vkGetPrivateData glad_vkGetPrivateData GLAD_API_CALL PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults; #define vkGetQueryPoolResults glad_vkGetQueryPoolResults GLAD_API_CALL PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity; #define vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity +GLAD_API_CALL PFN_vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue; +#define vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue GLAD_API_CALL PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR; #define vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR GLAD_API_CALL PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges; @@ -3440,6 +5458,8 @@ GLAD_API_CALL PFN_vkQueuePresentKHR glad_vkQueuePresentKHR; #define vkQueuePresentKHR glad_vkQueuePresentKHR GLAD_API_CALL PFN_vkQueueSubmit glad_vkQueueSubmit; #define vkQueueSubmit glad_vkQueueSubmit +GLAD_API_CALL PFN_vkQueueSubmit2 glad_vkQueueSubmit2; +#define vkQueueSubmit2 glad_vkQueueSubmit2 GLAD_API_CALL PFN_vkQueueWaitIdle glad_vkQueueWaitIdle; #define vkQueueWaitIdle glad_vkQueueWaitIdle GLAD_API_CALL PFN_vkResetCommandBuffer glad_vkResetCommandBuffer; @@ -3452,8 +5472,14 @@ GLAD_API_CALL PFN_vkResetEvent glad_vkResetEvent; #define vkResetEvent glad_vkResetEvent GLAD_API_CALL PFN_vkResetFences glad_vkResetFences; #define vkResetFences glad_vkResetFences +GLAD_API_CALL PFN_vkResetQueryPool glad_vkResetQueryPool; +#define vkResetQueryPool glad_vkResetQueryPool GLAD_API_CALL PFN_vkSetEvent glad_vkSetEvent; #define vkSetEvent glad_vkSetEvent +GLAD_API_CALL PFN_vkSetPrivateData glad_vkSetPrivateData; +#define vkSetPrivateData glad_vkSetPrivateData +GLAD_API_CALL PFN_vkSignalSemaphore glad_vkSignalSemaphore; +#define vkSignalSemaphore glad_vkSignalSemaphore GLAD_API_CALL PFN_vkTrimCommandPool glad_vkTrimCommandPool; #define vkTrimCommandPool glad_vkTrimCommandPool GLAD_API_CALL PFN_vkUnmapMemory glad_vkUnmapMemory; @@ -3464,6 +5490,11 @@ GLAD_API_CALL PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets; #define vkUpdateDescriptorSets glad_vkUpdateDescriptorSets GLAD_API_CALL PFN_vkWaitForFences glad_vkWaitForFences; #define vkWaitForFences glad_vkWaitForFences +GLAD_API_CALL PFN_vkWaitSemaphores glad_vkWaitSemaphores; +#define vkWaitSemaphores glad_vkWaitSemaphores + + + GLAD_API_CALL int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void *userptr); @@ -3471,9 +5502,6 @@ GLAD_API_CALL int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc - - - #ifdef __cplusplus } #endif diff --git a/deps/glad_vulkan.c b/deps/glad_vulkan.c index 5adfbbbe..6559df8b 100644 --- a/deps/glad_vulkan.c +++ b/deps/glad_vulkan.c @@ -14,10 +14,18 @@ #endif /* GLAD_IMPL_UTIL_C_ */ +#ifdef __cplusplus +extern "C" { +#endif + + int GLAD_VK_VERSION_1_0 = 0; int GLAD_VK_VERSION_1_1 = 0; +int GLAD_VK_VERSION_1_2 = 0; +int GLAD_VK_VERSION_1_3 = 0; int GLAD_VK_EXT_debug_report = 0; +int GLAD_VK_KHR_portability_enumeration = 0; int GLAD_VK_KHR_surface = 0; int GLAD_VK_KHR_swapchain = 0; @@ -35,18 +43,26 @@ PFN_vkBindImageMemory glad_vkBindImageMemory = NULL; PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL; PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL; PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL; +PFN_vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2 = NULL; +PFN_vkCmdBeginRendering glad_vkCmdBeginRendering = NULL; PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL; PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL; PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL; PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL; +PFN_vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2 = NULL; PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL; +PFN_vkCmdBlitImage2 glad_vkCmdBlitImage2 = NULL; PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL; PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL; PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL; PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL; +PFN_vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2 = NULL; PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL; +PFN_vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2 = NULL; PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL; +PFN_vkCmdCopyImage2 glad_vkCmdCopyImage2 = NULL; PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL; +PFN_vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2 = NULL; PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL; PFN_vkCmdDispatch glad_vkCmdDispatch = NULL; PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL; @@ -54,31 +70,56 @@ PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL; PFN_vkCmdDraw glad_vkCmdDraw = NULL; PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL; PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL; +PFN_vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount = NULL; PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL; +PFN_vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount = NULL; PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL; PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL; +PFN_vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2 = NULL; +PFN_vkCmdEndRendering glad_vkCmdEndRendering = NULL; PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL; PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL; PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL; +PFN_vkCmdNextSubpass2 glad_vkCmdNextSubpass2 = NULL; PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL; +PFN_vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2 = NULL; PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL; PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL; +PFN_vkCmdResetEvent2 glad_vkCmdResetEvent2 = NULL; PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL; PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL; +PFN_vkCmdResolveImage2 glad_vkCmdResolveImage2 = NULL; PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL; +PFN_vkCmdSetCullMode glad_vkCmdSetCullMode = NULL; PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL; +PFN_vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable = NULL; PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL; +PFN_vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable = NULL; +PFN_vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp = NULL; +PFN_vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable = NULL; +PFN_vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable = NULL; PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL; PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL; +PFN_vkCmdSetEvent2 glad_vkCmdSetEvent2 = NULL; +PFN_vkCmdSetFrontFace glad_vkCmdSetFrontFace = NULL; PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL; +PFN_vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable = NULL; +PFN_vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology = NULL; +PFN_vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable = NULL; PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL; +PFN_vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount = NULL; PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL; +PFN_vkCmdSetStencilOp glad_vkCmdSetStencilOp = NULL; PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL; +PFN_vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable = NULL; PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL; PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL; +PFN_vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount = NULL; PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL; PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL; +PFN_vkCmdWaitEvents2 glad_vkCmdWaitEvents2 = NULL; PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL; +PFN_vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2 = NULL; PFN_vkCreateBuffer glad_vkCreateBuffer = NULL; PFN_vkCreateBufferView glad_vkCreateBufferView = NULL; PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL; @@ -97,8 +138,10 @@ PFN_vkCreateImageView glad_vkCreateImageView = NULL; PFN_vkCreateInstance glad_vkCreateInstance = NULL; PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL; PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL; +PFN_vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot = NULL; PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL; PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL; +PFN_vkCreateRenderPass2 glad_vkCreateRenderPass2 = NULL; PFN_vkCreateSampler glad_vkCreateSampler = NULL; PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL; PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL; @@ -122,6 +165,7 @@ PFN_vkDestroyInstance glad_vkDestroyInstance = NULL; PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL; PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL; PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL; +PFN_vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot = NULL; PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL; PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL; PFN_vkDestroySampler glad_vkDestroySampler = NULL; @@ -143,13 +187,19 @@ PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL; PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL; PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL; PFN_vkFreeMemory glad_vkFreeMemory = NULL; +PFN_vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress = NULL; PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL; PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL; +PFN_vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress = NULL; PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL; +PFN_vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements = NULL; PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL; PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL; PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL; +PFN_vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements = NULL; +PFN_vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements = NULL; PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL; +PFN_vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress = NULL; PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL; PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL; PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL; @@ -183,9 +233,12 @@ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCap PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL; PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL; PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL; +PFN_vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties = NULL; PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL; +PFN_vkGetPrivateData glad_vkGetPrivateData = NULL; PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL; PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL; +PFN_vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue = NULL; PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL; PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL; PFN_vkMapMemory glad_vkMapMemory = NULL; @@ -193,216 +246,277 @@ PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL; PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL; PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL; PFN_vkQueueSubmit glad_vkQueueSubmit = NULL; +PFN_vkQueueSubmit2 glad_vkQueueSubmit2 = NULL; PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL; PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL; PFN_vkResetCommandPool glad_vkResetCommandPool = NULL; PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL; PFN_vkResetEvent glad_vkResetEvent = NULL; PFN_vkResetFences glad_vkResetFences = NULL; +PFN_vkResetQueryPool glad_vkResetQueryPool = NULL; PFN_vkSetEvent glad_vkSetEvent = NULL; +PFN_vkSetPrivateData glad_vkSetPrivateData = NULL; +PFN_vkSignalSemaphore glad_vkSignalSemaphore = NULL; PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL; PFN_vkUnmapMemory glad_vkUnmapMemory = NULL; PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL; PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL; PFN_vkWaitForFences glad_vkWaitForFences = NULL; +PFN_vkWaitSemaphores glad_vkWaitSemaphores = NULL; static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { if(!GLAD_VK_VERSION_1_0) return; - vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load("vkAllocateCommandBuffers", userptr); - vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load("vkAllocateDescriptorSets", userptr); - vkAllocateMemory = (PFN_vkAllocateMemory) load("vkAllocateMemory", userptr); - vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load("vkBeginCommandBuffer", userptr); - vkBindBufferMemory = (PFN_vkBindBufferMemory) load("vkBindBufferMemory", userptr); - vkBindImageMemory = (PFN_vkBindImageMemory) load("vkBindImageMemory", userptr); - vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load("vkCmdBeginQuery", userptr); - vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load("vkCmdBeginRenderPass", userptr); - vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load("vkCmdBindDescriptorSets", userptr); - vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load("vkCmdBindIndexBuffer", userptr); - vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load("vkCmdBindPipeline", userptr); - vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load("vkCmdBindVertexBuffers", userptr); - vkCmdBlitImage = (PFN_vkCmdBlitImage) load("vkCmdBlitImage", userptr); - vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load("vkCmdClearAttachments", userptr); - vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load("vkCmdClearColorImage", userptr); - vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load("vkCmdClearDepthStencilImage", userptr); - vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load("vkCmdCopyBuffer", userptr); - vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load("vkCmdCopyBufferToImage", userptr); - vkCmdCopyImage = (PFN_vkCmdCopyImage) load("vkCmdCopyImage", userptr); - vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load("vkCmdCopyImageToBuffer", userptr); - vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load("vkCmdCopyQueryPoolResults", userptr); - vkCmdDispatch = (PFN_vkCmdDispatch) load("vkCmdDispatch", userptr); - vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load("vkCmdDispatchIndirect", userptr); - vkCmdDraw = (PFN_vkCmdDraw) load("vkCmdDraw", userptr); - vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load("vkCmdDrawIndexed", userptr); - vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load("vkCmdDrawIndexedIndirect", userptr); - vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load("vkCmdDrawIndirect", userptr); - vkCmdEndQuery = (PFN_vkCmdEndQuery) load("vkCmdEndQuery", userptr); - vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load("vkCmdEndRenderPass", userptr); - vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load("vkCmdExecuteCommands", userptr); - vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load("vkCmdFillBuffer", userptr); - vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load("vkCmdNextSubpass", userptr); - vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load("vkCmdPipelineBarrier", userptr); - vkCmdPushConstants = (PFN_vkCmdPushConstants) load("vkCmdPushConstants", userptr); - vkCmdResetEvent = (PFN_vkCmdResetEvent) load("vkCmdResetEvent", userptr); - vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load("vkCmdResetQueryPool", userptr); - vkCmdResolveImage = (PFN_vkCmdResolveImage) load("vkCmdResolveImage", userptr); - vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load("vkCmdSetBlendConstants", userptr); - vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load("vkCmdSetDepthBias", userptr); - vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load("vkCmdSetDepthBounds", userptr); - vkCmdSetEvent = (PFN_vkCmdSetEvent) load("vkCmdSetEvent", userptr); - vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load("vkCmdSetLineWidth", userptr); - vkCmdSetScissor = (PFN_vkCmdSetScissor) load("vkCmdSetScissor", userptr); - vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load("vkCmdSetStencilCompareMask", userptr); - vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load("vkCmdSetStencilReference", userptr); - vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load("vkCmdSetStencilWriteMask", userptr); - vkCmdSetViewport = (PFN_vkCmdSetViewport) load("vkCmdSetViewport", userptr); - vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load("vkCmdUpdateBuffer", userptr); - vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load("vkCmdWaitEvents", userptr); - vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load("vkCmdWriteTimestamp", userptr); - vkCreateBuffer = (PFN_vkCreateBuffer) load("vkCreateBuffer", userptr); - vkCreateBufferView = (PFN_vkCreateBufferView) load("vkCreateBufferView", userptr); - vkCreateCommandPool = (PFN_vkCreateCommandPool) load("vkCreateCommandPool", userptr); - vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load("vkCreateComputePipelines", userptr); - vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load("vkCreateDescriptorPool", userptr); - vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load("vkCreateDescriptorSetLayout", userptr); - vkCreateDevice = (PFN_vkCreateDevice) load("vkCreateDevice", userptr); - vkCreateEvent = (PFN_vkCreateEvent) load("vkCreateEvent", userptr); - vkCreateFence = (PFN_vkCreateFence) load("vkCreateFence", userptr); - vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load("vkCreateFramebuffer", userptr); - vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load("vkCreateGraphicsPipelines", userptr); - vkCreateImage = (PFN_vkCreateImage) load("vkCreateImage", userptr); - vkCreateImageView = (PFN_vkCreateImageView) load("vkCreateImageView", userptr); - vkCreateInstance = (PFN_vkCreateInstance) load("vkCreateInstance", userptr); - vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load("vkCreatePipelineCache", userptr); - vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load("vkCreatePipelineLayout", userptr); - vkCreateQueryPool = (PFN_vkCreateQueryPool) load("vkCreateQueryPool", userptr); - vkCreateRenderPass = (PFN_vkCreateRenderPass) load("vkCreateRenderPass", userptr); - vkCreateSampler = (PFN_vkCreateSampler) load("vkCreateSampler", userptr); - vkCreateSemaphore = (PFN_vkCreateSemaphore) load("vkCreateSemaphore", userptr); - vkCreateShaderModule = (PFN_vkCreateShaderModule) load("vkCreateShaderModule", userptr); - vkDestroyBuffer = (PFN_vkDestroyBuffer) load("vkDestroyBuffer", userptr); - vkDestroyBufferView = (PFN_vkDestroyBufferView) load("vkDestroyBufferView", userptr); - vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load("vkDestroyCommandPool", userptr); - vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load("vkDestroyDescriptorPool", userptr); - vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load("vkDestroyDescriptorSetLayout", userptr); - vkDestroyDevice = (PFN_vkDestroyDevice) load("vkDestroyDevice", userptr); - vkDestroyEvent = (PFN_vkDestroyEvent) load("vkDestroyEvent", userptr); - vkDestroyFence = (PFN_vkDestroyFence) load("vkDestroyFence", userptr); - vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load("vkDestroyFramebuffer", userptr); - vkDestroyImage = (PFN_vkDestroyImage) load("vkDestroyImage", userptr); - vkDestroyImageView = (PFN_vkDestroyImageView) load("vkDestroyImageView", userptr); - vkDestroyInstance = (PFN_vkDestroyInstance) load("vkDestroyInstance", userptr); - vkDestroyPipeline = (PFN_vkDestroyPipeline) load("vkDestroyPipeline", userptr); - vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load("vkDestroyPipelineCache", userptr); - vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load("vkDestroyPipelineLayout", userptr); - vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load("vkDestroyQueryPool", userptr); - vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load("vkDestroyRenderPass", userptr); - vkDestroySampler = (PFN_vkDestroySampler) load("vkDestroySampler", userptr); - vkDestroySemaphore = (PFN_vkDestroySemaphore) load("vkDestroySemaphore", userptr); - vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load("vkDestroyShaderModule", userptr); - vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load("vkDeviceWaitIdle", userptr); - vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load("vkEndCommandBuffer", userptr); - vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load("vkEnumerateDeviceExtensionProperties", userptr); - vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load("vkEnumerateDeviceLayerProperties", userptr); - vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load("vkEnumerateInstanceExtensionProperties", userptr); - vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load("vkEnumerateInstanceLayerProperties", userptr); - vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load("vkEnumeratePhysicalDevices", userptr); - vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load("vkFlushMappedMemoryRanges", userptr); - vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load("vkFreeCommandBuffers", userptr); - vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load("vkFreeDescriptorSets", userptr); - vkFreeMemory = (PFN_vkFreeMemory) load("vkFreeMemory", userptr); - vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load("vkGetBufferMemoryRequirements", userptr); - vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load("vkGetDeviceMemoryCommitment", userptr); - vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load("vkGetDeviceProcAddr", userptr); - vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load("vkGetDeviceQueue", userptr); - vkGetEventStatus = (PFN_vkGetEventStatus) load("vkGetEventStatus", userptr); - vkGetFenceStatus = (PFN_vkGetFenceStatus) load("vkGetFenceStatus", userptr); - vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load("vkGetImageMemoryRequirements", userptr); - vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load("vkGetImageSparseMemoryRequirements", userptr); - vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load("vkGetImageSubresourceLayout", userptr); - vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load("vkGetInstanceProcAddr", userptr); - vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load("vkGetPhysicalDeviceFeatures", userptr); - vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load("vkGetPhysicalDeviceFormatProperties", userptr); - vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load("vkGetPhysicalDeviceImageFormatProperties", userptr); - vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load("vkGetPhysicalDeviceMemoryProperties", userptr); - vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load("vkGetPhysicalDeviceProperties", userptr); - vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load("vkGetPhysicalDeviceQueueFamilyProperties", userptr); - vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load("vkGetPhysicalDeviceSparseImageFormatProperties", userptr); - vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load("vkGetPipelineCacheData", userptr); - vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load("vkGetQueryPoolResults", userptr); - vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load("vkGetRenderAreaGranularity", userptr); - vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load("vkInvalidateMappedMemoryRanges", userptr); - vkMapMemory = (PFN_vkMapMemory) load("vkMapMemory", userptr); - vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load("vkMergePipelineCaches", userptr); - vkQueueBindSparse = (PFN_vkQueueBindSparse) load("vkQueueBindSparse", userptr); - vkQueueSubmit = (PFN_vkQueueSubmit) load("vkQueueSubmit", userptr); - vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load("vkQueueWaitIdle", userptr); - vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load("vkResetCommandBuffer", userptr); - vkResetCommandPool = (PFN_vkResetCommandPool) load("vkResetCommandPool", userptr); - vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load("vkResetDescriptorPool", userptr); - vkResetEvent = (PFN_vkResetEvent) load("vkResetEvent", userptr); - vkResetFences = (PFN_vkResetFences) load("vkResetFences", userptr); - vkSetEvent = (PFN_vkSetEvent) load("vkSetEvent", userptr); - vkUnmapMemory = (PFN_vkUnmapMemory) load("vkUnmapMemory", userptr); - vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load("vkUpdateDescriptorSets", userptr); - vkWaitForFences = (PFN_vkWaitForFences) load("vkWaitForFences", userptr); + glad_vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load(userptr, "vkAllocateCommandBuffers"); + glad_vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load(userptr, "vkAllocateDescriptorSets"); + glad_vkAllocateMemory = (PFN_vkAllocateMemory) load(userptr, "vkAllocateMemory"); + glad_vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load(userptr, "vkBeginCommandBuffer"); + glad_vkBindBufferMemory = (PFN_vkBindBufferMemory) load(userptr, "vkBindBufferMemory"); + glad_vkBindImageMemory = (PFN_vkBindImageMemory) load(userptr, "vkBindImageMemory"); + glad_vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load(userptr, "vkCmdBeginQuery"); + glad_vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load(userptr, "vkCmdBeginRenderPass"); + glad_vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load(userptr, "vkCmdBindDescriptorSets"); + glad_vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load(userptr, "vkCmdBindIndexBuffer"); + glad_vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load(userptr, "vkCmdBindPipeline"); + glad_vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load(userptr, "vkCmdBindVertexBuffers"); + glad_vkCmdBlitImage = (PFN_vkCmdBlitImage) load(userptr, "vkCmdBlitImage"); + glad_vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load(userptr, "vkCmdClearAttachments"); + glad_vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load(userptr, "vkCmdClearColorImage"); + glad_vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load(userptr, "vkCmdClearDepthStencilImage"); + glad_vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load(userptr, "vkCmdCopyBuffer"); + glad_vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load(userptr, "vkCmdCopyBufferToImage"); + glad_vkCmdCopyImage = (PFN_vkCmdCopyImage) load(userptr, "vkCmdCopyImage"); + glad_vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load(userptr, "vkCmdCopyImageToBuffer"); + glad_vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load(userptr, "vkCmdCopyQueryPoolResults"); + glad_vkCmdDispatch = (PFN_vkCmdDispatch) load(userptr, "vkCmdDispatch"); + glad_vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load(userptr, "vkCmdDispatchIndirect"); + glad_vkCmdDraw = (PFN_vkCmdDraw) load(userptr, "vkCmdDraw"); + glad_vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load(userptr, "vkCmdDrawIndexed"); + glad_vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load(userptr, "vkCmdDrawIndexedIndirect"); + glad_vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load(userptr, "vkCmdDrawIndirect"); + glad_vkCmdEndQuery = (PFN_vkCmdEndQuery) load(userptr, "vkCmdEndQuery"); + glad_vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load(userptr, "vkCmdEndRenderPass"); + glad_vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load(userptr, "vkCmdExecuteCommands"); + glad_vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load(userptr, "vkCmdFillBuffer"); + glad_vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load(userptr, "vkCmdNextSubpass"); + glad_vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load(userptr, "vkCmdPipelineBarrier"); + glad_vkCmdPushConstants = (PFN_vkCmdPushConstants) load(userptr, "vkCmdPushConstants"); + glad_vkCmdResetEvent = (PFN_vkCmdResetEvent) load(userptr, "vkCmdResetEvent"); + glad_vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load(userptr, "vkCmdResetQueryPool"); + glad_vkCmdResolveImage = (PFN_vkCmdResolveImage) load(userptr, "vkCmdResolveImage"); + glad_vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load(userptr, "vkCmdSetBlendConstants"); + glad_vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load(userptr, "vkCmdSetDepthBias"); + glad_vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load(userptr, "vkCmdSetDepthBounds"); + glad_vkCmdSetEvent = (PFN_vkCmdSetEvent) load(userptr, "vkCmdSetEvent"); + glad_vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load(userptr, "vkCmdSetLineWidth"); + glad_vkCmdSetScissor = (PFN_vkCmdSetScissor) load(userptr, "vkCmdSetScissor"); + glad_vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load(userptr, "vkCmdSetStencilCompareMask"); + glad_vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load(userptr, "vkCmdSetStencilReference"); + glad_vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load(userptr, "vkCmdSetStencilWriteMask"); + glad_vkCmdSetViewport = (PFN_vkCmdSetViewport) load(userptr, "vkCmdSetViewport"); + glad_vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load(userptr, "vkCmdUpdateBuffer"); + glad_vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load(userptr, "vkCmdWaitEvents"); + glad_vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load(userptr, "vkCmdWriteTimestamp"); + glad_vkCreateBuffer = (PFN_vkCreateBuffer) load(userptr, "vkCreateBuffer"); + glad_vkCreateBufferView = (PFN_vkCreateBufferView) load(userptr, "vkCreateBufferView"); + glad_vkCreateCommandPool = (PFN_vkCreateCommandPool) load(userptr, "vkCreateCommandPool"); + glad_vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load(userptr, "vkCreateComputePipelines"); + glad_vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load(userptr, "vkCreateDescriptorPool"); + glad_vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load(userptr, "vkCreateDescriptorSetLayout"); + glad_vkCreateDevice = (PFN_vkCreateDevice) load(userptr, "vkCreateDevice"); + glad_vkCreateEvent = (PFN_vkCreateEvent) load(userptr, "vkCreateEvent"); + glad_vkCreateFence = (PFN_vkCreateFence) load(userptr, "vkCreateFence"); + glad_vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load(userptr, "vkCreateFramebuffer"); + glad_vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load(userptr, "vkCreateGraphicsPipelines"); + glad_vkCreateImage = (PFN_vkCreateImage) load(userptr, "vkCreateImage"); + glad_vkCreateImageView = (PFN_vkCreateImageView) load(userptr, "vkCreateImageView"); + glad_vkCreateInstance = (PFN_vkCreateInstance) load(userptr, "vkCreateInstance"); + glad_vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load(userptr, "vkCreatePipelineCache"); + glad_vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load(userptr, "vkCreatePipelineLayout"); + glad_vkCreateQueryPool = (PFN_vkCreateQueryPool) load(userptr, "vkCreateQueryPool"); + glad_vkCreateRenderPass = (PFN_vkCreateRenderPass) load(userptr, "vkCreateRenderPass"); + glad_vkCreateSampler = (PFN_vkCreateSampler) load(userptr, "vkCreateSampler"); + glad_vkCreateSemaphore = (PFN_vkCreateSemaphore) load(userptr, "vkCreateSemaphore"); + glad_vkCreateShaderModule = (PFN_vkCreateShaderModule) load(userptr, "vkCreateShaderModule"); + glad_vkDestroyBuffer = (PFN_vkDestroyBuffer) load(userptr, "vkDestroyBuffer"); + glad_vkDestroyBufferView = (PFN_vkDestroyBufferView) load(userptr, "vkDestroyBufferView"); + glad_vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load(userptr, "vkDestroyCommandPool"); + glad_vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load(userptr, "vkDestroyDescriptorPool"); + glad_vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load(userptr, "vkDestroyDescriptorSetLayout"); + glad_vkDestroyDevice = (PFN_vkDestroyDevice) load(userptr, "vkDestroyDevice"); + glad_vkDestroyEvent = (PFN_vkDestroyEvent) load(userptr, "vkDestroyEvent"); + glad_vkDestroyFence = (PFN_vkDestroyFence) load(userptr, "vkDestroyFence"); + glad_vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load(userptr, "vkDestroyFramebuffer"); + glad_vkDestroyImage = (PFN_vkDestroyImage) load(userptr, "vkDestroyImage"); + glad_vkDestroyImageView = (PFN_vkDestroyImageView) load(userptr, "vkDestroyImageView"); + glad_vkDestroyInstance = (PFN_vkDestroyInstance) load(userptr, "vkDestroyInstance"); + glad_vkDestroyPipeline = (PFN_vkDestroyPipeline) load(userptr, "vkDestroyPipeline"); + glad_vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load(userptr, "vkDestroyPipelineCache"); + glad_vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load(userptr, "vkDestroyPipelineLayout"); + glad_vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load(userptr, "vkDestroyQueryPool"); + glad_vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load(userptr, "vkDestroyRenderPass"); + glad_vkDestroySampler = (PFN_vkDestroySampler) load(userptr, "vkDestroySampler"); + glad_vkDestroySemaphore = (PFN_vkDestroySemaphore) load(userptr, "vkDestroySemaphore"); + glad_vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load(userptr, "vkDestroyShaderModule"); + glad_vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load(userptr, "vkDeviceWaitIdle"); + glad_vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load(userptr, "vkEndCommandBuffer"); + glad_vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load(userptr, "vkEnumerateDeviceExtensionProperties"); + glad_vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load(userptr, "vkEnumerateDeviceLayerProperties"); + glad_vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load(userptr, "vkEnumerateInstanceExtensionProperties"); + glad_vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load(userptr, "vkEnumerateInstanceLayerProperties"); + glad_vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load(userptr, "vkEnumeratePhysicalDevices"); + glad_vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load(userptr, "vkFlushMappedMemoryRanges"); + glad_vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load(userptr, "vkFreeCommandBuffers"); + glad_vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load(userptr, "vkFreeDescriptorSets"); + glad_vkFreeMemory = (PFN_vkFreeMemory) load(userptr, "vkFreeMemory"); + glad_vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load(userptr, "vkGetBufferMemoryRequirements"); + glad_vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load(userptr, "vkGetDeviceMemoryCommitment"); + glad_vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load(userptr, "vkGetDeviceProcAddr"); + glad_vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load(userptr, "vkGetDeviceQueue"); + glad_vkGetEventStatus = (PFN_vkGetEventStatus) load(userptr, "vkGetEventStatus"); + glad_vkGetFenceStatus = (PFN_vkGetFenceStatus) load(userptr, "vkGetFenceStatus"); + glad_vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load(userptr, "vkGetImageMemoryRequirements"); + glad_vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load(userptr, "vkGetImageSparseMemoryRequirements"); + glad_vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load(userptr, "vkGetImageSubresourceLayout"); + glad_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load(userptr, "vkGetInstanceProcAddr"); + glad_vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load(userptr, "vkGetPhysicalDeviceFeatures"); + glad_vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load(userptr, "vkGetPhysicalDeviceFormatProperties"); + glad_vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load(userptr, "vkGetPhysicalDeviceImageFormatProperties"); + glad_vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load(userptr, "vkGetPhysicalDeviceMemoryProperties"); + glad_vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load(userptr, "vkGetPhysicalDeviceProperties"); + glad_vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties"); + glad_vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties"); + glad_vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load(userptr, "vkGetPipelineCacheData"); + glad_vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load(userptr, "vkGetQueryPoolResults"); + glad_vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load(userptr, "vkGetRenderAreaGranularity"); + glad_vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load(userptr, "vkInvalidateMappedMemoryRanges"); + glad_vkMapMemory = (PFN_vkMapMemory) load(userptr, "vkMapMemory"); + glad_vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load(userptr, "vkMergePipelineCaches"); + glad_vkQueueBindSparse = (PFN_vkQueueBindSparse) load(userptr, "vkQueueBindSparse"); + glad_vkQueueSubmit = (PFN_vkQueueSubmit) load(userptr, "vkQueueSubmit"); + glad_vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load(userptr, "vkQueueWaitIdle"); + glad_vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load(userptr, "vkResetCommandBuffer"); + glad_vkResetCommandPool = (PFN_vkResetCommandPool) load(userptr, "vkResetCommandPool"); + glad_vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load(userptr, "vkResetDescriptorPool"); + glad_vkResetEvent = (PFN_vkResetEvent) load(userptr, "vkResetEvent"); + glad_vkResetFences = (PFN_vkResetFences) load(userptr, "vkResetFences"); + glad_vkSetEvent = (PFN_vkSetEvent) load(userptr, "vkSetEvent"); + glad_vkUnmapMemory = (PFN_vkUnmapMemory) load(userptr, "vkUnmapMemory"); + glad_vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load(userptr, "vkUpdateDescriptorSets"); + glad_vkWaitForFences = (PFN_vkWaitForFences) load(userptr, "vkWaitForFences"); } static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { if(!GLAD_VK_VERSION_1_1) return; - vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load("vkBindBufferMemory2", userptr); - vkBindImageMemory2 = (PFN_vkBindImageMemory2) load("vkBindImageMemory2", userptr); - vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load("vkCmdDispatchBase", userptr); - vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load("vkCmdSetDeviceMask", userptr); - vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load("vkCreateDescriptorUpdateTemplate", userptr); - vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load("vkCreateSamplerYcbcrConversion", userptr); - vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load("vkDestroyDescriptorUpdateTemplate", userptr); - vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load("vkDestroySamplerYcbcrConversion", userptr); - vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr); - vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load("vkEnumeratePhysicalDeviceGroups", userptr); - vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load("vkGetBufferMemoryRequirements2", userptr); - vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load("vkGetDescriptorSetLayoutSupport", userptr); - vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load("vkGetDeviceGroupPeerMemoryFeatures", userptr); - vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load("vkGetDeviceQueue2", userptr); - vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load("vkGetImageMemoryRequirements2", userptr); - vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load("vkGetImageSparseMemoryRequirements2", userptr); - vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load("vkGetPhysicalDeviceExternalBufferProperties", userptr); - vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load("vkGetPhysicalDeviceExternalFenceProperties", userptr); - vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load("vkGetPhysicalDeviceExternalSemaphoreProperties", userptr); - vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load("vkGetPhysicalDeviceFeatures2", userptr); - vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load("vkGetPhysicalDeviceFormatProperties2", userptr); - vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load("vkGetPhysicalDeviceImageFormatProperties2", userptr); - vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load("vkGetPhysicalDeviceMemoryProperties2", userptr); - vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load("vkGetPhysicalDeviceProperties2", userptr); - vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load("vkGetPhysicalDeviceQueueFamilyProperties2", userptr); - vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load("vkGetPhysicalDeviceSparseImageFormatProperties2", userptr); - vkTrimCommandPool = (PFN_vkTrimCommandPool) load("vkTrimCommandPool", userptr); - vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load("vkUpdateDescriptorSetWithTemplate", userptr); + glad_vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load(userptr, "vkBindBufferMemory2"); + glad_vkBindImageMemory2 = (PFN_vkBindImageMemory2) load(userptr, "vkBindImageMemory2"); + glad_vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load(userptr, "vkCmdDispatchBase"); + glad_vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load(userptr, "vkCmdSetDeviceMask"); + glad_vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load(userptr, "vkCreateDescriptorUpdateTemplate"); + glad_vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load(userptr, "vkCreateSamplerYcbcrConversion"); + glad_vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load(userptr, "vkDestroyDescriptorUpdateTemplate"); + glad_vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load(userptr, "vkDestroySamplerYcbcrConversion"); + glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion"); + glad_vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load(userptr, "vkEnumeratePhysicalDeviceGroups"); + glad_vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load(userptr, "vkGetBufferMemoryRequirements2"); + glad_vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load(userptr, "vkGetDescriptorSetLayoutSupport"); + glad_vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load(userptr, "vkGetDeviceGroupPeerMemoryFeatures"); + glad_vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load(userptr, "vkGetDeviceQueue2"); + glad_vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load(userptr, "vkGetImageMemoryRequirements2"); + glad_vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load(userptr, "vkGetImageSparseMemoryRequirements2"); + glad_vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load(userptr, "vkGetPhysicalDeviceExternalBufferProperties"); + glad_vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load(userptr, "vkGetPhysicalDeviceExternalFenceProperties"); + glad_vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load(userptr, "vkGetPhysicalDeviceExternalSemaphoreProperties"); + glad_vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load(userptr, "vkGetPhysicalDeviceFeatures2"); + glad_vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load(userptr, "vkGetPhysicalDeviceFormatProperties2"); + glad_vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceImageFormatProperties2"); + glad_vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load(userptr, "vkGetPhysicalDeviceMemoryProperties2"); + glad_vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load(userptr, "vkGetPhysicalDeviceProperties2"); + glad_vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties2"); + glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties2"); + glad_vkTrimCommandPool = (PFN_vkTrimCommandPool) load(userptr, "vkTrimCommandPool"); + glad_vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load(userptr, "vkUpdateDescriptorSetWithTemplate"); +} +static void glad_vk_load_VK_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_VK_VERSION_1_2) return; + glad_vkCmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2) load(userptr, "vkCmdBeginRenderPass2"); + glad_vkCmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount) load(userptr, "vkCmdDrawIndexedIndirectCount"); + glad_vkCmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount) load(userptr, "vkCmdDrawIndirectCount"); + glad_vkCmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2) load(userptr, "vkCmdEndRenderPass2"); + glad_vkCmdNextSubpass2 = (PFN_vkCmdNextSubpass2) load(userptr, "vkCmdNextSubpass2"); + glad_vkCreateRenderPass2 = (PFN_vkCreateRenderPass2) load(userptr, "vkCreateRenderPass2"); + glad_vkGetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress) load(userptr, "vkGetBufferDeviceAddress"); + glad_vkGetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress) load(userptr, "vkGetBufferOpaqueCaptureAddress"); + glad_vkGetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress) load(userptr, "vkGetDeviceMemoryOpaqueCaptureAddress"); + glad_vkGetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue) load(userptr, "vkGetSemaphoreCounterValue"); + glad_vkResetQueryPool = (PFN_vkResetQueryPool) load(userptr, "vkResetQueryPool"); + glad_vkSignalSemaphore = (PFN_vkSignalSemaphore) load(userptr, "vkSignalSemaphore"); + glad_vkWaitSemaphores = (PFN_vkWaitSemaphores) load(userptr, "vkWaitSemaphores"); +} +static void glad_vk_load_VK_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_VK_VERSION_1_3) return; + glad_vkCmdBeginRendering = (PFN_vkCmdBeginRendering) load(userptr, "vkCmdBeginRendering"); + glad_vkCmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2) load(userptr, "vkCmdBindVertexBuffers2"); + glad_vkCmdBlitImage2 = (PFN_vkCmdBlitImage2) load(userptr, "vkCmdBlitImage2"); + glad_vkCmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2) load(userptr, "vkCmdCopyBuffer2"); + glad_vkCmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2) load(userptr, "vkCmdCopyBufferToImage2"); + glad_vkCmdCopyImage2 = (PFN_vkCmdCopyImage2) load(userptr, "vkCmdCopyImage2"); + glad_vkCmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2) load(userptr, "vkCmdCopyImageToBuffer2"); + glad_vkCmdEndRendering = (PFN_vkCmdEndRendering) load(userptr, "vkCmdEndRendering"); + glad_vkCmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2) load(userptr, "vkCmdPipelineBarrier2"); + glad_vkCmdResetEvent2 = (PFN_vkCmdResetEvent2) load(userptr, "vkCmdResetEvent2"); + glad_vkCmdResolveImage2 = (PFN_vkCmdResolveImage2) load(userptr, "vkCmdResolveImage2"); + glad_vkCmdSetCullMode = (PFN_vkCmdSetCullMode) load(userptr, "vkCmdSetCullMode"); + glad_vkCmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable) load(userptr, "vkCmdSetDepthBiasEnable"); + glad_vkCmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable) load(userptr, "vkCmdSetDepthBoundsTestEnable"); + glad_vkCmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp) load(userptr, "vkCmdSetDepthCompareOp"); + glad_vkCmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable) load(userptr, "vkCmdSetDepthTestEnable"); + glad_vkCmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable) load(userptr, "vkCmdSetDepthWriteEnable"); + glad_vkCmdSetEvent2 = (PFN_vkCmdSetEvent2) load(userptr, "vkCmdSetEvent2"); + glad_vkCmdSetFrontFace = (PFN_vkCmdSetFrontFace) load(userptr, "vkCmdSetFrontFace"); + glad_vkCmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable) load(userptr, "vkCmdSetPrimitiveRestartEnable"); + glad_vkCmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology) load(userptr, "vkCmdSetPrimitiveTopology"); + glad_vkCmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable) load(userptr, "vkCmdSetRasterizerDiscardEnable"); + glad_vkCmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount) load(userptr, "vkCmdSetScissorWithCount"); + glad_vkCmdSetStencilOp = (PFN_vkCmdSetStencilOp) load(userptr, "vkCmdSetStencilOp"); + glad_vkCmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable) load(userptr, "vkCmdSetStencilTestEnable"); + glad_vkCmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount) load(userptr, "vkCmdSetViewportWithCount"); + glad_vkCmdWaitEvents2 = (PFN_vkCmdWaitEvents2) load(userptr, "vkCmdWaitEvents2"); + glad_vkCmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2) load(userptr, "vkCmdWriteTimestamp2"); + glad_vkCreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot) load(userptr, "vkCreatePrivateDataSlot"); + glad_vkDestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot) load(userptr, "vkDestroyPrivateDataSlot"); + glad_vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements) load(userptr, "vkGetDeviceBufferMemoryRequirements"); + glad_vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements) load(userptr, "vkGetDeviceImageMemoryRequirements"); + glad_vkGetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements) load(userptr, "vkGetDeviceImageSparseMemoryRequirements"); + glad_vkGetPhysicalDeviceToolProperties = (PFN_vkGetPhysicalDeviceToolProperties) load(userptr, "vkGetPhysicalDeviceToolProperties"); + glad_vkGetPrivateData = (PFN_vkGetPrivateData) load(userptr, "vkGetPrivateData"); + glad_vkQueueSubmit2 = (PFN_vkQueueSubmit2) load(userptr, "vkQueueSubmit2"); + glad_vkSetPrivateData = (PFN_vkSetPrivateData) load(userptr, "vkSetPrivateData"); } static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) { if(!GLAD_VK_EXT_debug_report) return; - vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load("vkCreateDebugReportCallbackEXT", userptr); - vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load("vkDebugReportMessageEXT", userptr); - vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load("vkDestroyDebugReportCallbackEXT", userptr); + glad_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load(userptr, "vkCreateDebugReportCallbackEXT"); + glad_vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load(userptr, "vkDebugReportMessageEXT"); + glad_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load(userptr, "vkDestroyDebugReportCallbackEXT"); } static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) { if(!GLAD_VK_KHR_surface) return; - vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load("vkDestroySurfaceKHR", userptr); - vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", userptr); - vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load("vkGetPhysicalDeviceSurfaceFormatsKHR", userptr); - vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load("vkGetPhysicalDeviceSurfacePresentModesKHR", userptr); - vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load("vkGetPhysicalDeviceSurfaceSupportKHR", userptr); + glad_vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load(userptr, "vkDestroySurfaceKHR"); + glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load(userptr, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); + glad_vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load(userptr, "vkGetPhysicalDeviceSurfaceFormatsKHR"); + glad_vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load(userptr, "vkGetPhysicalDeviceSurfacePresentModesKHR"); + glad_vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load(userptr, "vkGetPhysicalDeviceSurfaceSupportKHR"); } static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) { if(!GLAD_VK_KHR_swapchain) return; - vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load("vkAcquireNextImage2KHR", userptr); - vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load("vkAcquireNextImageKHR", userptr); - vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load("vkCreateSwapchainKHR", userptr); - vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load("vkDestroySwapchainKHR", userptr); - vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load("vkGetDeviceGroupPresentCapabilitiesKHR", userptr); - vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load("vkGetDeviceGroupSurfacePresentModesKHR", userptr); - vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load("vkGetPhysicalDevicePresentRectanglesKHR", userptr); - vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load("vkGetSwapchainImagesKHR", userptr); - vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load("vkQueuePresentKHR", userptr); + glad_vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load(userptr, "vkAcquireNextImage2KHR"); + glad_vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load(userptr, "vkAcquireNextImageKHR"); + glad_vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load(userptr, "vkCreateSwapchainKHR"); + glad_vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load(userptr, "vkDestroySwapchainKHR"); + glad_vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load(userptr, "vkGetDeviceGroupPresentCapabilitiesKHR"); + glad_vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load(userptr, "vkGetDeviceGroupSurfacePresentModesKHR"); + glad_vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load(userptr, "vkGetPhysicalDevicePresentRectanglesKHR"); + glad_vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load(userptr, "vkGetSwapchainImagesKHR"); + glad_vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load(userptr, "vkQueuePresentKHR"); } @@ -411,47 +525,49 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o uint32_t i; uint32_t instance_extension_count = 0; uint32_t device_extension_count = 0; - uint32_t max_extension_count; - uint32_t total_extension_count; - char **extensions; - VkExtensionProperties *ext_properties; + uint32_t max_extension_count = 0; + uint32_t total_extension_count = 0; + char **extensions = NULL; + VkExtensionProperties *ext_properties = NULL; VkResult result; - if (vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && vkEnumerateDeviceExtensionProperties == NULL)) { + if (glad_vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && glad_vkEnumerateDeviceExtensionProperties == NULL)) { return 0; } - result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL); + result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL); if (result != VK_SUCCESS) { return 0; } if (physical_device != NULL) { - result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL); + result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL); if (result != VK_SUCCESS) { return 0; } } total_extension_count = instance_extension_count + device_extension_count; + if (total_extension_count <= 0) { + return 0; + } + max_extension_count = instance_extension_count > device_extension_count ? instance_extension_count : device_extension_count; ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties)); if (ext_properties == NULL) { - return 0; + goto glad_vk_get_extensions_error; } - result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties); + result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties); if (result != VK_SUCCESS) { - free((void*) ext_properties); - return 0; + goto glad_vk_get_extensions_error; } extensions = (char**) calloc(total_extension_count, sizeof(char*)); if (extensions == NULL) { - free((void*) ext_properties); - return 0; + goto glad_vk_get_extensions_error; } for (i = 0; i < instance_extension_count; ++i) { @@ -459,17 +575,16 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o size_t extension_name_length = strlen(ext.extensionName) + 1; extensions[i] = (char*) malloc(extension_name_length * sizeof(char)); + if (extensions[i] == NULL) { + goto glad_vk_get_extensions_error; + } memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char)); } if (physical_device != NULL) { - result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties); + result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties); if (result != VK_SUCCESS) { - for (i = 0; i < instance_extension_count; ++i) { - free((void*) extensions[i]); - } - free(extensions); - return 0; + goto glad_vk_get_extensions_error; } for (i = 0; i < device_extension_count; ++i) { @@ -477,6 +592,9 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o size_t extension_name_length = strlen(ext.extensionName) + 1; extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char)); + if (extensions[instance_extension_count + i] == NULL) { + goto glad_vk_get_extensions_error; + } memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char)); } } @@ -487,6 +605,16 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o *out_extensions = extensions; return 1; + +glad_vk_get_extensions_error: + free((void*) ext_properties); + if (extensions != NULL) { + for (i = 0; i < total_extension_count; ++i) { + free((void*) extensions[i]); + } + free(extensions); + } + return 0; } static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) { @@ -503,7 +631,7 @@ static int glad_vk_has_extension(const char *name, uint32_t extension_count, cha uint32_t i; for (i = 0; i < extension_count; ++i) { - if(strcmp(name, extensions[i]) == 0) { + if(extensions[i] != NULL && strcmp(name, extensions[i]) == 0) { return 1; } } @@ -511,7 +639,7 @@ static int glad_vk_has_extension(const char *name, uint32_t extension_count, cha return 0; } -static GLADapiproc glad_vk_get_proc_from_userptr(const char* name, void *userptr) { +static GLADapiproc glad_vk_get_proc_from_userptr(void *userptr, const char* name) { return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); } @@ -521,9 +649,12 @@ static int glad_vk_find_extensions_vulkan( VkPhysicalDevice physical_device) { if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0; GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions); + GLAD_VK_KHR_portability_enumeration = glad_vk_has_extension("VK_KHR_portability_enumeration", extension_count, extensions); GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions); GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions); + (void) glad_vk_has_extension; + glad_vk_free_extensions(extension_count, extensions); return 1; @@ -534,11 +665,11 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) { int minor = 0; #ifdef VK_VERSION_1_1 - if (vkEnumerateInstanceVersion != NULL) { + if (glad_vkEnumerateInstanceVersion != NULL) { uint32_t version; VkResult result; - result = vkEnumerateInstanceVersion(&version); + result = glad_vkEnumerateInstanceVersion(&version); if (result == VK_SUCCESS) { major = (int) VK_VERSION_MAJOR(version); minor = (int) VK_VERSION_MINOR(version); @@ -546,9 +677,9 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) { } #endif - if (physical_device != NULL && vkGetPhysicalDeviceProperties != NULL) { + if (physical_device != NULL && glad_vkGetPhysicalDeviceProperties != NULL) { VkPhysicalDeviceProperties properties; - vkGetPhysicalDeviceProperties(physical_device, &properties); + glad_vkGetPhysicalDeviceProperties(physical_device, &properties); major = (int) VK_VERSION_MAJOR(properties.apiVersion); minor = (int) VK_VERSION_MINOR(properties.apiVersion); @@ -556,6 +687,8 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) { GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_VK_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_VK_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; return GLAD_MAKE_VERSION(major, minor); } @@ -564,7 +697,7 @@ int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc int version; #ifdef VK_VERSION_1_1 - vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr); + glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion"); #endif version = glad_vk_find_core_vulkan( physical_device); if (!version) { @@ -573,6 +706,8 @@ int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc glad_vk_load_VK_VERSION_1_0(load, userptr); glad_vk_load_VK_VERSION_1_1(load, userptr); + glad_vk_load_VK_VERSION_1_2(load, userptr); + glad_vk_load_VK_VERSION_1_3(load, userptr); if (!glad_vk_find_extensions_vulkan( physical_device)) return 0; glad_vk_load_VK_EXT_debug_report(load, userptr); @@ -590,4 +725,9 @@ int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) { + + +#ifdef __cplusplus +} +#endif From 109f836675d43d84a88821680eea1a711df01c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 6 Jul 2022 23:07:20 +0200 Subject: [PATCH 105/207] Add support for VK_KHR_portability_enumeration The use of this extension is required to enable the MoltenVK physical device as of Vulkan SDK 1.3.216.0. This is because MoltenVK is still very (very) slightly non-conformant. This was adapted to 3.3-stable from 3b3d58df47166865494c29cf3aeb826d1dd29777 and 84e165ef64ce117c5f1fa99b607f5bd143973e65. --- tests/glfwinfo.c | 179 +++++++++++++++++++++++----------------- tests/triangle-vulkan.c | 24 ++++-- 2 files changed, 116 insertions(+), 87 deletions(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 074bcbd6..f681e0a5 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -210,30 +210,6 @@ static void list_context_extensions(int client, int major, int minor) } } -static void list_vulkan_instance_extensions(void) -{ - uint32_t i, ep_count = 0; - VkExtensionProperties* ep; - - printf("Vulkan instance extensions:\n"); - - if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL) != VK_SUCCESS) - return; - - ep = calloc(ep_count, sizeof(VkExtensionProperties)); - - if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep) != VK_SUCCESS) - { - free(ep); - return; - } - - for (i = 0; i < ep_count; i++) - printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion); - - free(ep); -} - static void list_vulkan_instance_layers(void) { uint32_t i, lp_count = 0; @@ -263,30 +239,6 @@ static void list_vulkan_instance_layers(void) free(lp); } -static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device) -{ - uint32_t i, ep_count; - VkExtensionProperties* ep; - - printf("Vulkan device extensions:\n"); - - if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL) != VK_SUCCESS) - return; - - ep = calloc(ep_count, sizeof(VkExtensionProperties)); - - if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep) != VK_SUCCESS) - { - free(ep); - return; - } - - for (i = 0; i < ep_count; i++) - printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion); - - free(ep); -} - static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device) { uint32_t i, lp_count; @@ -346,11 +298,6 @@ static void print_version(void) printf("GLFW library version string: \"%s\"\n", glfwGetVersionString()); } -static GLADapiproc glad_vulkan_callback(const char* name, void* user) -{ - return glfwGetInstanceProcAddress((VkInstance) user, name); -} - int main(int argc, char** argv) { int ch, client, major, minor, revision, profile; @@ -812,14 +759,16 @@ int main(int argc, char** argv) if (glfwVulkanSupported()) { uint32_t loader_version = VK_API_VERSION_1_0; - uint32_t i, re_count, pd_count; + int portability_enumeration = GLFW_FALSE; + uint32_t i, j, glfw_re_count, re_count, pd_count, ep_count; + const char** glfw_re; const char** re; VkApplicationInfo ai = {0}; VkInstanceCreateInfo ici = {0}; VkInstance instance; VkPhysicalDevice* pd; - gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL); + gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, NULL); if (vkEnumerateInstanceVersion) { @@ -832,20 +781,47 @@ int main(int argc, char** argv) VK_VERSION_MAJOR(loader_version), VK_VERSION_MINOR(loader_version)); - re = glfwGetRequiredInstanceExtensions(&re_count); + glfw_re = glfwGetRequiredInstanceExtensions(&glfw_re_count); - printf("Vulkan required instance extensions:"); - if (re) + re_count = glfw_re_count; + re = calloc(glfw_re_count, sizeof(char*)); + + printf("Vulkan window surface required instance extensions:\n"); + if (glfw_re) { - for (i = 0; i < re_count; i++) - printf(" %s", re[i]); - putchar('\n'); + for (i = 0; i < glfw_re_count; i++) + { + printf(" %s\n", glfw_re[i]); + re[i] = glfw_re[i]; + } } else printf(" missing\n"); + vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL); + VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties)); + vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep); + if (list_extensions) - list_vulkan_instance_extensions(); + { + printf("Vulkan instance extensions:\n"); + + for (i = 0; i < ep_count; i++) + printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion); + } + + for (i = 0; i < ep_count; i++) + { + if (strcmp(ep[i].extensionName, "VK_KHR_portability_enumeration") != 0) + continue; + + re_count++; + re = realloc((void*) re, sizeof(char*) * re_count); + re[re_count - 1] = "VK_KHR_portability_enumeration"; + portability_enumeration = GLFW_TRUE; + } + + free(ep); if (list_layers) list_vulkan_instance_layers(); @@ -866,34 +842,27 @@ int main(int argc, char** argv) ici.enabledExtensionCount = re_count; ici.ppEnabledExtensionNames = re; + if (portability_enumeration) + ici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS) { glfwTerminate(); exit(EXIT_FAILURE); } - gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, instance); + free((void*) re); - if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS) - { - vkDestroyInstance(instance, NULL); - glfwTerminate(); - exit(EXIT_FAILURE); - } + gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, instance); + vkEnumeratePhysicalDevices(instance, &pd_count, NULL); pd = calloc(pd_count, sizeof(VkPhysicalDevice)); - - if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS) - { - free(pd); - vkDestroyInstance(instance, NULL); - glfwTerminate(); - exit(EXIT_FAILURE); - } + vkEnumeratePhysicalDevices(instance, &pd_count, pd); for (i = 0; i < pd_count; i++) { VkPhysicalDeviceProperties pdp; + uint32_t qfp_count, ep_count; vkGetPhysicalDeviceProperties(pd[i], &pdp); @@ -903,8 +872,62 @@ int main(int argc, char** argv) VK_VERSION_MAJOR(pdp.apiVersion), VK_VERSION_MINOR(pdp.apiVersion)); + vkGetPhysicalDeviceQueueFamilyProperties(pd[i], &qfp_count, NULL); + + vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, NULL); + VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties)); + vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, ep); + + if (portability_enumeration) + { + int conformant = GLFW_TRUE; + + for (j = 0; j < ep_count; j++) + { + if (strcmp(ep[j].extensionName, "VK_KHR_portability_subset") == 0) + { + conformant = GLFW_FALSE; + break; + } + } + + printf("Vulkan %s %s device: \"%s\" (API version %i.%i)\n", + conformant ? "conformant" : "non-conformant", + get_device_type_name(pdp.deviceType), + pdp.deviceName, + VK_VERSION_MAJOR(pdp.apiVersion), + VK_VERSION_MINOR(pdp.apiVersion)); + } + else + { + printf("Vulkan %s device: \"%s\" (API version %i.%i)\n", + get_device_type_name(pdp.deviceType), + pdp.deviceName, + VK_VERSION_MAJOR(pdp.apiVersion), + VK_VERSION_MINOR(pdp.apiVersion)); + } + + if (glfw_re_count) + { + printf("Vulkan device queue family presentation support:\n"); + for (j = 0; j < qfp_count; j++) + { + printf(" %u: ", j); + if (glfwGetPhysicalDevicePresentationSupport(instance, pd[i], j)) + printf("supported\n"); + else + printf("no\n"); + } + } + if (list_extensions) - list_vulkan_device_extensions(instance, pd[i]); + { + printf("Vulkan device extensions:\n"); + for (j = 0; j < ep_count; j++) + printf(" %s (spec version %u)\n", ep[j].extensionName, ep[j].specVersion); + } + + free(ep); if (list_layers) list_vulkan_device_layers(instance, pd[i]); diff --git a/tests/triangle-vulkan.c b/tests/triangle-vulkan.c index 7f783694..3a4bfb18 100644 --- a/tests/triangle-vulkan.c +++ b/tests/triangle-vulkan.c @@ -65,11 +65,6 @@ exit(1); \ } while (0) -static GLADapiproc glad_vulkan_callback(const char* name, void* user) -{ - return glfwGetInstanceProcAddress((VkInstance) user, name); -} - static const uint32_t fragShaderCode[] = { 0x07230203,0x00010000,0x00080007,0x00000014,0x00000000,0x00020011,0x00000001,0x0006000b, 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, @@ -1251,7 +1246,7 @@ static void demo_prepare_pipeline(struct demo *demo) { VkPipelineDepthStencilStateCreateInfo ds; VkPipelineViewportStateCreateInfo vp; VkPipelineMultisampleStateCreateInfo ms; - VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; + VkDynamicState dynamicStateEnables[2]; VkPipelineDynamicStateCreateInfo dynamicState; VkResult U_ASSERT_ONLY err; @@ -1565,6 +1560,7 @@ static VkBool32 demo_check_layers(uint32_t check_count, const char **check_names static void demo_init_vk(struct demo *demo) { VkResult err; + VkBool32 portability_enumeration = VK_FALSE; uint32_t i = 0; uint32_t required_extension_count = 0; uint32_t instance_extension_count = 0; @@ -1672,6 +1668,13 @@ static void demo_init_vk(struct demo *demo) { } } assert(demo->enabled_extension_count < 64); + if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, + instance_extensions[i].extensionName)) { + demo->extension_names[demo->enabled_extension_count++] = + VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME; + portability_enumeration = VK_TRUE; + } + assert(demo->enabled_extension_count < 64); } free(instance_extensions); @@ -1696,6 +1699,9 @@ static void demo_init_vk(struct demo *demo) { .ppEnabledExtensionNames = (const char *const *)demo->extension_names, }; + if (portability_enumeration) + inst_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + uint32_t gpu_count; err = vkCreateInstance(&inst_info, NULL, &demo->inst); @@ -1715,7 +1721,7 @@ static void demo_init_vk(struct demo *demo) { "vkCreateInstance Failure"); } - gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, demo->inst); + gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, demo->inst); /* Make initial call to query gpu_count, then second call for gpu info*/ err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL); @@ -1738,7 +1744,7 @@ static void demo_init_vk(struct demo *demo) { "vkEnumeratePhysicalDevices Failure"); } - gladLoadVulkanUserPtr(demo->gpu, glad_vulkan_callback, demo->inst); + gladLoadVulkanUserPtr(demo->gpu, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, demo->inst); /* Look for device extensions */ uint32_t device_extension_count = 0; @@ -1966,7 +1972,7 @@ static void demo_init_connection(struct demo *demo) { exit(1); } - gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL); + gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, NULL); } static void demo_init(struct demo *demo, const int argc, const char *argv[]) From 1e49024e76d28b7aa4ad51ec4c37588921dc638c Mon Sep 17 00:00:00 2001 From: Nikita Fediuchin Date: Thu, 26 May 2022 09:27:39 +0300 Subject: [PATCH 106/207] Cocoa: Fix search path for private Vulkan loader According to both Apple and LunarG, a private copy of the macOS Vulkan loader libvulkan.1.dylib should be placed in the Frameworks directory of the bundle and not its main executable directory. This commit updates the dynamic loading path accordingly. Fixes #2113 Closes #2120 (cherry picked from commit 9b7713cf92582cf56c4f79116001c33d1e6e655f) --- src/cocoa_init.m | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 0d323d6b..4a8ebe9c 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -475,11 +475,18 @@ void* _glfwLoadLocalVulkanLoaderNS(void) if (!bundle) return NULL; - CFURLRef url = - CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib")); - if (!url) + CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle); + if (!frameworksUrl) return NULL; + CFURLRef url = CFURLCreateCopyAppendingPathComponent( + kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false); + if (!url) + { + CFRelease(frameworksUrl); + return NULL; + } + char path[PATH_MAX]; void* handle = NULL; @@ -487,6 +494,7 @@ void* _glfwLoadLocalVulkanLoaderNS(void) handle = _glfw_dlopen(path); CFRelease(url); + CFRelease(frameworksUrl); return handle; } From 876a177f6cb359c84078260250243e9403aa3011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 7 Jul 2022 20:01:28 +0200 Subject: [PATCH 107/207] Update changelog and add credit Related to #2113 Related to #2120 (cherry picked from commit dfb26023fca8d7cdd24bf43003109b89acea6869) --- CONTRIBUTORS.md | 1 + README.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index bf94a7fb..c1b432a6 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -59,6 +59,7 @@ video tutorials. - Jan Ekström - Siavash Eliasi - TheExileFox + - Nikita Fediuchin - Felipe Ferreira - Michael Fogleman - Jason Francis diff --git a/README.md b/README.md index 24260eba..92704e4e 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,8 @@ information on what to include when reporting a bug. application (#1886) - [Cocoa] Bugfix: Setting a monitor from macOS fullscreen would abort application (#2110) + - [Cocoa] Bugfix: The Vulkan loader was not loaded from the `Frameworks` bundle + subdirectory (#2113,#2120) - [X11] Bugfix: The OSMesa libray was not unloaded on termination - [X11] Bugfix: A malformed response during selection transfer could cause a segfault - [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108) From 8c63c935ea67ac33b084554f7b6c09d3b9357071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 7 Jul 2022 20:26:37 +0200 Subject: [PATCH 108/207] Documentation work Related to #2113 Related to #2120 (cherry picked from commit 78b19548d9395898ecca6b792a37125520f93f5c) --- docs/vulkan.dox | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/vulkan.dox b/docs/vulkan.dox index 68e3d5fe..f34366f3 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -42,9 +42,9 @@ The @ref GLFW_VULKAN_STATIC CMake option makes GLFW call the Vulkan loader directly instead of dynamically loading it at runtime. Not linking against the Vulkan loader will then be a compile-time error. -@macos Because the Vulkan loader and ICD are not installed globally on macOS, -you need to set up the application bundle according to the LunarG SDK -documentation. This is explained in more detail in the +@macos To make your application be redistributable you will need to set up the +application bundle according to the LunarG SDK documentation. This is explained +in more detail in the [SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html). @@ -177,6 +177,13 @@ check whether any extensions you wish to enable are already in the returned array, as it is an error to specify an extension more than once in the `VkInstanceCreateInfo` struct. +@macos MoltenVK is (as of July 2022) not yet a fully conformant implementation +of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the +`VK_KHR_portability_enumeration` instance extension and set the +`VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` bit in the instance creation +info flags for MoltenVK to show up in the list of physical devices. For more +information, see the Vulkan and MoltenVK documentation. + @section vulkan_present Querying for Vulkan presentation support From 2f3c6aa150f0f696cb63b0a81a19c5468052f15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 7 Jul 2022 22:48:03 +0200 Subject: [PATCH 109/207] Cocoa: Cleanup (cherry picked from commit 2db528d8cddcebc4c96fdac0c6a2d72792578004) --- src/cocoa_init.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 4a8ebe9c..f5273129 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -479,9 +479,9 @@ void* _glfwLoadLocalVulkanLoaderNS(void) if (!frameworksUrl) return NULL; - CFURLRef url = CFURLCreateCopyAppendingPathComponent( + CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent( kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false); - if (!url) + if (!loaderUrl) { CFRelease(frameworksUrl); return NULL; @@ -490,10 +490,10 @@ void* _glfwLoadLocalVulkanLoaderNS(void) char path[PATH_MAX]; void* handle = NULL; - if (CFURLGetFileSystemRepresentation(url, true, (UInt8*) path, sizeof(path) - 1)) + if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1)) handle = _glfw_dlopen(path); - CFRelease(url); + CFRelease(loaderUrl); CFRelease(frameworksUrl); return handle; } From 5324177d9035ec971ccaf3cf2c7a0a38bcead02f Mon Sep 17 00:00:00 2001 From: JoelNiemela Date: Fri, 8 Jul 2022 18:52:54 -0500 Subject: [PATCH 110/207] Fix typos in docs Closes #2150 (cherry picked from commit 060631c9658010945c6b89935e5ac41a5b4a991c) --- docs/CONTRIBUTING.md | 4 ++-- docs/build.dox | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 11ddf09b..050c1bed 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -351,8 +351,8 @@ __Note:__ If you haven't already implemented the feature, check first if there already is an open issue for it and if it's already being developed in an [experimental branch](https://github.com/glfw/glfw/branches/all). -__There is no preferred patch size__. A one character change is just as welcome -as one adding a thousand line one, if that is the appropriate size for the +__There is no preferred patch size__. A one-character change is just as welcome +as one adding a thousand lines, if that is the appropriate size for the feature. In addition to the code, a complete feature includes: diff --git a/docs/build.dox b/docs/build.dox index cb4d0f30..adbbb858 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -57,7 +57,7 @@ macros that disable similar headers below it. Both of these mechanisms depend on the extension loader header defining a known macro. If yours doesn't or you don't know which one your users will pick, the -@ref GLFW_INCLUDE_NONE macro will explicitly to prevent the GLFW header from +@ref GLFW_INCLUDE_NONE macro will explicitly prevent the GLFW header from including the OpenGL header. This will also allow you to include the two headers in any order. From 8d989cdc415e14de3b88df43e16a45b85a1c0b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 11 Jul 2022 20:54:03 +0200 Subject: [PATCH 111/207] Add credit Related to #2150 (cherry picked from commit 8e725338bf210b9cc53f6b874307080e16368802) --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c1b432a6..dae0b2d9 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -151,6 +151,7 @@ video tutorials. - ndogxj - F. Nedelec - Kristian Nielsen + - Joel Niemelä - Kamil Nowakowski - onox - Denis Ovod From 20d11f7f97095264170b2b31cc7449d8cf5c0729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 23:12:31 +0200 Subject: [PATCH 112/207] Wayland: Fix comment typo (cherry picked from commit 5c948a6e6e52eb89e11d1a424bbf578bfc573319) --- src/wl_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wl_window.c b/src/wl_window.c index 6c925a65..f57cdbe3 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2102,7 +2102,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) } else { - // We assume we are not minimized and acto only on maximization + // We assume we are not minimized and act only on maximization if (window->wl.maximized) { From 5937eec9148c0daa02ace0a8a233b6a1980839c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 21 Jun 2022 23:19:40 +0200 Subject: [PATCH 113/207] Wayland: Cleanup (cherry picked from commit 88a39006e3407656a7ca33d23f8045c6aca43008) --- src/wl_window.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index f57cdbe3..53cbd33b 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -647,9 +647,7 @@ static GLFWbool createShellObjects(_GLFWwindow* window) return GLFW_FALSE; } - xdg_surface_add_listener(window->wl.xdg.surface, - &xdgSurfaceListener, - window); + xdg_surface_add_listener(window->wl.xdg.surface, &xdgSurfaceListener, window); window->wl.xdg.toplevel = xdg_surface_get_toplevel(window->wl.xdg.surface); if (!window->wl.xdg.toplevel) @@ -659,17 +657,14 @@ static GLFWbool createShellObjects(_GLFWwindow* window) return GLFW_FALSE; } - xdg_toplevel_add_listener(window->wl.xdg.toplevel, - &xdgToplevelListener, - window); + xdg_toplevel_add_listener(window->wl.xdg.toplevel, &xdgToplevelListener, window); if (window->wl.title) xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title); if (window->monitor) { - xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, - window->monitor->wl.output); + xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, window->monitor->wl.output); setIdleInhibitor(window, GLFW_TRUE); } else From 935d7098b64906084922316c621255be46e7396d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 24 Jun 2022 19:29:29 +0200 Subject: [PATCH 114/207] Documentation work (cherry picked from commit 2796e61af7b4d0c5f2380c3e1803e21ac1089029) --- include/GLFW/glfw3.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index e178eb5e..5dcfa869 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3218,8 +3218,9 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity); * previously restored. If the window is already iconified, this function does * nothing. * - * If the specified window is a full screen window, the original monitor - * resolution is restored until the window is restored. + * If the specified window is a full screen window, GLFW restores the original + * video mode of the monitor. The window's desired video mode is set again + * when the window is restored. * * @param[in] window The window to iconify. * @@ -3245,8 +3246,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); * (minimized) or maximized. If the window is already restored, this function * does nothing. * - * If the specified window is a full screen window, the resolution chosen for - * the window is restored on the selected monitor. + * If the specified window is an iconified full screen window, its desired + * video mode is set again for its monitor when the window is restored. * * @param[in] window The window to restore. * @@ -3514,6 +3515,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int * errors. However, this function should not fail as long as it is passed * valid arguments and the library has been [initialized](@ref intro_init). * + * @remark @wayland The Wayland protocol provides no way to check whether a + * window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs From 0f341802e1cb164e2fc61ee274d83266e40cff64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 28 Jun 2022 22:26:39 +0200 Subject: [PATCH 115/207] Win32: Fix right Shift scancode when using CJK IME Fixes #2050 (cherry picked from commit 6dd526fb1a9c16c3170a0ebd2b5c73e4a2719245) --- CONTRIBUTORS.md | 1 + README.md | 1 + src/win32_window.c | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index dae0b2d9..0c7141b8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -18,6 +18,7 @@ video tutorials. - Nevyn Bengtsson - Niklas Bergström - Denis Bernard + - BiBi - Doug Binks - blanco - Waris Boonyasiriwat diff --git a/README.md b/README.md index 92704e4e..4abb16c7 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ information on what to include when reporting a bug. match event scancode (#1993) - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) - [Win32] Bugfix: The OSMesa library was not unloaded on termination + - [Win32] Bugfix: Right shift emitted `GLFW_KEY_UNKNOWN` when using a CJK IME (#2050) - [Cocoa] Disabled macOS fullscreen when `GLFW_RESIZABLE` is false - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination diff --git a/src/win32_window.c b/src/win32_window.c index 7a32bf8c..073ceee9 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -756,6 +756,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (scancode == 0x146) scancode = 0x45; + // HACK: CJK IME sets the extended bit for right Shift + if (scancode == 0x136) + scancode = 0x36; + key = _glfw.win32.keycodes[scancode]; // The Ctrl keys require special handling From 7482de6071d21db77a7236155da44c172a7f6c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 28 Jun 2022 23:19:30 +0200 Subject: [PATCH 116/207] Documentation work Fixes #1596 (cherry picked from commit aa80d24d01d150e26d664ff2d5da22e95db6bb82) --- docs/input.dox | 18 +++++++++++++++--- include/GLFW/glfw3.h | 3 +-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/input.dox b/docs/input.dox index 7514e957..1d61e5bc 100644 --- a/docs/input.dox +++ b/docs/input.dox @@ -123,9 +123,21 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod } @endcode -The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key -will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example -_E-mail_ and _Play_ keys. +The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. Events with +`GLFW_PRESS` and `GLFW_RELEASE` actions are emitted for every key press. Most +keys will also emit events with `GLFW_REPEAT` actions while a key is held down. + +Key events with `GLFW_REPEAT` actions are intended for text input. They are +emitted at the rate set in the user's keyboard settings. At most one key is +repeated even if several keys are held down. `GLFW_REPEAT` actions should not +be relied on to know which keys are being held down or to drive animation. +Instead you should either save the state of relevant keys based on `GLFW_PRESS` +and `GLFW_RELEASE` actions, or call @ref glfwGetKey, which provides basic cached +key state. + +The key will be one of the existing [key tokens](@ref keys), or +`GLFW_KEY_UNKNOWN` if GLFW lacks a token for it, for example _E-mail_ and _Play_ +keys. The scancode is unique for every key, regardless of whether it has a key token. Scancodes are platform-specific but consistent over time, so keys will have diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 5dcfa869..31b201ae 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -4278,8 +4278,7 @@ GLFWAPI int glfwGetKeyScancode(int key); * * This function returns the last state reported for the specified key to the * specified window. The returned state is one of `GLFW_PRESS` or - * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to - * the key callback. + * `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback. * * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns * `GLFW_PRESS` the first time you call it for a key that was pressed, even if From fe2ac5027b617234670d400f800c4b6f1e5f24bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 22 Jul 2022 16:04:36 +0200 Subject: [PATCH 117/207] Start 3.3.9 --- CMakeLists.txt | 2 +- README.md | 69 +------------------------------------------- include/GLFW/glfw3.h | 2 +- 3 files changed, 3 insertions(+), 70 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75069161..65c98ed0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR) -project(GLFW VERSION 3.3.8 LANGUAGES C) +project(GLFW VERSION 3.3.9 LANGUAGES C) set(CMAKE_LEGACY_CYGWIN_WIN32 OFF) diff --git a/README.md b/README.md index 4abb16c7..7c59dea9 100644 --- a/README.md +++ b/README.md @@ -123,74 +123,7 @@ information on what to include when reporting a bug. ## Changelog - - Added `GLFW_NATIVE_INCLUDE_NONE` for disabling inclusion of native headers (#1348) - - Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization - - Bugfix: `glfwSetGammaRamp` could emit `GLFW_INVALID_VALUE` before initialization - - Bugfix: `glfwGetJoystickUserPointer` returned `NULL` during disconnection (#2092) - - [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different - scancode than `PrtSc` (#1993) - - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not - match event scancode (#1993) - - [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395) - - [Win32] Bugfix: The OSMesa library was not unloaded on termination - - [Win32] Bugfix: Right shift emitted `GLFW_KEY_UNKNOWN` when using a CJK IME (#2050) - - [Cocoa] Disabled macOS fullscreen when `GLFW_RESIZABLE` is false - - [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791) - - [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination - - [Cocoa] Bugfix: `GLFW_MAXIMIZED` was always true when `GLFW_RESIZABLE` was false - - [Cocoa] Bugfix: Changing `GLFW_DECORATED` in macOS fullscreen would abort - application (#1886) - - [Cocoa] Bugfix: Setting a monitor from macOS fullscreen would abort - application (#2110) - - [Cocoa] Bugfix: The Vulkan loader was not loaded from the `Frameworks` bundle - subdirectory (#2113,#2120) - - [X11] Bugfix: The OSMesa libray was not unloaded on termination - - [X11] Bugfix: A malformed response during selection transfer could cause a segfault - - [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108) - - [Wayland] Added support for file path drop events (#2040) - - [Wayland] Added support for more human-readable monitor names where available - - [Wayland] Removed support for the deprecated wl\_shell protocol - - [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of - `glfwGetClipboardString` - - [Wayland] Bugfix: Data source creation error would cause double free at termination - - [Wayland] Bugfix: Partial writes of clipboard string would cause beginning to repeat - - [Wayland] Bugfix: Some errors would cause clipboard string transfer to hang - - [Wayland] Bugfix: Drag and drop data was misinterpreted as clipboard string - - [Wayland] Bugfix: MIME type matching was not performed for clipboard string - - [Wayland] Bugfix: The OSMesa library was not unloaded on termination - - [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_PLATFORM_ERROR` - - [Wayland] Bugfix: Lock key modifier bits were only set when lock keys were pressed - - [Wayland] Bugfix: A window leaving full screen mode would be iconified (#1995) - - [Wayland] Bugfix: A window leaving full screen mode ignored its desired size - - [Wayland] Bugfix: `glfwSetWindowMonitor` did not update windowed mode size - - [Wayland] Bugfix: `glfwRestoreWindow` would make a full screen window windowed - - [Wayland] Bugfix: A window maximized or restored by the user would enter an - inconsistent state - - [Wayland] Bugfix: Window maximization events were not emitted - - [Wayland] Bugfix: `glfwRestoreWindow` assumed it was always in windowed mode - - [Wayland] Bugfix: `glfwSetWindowSize` would resize a full screen window - - [Wayland] Bugfix: A window content scale event would be emitted every time - the window resized - - [Wayland] Bugfix: If `glfwInit` failed it would close stdin - - [Wayland] Bugfix: Manual resizing with fallback decorations behaved erratically - (#1991,#2115,#2127) - - [Wayland] Bugfix: Size limits included frame size for fallback decorations - - [Wayland] Bugfix: Updating `GLFW_DECORATED` had no effect on server-side - decorations - - [Wayland] Bugfix: A monitor would be reported as connected again if its scale - changed - - [Wayland] Bugfix: `glfwTerminate` would segfault if any monitor had changed - scale - - [Wayland] Bugfix: Window content scale events were not emitted when monitor - scale changed - - [Wayland] Bugfix: `glfwSetWindowAspectRatio` reported an error instead of - applying the specified ratio - - [Wayland] Bugfix: `GLFW_MAXIMIZED` window hint had no effect - - [Wayland] Bugfix: `glfwRestoreWindow` had no effect before first show - - [Wayland] Bugfix: Hiding and then showing a window caused program abort on - wlroots compositors (#1268) - - [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG - decorations +There is nothing here yet. ## Contact diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 31b201ae..726d5e12 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -298,7 +298,7 @@ extern "C" { * release is made that does not contain any API changes. * @ingroup init */ -#define GLFW_VERSION_REVISION 8 +#define GLFW_VERSION_REVISION 9 /*! @} */ /*! @brief One. From ccbbada181705b46b0c7d1c5200291101a9674f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 12:53:25 +0200 Subject: [PATCH 118/207] Wayland: Fix non-standard struct initialization (cherry picked from commit d77aaa770f97cd22b16cb4c8b9a3b9aaf33da245) --- src/wl_window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 53cbd33b..3b72c6aa 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -786,7 +786,7 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, static void setCursorImage(_GLFWwindow* window, _GLFWcursorWayland* cursorWayland) { - struct itimerspec timer = {}; + struct itimerspec timer = {0}; struct wl_cursor* wlCursor = cursorWayland->cursor; struct wl_cursor_image* image; struct wl_buffer* buffer; @@ -1442,7 +1442,7 @@ static void keyboardHandleLeave(void* userData, if (!window) return; - struct itimerspec timer = {}; + struct itimerspec timer = {0}; timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); _glfw.wl.serial = serial; @@ -1516,7 +1516,7 @@ static void keyboardHandleKey(void* userData, _glfw.wl.serial = serial; _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); - struct itimerspec timer = {}; + struct itimerspec timer = {0}; if (action == GLFW_PRESS) { From 41bb7b861706082e4790c0fabd3d1bbbe2382ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 14:26:25 +0200 Subject: [PATCH 119/207] Wayland: Do not emit events for destroyed window During platform window destruction, all of its callbacks have already been removed, so emitting events for it does nothing. (cherry picked from commit 4df24735ef6bb644830ecdacf89dd04cd8547b86) --- src/wl_window.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 3b72c6aa..87967cc7 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1907,15 +1907,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, void _glfwPlatformDestroyWindow(_GLFWwindow* window) { if (window == _glfw.wl.pointerFocus) - { _glfw.wl.pointerFocus = NULL; - _glfwInputCursorEnter(window, GLFW_FALSE); - } + if (window == _glfw.wl.keyboardFocus) - { _glfw.wl.keyboardFocus = NULL; - _glfwInputWindowFocus(window, GLFW_FALSE); - } if (window->wl.idleInhibitor) zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor); From ca5ccd819d10f977df92944fc0792bb0f71e3fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 20:13:01 +0200 Subject: [PATCH 120/207] Wayland: Update state before emitting events (cherry picked from commit e47cb7c1e20f20b8f7d091e477be3fe41201836e) --- src/wl_window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 87967cc7..dab453c2 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1087,8 +1087,8 @@ static void pointerHandleLeave(void* userData, _glfw.wl.serial = serial; _glfw.wl.pointerFocus = NULL; - _glfwInputCursorEnter(window, GLFW_FALSE); _glfw.wl.cursorPreviousName = NULL; + _glfwInputCursorEnter(window, GLFW_FALSE); } static void setCursor(_GLFWwindow* window, const char* name) @@ -1159,8 +1159,8 @@ static void pointerHandleMotion(void* userData, switch (window->wl.decorations.focus) { case mainWindow: - _glfwInputCursorPos(window, x, y); _glfw.wl.cursorPreviousName = NULL; + _glfwInputCursorPos(window, x, y); return; case topDecoration: if (y < GLFW_BORDER_SIZE) From a8d543f1f8a88389855c2e790fe08ef1802d3723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 20:33:30 +0200 Subject: [PATCH 121/207] Wayland: Make text input logic static Since the seat listener was moved into wl_window.c there is no reason for text input to have external linkage. (cherry picked from commit a1a73ee86257a62818b010cd3de55e10d7ce7105) --- src/wl_platform.h | 1 - src/wl_window.c | 101 +++++++++++++++++++++++----------------------- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 2146e2ad..4e8418b1 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -366,7 +366,6 @@ typedef struct _GLFWcursorWayland void _glfwAddOutputWayland(uint32_t name, uint32_t version); void _glfwUpdateContentScaleWayland(_GLFWwindow* window); -GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode); void _glfwAddSeatListenerWayland(struct wl_seat* seat); void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device); diff --git a/src/wl_window.c b/src/wl_window.c index dab453c2..7447d865 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -864,6 +864,54 @@ static GLFWbool flushDisplay(void) return GLFW_TRUE; } +static int translateKey(uint32_t scancode) +{ + if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) + return _glfw.wl.keycodes[scancode]; + + return GLFW_KEY_UNKNOWN; +} + +static xkb_keysym_t composeSymbol(xkb_keysym_t sym) +{ + if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState) + return sym; + if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym) + != XKB_COMPOSE_FEED_ACCEPTED) + return sym; + switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState)) + { + case XKB_COMPOSE_COMPOSED: + return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState); + case XKB_COMPOSE_COMPOSING: + case XKB_COMPOSE_CANCELLED: + return XKB_KEY_NoSymbol; + case XKB_COMPOSE_NOTHING: + default: + return sym; + } +} + +GLFWbool inputText(_GLFWwindow* window, uint32_t scancode) +{ + const xkb_keysym_t* keysyms; + const xkb_keycode_t keycode = scancode + 8; + + if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) + { + const xkb_keysym_t keysym = composeSymbol(keysyms[0]); + const uint32_t codepoint = _glfwKeySym2Unicode(keysym); + if (codepoint != GLFW_INVALID_CODEPOINT) + { + const int mods = _glfw.wl.xkb.modifiers; + const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); + _glfwInputChar(window, codepoint, mods, plain); + } + } + + return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); +} + static void handleEvents(double* timeout) { GLFWbool event = GLFW_FALSE; @@ -923,8 +971,7 @@ static void handleEvents(double* timeout) _glfw.wl.keyboardLastScancode, GLFW_PRESS, _glfw.wl.xkb.modifiers); - _glfwInputTextWayland(_glfw.wl.keyboardFocus, - _glfw.wl.keyboardLastScancode); + inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastScancode); } event = GLFW_TRUE; @@ -1450,54 +1497,6 @@ static void keyboardHandleLeave(void* userData, _glfwInputWindowFocus(window, GLFW_FALSE); } -static int translateKey(uint32_t scancode) -{ - if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) - return _glfw.wl.keycodes[scancode]; - - return GLFW_KEY_UNKNOWN; -} - -static xkb_keysym_t composeSymbol(xkb_keysym_t sym) -{ - if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState) - return sym; - if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym) - != XKB_COMPOSE_FEED_ACCEPTED) - return sym; - switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState)) - { - case XKB_COMPOSE_COMPOSED: - return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState); - case XKB_COMPOSE_COMPOSING: - case XKB_COMPOSE_CANCELLED: - return XKB_KEY_NoSymbol; - case XKB_COMPOSE_NOTHING: - default: - return sym; - } -} - -GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode) -{ - const xkb_keysym_t* keysyms; - const xkb_keycode_t keycode = scancode + 8; - - if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) - { - const xkb_keysym_t keysym = composeSymbol(keysyms[0]); - const uint32_t codepoint = _glfwKeySym2Unicode(keysym); - if (codepoint != GLFW_INVALID_CODEPOINT) - { - const int mods = _glfw.wl.xkb.modifiers; - const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); - _glfwInputChar(window, codepoint, mods, plain); - } - } - - return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); -} - static void keyboardHandleKey(void* userData, struct wl_keyboard* keyboard, uint32_t serial, @@ -1520,7 +1519,7 @@ static void keyboardHandleKey(void* userData, if (action == GLFW_PRESS) { - const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode); + const GLFWbool shouldRepeat = inputText(window, scancode); if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) { From 1acd67eeb6497adff839c6b20e44d3f133d9b64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 21:32:30 +0200 Subject: [PATCH 122/207] Wayland: Clean up key repeat logic (cherry picked from commit 9180923ea08d70d15a287b49a06ffbecd781a060) --- src/wl_init.c | 11 +++++++---- src/wl_platform.h | 10 +++++----- src/wl_window.c | 40 ++++++++++++++++++++-------------------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index e041d261..17714d3a 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -314,7 +314,7 @@ int _glfwPlatformInit(void) int cursorSize; // These must be set before any failure checks - _glfw.wl.timerfd = -1; + _glfw.wl.keyRepeatTimerfd = -1; _glfw.wl.cursorTimerfd = -1; _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0"); @@ -435,7 +435,10 @@ int _glfwPlatformInit(void) #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) - _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + { + _glfw.wl.keyRepeatTimerfd = + timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + } #endif if (!_glfw.wl.wmBase) @@ -571,8 +574,8 @@ void _glfwPlatformTerminate(void) wl_display_disconnect(_glfw.wl.display); } - if (_glfw.wl.timerfd >= 0) - close(_glfw.wl.timerfd); + if (_glfw.wl.keyRepeatTimerfd >= 0) + close(_glfw.wl.keyRepeatTimerfd); if (_glfw.wl.cursorTimerfd >= 0) close(_glfw.wl.cursorTimerfd); diff --git a/src/wl_platform.h b/src/wl_platform.h index 4e8418b1..dc74c2a5 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -270,12 +270,12 @@ typedef struct _GLFWlibraryWayland uint32_t serial; uint32_t pointerEnterSerial; - int32_t keyboardRepeatRate; - int32_t keyboardRepeatDelay; - int keyboardLastKey; - int keyboardLastScancode; + int keyRepeatTimerfd; + int32_t keyRepeatRate; + int32_t keyRepeatDelay; + int keyRepeatScancode; + char* clipboardString; - int timerfd; short int keycodes[256]; short int scancodes[GLFW_KEY_LAST + 1]; char keynames[GLFW_KEY_LAST + 1][5]; diff --git a/src/wl_window.c b/src/wl_window.c index 7447d865..d6f2dbbe 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -892,7 +892,7 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym) } } -GLFWbool inputText(_GLFWwindow* window, uint32_t scancode) +void inputText(_GLFWwindow* window, uint32_t scancode) { const xkb_keysym_t* keysyms; const xkb_keycode_t keycode = scancode + 8; @@ -908,8 +908,6 @@ GLFWbool inputText(_GLFWwindow* window, uint32_t scancode) _glfwInputChar(window, codepoint, mods, plain); } } - - return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); } static void handleEvents(double* timeout) @@ -918,7 +916,7 @@ static void handleEvents(double* timeout) struct pollfd fds[] = { { wl_display_get_fd(_glfw.wl.display), POLLIN }, - { _glfw.wl.timerfd, POLLIN }, + { _glfw.wl.keyRepeatTimerfd, POLLIN }, { _glfw.wl.cursorTimerfd, POLLIN }, }; @@ -962,16 +960,16 @@ static void handleEvents(double* timeout) { uint64_t repeats; - if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8) + if (read(_glfw.wl.keyRepeatTimerfd, &repeats, sizeof(repeats)) == 8) { for (uint64_t i = 0; i < repeats; i++) { _glfwInputKey(_glfw.wl.keyboardFocus, - _glfw.wl.keyboardLastKey, - _glfw.wl.keyboardLastScancode, + translateKey(_glfw.wl.keyRepeatScancode), + _glfw.wl.keyRepeatScancode, GLFW_PRESS, _glfw.wl.xkb.modifiers); - inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastScancode); + inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyRepeatScancode); } event = GLFW_TRUE; @@ -1490,7 +1488,7 @@ static void keyboardHandleLeave(void* userData, return; struct itimerspec timer = {0}; - timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); + timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL); _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = NULL; @@ -1519,23 +1517,25 @@ static void keyboardHandleKey(void* userData, if (action == GLFW_PRESS) { - const GLFWbool shouldRepeat = inputText(window, scancode); + inputText(window, scancode); - if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) + const xkb_keycode_t keycode = scancode + 8; + + if (xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode) && + _glfw.wl.keyRepeatRate > 0) { - _glfw.wl.keyboardLastKey = key; - _glfw.wl.keyboardLastScancode = scancode; - if (_glfw.wl.keyboardRepeatRate > 1) - timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate; + _glfw.wl.keyRepeatScancode = scancode; + if (_glfw.wl.keyRepeatRate > 1) + timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyRepeatRate; else timer.it_interval.tv_sec = 1; - timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000; - timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000; + timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000; + timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000; } } - timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); + timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL); } static void keyboardHandleModifiers(void* userData, @@ -1595,8 +1595,8 @@ static void keyboardHandleRepeatInfo(void* userData, if (keyboard != _glfw.wl.keyboard) return; - _glfw.wl.keyboardRepeatRate = rate; - _glfw.wl.keyboardRepeatDelay = delay; + _glfw.wl.keyRepeatRate = rate; + _glfw.wl.keyRepeatDelay = delay; } #endif From dea99146927ccd8272f470c1f0737dda9db4e9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 12:54:24 +0200 Subject: [PATCH 123/207] Wayland: Fix reappearing key repeat If the key or character callback performs actions that indirectly updates the key repeat timer, those changes would be undone once the key callback returned. This fixes the order of operations so that key repeat is fully set up before the key related events are emitted. (cherry picked from commit 40b5a8a37cb4770ff5d307beb660fadc64be1265) --- src/wl_window.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index d6f2dbbe..db366c49 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1511,14 +1511,11 @@ static void keyboardHandleKey(void* userData, state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; _glfw.wl.serial = serial; - _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); struct itimerspec timer = {0}; if (action == GLFW_PRESS) { - inputText(window, scancode); - const xkb_keycode_t keycode = scancode + 8; if (xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode) && @@ -1536,6 +1533,11 @@ static void keyboardHandleKey(void* userData, } timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL); + + _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); + + if (action == GLFW_PRESS) + inputText(window, scancode); } static void keyboardHandleModifiers(void* userData, From 4affd2207ca9b98270581a0e4658b0eb5320da7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 13 Jul 2022 21:46:14 +0200 Subject: [PATCH 124/207] Make events test window appear on Wayland (cherry picked from commit c50d53160fa9b579dda0d0a4f9a7c2512940df8e) --- tests/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/events.c b/tests/events.c index f29dfbb0..9f698f26 100644 --- a/tests/events.c +++ b/tests/events.c @@ -621,7 +621,7 @@ int main(int argc, char** argv) glfwMakeContextCurrent(slots[i].window); gladLoadGL(glfwGetProcAddress); - glfwSwapInterval(1); + glfwSwapBuffers(slots[i].window); } printf("Main loop starting\n"); From 388d0cf7c2ffa79ff5b966feafaa26c594c60e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Hempel?= Date: Sun, 6 Feb 2022 13:32:10 +0100 Subject: [PATCH 125/207] Linux: Fix joystick without buttons being ignored Joysticks in Linux without buttons were ignored by device enumeration. Remove the mandatory button attribute from detection. Fixes #2042 Closes #2043 (cherry picked from commit c424fe55892e7ac7c849989b9ab5e143825fdd4e) --- src/linux_joystick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linux_joystick.c b/src/linux_joystick.c index 0894a726..5d8c8d04 100644 --- a/src/linux_joystick.c +++ b/src/linux_joystick.c @@ -157,7 +157,7 @@ static GLFWbool openJoystickDevice(const char* path) } // Ensure this device supports the events expected of a joystick - if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits)) + if (!isBitSet(EV_ABS, evBits)) { close(linjs.fd); return GLFW_FALSE; From 2ca3bda1ccd69f9e3e97d4678f211cb1fe9f148e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 15 Jul 2022 15:54:35 +0200 Subject: [PATCH 126/207] Update changelog and add credit Related to #2042 Related to #2043 (cherry picked from commit 91a96ed4343944add92bc02619319bb9ae9379fd) --- CONTRIBUTORS.md | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0c7141b8..6884d5ba 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -81,6 +81,7 @@ video tutorials. - Jonathan Hale - hdf89shfdfs - Sylvain Hellegouarch + - Björn Hempel - Matthew Henry - heromyth - Lucas Hinderberger diff --git a/README.md b/README.md index 7c59dea9..1fe2593d 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ information on what to include when reporting a bug. ## Changelog -There is nothing here yet. + - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) ## Contact From b08271d315e3769385731db74203213720dcbaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 15 Jul 2022 12:50:18 +0200 Subject: [PATCH 127/207] Wayland: Clean up shared memory buffer creation (cherry picked from commit 7cc8b053b81ecbb32c013d47b8554c0ed116c820) --- src/wl_window.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index db366c49..9f39fc61 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -136,14 +136,10 @@ static int createAnonymousFile(off_t size) static struct wl_buffer* createShmBuffer(const GLFWimage* image) { - struct wl_shm_pool* pool; - struct wl_buffer* buffer; - int stride = image->width * 4; - int length = image->width * image->height * 4; - void* data; - int fd, i; + const int stride = image->width * 4; + const int length = image->width * image->height * 4; - fd = createAnonymousFile(length); + const int fd = createAnonymousFile(length); if (fd < 0) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -152,7 +148,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) return NULL; } - data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + void* data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -161,12 +157,13 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) return NULL; } - pool = wl_shm_create_pool(_glfw.wl.shm, fd, length); + struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, length); close(fd); + unsigned char* source = (unsigned char*) image->pixels; unsigned char* target = data; - for (i = 0; i < image->width * image->height; i++, source += 4) + for (int i = 0; i < image->width * image->height; i++, source += 4) { unsigned int alpha = source[3]; @@ -176,7 +173,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) *target++ = (unsigned char) alpha; } - buffer = + struct wl_buffer* buffer = wl_shm_pool_create_buffer(pool, 0, image->width, image->height, From ad206bdaeebf7ee0f08fcb210c038bd723ec64eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 15 Jul 2022 13:12:58 +0200 Subject: [PATCH 128/207] Wayland: Fix crash if mouse connected after init The cursor theme was only loaded if the chosen seat had a mouse (wl_pointer) during initialization. If a mouse was connected only after glfwInit, there would be no cursor theme but the rest of the cursor related code assumed one had already been loaded. This also moves the details of cursor theme loading out into a separate function to declutter platform init. Because the original cursor theme loading code checked whether we got a wl_shm, and because the rest of the code just assumes we have a wl_shm, initialization will now fail if there isn't one. Fixes #1450 (cherry picked from commit 71be34a6c30825aef502b652c86cc31fdcbb5457) --- CONTRIBUTORS.md | 1 + README.md | 1 + src/wl_init.c | 73 ++++++++++++++++++++++++++++--------------------- 3 files changed, 44 insertions(+), 31 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 6884d5ba..8dbedda0 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -183,6 +183,7 @@ video tutorials. - Philip Rideout - Eddie Ringle - Max Risuhin + - Joe Roback - Jorge Rodriguez - Luca Rood - Ed Ropple diff --git a/README.md b/README.md index 1fe2593d..f40a6e59 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ information on what to include when reporting a bug. ## Changelog + - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) diff --git a/src/wl_init.c b/src/wl_init.c index 17714d3a..d999692d 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -300,12 +300,7 @@ static void createKeyTables(void) } } - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformInit(void) +static GLFWbool loadCursorTheme(void) { const char* cursorTheme; const char* cursorSizeStr; @@ -313,6 +308,40 @@ int _glfwPlatformInit(void) long cursorSizeLong; int cursorSize; + cursorTheme = getenv("XCURSOR_THEME"); + cursorSizeStr = getenv("XCURSOR_SIZE"); + cursorSize = 32; + if (cursorSizeStr) + { + errno = 0; + cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10); + if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX) + cursorSize = (int)cursorSizeLong; + } + _glfw.wl.cursorTheme = + wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm); + if (!_glfw.wl.cursorTheme) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load default cursor theme"); + return GLFW_FALSE; + } + // If this happens to be NULL, we just fallback to the scale=1 version. + _glfw.wl.cursorThemeHiDPI = + wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm); + _glfw.wl.cursorSurface = + wl_compositor_create_surface(_glfw.wl.compositor); + _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + return GLFW_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ // These must be set before any failure checks _glfw.wl.keyRepeatTimerfd = -1; _glfw.wl.cursorTimerfd = -1; @@ -448,34 +477,16 @@ int _glfwPlatformInit(void) return GLFW_FALSE; } - if (_glfw.wl.pointer && _glfw.wl.shm) + if (!_glfw.wl.shm) { - cursorTheme = getenv("XCURSOR_THEME"); - cursorSizeStr = getenv("XCURSOR_SIZE"); - cursorSize = 32; - if (cursorSizeStr) - { - errno = 0; - cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10); - if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX) - cursorSize = (int)cursorSizeLong; - } - _glfw.wl.cursorTheme = - wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm); - if (!_glfw.wl.cursorTheme) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to load default cursor theme"); - return GLFW_FALSE; - } - // If this happens to be NULL, we just fallback to the scale=1 version. - _glfw.wl.cursorThemeHiDPI = - wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm); - _glfw.wl.cursorSurface = - wl_compositor_create_surface(_glfw.wl.compositor); - _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to find wl_shm in your compositor"); + return GLFW_FALSE; } + if (!loadCursorTheme()) + return GLFW_FALSE; + if (_glfw.wl.seat && _glfw.wl.dataDeviceManager) { _glfw.wl.dataDevice = From 74090d30cdc397528aa4c737dfab9a48be8398f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 15 Jul 2022 13:30:14 +0200 Subject: [PATCH 129/207] Wayland: Clean up cursor theme loading (cherry picked from commit 6987294df91d9b9be03a796174863cb9d1a06d62) --- src/wl_init.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index d999692d..f8f4f752 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -302,35 +302,32 @@ static void createKeyTables(void) static GLFWbool loadCursorTheme(void) { - const char* cursorTheme; - const char* cursorSizeStr; - char* cursorSizeEnd; - long cursorSizeLong; - int cursorSize; + int cursorSize = 32; - cursorTheme = getenv("XCURSOR_THEME"); - cursorSizeStr = getenv("XCURSOR_SIZE"); - cursorSize = 32; - if (cursorSizeStr) + const char* sizeString = getenv("XCURSOR_SIZE"); + if (sizeString) { errno = 0; - cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10); - if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX) - cursorSize = (int)cursorSizeLong; + const long cursorSizeLong = strtol(sizeString, NULL, 10); + if (errno == 0 && cursorSizeLong > 0 && cursorSizeLong < INT_MAX) + cursorSize = (int) cursorSizeLong; } - _glfw.wl.cursorTheme = - wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm); + + const char* themeName = getenv("XCURSOR_THEME"); + + _glfw.wl.cursorTheme = wl_cursor_theme_load(themeName, cursorSize, _glfw.wl.shm); if (!_glfw.wl.cursorTheme) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to load default cursor theme"); return GLFW_FALSE; } + // If this happens to be NULL, we just fallback to the scale=1 version. _glfw.wl.cursorThemeHiDPI = - wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm); - _glfw.wl.cursorSurface = - wl_compositor_create_surface(_glfw.wl.compositor); + wl_cursor_theme_load(themeName, cursorSize * 2, _glfw.wl.shm); + + _glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor); _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); return GLFW_TRUE; } From 78edf2516e01e90bea95f984fc440a251213999a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 14 Jul 2022 11:52:55 +0200 Subject: [PATCH 130/207] Wayland: Static function more static when static (cherry picked from commit 26b85215c07a32f860326bf02ef68f31c5e30837) --- src/wl_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wl_window.c b/src/wl_window.c index 9f39fc61..45da2620 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -889,7 +889,7 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym) } } -void inputText(_GLFWwindow* window, uint32_t scancode) +static void inputText(_GLFWwindow* window, uint32_t scancode) { const xkb_keysym_t* keysyms; const xkb_keycode_t keycode = scancode + 8; From 5189d52ae3d4b846829d276657e0d822f2d7ff04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 24 Jul 2022 22:27:22 +0200 Subject: [PATCH 131/207] Wayland: Clean up pointer locking Shorten names and allow C99 declarations. Replace helper function with the NULL check it was hiding. Separate cursor hiding from pointer locking. (cherry picked from commit e85b645b8adbbc565c9e9fccbf474705f453d1c1) --- src/wl_platform.h | 6 ++-- src/wl_window.c | 88 +++++++++++++++++++---------------------------- 2 files changed, 37 insertions(+), 57 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index dc74c2a5..e5749660 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -214,10 +214,8 @@ typedef struct _GLFWwindowWayland int monitorsCount; int monitorsSize; - struct { - struct zwp_relative_pointer_v1* relativePointer; - struct zwp_locked_pointer_v1* lockedPointer; - } pointerLock; + struct zwp_relative_pointer_v1* relativePointer; + struct zwp_locked_pointer_v1* lockedPointer; struct zwp_idle_inhibitor_v1* idleInhibitor; diff --git a/src/wl_window.c b/src/wl_window.c index 45da2620..a7b48441 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2286,15 +2286,14 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) *ypos = window->wl.cursorPosY; } -static GLFWbool isPointerLocked(_GLFWwindow* window); - void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) { - if (isPointerLocked(window)) + if (window->wl.lockedPointer) { zwp_locked_pointer_v1_set_cursor_position_hint( - window->wl.pointerLock.lockedPointer, - wl_fixed_from_double(x), wl_fixed_from_double(y)); + window->wl.lockedPointer, + wl_fixed_from_double(x), + wl_fixed_from_double(y)); } } @@ -2457,20 +2456,13 @@ static void lockedPointerHandleLocked(void* userData, static void unlockPointer(_GLFWwindow* window) { - struct zwp_relative_pointer_v1* relativePointer = - window->wl.pointerLock.relativePointer; - struct zwp_locked_pointer_v1* lockedPointer = - window->wl.pointerLock.lockedPointer; + zwp_relative_pointer_v1_destroy(window->wl.relativePointer); + window->wl.relativePointer = NULL; - zwp_relative_pointer_v1_destroy(relativePointer); - zwp_locked_pointer_v1_destroy(lockedPointer); - - window->wl.pointerLock.relativePointer = NULL; - window->wl.pointerLock.lockedPointer = NULL; + zwp_locked_pointer_v1_destroy(window->wl.lockedPointer); + window->wl.lockedPointer = NULL; } -static void lockPointer(_GLFWwindow* window); - static void lockedPointerHandleUnlocked(void* userData, struct zwp_locked_pointer_v1* lockedPointer) { @@ -2484,9 +2476,6 @@ static const struct zwp_locked_pointer_v1_listener lockedPointerListener = static void lockPointer(_GLFWwindow* window) { - struct zwp_relative_pointer_v1* relativePointer; - struct zwp_locked_pointer_v1* lockedPointer; - if (!_glfw.wl.relativePointerManager) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -2494,42 +2483,28 @@ static void lockPointer(_GLFWwindow* window) return; } - relativePointer = + window->wl.relativePointer = zwp_relative_pointer_manager_v1_get_relative_pointer( _glfw.wl.relativePointerManager, _glfw.wl.pointer); - zwp_relative_pointer_v1_add_listener(relativePointer, + zwp_relative_pointer_v1_add_listener(window->wl.relativePointer, &relativePointerListener, window); - lockedPointer = + window->wl.lockedPointer = zwp_pointer_constraints_v1_lock_pointer( _glfw.wl.pointerConstraints, window->wl.surface, _glfw.wl.pointer, NULL, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); - zwp_locked_pointer_v1_add_listener(lockedPointer, + zwp_locked_pointer_v1_add_listener(window->wl.lockedPointer, &lockedPointerListener, window); - - window->wl.pointerLock.relativePointer = relativePointer; - window->wl.pointerLock.lockedPointer = lockedPointer; - - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, - NULL, 0, 0); -} - -static GLFWbool isPointerLocked(_GLFWwindow* window) -{ - return window->wl.pointerLock.lockedPointer != NULL; } void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) { - struct wl_cursor* defaultCursor; - struct wl_cursor* defaultCursorHiDPI = NULL; - if (!_glfw.wl.pointer) return; @@ -2540,9 +2515,17 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow) return; - // Unlock possible pointer lock if no longer disabled. - if (window->cursorMode != GLFW_CURSOR_DISABLED && isPointerLocked(window)) - unlockPointer(window); + // Update pointer lock to match cursor mode + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + if (!window->wl.lockedPointer) + lockPointer(window); + } + else + { + if (window->wl.lockedPointer) + unlockPointer(window); + } if (window->cursorMode == GLFW_CURSOR_NORMAL) { @@ -2550,19 +2533,24 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) setCursorImage(window, &cursor->wl); else { - defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, - "left_ptr"); + struct wl_cursor* defaultCursor = + wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr"); if (!defaultCursor) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Standard cursor not found"); return; } + + struct wl_cursor* defaultCursorHiDPI = NULL; if (_glfw.wl.cursorThemeHiDPI) + { defaultCursorHiDPI = - wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, - "left_ptr"); - _GLFWcursorWayland cursorWayland = { + wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, "left_ptr"); + } + + _GLFWcursorWayland cursorWayland = + { defaultCursor, defaultCursorHiDPI, NULL, @@ -2570,18 +2558,12 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) 0, 0, 0 }; + setCursorImage(window, &cursorWayland); } } - else if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - if (!isPointerLocked(window)) - lockPointer(window); - } - else if (window->cursorMode == GLFW_CURSOR_HIDDEN) - { + else wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, NULL, 0, 0); - } } static void dataSourceHandleTarget(void* userData, From 632d35e0d461f305b0ef94cc85a75b3ce871fb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Jul 2022 17:40:22 +0200 Subject: [PATCH 132/207] Wayland: Fix leaks of pointer related objects (cherry picked from commit 03af6b3d4c2dbd763fbf32927c44fe6fd517991c) --- src/wl_window.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wl_window.c b/src/wl_window.c index a7b48441..6d490843 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1913,6 +1913,12 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->wl.idleInhibitor) zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor); + if (window->wl.relativePointer) + zwp_relative_pointer_v1_destroy(window->wl.relativePointer); + + if (window->wl.lockedPointer) + zwp_locked_pointer_v1_destroy(window->wl.lockedPointer); + if (window->context.destroy) window->context.destroy(window); From 5f3e5542cfa84dab141796b6b3e03319d14ceb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 8 Jul 2019 14:45:31 +0200 Subject: [PATCH 133/207] Refactor cursor mode paths This is the refactoring part of adding GLFW_CURSOR_CAPTURED, separated out to help keep 3.3-stable similar to the main branch. Related to #58. (cherry picked from commit a46f829de8d90d6932a696fd397479042ec1071d) --- src/win32_platform.h | 2 ++ src/win32_window.c | 83 +++++++++++++++++++++++++++++++------------- src/wl_window.c | 8 +++-- src/x11_window.c | 70 ++++++++++++++++++++++++++++--------- 4 files changed, 120 insertions(+), 43 deletions(-) diff --git a/src/win32_platform.h b/src/win32_platform.h index bf703d7e..e729709f 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -347,6 +347,8 @@ typedef struct _GLFWlibraryWin32 double restoreCursorPosX, restoreCursorPosY; // The window whose disabled cursor mode is active _GLFWwindow* disabledCursorWindow; + // The window the cursor is captured in + _GLFWwindow* capturedCursorWindow; RAWINPUT* rawInput; int rawInputSize; UINT mouseTrailSize; diff --git a/src/win32_window.c b/src/win32_window.c index 073ceee9..2801f6c2 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -251,20 +251,24 @@ static void updateCursorImage(_GLFWwindow* window) SetCursor(NULL); } -// Updates the cursor clip rect +// Sets the cursor clip rect to the window content area // -static void updateClipRect(_GLFWwindow* window) +static void captureCursor(_GLFWwindow* window) { - if (window) - { - RECT clipRect; - GetClientRect(window->win32.handle, &clipRect); - ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); - ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); - ClipCursor(&clipRect); - } - else - ClipCursor(NULL); + RECT clipRect; + GetClientRect(window->win32.handle, &clipRect); + ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); + ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); + ClipCursor(&clipRect); + _glfw.win32.capturedCursorWindow = window; +} + +// Disabled clip cursor +// +static void releaseCursor(void) +{ + ClipCursor(NULL); + _glfw.win32.capturedCursorWindow = NULL; } // Enables WM_INPUT messages for the mouse for the specified window @@ -303,7 +307,7 @@ static void disableCursor(_GLFWwindow* window) &_glfw.win32.restoreCursorPosY); updateCursorImage(window); _glfwCenterCursorInContentArea(window); - updateClipRect(window); + captureCursor(window); if (window->rawMouseMotion) enableRawMouseMotion(window); @@ -317,7 +321,7 @@ static void enableCursor(_GLFWwindow* window) disableRawMouseMotion(window); _glfw.win32.disabledCursorWindow = NULL; - updateClipRect(NULL); + releaseCursor(); _glfwPlatformSetCursorPos(window, _glfw.win32.restoreCursorPosX, _glfw.win32.restoreCursorPosY); @@ -1033,8 +1037,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, (window->win32.maximized && wParam != SIZE_RESTORED); - if (_glfw.win32.disabledCursorWindow == window) - updateClipRect(window); + if (_glfw.win32.capturedCursorWindow == window) + captureCursor(window); if (window->win32.iconified != iconified) _glfwInputWindowIconify(window, iconified); @@ -1069,8 +1073,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_MOVE: { - if (_glfw.win32.disabledCursorWindow == window) - updateClipRect(window); + if (_glfw.win32.capturedCursorWindow == window) + captureCursor(window); // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as // those macros do not handle negative window positions correctly @@ -1540,7 +1544,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) window->context.destroy(window); if (_glfw.win32.disabledCursorWindow == window) - _glfw.win32.disabledCursorWindow = NULL; + enableCursor(window); + + if (_glfw.win32.capturedCursorWindow == window) + releaseCursor(); if (window->win32.handle) { @@ -2156,14 +2163,40 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { - if (mode == GLFW_CURSOR_DISABLED) + if (_glfwPlatformWindowFocused(window)) { - if (_glfwPlatformWindowFocused(window)) - disableCursor(window); + if (mode == GLFW_CURSOR_DISABLED) + { + _glfwPlatformGetCursorPos(window, + &_glfw.win32.restoreCursorPosX, + &_glfw.win32.restoreCursorPosY); + _glfwCenterCursorInContentArea(window); + if (window->rawMouseMotion) + enableRawMouseMotion(window); + } + else if (_glfw.win32.disabledCursorWindow == window) + { + if (window->rawMouseMotion) + disableRawMouseMotion(window); + } + + if (mode == GLFW_CURSOR_DISABLED) + captureCursor(window); + else + releaseCursor(); + + if (mode == GLFW_CURSOR_DISABLED) + _glfw.win32.disabledCursorWindow = window; + else if (_glfw.win32.disabledCursorWindow == window) + { + _glfw.win32.disabledCursorWindow = NULL; + _glfwPlatformSetCursorPos(window, + _glfw.win32.restoreCursorPosX, + _glfw.win32.restoreCursorPosY); + } } - else if (_glfw.win32.disabledCursorWindow == window) - enableCursor(window); - else if (cursorInContentArea(window)) + + if (cursorInContentArea(window)) updateCursorImage(window); } diff --git a/src/wl_window.c b/src/wl_window.c index 6d490843..333fd7fd 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2527,7 +2527,8 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) if (!window->wl.lockedPointer) lockPointer(window); } - else + else if (window->cursorMode == GLFW_CURSOR_NORMAL || + window->cursorMode == GLFW_CURSOR_HIDDEN) { if (window->wl.lockedPointer) unlockPointer(window); @@ -2568,8 +2569,11 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) setCursorImage(window, &cursorWayland); } } - else + else if (window->cursorMode == GLFW_CURSOR_HIDDEN || + window->cursorMode == GLFW_CURSOR_DISABLED) + { wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, NULL, 0, 0); + } } static void dataSourceHandleTarget(void* userData, diff --git a/src/x11_window.c b/src/x11_window.c index ddda48d7..c34a0b80 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -523,6 +523,25 @@ static void updateCursorImage(_GLFWwindow* window) } } +// Grabs the cursor and confines it to the window +// +static void captureCursor(_GLFWwindow* window) +{ + XGrabPointer(_glfw.x11.display, window->x11.handle, True, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + window->x11.handle, + None, + CurrentTime); +} + +// Ungrabs the cursor +// +static void releaseCursor(void) +{ + XUngrabPointer(_glfw.x11.display, CurrentTime); +} + // Enable XI2 raw mouse motion events // static void enableRawMouseMotion(_GLFWwindow* window) @@ -565,12 +584,7 @@ static void disableCursor(_GLFWwindow* window) &_glfw.x11.restoreCursorPosY); updateCursorImage(window); _glfwCenterCursorInContentArea(window); - XGrabPointer(_glfw.x11.display, window->x11.handle, True, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask, - GrabModeAsync, GrabModeAsync, - window->x11.handle, - _glfw.x11.hiddenCursorHandle, - CurrentTime); + captureCursor(window); } // Exit disabled cursor mode for the specified window @@ -581,7 +595,7 @@ static void enableCursor(_GLFWwindow* window) disableRawMouseMotion(window); _glfw.x11.disabledCursorWindow = NULL; - XUngrabPointer(_glfw.x11.display, CurrentTime); + releaseCursor(); _glfwPlatformSetCursorPos(window, _glfw.x11.restoreCursorPosX, _glfw.x11.restoreCursorPosY); @@ -2044,7 +2058,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, void _glfwPlatformDestroyWindow(_GLFWwindow* window) { if (_glfw.x11.disabledCursorWindow == window) - _glfw.x11.disabledCursorWindow = NULL; + enableCursor(window); if (window->monitor) releaseMonitor(window); @@ -2851,16 +2865,40 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { - if (mode == GLFW_CURSOR_DISABLED) + if (_glfwPlatformWindowFocused(window)) { - if (_glfwPlatformWindowFocused(window)) - disableCursor(window); - } - else if (_glfw.x11.disabledCursorWindow == window) - enableCursor(window); - else - updateCursorImage(window); + if (mode == GLFW_CURSOR_DISABLED) + { + _glfwPlatformGetCursorPos(window, + &_glfw.x11.restoreCursorPosX, + &_glfw.x11.restoreCursorPosY); + _glfwCenterCursorInContentArea(window); + if (window->rawMouseMotion) + enableRawMouseMotion(window); + } + else if (_glfw.x11.disabledCursorWindow == window) + { + if (window->rawMouseMotion) + disableRawMouseMotion(window); + } + if (mode == GLFW_CURSOR_DISABLED) + captureCursor(window); + else + releaseCursor(); + + if (mode == GLFW_CURSOR_DISABLED) + _glfw.x11.disabledCursorWindow = window; + else if (_glfw.x11.disabledCursorWindow == window) + { + _glfw.x11.disabledCursorWindow = NULL; + _glfwPlatformSetCursorPos(window, + _glfw.x11.restoreCursorPosX, + _glfw.x11.restoreCursorPosY); + } + } + + updateCursorImage(window); XFlush(_glfw.x11.display); } From 0ee9b7281bae50695ad4e5212f5b760bc0728751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Jul 2022 13:04:21 +0200 Subject: [PATCH 134/207] Wayland: Clean up pointer helper function order (cherry picked from commit 7be6a2cabec3a50419448cc618792d2949d988fd) --- src/wl_window.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 333fd7fd..d15f4739 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2460,15 +2460,6 @@ static void lockedPointerHandleLocked(void* userData, { } -static void unlockPointer(_GLFWwindow* window) -{ - zwp_relative_pointer_v1_destroy(window->wl.relativePointer); - window->wl.relativePointer = NULL; - - zwp_locked_pointer_v1_destroy(window->wl.lockedPointer); - window->wl.lockedPointer = NULL; -} - static void lockedPointerHandleUnlocked(void* userData, struct zwp_locked_pointer_v1* lockedPointer) { @@ -2509,6 +2500,15 @@ static void lockPointer(_GLFWwindow* window) window); } +static void unlockPointer(_GLFWwindow* window) +{ + zwp_relative_pointer_v1_destroy(window->wl.relativePointer); + window->wl.relativePointer = NULL; + + zwp_locked_pointer_v1_destroy(window->wl.lockedPointer); + window->wl.lockedPointer = NULL; +} + void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) { if (!_glfw.wl.pointer) From 3670cd0561e149a0162fb222ea91d0127ded51ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Jul 2022 16:28:23 +0200 Subject: [PATCH 135/207] Wayland: Remove unreachable code This platform function is only called if the cursor is enabled. (cherry picked from commit 3a5c726d1bd485e63219c2a6c3e377f434d6ee10) --- src/wl_window.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index d15f4739..b1f47804 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2294,13 +2294,6 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) { - if (window->wl.lockedPointer) - { - zwp_locked_pointer_v1_set_cursor_position_hint( - window->wl.lockedPointer, - wl_fixed_from_double(x), - wl_fixed_from_double(y)); - } } void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) From 34bfb526416e71e837216ccedf31a064efe975ff Mon Sep 17 00:00:00 2001 From: TheChocolateOre <50585073+TheChocolateOre@users.noreply.github.com> Date: Thu, 28 Jul 2022 16:56:18 +0300 Subject: [PATCH 136/207] Fix typos and other issues in docs This fixes spelling, grammar and punctuation issues, missing words and stray words across the documentation. A confusing sentence was removed from the tutorial. Closes #2085 (cherry picked from commit 2e12ef00bb4b96c7b4c6ea14f594cc8f50ea718f) --- docs/build.dox | 2 +- docs/compat.dox | 6 +++--- docs/compile.dox | 11 ++++++----- docs/context.dox | 6 +++--- docs/input.dox | 4 ++-- docs/intro.dox | 14 +++++++------- docs/monitor.dox | 4 ++-- docs/moving.dox | 6 +++--- docs/quick.dox | 6 +----- docs/vulkan.dox | 2 +- 10 files changed, 29 insertions(+), 32 deletions(-) diff --git a/docs/build.dox b/docs/build.dox index adbbb858..faa36b27 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -26,7 +26,7 @@ GLFW. @endcode This header defines all the constants and declares all the types and function -prototypes of the GLFW API. By default it also includes the OpenGL header from +prototypes of the GLFW API. By default, it also includes the OpenGL header from your development environment. See [option macros](@ref build_macros) below for how to select OpenGL ES headers and more. diff --git a/docs/compat.dox b/docs/compat.dox index 0b7c4b0b..cf5b4e23 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -146,7 +146,7 @@ formats. If GLX 1.3 is not supported, @ref glfwInit will fail. GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and `GLX_SGI_swap_control` extensions to provide vertical retrace synchronization -(or _vsync_), in that order of preference. Where none of these extension are +(or _vsync_), in that order of preference. When none of these extensions are available, calling @ref glfwSwapInterval will have no effect. GLFW uses the `GLX_ARB_multisample` extension to create contexts with @@ -215,8 +215,8 @@ extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no effect and the context will always be flushed when released. GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB` -extensions to provide support for sRGB framebuffers. Where both of these -extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect. +extensions to provide support for sRGB framebuffers. When both of these +extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect. @section compat_osx OpenGL on macOS diff --git a/docs/compile.dox b/docs/compile.dox index ec458f4f..99d5a68e 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -45,7 +45,7 @@ Linux and FreeBSD you will need a few extra packages. To compile GLFW for X11, you need to have the X11 development packages installed. They are not needed to build or run programs that use GLFW. -On Debian and derivates like Ubuntu and Linux Mint the `xorg-dev` meta-package +On Debian and derivatives like Ubuntu and Linux Mint the `xorg-dev` meta-package pulls in the development packages for all of X11. @code{.sh} @@ -82,8 +82,9 @@ To compile GLFW for Wayland, you need to have the Wayland and xkbcommon development packages installed. They are not needed to build or run programs that use GLFW. -On Debian and derivates like Ubuntu and Linux Mint you will need the `libwayland-dev`, +On Debian and derivatives like Ubuntu and Linux Mint you will need the `libwayland-dev`, `libxkbcommon-dev`, `wayland-protocols` and `extra-cmake-modules` packages. +These will pull in all other dependencies. @code{.sh} sudo apt install libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules @@ -137,7 +138,7 @@ If you wish change any CMake variables in the list, press _Configure_ and then _Generate_ to have the new values take effect. The variable list will be populated after the first configure step. -By default GLFW will use X11 on Linux and other Unix-like systems other +By default, GLFW will use X11 on Linux and other Unix-like systems other than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` option in the GLFW section of the variable list, then apply the new value as described above. @@ -171,7 +172,7 @@ flag. cmake -S path/to/glfw -B path/to/build -G Xcode @endcode -By default GLFW will use X11 on Linux and other Unix-like systems other +By default, GLFW will use X11 on Linux and other Unix-like systems other than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` CMake option. @code{.sh} @@ -327,7 +328,7 @@ For more details see the @section compile_manual Compiling GLFW manually If you wish to compile GLFW without its CMake build environment then you will -have to do at least some of the platform detection yourself. GLFW needs +have to do at least some of the platform-detection yourself. GLFW needs a configuration macro to be defined in order to know what window system it is being compiled for and also has optional, platform-specific ones for various features. diff --git a/docs/context.dox b/docs/context.dox index 25de69ff..1a3f35a5 100644 --- a/docs/context.dox +++ b/docs/context.dox @@ -61,7 +61,7 @@ information. The name and number of this chapter unfortunately varies between versions and APIs, but has at times been named _Shared Objects and Multiple Contexts_. -GLFW comes with a barebones object sharing example program called `sharing`. +GLFW comes with a bare-bones object sharing example program called `sharing`. @subsection context_offscreen Offscreen contexts @@ -193,7 +193,7 @@ it suppresses the development environment's OpenGL or OpenGL ES header. #include @endcode -Finally you need to initialize glad once you have a suitable current context. +Finally, you need to initialize glad once you have a suitable current context. @code window = glfwCreateWindow(640, 480, "My Window", NULL, NULL); @@ -209,7 +209,7 @@ gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); Once glad has been loaded, you have access to all OpenGL core and extension functions supported by both the context you created and the glad loader you -generated and you are ready to start rendering. +generated. After that, you are ready to start rendering. You can specify a minimum required OpenGL or OpenGL ES version with [context hints](@ref window_hints_ctx). If your needs are more complex, you can diff --git a/docs/input.dox b/docs/input.dox index 1d61e5bc..d0834408 100644 --- a/docs/input.dox +++ b/docs/input.dox @@ -24,7 +24,7 @@ All input callbacks receive a window handle. By using the or objects from your callbacks. To get a better feel for how the various events callbacks behave, run the -`events` test program. It register every callback supported by GLFW and prints +`events` test program. It registers every callback supported by GLFW and prints out all arguments provided for every event, along with time and sequence information. @@ -382,7 +382,7 @@ sequential rows, starting from the top-left corner. @subsubsection cursor_standard Standard cursor creation A cursor with a [standard shape](@ref shapes) from the current system cursor -theme can be can be created with @ref glfwCreateStandardCursor. +theme can be created with @ref glfwCreateStandardCursor. @code GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); diff --git a/docs/intro.dox b/docs/intro.dox index e563b505..c5d1b930 100644 --- a/docs/intro.dox +++ b/docs/intro.dox @@ -124,9 +124,9 @@ This will destroy any remaining window, monitor and cursor objects, restore any modified gamma ramps, re-enable the screensaver if it had been disabled and free any other resources allocated by GLFW. -Once the library is terminated, it is as if it had never been initialized and +Once the library is terminated, it is as if it had never been initialized, therefore you will need to initialize it again before being able to use GLFW. If the -library was not initialized or had already been terminated, it return +library was not initialized or had already been terminated, it returns immediately. @@ -246,14 +246,14 @@ which monitor the window is currently considered to be on. This section describes the conditions under which GLFW can be expected to function, barring bugs in the operating system or drivers. Use of GLFW outside -of these limits may work on some platforms, or on some machines, or some of the +these limits may work on some platforms, or on some machines, or some of the time, or on some versions of GLFW, but it may break at any time and this will not be considered a bug. @subsection lifetime Pointer lifetimes -GLFW will never free any pointer you provide to it and you must never free any +GLFW will never free any pointer you provide to it, and you must never free any pointer it provides to you. Many GLFW functions return pointers to dynamically allocated structures, strings @@ -444,11 +444,11 @@ The format of the string is as follows: - The name of the context creation API - Any additional options or APIs -For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL -back ends, the version string may look something like this: +For example, when compiling GLFW 3.3.9 with MinGW for Windows, may result in +a version string like this: @code -3.0.0 Win32 WGL MinGW +3.3.9 Win32 WGL EGL OSMesa MinGW @endcode */ diff --git a/docs/monitor.dox b/docs/monitor.dox index 86eb4540..b4099dbf 100644 --- a/docs/monitor.dox +++ b/docs/monitor.dox @@ -138,7 +138,7 @@ glfwGetMonitorPhysicalSize(monitor, &width_mm, &height_mm); @endcode While this can be used to calculate the raw DPI of a monitor, this is often not -useful. Instead use the [monitor content scale](@ref monitor_scale) and +useful. Instead, use the [monitor content scale](@ref monitor_scale) and [window content scale](@ref window_scale) to scale your content. @@ -261,7 +261,7 @@ To experiment with gamma correction via the @ref glfwSetGamma function, run the `gamma` test program. @note The software controlled gamma ramp is applied _in addition_ to the -hardware gamma correction, which today is usually an approximation of sRGB +hardware gamma correction, which today is typically an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior. diff --git a/docs/moving.dox b/docs/moving.dox index b80d84a2..705b4fa8 100644 --- a/docs/moving.dox +++ b/docs/moving.dox @@ -243,7 +243,7 @@ while (!glfwWindowShouldClose(window)) @endcode The close callback no longer returns a value. Instead, it is called after the -close flag has been set so it can override its value, if it chooses to, before +close flag has been set, so it can optionally override its value, before event processing completes. You may however not call @ref glfwDestroyWindow from the close callback (or any other window related callback). @@ -350,11 +350,11 @@ from a repeat. Note that @ref glfwGetKey still returns only `GLFW_PRESS` or GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to the values generated by the current keyboard layout. The tokens are named -according to the values they would have using the standard US layout, but this +according to the values they would have in the standard US layout, but this is only a convenience, as most programmers are assumed to know that layout. This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and is the same key in the same place regardless of what keyboard layouts the users -of your program has. +of your program have. The key input facility was never meant for text input, although using it that way worked slightly better in GLFW 2. If you were using it to input text, you diff --git a/docs/quick.dox b/docs/quick.dox index 3645fc05..2cce29f6 100644 --- a/docs/quick.dox +++ b/docs/quick.dox @@ -144,10 +144,6 @@ if (!window) } @endcode -The window handle is passed to all window related functions and is provided to -along to all window related callbacks, so they can tell which window received -the event. - When a window and context is no longer needed, destroy it. @code @@ -233,7 +229,7 @@ events as described below. @subsection quick_render Rendering with OpenGL Once you have a current OpenGL context, you can use OpenGL normally. In this -tutorial, a multi-colored rotating triangle will be rendered. The framebuffer +tutorial, a multicolored rotating triangle will be rendered. The framebuffer size needs to be retrieved for `glViewport`. @code diff --git a/docs/vulkan.dox b/docs/vulkan.dox index f34366f3..7e4a0f0b 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -131,7 +131,7 @@ PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); @endcode -Device-specific functions may execute a little bit faster, due to not having to +Device-specific functions may execute a little faster, due to not having to dispatch internally based on the device passed to them. For more information about `vkGetDeviceProcAddr`, see the Vulkan documentation. From 1fe29e2c19d6370fa054bb1de3d87fd1f4b6ec42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 26 Jul 2022 19:21:07 +0200 Subject: [PATCH 137/207] Fix native access macros being mutually exclusive The documentation was updated with the introduction of run-time platform selection, but the preprocessor logic was not. (cherry picked from commit 2efc598d70be92267a97c95ac08668565784ab19) --- include/GLFW/glfw3native.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 7be0227d..7e093899 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -103,17 +103,23 @@ extern "C" { #undef GLFW_APIENTRY_DEFINED #endif #include - #elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) + #endif + + #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) #if defined(__OBJC__) #import #else #include #include #endif - #elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) + #endif + + #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) #include #include - #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #endif + + #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) #include #endif From 426c6ed6b1f66b85ab99a5614b514eec60cced5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 26 Oct 2021 20:30:29 +0200 Subject: [PATCH 138/207] X11: Preserve unrelated values in WM_NORMAL_HINTS This stops GLFW overwriting the whole WM_NORMAL_HINTS property every time it updates size-related parts of it. (cherry picked from commit 7d73629e5071b0baea87135f01a4335b10740068) --- src/x11_window.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index c34a0b80..9bd29e34 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -321,6 +321,11 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height) { XSizeHints* hints = XAllocSizeHints(); + long supplied; + XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied); + + hints->flags &= ~(PMinSize | PMaxSize | PAspect); + if (!window->monitor) { if (window->resizable) @@ -357,9 +362,6 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height) } } - hints->flags |= PWinGravity; - hints->win_gravity = StaticGravity; - XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } @@ -740,7 +742,28 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, XFree(hints); } - updateNormalHints(window, width, height); + // Set ICCCM WM_NORMAL_HINTS property + { + XSizeHints* hints = XAllocSizeHints(); + if (!hints) + { + _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate size hints"); + return GLFW_FALSE; + } + + if (!wndconfig->resizable) + { + hints->flags |= (PMinSize | PMaxSize); + hints->min_width = hints->max_width = width; + hints->min_height = hints->max_height = height; + } + + hints->flags |= PWinGravity; + hints->win_gravity = StaticGravity; + + XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); + XFree(hints); + } // Set ICCCM WM_CLASS property { From ed55529ce850dc27a5dd0895e917ed5f3f6ede1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 27 Jul 2022 15:03:16 +0200 Subject: [PATCH 139/207] EGL: Add support for loading glvnd libOpenGL (cherry picked from commit 55aad3c37b67f17279378db52da0a3ab81bbf26d) --- README.md | 1 + src/egl_context.c | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index f40a6e59..1802d78b 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) + [EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL ## Contact diff --git a/src/egl_context.c b/src/egl_context.c index 58d9557b..ec0ff49e 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -678,6 +678,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, #elif defined(__OpenBSD__) || defined(__NetBSD__) "libGL.so", #else + "libOpenGL.so.0", "libGL.so.1", #endif NULL From 1f675ab62f712aa0214f6423c162c8c5c0adff39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 27 Jul 2022 15:05:23 +0200 Subject: [PATCH 140/207] GLX: Add support for loading glvnd libGLX (cherry picked from commit c18851f52ec9704eb06464058a600845ec1eada1) --- README.md | 1 + src/glx_context.c | 4 ++++ src/glx_context.h | 1 - 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1802d78b..8ae21365 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) [EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL + - [GLX] Added loading of glvnd `libGLX.so.0` where available ## Contact diff --git a/src/glx_context.c b/src/glx_context.c index 1b1b3f90..46f63476 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -226,7 +226,10 @@ static GLFWglproc getProcAddressGLX(const char* procname) else if (_glfw.glx.GetProcAddressARB) return _glfw.glx.GetProcAddressARB((const GLubyte*) procname); else + { + // NOTE: glvnd provides GLX 1.4, so this can only happen with libGL return _glfw_dlsym(_glfw.glx.handle, procname); + } } static void destroyContextGLX(_GLFWwindow* window) @@ -263,6 +266,7 @@ GLFWbool _glfwInitGLX(void) #elif defined(__OpenBSD__) || defined(__NetBSD__) "libGL.so", #else + "libGLX.so.0", "libGL.so.1", "libGL.so", #endif diff --git a/src/glx_context.h b/src/glx_context.h index df0233eb..2ea17d19 100644 --- a/src/glx_context.h +++ b/src/glx_context.h @@ -127,7 +127,6 @@ typedef struct _GLFWlibraryGLX int eventBase; int errorBase; - // dlopen handle for libGL.so.1 void* handle; // GLX 1.3 functions From 8b4f1ebbea4acdd9a89881330bb7eeb4cdf04b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Jul 2022 20:33:47 +0200 Subject: [PATCH 141/207] Wayland: Fix window opacity on older systems On systems lacking the EGL_EXT_present_opaque extension, some compositors treat any buffer with an alpha channel as per-pixel transparent. This commit ignores any EGLConfig with an alpha channel if the extension is missing and the window is created with GLFW_TRANSPARENT_FRAMEBUFFER set to false. This is technically not a breaking change since GLFW_ALPHA_BITS is not a hard constraint, but it is still going to inconvenience anyone using the framebuffer alpa channel to store other kinds of data. Related to #1895 (cherry picked from commit ef6c9d8b4f957c2a53374558e393bdb5c4264fa5) --- CONTRIBUTORS.md | 1 + README.md | 2 ++ docs/news.dox | 13 +++++++++++++ src/egl_context.c | 12 ++++++++++++ 4 files changed, 28 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8dbedda0..835b788a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -180,6 +180,7 @@ video tutorials. - pthom - Martin Pulec - Guillaume Racicot + - Christian Rauch - Philip Rideout - Eddie Ringle - Max Risuhin diff --git a/README.md b/README.md index 8ae21365..ea830772 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,8 @@ information on what to include when reporting a bug. ## Changelog - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) + - [Wayland] Disabled alpha channel for opaque windows on systems lacking + `EGL_EXT_present_opaque` (#1895) - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) [EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL - [GLX] Added loading of glvnd `libGLX.so.0` where available diff --git a/docs/news.dox b/docs/news.dox index 1f016d39..3a7ce4dd 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -312,6 +312,19 @@ Starting with GLFW 3.3.7, events posted with @ref glfwPostEmptyEvent now use a s unnamed pipe instead of sending an X11 client event to the helper window. +@subsubsection wayland_alpha_34 Frambuffer may lack alpha channel on older Wayland systems + +On Wayland, when creating an EGL context on a machine lacking the new +`EGL_EXT_present_opaque` extension, the @ref GLFW_ALPHA_BITS window hint will be +ignored and the framebuffer will have no alpha channel. This is because some +Wayland compositors treat any buffer with an alpha channel as per-pixel +transparent. + +If you want a per-pixel transparent window, see the +[GLFW_TRANSPARENT_FRAMEBUFFER](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) window +hint. + + @subsection deprecations_33 Deprecations in version 3.3 @subsubsection charmods_callback_33 Character with modifiers callback diff --git a/src/egl_context.c b/src/egl_context.c index ec0ff49e..00f43b5d 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -172,6 +172,18 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE); u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE); +#if defined(_GLFW_WAYLAND) + // NOTE: The wl_surface opaque region is no guarantee that its buffer + // is presented as opaque, if it also has an alpha channel + // HACK: If EGL_EXT_present_opaque is unavailable, ignore any config + // with an alpha channel to ensure the buffer is opaque + if (!_glfw.egl.EXT_present_opaque) + { + if (!desired->transparent && u->alphaBits > 0) + continue; + } +#endif // _GLFW_WAYLAND + u->samples = getEGLConfigAttrib(n, EGL_SAMPLES); u->doublebuffer = desired->doublebuffer; From bd13f55ca8b220acb9484c4f97b39b6cbaf54be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 24 Apr 2022 22:31:28 +0200 Subject: [PATCH 142/207] WGL: Fix count of displayable pixel formats We only care about displayable pixel formats (as defined in WGL_ARB_pixel_format) for window context creation. This changes pixel format enumeration to ignore non-displayable formats, which are specified to be listed after displayable ones, by always using the return value of DescribePixelFormat as the pixel format count. (cherry picked from commit 2c0f34b60f7c7a07183ed71754b0156ece3b6c1b) --- src/wgl_context.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 72ad11de..a7704738 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -73,18 +73,13 @@ static int choosePixelFormat(_GLFWwindow* window, int attribs[40]; int values[sizeof(attribs) / sizeof(attribs[0])]; + nativeCount = DescribePixelFormat(window->context.wgl.dc, + 1, + sizeof(PIXELFORMATDESCRIPTOR), + NULL); + 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); @@ -122,13 +117,6 @@ static int choosePixelFormat(_GLFWwindow* window, addAttrib(WGL_COLORSPACE_EXT); } } - else - { - nativeCount = DescribePixelFormat(window->context.wgl.dc, - 1, - sizeof(PIXELFORMATDESCRIPTOR), - NULL); - } usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); From bc36010350863b007879b52a4ff39c93f1ea9f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 15 Aug 2022 23:29:10 +0200 Subject: [PATCH 143/207] Check if context creation APIs match when sharing (cherry picked from commit 6b57e08bb0078c9834889eab871bac2368198c15) --- src/context.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/context.c b/src/context.c index d86e0fae..93c9a935 100644 --- a/src/context.c +++ b/src/context.c @@ -48,16 +48,6 @@ // 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) @@ -78,6 +68,23 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) return GLFW_FALSE; } + 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 != ctxconfig->share->context.source) + { + _glfwInputError(GLFW_INVALID_ENUM, + "Context creation APIs do not match between contexts"); + return GLFW_FALSE; + } + } + if (ctxconfig->client == GLFW_OPENGL_API) { if ((ctxconfig->major < 1 || ctxconfig->minor < 0) || From 6fb86c089e54973fed8a8aaf18886625288830b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 26 Aug 2022 18:16:29 +0200 Subject: [PATCH 144/207] EGL: Add better errors for client API mismatch Because EGL ties client API support to configs, attempts to create a context with an unavailable client API will fail with the unhelpful "failed to find suitable config" error description. This attempts to detect cases where there are usable configs for the other client API and emit a hopefully more helpful error. Related to #2173 (cherry picked from commit e0576666426ff321414f54aefc7583cf457865fc) --- src/egl_context.c | 69 ++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/egl_context.c b/src/egl_context.c index 00f43b5d..7b56acab 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -94,7 +94,18 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; + int i, nativeCount, usableCount, apiBit; + GLFWbool wrongApiAvailable = GLFW_FALSE; + + if (ctxconfig->client == GLFW_OPENGL_ES_API) + { + if (ctxconfig->major == 1) + apiBit = EGL_OPENGL_ES_BIT; + else + apiBit = EGL_OPENGL_ES2_BIT; + } + else + apiBit = EGL_OPENGL_BIT; eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); if (!nativeCount) @@ -145,23 +156,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, } #endif // _GLFW_X11 - if (ctxconfig->client == GLFW_OPENGL_ES_API) + if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit)) { - 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; + wrongApiAvailable = GLFW_TRUE; + continue; } u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE); @@ -194,6 +192,35 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (closest) *result = (EGLConfig) closest->handle; + else + { + if (wrongApiAvailable) + { + if (ctxconfig->client == GLFW_OPENGL_ES_API) + { + if (ctxconfig->major == 1) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to find support for OpenGL ES 1.x"); + } + else + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to find support for OpenGL ES 2 or later"); + } + } + else + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to find support for OpenGL"); + } + } + else + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, + "EGL: Failed to find a suitable EGLConfig"); + } + } free(nativeConfigs); free(usableConfigs); @@ -497,11 +524,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, 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) { @@ -753,11 +776,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, 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); From 31b038663a0b2ffcf4fe7b3b2074c1892b2d2831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 26 Aug 2022 19:00:08 +0200 Subject: [PATCH 145/207] EGL: Add better error for no stereo (cherry picked from commit 93e93135f22c27a0120c5b0c7f2242901c8b1b52) --- src/egl_context.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/egl_context.c b/src/egl_context.c index 7b56acab..19668af9 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -107,6 +107,12 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, else apiBit = EGL_OPENGL_BIT; + if (desired->stereo) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported"); + return GLFW_FALSE; + } + eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); if (!nativeCount) { From 493df4a0b59123fea80a40865a037c701c15c2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 26 Aug 2022 19:08:18 +0200 Subject: [PATCH 146/207] EGL: Cleanup Both config parameters are "desired", but one is older and never had its name updated. This commit at least makes it clearer that they are similar. (cherry picked from commit ab1b1edfd08352da95e84118b1c91bf612117f56) --- src/egl_context.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/egl_context.c b/src/egl_context.c index 19668af9..aeadbded 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -88,7 +88,7 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib) // Return the EGLConfig most closely matching the specified hints // static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* desired, + const _GLFWfbconfig* fbconfig, EGLConfig* result) { EGLConfig* nativeConfigs; @@ -107,7 +107,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, else apiBit = EGL_OPENGL_BIT; - if (desired->stereo) + if (fbconfig->stereo) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported"); return GLFW_FALSE; @@ -148,7 +148,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, if (!vi.visualid) continue; - if (desired->transparent) + if (fbconfig->transparent) { int count; XVisualInfo* vis = @@ -183,19 +183,19 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, // with an alpha channel to ensure the buffer is opaque if (!_glfw.egl.EXT_present_opaque) { - if (!desired->transparent && u->alphaBits > 0) + if (!fbconfig->transparent && u->alphaBits > 0) continue; } #endif // _GLFW_WAYLAND u->samples = getEGLConfigAttrib(n, EGL_SAMPLES); - u->doublebuffer = desired->doublebuffer; + u->doublebuffer = fbconfig->doublebuffer; u->handle = (uintptr_t) n; usableCount++; } - closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); + closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount); if (closest) *result = (EGLConfig) closest->handle; else From d36d062d72471cd4a1390f785ff2dc9f590c5305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Apr 2022 19:26:05 +0200 Subject: [PATCH 147/207] Win32: Remove unhelpful helper function (cherry picked from commit ab3ea8ac9f1b3dbe6aaf2e830d35e93c30657064) --- src/win32_window.c | 95 ++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 53 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 2801f6c2..a2ab94d8 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -186,53 +186,38 @@ static HICON createIcon(const GLFWimage* image, return handle; } -// Translate content area size to full window size according to styles and DPI -// -static void getFullWindowSize(DWORD style, DWORD exStyle, - int contentWidth, int contentHeight, - int* fullWidth, int* fullHeight, - UINT dpi) -{ - RECT rect = { 0, 0, contentWidth, contentHeight }; - - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) - AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi); - else - AdjustWindowRectEx(&rect, style, FALSE, exStyle); - - *fullWidth = rect.right - rect.left; - *fullHeight = rect.bottom - rect.top; -} - // Enforce the content area aspect ratio based on which edge is being dragged // static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) { - int xoff, yoff; - UINT dpi = USER_DEFAULT_SCREEN_DPI; + RECT frame = {0}; const float ratio = (float) window->numer / (float) window->denom; + const DWORD style = getWindowStyle(window); + const DWORD exStyle = getWindowExStyle(window); if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) - dpi = GetDpiForWindow(window->win32.handle); - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, dpi); + { + AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle, + GetDpiForWindow(window->win32.handle)); + } + else + AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT || edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT) { - area->bottom = area->top + yoff + - (int) ((area->right - area->left - xoff) / ratio); + area->bottom = area->top + (frame.bottom - frame.top) + + (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) { - area->top = area->bottom - yoff - - (int) ((area->right - area->left - xoff) / ratio); + area->top = area->bottom - (frame.bottom - frame.top) - + (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) { - area->right = area->left + xoff + - (int) ((area->bottom - area->top - yoff) * ratio); + area->right = area->left + (frame.right - frame.left) + + (int) (((area->bottom - area->top) - (frame.bottom - frame.top)) * ratio); } } @@ -1098,31 +1083,34 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_GETMINMAXINFO: { - int xoff, yoff; - UINT dpi = USER_DEFAULT_SCREEN_DPI; + RECT frame = {0}; MINMAXINFO* mmi = (MINMAXINFO*) lParam; + const DWORD style = getWindowStyle(window); + const DWORD exStyle = getWindowExStyle(window); if (window->monitor) break; if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) - dpi = GetDpiForWindow(window->win32.handle); - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, dpi); + { + AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle, + GetDpiForWindow(window->win32.handle)); + } + else + AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) { - mmi->ptMinTrackSize.x = window->minwidth + xoff; - mmi->ptMinTrackSize.y = window->minheight + yoff; + mmi->ptMinTrackSize.x = window->minwidth + frame.right - frame.left; + mmi->ptMinTrackSize.y = window->minheight + frame.bottom - frame.top; } if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) { - mmi->ptMaxTrackSize.x = window->maxwidth + xoff; - mmi->ptMaxTrackSize.y = window->maxheight + yoff; + mmi->ptMaxTrackSize.x = window->maxwidth + frame.right - frame.left; + mmi->ptMaxTrackSize.y = window->maxheight + frame.bottom - frame.top; } if (!window->decorated) @@ -1281,7 +1269,7 @@ static int createNativeWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) { - int xpos, ypos, fullWidth, fullHeight; + int frameX, frameY, frameWidth, frameHeight; WCHAR* wideTitle; DWORD style = getWindowStyle(window); DWORD exStyle = getWindowExStyle(window); @@ -1294,24 +1282,25 @@ static int createNativeWindow(_GLFWwindow* window, // NOTE: This window placement is temporary and approximate, as the // correct position and size cannot be known until the monitor // video mode has been picked in _glfwSetVideoModeWin32 - xpos = mi.rcMonitor.left; - ypos = mi.rcMonitor.top; - fullWidth = mi.rcMonitor.right - mi.rcMonitor.left; - fullHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; + frameX = mi.rcMonitor.left; + frameY = mi.rcMonitor.top; + frameWidth = mi.rcMonitor.right - mi.rcMonitor.left; + frameHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; } else { - xpos = CW_USEDEFAULT; - ypos = CW_USEDEFAULT; + RECT rect = { 0, 0, wndconfig->width, wndconfig->height }; window->win32.maximized = wndconfig->maximized; if (wndconfig->maximized) style |= WS_MAXIMIZE; - getFullWindowSize(style, exStyle, - wndconfig->width, wndconfig->height, - &fullWidth, &fullHeight, - USER_DEFAULT_SCREEN_DPI); + AdjustWindowRectEx(&rect, style, FALSE, exStyle); + + frameX = CW_USEDEFAULT; + frameY = CW_USEDEFAULT; + frameWidth = rect.right - rect.left; + frameHeight = rect.bottom - rect.top; } wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title); @@ -1322,8 +1311,8 @@ static int createNativeWindow(_GLFWwindow* window, _GLFW_WNDCLASSNAME, wideTitle, style, - xpos, ypos, - fullWidth, fullHeight, + frameX, frameY, + frameWidth, frameHeight, NULL, // No parent window NULL, // No window menu _glfw.win32.instance, From af3e14fbc20936e12db18f75ca49b5b16aca1c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 9 Sep 2022 17:35:48 +0200 Subject: [PATCH 148/207] Document X11 WM_CLASS hint behavior Fixes #2180 (cherry picked from commit ed1d9e1ca75600d80f9956bc3de333987a777cfa) --- CONTRIBUTORS.md | 1 + docs/window.dox | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 835b788a..e0c0319a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -125,6 +125,7 @@ video tutorials. - lukect - Tristam MacDonald - Hans Mackowiak + - Ramiro Magno - Дмитри Малышев - Zbigniew Mandziejewicz - Adam Marcus diff --git a/docs/window.dox b/docs/window.dox index 2fcf11f8..a0b4be65 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -471,7 +471,8 @@ should also declare this in its `Info.plist` by setting the @anchor GLFW_X11_CLASS_NAME_hint @anchor GLFW_X11_INSTANCE_NAME_hint __GLFW_X11_CLASS_NAME__ and __GLFW_X11_INSTANCE_NAME__ specifies the desired -ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. +ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. Both +hints need to be set to something other than an empty string for them to take effect. These are set with @ref glfwWindowHintString. From 05e28537a3da63a4fb91e37b865bdd5531c48af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 13 Sep 2022 22:01:38 +0200 Subject: [PATCH 149/207] Remove Doxyfile tags deprecated by Doxygen 1.9.5 (cherry picked from commit d299d9f78857e921b66bdab42c7ea27fe2e31810) --- docs/Doxyfile.in | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index 482b0285..a24ed015 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -1167,14 +1167,6 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not @@ -1616,14 +1608,6 @@ EXTERNAL_GROUPS = YES # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. @@ -1645,20 +1629,6 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. @@ -1800,14 +1770,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) From c7a53338733fad040814fb5d6d9180921e7a107b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 11 Apr 2021 21:26:27 +0200 Subject: [PATCH 150/207] Add window surface creation to glfwinfo The glfwinfo tool now attempts Vulkan surface creation via glfwCreateWindowSurface and reports the results. (cherry picked from commit 0beadfdc667622d59b173ccce8674dc1ff12bb90) --- tests/glfwinfo.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index f681e0a5..e3163698 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -753,6 +753,17 @@ int main(int argc, char** argv) if (list_extensions) list_context_extensions(client, major, minor); + glfwDestroyWindow(window); + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + + window = glfwCreateWindow(200, 200, "Version", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + printf("Vulkan loader: %s\n", glfwVulkanSupported() ? "available" : "missing"); @@ -851,6 +862,19 @@ int main(int argc, char** argv) exit(EXIT_FAILURE); } + if (re) + { + VkSurfaceKHR surface = VK_NULL_HANDLE; + + if (glfwCreateWindowSurface(instance, window, NULL, &surface) == VK_SUCCESS) + { + printf("Vulkan window surface created successfully\n"); + vkDestroySurfaceKHR(instance, surface, NULL); + } + else + printf("Failed to create Vulkan window surface\n"); + } + free((void*) re); gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, instance); @@ -937,6 +961,8 @@ int main(int argc, char** argv) vkDestroyInstance(instance, NULL); } + glfwDestroyWindow(window); + glfwTerminate(); exit(EXIT_SUCCESS); } From b06a91e92bd1e4f0bb5109206cee27f42f965b88 Mon Sep 17 00:00:00 2001 From: Takuro Ashie Date: Fri, 16 Dec 2022 21:40:36 +0900 Subject: [PATCH 151/207] Wayland: Fix wrong array size for _GLFWofferWayland Closes #2225 (cherry picked from commit 41d8da1cea55732867b5c3a7159215071b87b790) --- src/wl_window.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wl_window.c b/src/wl_window.c index b1f47804..6330bdba 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1678,7 +1678,8 @@ static void dataDeviceHandleDataOffer(void* userData, struct wl_data_offer* offer) { _GLFWofferWayland* offers = - realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1); + realloc(_glfw.wl.offers, + sizeof(_GLFWofferWayland) * (_glfw.wl.offerCount + 1)); if (!offers) { _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); From 4a33051456083a50cfe282bf50696bd8d667fbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 16 Dec 2022 13:44:59 +0100 Subject: [PATCH 152/207] Update change log and add credit Related to #2225 This was adapted to 3.3-stable from 57cbded0760a50b9039ee0cb3f3c14f60145567c. --- CONTRIBUTORS.md | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e0c0319a..e078fa03 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -8,6 +8,7 @@ video tutorials. - Bobyshev Alexander - Laurent Aphecetche - Matt Arsenault + - Takuro Ashie - ashishgamedev - David Avedissian - Keith Bauer diff --git a/README.md b/README.md index ea830772..75251fef 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Wayland] Disabled alpha channel for opaque windows on systems lacking `EGL_EXT_present_opaque` (#1895) + - [Wayland] Bugfix: Buffer would overrun when storing received drag offer (#2225) - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) [EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL - [GLX] Added loading of glvnd `libGLX.so.0` where available From 71dfc3f65c945dcd97c212eaceb76be46daa5f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 26 Jan 2023 18:41:46 +0100 Subject: [PATCH 153/207] Add support for manually running build workflow (cherry picked from commit 8f470597d625ae28758c16b4293dd42d63e8a83a) --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b09e0f3..fc0d6c3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,7 @@ on: pull_request: push: branches: [ ci, master, latest, 3.3-stable ] + workflow_dispatch: permissions: statuses: write contents: read From 1b4e126dc091e69a7742ae3048b08e8d90ae275a Mon Sep 17 00:00:00 2001 From: Juan Ramos Date: Sat, 21 Jan 2023 11:30:56 -0700 Subject: [PATCH 154/207] Remove CMAKE_LEGACY_CYGWIN_WIN32 CMake option This was needed for compatibility with CMake versions before 2.8.4. Related to #2256 (cherry picked from commit 30b91c8b60a29d2c921bee494542b980710b59a7) --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65c98ed0..50b62e5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR) project(GLFW VERSION 3.3.9 LANGUAGES C) -set(CMAKE_LEGACY_CYGWIN_WIN32 OFF) - if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) endif() From 2178c3e536e96a239d12c310c99574ee4536dd2c Mon Sep 17 00:00:00 2001 From: Juan Ramos Date: Sat, 21 Jan 2023 11:18:35 -0700 Subject: [PATCH 155/207] Update to actions/checkout@v3 Fixes the following CI warning: "Node.js 12 actions are deprecated. Please update the following actions to use Node.js 16: actions/checkout@v2..." Closes #2255 (cherry picked from commit 9a87635686c7fcb63ca63149c5b179b85a53a725) --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc0d6c3e..79a1dd5a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: CC: clang CFLAGS: -Werror steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | sudo apt update @@ -39,7 +39,7 @@ jobs: CC: clang CFLAGS: -Werror steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | sudo apt update @@ -85,7 +85,7 @@ jobs: CFLAGS: -Werror MACOSX_DEPLOYMENT_TARGET: 10.8 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Configure static library run: cmake -S . -B build-static @@ -103,7 +103,7 @@ jobs: env: CFLAGS: /WX steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Configure static library run: cmake -S . -B build-static -G "Visual Studio 17 2022" From ba80e23dab2ac320dad3d7165f27d4aec9078939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 8 Jan 2023 16:53:21 +0100 Subject: [PATCH 156/207] Wayland: Pick more plausible default cursor size This is not intended as a replacement for actually querying the desktop for the correct size, but it appears to be a better fallback value. (cherry picked from commit 82e77dbff4a6695fb8ed3f3e9ed58c4814dd62b4) --- src/wl_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wl_init.c b/src/wl_init.c index f8f4f752..359bfe0a 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -302,7 +302,7 @@ static void createKeyTables(void) static GLFWbool loadCursorTheme(void) { - int cursorSize = 32; + int cursorSize = 16; const char* sizeString = getenv("XCURSOR_SIZE"); if (sizeString) From 85224477924a661d6cf422d8eaa0babe0d964377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 28 Dec 2022 23:35:06 +0100 Subject: [PATCH 157/207] Wayland: Simplify test for fallback decorations The GLFW fallback decorations only exist when the window is visible, decorated and in windowed mode. (cherry picked from commit 228428fa4f0a6efc0504f03c0b7f12d8a997a6f7) --- src/wl_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wl_window.c b/src/wl_window.c index 6330bdba..f71f1574 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2060,7 +2060,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom) { - if (window->decorated && !window->monitor && window->wl.decorations.top.surface) + if (window->wl.decorations.top.surface) { if (top) *top = GLFW_CAPTION_HEIGHT; From ba99e20f6ab4d3281f985d2a144a5073b706b04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 20 Dec 2022 18:34:08 +0100 Subject: [PATCH 158/207] Wayland: Fix decorations not always being created If a window was initially fullscreen then it would not get an XDG decoration object. If the window was later switched to windowed mode it would then get fallback decorations instead of XDG ones. (cherry picked from commit 735fc101f5f690370b8943116e183b5b032356e3) --- src/wl_window.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index f71f1574..3bf1acb9 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -670,30 +670,30 @@ static GLFWbool createShellObjects(_GLFWwindow* window) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); setIdleInhibitor(window, GLFW_FALSE); + } - if (_glfw.wl.decorationManager) - { - window->wl.xdg.decoration = - zxdg_decoration_manager_v1_get_toplevel_decoration( - _glfw.wl.decorationManager, window->wl.xdg.toplevel); - zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, - &xdgDecorationListener, - window); + if (_glfw.wl.decorationManager) + { + window->wl.xdg.decoration = + zxdg_decoration_manager_v1_get_toplevel_decoration( + _glfw.wl.decorationManager, window->wl.xdg.toplevel); + zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, + &xdgDecorationListener, + window); - uint32_t mode; + uint32_t mode; - if (window->decorated) - mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; - else - mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - - zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); - } + if (window->decorated) + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; else - { - if (window->decorated) - createFallbackDecorations(window); - } + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + + zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); + } + else + { + if (window->decorated && !window->monitor) + createFallbackDecorations(window); } if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) From a6e3efbafc4c6d498eae4493f4296952fae7fbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 8 Jan 2023 22:12:56 +0100 Subject: [PATCH 159/207] Wayland: Fix some missing window refresh events (cherry picked from commit 8397b39afa30df18eeec0453acca3510fe160dd7) --- src/wl_window.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/wl_window.c b/src/wl_window.c index 3bf1acb9..5c516e73 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -397,6 +397,9 @@ void _glfwUpdateContentScaleWayland(_GLFWwindow* window) wl_surface_set_buffer_scale(window->wl.surface, maxScale); _glfwInputWindowContentScale(window, maxScale, maxScale); resizeWindow(window); + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } @@ -1990,6 +1993,9 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) window->wl.width = width; window->wl.height = height; resizeWindow(window); + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } @@ -2043,6 +2049,9 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, window->wl.width = window->wl.height * targetRatio; resizeWindow(window); + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } From 1de73c0dc545448dd40829a665c393fab19a5a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 8 Jan 2023 22:13:45 +0100 Subject: [PATCH 160/207] Wayland: Emit size event when setting aspect ratio (cherry picked from commit c1a79c1c41456a6fb0d2490a449eb4b2e0144302) --- src/wl_window.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 5c516e73..123039dd 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2039,17 +2039,26 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, if (window->wl.maximized || window->wl.fullscreen) return; + int width = window->wl.width, height = window->wl.height; + if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) { - const float aspectRatio = (float) window->wl.width / (float) window->wl.height; + const float aspectRatio = (float) width / (float) height; const float targetRatio = (float) numer / (float) denom; if (aspectRatio < targetRatio) - window->wl.height = window->wl.width / targetRatio; + height /= targetRatio; else if (aspectRatio > targetRatio) - window->wl.width = window->wl.height * targetRatio; + width *= targetRatio; + } + if (width != window->wl.width || height != window->wl.height) + { + window->wl.width = width; + window->wl.height = height; resizeWindow(window); + _glfwInputWindowSize(window, width, height); + if (window->wl.visible) _glfwInputWindowDamage(window); } From a29b5f38c6b93ee1948654303a2758a470078009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 3 Nov 2022 20:54:32 +0100 Subject: [PATCH 161/207] Wayland: Stop manually tracking interface versions This is already tracked by the proxies we care about. (cherry picked from commit 4cf510511ca067af7c028c98b2cb90695199052f) --- src/wl_init.c | 8 +++----- src/wl_platform.h | 3 --- src/wl_window.c | 5 ++++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 359bfe0a..90ec449f 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -61,10 +61,9 @@ static void registryHandleGlobal(void* userData, { if (strcmp(interface, "wl_compositor") == 0) { - _glfw.wl.compositorVersion = _glfw_min(3, version); _glfw.wl.compositor = wl_registry_bind(registry, name, &wl_compositor_interface, - _glfw.wl.compositorVersion); + _glfw_min(3, version)); } else if (strcmp(interface, "wl_subcompositor") == 0) { @@ -84,10 +83,9 @@ static void registryHandleGlobal(void* userData, { if (!_glfw.wl.seat) { - _glfw.wl.seatVersion = _glfw_min(4, version); _glfw.wl.seat = wl_registry_bind(registry, name, &wl_seat_interface, - _glfw.wl.seatVersion); + _glfw_min(4, version)); _glfwAddSeatListenerWayland(_glfw.wl.seat); } } @@ -460,7 +458,7 @@ int _glfwPlatformInit(void) _glfwInitTimerPOSIX(); #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION - if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) + if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { _glfw.wl.keyRepeatTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); diff --git a/src/wl_platform.h b/src/wl_platform.h index e5749660..8e5714bb 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -257,9 +257,6 @@ typedef struct _GLFWlibraryWayland _GLFWwindow* dragFocus; uint32_t dragSerial; - int compositorVersion; - int seatVersion; - struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorThemeHiDPI; struct wl_surface* cursorSurface; diff --git a/src/wl_window.c b/src/wl_window.c index 123039dd..e4335295 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -381,8 +381,11 @@ static void resizeWindow(_GLFWwindow* window) void _glfwUpdateContentScaleWayland(_GLFWwindow* window) { - if (_glfw.wl.compositorVersion < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + if (wl_compositor_get_version(_glfw.wl.compositor) < + WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + { return; + } // Get the scale factor from the highest scale monitor. int maxScale = 1; From 677fbb0f8246a259e3ed4f413768edd75821a034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 3 Nov 2022 20:58:15 +0100 Subject: [PATCH 162/207] Wayland: Remove duplicate setting of user data The surface user data is already set by wl_surface_add_listener. (cherry picked from commit 6d9083af03d04996829b02316770ad755fb6252c) --- src/wl_window.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index e4335295..fc5ea2d6 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -770,8 +770,6 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, &surfaceListener, window); - wl_surface_set_user_data(window->wl.surface, window); - window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; window->wl.scale = 1; From 5ac970120a5d276692e3f931db4a37f3d73ebdc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 3 Nov 2022 21:51:29 +0100 Subject: [PATCH 163/207] Wayland: Use tags to verify proxy ownership This is in preparation for adding support for libdecor, which creates its own proxies on our display. It will likely also be helpful to some people using native access on Wayland. This is partly based on the implementation of libdecor support in PR #1693 by @ christianrauch. (cherry picked from commit 91c837ace563cb2bf188dc8ac8e0ae60f616ffe3) --- src/wl_init.c | 2 ++ src/wl_monitor.c | 1 + src/wl_platform.h | 2 ++ src/wl_window.c | 26 ++++++++++++++++++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 90ec449f..3f359e81 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -341,6 +341,8 @@ int _glfwPlatformInit(void) _glfw.wl.keyRepeatTimerfd = -1; _glfw.wl.cursorTimerfd = -1; + _glfw.wl.tag = glfwGetVersionString(); + _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0"); if (!_glfw.wl.cursor.handle) { diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 99de8933..4792fd6b 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -187,6 +187,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) monitor->wl.output = output; monitor->wl.name = name; + wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag); wl_output_add_listener(output, &outputListener, monitor); } diff --git a/src/wl_platform.h b/src/wl_platform.h index 8e5714bb..ade4454a 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -257,6 +257,8 @@ typedef struct _GLFWlibraryWayland _GLFWwindow* dragFocus; uint32_t dragSerial; + const char* tag; + struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorThemeHiDPI; struct wl_surface* cursorSurface; diff --git a/src/wl_window.c b/src/wl_window.c index fc5ea2d6..4efef7b6 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -238,6 +238,7 @@ static void createFallbackDecoration(_GLFWdecorationWayland* decoration, int width, int height) { decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor); + wl_proxy_set_tag((struct wl_proxy*) decoration->surface, &_glfw.wl.tag); decoration->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, decoration->surface, parent); @@ -410,6 +411,9 @@ static void surfaceHandleEnter(void* userData, struct wl_surface* surface, struct wl_output* output) { + if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag) + return; + _GLFWwindow* window = userData; _GLFWmonitor* monitor = wl_output_get_user_data(output); @@ -430,6 +434,9 @@ static void surfaceHandleLeave(void* userData, struct wl_surface* surface, struct wl_output* output) { + if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag) + return; + _GLFWwindow* window = userData; _GLFWmonitor* monitor = wl_output_get_user_data(output); GLFWbool found; @@ -766,6 +773,7 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, return GLFW_FALSE; } + wl_proxy_set_tag((struct wl_proxy*) window->wl.surface, &_glfw.wl.tag); wl_surface_add_listener(window->wl.surface, &surfaceListener, window); @@ -1099,6 +1107,9 @@ static void pointerHandleEnter(void* userData, if (!surface) return; + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + _GLFWdecorationSideWayland focus = mainWindow; _GLFWwindow* window = wl_surface_get_user_data(surface); if (!window) @@ -1124,8 +1135,13 @@ static void pointerHandleLeave(void* userData, uint32_t serial, struct wl_surface* surface) { - _GLFWwindow* window = _glfw.wl.pointerFocus; + if (!surface) + return; + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + + _GLFWwindow* window = _glfw.wl.pointerFocus; if (!window) return; @@ -1719,7 +1735,10 @@ static void dataDeviceHandleEnter(void* userData, _GLFWwindow* window = NULL; if (surface) - window = wl_surface_get_user_data(surface); + { + if (wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag) + window = wl_surface_get_user_data(surface); + } if (window && _glfw.wl.offers[i].text_uri_list) { @@ -1734,6 +1753,9 @@ static void dataDeviceHandleEnter(void* userData, } } + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + if (_glfw.wl.dragOffer) wl_data_offer_accept(offer, serial, "text/uri-list"); else From e5d19c9fac8e0830c8e3e5dda45d96ac90bb3bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 8 Nov 2022 20:33:29 +0100 Subject: [PATCH 164/207] Wayland: Simplify per-window ouput scales tracking This replaces (one case of) manual management of weak links between windows and monitors, both objects with complex life times, with wl_object pointers used as opaque key values. (cherry picked from commit efa9297a41fb88b1c34ea3835d16463607e7a9a7) --- src/wl_monitor.c | 13 ++++++----- src/wl_platform.h | 16 +++++++++---- src/wl_window.c | 58 ++++++++++++++++++++++++----------------------- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 4792fd6b..6f785a31 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -110,14 +110,15 @@ static void outputHandleScale(void* userData, { struct _GLFWmonitor* monitor = userData; - monitor->wl.scale = factor; + monitor->wl.contentScale = factor; for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) { - for (int i = 0; i < window->wl.monitorsCount; i++) + for (int i = 0; i < window->wl.scaleCount; i++) { - if (window->wl.monitors[i] == monitor) + if (window->wl.scales[i].output == monitor->wl.output) { + window->wl.scales[i].factor = monitor->wl.contentScale; _glfwUpdateContentScaleWayland(window); break; } @@ -183,7 +184,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) // The actual name of this output will be set in the geometry handler _GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0); - monitor->wl.scale = 1; + monitor->wl.contentScale = 1; monitor->wl.output = output; monitor->wl.name = name; @@ -214,9 +215,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, float* xscale, float* yscale) { if (xscale) - *xscale = (float) monitor->wl.scale; + *xscale = (float) monitor->wl.contentScale; if (yscale) - *yscale = (float) monitor->wl.scale; + *yscale = (float) monitor->wl.contentScale; } void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, diff --git a/src/wl_platform.h b/src/wl_platform.h index ade4454a..2d4c77c6 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -169,6 +169,12 @@ typedef struct _GLFWofferWayland GLFWbool text_uri_list; } _GLFWofferWayland; +typedef struct _GLFWscaleWayland +{ + struct wl_output* output; + int factor; +} _GLFWscaleWayland; + // Wayland-specific per-window data // typedef struct _GLFWwindowWayland @@ -209,10 +215,10 @@ typedef struct _GLFWwindowWayland // We need to track the monitors the window spans on to calculate the // optimal scaling factor. - int scale; - _GLFWmonitor** monitors; - int monitorsCount; - int monitorsSize; + int contentScale; + _GLFWscaleWayland* scales; + int scaleCount; + int scaleSize; struct zwp_relative_pointer_v1* relativePointer; struct zwp_locked_pointer_v1* lockedPointer; @@ -346,7 +352,7 @@ typedef struct _GLFWmonitorWayland int x; int y; - int scale; + int contentScale; } _GLFWmonitorWayland; // Wayland-specific per-cursor data diff --git a/src/wl_window.c b/src/wl_window.c index 4efef7b6..336944fb 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -346,7 +346,7 @@ static void setContentAreaOpaque(_GLFWwindow* window) static void resizeWindow(_GLFWwindow* window) { - int scale = window->wl.scale; + int scale = window->wl.contentScale; int scaledWidth = window->wl.width * scale; int scaledHeight = window->wl.height * scale; @@ -391,13 +391,13 @@ void _glfwUpdateContentScaleWayland(_GLFWwindow* window) // Get the scale factor from the highest scale monitor. int maxScale = 1; - for (int i = 0; i < window->wl.monitorsCount; i++) - maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale); + for (int i = 0; i < window->wl.scaleCount; i++) + maxScale = _glfw_max(window->wl.scales[i].factor, maxScale); // Only change the framebuffer size if the scale changed. - if (window->wl.scale != maxScale) + if (window->wl.contentScale != maxScale) { - window->wl.scale = maxScale; + window->wl.contentScale = maxScale; wl_surface_set_buffer_scale(window->wl.surface, maxScale); _glfwInputWindowContentScale(window, maxScale, maxScale); resizeWindow(window); @@ -416,16 +416,20 @@ static void surfaceHandleEnter(void* userData, _GLFWwindow* window = userData; _GLFWmonitor* monitor = wl_output_get_user_data(output); + if (!window || !monitor) + return; - if (window->wl.monitorsCount + 1 > window->wl.monitorsSize) + if (window->wl.scaleCount + 1 > window->wl.scaleSize) { - ++window->wl.monitorsSize; - window->wl.monitors = - realloc(window->wl.monitors, - window->wl.monitorsSize * sizeof(_GLFWmonitor*)); + window->wl.scaleSize++; + window->wl.scales = + realloc(window->wl.scales, + window->wl.scaleSize * sizeof(_GLFWscaleWayland)); } - window->wl.monitors[window->wl.monitorsCount++] = monitor; + window->wl.scaleCount++; + window->wl.scales[window->wl.scaleCount - 1].factor = monitor->wl.contentScale; + window->wl.scales[window->wl.scaleCount - 1].output = output; _glfwUpdateContentScaleWayland(window); } @@ -438,18 +442,16 @@ static void surfaceHandleLeave(void* userData, return; _GLFWwindow* window = userData; - _GLFWmonitor* monitor = wl_output_get_user_data(output); - GLFWbool found; - int i; - for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i) + for (int i = 0; i < window->wl.scaleCount; i++) { - if (monitor == window->wl.monitors[i]) - found = GLFW_TRUE; - if (found) - window->wl.monitors[i] = window->wl.monitors[i + 1]; + if (window->wl.scales[i].output == output) + { + window->wl.scales[i] = window->wl.scales[window->wl.scaleCount - 1]; + window->wl.scaleCount--; + break; + } } - window->wl.monitors[--window->wl.monitorsCount] = NULL; _glfwUpdateContentScaleWayland(window); } @@ -780,7 +782,7 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; - window->wl.scale = 1; + window->wl.contentScale = 1; window->wl.title = _glfw_strdup(wndconfig->title); window->wl.maximized = wndconfig->maximized; @@ -806,7 +808,7 @@ static void setCursorImage(_GLFWwindow* window, buffer = cursorWayland->buffer; else { - if (window->wl.scale > 1 && cursorWayland->cursorHiDPI) + if (window->wl.contentScale > 1 && cursorWayland->cursorHiDPI) { wlCursor = cursorWayland->cursorHiDPI; scale = 2; @@ -1162,7 +1164,7 @@ static void setCursor(_GLFWwindow* window, const char* name) struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; int scale = 1; - if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI) + if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI) { // We only support up to scale=2 for now, since libwayland-cursor // requires us to load a different theme for each size. @@ -1961,7 +1963,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) wl_surface_destroy(window->wl.surface); free(window->wl.title); - free(window->wl.monitors); + free(window->wl.scales); } void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) @@ -2092,9 +2094,9 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, { _glfwPlatformGetWindowSize(window, width, height); if (width) - *width *= window->wl.scale; + *width *= window->wl.contentScale; if (height) - *height *= window->wl.scale; + *height *= window->wl.contentScale; } void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, @@ -2118,9 +2120,9 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, float* xscale, float* yscale) { if (xscale) - *xscale = (float) window->wl.scale; + *xscale = (float) window->wl.contentScale; if (yscale) - *yscale = (float) window->wl.scale; + *yscale = (float) window->wl.contentScale; } void _glfwPlatformIconifyWindow(_GLFWwindow* window) From 95b35c43c252c60bd8e01e8a49535a6cffa838fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 1 Dec 2022 13:10:07 +0100 Subject: [PATCH 165/207] Wayland: Clean up enum value names (cherry picked from commit 39f0e8622898f9533f43aa805ac0667945c1c26e) --- src/wl_platform.h | 10 +++++----- src/wl_window.c | 42 +++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index 2d4c77c6..63b25196 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -148,11 +148,11 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st typedef enum _GLFWdecorationSideWayland { - mainWindow, - topDecoration, - leftDecoration, - rightDecoration, - bottomDecoration, + GLFW_MAIN_WINDOW, + GLFW_TOP_DECORATION, + GLFW_LEFT_DECORATION, + GLFW_RIGHT_DECORATION, + GLFW_BOTTOM_DECORATION } _GLFWdecorationSideWayland; typedef struct _GLFWdecorationWayland diff --git a/src/wl_window.c b/src/wl_window.c index 336944fb..f457fbe0 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -844,7 +844,7 @@ static void incrementCursorImage(_GLFWwindow* window) { _GLFWcursor* cursor; - if (!window || window->wl.decorations.focus != mainWindow) + if (!window || window->wl.decorations.focus != GLFW_MAIN_WINDOW) return; cursor = window->wl.currentCursor; @@ -1075,22 +1075,22 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, { if (surface == window->wl.decorations.top.surface) { - *which = topDecoration; + *which = GLFW_TOP_DECORATION; break; } if (surface == window->wl.decorations.left.surface) { - *which = leftDecoration; + *which = GLFW_LEFT_DECORATION; break; } if (surface == window->wl.decorations.right.surface) { - *which = rightDecoration; + *which = GLFW_RIGHT_DECORATION; break; } if (surface == window->wl.decorations.bottom.surface) { - *which = bottomDecoration; + *which = GLFW_BOTTOM_DECORATION; break; } window = window->next; @@ -1112,7 +1112,7 @@ static void pointerHandleEnter(void* userData, if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) return; - _GLFWdecorationSideWayland focus = mainWindow; + _GLFWdecorationSideWayland focus = GLFW_MAIN_WINDOW; _GLFWwindow* window = wl_surface_get_user_data(surface); if (!window) { @@ -1222,29 +1222,29 @@ static void pointerHandleMotion(void* userData, switch (window->wl.decorations.focus) { - case mainWindow: + case GLFW_MAIN_WINDOW: _glfw.wl.cursorPreviousName = NULL; _glfwInputCursorPos(window, x, y); return; - case topDecoration: + case GLFW_TOP_DECORATION: if (y < GLFW_BORDER_SIZE) cursorName = "n-resize"; else cursorName = "left_ptr"; break; - case leftDecoration: + case GLFW_LEFT_DECORATION: if (y < GLFW_BORDER_SIZE) cursorName = "nw-resize"; else cursorName = "w-resize"; break; - case rightDecoration: + case GLFW_RIGHT_DECORATION: if (y < GLFW_BORDER_SIZE) cursorName = "ne-resize"; else cursorName = "e-resize"; break; - case bottomDecoration: + case GLFW_BOTTOM_DECORATION: if (x < GLFW_BORDER_SIZE) cursorName = "sw-resize"; else if (x > window->wl.width + GLFW_BORDER_SIZE) @@ -1277,9 +1277,9 @@ static void pointerHandleButton(void* userData, { switch (window->wl.decorations.focus) { - case mainWindow: + case GLFW_MAIN_WINDOW: break; - case topDecoration: + case GLFW_TOP_DECORATION: if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP; else @@ -1287,19 +1287,19 @@ static void pointerHandleButton(void* userData, xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); } break; - case leftDecoration: + case GLFW_LEFT_DECORATION: if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; break; - case rightDecoration: + case GLFW_RIGHT_DECORATION: if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; break; - case bottomDecoration: + case GLFW_BOTTOM_DECORATION: if (window->wl.cursorPosX < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE) @@ -1319,7 +1319,8 @@ static void pointerHandleButton(void* userData, } else if (button == BTN_RIGHT) { - if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel) + if (window->wl.decorations.focus != GLFW_MAIN_WINDOW && + window->wl.xdg.toplevel) { xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, _glfw.wl.seat, serial, @@ -1330,7 +1331,7 @@ static void pointerHandleButton(void* userData, } // Don’t pass the button to the user if it was related to a decoration. - if (window->wl.decorations.focus != mainWindow) + if (window->wl.decorations.focus != GLFW_MAIN_WINDOW) return; _glfw.wl.serial = serial; @@ -2555,8 +2556,11 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) // If we're not in the correct window just save the cursor // the next time the pointer enters the window the cursor will change - if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow) + if (window != _glfw.wl.pointerFocus || + window->wl.decorations.focus != GLFW_MAIN_WINDOW) + { return; + } // Update pointer lock to match cursor mode if (window->cursorMode == GLFW_CURSOR_DISABLED) From 1ad5df803239250c43e021f92fe87b738f231f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 28 Dec 2022 16:40:00 +0100 Subject: [PATCH 166/207] Wayland: Simplify decoration side detection This commit simplifies the detection of which element of a fallback decorated window the pointer has entered. Instead of looping through the list of windows, the user pointer of fallback decoration surfaces is set to the GLFW window object. (cherry picked from commit cd466cf9fd741a9ff704ce773f12dbfee8713640) --- src/wl_window.c | 78 +++++++++++++++---------------------------------- 1 file changed, 24 insertions(+), 54 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index f457fbe0..69d344aa 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -231,13 +231,15 @@ static GLFWbool waitForData(struct pollfd* fds, nfds_t count, double* timeout) } } -static void createFallbackDecoration(_GLFWdecorationWayland* decoration, +static void createFallbackDecoration(_GLFWwindow* window, + _GLFWdecorationWayland* decoration, struct wl_surface* parent, struct wl_buffer* buffer, int x, int y, int width, int height) { decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor); + wl_surface_set_user_data(decoration->surface, window); wl_proxy_set_tag((struct wl_proxy*) decoration->surface, &_glfw.wl.tag); decoration->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, @@ -268,19 +270,19 @@ static void createFallbackDecorations(_GLFWwindow* window) if (!window->wl.decorations.buffer) return; - createFallbackDecoration(&window->wl.decorations.top, window->wl.surface, + createFallbackDecoration(window, &window->wl.decorations.top, window->wl.surface, window->wl.decorations.buffer, 0, -GLFW_CAPTION_HEIGHT, window->wl.width, GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.left, window->wl.surface, + createFallbackDecoration(window, &window->wl.decorations.left, window->wl.surface, window->wl.decorations.buffer, -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.right, window->wl.surface, + createFallbackDecoration(window, &window->wl.decorations.right, window->wl.surface, window->wl.decorations.buffer, window->wl.width, -GLFW_CAPTION_HEIGHT, GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.bottom, window->wl.surface, + createFallbackDecoration(window, &window->wl.decorations.bottom, window->wl.surface, window->wl.decorations.buffer, -GLFW_BORDER_SIZE, window->wl.height, window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); @@ -1064,40 +1066,6 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime return string; } -static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, - _GLFWdecorationSideWayland* which) -{ - _GLFWdecorationSideWayland focus; - _GLFWwindow* window = _glfw.windowListHead; - if (!which) - which = &focus; - while (window) - { - if (surface == window->wl.decorations.top.surface) - { - *which = GLFW_TOP_DECORATION; - break; - } - if (surface == window->wl.decorations.left.surface) - { - *which = GLFW_LEFT_DECORATION; - break; - } - if (surface == window->wl.decorations.right.surface) - { - *which = GLFW_RIGHT_DECORATION; - break; - } - if (surface == window->wl.decorations.bottom.surface) - { - *which = GLFW_BOTTOM_DECORATION; - break; - } - window = window->next; - } - return window; -} - static void pointerHandleEnter(void* userData, struct wl_pointer* pointer, uint32_t serial, @@ -1112,16 +1080,19 @@ static void pointerHandleEnter(void* userData, if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) return; - _GLFWdecorationSideWayland focus = GLFW_MAIN_WINDOW; _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, &focus); - if (!window) - return; - } - window->wl.decorations.focus = focus; + if (surface == window->wl.decorations.top.surface) + window->wl.decorations.focus = GLFW_TOP_DECORATION; + else if (surface == window->wl.decorations.left.surface) + window->wl.decorations.focus = GLFW_LEFT_DECORATION; + else if (surface == window->wl.decorations.right.surface) + window->wl.decorations.focus = GLFW_RIGHT_DECORATION; + else if (surface == window->wl.decorations.bottom.surface) + window->wl.decorations.focus = GLFW_BOTTOM_DECORATION; + else + window->wl.decorations.focus = GLFW_MAIN_WINDOW; + _glfw.wl.serial = serial; _glfw.wl.pointerEnterSerial = serial; _glfw.wl.pointerFocus = window; @@ -1484,13 +1455,12 @@ static void keyboardHandleEnter(void* userData, if (!surface) return; + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, NULL); - if (!window) - return; - } + if (surface != window->wl.surface) + return; _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = window; @@ -1743,7 +1713,7 @@ static void dataDeviceHandleEnter(void* userData, window = wl_surface_get_user_data(surface); } - if (window && _glfw.wl.offers[i].text_uri_list) + if (surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list) { _glfw.wl.dragOffer = offer; _glfw.wl.dragFocus = window; From 0c2db4a23ead75961d61dac41accc5fc2fd23427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 27 Dec 2022 14:37:27 +0100 Subject: [PATCH 167/207] Wayland: Add initial support for libdecor This is partly based on the implementation of libdecor support in PR #1693 by @ christianrauch. Where available, the libdecor library is loaded at init and becomes the preferred method for window decorations. On compositors that support XDG decorations, libdecor in turn uses those. If not, libdecor has a plug-in archtecture and may load additional libraries to either use compositor-specific decorations or draw its own. If necessary, support for libdecor can be disabled with the GLFW_WAYLAND_LIBDECOR init hint. This is mostly in case some part of the dynamic loading or duplication of header material added here turns out to cause problems with future versions of libdecor-0.so.0. Fixes #1639 Closes #1693 Related to #1725 This was adapted to 3.3-stable from fbdb53b9ca457ab01675e20d9127cb62d8db88b8. --- README.md | 1 + docs/compat.dox | 8 ++ docs/intro.dox | 25 ++++ docs/news.dox | 13 ++ include/GLFW/glfw3.h | 8 ++ src/init.c | 8 +- src/internal.h | 3 + src/wl_init.c | 119 +++++++++++++++++ src/wl_platform.h | 153 ++++++++++++++++++++++ src/wl_window.c | 301 ++++++++++++++++++++++++++++++++++++++++--- 10 files changed, 620 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 75251fef..dd125530 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ information on what to include when reporting a bug. ## Changelog + - [Wayland] Added improved fallback window decorations via libdecor (#1639,#1693) - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Wayland] Disabled alpha channel for opaque windows on systems lacking `EGL_EXT_present_opaque` (#1895) diff --git a/docs/compat.dox b/docs/compat.dox index cf5b4e23..ceeff410 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -122,6 +122,14 @@ wayland-protocols 1.6, and mandatory at build time. If the running compositor does not support this protocol, the screensaver may start even for full screen windows. +GLFW uses the [libdecor library](https://gitlab.freedesktop.org/libdecor/libdecor) +for window decorations, where available. This in turn provides good quality +client-side decorations (drawn by the application) on desktop systems that do +not support server-side decorations (drawn by the window manager). On systems +that do not provide either libdecor or xdg-decoration, very basic window +decorations are provided. These do not include the window title or any caption +buttons. + GLFW uses the [xdg-decoration protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml) to request decorations to be drawn around its windows. This protocol is part diff --git a/docs/intro.dox b/docs/intro.dox index c5d1b930..57f86c01 100644 --- a/docs/intro.dox +++ b/docs/intro.dox @@ -102,6 +102,30 @@ a nib or manually, when the first window is created, which is when AppKit is initialized. Set this with @ref glfwInitHint. +@subsubsection init_hints_wayland Wayland specific init hints + +@anchor GLFW_WAYLAND_LIBDECOR_hint +__GLFW_WAYLAND_LIBDECOR__ specifies whether to use +[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) for window +decorations where available. Possible values are `GLFW_WAYLAND_PREFER_LIBDECOR` +and `GLFW_WAYLAND_DISABLE_LIBDECOR`. This is ignored on other platforms. + +@note This init hint was added in 3.3.9 and is not present in earlier patch releases. It +is safe to attempt to set this hint on earlier versions of GLFW 3.3 but it will emit +a harmless @ref GLFW_INVALID_ENUM error. If you need to avoid causing any errors, you can +check the library version first with @ref glfwGetVersion. + +@note To set this hint while also building against earlier versions of GLFW 3.3, you can +use the numerical constants directly. + +@note @code +int minor, patch; +glfwGetVersion(NULL, &minor, &patch); +if (minor > 3 || (minor == 3 && patch >= 9)) + glfwInitHint(0x00053001 /*GLFW_WAYLAND_LIBDECOR*/, 0x00038002 /*GLFW_WAYLAND_DISABLE_LIBDECOR*/); +@endcode + + @subsubsection init_hints_values Supported and default values Initialization hint | Default value | Supported values @@ -109,6 +133,7 @@ Initialization hint | Default value | Supported values @ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +@ref GLFW_WAYLAND_LIBDECOR | `GLFW_WAYLAND_PREFER_LIBDECOR` | `GLFW_WAYLAND_PREFER_LIBDECOR` or `GLFW_WAYLAND_DISABLE_LIBDECOR` @subsection intro_init_terminate Terminating GLFW diff --git a/docs/news.dox b/docs/news.dox index 3a7ce4dd..103224f5 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -37,6 +37,16 @@ SDK](https://vulkan.lunarg.com/). For more information see @ref vulkan_guide. +@subsubsection wayland_libdecor_33 Wayland libdecor decorations + +GLFW now supports improved fallback window decorations via +[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor). + +Support for libdecor can be toggled before GLFW is initialized with the +[GLFW_WAYLAND_LIBDECOR](@ref GLFW_WAYLAND_LIBDECOR_hint) init hint. It is +enabled by default. + + @subsubsection content_scale_33 Content scale queries for DPI-aware rendering GLFW now provides content scales for windows and monitors, i.e. the ratio @@ -443,6 +453,9 @@ Use Wayland or X11 instead. - @ref GLFWwindowmaximizefun - @ref GLFWwindowcontentscalefun - @ref GLFWgamepadstate + - @ref GLFW_WAYLAND_LIBDECOR + - @ref GLFW_WAYLAND_PREFER_LIBDECOR + - @ref GLFW_WAYLAND_DISABLE_LIBDECOR @subsubsection constants_33 New constants in version 3.3 diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 726d5e12..90fcaec5 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1063,6 +1063,9 @@ extern "C" { #define GLFW_EGL_CONTEXT_API 0x00036002 #define GLFW_OSMESA_CONTEXT_API 0x00036003 +#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001 +#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002 + /*! @defgroup shapes Standard cursor shapes * @brief Standard system cursor shapes. * @@ -1123,6 +1126,11 @@ extern "C" { * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint). */ #define GLFW_COCOA_MENUBAR 0x00051002 +/*! @brief Wayland specific init hint. + * + * Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint). + */ +#define GLFW_WAYLAND_LIBDECOR 0x00053001 /*! @} */ #define GLFW_DONT_CARE -1 diff --git a/src/init.c b/src/init.c index cfdd512d..b1af8e5c 100644 --- a/src/init.c +++ b/src/init.c @@ -54,7 +54,10 @@ static _GLFWinitconfig _glfwInitHints = { GLFW_TRUE, // macOS menu bar GLFW_TRUE // macOS bundle chdir - } + }, + { + GLFW_WAYLAND_PREFER_LIBDECOR // Wayland libdecor mode + }, }; // Terminate the library @@ -367,6 +370,9 @@ GLFWAPI void glfwInitHint(int hint, int value) case GLFW_COCOA_MENUBAR: _glfwInitHints.ns.menubar = value; return; + case GLFW_WAYLAND_LIBDECOR: + _glfwInitHints.wl.libdecorMode = value; + return; } _glfwInputError(GLFW_INVALID_ENUM, diff --git a/src/internal.h b/src/internal.h index 7734caa3..3f081bf3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -244,6 +244,9 @@ struct _GLFWinitconfig GLFWbool menubar; GLFWbool chdir; } ns; + struct { + int libdecorMode; + } wl; }; // Window configuration diff --git a/src/wl_init.c b/src/wl_init.c index 3f359e81..8b4b33e4 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -163,6 +163,20 @@ static const struct wl_registry_listener registryListener = registryHandleGlobalRemove }; +void libdecorHandleError(struct libdecor* context, + enum libdecor_error error, + const char* message) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: libdecor error %u: %s", + error, message); +} + +static const struct libdecor_interface libdecorInterface = +{ + libdecorHandleError +}; + // Create key code translation tables // static void createKeyTables(void) @@ -433,6 +447,93 @@ int _glfwPlatformInit(void) return GLFW_FALSE; } + if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR) + _glfw.wl.libdecor.handle = _glfw_dlopen("libdecor-0.so.0"); + + if (_glfw.wl.libdecor.handle) + { + _glfw.wl.libdecor.libdecor_new_ = (PFN_libdecor_new) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_new"); + _glfw.wl.libdecor.libdecor_unref_ = (PFN_libdecor_unref) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_unref"); + _glfw.wl.libdecor.libdecor_get_fd_ = (PFN_libdecor_get_fd) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_get_fd"); + _glfw.wl.libdecor.libdecor_dispatch_ = (PFN_libdecor_dispatch) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_dispatch"); + _glfw.wl.libdecor.libdecor_decorate_ = (PFN_libdecor_decorate) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_decorate"); + _glfw.wl.libdecor.libdecor_frame_unref_ = (PFN_libdecor_frame_unref) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unref"); + _glfw.wl.libdecor.libdecor_frame_set_app_id_ = (PFN_libdecor_frame_set_app_id) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_app_id"); + _glfw.wl.libdecor.libdecor_frame_set_title_ = (PFN_libdecor_frame_set_title) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_title"); + _glfw.wl.libdecor.libdecor_frame_set_minimized_ = (PFN_libdecor_frame_set_minimized) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_minimized"); + _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ = (PFN_libdecor_frame_set_fullscreen) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_fullscreen"); + _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ = (PFN_libdecor_frame_unset_fullscreen) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unset_fullscreen"); + _glfw.wl.libdecor.libdecor_frame_map_ = (PFN_libdecor_frame_map) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_map"); + _glfw.wl.libdecor.libdecor_frame_commit_ = (PFN_libdecor_frame_commit) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_commit"); + _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ = (PFN_libdecor_frame_set_min_content_size) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_min_content_size"); + _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ = (PFN_libdecor_frame_set_max_content_size) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_max_content_size"); + _glfw.wl.libdecor.libdecor_frame_set_maximized_ = (PFN_libdecor_frame_set_maximized) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_maximized"); + _glfw.wl.libdecor.libdecor_frame_unset_maximized_ = (PFN_libdecor_frame_unset_maximized) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unset_maximized"); + _glfw.wl.libdecor.libdecor_frame_set_capabilities_ = (PFN_libdecor_frame_set_capabilities) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_capabilities"); + _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ = (PFN_libdecor_frame_unset_capabilities) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities"); + _glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility"); + _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel"); + _glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_configuration_get_content_size"); + _glfw.wl.libdecor.libdecor_configuration_get_window_state_ = (PFN_libdecor_configuration_get_window_state) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_configuration_get_window_state"); + _glfw.wl.libdecor.libdecor_state_new_ = (PFN_libdecor_state_new) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_state_new"); + _glfw.wl.libdecor.libdecor_state_free_ = (PFN_libdecor_state_free) + _glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_state_free"); + + if (!_glfw.wl.libdecor.libdecor_new_ || + !_glfw.wl.libdecor.libdecor_unref_ || + !_glfw.wl.libdecor.libdecor_get_fd_ || + !_glfw.wl.libdecor.libdecor_dispatch_ || + !_glfw.wl.libdecor.libdecor_decorate_ || + !_glfw.wl.libdecor.libdecor_frame_unref_ || + !_glfw.wl.libdecor.libdecor_frame_set_app_id_ || + !_glfw.wl.libdecor.libdecor_frame_set_title_ || + !_glfw.wl.libdecor.libdecor_frame_set_minimized_ || + !_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ || + !_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ || + !_glfw.wl.libdecor.libdecor_frame_map_ || + !_glfw.wl.libdecor.libdecor_frame_commit_ || + !_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ || + !_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ || + !_glfw.wl.libdecor.libdecor_frame_set_maximized_ || + !_glfw.wl.libdecor.libdecor_frame_unset_maximized_ || + !_glfw.wl.libdecor.libdecor_frame_set_capabilities_ || + !_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ || + !_glfw.wl.libdecor.libdecor_frame_set_visibility_ || + !_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ || + !_glfw.wl.libdecor.libdecor_configuration_get_content_size_ || + !_glfw.wl.libdecor.libdecor_configuration_get_window_state_ || + !_glfw.wl.libdecor.libdecor_state_new_ || + !_glfw.wl.libdecor.libdecor_state_free_) + { + _glfw_dlclose(_glfw.wl.libdecor.handle); + memset(&_glfw.wl.libdecor, 0, sizeof(_glfw.wl.libdecor)); + } + } + _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); @@ -459,6 +560,15 @@ int _glfwPlatformInit(void) _glfwInitTimerPOSIX(); + if (_glfw.wl.libdecor.handle) + { + _glfw.wl.libdecor.context = libdecor_new(_glfw.wl.display, &libdecorInterface); + + // Allow libdecor to receive its globals before proceeding + if (_glfw.wl.libdecor.context) + libdecor_dispatch(_glfw.wl.libdecor.context, 1); + } + #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { @@ -503,6 +613,15 @@ void _glfwPlatformTerminate(void) _glfwTerminateEGL(); _glfwTerminateOSMesa(); + if (_glfw.wl.libdecor.context) + libdecor_unref(_glfw.wl.libdecor.context); + + if (_glfw.wl.libdecor.handle) + { + _glfw_dlclose(_glfw.wl.libdecor.handle); + _glfw.wl.libdecor.handle = NULL; + } + if (_glfw.wl.egl.handle) { _glfw_dlclose(_glfw.wl.egl.handle); diff --git a/src/wl_platform.h b/src/wl_platform.h index 63b25196..4392dced 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -29,6 +29,8 @@ #include #include +#include + typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef struct VkWaylandSurfaceCreateInfoKHR @@ -146,6 +148,122 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st #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 +struct libdecor; +struct libdecor_frame; +struct libdecor_state; +struct libdecor_configuration; + +enum libdecor_error +{ + LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE, + LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION, +}; + +enum libdecor_window_state +{ + LIBDECOR_WINDOW_STATE_NONE = 0, + LIBDECOR_WINDOW_STATE_ACTIVE = 1, + LIBDECOR_WINDOW_STATE_MAXIMIZED = 2, + LIBDECOR_WINDOW_STATE_FULLSCREEN = 4, + LIBDECOR_WINDOW_STATE_TILED_LEFT = 8, + LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16, + LIBDECOR_WINDOW_STATE_TILED_TOP = 32, + LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64 +}; + +enum libdecor_capabilities +{ + LIBDECOR_ACTION_MOVE = 1, + LIBDECOR_ACTION_RESIZE = 2, + LIBDECOR_ACTION_MINIMIZE = 4, + LIBDECOR_ACTION_FULLSCREEN = 8, + LIBDECOR_ACTION_CLOSE = 16 +}; + +struct libdecor_interface +{ + void (* error)(struct libdecor*,enum libdecor_error,const char*); + void (* reserved0)(void); + void (* reserved1)(void); + void (* reserved2)(void); + void (* reserved3)(void); + void (* reserved4)(void); + void (* reserved5)(void); + void (* reserved6)(void); + void (* reserved7)(void); + void (* reserved8)(void); + void (* reserved9)(void); +}; + +struct libdecor_frame_interface +{ + void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*); + void (* close)(struct libdecor_frame*,void*); + void (* commit)(struct libdecor_frame*,void*); + void (* dismiss_popup)(struct libdecor_frame*,const char*,void*); + void (* reserved0)(void); + void (* reserved1)(void); + void (* reserved2)(void); + void (* reserved3)(void); + void (* reserved4)(void); + void (* reserved5)(void); + void (* reserved6)(void); + void (* reserved7)(void); + void (* reserved8)(void); + void (* reserved9)(void); +}; + +typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*); +typedef void (* PFN_libdecor_unref)(struct libdecor*); +typedef int (* PFN_libdecor_get_fd)(struct libdecor*); +typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int); +typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*); +typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*); +typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*); +typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*); +typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*); +typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int); +typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int); +typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); +typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); +typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible); +typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*); +typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*); +typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*); +typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int); +typedef void (* PFN_libdecor_state_free)(struct libdecor_state*); +#define libdecor_new _glfw.wl.libdecor.libdecor_new_ +#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_ +#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_ +#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_ +#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_ +#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_ +#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_ +#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_ +#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_ +#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ +#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ +#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_ +#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_ +#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ +#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ +#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_ +#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_ +#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_ +#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ +#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_ +#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ +#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_ +#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_ +#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_ +#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_ + typedef enum _GLFWdecorationSideWayland { GLFW_MAIN_WINDOW, @@ -208,6 +326,11 @@ typedef struct _GLFWwindowWayland uint32_t decorationMode; } xdg; + struct { + struct libdecor_frame* frame; + int mode; + } libdecor; + _GLFWcursor* currentCursor; double cursorPosX, cursorPosY; @@ -340,6 +463,36 @@ typedef struct _GLFWlibraryWayland PFN_wl_egl_window_destroy window_destroy; PFN_wl_egl_window_resize window_resize; } egl; + + struct { + void* handle; + struct libdecor* context; + PFN_libdecor_new libdecor_new_; + PFN_libdecor_unref libdecor_unref_; + PFN_libdecor_get_fd libdecor_get_fd_; + PFN_libdecor_dispatch libdecor_dispatch_; + PFN_libdecor_decorate libdecor_decorate_; + PFN_libdecor_frame_unref libdecor_frame_unref_; + PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_; + PFN_libdecor_frame_set_title libdecor_frame_set_title_; + PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_; + PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_; + PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_; + PFN_libdecor_frame_map libdecor_frame_map_; + PFN_libdecor_frame_commit libdecor_frame_commit_; + PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_; + PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_; + PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_; + PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_; + PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_; + PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_; + PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_; + PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_; + PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_; + PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_; + PFN_libdecor_state_new libdecor_state_new_; + PFN_libdecor_state_free libdecor_state_free_; + } libdecor; } _GLFWlibraryWayland; // Wayland-specific per-monitor data diff --git a/src/wl_window.c b/src/wl_window.c index 69d344aa..c52a5923 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -486,7 +486,12 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable) // static void acquireMonitor(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + { + libdecor_frame_set_fullscreen(window->wl.libdecor.frame, + window->monitor->wl.output); + } + else if (window->wl.xdg.toplevel) { xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, window->monitor->wl.output); @@ -502,12 +507,15 @@ static void acquireMonitor(_GLFWwindow* window) // static void releaseMonitor(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_unset_fullscreen(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel); setIdleInhibitor(window, GLFW_FALSE); - if (window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) + if (!window->wl.libdecor.frame && + window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) { if (window->decorated) createFallbackDecorations(window); @@ -650,7 +658,187 @@ static const struct xdg_surface_listener xdgSurfaceListener = xdgSurfaceHandleConfigure }; -static GLFWbool createShellObjects(_GLFWwindow* window) +void libdecorFrameHandleConfigure(struct libdecor_frame* frame, + struct libdecor_configuration* config, + void* userData) +{ + _GLFWwindow* window = userData; + int width, height; + + enum libdecor_window_state windowState; + GLFWbool fullscreen, activated, maximized; + + if (libdecor_configuration_get_window_state(config, &windowState)) + { + fullscreen = (windowState & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0; + activated = (windowState & LIBDECOR_WINDOW_STATE_ACTIVE) != 0; + maximized = (windowState & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0; + } + else + { + fullscreen = window->wl.fullscreen; + activated = window->wl.activated; + maximized = window->wl.maximized; + } + + if (!libdecor_configuration_get_content_size(config, frame, &width, &height)) + { + width = window->wl.width; + height = window->wl.height; + } + + if (!maximized && !fullscreen) + { + if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) + { + const float aspectRatio = (float) width / (float) height; + const float targetRatio = (float) window->numer / (float) window->denom; + if (aspectRatio < targetRatio) + height = width / targetRatio; + else if (aspectRatio > targetRatio) + width = height * targetRatio; + } + } + + struct libdecor_state* frameState = libdecor_state_new(width, height); + libdecor_frame_commit(frame, frameState, config); + libdecor_state_free(frameState); + + if (window->wl.activated != activated) + { + window->wl.activated = activated; + if (!window->wl.activated) + { + if (window->monitor && window->autoIconify) + libdecor_frame_set_minimized(window->wl.libdecor.frame); + } + } + + if (window->wl.maximized != maximized) + { + window->wl.maximized = maximized; + _glfwInputWindowMaximize(window, window->wl.maximized); + } + + window->wl.fullscreen = fullscreen; + + GLFWbool damaged = GLFW_FALSE; + + if (!window->wl.visible) + { + window->wl.visible = GLFW_TRUE; + damaged = GLFW_TRUE; + } + + if (width != window->wl.width || height != window->wl.height) + { + window->wl.width = width; + window->wl.height = height; + resizeWindow(window); + + _glfwInputWindowSize(window, width, height); + damaged = GLFW_TRUE; + } + + if (damaged) + _glfwInputWindowDamage(window); + else + wl_surface_commit(window->wl.surface); +} + +void libdecorFrameHandleClose(struct libdecor_frame* frame, void* userData) +{ + _GLFWwindow* window = userData; + _glfwInputWindowCloseRequest(window); +} + +void libdecorFrameHandleCommit(struct libdecor_frame* frame, void* userData) +{ + _GLFWwindow* window = userData; + wl_surface_commit(window->wl.surface); +} + +void libdecorFrameHandleDismissPopup(struct libdecor_frame* frame, + const char* seatName, + void* userData) +{ +} + +static const struct libdecor_frame_interface libdecorFrameInterface = +{ + libdecorFrameHandleConfigure, + libdecorFrameHandleClose, + libdecorFrameHandleCommit, + libdecorFrameHandleDismissPopup +}; + +static GLFWbool createLibdecorFrame(_GLFWwindow* window) +{ + window->wl.libdecor.frame = libdecor_decorate(_glfw.wl.libdecor.context, + window->wl.surface, + &libdecorFrameInterface, + window); + if (!window->wl.libdecor.frame) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create libdecor frame"); + return GLFW_FALSE; + } + + if (strlen(window->wl.title)) + libdecor_frame_set_title(window->wl.libdecor.frame, window->wl.title); + + if (window->minwidth != GLFW_DONT_CARE && + window->minheight != GLFW_DONT_CARE) + { + libdecor_frame_set_min_content_size(window->wl.libdecor.frame, + window->minwidth, + window->minheight); + } + + if (window->maxwidth != GLFW_DONT_CARE && + window->maxheight != GLFW_DONT_CARE) + { + libdecor_frame_set_max_content_size(window->wl.libdecor.frame, + window->maxwidth, + window->maxheight); + } + + if (!window->resizable) + { + libdecor_frame_unset_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + + if (window->monitor) + { + // HACK: Allow libdecor to finish initialization of itself and its + // plugin so it will create the xdg_toplevel for the frame + // This needs to exist when setting the frame to fullscreen + while (!libdecor_frame_get_xdg_toplevel(window->wl.libdecor.frame)) + _glfwPlatformWaitEvents(); + + libdecor_frame_set_fullscreen(window->wl.libdecor.frame, + window->monitor->wl.output); + setIdleInhibitor(window, GLFW_TRUE); + } + else + { + if (window->wl.maximized) + libdecor_frame_set_maximized(window->wl.libdecor.frame); + + if (!window->decorated) + libdecor_frame_set_visibility(window->wl.libdecor.frame, false); + + setIdleInhibitor(window, GLFW_FALSE); + } + + libdecor_frame_map(window->wl.libdecor.frame); + wl_display_roundtrip(_glfw.wl.display); + return GLFW_TRUE; +} + +static GLFWbool createXdgShellObjects(_GLFWwindow* window) { window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase, window->wl.surface); @@ -743,14 +931,27 @@ static GLFWbool createShellObjects(_GLFWwindow* window) wl_surface_commit(window->wl.surface); wl_display_roundtrip(_glfw.wl.display); - return GLFW_TRUE; } +static GLFWbool createShellObjects(_GLFWwindow* window) +{ + if (_glfw.wl.libdecor.context) + { + if (createLibdecorFrame(window)) + return GLFW_TRUE; + } + + return createXdgShellObjects(window); +} + static void destroyShellObjects(_GLFWwindow* window) { destroyFallbackDecorations(window); + if (window->wl.libdecor.frame) + libdecor_frame_unref(window->wl.libdecor.frame); + if (window->wl.xdg.decoration) zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration); @@ -760,6 +961,7 @@ static void destroyShellObjects(_GLFWwindow* window) if (window->wl.xdg.surface) xdg_surface_destroy(window->wl.xdg.surface); + window->wl.libdecor.frame = NULL; window->wl.xdg.decoration = NULL; window->wl.xdg.decorationMode = 0; window->wl.xdg.toplevel = NULL; @@ -926,13 +1128,17 @@ static void inputText(_GLFWwindow* window, uint32_t scancode) static void handleEvents(double* timeout) { GLFWbool event = GLFW_FALSE; - struct pollfd fds[] = + struct pollfd fds[4] = { { wl_display_get_fd(_glfw.wl.display), POLLIN }, { _glfw.wl.keyRepeatTimerfd, POLLIN }, { _glfw.wl.cursorTimerfd, POLLIN }, + { -1, POLLIN } }; + if (_glfw.wl.libdecor.context) + fds[3].fd = libdecor_get_fd(_glfw.wl.libdecor.context); + while (!event) { while (wl_display_prepare_read(_glfw.wl.display) != 0) @@ -954,7 +1160,7 @@ static void handleEvents(double* timeout) return; } - if (!waitForData(fds, 3, timeout)) + if (!waitForData(fds, sizeof(fds) / sizeof(fds[0]), timeout)) { wl_display_cancel_read(_glfw.wl.display); return; @@ -999,6 +1205,9 @@ static void handleEvents(double* timeout) event = GLFW_TRUE; } } + + if (fds[3].revents & POLLIN) + libdecor_dispatch(_glfw.wl.libdecor.context, 0); } } @@ -1942,7 +2151,10 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) if (window->wl.title) free(window->wl.title); window->wl.title = _glfw_strdup(title); - if (window->wl.xdg.toplevel) + + if (window->wl.libdecor.frame) + libdecor_frame_set_title(window->wl.libdecor.frame, title); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_title(window->wl.xdg.toplevel, title); } @@ -1990,6 +2202,13 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) window->wl.height = height; resizeWindow(window); + if (window->wl.libdecor.frame) + { + struct libdecor_state* frameState = libdecor_state_new(width, height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + } + if (window->wl.visible) _glfwInputWindowDamage(window); } @@ -1999,7 +2218,20 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + { + if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) + minwidth = minheight = 0; + + if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE) + maxwidth = maxheight = 0; + + libdecor_frame_set_min_content_size(window->wl.libdecor.frame, + minwidth, minheight); + libdecor_frame_set_max_content_size(window->wl.libdecor.frame, + maxwidth, maxheight); + } + else if (window->wl.xdg.toplevel) { if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) minwidth = minheight = 0; @@ -2053,6 +2285,13 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, window->wl.height = height; resizeWindow(window); + if (window->wl.libdecor.frame) + { + struct libdecor_state* frameState = libdecor_state_new(width, height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + } + _glfwInputWindowSize(window, width, height); if (window->wl.visible) @@ -2098,7 +2337,9 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, void _glfwPlatformIconifyWindow(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_minimized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_minimized(window->wl.xdg.toplevel); } @@ -2115,7 +2356,9 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) if (window->wl.maximized) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_unset_maximized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); else window->wl.maximized = GLFW_FALSE; @@ -2125,7 +2368,9 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwPlatformMaximizeWindow(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_maximized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); else window->wl.maximized = GLFW_TRUE; @@ -2133,7 +2378,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window) { - if (!window->wl.xdg.toplevel) + if (!window->wl.libdecor.frame && !window->wl.xdg.toplevel) { // NOTE: The XDG/shell surface is created here so command-line applications // with off-screen windows do not appear in for example the Unity dock @@ -2224,14 +2469,34 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) { - // TODO - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window attribute setting not implemented yet"); + if (window->wl.libdecor.frame) + { + if (enabled) + { + libdecor_frame_set_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + else + { + libdecor_frame_unset_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + } + else + { + // TODO + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Window attribute setting not implemented yet"); + } } void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) { - if (window->wl.xdg.decoration) + if (window->wl.libdecor.frame) + { + libdecor_frame_set_visibility(window->wl.libdecor.frame, enabled); + } + else if (window->wl.xdg.decoration) { uint32_t mode; @@ -2242,7 +2507,7 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); } - else + else if (window->wl.xdg.toplevel) { if (enabled) createFallbackDecorations(window); From 06a2ed38ea09ae586da425f48ff38a976ce6c943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 26 Jan 2023 18:18:14 +0100 Subject: [PATCH 168/207] Fix glfwinfo output of Vulkan layer spec version (cherry picked from commit f27daa34ada52c67bf2f258e1135254dc4fa5b34) --- tests/glfwinfo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index e3163698..1f3b24b7 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -230,9 +230,10 @@ static void list_vulkan_instance_layers(void) for (i = 0; i < lp_count; i++) { - printf(" %s (v%u) \"%s\"\n", + printf(" %s (spec version %u.%u) \"%s\"\n", lp[i].layerName, - lp[i].specVersion >> 22, + VK_VERSION_MAJOR(lp[i].specVersion), + VK_VERSION_MINOR(lp[i].specVersion), lp[i].description); } @@ -259,9 +260,10 @@ static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice devi for (i = 0; i < lp_count; i++) { - printf(" %s (v%u) \"%s\"\n", + printf(" %s (spec version %u.%u) \"%s\"\n", lp[i].layerName, - lp[i].specVersion >> 22, + VK_VERSION_MAJOR(lp[i].specVersion), + VK_VERSION_MINOR(lp[i].specVersion), lp[i].description); } From 67d722788da5099a9ad9474f45357b952fac7cbf Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Fri, 7 Oct 2022 21:26:21 -0400 Subject: [PATCH 169/207] Wayland: Fix detection of joysticks after init Closes #2198 This was adapted to 3.3-stable from 0b94e1b29b5be16fc0979de8ac107e93ae440419 and 3fa2360720eeba1964df3c0ecf4b5df8648a8e52. --- README.md | 1 + src/wl_window.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index dd125530..525fefd6 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ information on what to include when reporting a bug. - [Wayland] Disabled alpha channel for opaque windows on systems lacking `EGL_EXT_present_opaque` (#1895) - [Wayland] Bugfix: Buffer would overrun when storing received drag offer (#2225) + - [Wayland] Bugfix: Joysticks connected after `glfwInit` were not detected (#2198) - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) [EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL - [GLX] Added loading of glvnd `libGLX.so.0` where available diff --git a/src/wl_window.c b/src/wl_window.c index c52a5923..88647a53 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1127,6 +1127,10 @@ static void inputText(_GLFWwindow* window, uint32_t scancode) static void handleEvents(double* timeout) { +#if defined(__linux__) + _glfwDetectJoystickConnectionLinux(); +#endif + GLFWbool event = GLFW_FALSE; struct pollfd fds[4] = { From 1d766c8b39936469280001a18f506c4efb394cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Apr 2023 22:47:18 +0200 Subject: [PATCH 170/207] Wayland: Fix fallback decorations emitting errors A GLFW_CURSOR_UNAVAILABLE error would be emitted each time the cursor moved over the fallback decorations if the standard cursor shape appropriate for that part was missing on the system. These errors served no useful purpose and have been removed. (cherry picked from commit 00a663dafd3bc214181a2987af1f5dac81e3b053) --- README.md | 1 + src/wl_window.c | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 525fefd6..5b8cd7a0 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ information on what to include when reporting a bug. `EGL_EXT_present_opaque` (#1895) - [Wayland] Bugfix: Buffer would overrun when storing received drag offer (#2225) - [Wayland] Bugfix: Joysticks connected after `glfwInit` were not detected (#2198) + - [Wayland] Bugfix: Fallback decorations emitted `GLFW_CURSOR_UNAVAILABLE` errors - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) [EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL - [GLX] Added loading of glvnd `libGLX.so.0` where available diff --git a/src/wl_window.c b/src/wl_window.c index 88647a53..a798c57e 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1358,11 +1358,8 @@ static void setCursor(_GLFWwindow* window, const char* name) cursor = wl_cursor_theme_get_cursor(theme, name); if (!cursor) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Standard cursor shape unavailable"); return; - } + // TODO: handle animated cursors too. image = cursor->images[0]; From c3f15da23a0b597eb8602770d11726fac6fffdf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Apr 2023 22:53:17 +0200 Subject: [PATCH 171/207] Wayland: Merge function called once This brings together the two halves of the cursor setting logic for the fallback decorations. (cherry picked from commit 6b48f2be97057cf436c6eb3059bbbfdcb5f66d7c) --- src/wl_window.c | 85 ++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index a798c57e..0ca0769c 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1339,48 +1339,6 @@ static void pointerHandleLeave(void* userData, _glfwInputCursorEnter(window, GLFW_FALSE); } -static void setCursor(_GLFWwindow* window, const char* name) -{ - struct wl_buffer* buffer; - struct wl_cursor* cursor; - struct wl_cursor_image* image; - struct wl_surface* surface = _glfw.wl.cursorSurface; - struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; - int scale = 1; - - if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI) - { - // We only support up to scale=2 for now, since libwayland-cursor - // requires us to load a different theme for each size. - scale = 2; - theme = _glfw.wl.cursorThemeHiDPI; - } - - cursor = wl_cursor_theme_get_cursor(theme, name); - if (!cursor) - return; - - // TODO: handle animated cursors too. - image = cursor->images[0]; - - if (!image) - return; - - buffer = wl_cursor_image_get_buffer(image); - if (!buffer) - return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, - surface, - image->hotspot_x / scale, - image->hotspot_y / scale); - wl_surface_set_buffer_scale(surface, scale); - wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); - wl_surface_commit(surface); - _glfw.wl.cursorPreviousName = name; -} - static void pointerHandleMotion(void* userData, struct wl_pointer* pointer, uint32_t time, @@ -1436,8 +1394,49 @@ static void pointerHandleMotion(void* userData, default: assert(0); } + if (_glfw.wl.cursorPreviousName != cursorName) - setCursor(window, cursorName); + { + struct wl_buffer* buffer; + struct wl_cursor* cursor; + struct wl_cursor_image* image; + struct wl_surface* surface = _glfw.wl.cursorSurface; + struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; + int scale = 1; + + if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI) + { + // We only support up to scale=2 for now, since libwayland-cursor + // requires us to load a different theme for each size. + scale = 2; + theme = _glfw.wl.cursorThemeHiDPI; + } + + cursor = wl_cursor_theme_get_cursor(theme, name); + if (!cursor) + return; + + // TODO: handle animated cursors too. + image = cursor->images[0]; + + if (!image) + return; + + buffer = wl_cursor_image_get_buffer(image); + if (!buffer) + return; + + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, + surface, + image->hotspot_x / scale, + image->hotspot_y / scale); + wl_surface_set_buffer_scale(surface, scale); + wl_surface_attach(surface, buffer, 0, 0); + wl_surface_damage(surface, 0, 0, + image->width, image->height); + wl_surface_commit(surface); + _glfw.wl.cursorPreviousName = name; + } } static void pointerHandleButton(void* userData, From 8da6223c905325e2e35a38e8313b83a1f4e1d60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Apr 2023 22:59:25 +0200 Subject: [PATCH 172/207] Wayland: Cleanup Update naming and declarations to current standard. (cherry picked from commit 3eaf1255b29fdf5c2895856c7be7d7185ef2b241) --- src/wl_window.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 0ca0769c..d3493d11 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1346,47 +1346,47 @@ static void pointerHandleMotion(void* userData, wl_fixed_t sy) { _GLFWwindow* window = _glfw.wl.pointerFocus; - const char* cursorName = NULL; - double x, y; - if (!window) return; if (window->cursorMode == GLFW_CURSOR_DISABLED) return; - x = wl_fixed_to_double(sx); - y = wl_fixed_to_double(sy); - window->wl.cursorPosX = x; - window->wl.cursorPosY = y; + + const double xpos = wl_fixed_to_double(sx); + const double ypos = wl_fixed_to_double(sy); + window->wl.cursorPosX = xpos; + window->wl.cursorPosY = ypos; + + const char* cursorName = NULL; switch (window->wl.decorations.focus) { case GLFW_MAIN_WINDOW: _glfw.wl.cursorPreviousName = NULL; - _glfwInputCursorPos(window, x, y); + _glfwInputCursorPos(window, xpos, ypos); return; case GLFW_TOP_DECORATION: - if (y < GLFW_BORDER_SIZE) + if (ypos < GLFW_BORDER_SIZE) cursorName = "n-resize"; else cursorName = "left_ptr"; break; case GLFW_LEFT_DECORATION: - if (y < GLFW_BORDER_SIZE) + if (ypos < GLFW_BORDER_SIZE) cursorName = "nw-resize"; else cursorName = "w-resize"; break; case GLFW_RIGHT_DECORATION: - if (y < GLFW_BORDER_SIZE) + if (ypos < GLFW_BORDER_SIZE) cursorName = "ne-resize"; else cursorName = "e-resize"; break; case GLFW_BOTTOM_DECORATION: - if (x < GLFW_BORDER_SIZE) + if (xpos < GLFW_BORDER_SIZE) cursorName = "sw-resize"; - else if (x > window->wl.width + GLFW_BORDER_SIZE) + else if (xpos > window->wl.width + GLFW_BORDER_SIZE) cursorName = "se-resize"; else cursorName = "s-resize"; @@ -1397,9 +1397,6 @@ static void pointerHandleMotion(void* userData, if (_glfw.wl.cursorPreviousName != cursorName) { - struct wl_buffer* buffer; - struct wl_cursor* cursor; - struct wl_cursor_image* image; struct wl_surface* surface = _glfw.wl.cursorSurface; struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; int scale = 1; @@ -1412,17 +1409,16 @@ static void pointerHandleMotion(void* userData, theme = _glfw.wl.cursorThemeHiDPI; } - cursor = wl_cursor_theme_get_cursor(theme, name); + struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName); if (!cursor) return; // TODO: handle animated cursors too. - image = cursor->images[0]; - + struct wl_cursor_image* image = cursor->images[0]; if (!image) return; - buffer = wl_cursor_image_get_buffer(image); + struct wl_buffer* buffer = wl_cursor_image_get_buffer(image); if (!buffer) return; @@ -1432,10 +1428,10 @@ static void pointerHandleMotion(void* userData, image->hotspot_y / scale); wl_surface_set_buffer_scale(surface, scale); wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); + wl_surface_damage(surface, 0, 0, image->width, image->height); wl_surface_commit(surface); - _glfw.wl.cursorPreviousName = name; + + _glfw.wl.cursorPreviousName = cursorName; } } From bf429fb628f85fe518d825ae92f23ad8d657d910 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 14 Oct 2020 17:53:01 +0100 Subject: [PATCH 173/207] Fix macOS Print Screen Many years ago this value was changed from F13 to Print Screen with 1ae9ce1e0a00bf6f8b7e719bf1ec6e73f111afcf. However, this was later reverted to F13 with 5759d0fdf272351b35f666718a6e2a665db827e8. This changes it back to Print Screen for consistency with other platforms. Closes #1786 Fixes #2169 (cherry picked from commit c940695eb03723fa6e4b174db524bcaa4f55bbee) --- src/cocoa_init.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index f5273129..fb094d3b 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -251,7 +251,7 @@ static void createKeyTables(void) _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[0x69] = GLFW_KEY_PRINT_SCREEN; _glfw.ns.keycodes[0x6B] = GLFW_KEY_F14; _glfw.ns.keycodes[0x71] = GLFW_KEY_F15; _glfw.ns.keycodes[0x6A] = GLFW_KEY_F16; From c754de5deb1fb339a76fe70fe28687e0f681ef83 Mon Sep 17 00:00:00 2001 From: moritz-h <7849248+moritz-h@users.noreply.github.com> Date: Wed, 15 Nov 2023 16:37:46 +0100 Subject: [PATCH 174/207] Win32: Add library name suffix to pkg-config file Closes #2386 This was adapted to 3.3-stable from 93a3ba808067134b5a964b1a1c44701450386fe4. --- CMakeLists.txt | 5 +++++ src/CMakeLists.txt | 1 + src/glfw3.pc.in | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50b62e5a..b035b984 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ if (BUILD_SHARED_LIBS AND UNIX) else() set(GLFW_LIB_NAME glfw3) endif() +set(GLFW_LIB_NAME_SUFFIX "") if (GLFW_VULKAN_STATIC) if (BUILD_SHARED_LIBS) @@ -196,6 +197,10 @@ if (_GLFW_WIN32) if (GLFW_USE_HYBRID_HPG) set(_GLFW_USE_HYBRID_HPG 1) endif() + + if (BUILD_SHARED_LIBS) + set (GLFW_LIB_NAME_SUFFIX "dll") + endif() endif() #-------------------------------------------------------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b6dd86c5..efd65927 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -168,6 +168,7 @@ if (BUILD_SHARED_LIBS) # Add a suffix to the import library to avoid naming conflicts set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") endif() + set (GLFW_LIB_NAME_SUFFIX "dll") target_compile_definitions(glfw INTERFACE GLFW_DLL) elseif (APPLE) diff --git a/src/glfw3.pc.in b/src/glfw3.pc.in index f74298d4..17779ace 100644 --- a/src/glfw3.pc.in +++ b/src/glfw3.pc.in @@ -8,6 +8,6 @@ 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: -L${libdir} -l@GLFW_LIB_NAME@@GLFW_LIB_NAME_SUFFIX@ Libs.private: @GLFW_PKG_LIBS@ Cflags: -I${includedir} From 8ef347157aa17c504ded518187f839f78f582c7d Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 15 Nov 2023 16:44:24 +0100 Subject: [PATCH 175/207] Updated changelog (cherry picked from commit 46c2e35c554d96fdb8a94c3f19c88e34a613532a) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5b8cd7a0..0b94356b 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ information on what to include when reporting a bug. ## Changelog + - [Win32] Fix pkg-config for dynamic library on Windows (#2386, #2420) - [Wayland] Added improved fallback window decorations via libdecor (#1639,#1693) - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Wayland] Disabled alpha channel for opaque windows on systems lacking From af93f062591c3c9de191a48db24a3442be9ac331 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 15 Nov 2023 16:48:19 +0100 Subject: [PATCH 176/207] Add credits Related to #2386 and #2420 (cherry picked from commit 9a80225ddfdaf9457c80c97ce4c12aed3377dd24) --- CONTRIBUTORS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e078fa03..ebad8f00 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -148,6 +148,7 @@ video tutorials. - Alexander Monakov - Pierre Morel - Jon Morton + - moritz-h - Pierre Moulon - Martins Mozeiko - James Murphy @@ -236,6 +237,7 @@ video tutorials. - Corentin Wallez - Torsten Walluhn - Patrick Walton + - Jim Wang - Xo Wang - Jay Weisskopf - Frank Wille From 489339b8378cc727b5542063979298060b543393 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 15 Nov 2023 17:48:30 +0100 Subject: [PATCH 177/207] Updated credit (cherry picked from commit 3ed6e9d89aa518b44ab30e598e5b813879eda71c) --- CONTRIBUTORS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ebad8f00..d201407a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -81,6 +81,7 @@ video tutorials. - Stephen Gutekanst - Jonathan Hale - hdf89shfdfs + - Moritz Heinemann - Sylvain Hellegouarch - Björn Hempel - Matthew Henry @@ -148,7 +149,6 @@ video tutorials. - Alexander Monakov - Pierre Morel - Jon Morton - - moritz-h - Pierre Moulon - Martins Mozeiko - James Murphy From ff156743ab9e00a658877c6afb9013b3d9c570f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 19 Jul 2023 17:40:22 +0200 Subject: [PATCH 178/207] Update Doxyfile template for Doxygen 1.9.7 This was adapted to 3.3-stable from 938a3c29b2e1b93a681cfde82876dfce97635658. --- docs/Doxyfile.in | 2763 +++++++++++++++++++++++++++++++--------------- 1 file changed, 1855 insertions(+), 908 deletions(-) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index a24ed015..067619c7 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -1,110 +1,151 @@ -# Doxyfile 1.8.3.1 +# Doxyfile 1.9.7 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored. +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. # The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. PROJECT_NAME = "GLFW" -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. PROJECT_NUMBER = @GLFW_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "A multi-platform library for OpenGL, window and input" -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. OUTPUT_DIRECTORY = "@GLFW_BINARY_DIR@/docs" -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. +# The default value is: YES. REPEAT_BRIEF = NO -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# doxygen will generate a detailed section even if there is only a brief # description. +# The default value is: NO. ALWAYS_DETAILED_SEC = YES @@ -112,88 +153,125 @@ ALWAYS_DETAILED_SEC = YES # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. +# The default value is: NO. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. Note that you specify absolute paths here, but also -# relative paths, which will be relative from the directory where doxygen is -# started. +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. JAVADOC_AUTOBRIEF = NO -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = "thread_safety=@par Thread safety^^" \ "pointer_lifetime=@par Pointer lifetime^^" \ @@ -208,483 +286,716 @@ ALIASES = "thread_safety=@par Thread safety^^" \ "macos=__macOS:__" \ "linux=__Linux:__" -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, -# and language is one of the parsers supported by doxygen: IDL, Java, -# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, -# C++. For instance to make doxygen treat .inc files as Fortran files (default -# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note -# that for custom extensions you also need to set FILE_PATTERNS otherwise the -# files are not read by doxygen. +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. MARKDOWN_SUPPORT = YES -# When enabled doxygen tries to link words that correspond to documented classes, -# or namespaces to their corresponding documentation. Such a link can be -# prevented in individual cases by putting a % sign in front of the word or +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN Use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0. and GITHUB Use the lower case version of title +# with any whitespace replaced by '-' and punctations characters removed.. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. +# The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. +# The default value is: NO. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES (the -# default) will make doxygen replace the get and set methods by a property in -# the documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. -IDL_PROPERTY_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. +# The default value is: NO. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. SUBGROUPING = YES -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. INLINE_GROUPED_CLASSES = NO -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. INLINE_SIMPLE_STRUCTS = NO -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. TYPEDEF_HIDES_STRUCT = NO -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. +# The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the # documentation. +# The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. -CASE_SENSE_NAMES = YES +CASE_SENSE_NAMES = SYSTEM -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. SHOW_INCLUDE_FILES = NO -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. FORCE_LOCAL_INCLUDES = NO -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. SORT_MEMBER_DOCS = NO -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. SORT_GROUP_NAMES = YES -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. SORT_BY_SCOPE_NAME = NO -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if section-label ... \endif -# and \cond section-label ... \endcond blocks. +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. +# The default value is: YES. SHOW_USED_FILES = YES -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. SHOW_NAMESPACES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. LAYOUT_FILE = "@GLFW_SOURCE_DIR@/docs/DoxygenLayout.xml" -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. Do not use -# file names with spaces, bibtex cannot handle them. +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# Configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. WARN_IF_DOC_ERROR = YES -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. WARN_NO_PARAMDOC = YES -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = "@GLFW_BINARY_DIR@/docs/warnings.txt" #--------------------------------------------------------------------------- -# configuration options related to the input files +# Configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. INPUT = @GLFW_DOXYGEN_INPUT@ # This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.h *.dox -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# # Note that relative paths are relative to the directory from which doxygen is # run. @@ -693,14 +1004,16 @@ EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. +# The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = @@ -708,787 +1021,1233 @@ EXCLUDE_PATTERNS = # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test +# ANamespace::AClass, ANamespace::*Test EXCLUDE_SYMBOLS = APIENTRY GLFWAPI -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). EXAMPLE_PATH = "@GLFW_SOURCE_DIR@/examples" # If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = -# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page (index.html). -# This can be useful if you have a project on for instance GitHub and want reuse -# the introduction page also for the doxygen output. +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- -# configuration options related to source browsing +# Configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. SOURCE_BROWSER = NO -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C, C++ and Fortran comments will always remain visible. +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. REFERENCED_BY_RELATION = NO -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. REFERENCES_RELATION = NO -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index +# Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. ALPHABETICAL_INDEX = YES -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = glfw GLFW_ #--------------------------------------------------------------------------- -# configuration options related to the HTML output +# Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = "@GLFW_SOURCE_DIR@/docs/header.html" -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = "@GLFW_SOURCE_DIR@/docs/footer.html" -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If left blank doxygen will -# generate a default style sheet. Note that it is recommended to use -# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this -# tag will in the future become obsolete. +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional -# user-defined cascading style sheet that is included after the standard -# style sheets created by doxygen. Using this option one can overrule -# certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more -# robust against future updates. Doxygen will copy the style sheet file to -# the output directory. +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = "@GLFW_SOURCE_DIR@/docs/extra.css" # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = "@GLFW_SOURCE_DIR@/docs/spaces.svg" -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = YES +HTML_DYNAMIC_MENUS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely -# identify the documentation publisher. This should be a reverse domain-name -# style string, e.g. com.mycompany.MyDocSet.documentation. +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be # written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. -TREEVIEW_WIDTH = 300 +TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and -# SVG. The default value is HTML-CSS, which is slower, but has the best -# compatibility. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /