Compare commits

..

2 Commits

Author SHA1 Message Date
Camilla Löwy 413ba1dceb Wayland: Fix EGL buffer swap blocking indefinitely
This re-implements the wait for a surface frame that previously happened
inside EGL, so that we can add a reasonable timeout.  That allows
applications to make progress despite the window being suspended.

This initial implementation still has a race between glfwHideWindow and
glfwSwapBuffers when rendering on a separate thread.

Related to #1350
Related to #2582
Related to #2640
Related to #2719
Related to #2723
Related to #2800
2026-02-20 16:28:19 +01:00
Camilla Löwy e59b5e1fda Fix cleanup on success in threaded rendering test 2026-02-18 19:13:16 +01:00
31 changed files with 350 additions and 394 deletions
+3 -3
View File
@@ -17,7 +17,7 @@ jobs:
CC: clang CC: clang
CFLAGS: -Werror CFLAGS: -Werror
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update sudo apt update
@@ -57,7 +57,7 @@ jobs:
MACOSX_DEPLOYMENT_TARGET: 10.11 MACOSX_DEPLOYMENT_TARGET: 10.11
CMAKE_OSX_ARCHITECTURES: x86_64;arm64 CMAKE_OSX_ARCHITECTURES: x86_64;arm64
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Configure Null shared library - name: Configure Null shared library
run: cmake -B build-null-shared -D GLFW_BUILD_COCOA=OFF -D BUILD_SHARED_LIBS=ON run: cmake -B build-null-shared -D GLFW_BUILD_COCOA=OFF -D BUILD_SHARED_LIBS=ON
@@ -81,7 +81,7 @@ jobs:
env: env:
CFLAGS: /WX CFLAGS: /WX
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Configure Win32 shared x86 library - name: Configure Win32 shared x86 library
run: cmake -B build-win32-shared-x86 -G "Visual Studio 17 2022" -A Win32 -D BUILD_SHARED_LIBS=ON run: cmake -B build-win32-shared-x86 -G "Visual Studio 17 2022" -A Win32 -D BUILD_SHARED_LIBS=ON
-4
View File
@@ -10,7 +10,6 @@ video tutorials.
- Matt Arsenault - Matt Arsenault
- Takuro Ashie - Takuro Ashie
- ashishgamedev - ashishgamedev
- avagordon01
- David Avedissian - David Avedissian
- Luca Bacci - Luca Bacci
- Keith Bauer - Keith Bauer
@@ -57,7 +56,6 @@ video tutorials.
- Jason Daly - Jason Daly
- danhambleton - danhambleton
- Jarrod Davis - Jarrod Davis
- Aaron Day
- decce - decce
- Olivier Delannoy - Olivier Delannoy
- Paul R. Deppe - Paul R. Deppe
@@ -77,7 +75,6 @@ video tutorials.
- Nikita Fediuchin - Nikita Fediuchin
- Felipe Ferreira - Felipe Ferreira
- Michael Fogleman - Michael Fogleman
- Folling
- forworldm - forworldm
- Jason Francis - Jason Francis
- Gerald Franz - Gerald Franz
@@ -164,7 +161,6 @@ video tutorials.
- Bryce Mehring - Bryce Mehring
- Jonathan Mercier - Jonathan Mercier
- Marcel Metz - Marcel Metz
- Lucas Michaudel
- Liam Middlebrook - Liam Middlebrook
- mightgoyardstill - mightgoyardstill
- Mihail - Mihail
+1 -4
View File
@@ -152,11 +152,8 @@ information on what to include when reporting a bug.
- [Wayland] Bugfix: The `libwayland-client` library was not unloaded at termination - [Wayland] Bugfix: The `libwayland-client` library was not unloaded at termination
- [Wayland] Bugfix: Scroll events were sent twice on some versions of GNOME (#2494) - [Wayland] Bugfix: Scroll events were sent twice on some versions of GNOME (#2494)
- [Wayland] Bugfix: Two-dimensional scroll input was emitted as separate axes - [Wayland] Bugfix: Two-dimensional scroll input was emitted as separate axes
- [Wayland] Bugfix: Mouse wheel scroll distance was incorrect on some compositors
- [Wayland] Bugfix: `glfwSwapBuffers` would halt with nonzero swap interval when window - [Wayland] Bugfix: `glfwSwapBuffers` would halt with nonzero swap interval when window
was suspended (#1350,#2582,#2640,#2719,#2723,#2800,#2827) was suspended (#1350,#2582,#2640,#2719,#2723,#2800)
- [Wayland] Bugfix: `glfwPostEmptyEvent` would leak a callback proxy (#2836)
- [Wayland] Bugfix: `glfwHideWindow` did not always send its request immediately
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631) - [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
- [X11] Bugfix: Occasional crash when an idle display awakes (#2766) - [X11] Bugfix: Occasional crash when an idle display awakes (#2766)
- [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale - [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale
-8
View File
@@ -1344,10 +1344,6 @@ extern "C" {
#define GLFW_PLATFORM_NULL 0x00060005 #define GLFW_PLATFORM_NULL 0x00060005
/*! @} */ /*! @} */
/* Reserved platform define for external Emscripten ports: 0x00060006
* See https://github.com/pongasoft/emscripten-glfw
*/
#define GLFW_DONT_CARE -1 #define GLFW_DONT_CARE -1
@@ -6174,10 +6170,6 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
* *
* @remark __Wayland:__ When the swap interval is greater than zero and the
* window is not in view, this function may take a few extra milliseconds to
* return.
*
* @remark __EGL:__ The context of the specified window must be current on the * @remark __EGL:__ The context of the specified window must be current on the
* calling thread. * calling thread.
* *
+5 -10
View File
@@ -10,7 +10,7 @@ add_library(glfw ${GLFW_LIBRARY_TYPE}
# The time, thread and module code is shared between all backends on a given OS, # The time, thread and module code is shared between all backends on a given OS,
# including the null backend, which still needs those bits to be functional # including the null backend, which still needs those bits to be functional
if (APPLE) if (APPLE)
target_sources(glfw PRIVATE macos_time.h macos_time.c posix_thread.h target_sources(glfw PRIVATE cocoa_time.h cocoa_time.c posix_thread.h
posix_module.c posix_thread.c) posix_module.c posix_thread.c)
elseif (WIN32) elseif (WIN32)
target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c
@@ -46,7 +46,7 @@ endif()
if (GLFW_BUILD_X11) if (GLFW_BUILD_X11)
target_compile_definitions(glfw PRIVATE _GLFW_X11) target_compile_definitions(glfw PRIVATE _GLFW_X11)
target_sources(glfw PRIVATE x11_platform.h x11_init.c target_sources(glfw PRIVATE x11_platform.h xkb_unicode.h x11_init.c
x11_monitor.c x11_window.c xkb_unicode.c x11_monitor.c x11_window.c xkb_unicode.c
glx_context.c) glx_context.c)
endif() endif()
@@ -145,11 +145,11 @@ endif()
if (GLFW_BUILD_COCOA) if (GLFW_BUILD_COCOA)
target_link_libraries(glfw PRIVATE "-framework Cocoa" target_link_libraries(glfw PRIVATE "-framework Cocoa"
"-framework IOKit" "-framework IOKit"
"-framework CoreFoundation"
"-framework QuartzCore") "-framework QuartzCore")
list(APPEND glfw_PKG_LIBS "-framework Cocoa" set(glfw_PKG_DEPS "")
"-framework IOKit" set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework QuartzCore")
"-framework QuartzCore")
endif() endif()
if (GLFW_BUILD_WAYLAND) if (GLFW_BUILD_WAYLAND)
@@ -234,11 +234,6 @@ if (UNIX AND NOT APPLE)
endif() endif()
endif() endif()
if (APPLE)
target_link_libraries(glfw PRIVATE "-framework CoreFoundation")
list(APPEND glfw_PKG_LIBS "-framework CoreFoundation")
endif()
if (WIN32) if (WIN32)
if (GLFW_USE_HYBRID_HPG) if (GLFW_USE_HYBRID_HPG)
target_compile_definitions(glfw PRIVATE _GLFW_USE_HYBRID_HPG) target_compile_definitions(glfw PRIVATE _GLFW_USE_HYBRID_HPG)
+36 -1
View File
@@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.5 Cocoa - www.glfw.org // GLFW 3.5 macOS - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// //
@@ -450,6 +450,41 @@ static GLFWbool initializeTIS(void)
@end // GLFWApplicationDelegate @end // GLFWApplicationDelegate
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwLoadLocalVulkanLoaderCocoa(void)
{
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return NULL;
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
if (!frameworksUrl)
return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX];
void* handle = NULL;
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfwPlatformLoadModule(path);
CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.5 Cocoa - www.glfw.org // GLFW 3.5 macOS - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
+3 -1
View File
@@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.5 Cocoa - www.glfw.org // GLFW 3.5 macOS - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// //
@@ -291,6 +291,8 @@ void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
float _glfwTransformYCocoa(float y); float _glfwTransformYCocoa(float y);
void* _glfwLoadLocalVulkanLoaderCocoa(void);
GLFWbool _glfwInitNSGL(void); GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void); void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
+4 -4
View File
@@ -26,7 +26,7 @@
#include "internal.h" #include "internal.h"
#if defined(GLFW_BUILD_MACOS_TIMER) #if defined(GLFW_BUILD_COCOA_TIMER)
#include <mach/mach_time.h> #include <mach/mach_time.h>
@@ -40,7 +40,7 @@ void _glfwPlatformInitTimer(void)
mach_timebase_info_data_t info; mach_timebase_info_data_t info;
mach_timebase_info(&info); mach_timebase_info(&info);
_glfw.timer.macos.frequency = (info.denom * 1e9) / info.numer; _glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
} }
uint64_t _glfwPlatformGetTimerValue(void) uint64_t _glfwPlatformGetTimerValue(void)
@@ -50,8 +50,8 @@ uint64_t _glfwPlatformGetTimerValue(void)
uint64_t _glfwPlatformGetTimerFrequency(void) uint64_t _glfwPlatformGetTimerFrequency(void)
{ {
return _glfw.timer.macos.frequency; return _glfw.timer.ns.frequency;
} }
#endif // GLFW_BUILD_MACOS_TIMER #endif // GLFW_BUILD_COCOA_TIMER
+4 -4
View File
@@ -24,12 +24,12 @@
// //
//======================================================================== //========================================================================
#define GLFW_MACOS_LIBRARY_TIMER_STATE _GLFWtimerMacOS macos; #define GLFW_COCOA_LIBRARY_TIMER_STATE _GLFWtimerNS ns;
// macOS-specific global timer data // Cocoa-specific global timer data
// //
typedef struct _GLFWtimerMacOS typedef struct _GLFWtimerNS
{ {
uint64_t frequency; uint64_t frequency;
} _GLFWtimerMacOS; } _GLFWtimerNS;
+1 -1
View File
@@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.5 Cocoa - www.glfw.org // GLFW 3.5 macOS - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org> // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// //
+1 -1
View File
@@ -195,7 +195,7 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
{ {
current = alternatives + i; current = alternatives + i;
if (desired->stereo && !current->stereo) if (desired->stereo > 0 && current->stereo == 0)
{ {
// Stereo is a hard constraint // Stereo is a hard constraint
continue; continue;
+1 -2
View File
@@ -32,7 +32,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
// Return a description of the specified EGL error // Return a description of the specified EGL error
// //
static const char* getEGLErrorString(EGLint error) static const char* getEGLErrorString(EGLint error)
@@ -675,7 +674,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (ctxconfig->noerror) if (ctxconfig->noerror)
{ {
if (_glfw.egl.KHR_create_context_no_error) if (_glfw.egl.KHR_create_context_no_error)
SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true); SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
} }
if (mask) if (mask)
+15 -13
View File
@@ -119,7 +119,9 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS); u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
u->stereo = getGLXFBConfigAttrib(n, GLX_STEREO);
if (getGLXFBConfigAttrib(n, GLX_STEREO))
u->stereo = GLFW_TRUE;
if (_glfw.glx.ARB_multisample) if (_glfw.glx.ARB_multisample)
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES); u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
@@ -365,7 +367,7 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalEXT"); getProcAddressGLX("glXSwapIntervalEXT");
if (_glfw.glx.SwapIntervalEXT) if (_glfw.glx.SwapIntervalEXT)
_glfw.glx.EXT_swap_control = true; _glfw.glx.EXT_swap_control = GLFW_TRUE;
} }
if (extensionSupportedGLX("GLX_SGI_swap_control")) if (extensionSupportedGLX("GLX_SGI_swap_control"))
@@ -374,7 +376,7 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalSGI"); getProcAddressGLX("glXSwapIntervalSGI");
if (_glfw.glx.SwapIntervalSGI) if (_glfw.glx.SwapIntervalSGI)
_glfw.glx.SGI_swap_control = true; _glfw.glx.SGI_swap_control = GLFW_TRUE;
} }
if (extensionSupportedGLX("GLX_MESA_swap_control")) if (extensionSupportedGLX("GLX_MESA_swap_control"))
@@ -383,17 +385,17 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalMESA"); getProcAddressGLX("glXSwapIntervalMESA");
if (_glfw.glx.SwapIntervalMESA) if (_glfw.glx.SwapIntervalMESA)
_glfw.glx.MESA_swap_control = true; _glfw.glx.MESA_swap_control = GLFW_TRUE;
} }
if (extensionSupportedGLX("GLX_ARB_multisample")) if (extensionSupportedGLX("GLX_ARB_multisample"))
_glfw.glx.ARB_multisample = true; _glfw.glx.ARB_multisample = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB")) if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
_glfw.glx.ARB_framebuffer_sRGB = true; _glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB")) if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
_glfw.glx.EXT_framebuffer_sRGB = true; _glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context")) if (extensionSupportedGLX("GLX_ARB_create_context"))
{ {
@@ -401,23 +403,23 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXCreateContextAttribsARB"); getProcAddressGLX("glXCreateContextAttribsARB");
if (_glfw.glx.CreateContextAttribsARB) if (_glfw.glx.CreateContextAttribsARB)
_glfw.glx.ARB_create_context = true; _glfw.glx.ARB_create_context = GLFW_TRUE;
} }
if (extensionSupportedGLX("GLX_ARB_create_context_robustness")) if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
_glfw.glx.ARB_create_context_robustness = true; _glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context_profile")) if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
_glfw.glx.ARB_create_context_profile = true; _glfw.glx.ARB_create_context_profile = GLFW_TRUE;
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile")) if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
_glfw.glx.EXT_create_context_es2_profile = true; _glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context_no_error")) if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
_glfw.glx.ARB_create_context_no_error = true; _glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_context_flush_control")) if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
_glfw.glx.ARB_context_flush_control = true; _glfw.glx.ARB_context_flush_control = GLFW_TRUE;
return GLFW_TRUE; return GLFW_TRUE;
} }
+4 -4
View File
@@ -49,18 +49,18 @@ static GLFWerrorfun _glfwErrorCallback;
static GLFWallocator _glfwInitAllocator; static GLFWallocator _glfwInitAllocator;
static _GLFWinitconfig _glfwInitHints = static _GLFWinitconfig _glfwInitHints =
{ {
.hatButtons = true, .hatButtons = GLFW_TRUE,
.angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE, .angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE,
.platformID = GLFW_ANY_PLATFORM, .platformID = GLFW_ANY_PLATFORM,
.vulkanLoader = NULL, .vulkanLoader = NULL,
.ns = .ns =
{ {
.menubar = true, .menubar = GLFW_TRUE,
.chdir = true .chdir = GLFW_TRUE
}, },
.x11 = .x11 =
{ {
.xcbVulkanSurface = true, .xcbVulkanSurface = GLFW_TRUE,
}, },
.wl = .wl =
{ {
+11 -7
View File
@@ -333,8 +333,10 @@ void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
{ {
assert(window != NULL); assert(window != NULL);
assert(isfinite(xoffset)); assert(xoffset > -FLT_MAX);
assert(isfinite(yoffset)); assert(xoffset < FLT_MAX);
assert(yoffset > -FLT_MAX);
assert(yoffset < FLT_MAX);
if (window->callbacks.scroll) if (window->callbacks.scroll)
window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset); window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
@@ -373,8 +375,10 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
{ {
assert(window != NULL); assert(window != NULL);
assert(isfinite(xpos)); assert(xpos > -FLT_MAX);
assert(isfinite(ypos)); assert(xpos < FLT_MAX);
assert(ypos > -FLT_MAX);
assert(ypos < FLT_MAX);
if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos) if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
return; return;
@@ -432,7 +436,6 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
assert(js != NULL); assert(js != NULL);
assert(axis >= 0); assert(axis >= 0);
assert(axis < js->axisCount); assert(axis < js->axisCount);
assert(isfinite(value));
js->axes[axis] = value; js->axes[axis] = value;
} }
@@ -815,7 +818,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
if (!isfinite(xpos) || !isfinite(ypos)) if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)
{ {
_glfwInputError(GLFW_INVALID_VALUE, _glfwInputError(GLFW_INVALID_VALUE,
"Invalid cursor position %f %f", "Invalid cursor position %f %f",
@@ -1495,7 +1499,7 @@ GLFWAPI void glfwSetTime(double time)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (!isfinite(time) || time < 0.0 || time > 18446744073.0) if (time != time || time < 0.0 || time > 18446744073.0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", time); _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", time);
return; return;
+50 -50
View File
@@ -375,16 +375,16 @@ struct _GLFWerror
// //
struct _GLFWinitconfig struct _GLFWinitconfig
{ {
bool hatButtons; GLFWbool hatButtons;
int angleType; int angleType;
int platformID; int platformID;
PFN_vkGetInstanceProcAddr vulkanLoader; PFN_vkGetInstanceProcAddr vulkanLoader;
struct { struct {
bool menubar; GLFWbool menubar;
bool chdir; GLFWbool chdir;
} ns; } ns;
struct { struct {
bool xcbVulkanSurface; GLFWbool xcbVulkanSurface;
} x11; } x11;
struct { struct {
int libdecorMode; int libdecorMode;
@@ -403,18 +403,18 @@ struct _GLFWwndconfig
int ypos; int ypos;
int width; int width;
int height; int height;
bool resizable; GLFWbool resizable;
bool visible; GLFWbool visible;
bool decorated; GLFWbool decorated;
bool focused; GLFWbool focused;
bool autoIconify; GLFWbool autoIconify;
bool floating; GLFWbool floating;
bool maximized; GLFWbool maximized;
bool centerCursor; GLFWbool centerCursor;
bool focusOnShow; GLFWbool focusOnShow;
bool mousePassthrough; GLFWbool mousePassthrough;
bool scaleToMonitor; GLFWbool scaleToMonitor;
bool scaleFramebuffer; GLFWbool scaleFramebuffer;
struct { struct {
char frameName[256]; char frameName[256];
} ns; } ns;
@@ -423,8 +423,8 @@ struct _GLFWwndconfig
char instanceName[256]; char instanceName[256];
} x11; } x11;
struct { struct {
bool keymenu; GLFWbool keymenu;
bool showDefault; GLFWbool showDefault;
} win32; } win32;
struct { struct {
char appId[256]; char appId[256];
@@ -443,15 +443,15 @@ struct _GLFWctxconfig
int source; int source;
int major; int major;
int minor; int minor;
bool forward; GLFWbool forward;
bool debug; GLFWbool debug;
bool noerror; GLFWbool noerror;
int profile; int profile;
int robustness; int robustness;
int release; int release;
_GLFWwindow* share; _GLFWwindow* share;
struct { struct {
bool offline; GLFWbool offline;
} nsgl; } nsgl;
}; };
@@ -476,11 +476,11 @@ struct _GLFWfbconfig
int accumBlueBits; int accumBlueBits;
int accumAlphaBits; int accumAlphaBits;
int auxBuffers; int auxBuffers;
bool stereo; GLFWbool stereo;
int samples; int samples;
bool sRGB; GLFWbool sRGB;
bool doublebuffer; GLFWbool doublebuffer;
bool transparent; GLFWbool transparent;
uintptr_t handle; uintptr_t handle;
}; };
@@ -807,22 +807,22 @@ struct _GLFWlibrary
EGLint major, minor; EGLint major, minor;
GLFWbool prefix; GLFWbool prefix;
bool KHR_create_context; GLFWbool KHR_create_context;
bool KHR_create_context_no_error; GLFWbool KHR_create_context_no_error;
bool KHR_gl_colorspace; GLFWbool KHR_gl_colorspace;
bool KHR_get_all_proc_addresses; GLFWbool KHR_get_all_proc_addresses;
bool KHR_context_flush_control; GLFWbool KHR_context_flush_control;
bool EXT_client_extensions; GLFWbool EXT_client_extensions;
bool EXT_platform_base; GLFWbool EXT_platform_base;
bool EXT_platform_x11; GLFWbool EXT_platform_x11;
bool EXT_platform_wayland; GLFWbool EXT_platform_wayland;
bool EXT_present_opaque; GLFWbool EXT_present_opaque;
bool ANGLE_platform_angle; GLFWbool ANGLE_platform_angle;
bool ANGLE_platform_angle_opengl; GLFWbool ANGLE_platform_angle_opengl;
bool ANGLE_platform_angle_d3d; GLFWbool ANGLE_platform_angle_d3d;
bool ANGLE_platform_angle_vulkan; GLFWbool ANGLE_platform_angle_vulkan;
bool ANGLE_platform_angle_metal; GLFWbool ANGLE_platform_angle_metal;
bool MESA_platform_surfaceless; GLFWbool MESA_platform_surfaceless;
void* handle; void* handle;
@@ -866,14 +866,14 @@ struct _GLFWlibrary
void* handle; void* handle;
char* extensions[2]; char* extensions[2];
PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
bool KHR_surface; GLFWbool KHR_surface;
bool KHR_win32_surface; GLFWbool KHR_win32_surface;
bool MVK_macos_surface; GLFWbool MVK_macos_surface;
bool EXT_metal_surface; GLFWbool EXT_metal_surface;
bool KHR_xlib_surface; GLFWbool KHR_xlib_surface;
bool KHR_xcb_surface; GLFWbool KHR_xcb_surface;
bool KHR_wayland_surface; GLFWbool KHR_wayland_surface;
bool EXT_headless_surface; GLFWbool EXT_headless_surface;
} vk; } vk;
struct { struct {
+2 -3
View File
@@ -467,15 +467,14 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
unsigned short* values; unsigned short* values;
GLFWgammaramp ramp; GLFWgammaramp ramp;
const GLFWgammaramp* original; const GLFWgammaramp* original;
assert(gamma > 0.f); assert(gamma > 0.f);
assert(isfinite(gamma)); assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
assert(handle != NULL); assert(handle != NULL);
if (!isfinite(gamma) || gamma <= 0.f) if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma); _glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
return; return;
+5 -6
View File
@@ -28,7 +28,7 @@
#if defined(GLFW_BUILD_WIN32_TIMER) || \ #if defined(GLFW_BUILD_WIN32_TIMER) || \
defined(GLFW_BUILD_WIN32_MODULE) || \ defined(GLFW_BUILD_WIN32_MODULE) || \
defined(GLFW_BUILD_WIN32_THREAD) || \ defined(GLFW_BUILD_WIN32_THREAD) || \
defined(GLFW_BUILD_MACOS_TIMER) || \ defined(GLFW_BUILD_COCOA_TIMER) || \
defined(GLFW_BUILD_POSIX_TIMER) || \ defined(GLFW_BUILD_POSIX_TIMER) || \
defined(GLFW_BUILD_POSIX_MODULE) || \ defined(GLFW_BUILD_POSIX_MODULE) || \
defined(GLFW_BUILD_POSIX_THREAD) || \ defined(GLFW_BUILD_POSIX_THREAD) || \
@@ -184,7 +184,7 @@
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_BUILD_WIN32_TIMER #define GLFW_BUILD_WIN32_TIMER
#elif defined(__APPLE__) #elif defined(__APPLE__)
#define GLFW_BUILD_MACOS_TIMER #define GLFW_BUILD_COCOA_TIMER
#else #else
#define GLFW_BUILD_POSIX_TIMER #define GLFW_BUILD_POSIX_TIMER
#endif #endif
@@ -192,9 +192,9 @@
#if defined(GLFW_BUILD_WIN32_TIMER) #if defined(GLFW_BUILD_WIN32_TIMER)
#include "win32_time.h" #include "win32_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_MACOS_TIMER) #elif defined(GLFW_BUILD_COCOA_TIMER)
#include "macos_time.h" #include "cocoa_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_MACOS_LIBRARY_TIMER_STATE #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_POSIX_TIMER) #elif defined(GLFW_BUILD_POSIX_TIMER)
#include "posix_time.h" #include "posix_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
@@ -207,7 +207,6 @@
#endif #endif
#if defined(_GLFW_WAYLAND) || defined(_GLFW_X11) #if defined(_GLFW_WAYLAND) || defined(_GLFW_X11)
#include "posix_poll.h"
#define GLFW_BUILD_POSIX_POLL #define GLFW_BUILD_POSIX_POLL
#endif #endif
+11 -44
View File
@@ -34,40 +34,6 @@
#define _GLFW_FIND_LOADER 1 #define _GLFW_FIND_LOADER 1
#define _GLFW_REQUIRE_LOADER 2 #define _GLFW_REQUIRE_LOADER 2
#if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
static void* loadLocalVulkanLoaderMacOS(void)
{
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return NULL;
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
if (!frameworksUrl)
return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX];
void* handle = NULL;
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfwPlatformLoadModule(path);
CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle;
}
#endif // __APPLE__
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
@@ -91,10 +57,11 @@ GLFWbool _glfwInitVulkan(int mode)
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY); _glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
#elif defined(_WIN32) #elif defined(_WIN32)
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll"); _glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
#elif defined(__APPLE__) #elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib"); _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
if (!_glfw.vk.handle) if (!_glfw.vk.handle)
_glfw.vk.handle = loadLocalVulkanLoaderMacOS(); _glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
#elif defined(__APPLE__)
#elif defined(__OpenBSD__) || defined(__NetBSD__) #elif defined(__OpenBSD__) || defined(__NetBSD__)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so"); _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
#else #else
@@ -163,21 +130,21 @@ GLFWbool _glfwInitVulkan(int mode)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0) if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
_glfw.vk.KHR_surface = true; _glfw.vk.KHR_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = true; _glfw.vk.KHR_win32_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_glfw.vk.MVK_macos_surface = true; _glfw.vk.MVK_macos_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
_glfw.vk.EXT_metal_surface = true; _glfw.vk.EXT_metal_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = true; _glfw.vk.KHR_xlib_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
_glfw.vk.KHR_xcb_surface = true; _glfw.vk.KHR_xcb_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_glfw.vk.KHR_wayland_surface = true; _glfw.vk.KHR_wayland_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_EXT_headless_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_EXT_headless_surface") == 0)
_glfw.vk.EXT_headless_surface = true; _glfw.vk.EXT_headless_surface = GLFW_TRUE;
} }
_glfw_free(ep); _glfw_free(ep);
+14 -6
View File
@@ -186,22 +186,28 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB); u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB);
u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB); u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB);
u->stereo = FIND_ATTRIB_VALUE(WGL_STEREO_ARB);
if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB))
u->stereo = GLFW_TRUE;
if (_glfw.wgl.ARB_multisample) if (_glfw.wgl.ARB_multisample)
u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB); u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) if (_glfw.wgl.ARB_framebuffer_sRGB ||
u->sRGB = FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); _glfw.wgl.EXT_framebuffer_sRGB)
{
if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE;
}
} }
else else
{ {
if (_glfw.wgl.EXT_colorspace) if (_glfw.wgl.EXT_colorspace)
{ {
if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
u->sRGB = true; u->sRGB = GLFW_TRUE;
} }
} }
} }
@@ -255,7 +261,9 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
u->accumAlphaBits = pfd.cAccumAlphaBits; u->accumAlphaBits = pfd.cAccumAlphaBits;
u->auxBuffers = pfd.cAuxBuffers; u->auxBuffers = pfd.cAuxBuffers;
u->stereo = (pfd.dwFlags & PFD_STEREO);
if (pfd.dwFlags & PFD_STEREO)
u->stereo = GLFW_TRUE;
} }
u->handle = pixelFormat; u->handle = pixelFormat;
@@ -656,7 +664,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
if (ctxconfig->noerror) if (ctxconfig->noerror)
{ {
if (_glfw.wgl.ARB_create_context_no_error) if (_glfw.wgl.ARB_create_context_no_error)
SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, true); SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
} }
// NOTE: Only request an explicitly versioned context when necessary, as // NOTE: Only request an explicitly versioned context when necessary, as
+12 -12
View File
@@ -336,18 +336,18 @@ typedef struct _GLFWlibraryWGL
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT; PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB; PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
bool EXT_swap_control; GLFWbool EXT_swap_control;
bool EXT_colorspace; GLFWbool EXT_colorspace;
bool ARB_multisample; GLFWbool ARB_multisample;
bool ARB_framebuffer_sRGB; GLFWbool ARB_framebuffer_sRGB;
bool EXT_framebuffer_sRGB; GLFWbool EXT_framebuffer_sRGB;
bool ARB_pixel_format; GLFWbool ARB_pixel_format;
bool ARB_create_context; GLFWbool ARB_create_context;
bool ARB_create_context_profile; GLFWbool ARB_create_context_profile;
bool EXT_create_context_es2_profile; GLFWbool EXT_create_context_es2_profile;
bool ARB_create_context_robustness; GLFWbool ARB_create_context_robustness;
bool ARB_create_context_no_error; GLFWbool ARB_create_context_no_error;
bool ARB_context_flush_control; GLFWbool ARB_context_flush_control;
} _GLFWlibraryWGL; } _GLFWlibraryWGL;
// Win32-specific per-window data // Win32-specific per-window data
+39 -38
View File
@@ -32,7 +32,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <float.h> #include <float.h>
#include <math.h>
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW event API ////// ////// GLFW event API //////
@@ -135,9 +135,9 @@ void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscal
{ {
assert(window != NULL); assert(window != NULL);
assert(xscale > 0.f); assert(xscale > 0.f);
assert(isfinite(xscale)); assert(xscale < FLT_MAX);
assert(yscale > 0.f); assert(yscale > 0.f);
assert(isfinite(yscale)); assert(yscale < FLT_MAX);
if (window->callbacks.scale) if (window->callbacks.scale)
window->callbacks.scale((GLFWwindow*) window, xscale, yscale); window->callbacks.scale((GLFWwindow*) window, xscale, yscale);
@@ -265,16 +265,16 @@ void glfwDefaultWindowHints(void)
// The default is a focused, visible, resizable window with decorations // The default is a focused, visible, resizable window with decorations
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window)); memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
_glfw.hints.window.resizable = true; _glfw.hints.window.resizable = GLFW_TRUE;
_glfw.hints.window.visible = true; _glfw.hints.window.visible = GLFW_TRUE;
_glfw.hints.window.decorated = true; _glfw.hints.window.decorated = GLFW_TRUE;
_glfw.hints.window.focused = true; _glfw.hints.window.focused = GLFW_TRUE;
_glfw.hints.window.autoIconify = true; _glfw.hints.window.autoIconify = GLFW_TRUE;
_glfw.hints.window.centerCursor = true; _glfw.hints.window.centerCursor = GLFW_TRUE;
_glfw.hints.window.focusOnShow = true; _glfw.hints.window.focusOnShow = GLFW_TRUE;
_glfw.hints.window.xpos = GLFW_ANY_POSITION; _glfw.hints.window.xpos = GLFW_ANY_POSITION;
_glfw.hints.window.ypos = GLFW_ANY_POSITION; _glfw.hints.window.ypos = GLFW_ANY_POSITION;
_glfw.hints.window.scaleFramebuffer = true; _glfw.hints.window.scaleFramebuffer = GLFW_TRUE;
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
// double buffered // double buffered
@@ -285,7 +285,7 @@ void glfwDefaultWindowHints(void)
_glfw.hints.framebuffer.alphaBits = 8; _glfw.hints.framebuffer.alphaBits = 8;
_glfw.hints.framebuffer.depthBits = 24; _glfw.hints.framebuffer.depthBits = 24;
_glfw.hints.framebuffer.stencilBits = 8; _glfw.hints.framebuffer.stencilBits = 8;
_glfw.hints.framebuffer.doublebuffer = true; _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
// The default is to select the highest available refresh rate // The default is to select the highest available refresh rate
_glfw.hints.refreshRate = GLFW_DONT_CARE; _glfw.hints.refreshRate = GLFW_DONT_CARE;
@@ -331,40 +331,40 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.framebuffer.auxBuffers = value; _glfw.hints.framebuffer.auxBuffers = value;
return; return;
case GLFW_STEREO: case GLFW_STEREO:
_glfw.hints.framebuffer.stereo = value; _glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_DOUBLEBUFFER: case GLFW_DOUBLEBUFFER:
_glfw.hints.framebuffer.doublebuffer = value; _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_TRANSPARENT_FRAMEBUFFER: case GLFW_TRANSPARENT_FRAMEBUFFER:
_glfw.hints.framebuffer.transparent = value; _glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_SAMPLES: case GLFW_SAMPLES:
_glfw.hints.framebuffer.samples = value; _glfw.hints.framebuffer.samples = value;
return; return;
case GLFW_SRGB_CAPABLE: case GLFW_SRGB_CAPABLE:
_glfw.hints.framebuffer.sRGB = value; _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_RESIZABLE: case GLFW_RESIZABLE:
_glfw.hints.window.resizable = value; _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_DECORATED: case GLFW_DECORATED:
_glfw.hints.window.decorated = value; _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_FOCUSED: case GLFW_FOCUSED:
_glfw.hints.window.focused = value; _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_AUTO_ICONIFY: case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = value; _glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_FLOATING: case GLFW_FLOATING:
_glfw.hints.window.floating = value; _glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_MAXIMIZED: case GLFW_MAXIMIZED:
_glfw.hints.window.maximized = value; _glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_VISIBLE: case GLFW_VISIBLE:
_glfw.hints.window.visible = value; _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_POSITION_X: case GLFW_POSITION_X:
_glfw.hints.window.xpos = value; _glfw.hints.window.xpos = value;
@@ -373,29 +373,29 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.window.ypos = value; _glfw.hints.window.ypos = value;
return; return;
case GLFW_WIN32_KEYBOARD_MENU: case GLFW_WIN32_KEYBOARD_MENU:
_glfw.hints.window.win32.keymenu = value; _glfw.hints.window.win32.keymenu = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_WIN32_SHOWDEFAULT: case GLFW_WIN32_SHOWDEFAULT:
_glfw.hints.window.win32.showDefault = value; _glfw.hints.window.win32.showDefault = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_COCOA_GRAPHICS_SWITCHING: case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value; _glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_SCALE_TO_MONITOR: case GLFW_SCALE_TO_MONITOR:
_glfw.hints.window.scaleToMonitor = value; _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_SCALE_FRAMEBUFFER: case GLFW_SCALE_FRAMEBUFFER:
case GLFW_COCOA_RETINA_FRAMEBUFFER: case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.scaleFramebuffer = value; _glfw.hints.window.scaleFramebuffer = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_CENTER_CURSOR: case GLFW_CENTER_CURSOR:
_glfw.hints.window.centerCursor = value; _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_FOCUS_ON_SHOW: case GLFW_FOCUS_ON_SHOW:
_glfw.hints.window.focusOnShow = value; _glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_MOUSE_PASSTHROUGH: case GLFW_MOUSE_PASSTHROUGH:
_glfw.hints.window.mousePassthrough = value; _glfw.hints.window.mousePassthrough = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_CLIENT_API: case GLFW_CLIENT_API:
_glfw.hints.context.client = value; _glfw.hints.context.client = value;
@@ -413,13 +413,13 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.context.robustness = value; _glfw.hints.context.robustness = value;
return; return;
case GLFW_OPENGL_FORWARD_COMPAT: case GLFW_OPENGL_FORWARD_COMPAT:
_glfw.hints.context.forward = value; _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_CONTEXT_DEBUG: case GLFW_CONTEXT_DEBUG:
_glfw.hints.context.debug = value; _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_CONTEXT_NO_ERROR: case GLFW_CONTEXT_NO_ERROR:
_glfw.hints.context.noerror = value; _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_OPENGL_PROFILE: case GLFW_OPENGL_PROFILE:
_glfw.hints.context.profile = value; _glfw.hints.context.profile = value;
@@ -776,7 +776,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
{ {
assert(isfinite(opacity)); assert(opacity == opacity);
assert(opacity >= 0.f); assert(opacity >= 0.f);
assert(opacity <= 1.f); assert(opacity <= 1.f);
@@ -785,7 +785,7 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
if (!isfinite(opacity) || opacity < 0.f || opacity > 1.f) if (opacity != opacity || opacity < 0.f || opacity > 1.f)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity); _glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity);
return; return;
@@ -1178,10 +1178,11 @@ GLFWAPI void glfwWaitEvents(void)
GLFWAPI void glfwWaitEventsTimeout(double timeout) GLFWAPI void glfwWaitEventsTimeout(double timeout)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
assert(isfinite(timeout)); assert(timeout == timeout);
assert(timeout >= 0.0); assert(timeout >= 0.0);
assert(timeout <= DBL_MAX);
if (!isfinite(timeout) || timeout < 0.0) if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout); _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);
return; return;
+9 -4
View File
@@ -135,7 +135,7 @@ static void registryHandleGlobal(void* userData,
{ {
_glfw.wl.seat = _glfw.wl.seat =
wl_registry_bind(registry, name, &wl_seat_interface, wl_registry_bind(registry, name, &wl_seat_interface,
_glfw_min(8, version)); _glfw_min(5, version));
_glfwAddSeatListenerWayland(_glfw.wl.seat); _glfwAddSeatListenerWayland(_glfw.wl.seat);
} }
} }
@@ -244,7 +244,10 @@ static void libdecorReadyCallback(void* userData,
uint32_t time) uint32_t time)
{ {
_glfw.wl.libdecor.ready = GLFW_TRUE; _glfw.wl.libdecor.ready = GLFW_TRUE;
wl_callback_destroy(callback);
assert(_glfw.wl.libdecor.callback == callback);
wl_callback_destroy(_glfw.wl.libdecor.callback);
_glfw.wl.libdecor.callback = NULL;
} }
static const struct wl_callback_listener libdecorReadyListener = static const struct wl_callback_listener libdecorReadyListener =
@@ -878,8 +881,10 @@ int _glfwInitWayland(void)
libdecor_dispatch(_glfw.wl.libdecor.context, 0); libdecor_dispatch(_glfw.wl.libdecor.context, 0);
// Create sync point to "know" when libdecor is ready for use // Create sync point to "know" when libdecor is ready for use
struct wl_callback* callback = wl_display_sync(_glfw.wl.display); _glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display);
wl_callback_add_listener(callback, &libdecorReadyListener, NULL); wl_callback_add_listener(_glfw.wl.libdecor.callback,
&libdecorReadyListener,
NULL);
} }
} }
+3 -2
View File
@@ -42,6 +42,8 @@ typedef struct VkWaylandSurfaceCreateInfoKHR
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*); typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "posix_poll.h"
typedef int (* PFN_wl_display_flush)(struct wl_display* display); typedef int (* PFN_wl_display_flush)(struct wl_display* display);
typedef void (* PFN_wl_display_cancel_read)(struct wl_display* display); typedef void (* PFN_wl_display_cancel_read)(struct wl_display* display);
typedef int (* PFN_wl_display_dispatch_pending)(struct wl_display* display); typedef int (* PFN_wl_display_dispatch_pending)(struct wl_display* display);
@@ -496,8 +498,6 @@ typedef struct _GLFWlibraryWayland
double pointerY; double pointerY;
double scrollX; double scrollX;
double scrollY; double scrollY;
double discreteX;
double discreteY;
int button; int button;
int action; int action;
} pending; } pending;
@@ -595,6 +595,7 @@ typedef struct _GLFWlibraryWayland
struct { struct {
void* handle; void* handle;
struct libdecor* context; struct libdecor* context;
struct wl_callback* callback;
GLFWbool ready; GLFWbool ready;
PFN_libdecor_new libdecor_new_; PFN_libdecor_new libdecor_new_;
PFN_libdecor_unref libdecor_unref_; PFN_libdecor_unref libdecor_unref_;
+35 -66
View File
@@ -55,11 +55,10 @@
#define GLFW_BORDER_SIZE 4 #define GLFW_BORDER_SIZE 4
#define GLFW_CAPTION_HEIGHT 24 #define GLFW_CAPTION_HEIGHT 24
#define GLFW_PENDING_SURFACE 1 #define GLFW_PENDING_SURFACE 1
#define GLFW_PENDING_BUTTON 2 #define GLFW_PENDING_BUTTON 2
#define GLFW_PENDING_MOTION 4 #define GLFW_PENDING_MOTION 4
#define GLFW_PENDING_SCROLL 8 #define GLFW_PENDING_SCROLL 8
#define GLFW_PENDING_DISCRETE 16
static int createTmpfileCloexec(char* tmpname) static int createTmpfileCloexec(char* tmpname)
{ {
@@ -199,16 +198,6 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
return buffer; return buffer;
} }
static void callbackHandleDone(void* userData, struct wl_callback* callback, uint32_t data)
{
wl_callback_destroy(callback);
}
static const struct wl_callback_listener noopCallbackListener =
{
callbackHandleDone
};
static void createFallbackEdge(_GLFWwindow* window, static void createFallbackEdge(_GLFWwindow* window,
_GLFWfallbackEdgeWayland* edge, _GLFWfallbackEdgeWayland* edge,
struct wl_surface* parent, struct wl_surface* parent,
@@ -1751,9 +1740,7 @@ static void pointerHandleFrame(void* userData, struct wl_pointer* pointer)
if (_glfw.wl.pending.events & GLFW_PENDING_BUTTON) if (_glfw.wl.pending.events & GLFW_PENDING_BUTTON)
processPointerButton(_glfw.wl.pending.button, _glfw.wl.pending.action); processPointerButton(_glfw.wl.pending.button, _glfw.wl.pending.action);
if (_glfw.wl.pending.events & GLFW_PENDING_DISCRETE) if (_glfw.wl.pending.events & GLFW_PENDING_SCROLL)
processPointerScroll(_glfw.wl.pending.discreteX, _glfw.wl.pending.discreteY);
else if (_glfw.wl.pending.events & GLFW_PENDING_SCROLL)
processPointerScroll(_glfw.wl.pending.scrollX, _glfw.wl.pending.scrollY); processPointerScroll(_glfw.wl.pending.scrollX, _glfw.wl.pending.scrollY);
memset(&_glfw.wl.pending, 0, sizeof(_glfw.wl.pending)); memset(&_glfw.wl.pending, 0, sizeof(_glfw.wl.pending));
@@ -1779,21 +1766,6 @@ static void pointerHandleAxisDiscrete(void* userData,
{ {
} }
static void pointerHandleAxisValue120(void* data,
struct wl_pointer* pointer,
uint32_t axis,
int32_t value120)
{
if (!_glfw.wl.pointerSurface)
return;
_glfw.wl.pending.events |= GLFW_PENDING_DISCRETE;
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
_glfw.wl.pending.discreteX = -(value120 / 120.0);
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
_glfw.wl.pending.discreteY = -(value120 / 120.0);
}
static const struct wl_pointer_listener pointerListener = static const struct wl_pointer_listener pointerListener =
{ {
pointerHandleEnter, pointerHandleEnter,
@@ -1804,8 +1776,7 @@ static const struct wl_pointer_listener pointerListener =
pointerHandleFrame, pointerHandleFrame,
pointerHandleAxisSource, pointerHandleAxisSource,
pointerHandleAxisStop, pointerHandleAxisStop,
pointerHandleAxisDiscrete, pointerHandleAxisDiscrete
pointerHandleAxisValue120
}; };
static void keyboardHandleKeymap(void* userData, static void keyboardHandleKeymap(void* userData,
@@ -1828,7 +1799,7 @@ static void keyboardHandleKeymap(void* userData,
return; return;
} }
mapStr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (mapStr == MAP_FAILED) if (mapStr == MAP_FAILED)
{ {
close(fd); close(fd);
@@ -2330,37 +2301,41 @@ void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device)
GLFWbool _glfwWaitForEGLFrameWayland(_GLFWwindow* window) GLFWbool _glfwWaitForEGLFrameWayland(_GLFWwindow* window)
{ {
double timeout = 0.02; for (int i = 0; i < window->wl.egl.interval; i++)
while (window->wl.egl.callback)
{ {
if (wl_display_prepare_read_queue(_glfw.wl.display, window->wl.egl.queue) != 0) double timeout = 0.02;
while (window->wl.egl.callback)
{ {
while (wl_display_prepare_read_queue(_glfw.wl.display, window->wl.egl.queue) != 0)
wl_display_dispatch_queue_pending(_glfw.wl.display, window->wl.egl.queue);
if (!flushDisplay())
{
wl_display_cancel_read(_glfw.wl.display);
return GLFW_FALSE;
}
struct pollfd fd = { wl_display_get_fd(_glfw.wl.display), POLLIN };
if (!_glfwPollPOSIX(&fd, 1, &timeout))
{
wl_display_cancel_read(_glfw.wl.display);
return GLFW_FALSE;
}
wl_display_read_events(_glfw.wl.display);
wl_display_dispatch_queue_pending(_glfw.wl.display, window->wl.egl.queue); wl_display_dispatch_queue_pending(_glfw.wl.display, window->wl.egl.queue);
continue;
} }
if (!flushDisplay()) window->wl.egl.callback = wl_surface_frame(window->wl.egl.wrapper);
{ wl_callback_add_listener(window->wl.egl.callback, &frameCallbackListener, window);
wl_display_cancel_read(_glfw.wl.display);
return GLFW_FALSE;
}
struct pollfd fd = { wl_display_get_fd(_glfw.wl.display), POLLIN }; // Commit the old buffer for every frame but the last one so we get new callbacks
if (i + 1 < window->wl.egl.interval)
if (!_glfwPollPOSIX(&fd, 1, &timeout)) wl_surface_commit(window->wl.surface);
{
wl_display_cancel_read(_glfw.wl.display);
return GLFW_FALSE;
}
wl_display_read_events(_glfw.wl.display);
wl_display_dispatch_queue_pending(_glfw.wl.display, window->wl.egl.queue);
} }
window->wl.egl.callback = wl_surface_frame(window->wl.egl.wrapper);
wl_callback_add_listener(window->wl.egl.callback, &frameCallbackListener, window);
// If the window is hidden when the wait is over then don't swap // If the window is hidden when the wait is over then don't swap
return window->wl.visible; return window->wl.visible;
} }
@@ -2411,8 +2386,6 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
wl_proxy_set_queue((struct wl_proxy*) window->wl.egl.wrapper, wl_proxy_set_queue((struct wl_proxy*) window->wl.egl.wrapper,
window->wl.egl.queue); window->wl.egl.queue);
window->wl.egl.interval = 1;
if (!_glfwInitEGL()) if (!_glfwInitEGL())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
@@ -2726,8 +2699,6 @@ void _glfwHideWindowWayland(_GLFWwindow* window)
wl_surface_attach(window->wl.surface, NULL, 0, 0); wl_surface_attach(window->wl.surface, NULL, 0, 0);
wl_surface_commit(window->wl.surface); wl_surface_commit(window->wl.surface);
flushDisplay();
} }
} }
@@ -2942,9 +2913,7 @@ void _glfwWaitEventsTimeoutWayland(double timeout)
void _glfwPostEmptyEventWayland(void) void _glfwPostEmptyEventWayland(void)
{ {
struct wl_callback* callback = wl_display_sync(_glfw.wl.display); wl_display_sync(_glfw.wl.display);
wl_callback_add_listener(callback, &noopCallbackListener, NULL);
flushDisplay(); flushDisplay();
} }
+15 -15
View File
@@ -452,6 +452,9 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(V
typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t); typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
#include "xkb_unicode.h"
#include "posix_poll.h"
#define GLFW_X11_WINDOW_STATE _GLFWwindowX11 x11; #define GLFW_X11_WINDOW_STATE _GLFWwindowX11 x11;
#define GLFW_X11_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11; #define GLFW_X11_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11;
#define GLFW_X11_MONITOR_STATE _GLFWmonitorX11 x11; #define GLFW_X11_MONITOR_STATE _GLFWmonitorX11 x11;
@@ -460,7 +463,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
#define GLFW_GLX_CONTEXT_STATE _GLFWcontextGLX glx; #define GLFW_GLX_CONTEXT_STATE _GLFWcontextGLX glx;
#define GLFW_GLX_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx; #define GLFW_GLX_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx;
#define GLFW_INVALID_CODEPOINT 0xffffffffu
// GLX-specific per-context data // GLX-specific per-context data
// //
@@ -503,18 +505,18 @@ typedef struct _GLFWlibraryGLX
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT; PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA; PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
bool SGI_swap_control; GLFWbool SGI_swap_control;
bool EXT_swap_control; GLFWbool EXT_swap_control;
bool MESA_swap_control; GLFWbool MESA_swap_control;
bool ARB_multisample; GLFWbool ARB_multisample;
bool ARB_framebuffer_sRGB; GLFWbool ARB_framebuffer_sRGB;
bool EXT_framebuffer_sRGB; GLFWbool EXT_framebuffer_sRGB;
bool ARB_create_context; GLFWbool ARB_create_context;
bool ARB_create_context_profile; GLFWbool ARB_create_context_profile;
bool ARB_create_context_robustness; GLFWbool ARB_create_context_robustness;
bool EXT_create_context_es2_profile; GLFWbool EXT_create_context_es2_profile;
bool ARB_create_context_no_error; GLFWbool ARB_create_context_no_error;
bool ARB_context_flush_control; GLFWbool ARB_context_flush_control;
} _GLFWlibraryGLX; } _GLFWlibraryGLX;
// X11-specific per-window data // X11-specific per-window data
@@ -983,8 +985,6 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
unsigned char** value); unsigned char** value);
GLFWbool _glfwIsVisualTransparentX11(Visual* visual); GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
uint32_t _glfwKeySym2UnicodeX11(unsigned int keysym);
void _glfwGrabErrorHandlerX11(void); void _glfwGrabErrorHandlerX11(void);
void _glfwReleaseErrorHandlerX11(void); void _glfwReleaseErrorHandlerX11(void);
void _glfwInputErrorX11(int error, const char* message); void _glfwInputErrorX11(int error, const char* message);
+2 -2
View File
@@ -1308,7 +1308,7 @@ static void processEvent(XEvent *event)
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods); _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
const uint32_t codepoint = _glfwKeySym2UnicodeX11(keysym); const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
if (codepoint != GLFW_INVALID_CODEPOINT) if (codepoint != GLFW_INVALID_CODEPOINT)
_glfwInputChar(window, codepoint, mods, plain); _glfwInputChar(window, codepoint, mods, plain);
} }
@@ -2944,7 +2944,7 @@ const char* _glfwGetScancodeNameX11(int scancode)
if (keysym == NoSymbol) if (keysym == NoSymbol)
return NULL; return NULL;
const uint32_t codepoint = _glfwKeySym2UnicodeX11(keysym); const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
if (codepoint == GLFW_INVALID_CODEPOINT) if (codepoint == GLFW_INVALID_CODEPOINT)
return NULL; return NULL;
+3 -3
View File
@@ -27,7 +27,7 @@
#include "internal.h" #include "internal.h"
#if defined(_GLFW_X11) #if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
/* /*
* Marcus: This code was originally written by Markus G. Kuhn. * Marcus: This code was originally written by Markus G. Kuhn.
@@ -906,7 +906,7 @@ static const struct codepair {
// Convert XKB KeySym to Unicode // Convert XKB KeySym to Unicode
// //
uint32_t _glfwKeySym2UnicodeX11(unsigned int keysym) uint32_t _glfwKeySym2Unicode(unsigned int keysym)
{ {
int min = 0; int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
@@ -939,5 +939,5 @@ uint32_t _glfwKeySym2UnicodeX11(unsigned int keysym)
return GLFW_INVALID_CODEPOINT; return GLFW_INVALID_CODEPOINT;
} }
#endif // _GLFW_X11 #endif // _GLFW_WAYLAND or _GLFW_X11
+30
View File
@@ -0,0 +1,30 @@
//========================================================================
// GLFW 3.5 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_INVALID_CODEPOINT 0xffffffffu
uint32_t _glfwKeySym2Unicode(unsigned int keysym);
+30 -75
View File
@@ -23,10 +23,7 @@
// //
//======================================================================== //========================================================================
// //
// This test is intended to verify that the posting of empty events works. // This test is intended to verify that posting of empty events works
// Background colors are produced on a secondary thread, which then wakes
// the main thread with glfwPostEmptyEvent when a new one is available.
// This allows the main thread to wait for events unconditionally.
// //
//======================================================================== //========================================================================
@@ -40,53 +37,25 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
struct State static volatile int running = GLFW_TRUE;
{
mtx_t lock;
bool running;
bool needs_update;
int width;
int height;
float r, g, b;
};
static void error_callback(int error, const char* description) static void error_callback(int error, const char* description)
{ {
fprintf(stderr, "Error: %s\n", description); fprintf(stderr, "Error: %s\n", description);
} }
static void generate_color(struct State* state)
{
const float r = (float) rand() / (float) RAND_MAX;
const float g = (float) rand() / (float) RAND_MAX;
const float b = (float) rand() / (float) RAND_MAX;
const float l = sqrtf(r * r + g * g + b * b);
mtx_lock(&state->lock);
state->r = r / l;
state->g = g / l;
state->b = b / l;
state->needs_update = true;
mtx_unlock(&state->lock);
}
static int thread_main(void* data) static int thread_main(void* data)
{ {
struct State* const state = data; struct timespec time;
srand((unsigned int) time(NULL)); while (running)
while (state->running)
{ {
generate_color(state);
glfwPostEmptyEvent();
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time); clock_gettime(CLOCK_REALTIME, &time);
time.tv_sec += 1; time.tv_sec += 1;
thrd_sleep(&time, NULL); thrd_sleep(&time, NULL);
glfwPostEmptyEvent();
} }
return 0; return 0;
@@ -95,38 +64,28 @@ static int thread_main(void* data)
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, GLFW_TRUE);
} }
static void framebuffer_size_callback(GLFWwindow* window, int width, int height) static float nrand(void)
{ {
struct State* const state = glfwGetWindowUserPointer(window); return (float) rand() / (float) RAND_MAX;
mtx_lock(&state->lock);
state->width = width;
state->height = height;
state->needs_update = true;
mtx_unlock(&state->lock);
} }
int main(void) int main(void)
{ {
struct State state = { .running = true }; int result;
thrd_t thread;
GLFWwindow* window;
if (mtx_init(&state.lock, mtx_plain) != thrd_success) srand((unsigned int) time(NULL));
{
glfwTerminate();
exit(EXIT_FAILURE);
}
generate_color(&state);
glfwSetErrorCallback(error_callback); glfwSetErrorCallback(error_callback);
if (!glfwInit()) if (!glfwInit())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
GLFWwindow* window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL); window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL);
if (!window) if (!window)
{ {
glfwTerminate(); glfwTerminate();
@@ -136,13 +95,8 @@ int main(void)
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
gladLoadGL(glfwGetProcAddress); gladLoadGL(glfwGetProcAddress);
glfwSetKeyCallback(window, key_callback); glfwSetKeyCallback(window, key_callback);
glfwSetWindowUserPointer(window, &state);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwGetFramebufferSize(window, &state.width, &state.height);
thrd_t color_thread; if (thrd_create(&thread, thread_main, NULL) != thrd_success)
if (thrd_create(&color_thread, thread_main, &state) != thrd_success)
{ {
fprintf(stderr, "Failed to create secondary thread\n"); fprintf(stderr, "Failed to create secondary thread\n");
@@ -150,27 +104,28 @@ int main(void)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
while (!glfwWindowShouldClose(window)) while (running)
{ {
if (state.needs_update) int width, height;
{ float r = nrand(), g = nrand(), b = nrand();
mtx_lock(&state.lock); float l = (float) sqrt(r * r + g * g + b * b);
glViewport(0, 0, state.width, state.height);
glClearColor(state.r, state.g, state.b, 1.f);
state.needs_update = false;
mtx_unlock(&state.lock);
glClear(GL_COLOR_BUFFER_BIT); glfwGetFramebufferSize(window, &width, &height);
glfwSwapBuffers(window);
} glViewport(0, 0, width, height);
glClearColor(r / l, g / l, b / l, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwWaitEvents(); glfwWaitEvents();
if (glfwWindowShouldClose(window))
running = GLFW_FALSE;
} }
glfwHideWindow(window); glfwHideWindow(window);
state.running = false; thrd_join(thread, &result);
thrd_join(color_thread, NULL); glfwDestroyWindow(window);
mtx_destroy(&state.lock);
glfwTerminate(); glfwTerminate();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);