From bf945f1213728a98f7647380616f9cff9f6b3611 Mon Sep 17 00:00:00 2001 From: Grzesiek11 Date: Thu, 29 Feb 2024 15:50:50 +0000 Subject: [PATCH 01/15] Unlimited mouse button input mode This adds the GLFW_UNLIMITED_MOUSE_BUTTONS input mode which permits mouse buttons over GLFW_MOUSE_BUTTON_LAST to be reported to the mouse button callback. Closes #2423 --- README.md | 3 +++ docs/input.md | 25 ++++++++++++++++++++++--- docs/news.md | 11 +++++++++++ include/GLFW/glfw3.h | 38 ++++++++++++++++++++++++++------------ src/input.c | 22 ++++++++++++++++------ src/internal.h | 1 + tests/events.c | 1 + tests/window.c | 1 + 8 files changed, 81 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 050ada3c..d2615b17 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,9 @@ information on what to include when reporting a bug. ## Changelog since 3.4 + - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond + the limit of the mouse button tokens to be reported (#2423) + ## Contact diff --git a/docs/input.md b/docs/input.md index 56983b08..3ef1aebe 100644 --- a/docs/input.md +++ b/docs/input.md @@ -492,6 +492,20 @@ a mouse button callback. glfwSetMouseButtonCallback(window, mouse_button_callback); ``` +@anchor GLFW_UNLIMITED_MOUSE_BUTTONS +To handle all mouse buttons in the callback, instead of only ones with associated +[button tokens](@ref buttons), set the @ref GLFW_UNLIMITED_MOUSE_BUTTONS +input mode. + +```c +glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE); +``` + +When this input mode is enabled, GLFW doesn't limit the reported mouse buttons +to only those that have an associated button token, for compatibility with +earlier versions of GLFW, which never reported any buttons over +@ref GLFW_MOUSE_BUTTON_LAST, on which users could have relied on. + The callback function receives the [mouse button](@ref buttons), button action and [modifier bits](@ref mods). @@ -503,11 +517,16 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) } ``` +The mouse button is an integer that can be one of the +[mouse button tokens](@ref buttons) or, if the +@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set, any other positive value. + The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. -The last reported state for every [supported mouse button](@ref buttons) is also +The last reported state for every [mouse button token](@ref buttons) is also saved in per-window state arrays that can be polled with @ref -glfwGetMouseButton. +glfwGetMouseButton. This is not effected by the @ref GLFW_UNLIMITED_MOUSE_BUTTONS +input mode. ```c int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); @@ -540,7 +559,7 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`. The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any -[supported mouse button](@ref buttons). +[mouse button token](@ref buttons). ### Scroll input {#scrolling} diff --git a/docs/news.md b/docs/news.md index fd93a712..148d0871 100644 --- a/docs/news.md +++ b/docs/news.md @@ -5,6 +5,15 @@ ## New features {#features} +### Unlimited mouse buttons {#unlimited_mouse_buttons} + +GLFW now has an input mode which allows an unlimited number of mouse buttons to +be reported by the mouse buttton callback, rather than just the associated +[mouse button tokens](@ref buttons). This allows using mouse buttons with +values over 8. For compatibility with older versions, the +@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of +this. + ## Caveats {#caveats} ## Deprecations {#deprecations} @@ -19,6 +28,8 @@ ### New constants {#new_constants} +- @ref GLFW_UNLIMITED_MOUSE_BUTTONS + ## Release notes for earlier versions {#news_archive} - [Release notes for 3.4](https://www.glfw.org/docs/3.4/news.html) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 9a6ad6fd..bed739dc 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1149,11 +1149,12 @@ extern "C" { #define GLFW_OPENGL_CORE_PROFILE 0x00032001 #define GLFW_OPENGL_COMPAT_PROFILE 0x00032002 -#define GLFW_CURSOR 0x00033001 -#define GLFW_STICKY_KEYS 0x00033002 -#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 -#define GLFW_LOCK_KEY_MODS 0x00033004 -#define GLFW_RAW_MOUSE_MOTION 0x00033005 +#define GLFW_CURSOR 0x00033001 +#define GLFW_STICKY_KEYS 0x00033002 +#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 +#define GLFW_LOCK_KEY_MODS 0x00033004 +#define GLFW_RAW_MOUSE_MOTION 0x00033005 +#define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006 #define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_HIDDEN 0x00034002 @@ -4676,8 +4677,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * * This function sets an input mode option for the specified window. The mode * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, - * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or - * @ref GLFW_RAW_MOUSE_MOTION. + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS + * @ref GLFW_RAW_MOUSE_MOTION, or @ref GLFW_UNLIMITED_MOUSE_BUTTONS. * * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * modes: @@ -4717,6 +4718,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref * glfwRawMouseMotionSupported to check for support. * + * If the mode is `GLFW_UNLIMITED_MOUSE_BUTTONS`, the value must be either + * `GLFW_TRUE` to disable the mouse button limit when calling the mouse button + * callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback + * to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`. + * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or @@ -4911,8 +4917,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); * returns `GLFW_PRESS` the first time you call it for a mouse button that was * pressed, even if that mouse button has already been released. * + * The @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode does not effect the + * limit on buttons which can be polled with this function. + * * @param[in] window The desired window. - * @param[in] button The desired [mouse button](@ref buttons). + * @param[in] button The desired [mouse button token](@ref buttons). * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref @@ -5288,10 +5297,15 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods * is called when a mouse button is pressed or released. * * When a window loses input focus, it will generate synthetic mouse button - * release events for all pressed mouse buttons. You can tell these events - * from user-generated events by the fact that the synthetic ones are generated - * after the focus loss event has been processed, i.e. after the - * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. + * release events for all pressed mouse buttons with associated button tokens. + * You can tell these events from user-generated events by the fact that the + * synthetic ones are generated after the focus loss event has been processed, + * i.e. after the [window focus callback](@ref glfwSetWindowFocusCallback) has + * been called. + * + * The reported `button` value can be higher than `GLFW_MOUSE_BUTTON_LAST` if + * the button does not have an associated [button token](@ref buttons) and the + * @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set. * * @param[in] window The window whose callback to set. * @param[in] callback The new callback, or `NULL` to remove the currently set diff --git a/src/input.c b/src/input.c index 3f8ddb30..8148a57d 100644 --- a/src/input.c +++ b/src/input.c @@ -348,20 +348,22 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) { assert(window != NULL); assert(button >= 0); - assert(button <= GLFW_MOUSE_BUTTON_LAST); assert(action == GLFW_PRESS || action == GLFW_RELEASE); assert(mods == (mods & GLFW_MOD_MASK)); - if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) + if (button < 0 || (!window->disableMouseButtonLimit && button > GLFW_MOUSE_BUTTON_LAST)) return; if (!window->lockKeyMods) mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK); - if (action == GLFW_RELEASE && window->stickyMouseButtons) - window->mouseButtons[button] = _GLFW_STICK; - else - window->mouseButtons[button] = (char) action; + if (button <= GLFW_MOUSE_BUTTON_LAST) + { + if (action == GLFW_RELEASE && window->stickyMouseButtons) + window->mouseButtons[button] = _GLFW_STICK; + else + window->mouseButtons[button] = (char) action; + } if (window->callbacks.mouseButton) window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); @@ -576,6 +578,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) return window->lockKeyMods; case GLFW_RAW_MOUSE_MOTION: return window->rawMouseMotion; + case GLFW_UNLIMITED_MOUSE_BUTTONS: + return window->disableMouseButtonLimit; } _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); @@ -683,6 +687,12 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) _glfw.platform.setRawMouseMotion(window, value); return; } + + case GLFW_UNLIMITED_MOUSE_BUTTONS: + { + window->disableMouseButtonLimit = value ? GLFW_TRUE : GLFW_FALSE; + return; + } } _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); diff --git a/src/internal.h b/src/internal.h index 76f3ede2..eae87c73 100644 --- a/src/internal.h +++ b/src/internal.h @@ -544,6 +544,7 @@ struct _GLFWwindow GLFWbool stickyKeys; GLFWbool stickyMouseButtons; GLFWbool lockKeyMods; + GLFWbool disableMouseButtonLimit; int cursorMode; char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; char keys[GLFW_KEY_LAST + 1]; diff --git a/tests/events.c b/tests/events.c index fdc3c199..ab3b99a7 100644 --- a/tests/events.c +++ b/tests/events.c @@ -630,6 +630,7 @@ int main(int argc, char** argv) glfwTerminate(); exit(EXIT_FAILURE); } + glfwSetInputMode(slots[i].window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE); glfwSetWindowUserPointer(slots[i].window, slots + i); diff --git a/tests/window.c b/tests/window.c index c81bf024..ffea5dbf 100644 --- a/tests/window.c +++ b/tests/window.c @@ -78,6 +78,7 @@ int main(int argc, char** argv) glfwTerminate(); exit(EXIT_FAILURE); } + glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE); glfwMakeContextCurrent(window); gladLoadGL(glfwGetProcAddress); From 42dc1ffaee922629cf503dac5888b95a2f7532ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 8 Mar 2024 15:22:36 +0100 Subject: [PATCH 02/15] Wayland: Fix leak of surface scaling objects --- README.md | 1 + src/wl_window.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index d2615b17..77a98ca7 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ information on what to include when reporting a bug. - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond the limit of the mouse button tokens to be reported (#2423) + - [Wayland] Bugfix: The fractional scaling related objects were not destroyed ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index 218b4efd..9a411155 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2183,6 +2183,12 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window) if (window == _glfw.wl.keyboardFocus) _glfw.wl.keyboardFocus = NULL; + if (window->wl.fractionalScale) + wp_fractional_scale_v1_destroy(window->wl.fractionalScale); + + if (window->wl.scalingViewport) + wp_viewport_destroy(window->wl.scalingViewport); + if (window->wl.activationToken) xdg_activation_token_v1_destroy(window->wl.activationToken); From 860c8ef38f0200824a8f038a5e6502963ec9c443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 11 Mar 2024 11:33:51 +0100 Subject: [PATCH 03/15] Null: Add Vulkan 'window' surface creation This adds support for Vulkan 'window' surface creation on the Null platform via the VK_EXT_headless_surface extension, where available. Tested with MoltenVK. --- README.md | 1 + src/internal.h | 2 ++ src/null_platform.h | 11 +++++++++++ src/null_window.c | 33 ++++++++++++++++++++++++++++++--- src/vulkan.c | 2 ++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 77a98ca7..e514ced3 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ information on what to include when reporting a bug. - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond the limit of the mouse button tokens to be reported (#2423) - [Wayland] Bugfix: The fractional scaling related objects were not destroyed + - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` ## Contact diff --git a/src/internal.h b/src/internal.h index eae87c73..e36c4455 100644 --- a/src/internal.h +++ b/src/internal.h @@ -277,6 +277,7 @@ typedef enum VkStructureType VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, + VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; @@ -861,6 +862,7 @@ struct _GLFWlibrary GLFWbool KHR_xlib_surface; GLFWbool KHR_xcb_surface; GLFWbool KHR_wayland_surface; + GLFWbool EXT_headless_surface; } vk; struct { diff --git a/src/null_platform.h b/src/null_platform.h index 8222b0de..dbcb835b 100644 --- a/src/null_platform.h +++ b/src/null_platform.h @@ -156,6 +156,17 @@ #define GLFW_NULL_SC_MENU 120 #define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU +typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT; + +typedef struct VkHeadlessSurfaceCreateInfoEXT +{ + VkStructureType sType; + const void* pNext; + VkHeadlessSurfaceCreateFlagsEXT flags; +} VkHeadlessSurfaceCreateInfoEXT; + +typedef VkResult (APIENTRY *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance,const VkHeadlessSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*); + // Null-specific per-window data // typedef struct _GLFWwindowNull diff --git a/src/null_window.c b/src/null_window.c index 75326065..f31489b0 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -28,6 +28,7 @@ #include "internal.h" #include +#include static void applySizeLimits(_GLFWwindow* window, int* width, int* height) { @@ -699,13 +700,18 @@ int _glfwGetKeyScancodeNull(int key) void _glfwGetRequiredInstanceExtensionsNull(char** extensions) { + if (!_glfw.vk.KHR_surface || !_glfw.vk.EXT_headless_surface) + return; + + extensions[0] = "VK_KHR_surface"; + extensions[1] = "VK_EXT_headless_surface"; } GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily) { - return GLFW_FALSE; + return GLFW_TRUE; } VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, @@ -713,7 +719,28 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) { - // This seems like the most appropriate error to return here - return VK_ERROR_EXTENSION_NOT_PRESENT; + PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT = + (PFN_vkCreateHeadlessSurfaceEXT) + vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT"); + if (!vkCreateHeadlessSurfaceEXT) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Null: Vulkan instance missing VK_EXT_headless_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + VkHeadlessSurfaceCreateInfoEXT sci; + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT; + + const VkResult err = vkCreateHeadlessSurfaceEXT(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Null: Failed to create Vulkan surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; } diff --git a/src/vulkan.c b/src/vulkan.c index 274d21ca..3f76c540 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -142,6 +142,8 @@ GLFWbool _glfwInitVulkan(int mode) _glfw.vk.KHR_xcb_surface = GLFW_TRUE; else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) _glfw.vk.KHR_wayland_surface = GLFW_TRUE; + else if (strcmp(ep[i].extensionName, "VK_EXT_headless_surface") == 0) + _glfw.vk.EXT_headless_surface = GLFW_TRUE; } _glfw_free(ep); From 738dd6ff1d4f79cf4f8b8af0621a8afb40c51b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 11 Mar 2024 14:29:07 +0100 Subject: [PATCH 04/15] Null: Add limited EGL context creation on Mesa This provides very limited support for context creation via EGL on the Null platform. It supports Unix-like systems with a version of Mesa that provides EGL_MESA_platform_surfaceless. Even then, the actual framebuffer provided is not resized along with the 'window'. That will hopefully change once context and framebuffer creation are separated, but this commit should at least allow more applications than before to run on the Null platform. --- README.md | 1 + src/egl_context.c | 41 +++++++++++++++++++++++++++++++++-------- src/internal.h | 8 ++++++++ src/null_window.c | 7 +++++-- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e514ced3..825329ca 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ information on what to include when reporting a bug. the limit of the mouse button tokens to be reported (#2423) - [Wayland] Bugfix: The fractional scaling related objects were not destroyed - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` + - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` ## Contact diff --git a/src/egl_context.c b/src/egl_context.c index 06deb76f..8dbe3caa 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -92,7 +92,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, nativeCount, usableCount, apiBit; + int i, nativeCount, usableCount, apiBit, surfaceTypeBit; GLFWbool wrongApiAvailable = GLFW_FALSE; if (ctxconfig->client == GLFW_OPENGL_ES_API) @@ -105,6 +105,11 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, else apiBit = EGL_OPENGL_BIT; + if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA) + surfaceTypeBit = EGL_PBUFFER_BIT; + else + surfaceTypeBit = EGL_WINDOW_BIT; + if (fbconfig->stereo) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported"); @@ -133,8 +138,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER) continue; - // Only consider window EGLConfigs - if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) + if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & surfaceTypeBit)) continue; #if defined(_GLFW_X11) @@ -420,6 +424,8 @@ GLFWbool _glfwInitEGL(void) _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext"); _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface) _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface"); + _glfw.egl.CreatePbufferSurface = (PFN_eglCreatePbufferSurface) + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreatePbufferSurface"); _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent) _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent"); _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers) @@ -442,6 +448,7 @@ GLFWbool _glfwInitEGL(void) !_glfw.egl.DestroySurface || !_glfw.egl.DestroyContext || !_glfw.egl.CreateWindowSurface || + !_glfw.egl.CreatePbufferSurface || !_glfw.egl.MakeCurrent || !_glfw.egl.SwapBuffers || !_glfw.egl.SwapInterval || @@ -477,6 +484,8 @@ GLFWbool _glfwInitEGL(void) _glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions); _glfw.egl.ANGLE_platform_angle_metal = _glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions); + _glfw.egl.MESA_platform_surfaceless = + _glfwStringInExtensionString("EGL_MESA_platform_surfaceless", extensions); } if (_glfw.egl.EXT_platform_base) @@ -708,20 +717,36 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); } + if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA) + { + int width, height; + _glfw.platform.getFramebufferSize(window, &width, &height); + + SET_ATTRIB(EGL_WIDTH, width); + SET_ATTRIB(EGL_HEIGHT, height); + } + SET_ATTRIB(EGL_NONE, EGL_NONE); native = _glfw.platform.getEGLNativeWindow(window); - // HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT - // despite reporting EGL_EXT_platform_base - if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE) + if (!_glfw.egl.platform || _glfw.egl.platform == EGL_PLATFORM_ANGLE_ANGLE) { + // HACK: Also use non-platform function for ANGLE, as it does not + // implement eglCreatePlatformWindowSurfaceEXT despite reporting + // support for EGL_EXT_platform_base window->context.egl.surface = - eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs); + eglCreateWindowSurface(_glfw.egl.display, config, native, attribs); + } + else if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA) + { + // HACK: Use a pbuffer surface as the default framebuffer + window->context.egl.surface = + eglCreatePbufferSurface(_glfw.egl.display, config, attribs); } else { window->context.egl.surface = - eglCreateWindowSurface(_glfw.egl.display, config, native, attribs); + eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs); } if (window->context.egl.surface == EGL_NO_SURFACE) diff --git a/src/internal.h b/src/internal.h index e36c4455..ad59efb5 100644 --- a/src/internal.h +++ b/src/internal.h @@ -150,6 +150,9 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); #define EGL_NO_DISPLAY ((EGLDisplay) 0) #define EGL_NO_CONTEXT ((EGLContext) 0) #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0) +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_WIDTH 0x3057 +#define EGL_HEIGHT 0x3056 #define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 #define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 @@ -181,6 +184,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); #define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450 #define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489 #define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f +#define EGL_PLATFORM_SURFACELESS_MESA 0x31dd typedef int EGLint; typedef unsigned int EGLBoolean; @@ -205,6 +209,7 @@ typedef EGLContext (APIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLCon typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface); typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext); typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*); +typedef EGLSurface (APIENTRY * PFN_eglCreatePbufferSurface)(EGLDisplay,EGLContext,const EGLint*); typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext); typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); @@ -221,6 +226,7 @@ typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*); #define eglDestroySurface _glfw.egl.DestroySurface #define eglDestroyContext _glfw.egl.DestroyContext #define eglCreateWindowSurface _glfw.egl.CreateWindowSurface +#define eglCreatePbufferSurface _glfw.egl.CreatePbufferSurface #define eglMakeCurrent _glfw.egl.MakeCurrent #define eglSwapBuffers _glfw.egl.SwapBuffers #define eglSwapInterval _glfw.egl.SwapInterval @@ -813,6 +819,7 @@ struct _GLFWlibrary GLFWbool ANGLE_platform_angle_d3d; GLFWbool ANGLE_platform_angle_vulkan; GLFWbool ANGLE_platform_angle_metal; + GLFWbool MESA_platform_surfaceless; void* handle; @@ -827,6 +834,7 @@ struct _GLFWlibrary PFN_eglDestroySurface DestroySurface; PFN_eglDestroyContext DestroyContext; PFN_eglCreateWindowSurface CreateWindowSurface; + PFN_eglCreatePbufferSurface CreatePbufferSurface; PFN_eglMakeCurrent MakeCurrent; PFN_eglSwapBuffers SwapBuffers; PFN_eglSwapInterval SwapInterval; diff --git a/src/null_window.c b/src/null_window.c index f31489b0..f0e1dcc9 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -553,12 +553,15 @@ const char* _glfwGetClipboardStringNull(void) EGLenum _glfwGetEGLPlatformNull(EGLint** attribs) { - return 0; + if (_glfw.egl.EXT_platform_base && _glfw.egl.MESA_platform_surfaceless) + return EGL_PLATFORM_SURFACELESS_MESA; + else + return 0; } EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void) { - return 0; + return EGL_DEFAULT_DISPLAY; } EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window) From 38ec7abd3baffdd3ec4e6f8cbb5384cda8882ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 10 Mar 2024 16:18:08 +0100 Subject: [PATCH 05/15] Fix missing assertions for native access functions --- src/cocoa_monitor.m | 3 +++ src/cocoa_window.m | 5 +++++ src/egl_context.c | 4 ++++ src/glx_context.c | 4 ++++ src/nsgl_context.m | 3 +++ src/osmesa_context.c | 2 ++ src/wgl_context.c | 2 ++ src/win32_monitor.c | 5 +++++ src/win32_window.c | 3 +++ src/wl_monitor.c | 3 +++ src/wl_window.c | 2 ++ src/x11_monitor.c | 5 +++++ src/x11_window.c | 4 ++++ 13 files changed, 45 insertions(+) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 75f8ec53..150a7477 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -628,6 +629,8 @@ void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 5fa360dd..32df0b9e 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -30,6 +30,7 @@ #include #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 @@ -2041,6 +2042,8 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(nil); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) @@ -2056,6 +2059,8 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) GLFWAPI id glfwGetCocoaView(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(nil); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) diff --git a/src/egl_context.c b/src/egl_context.c index 8dbe3caa..831a9cf7 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -909,6 +909,8 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void) GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); if (window->context.source != GLFW_EGL_CONTEXT_API) @@ -923,6 +925,8 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); if (window->context.source != GLFW_EGL_CONTEXT_API) diff --git a/src/glx_context.c b/src/glx_context.c index fae55966..a971585f 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -678,6 +678,8 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -698,6 +700,8 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) diff --git a/src/nsgl_context.m b/src/nsgl_context.m index d34cc224..e93eb4d4 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -30,6 +30,7 @@ #include #include +#include static void makeContextCurrentNSGL(_GLFWwindow* window) { @@ -362,6 +363,8 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(nil); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) diff --git a/src/osmesa_context.c b/src/osmesa_context.c index 0b9d83a2..88f5adb8 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -370,6 +370,8 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle, GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (window->context.source != GLFW_OSMESA_CONTEXT_API) diff --git a/src/wgl_context.c b/src/wgl_context.c index 209469e2..dd92b6f4 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -776,6 +776,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 1be43e66..d13a9040 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -33,6 +33,7 @@ #include #include #include +#include // Callback for EnumDisplayMonitors in createMonitor @@ -540,6 +541,8 @@ void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) @@ -554,6 +557,8 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) diff --git a/src/win32_window.c b/src/win32_window.c index 7d26f0b1..5cd08f68 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -2577,6 +2578,8 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) diff --git a/src/wl_monitor.c b/src/wl_monitor.c index dca8ebbd..9f56c3ae 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "wayland-client-protocol.h" @@ -259,6 +260,8 @@ void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) diff --git a/src/wl_window.c b/src/wl_window.c index 9a411155..812b9e91 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -3298,6 +3298,8 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void) GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) diff --git a/src/x11_monitor.c b/src/x11_monitor.c index cab81127..8f8e2bcd 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -33,6 +33,7 @@ #include #include #include +#include // Check whether the display mode should be included in enumeration @@ -612,6 +613,8 @@ void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -626,6 +629,8 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) diff --git a/src/x11_window.c b/src/x11_window.c index 601387a9..fa2d390f 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -3303,6 +3303,8 @@ GLFWAPI Display* glfwGetX11Display(void) GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -3316,6 +3318,8 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) GLFWAPI void glfwSetX11SelectionString(const char* string) { + assert(string != NULL); + _GLFW_REQUIRE_INIT(); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) From 68dcea0d7fcd91011695dbc74d6b1c999fcda2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 18 Jan 2024 21:33:27 +0100 Subject: [PATCH 06/15] Place assertions for handles after init check This lets automated testing check that GLFW_NOT_INITIALIZED is emitted for every public function. --- src/cocoa_monitor.m | 6 +- src/cocoa_window.m | 12 ++-- src/context.c | 8 +-- src/egl_context.c | 8 +-- src/glx_context.c | 12 ++-- src/input.c | 58 +++++++++------- src/monitor.c | 55 ++++++++------- src/nsgl_context.m | 6 +- src/osmesa_context.c | 14 ++-- src/vulkan.c | 11 +-- src/wgl_context.c | 6 +- src/win32_monitor.c | 12 ++-- src/win32_window.c | 6 +- src/window.c | 162 +++++++++++++++++++++++++------------------ src/wl_monitor.c | 6 +- src/wl_window.c | 6 +- src/x11_monitor.c | 12 ++-- src/x11_window.c | 6 +- 18 files changed, 226 insertions(+), 180 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 150a7477..1abf6ff5 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -628,9 +628,6 @@ void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) @@ -639,6 +636,9 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) return kCGNullDirectDisplay; } + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + return monitor->ns.displayID; } diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 32df0b9e..780bc7d3 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -2041,9 +2041,6 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(nil); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) @@ -2053,14 +2050,14 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) return nil; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + return window->ns.object; } GLFWAPI id glfwGetCocoaView(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(nil); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) @@ -2070,6 +2067,9 @@ GLFWAPI id glfwGetCocoaView(GLFWwindow* handle) return nil; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + return window->ns.view; } diff --git a/src/context.c b/src/context.c index 7232dc2a..f4fa63ad 100644 --- a/src/context.c +++ b/src/context.c @@ -615,11 +615,11 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* previous; - _GLFW_REQUIRE_INIT(); - previous = _glfwPlatformGetTls(&_glfw.contextSlot); if (window && window->context.client == GLFW_NO_API) @@ -647,11 +647,11 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void) GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - if (window->context.client == GLFW_NO_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, diff --git a/src/egl_context.c b/src/egl_context.c index 831a9cf7..b901c1be 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -908,11 +908,11 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void) GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); - if (window->context.source != GLFW_EGL_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); @@ -924,11 +924,11 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); - if (window->context.source != GLFW_EGL_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); diff --git a/src/glx_context.c b/src/glx_context.c index a971585f..a2464a9d 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -677,9 +677,6 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -688,6 +685,9 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) return NULL; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); @@ -699,9 +699,6 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -710,6 +707,9 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) return None; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); diff --git a/src/input.c b/src/input.c index 8148a57d..c619eefc 100644 --- a/src/input.c +++ b/src/input.c @@ -561,11 +561,11 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window) GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) { + _GLFW_REQUIRE_INIT_OR_RETURN(0); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(0); - switch (mode) { case GLFW_CURSOR: @@ -588,11 +588,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - switch (mode) { case GLFW_CURSOR: @@ -744,11 +744,11 @@ GLFWAPI int glfwGetKeyScancode(int key) GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) { + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); - if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) { _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); @@ -767,11 +767,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) { + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); - if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST) { _glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button); @@ -790,9 +790,6 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - if (xpos) *xpos = 0; if (ypos) @@ -800,6 +797,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (xpos) @@ -813,11 +813,11 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX || ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX) { @@ -907,10 +907,10 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape) GLFWAPI void glfwDestroyCursor(GLFWcursor* handle) { - _GLFWcursor* cursor = (_GLFWcursor*) handle; - _GLFW_REQUIRE_INIT(); + _GLFWcursor* cursor = (_GLFWcursor*) handle; + if (cursor == NULL) return; @@ -942,12 +942,12 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle) GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) windowHandle; _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - window->cursor = cursor; _glfw.platform.setCursor(window, cursor); @@ -955,30 +955,33 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun); return cbfun; } GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun); return cbfun; } GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun); return cbfun; } @@ -986,10 +989,11 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, GLFWmousebuttonfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun); return cbfun; } @@ -997,10 +1001,11 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, GLFWcursorposfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun); return cbfun; } @@ -1008,10 +1013,11 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, GLFWcursorenterfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun); return cbfun; } @@ -1019,20 +1025,22 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, GLFWscrollfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun); return cbfun; } GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun); return cbfun; } diff --git a/src/monitor.c b/src/monitor.c index 6f802e32..cc95efb6 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -325,9 +325,6 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void) GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - if (xpos) *xpos = 0; if (ypos) @@ -335,6 +332,9 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) _GLFW_REQUIRE_INIT(); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _glfw.platform.getMonitorPos(monitor, xpos, ypos); } @@ -342,9 +342,6 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, int* xpos, int* ypos, int* width, int* height) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - if (xpos) *xpos = 0; if (ypos) @@ -356,14 +353,14 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, _GLFW_REQUIRE_INIT(); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height); } GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - if (widthMM) *widthMM = 0; if (heightMM) @@ -371,6 +368,9 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* _GLFW_REQUIRE_INIT(); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + if (widthMM) *widthMM = monitor->widthMM; if (heightMM) @@ -380,42 +380,46 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle, float* xscale, float* yscale) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - if (xscale) *xscale = 0.f; if (yscale) *yscale = 0.f; _GLFW_REQUIRE_INIT(); + + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + _glfw.platform.getMonitorContentScale(monitor, xscale, yscale); } GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return monitor->name; } GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer) { + _GLFW_REQUIRE_INIT(); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; assert(monitor != NULL); - _GLFW_REQUIRE_INIT(); monitor->userPointer = pointer; } GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return monitor->userPointer; } @@ -428,14 +432,15 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); assert(count != NULL); *count = 0; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + if (!refreshVideoModes(monitor)) return NULL; @@ -445,11 +450,11 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode)) return NULL; @@ -462,12 +467,13 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) unsigned short* values; GLFWgammaramp ramp; const GLFWgammaramp* original; - assert(handle != NULL); assert(gamma > 0.f); assert(gamma <= FLT_MAX); _GLFW_REQUIRE_INIT(); + assert(handle != NULL); + if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma); @@ -505,11 +511,11 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _glfwFreeGammaArrays(&monitor->currentRamp); if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp)) return NULL; @@ -519,8 +525,6 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); assert(ramp != NULL); assert(ramp->size > 0); assert(ramp->red != NULL); @@ -529,6 +533,9 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) _GLFW_REQUIRE_INIT(); + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + if (ramp->size <= 0) { _glfwInputError(GLFW_INVALID_VALUE, diff --git a/src/nsgl_context.m b/src/nsgl_context.m index e93eb4d4..57f117ba 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -362,9 +362,6 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(nil); if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) @@ -374,6 +371,9 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) return nil; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); diff --git a/src/osmesa_context.c b/src/osmesa_context.c index 88f5adb8..0bb375a8 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -296,11 +296,12 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width, { void* mesaBuffer; GLint mesaWidth, mesaHeight, mesaFormat; - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (window->context.source != GLFW_OSMESA_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); @@ -335,11 +336,12 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle, { void* mesaBuffer; GLint mesaWidth, mesaHeight, mesaBytes; - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (window->context.source != GLFW_OSMESA_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); @@ -369,11 +371,11 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle, GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - if (window->context.source != GLFW_OSMESA_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); diff --git a/src/vulkan.c b/src/vulkan.c index 3f76c540..9c87fcfe 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -274,11 +274,11 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily) { + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + assert(instance != VK_NULL_HANDLE); assert(device != VK_NULL_HANDLE); - _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); - if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) return GLFW_FALSE; @@ -299,15 +299,16 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(instance != VK_NULL_HANDLE); - assert(window != NULL); assert(surface != NULL); *surface = VK_NULL_HANDLE; _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + assert(instance != VK_NULL_HANDLE); + if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) return VK_ERROR_INITIALIZATION_FAILED; diff --git a/src/wgl_context.c b/src/wgl_context.c index dd92b6f4..1c9189fa 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -775,9 +775,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) @@ -787,6 +784,9 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) return NULL; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); diff --git a/src/win32_monitor.c b/src/win32_monitor.c index d13a9040..87e5c206 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -540,9 +540,6 @@ void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) @@ -551,14 +548,14 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) return NULL; } + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + return monitor->win32.publicAdapterName; } GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) @@ -567,6 +564,9 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) return NULL; } + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + return monitor->win32.publicDisplayName; } diff --git a/src/win32_window.c b/src/win32_window.c index 5cd08f68..d014944b 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -2577,9 +2577,6 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) @@ -2589,6 +2586,9 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) return NULL; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + return window->win32.handle; } diff --git a/src/window.c b/src/window.c index 8b5d9f34..e03121a4 100644 --- a/src/window.c +++ b/src/window.c @@ -467,10 +467,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value) GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; + // Allow closing of NULL (to match the behavior of free) if (window == NULL) return; @@ -501,40 +501,43 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(0); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(0); return window->shouldClose; } GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); window->shouldClose = value; } GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return window->title; } GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); assert(title != NULL); _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + char* prev = window->title; window->title = _glfw_strdup(title); @@ -546,14 +549,15 @@ 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(); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (count < 0) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon"); @@ -577,25 +581,26 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - if (xpos) *xpos = 0; if (ypos) *ypos = 0; _GLFW_REQUIRE_INIT(); + + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _glfw.platform.getWindowPos(window, xpos, ypos); } GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - if (window->monitor) return; @@ -604,27 +609,29 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - if (width) *width = 0; if (height) *height = 0; _GLFW_REQUIRE_INIT(); + + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _glfw.platform.getWindowSize(window, width, height); } GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); assert(width >= 0); assert(height >= 0); _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + window->videoMode.width = width; window->videoMode.height = height; @@ -635,11 +642,11 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, int minwidth, int minheight, int maxwidth, int maxheight) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE) { if (minwidth < 0 || minheight < 0) @@ -678,13 +685,14 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); assert(numer != 0); assert(denom != 0); _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) { if (numer <= 0 || denom <= 0) @@ -707,15 +715,16 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - if (width) *width = 0; if (height) *height = 0; _GLFW_REQUIRE_INIT(); + + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _glfw.platform.getFramebufferSize(window, width, height); } @@ -723,9 +732,6 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, int* left, int* top, int* right, int* bottom) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - if (left) *left = 0; if (top) @@ -736,43 +742,50 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, *bottom = 0; _GLFW_REQUIRE_INIT(); + + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _glfw.platform.getWindowFrameSize(window, left, top, right, bottom); } GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle, float* xscale, float* yscale) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - if (xscale) *xscale = 0.f; if (yscale) *yscale = 0.f; _GLFW_REQUIRE_INIT(); + + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + _glfw.platform.getWindowContentScale(window, xscale, yscale); } GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(0.f); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(0.f); return _glfw.platform.getWindowOpacity(window); } GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); assert(opacity == opacity); assert(opacity >= 0.f); assert(opacity <= 1.f); _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + if (opacity != opacity || opacity < 0.f || opacity > 1.f) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity); @@ -784,29 +797,31 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); _glfw.platform.iconifyWindow(window); } GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); _glfw.platform.restoreWindow(window); } GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - if (window->monitor) return; @@ -815,11 +830,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) GLFWAPI void glfwShowWindow(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - if (window->monitor) return; @@ -831,21 +846,21 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle) GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - _glfw.platform.requestWindowAttention(window); } GLFWAPI void glfwHideWindow(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - if (window->monitor) return; @@ -854,21 +869,21 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle) GLFWAPI void glfwFocusWindow(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - _glfw.platform.focusWindow(window); } GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) { + _GLFW_REQUIRE_INIT_OR_RETURN(0); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(0); - switch (attrib) { case GLFW_FOCUSED: @@ -927,11 +942,11 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); - value = value ? GLFW_TRUE : GLFW_FALSE; switch (attrib) @@ -973,10 +988,11 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return (GLFWmonitor*) window->monitor; } @@ -986,14 +1002,15 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh, int width, int height, int refreshRate) { - _GLFWwindow* window = (_GLFWwindow*) wh; - _GLFWmonitor* monitor = (_GLFWmonitor*) mh; - assert(window != NULL); assert(width >= 0); assert(height >= 0); _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) wh; + _GLFWmonitor* monitor = (_GLFWmonitor*) mh; + assert(window != NULL); + if (width <= 0 || height <= 0) { _glfwInputError(GLFW_INVALID_VALUE, @@ -1021,29 +1038,32 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh, GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) { + _GLFW_REQUIRE_INIT(); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT(); window->userPointer = pointer; } GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return window->userPointer; } GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, GLFWwindowposfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun); return cbfun; } @@ -1051,10 +1071,11 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, GLFWwindowsizefun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun); return cbfun; } @@ -1062,10 +1083,11 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, GLFWwindowclosefun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun); return cbfun; } @@ -1073,10 +1095,11 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, GLFWwindowrefreshfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun); return cbfun; } @@ -1084,10 +1107,11 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, GLFWwindowfocusfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun); return cbfun; } @@ -1095,10 +1119,11 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, GLFWwindowiconifyfun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun); return cbfun; } @@ -1106,10 +1131,11 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle, GLFWwindowmaximizefun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun); return cbfun; } @@ -1117,10 +1143,11 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle, GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle, GLFWframebuffersizefun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun); return cbfun; } @@ -1128,10 +1155,11 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle, GLFWwindowcontentscalefun cbfun) { + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun); return cbfun; } diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 9f56c3ae..1ec5f5af 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -259,9 +259,6 @@ void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) @@ -270,6 +267,9 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle) return NULL; } + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + return monitor->wl.output; } diff --git a/src/wl_window.c b/src/wl_window.c index 812b9e91..dc7dcd07 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -3297,9 +3297,6 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void) GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) @@ -3309,6 +3306,9 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) return NULL; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + return window->wl.surface; } diff --git a/src/x11_monitor.c b/src/x11_monitor.c index 8f8e2bcd..3af82752 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -612,9 +612,6 @@ void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -623,14 +620,14 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) return None; } + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + return monitor->x11.crtc; } GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) { - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - assert(monitor != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -639,6 +636,9 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) return None; } + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + return monitor->x11.output; } diff --git a/src/x11_window.c b/src/x11_window.c index fa2d390f..322349f0 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -3302,9 +3302,6 @@ GLFWAPI Display* glfwGetX11Display(void) GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) { - _GLFWwindow* window = (_GLFWwindow*) handle; - assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(None); if (_glfw.platform.platformID != GLFW_PLATFORM_X11) @@ -3313,6 +3310,9 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) return None; } + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + return window->x11.handle; } From 072f660d93144aa3de3ee8964f3165dff0e3866d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 29 Feb 2024 16:51:41 +0100 Subject: [PATCH 07/15] Allow C99 booleans --- src/internal.h | 2 ++ src/wl_platform.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal.h b/src/internal.h index ad59efb5..4f097aa8 100644 --- a/src/internal.h +++ b/src/internal.h @@ -48,6 +48,8 @@ #define GLFW_INCLUDE_NONE #include "../include/GLFW/glfw3.h" +#include + #define _GLFW_INSERT_FIRST 0 #define _GLFW_INSERT_LAST 1 diff --git a/src/wl_platform.h b/src/wl_platform.h index 2a843b3c..f3e8cba2 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -28,8 +28,6 @@ #include #include -#include - typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef struct VkWaylandSurfaceCreateInfoKHR From 3573c5a890b4878bb7357f71daaf49260c6fef15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Mar 2024 21:00:08 +0100 Subject: [PATCH 08/15] Wayland: Fix segfault when there is no seat Bug encountered running on a headless instance of Weston. Fixes #2517 --- CONTRIBUTORS.md | 1 + README.md | 1 + src/wl_init.c | 13 +++++++------ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c4c74ade..e04a68c3 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -48,6 +48,7 @@ video tutorials. - Andrew Corrigan - Bailey Cosier - Noel Cower + - James Cowgill - CuriouserThing - Bill Currie - Jason Daly diff --git a/README.md b/README.md index 825329ca..4bccdb29 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ information on what to include when reporting a bug. - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond the limit of the mouse button tokens to be reported (#2423) - [Wayland] Bugfix: The fractional scaling related objects were not destroyed + - [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517) - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` diff --git a/src/wl_init.c b/src/wl_init.c index 025d46e5..76054bc6 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -137,6 +137,13 @@ static void registryHandleGlobal(void* userData, wl_registry_bind(registry, name, &wl_seat_interface, _glfw_min(4, version)); _glfwAddSeatListenerWayland(_glfw.wl.seat); + + 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); + } } } else if (strcmp(interface, "wl_data_device_manager") == 0) @@ -853,12 +860,6 @@ int _glfwInitWayland(void) } } - 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); - } - if (!_glfw.wl.wmBase) { _glfwInputError(GLFW_PLATFORM_ERROR, From 228e58262e18f2ee61799bd86d0be718b1e31f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Mar 2024 21:02:10 +0100 Subject: [PATCH 09/15] EGL: Allow native access with defaults on Wayland The intent of enforcing GLFW_EGL_CONTEXT_API for EGL native access functions was to ensure that the application had requested the same context creation API at window creation time that it then attempted native access for. With the 3.4 ABI this both isn't true anymore, as a single binary may have multiple meanings of GLFW_NATIVE_CONTEXT_API, and is no longer necessary, since glfwGetPlatform provides enough information to disambiguate even without knowing what GLFW_PLATFORM was set to. This all leaves the requirement that the context creation API be GLFW_EGL_CONTEXT_API as just an unnecessary annoyance. Fixes #2518 --- CONTRIBUTORS.md | 1 + README.md | 2 ++ src/egl_context.c | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e04a68c3..1371aedb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -33,6 +33,7 @@ video tutorials. - Nicolas Caramelli - David Carlier - Arturo Castro + - Jose Luis Cercós Pita - Chi-kwan Chan - Victor Chernyakin - TheChocolateOre diff --git a/README.md b/README.md index 4bccdb29..2718e45e 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,8 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517) - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` + - [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to + `GLFW_NATIVE_CONTEXT_API` (#2518) ## Contact diff --git a/src/egl_context.c b/src/egl_context.c index b901c1be..517c64cb 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -915,8 +915,12 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) if (window->context.source != GLFW_EGL_CONTEXT_API) { - _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); - return EGL_NO_CONTEXT; + if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND || + window->context.source != GLFW_NATIVE_CONTEXT_API) + { + _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); + return EGL_NO_CONTEXT; + } } return window->context.egl.handle; @@ -931,8 +935,12 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) if (window->context.source != GLFW_EGL_CONTEXT_API) { - _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); - return EGL_NO_SURFACE; + if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND || + window->context.source != GLFW_NATIVE_CONTEXT_API) + { + _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); + return EGL_NO_CONTEXT; + } } return window->context.egl.surface; From 8b574030a847febcf90f365a9084dec1f2157d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 7 Apr 2024 19:26:01 +0200 Subject: [PATCH 10/15] Cocoa: Remove support for OS X 10.10 Yosemite Fixes #2506 --- .github/workflows/build.yml | 2 +- README.md | 3 ++- include/GLFW/glfw3.h | 4 ++-- src/cocoa_monitor.m | 6 +++--- src/cocoa_window.m | 6 ------ src/nsgl_context.m | 5 +---- 6 files changed, 9 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e980c547..8ef9ed79 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,7 +54,7 @@ jobs: timeout-minutes: 4 env: CFLAGS: -Werror - MACOSX_DEPLOYMENT_TARGET: 10.8 + MACOSX_DEPLOYMENT_TARGET: 10.11 CMAKE_OSX_ARCHITECTURES: x86_64;arm64 steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 2718e45e..ca8850e9 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ more information. ## System requirements -GLFW supports Windows XP and later and macOS 10.8 and later. Linux and other +GLFW supports Windows XP and later and macOS 10.11 and later. Linux and other Unix-like systems running the X Window System are supported even without a desktop environment or modern extensions, although some features require a running window or clipboard manager. The OSMesa backend requires Mesa 6.3. @@ -123,6 +123,7 @@ information on what to include when reporting a bug. - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond the limit of the mouse button tokens to be reported (#2423) + - [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506) - [Wayland] Bugfix: The fractional scaling related objects were not destroyed - [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517) - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index bed739dc..79b06288 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3183,8 +3183,8 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * - * @remark @macos On OS X 10.10 and later the window frame will not be rendered - * at full resolution on Retina displays unless the + * @remark @macos The window frame will not be rendered at full resolution on + * Retina displays unless the * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the * application bundle's `Info.plist`. For more information, see diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 1abf6ff5..6495e1f3 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -137,7 +137,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode) if (flags & kDisplayModeStretchedFlag) return GLFW_FALSE; -#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 +#if MAC_OS_X_VERSION_MAX_ALLOWED == 101100 CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) @@ -164,7 +164,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, if (result.refreshRate == 0) result.refreshRate = (int) round(fallbackRefreshRate); -#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 +#if MAC_OS_X_VERSION_MAX_ALLOWED == 101100 CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) { @@ -180,7 +180,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, result.blueBits = 8; } -#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 +#if MAC_OS_X_VERSION_MAX_ALLOWED == 101100 CFRelease(format); #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ return result; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 780bc7d3..97626a90 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -310,7 +310,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)windowDidChangeOcclusionState:(NSNotification* )notification { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 if ([window->ns.object respondsToSelector:@selector(occlusionState)]) { if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible) @@ -318,7 +317,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; else window->ns.occluded = GLFW_TRUE; } -#endif } @end @@ -1950,7 +1948,6 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, { @autoreleasepool { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 // HACK: Dynamically load Core Animation to avoid adding an extra // dependency for the majority who don't use MoltenVK NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"]; @@ -2027,9 +2024,6 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, } return err; -#else - return VK_ERROR_EXTENSION_NOT_PRESENT; -#endif } // autoreleasepool } diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 57f117ba..e728fc6e 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -218,14 +218,11 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching); } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 if (ctxconfig->major >= 4) { SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); } - else -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - if (ctxconfig->major >= 3) + else if (ctxconfig->major >= 3) { SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); } From 97892c60373f2e3c12e3f119d3788ad38a18c170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 7 Apr 2024 19:39:52 +0200 Subject: [PATCH 11/15] Cocoa: Add QuartzCore as a link-time dependency --- README.md | 1 + docs/build.md | 6 +++--- src/CMakeLists.txt | 5 +++-- src/cocoa_window.m | 14 +++----------- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ca8850e9..9447dcf1 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ information on what to include when reporting a bug. - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond the limit of the mouse button tokens to be reported (#2423) + - [Cocoa] Added `QuartzCore` framework as link-time dependency - [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506) - [Wayland] Bugfix: The fractional scaling related objects were not destroyed - [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517) diff --git a/docs/build.md b/docs/build.md index ab4b6817..7b0f8bfe 100644 --- a/docs/build.md +++ b/docs/build.md @@ -390,8 +390,8 @@ If you are using the dynamic library version of GLFW, add it to the project dependencies. If you are using the static library version of GLFW, add it and the Cocoa, -OpenGL and IOKit frameworks to the project as dependencies. They can all be -found in `/System/Library/Frameworks`. +OpenGL, IOKit and QuartzCore frameworks to the project as dependencies. They +can all be found in `/System/Library/Frameworks`. ### With command-line or makefile on macOS {#build_link_osx} @@ -405,7 +405,7 @@ command-line yourself using the `-l` and `-framework` switches. If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do: ```sh -cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit +cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework QuartzCore ``` If you are using the static library, named `libglfw3.a`, substitute `-lglfw3` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1057a6f9..463b898d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -151,10 +151,11 @@ endif() if (GLFW_BUILD_COCOA) target_link_libraries(glfw PRIVATE "-framework Cocoa" "-framework IOKit" - "-framework CoreFoundation") + "-framework CoreFoundation" + "-framework QuartzCore") set(glfw_PKG_DEPS "") - set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation") + set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework QuartzCore") endif() if (GLFW_BUILD_WAYLAND) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 97626a90..e69b5fe0 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -28,6 +28,8 @@ #if defined(_GLFW_COCOA) +#import + #include #include #include @@ -1948,18 +1950,8 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, { @autoreleasepool { - // HACK: Dynamically load Core Animation to avoid adding an extra - // dependency for the majority who don't use MoltenVK - NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"]; - if (!bundle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Cocoa: Failed to find QuartzCore.framework"); - return VK_ERROR_EXTENSION_NOT_PRESENT; - } - // NOTE: Create the layer here as makeBackingLayer should not return nil - window->ns.layer = [[bundle classNamed:@"CAMetalLayer"] layer]; + window->ns.layer = [CAMetalLayer layer]; if (!window->ns.layer) { _glfwInputError(GLFW_PLATFORM_ERROR, From dfebad786d2bc00b2d63ff71b3fbeb75a1e513d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 7 Apr 2024 20:03:37 +0200 Subject: [PATCH 12/15] Update macOS OpenGL compatibility notes --- docs/compat.md | 35 +++++++++++++++++++---------------- src/nsgl_context.m | 8 ++++---- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/docs/compat.md b/docs/compat.md index ef64b0cc..5072d5c1 100644 --- a/docs/compat.md +++ b/docs/compat.md @@ -242,24 +242,27 @@ extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect. ## OpenGL on macOS {#compat_osx} -Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then -only forward-compatible, core profile contexts are supported. Support for -OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible, -core profile contexts. There is also still no mechanism for requesting debug -contexts or no-error contexts. Versions of Mac OS X earlier than 10.7 support -at most OpenGL version 2.1. +macOS (as of version 14) still provides OpenGL but it has been deprecated by +Apple. While the API is still available, it is poorly maintained and frequently +develops new issues. On modern systems, OpenGL is implemented on top of Metal +and is not fully thread-safe. -Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and -`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if -given version 3.0 or 3.1. The `GLFW_OPENGL_PROFILE` hint must be set to -`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts. The -`GLFW_CONTEXT_DEBUG` and `GLFW_CONTEXT_NO_ERROR` hints are ignored. +macOS does not support OpenGL stereo rendering. If the `GLFW_STEREO` hint is +set to true, OpenGL context creation will always fail. -Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and -`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, -setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to -a non-default value will cause @ref glfwCreateWindow to fail and the -`GLFW_CONTEXT_DEBUG` hint is ignored. +macOS only supports OpenGL core profile contexts that are forward-compatible, +but the `GLFW_OPENGL_FORWARD_COMPAT` hint is ignored since GLFW 3.4. Even if +this hint is set to false (the default), a forward-compatible context will be +returned if available. + +macOS does not support OpenGL debug contexts, no-error contexts or robustness. +The `GLFW_CONTEXT_DEBUG`, `GLFW_CONTEXT_NO_ERROR` and `GLFW_CONTEXT_ROBUSTNESS` +hints will be ignored and a context without these features will be returned. + +macOS does not flush OpenGL contexts when they are made non-current. The +`GLFW_CONTEXT_RELEASE_BEHAVIOR` hint is ignored and the release behavior will +always be the equivalent of `GLFW_RELEASE_BEHAVIOR_NONE`. If you need a context +to be flushed, call `glFlush` before making it non-current. ## Vulkan loader and API {#compat_vulkan} diff --git a/src/nsgl_context.m b/src/nsgl_context.m index e728fc6e..df729800 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -183,16 +183,16 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, return GLFW_FALSE; } - // Context robustness modes (GL_KHR_robustness) are not yet supported by + // Context robustness modes (GL_KHR_robustness) are not supported by // macOS but are not a hard constraint, so ignore and continue - // Context release behaviors (GL_KHR_context_flush_control) are not yet + // Context release behaviors (GL_KHR_context_flush_control) are not // supported by macOS but are not a hard constraint, so ignore and continue - // Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not + // Debug contexts (GL_KHR_debug) are not supported by macOS but are not // a hard constraint, so ignore and continue - // No-error contexts (GL_KHR_no_error) are not yet supported by macOS but + // No-error contexts (GL_KHR_no_error) are not supported by macOS but // are not a hard constraint, so ignore and continue #define ADD_ATTRIB(a) \ From 51b6434ac46a3a8b852679486f57b5e924b312dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 8 Apr 2024 18:50:08 +0200 Subject: [PATCH 13/15] Wayland: Fix possible segfault on drag enter Found with Clang static analysis. --- README.md | 1 + src/wl_window.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9447dcf1..10044faf 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ information on what to include when reporting a bug. - [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506) - [Wayland] Bugfix: The fractional scaling related objects were not destroyed - [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517) + - [Wayland] Bugfix: A drag entering a non-GLFW surface could cause a segfault - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` - [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to diff --git a/src/wl_window.c b/src/wl_window.c index dc7dcd07..7ace6b4b 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1986,7 +1986,7 @@ static void dataDeviceHandleEnter(void* userData, window = wl_surface_get_user_data(surface); } - if (surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list) + if (window && surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list) { _glfw.wl.dragOffer = offer; _glfw.wl.dragFocus = window; From 64906f8e64c873399025fc78133e8616173713cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 8 Apr 2024 18:50:08 +0200 Subject: [PATCH 14/15] Wayland: Cleanup --- 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 7ace6b4b..96f80399 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1974,41 +1974,41 @@ static void dataDeviceHandleEnter(void* userData, _glfw.wl.dragFocus = NULL; } - for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + unsigned int i; + + for (i = 0; i < _glfw.wl.offerCount; i++) { if (_glfw.wl.offers[i].offer == offer) + break; + } + + if (i == _glfw.wl.offerCount) + return; + + if (surface && wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag) + { + _GLFWwindow* window = wl_surface_get_user_data(surface); + if (window->wl.surface == surface) { - _GLFWwindow* window = NULL; - - if (surface) - { - if (wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag) - window = wl_surface_get_user_data(surface); - } - - if (window && surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list) + if (_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--; - break; + wl_data_offer_accept(offer, serial, "text/uri-list"); + } } } - 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 + if (!_glfw.wl.dragOffer) { wl_data_offer_accept(offer, serial, NULL); wl_data_offer_destroy(offer); } + + _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1]; + _glfw.wl.offerCount--; } static void dataDeviceHandleLeave(void* userData, From b35641f4a3c62aa86a0b3c983d163bc0fe36026d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 12 Apr 2024 18:25:19 +0200 Subject: [PATCH 15/15] Wayland: Cleanup --- src/wl_window.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 96f80399..2e842aaa 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2042,15 +2042,17 @@ static void dataDeviceHandleDrop(void* userData, int count; char** paths = _glfwParseUriList(string, &count); if (paths) + { _glfwInputDrop(_glfw.wl.dragFocus, count, (const char**) paths); - for (int i = 0; i < count; i++) - _glfw_free(paths[i]); + for (int i = 0; i < count; i++) + _glfw_free(paths[i]); - _glfw_free(paths); + _glfw_free(paths); + } + + _glfw_free(string); } - - _glfw_free(string); } static void dataDeviceHandleSelection(void* userData,