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 1/8] 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 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 8/8] 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;