mirror of
https://github.com/glfw/glfw.git
synced 2026-09-23 00:59:48 +00:00
Compare commits
46 Commits
8e15281d34
...
b00e6a8a88
| Author | SHA1 | Date | |
|---|---|---|---|
| b00e6a8a88 | |||
| 51683a6f1c | |||
| 55fd451d5f | |||
| 1929088dd9 | |||
| 3130c004e1 | |||
| bb8048122a | |||
| 50b0a135a5 | |||
| fdd14e65b1 | |||
| 54b18d5547 | |||
| 05f57c0bee | |||
| 0d15b54c7a | |||
| f472380d7e | |||
| 1839271de4 | |||
| aa5047709d | |||
| bae8aa6e7d | |||
| c5c0b69149 | |||
| 29cd880ab5 | |||
| 3d89365fdb | |||
| 7c9ea95233 | |||
| abfbf07830 | |||
| 99cdcfb0a4 | |||
| 001f94eaa7 | |||
| 3f14b6feed | |||
| f0b2992b3a | |||
| b579ea6792 | |||
| a3095e1aa5 | |||
| a98badf088 | |||
| c4684b288d | |||
| 232164f62b | |||
| abb9db0d75 | |||
| 0aa77a9a3a | |||
| 7b370d8df0 | |||
| f871f14d5e | |||
| bafb134769 | |||
| 2d7ae8f2d0 | |||
| 96e0f49395 | |||
| 9352d8fe93 | |||
| a228a8b447 | |||
| dbadda2683 | |||
| 08449b7183 | |||
| 1ce855b0b1 | |||
| ebff6606ee | |||
| 162896e5b9 | |||
| 936307558e | |||
| 4df5129529 | |||
| 6de70d8252 |
@@ -17,7 +17,7 @@ jobs:
|
|||||||
CC: clang
|
CC: clang
|
||||||
CFLAGS: -Werror
|
CFLAGS: -Werror
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- 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@v4
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- 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@v4
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- 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
|
||||||
|
|||||||
+1
-5
@@ -38,11 +38,7 @@ set(GLFW_LIBRARY_TYPE "${GLFW_LIBRARY_TYPE}" CACHE STRING
|
|||||||
"Library type override for GLFW (SHARED, STATIC, OBJECT, or empty to follow BUILD_SHARED_LIBS)")
|
"Library type override for GLFW (SHARED, STATIC, OBJECT, or empty to follow BUILD_SHARED_LIBS)")
|
||||||
|
|
||||||
if (GLFW_LIBRARY_TYPE)
|
if (GLFW_LIBRARY_TYPE)
|
||||||
if (GLFW_LIBRARY_TYPE STREQUAL "SHARED")
|
string(COMPARE EQUAL "${GLFW_LIBRARY_TYPE}" "SHARED" GLFW_BUILD_SHARED_LIBRARY)
|
||||||
set(GLFW_BUILD_SHARED_LIBRARY TRUE)
|
|
||||||
else()
|
|
||||||
set(GLFW_BUILD_SHARED_LIBRARY FALSE)
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
set(GLFW_BUILD_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
|
set(GLFW_BUILD_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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
|
||||||
@@ -56,6 +57,7 @@ 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
|
||||||
@@ -75,10 +77,12 @@ 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
|
||||||
- Mário Freitas
|
- Mário Freitas
|
||||||
|
- Friz64
|
||||||
- GeO4d
|
- GeO4d
|
||||||
- Marcus Geelnard
|
- Marcus Geelnard
|
||||||
- Gegy
|
- Gegy
|
||||||
@@ -160,8 +164,10 @@ video tutorials.
|
|||||||
- Bryce Mehring
|
- Bryce Mehring
|
||||||
- Jonathan Mercier
|
- Jonathan Mercier
|
||||||
- Marcel Metz
|
- Marcel Metz
|
||||||
|
- Lucas Michaudel
|
||||||
- Liam Middlebrook
|
- Liam Middlebrook
|
||||||
- mightgoyardstill
|
- mightgoyardstill
|
||||||
|
- Mihail
|
||||||
- Ave Milia
|
- Ave Milia
|
||||||
- Icyllis Milica
|
- Icyllis Milica
|
||||||
- Jonathan Miller
|
- Jonathan Miller
|
||||||
@@ -282,10 +288,12 @@ video tutorials.
|
|||||||
- Corentin Wallez
|
- Corentin Wallez
|
||||||
- Torsten Walluhn
|
- Torsten Walluhn
|
||||||
- Patrick Walton
|
- Patrick Walton
|
||||||
|
- Ivor Wanders
|
||||||
- Jim Wang
|
- Jim Wang
|
||||||
- Xo Wang
|
- Xo Wang
|
||||||
- Andre Weissflog
|
- Andre Weissflog
|
||||||
- Jay Weisskopf
|
- Jay Weisskopf
|
||||||
|
- Drew Weymouth
|
||||||
- Frank Wille
|
- Frank Wille
|
||||||
- Andy Williams
|
- Andy Williams
|
||||||
- Joel Winarske
|
- Joel Winarske
|
||||||
|
|||||||
@@ -144,7 +144,27 @@ information on what to include when reporting a bug.
|
|||||||
a modal to a fallback decoration
|
a modal to a fallback decoration
|
||||||
- [Wayland] Bugfix: The cursor position was not updated when clicking through
|
- [Wayland] Bugfix: The cursor position was not updated when clicking through
|
||||||
from a modal to the content area
|
from a modal to the content area
|
||||||
|
- [Wayland] Bugfix: free modules at end of terminate function to resolve
|
||||||
|
potential segmentation fault (#2744)
|
||||||
|
- [Wayland] Bugfix: Confining or disabling the cursor could segfault on
|
||||||
|
compositors without `pointer-constraints-unstable-v1`
|
||||||
|
- [Wayland] Bugfix: Key repeat did not function on very old compositors
|
||||||
|
- [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: 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
|
||||||
|
was suspended (#1350,#2582,#2640,#2719,#2723,#2800,#2827)
|
||||||
|
- [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: Prevent BadWindow when creating small windows with a content scale
|
||||||
|
less than 1 (#2754)
|
||||||
|
- [X11] Bugfix: Clamp width and height to >= 1 to prevent BadValue error and app exit
|
||||||
|
- [X11] Bugfix: Floating windows silently became non-floating when hidden (#2276)
|
||||||
|
- [X11] Bugfix: The `libXext` library was not unloaded at termination
|
||||||
|
- [Linux] Bugfix: The header for `ioctl` was only implicitly included (#2778)
|
||||||
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
|
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
|
||||||
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
|
- [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
|
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
|
||||||
|
|||||||
+14
-3
@@ -1344,6 +1344,10 @@ 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
|
||||||
|
|
||||||
|
|
||||||
@@ -4520,7 +4524,8 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
|
|||||||
* GLFW will pass those events on to the application callbacks before
|
* GLFW will pass those events on to the application callbacks before
|
||||||
* returning.
|
* returning.
|
||||||
*
|
*
|
||||||
* Event processing is not required for joystick input to work.
|
* Event processing is not required to receive joystick input. Joystick state
|
||||||
|
* is polled when a joystick input or gamepad input function is called.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR.
|
||||||
@@ -4565,7 +4570,8 @@ GLFWAPI void glfwPollEvents(void);
|
|||||||
* GLFW will pass those events on to the application callbacks before
|
* GLFW will pass those events on to the application callbacks before
|
||||||
* returning.
|
* returning.
|
||||||
*
|
*
|
||||||
* Event processing is not required for joystick input to work.
|
* Event processing is not required to receive joystick input. Joystick state
|
||||||
|
* is polled when a joystick input or gamepad input function is called.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR.
|
||||||
@@ -4612,7 +4618,8 @@ GLFWAPI void glfwWaitEvents(void);
|
|||||||
* GLFW will pass those events on to the application callbacks before
|
* GLFW will pass those events on to the application callbacks before
|
||||||
* returning.
|
* returning.
|
||||||
*
|
*
|
||||||
* Event processing is not required for joystick input to work.
|
* Event processing is not required to receive joystick input. Joystick state
|
||||||
|
* is polled when a joystick input or gamepad input function is called.
|
||||||
*
|
*
|
||||||
* @param[in] timeout The maximum amount of time, in seconds, to wait.
|
* @param[in] timeout The maximum amount of time, in seconds, to wait.
|
||||||
*
|
*
|
||||||
@@ -6167,6 +6174,10 @@ 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.
|
||||||
*
|
*
|
||||||
|
|||||||
+10
-5
@@ -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 cocoa_time.h cocoa_time.c posix_thread.h
|
target_sources(glfw PRIVATE macos_time.h macos_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 xkb_unicode.h x11_init.c
|
target_sources(glfw PRIVATE x11_platform.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")
|
||||||
|
|
||||||
set(glfw_PKG_DEPS "")
|
list(APPEND glfw_PKG_LIBS "-framework Cocoa"
|
||||||
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework QuartzCore")
|
"-framework IOKit"
|
||||||
|
"-framework QuartzCore")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (GLFW_BUILD_WAYLAND)
|
if (GLFW_BUILD_WAYLAND)
|
||||||
@@ -234,6 +234,11 @@ 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)
|
||||||
|
|||||||
+3
-36
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.5 macOS - www.glfw.org
|
// GLFW 3.5 Cocoa - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
//
|
//
|
||||||
@@ -450,41 +450,6 @@ 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 //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -688,6 +653,8 @@ void _glfwTerminateCocoa(void)
|
|||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
_glfwTerminateOSMesa();
|
_glfwTerminateOSMesa();
|
||||||
|
|
||||||
|
memset(&_glfw.ns, 0, sizeof(_glfw.ns));
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.5 macOS - www.glfw.org
|
// GLFW 3.5 Cocoa - 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>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.5 macOS - www.glfw.org
|
// GLFW 3.5 Cocoa - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
//
|
//
|
||||||
@@ -291,8 +291,6 @@ 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,
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.5 macOS - www.glfw.org
|
// GLFW 3.5 Cocoa - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
//
|
//
|
||||||
|
|||||||
+7
-2
@@ -195,7 +195,7 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
|||||||
{
|
{
|
||||||
current = alternatives + i;
|
current = alternatives + i;
|
||||||
|
|
||||||
if (desired->stereo > 0 && current->stereo == 0)
|
if (desired->stereo && !current->stereo)
|
||||||
{
|
{
|
||||||
// Stereo is a hard constraint
|
// Stereo is a hard constraint
|
||||||
continue;
|
continue;
|
||||||
@@ -368,7 +368,12 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
|||||||
window->context.getProcAddress("glGetIntegerv");
|
window->context.getProcAddress("glGetIntegerv");
|
||||||
window->context.GetString = (PFNGLGETSTRINGPROC)
|
window->context.GetString = (PFNGLGETSTRINGPROC)
|
||||||
window->context.getProcAddress("glGetString");
|
window->context.getProcAddress("glGetString");
|
||||||
if (!window->context.GetIntegerv || !window->context.GetString)
|
window->context.Flush = (PFNGLFLUSHPROC)
|
||||||
|
window->context.getProcAddress("glFlush");
|
||||||
|
|
||||||
|
if (!window->context.GetIntegerv ||
|
||||||
|
!window->context.GetString ||
|
||||||
|
!window->context.Flush)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
||||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||||
|
|||||||
+44
-26
@@ -254,6 +254,12 @@ static void makeContextCurrentEGL(_GLFWwindow* window)
|
|||||||
getEGLErrorString(eglGetError()));
|
getEGLErrorString(eglGetError()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_GLFW_WAYLAND)
|
||||||
|
// NOTE: Disable EGL vsync so we can substitute our own that includes a timeout
|
||||||
|
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
|
||||||
|
eglSwapInterval(_glfw.egl.display, 0);
|
||||||
|
#endif // _GLFW_WAYLAND
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -287,6 +293,15 @@ static void swapBuffersEGL(_GLFWwindow* window)
|
|||||||
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
|
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
|
||||||
if (!window->wl.visible)
|
if (!window->wl.visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// NOTE: We wait for a frame manually so we can add a timeout,
|
||||||
|
// as the EGL implementation will wait indefinitely
|
||||||
|
if (window->wl.egl.interval > 0)
|
||||||
|
{
|
||||||
|
window->context.Flush();
|
||||||
|
if (!_glfwWaitForEGLFrameWayland(window))
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -295,6 +310,16 @@ static void swapBuffersEGL(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void swapIntervalEGL(int interval)
|
static void swapIntervalEGL(int interval)
|
||||||
{
|
{
|
||||||
|
#if defined(_GLFW_WAYLAND)
|
||||||
|
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
assert(window != NULL);
|
||||||
|
window->wl.egl.interval = interval;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
eglSwapInterval(_glfw.egl.display, interval);
|
eglSwapInterval(_glfw.egl.display, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,19 +336,20 @@ static int extensionSupportedEGL(const char* extension)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GLFWglproc getProcAddressEGL(const char* procname)
|
static GLFWglproc getProcAddressEGL(const char* procname)
|
||||||
|
{
|
||||||
|
const GLFWglproc proc = (GLFWglproc) eglGetProcAddress(procname);
|
||||||
|
if (proc)
|
||||||
|
return proc;
|
||||||
|
|
||||||
|
if (!_glfw.egl.KHR_get_all_proc_addresses)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
|
|
||||||
if (window->context.egl.client)
|
return _glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
|
||||||
{
|
|
||||||
GLFWglproc proc = (GLFWglproc)
|
|
||||||
_glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
|
|
||||||
if (proc)
|
|
||||||
return proc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return eglGetProcAddress(procname);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroyContextEGL(_GLFWwindow* window)
|
static void destroyContextEGL(_GLFWwindow* window)
|
||||||
@@ -332,13 +358,10 @@ static void destroyContextEGL(_GLFWwindow* window)
|
|||||||
// as it will make XCloseDisplay segfault
|
// as it will make XCloseDisplay segfault
|
||||||
if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
|
if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
|
||||||
window->context.client != GLFW_OPENGL_API)
|
window->context.client != GLFW_OPENGL_API)
|
||||||
{
|
|
||||||
if (window->context.egl.client)
|
|
||||||
{
|
{
|
||||||
_glfwPlatformFreeModule(window->context.egl.client);
|
_glfwPlatformFreeModule(window->context.egl.client);
|
||||||
window->context.egl.client = NULL;
|
window->context.egl.client = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (window->context.egl.surface)
|
if (window->context.egl.surface)
|
||||||
{
|
{
|
||||||
@@ -358,8 +381,6 @@ static void destroyContextEGL(_GLFWwindow* window)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Initialize EGL
|
|
||||||
//
|
|
||||||
GLFWbool _glfwInitEGL(void)
|
GLFWbool _glfwInitEGL(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -369,10 +390,10 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
{
|
{
|
||||||
#if defined(_GLFW_EGL_LIBRARY)
|
#if defined(_GLFW_EGL_LIBRARY)
|
||||||
_GLFW_EGL_LIBRARY,
|
_GLFW_EGL_LIBRARY,
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_WIN32)
|
||||||
"libEGL.dll",
|
"libEGL.dll",
|
||||||
"EGL.dll",
|
"EGL.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(__APPLE__)
|
||||||
"libEGL.dylib",
|
"libEGL.dylib",
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
"libEGL-1.so",
|
"libEGL-1.so",
|
||||||
@@ -545,8 +566,6 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminate EGL
|
|
||||||
//
|
|
||||||
void _glfwTerminateEGL(void)
|
void _glfwTerminateEGL(void)
|
||||||
{
|
{
|
||||||
if (_glfw.egl.display)
|
if (_glfw.egl.display)
|
||||||
@@ -555,7 +574,8 @@ void _glfwTerminateEGL(void)
|
|||||||
_glfw.egl.display = EGL_NO_DISPLAY;
|
_glfw.egl.display = EGL_NO_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.egl.handle)
|
// Free modules only after all wayland termination functions are called
|
||||||
|
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
|
||||||
{
|
{
|
||||||
_glfwPlatformFreeModule(_glfw.egl.handle);
|
_glfwPlatformFreeModule(_glfw.egl.handle);
|
||||||
_glfw.egl.handle = NULL;
|
_glfw.egl.handle = NULL;
|
||||||
@@ -569,8 +589,6 @@ void _glfwTerminateEGL(void)
|
|||||||
attribs[index++] = v; \
|
attribs[index++] = v; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
|
||||||
//
|
|
||||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
@@ -657,7 +675,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, GLFW_TRUE);
|
SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
@@ -768,10 +786,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
#if defined(_GLFW_GLESV1_LIBRARY)
|
#if defined(_GLFW_GLESV1_LIBRARY)
|
||||||
_GLFW_GLESV1_LIBRARY,
|
_GLFW_GLESV1_LIBRARY,
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_WIN32)
|
||||||
"GLESv1_CM.dll",
|
"GLESv1_CM.dll",
|
||||||
"libGLES_CM.dll",
|
"libGLES_CM.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(__APPLE__)
|
||||||
"libGLESv1_CM.dylib",
|
"libGLESv1_CM.dylib",
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libGLESv1_CM.so",
|
"libGLESv1_CM.so",
|
||||||
@@ -785,10 +803,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
#if defined(_GLFW_GLESV2_LIBRARY)
|
#if defined(_GLFW_GLESV2_LIBRARY)
|
||||||
_GLFW_GLESV2_LIBRARY,
|
_GLFW_GLESV2_LIBRARY,
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_WIN32)
|
||||||
"GLESv2.dll",
|
"GLESv2.dll",
|
||||||
"libGLESv2.dll",
|
"libGLESv2.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(__APPLE__)
|
||||||
"libGLESv2.dylib",
|
"libGLESv2.dylib",
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
"libGLESv2-2.so",
|
"libGLESv2-2.so",
|
||||||
@@ -803,8 +821,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
#if defined(_GLFW_OPENGL_LIBRARY)
|
#if defined(_GLFW_OPENGL_LIBRARY)
|
||||||
_GLFW_OPENGL_LIBRARY,
|
_GLFW_OPENGL_LIBRARY,
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_WIN32)
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(__APPLE__)
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libGL.so",
|
"libGL.so",
|
||||||
#else
|
#else
|
||||||
|
|||||||
+13
-24
@@ -119,9 +119,7 @@ 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);
|
||||||
@@ -253,8 +251,6 @@ static void destroyContextGLX(_GLFWwindow* window)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Initialize GLX
|
|
||||||
//
|
|
||||||
GLFWbool _glfwInitGLX(void)
|
GLFWbool _glfwInitGLX(void)
|
||||||
{
|
{
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
@@ -369,7 +365,7 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
getProcAddressGLX("glXSwapIntervalEXT");
|
getProcAddressGLX("glXSwapIntervalEXT");
|
||||||
|
|
||||||
if (_glfw.glx.SwapIntervalEXT)
|
if (_glfw.glx.SwapIntervalEXT)
|
||||||
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
_glfw.glx.EXT_swap_control = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_SGI_swap_control"))
|
if (extensionSupportedGLX("GLX_SGI_swap_control"))
|
||||||
@@ -378,7 +374,7 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
getProcAddressGLX("glXSwapIntervalSGI");
|
getProcAddressGLX("glXSwapIntervalSGI");
|
||||||
|
|
||||||
if (_glfw.glx.SwapIntervalSGI)
|
if (_glfw.glx.SwapIntervalSGI)
|
||||||
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
_glfw.glx.SGI_swap_control = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_MESA_swap_control"))
|
if (extensionSupportedGLX("GLX_MESA_swap_control"))
|
||||||
@@ -387,17 +383,17 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
getProcAddressGLX("glXSwapIntervalMESA");
|
getProcAddressGLX("glXSwapIntervalMESA");
|
||||||
|
|
||||||
if (_glfw.glx.SwapIntervalMESA)
|
if (_glfw.glx.SwapIntervalMESA)
|
||||||
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
_glfw.glx.MESA_swap_control = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_ARB_multisample"))
|
if (extensionSupportedGLX("GLX_ARB_multisample"))
|
||||||
_glfw.glx.ARB_multisample = GLFW_TRUE;
|
_glfw.glx.ARB_multisample = true;
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
|
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
|
||||||
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
|
_glfw.glx.ARB_framebuffer_sRGB = true;
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
|
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
|
||||||
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
|
_glfw.glx.EXT_framebuffer_sRGB = true;
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_ARB_create_context"))
|
if (extensionSupportedGLX("GLX_ARB_create_context"))
|
||||||
{
|
{
|
||||||
@@ -405,40 +401,35 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
getProcAddressGLX("glXCreateContextAttribsARB");
|
getProcAddressGLX("glXCreateContextAttribsARB");
|
||||||
|
|
||||||
if (_glfw.glx.CreateContextAttribsARB)
|
if (_glfw.glx.CreateContextAttribsARB)
|
||||||
_glfw.glx.ARB_create_context = GLFW_TRUE;
|
_glfw.glx.ARB_create_context = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
|
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
|
||||||
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
|
_glfw.glx.ARB_create_context_robustness = true;
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
|
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
|
||||||
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
|
_glfw.glx.ARB_create_context_profile = true;
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
|
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
|
||||||
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
|
_glfw.glx.EXT_create_context_es2_profile = true;
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
|
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
|
||||||
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
|
_glfw.glx.ARB_create_context_no_error = true;
|
||||||
|
|
||||||
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
|
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
|
||||||
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
|
_glfw.glx.ARB_context_flush_control = true;
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminate GLX
|
|
||||||
//
|
|
||||||
void _glfwTerminateGLX(void)
|
void _glfwTerminateGLX(void)
|
||||||
{
|
{
|
||||||
// NOTE: This function must not call any X11 functions, as it is called
|
// NOTE: This function must not call any X11 functions, as it is called
|
||||||
// after XCloseDisplay (see _glfwTerminateX11 for details)
|
// after XCloseDisplay (see _glfwTerminateX11 for details)
|
||||||
|
|
||||||
if (_glfw.glx.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.glx.handle);
|
_glfwPlatformFreeModule(_glfw.glx.handle);
|
||||||
_glfw.glx.handle = NULL;
|
_glfw.glx.handle = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_ATTRIB(a, v) \
|
#define SET_ATTRIB(a, v) \
|
||||||
{ \
|
{ \
|
||||||
@@ -447,8 +438,6 @@ void _glfwTerminateGLX(void)
|
|||||||
attribs[index++] = v; \
|
attribs[index++] = v; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
|
||||||
//
|
|
||||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
|||||||
+4
-4
@@ -49,18 +49,18 @@ static GLFWerrorfun _glfwErrorCallback;
|
|||||||
static GLFWallocator _glfwInitAllocator;
|
static GLFWallocator _glfwInitAllocator;
|
||||||
static _GLFWinitconfig _glfwInitHints =
|
static _GLFWinitconfig _glfwInitHints =
|
||||||
{
|
{
|
||||||
.hatButtons = GLFW_TRUE,
|
.hatButtons = 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 = GLFW_TRUE,
|
.menubar = true,
|
||||||
.chdir = GLFW_TRUE
|
.chdir = true
|
||||||
},
|
},
|
||||||
.x11 =
|
.x11 =
|
||||||
{
|
{
|
||||||
.xcbVulkanSurface = GLFW_TRUE,
|
.xcbVulkanSurface = true,
|
||||||
},
|
},
|
||||||
.wl =
|
.wl =
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-11
@@ -333,10 +333,8 @@ 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(xoffset > -FLT_MAX);
|
assert(isfinite(xoffset));
|
||||||
assert(xoffset < FLT_MAX);
|
assert(isfinite(yoffset));
|
||||||
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);
|
||||||
@@ -375,10 +373,8 @@ 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(xpos > -FLT_MAX);
|
assert(isfinite(xpos));
|
||||||
assert(xpos < FLT_MAX);
|
assert(isfinite(ypos));
|
||||||
assert(ypos > -FLT_MAX);
|
|
||||||
assert(ypos < FLT_MAX);
|
|
||||||
|
|
||||||
if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
|
if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
|
||||||
return;
|
return;
|
||||||
@@ -436,6 +432,7 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -818,8 +815,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
|
|||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
|
|
||||||
if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
|
if (!isfinite(xpos) || !isfinite(ypos))
|
||||||
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",
|
||||||
@@ -1499,7 +1495,7 @@ GLFWAPI void glfwSetTime(double time)
|
|||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
if (time != time || time < 0.0 || time > 18446744073.0)
|
if (!isfinite(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;
|
||||||
|
|||||||
+52
-50
@@ -109,6 +109,7 @@ typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield);
|
|||||||
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
|
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
|
||||||
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
|
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
|
||||||
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
||||||
|
typedef void (APIENTRY * PFNGLFLUSHPROC)(void);
|
||||||
|
|
||||||
#define EGL_SUCCESS 0x3000
|
#define EGL_SUCCESS 0x3000
|
||||||
#define EGL_NOT_INITIALIZED 0x3001
|
#define EGL_NOT_INITIALIZED 0x3001
|
||||||
@@ -374,16 +375,16 @@ struct _GLFWerror
|
|||||||
//
|
//
|
||||||
struct _GLFWinitconfig
|
struct _GLFWinitconfig
|
||||||
{
|
{
|
||||||
GLFWbool hatButtons;
|
bool hatButtons;
|
||||||
int angleType;
|
int angleType;
|
||||||
int platformID;
|
int platformID;
|
||||||
PFN_vkGetInstanceProcAddr vulkanLoader;
|
PFN_vkGetInstanceProcAddr vulkanLoader;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool menubar;
|
bool menubar;
|
||||||
GLFWbool chdir;
|
bool chdir;
|
||||||
} ns;
|
} ns;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool xcbVulkanSurface;
|
bool xcbVulkanSurface;
|
||||||
} x11;
|
} x11;
|
||||||
struct {
|
struct {
|
||||||
int libdecorMode;
|
int libdecorMode;
|
||||||
@@ -402,18 +403,18 @@ struct _GLFWwndconfig
|
|||||||
int ypos;
|
int ypos;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
GLFWbool resizable;
|
bool resizable;
|
||||||
GLFWbool visible;
|
bool visible;
|
||||||
GLFWbool decorated;
|
bool decorated;
|
||||||
GLFWbool focused;
|
bool focused;
|
||||||
GLFWbool autoIconify;
|
bool autoIconify;
|
||||||
GLFWbool floating;
|
bool floating;
|
||||||
GLFWbool maximized;
|
bool maximized;
|
||||||
GLFWbool centerCursor;
|
bool centerCursor;
|
||||||
GLFWbool focusOnShow;
|
bool focusOnShow;
|
||||||
GLFWbool mousePassthrough;
|
bool mousePassthrough;
|
||||||
GLFWbool scaleToMonitor;
|
bool scaleToMonitor;
|
||||||
GLFWbool scaleFramebuffer;
|
bool scaleFramebuffer;
|
||||||
struct {
|
struct {
|
||||||
char frameName[256];
|
char frameName[256];
|
||||||
} ns;
|
} ns;
|
||||||
@@ -422,8 +423,8 @@ struct _GLFWwndconfig
|
|||||||
char instanceName[256];
|
char instanceName[256];
|
||||||
} x11;
|
} x11;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool keymenu;
|
bool keymenu;
|
||||||
GLFWbool showDefault;
|
bool showDefault;
|
||||||
} win32;
|
} win32;
|
||||||
struct {
|
struct {
|
||||||
char appId[256];
|
char appId[256];
|
||||||
@@ -442,15 +443,15 @@ struct _GLFWctxconfig
|
|||||||
int source;
|
int source;
|
||||||
int major;
|
int major;
|
||||||
int minor;
|
int minor;
|
||||||
GLFWbool forward;
|
bool forward;
|
||||||
GLFWbool debug;
|
bool debug;
|
||||||
GLFWbool noerror;
|
bool noerror;
|
||||||
int profile;
|
int profile;
|
||||||
int robustness;
|
int robustness;
|
||||||
int release;
|
int release;
|
||||||
_GLFWwindow* share;
|
_GLFWwindow* share;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool offline;
|
bool offline;
|
||||||
} nsgl;
|
} nsgl;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -475,11 +476,11 @@ struct _GLFWfbconfig
|
|||||||
int accumBlueBits;
|
int accumBlueBits;
|
||||||
int accumAlphaBits;
|
int accumAlphaBits;
|
||||||
int auxBuffers;
|
int auxBuffers;
|
||||||
GLFWbool stereo;
|
bool stereo;
|
||||||
int samples;
|
int samples;
|
||||||
GLFWbool sRGB;
|
bool sRGB;
|
||||||
GLFWbool doublebuffer;
|
bool doublebuffer;
|
||||||
GLFWbool transparent;
|
bool transparent;
|
||||||
uintptr_t handle;
|
uintptr_t handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -498,6 +499,7 @@ struct _GLFWcontext
|
|||||||
PFNGLGETSTRINGIPROC GetStringi;
|
PFNGLGETSTRINGIPROC GetStringi;
|
||||||
PFNGLGETINTEGERVPROC GetIntegerv;
|
PFNGLGETINTEGERVPROC GetIntegerv;
|
||||||
PFNGLGETSTRINGPROC GetString;
|
PFNGLGETSTRINGPROC GetString;
|
||||||
|
PFNGLFLUSHPROC Flush;
|
||||||
|
|
||||||
void (*makeCurrent)(_GLFWwindow*);
|
void (*makeCurrent)(_GLFWwindow*);
|
||||||
void (*swapBuffers)(_GLFWwindow*);
|
void (*swapBuffers)(_GLFWwindow*);
|
||||||
@@ -805,22 +807,22 @@ struct _GLFWlibrary
|
|||||||
EGLint major, minor;
|
EGLint major, minor;
|
||||||
GLFWbool prefix;
|
GLFWbool prefix;
|
||||||
|
|
||||||
GLFWbool KHR_create_context;
|
bool KHR_create_context;
|
||||||
GLFWbool KHR_create_context_no_error;
|
bool KHR_create_context_no_error;
|
||||||
GLFWbool KHR_gl_colorspace;
|
bool KHR_gl_colorspace;
|
||||||
GLFWbool KHR_get_all_proc_addresses;
|
bool KHR_get_all_proc_addresses;
|
||||||
GLFWbool KHR_context_flush_control;
|
bool KHR_context_flush_control;
|
||||||
GLFWbool EXT_client_extensions;
|
bool EXT_client_extensions;
|
||||||
GLFWbool EXT_platform_base;
|
bool EXT_platform_base;
|
||||||
GLFWbool EXT_platform_x11;
|
bool EXT_platform_x11;
|
||||||
GLFWbool EXT_platform_wayland;
|
bool EXT_platform_wayland;
|
||||||
GLFWbool EXT_present_opaque;
|
bool EXT_present_opaque;
|
||||||
GLFWbool ANGLE_platform_angle;
|
bool ANGLE_platform_angle;
|
||||||
GLFWbool ANGLE_platform_angle_opengl;
|
bool ANGLE_platform_angle_opengl;
|
||||||
GLFWbool ANGLE_platform_angle_d3d;
|
bool ANGLE_platform_angle_d3d;
|
||||||
GLFWbool ANGLE_platform_angle_vulkan;
|
bool ANGLE_platform_angle_vulkan;
|
||||||
GLFWbool ANGLE_platform_angle_metal;
|
bool ANGLE_platform_angle_metal;
|
||||||
GLFWbool MESA_platform_surfaceless;
|
bool MESA_platform_surfaceless;
|
||||||
|
|
||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
@@ -864,14 +866,14 @@ struct _GLFWlibrary
|
|||||||
void* handle;
|
void* handle;
|
||||||
char* extensions[2];
|
char* extensions[2];
|
||||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||||
GLFWbool KHR_surface;
|
bool KHR_surface;
|
||||||
GLFWbool KHR_win32_surface;
|
bool KHR_win32_surface;
|
||||||
GLFWbool MVK_macos_surface;
|
bool MVK_macos_surface;
|
||||||
GLFWbool EXT_metal_surface;
|
bool EXT_metal_surface;
|
||||||
GLFWbool KHR_xlib_surface;
|
bool KHR_xlib_surface;
|
||||||
GLFWbool KHR_xcb_surface;
|
bool KHR_xcb_surface;
|
||||||
GLFWbool KHR_wayland_surface;
|
bool KHR_wayland_surface;
|
||||||
GLFWbool EXT_headless_surface;
|
bool EXT_headless_surface;
|
||||||
} vk;
|
} vk;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#if defined(GLFW_BUILD_COCOA_TIMER)
|
#if defined(GLFW_BUILD_MACOS_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.ns.frequency = (info.denom * 1e9) / info.numer;
|
_glfw.timer.macos.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.ns.frequency;
|
return _glfw.timer.macos.frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GLFW_BUILD_COCOA_TIMER
|
#endif // GLFW_BUILD_MACOS_TIMER
|
||||||
|
|
||||||
@@ -24,12 +24,12 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#define GLFW_COCOA_LIBRARY_TIMER_STATE _GLFWtimerNS ns;
|
#define GLFW_MACOS_LIBRARY_TIMER_STATE _GLFWtimerMacOS macos;
|
||||||
|
|
||||||
// Cocoa-specific global timer data
|
// macOS-specific global timer data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWtimerNS
|
typedef struct _GLFWtimerMacOS
|
||||||
{
|
{
|
||||||
uint64_t frequency;
|
uint64_t frequency;
|
||||||
} _GLFWtimerNS;
|
} _GLFWtimerMacOS;
|
||||||
|
|
||||||
+3
-2
@@ -467,14 +467,15 @@ 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(gamma <= FLT_MAX);
|
assert(isfinite(gamma));
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
|
if (!isfinite(gamma) || gamma <= 0.f)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -128,8 +128,6 @@ static void destroyContextNSGL(_GLFWwindow* window)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Initialize OpenGL support
|
|
||||||
//
|
|
||||||
GLFWbool _glfwInitNSGL(void)
|
GLFWbool _glfwInitNSGL(void)
|
||||||
{
|
{
|
||||||
if (_glfw.nsgl.framework)
|
if (_glfw.nsgl.framework)
|
||||||
@@ -147,14 +145,10 @@ GLFWbool _glfwInitNSGL(void)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminate OpenGL support
|
|
||||||
//
|
|
||||||
void _glfwTerminateNSGL(void)
|
void _glfwTerminateNSGL(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL context
|
|
||||||
//
|
|
||||||
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
|||||||
@@ -260,5 +260,6 @@ void _glfwTerminateNull(void)
|
|||||||
free(_glfw.null.clipboardString);
|
free(_glfw.null.clipboardString);
|
||||||
_glfwTerminateOSMesa();
|
_glfwTerminateOSMesa();
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
|
memset(&_glfw.null, 0, sizeof(_glfw.null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,13 +179,10 @@ GLFWbool _glfwInitOSMesa(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _glfwTerminateOSMesa(void)
|
void _glfwTerminateOSMesa(void)
|
||||||
{
|
|
||||||
if (_glfw.osmesa.handle)
|
|
||||||
{
|
{
|
||||||
_glfwPlatformFreeModule(_glfw.osmesa.handle);
|
_glfwPlatformFreeModule(_glfw.osmesa.handle);
|
||||||
_glfw.osmesa.handle = NULL;
|
_glfw.osmesa.handle = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_ATTRIB(a, v) \
|
#define SET_ATTRIB(a, v) \
|
||||||
{ \
|
{ \
|
||||||
|
|||||||
+6
-5
@@ -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_COCOA_TIMER) || \
|
defined(GLFW_BUILD_MACOS_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_COCOA_TIMER
|
#define GLFW_BUILD_MACOS_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_COCOA_TIMER)
|
#elif defined(GLFW_BUILD_MACOS_TIMER)
|
||||||
#include "cocoa_time.h"
|
#include "macos_time.h"
|
||||||
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE
|
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_MACOS_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,6 +207,7 @@
|
|||||||
#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
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ void* _glfwPlatformLoadModule(const char* path)
|
|||||||
|
|
||||||
void _glfwPlatformFreeModule(void* module)
|
void _glfwPlatformFreeModule(void* module)
|
||||||
{
|
{
|
||||||
|
if (module)
|
||||||
dlclose(module);
|
dlclose(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+46
-12
@@ -34,6 +34,40 @@
|
|||||||
#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 //////
|
||||||
@@ -55,12 +89,12 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
{
|
{
|
||||||
#if defined(_GLFW_VULKAN_LIBRARY)
|
#if defined(_GLFW_VULKAN_LIBRARY)
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
|
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_WIN32)
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
|
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(__APPLE__)
|
||||||
_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 = _glfwLoadLocalVulkanLoaderCocoa();
|
_glfw.vk.handle = loadLocalVulkanLoaderMacOS();
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
|
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
|
||||||
#else
|
#else
|
||||||
@@ -129,21 +163,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 = GLFW_TRUE;
|
_glfw.vk.KHR_surface = 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 = GLFW_TRUE;
|
_glfw.vk.KHR_win32_surface = 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 = GLFW_TRUE;
|
_glfw.vk.MVK_macos_surface = 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 = GLFW_TRUE;
|
_glfw.vk.EXT_metal_surface = 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 = GLFW_TRUE;
|
_glfw.vk.KHR_xlib_surface = 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 = GLFW_TRUE;
|
_glfw.vk.KHR_xcb_surface = 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 = GLFW_TRUE;
|
_glfw.vk.KHR_wayland_surface = 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 = GLFW_TRUE;
|
_glfw.vk.EXT_headless_surface = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw_free(ep);
|
_glfw_free(ep);
|
||||||
@@ -157,8 +191,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
|
|
||||||
void _glfwTerminateVulkan(void)
|
void _glfwTerminateVulkan(void)
|
||||||
{
|
{
|
||||||
if (_glfw.vk.handle)
|
|
||||||
_glfwPlatformFreeModule(_glfw.vk.handle);
|
_glfwPlatformFreeModule(_glfw.vk.handle);
|
||||||
|
_glfw.vk.handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwGetVulkanResultString(VkResult result)
|
const char* _glfwGetVulkanResultString(VkResult result)
|
||||||
|
|||||||
+7
-21
@@ -186,28 +186,22 @@ 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 ||
|
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
|
||||||
_glfw.wgl.EXT_framebuffer_sRGB)
|
u->sRGB = FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
||||||
{
|
|
||||||
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 = GLFW_TRUE;
|
u->sRGB = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,9 +255,7 @@ 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;
|
||||||
@@ -401,8 +393,6 @@ static void destroyContextWGL(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize WGL
|
|
||||||
//
|
|
||||||
GLFWbool _glfwInitWGL(void)
|
GLFWbool _glfwInitWGL(void)
|
||||||
{
|
{
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
@@ -521,12 +511,10 @@ GLFWbool _glfwInitWGL(void)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminate WGL
|
|
||||||
//
|
|
||||||
void _glfwTerminateWGL(void)
|
void _glfwTerminateWGL(void)
|
||||||
{
|
{
|
||||||
if (_glfw.wgl.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.wgl.instance);
|
_glfwPlatformFreeModule(_glfw.wgl.instance);
|
||||||
|
_glfw.wgl.instance = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SET_ATTRIB(a, v) \
|
#define SET_ATTRIB(a, v) \
|
||||||
@@ -536,8 +524,6 @@ void _glfwTerminateWGL(void)
|
|||||||
attribs[index++] = v; \
|
attribs[index++] = v; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
|
||||||
//
|
|
||||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
@@ -670,7 +656,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, GLFW_TRUE);
|
SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||||
|
|||||||
+10
-25
@@ -166,29 +166,6 @@ static GLFWbool loadLibraries(void)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unload used libraries (DLLs)
|
|
||||||
//
|
|
||||||
static void freeLibraries(void)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.xinput.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.win32.xinput.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.dinput8.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.win32.dinput8.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.user32.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.win32.user32.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.dwmapi.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.win32.dwmapi.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.shcore.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.win32.shcore.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.ntdll.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create key code translation tables
|
// Create key code translation tables
|
||||||
//
|
//
|
||||||
static void createKeyTables(void)
|
static void createKeyTables(void)
|
||||||
@@ -528,7 +505,8 @@ void _glfwUpdateKeyNamesWin32(void)
|
|||||||
|
|
||||||
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
|
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
|
||||||
{
|
{
|
||||||
const UINT vks[] = {
|
const UINT vks[] =
|
||||||
|
{
|
||||||
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
||||||
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
||||||
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
|
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
|
||||||
@@ -720,7 +698,14 @@ void _glfwTerminateWin32(void)
|
|||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
_glfwTerminateOSMesa();
|
_glfwTerminateOSMesa();
|
||||||
|
|
||||||
freeLibraries();
|
_glfwPlatformFreeModule(_glfw.win32.xinput.instance);
|
||||||
|
_glfwPlatformFreeModule(_glfw.win32.dinput8.instance);
|
||||||
|
_glfwPlatformFreeModule(_glfw.win32.user32.instance);
|
||||||
|
_glfwPlatformFreeModule(_glfw.win32.dwmapi.instance);
|
||||||
|
_glfwPlatformFreeModule(_glfw.win32.shcore.instance);
|
||||||
|
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
|
||||||
|
|
||||||
|
memset(&_glfw.win32, 0, sizeof(_glfw.win32));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WIN32
|
#endif // _GLFW_WIN32
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ void* _glfwPlatformLoadModule(const char* path)
|
|||||||
|
|
||||||
void _glfwPlatformFreeModule(void* module)
|
void _glfwPlatformFreeModule(void* module)
|
||||||
{
|
{
|
||||||
|
if (module)
|
||||||
FreeLibrary((HMODULE) module);
|
FreeLibrary((HMODULE) module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -336,18 +336,18 @@ typedef struct _GLFWlibraryWGL
|
|||||||
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
|
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
|
||||||
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
||||||
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||||
GLFWbool EXT_swap_control;
|
bool EXT_swap_control;
|
||||||
GLFWbool EXT_colorspace;
|
bool EXT_colorspace;
|
||||||
GLFWbool ARB_multisample;
|
bool ARB_multisample;
|
||||||
GLFWbool ARB_framebuffer_sRGB;
|
bool ARB_framebuffer_sRGB;
|
||||||
GLFWbool EXT_framebuffer_sRGB;
|
bool EXT_framebuffer_sRGB;
|
||||||
GLFWbool ARB_pixel_format;
|
bool ARB_pixel_format;
|
||||||
GLFWbool ARB_create_context;
|
bool ARB_create_context;
|
||||||
GLFWbool ARB_create_context_profile;
|
bool ARB_create_context_profile;
|
||||||
GLFWbool EXT_create_context_es2_profile;
|
bool EXT_create_context_es2_profile;
|
||||||
GLFWbool ARB_create_context_robustness;
|
bool ARB_create_context_robustness;
|
||||||
GLFWbool ARB_create_context_no_error;
|
bool ARB_create_context_no_error;
|
||||||
GLFWbool ARB_context_flush_control;
|
bool ARB_context_flush_control;
|
||||||
} _GLFWlibraryWGL;
|
} _GLFWlibraryWGL;
|
||||||
|
|
||||||
// Win32-specific per-window data
|
// Win32-specific per-window data
|
||||||
|
|||||||
+38
-39
@@ -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(xscale < FLT_MAX);
|
assert(isfinite(xscale));
|
||||||
assert(yscale > 0.f);
|
assert(yscale > 0.f);
|
||||||
assert(yscale < FLT_MAX);
|
assert(isfinite(yscale));
|
||||||
|
|
||||||
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 = GLFW_TRUE;
|
_glfw.hints.window.resizable = true;
|
||||||
_glfw.hints.window.visible = GLFW_TRUE;
|
_glfw.hints.window.visible = true;
|
||||||
_glfw.hints.window.decorated = GLFW_TRUE;
|
_glfw.hints.window.decorated = true;
|
||||||
_glfw.hints.window.focused = GLFW_TRUE;
|
_glfw.hints.window.focused = true;
|
||||||
_glfw.hints.window.autoIconify = GLFW_TRUE;
|
_glfw.hints.window.autoIconify = true;
|
||||||
_glfw.hints.window.centerCursor = GLFW_TRUE;
|
_glfw.hints.window.centerCursor = true;
|
||||||
_glfw.hints.window.focusOnShow = GLFW_TRUE;
|
_glfw.hints.window.focusOnShow = 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 = GLFW_TRUE;
|
_glfw.hints.window.scaleFramebuffer = 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 = GLFW_TRUE;
|
_glfw.hints.framebuffer.doublebuffer = 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_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.stereo = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_DOUBLEBUFFER:
|
case GLFW_DOUBLEBUFFER:
|
||||||
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.doublebuffer = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_TRANSPARENT_FRAMEBUFFER:
|
case GLFW_TRANSPARENT_FRAMEBUFFER:
|
||||||
_glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.transparent = value;
|
||||||
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_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.sRGB = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_RESIZABLE:
|
case GLFW_RESIZABLE:
|
||||||
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.resizable = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_DECORATED:
|
case GLFW_DECORATED:
|
||||||
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.decorated = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_FOCUSED:
|
case GLFW_FOCUSED:
|
||||||
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.focused = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_AUTO_ICONIFY:
|
case GLFW_AUTO_ICONIFY:
|
||||||
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.autoIconify = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_FLOATING:
|
case GLFW_FLOATING:
|
||||||
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.floating = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_MAXIMIZED:
|
case GLFW_MAXIMIZED:
|
||||||
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.maximized = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_VISIBLE:
|
case GLFW_VISIBLE:
|
||||||
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.visible = value;
|
||||||
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_TRUE : GLFW_FALSE;
|
_glfw.hints.window.win32.keymenu = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_WIN32_SHOWDEFAULT:
|
case GLFW_WIN32_SHOWDEFAULT:
|
||||||
_glfw.hints.window.win32.showDefault = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.win32.showDefault = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.nsgl.offline = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_SCALE_TO_MONITOR:
|
case GLFW_SCALE_TO_MONITOR:
|
||||||
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.scaleToMonitor = value;
|
||||||
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_TRUE : GLFW_FALSE;
|
_glfw.hints.window.scaleFramebuffer = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_CENTER_CURSOR:
|
case GLFW_CENTER_CURSOR:
|
||||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.centerCursor = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_FOCUS_ON_SHOW:
|
case GLFW_FOCUS_ON_SHOW:
|
||||||
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.focusOnShow = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_MOUSE_PASSTHROUGH:
|
case GLFW_MOUSE_PASSTHROUGH:
|
||||||
_glfw.hints.window.mousePassthrough = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.mousePassthrough = value;
|
||||||
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_TRUE : GLFW_FALSE;
|
_glfw.hints.context.forward = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_CONTEXT_DEBUG:
|
case GLFW_CONTEXT_DEBUG:
|
||||||
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.debug = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_CONTEXT_NO_ERROR:
|
case GLFW_CONTEXT_NO_ERROR:
|
||||||
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.noerror = value;
|
||||||
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(opacity == opacity);
|
assert(isfinite(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 (opacity != opacity || opacity < 0.f || opacity > 1.f)
|
if (!isfinite(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,11 +1178,10 @@ GLFWAPI void glfwWaitEvents(void)
|
|||||||
GLFWAPI void glfwWaitEventsTimeout(double timeout)
|
GLFWAPI void glfwWaitEventsTimeout(double timeout)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
assert(timeout == timeout);
|
assert(isfinite(timeout));
|
||||||
assert(timeout >= 0.0);
|
assert(timeout >= 0.0);
|
||||||
assert(timeout <= DBL_MAX);
|
|
||||||
|
|
||||||
if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
|
if (!isfinite(timeout) || timeout < 0.0)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+48
-40
@@ -135,15 +135,8 @@ 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(4, version));
|
_glfw_min(8, version));
|
||||||
_glfwAddSeatListenerWayland(_glfw.wl.seat);
|
_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)
|
else if (strcmp(interface, "wl_data_device_manager") == 0)
|
||||||
@@ -251,10 +244,7 @@ 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 =
|
||||||
@@ -585,6 +575,14 @@ int _glfwInitWayland(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_get_fd");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_get_fd");
|
||||||
_glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read)
|
_glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read");
|
||||||
|
_glfw.wl.client.display_create_queue = (PFN_wl_display_create_queue)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_create_queue");
|
||||||
|
_glfw.wl.client.display_prepare_read_queue = (PFN_wl_display_prepare_read_queue)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read_queue");
|
||||||
|
_glfw.wl.client.display_dispatch_queue_pending = (PFN_wl_display_dispatch_queue_pending)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_dispatch_queue_pending");
|
||||||
|
_glfw.wl.client.event_queue_destroy = (PFN_wl_event_queue_destroy)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_event_queue_destroy");
|
||||||
_glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal)
|
_glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal");
|
||||||
_glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener)
|
_glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener)
|
||||||
@@ -607,6 +605,12 @@ int _glfwInitWayland(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version");
|
||||||
_glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)
|
_glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_flags");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_flags");
|
||||||
|
_glfw.wl.client.proxy_create_wrapper = (PFN_wl_proxy_create_wrapper)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_create_wrapper");
|
||||||
|
_glfw.wl.client.proxy_wrapper_destroy = (PFN_wl_proxy_wrapper_destroy)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_wrapper_destroy");
|
||||||
|
_glfw.wl.client.proxy_set_queue = (PFN_wl_proxy_set_queue)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_queue");
|
||||||
|
|
||||||
if (!_glfw.wl.client.display_flush ||
|
if (!_glfw.wl.client.display_flush ||
|
||||||
!_glfw.wl.client.display_cancel_read ||
|
!_glfw.wl.client.display_cancel_read ||
|
||||||
@@ -616,6 +620,10 @@ int _glfwInitWayland(void)
|
|||||||
!_glfw.wl.client.display_roundtrip ||
|
!_glfw.wl.client.display_roundtrip ||
|
||||||
!_glfw.wl.client.display_get_fd ||
|
!_glfw.wl.client.display_get_fd ||
|
||||||
!_glfw.wl.client.display_prepare_read ||
|
!_glfw.wl.client.display_prepare_read ||
|
||||||
|
!_glfw.wl.client.display_create_queue ||
|
||||||
|
!_glfw.wl.client.display_prepare_read_queue ||
|
||||||
|
!_glfw.wl.client.display_dispatch_queue_pending ||
|
||||||
|
!_glfw.wl.client.event_queue_destroy ||
|
||||||
!_glfw.wl.client.proxy_marshal ||
|
!_glfw.wl.client.proxy_marshal ||
|
||||||
!_glfw.wl.client.proxy_add_listener ||
|
!_glfw.wl.client.proxy_add_listener ||
|
||||||
!_glfw.wl.client.proxy_destroy ||
|
!_glfw.wl.client.proxy_destroy ||
|
||||||
@@ -624,7 +632,10 @@ int _glfwInitWayland(void)
|
|||||||
!_glfw.wl.client.proxy_get_user_data ||
|
!_glfw.wl.client.proxy_get_user_data ||
|
||||||
!_glfw.wl.client.proxy_set_user_data ||
|
!_glfw.wl.client.proxy_set_user_data ||
|
||||||
!_glfw.wl.client.proxy_get_tag ||
|
!_glfw.wl.client.proxy_get_tag ||
|
||||||
!_glfw.wl.client.proxy_set_tag)
|
!_glfw.wl.client.proxy_set_tag ||
|
||||||
|
!_glfw.wl.client.proxy_create_wrapper ||
|
||||||
|
!_glfw.wl.client.proxy_wrapper_destroy ||
|
||||||
|
!_glfw.wl.client.proxy_set_queue)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Failed to load libwayland-client entry point");
|
"Wayland: Failed to load libwayland-client entry point");
|
||||||
@@ -834,7 +845,17 @@ int _glfwInitWayland(void)
|
|||||||
|
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
|
|
||||||
_glfw.wl.xkb.context = xkb_context_new(0);
|
_glfw.wl.keyRepeatTimerfd =
|
||||||
|
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||||
|
if (_glfw.wl.keyRepeatTimerfd == -1)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create timerfd: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!_glfw.wl.xkb.context)
|
if (!_glfw.wl.xkb.context)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@@ -857,10 +878,8 @@ 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
|
||||||
_glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display);
|
struct wl_callback* callback = wl_display_sync(_glfw.wl.display);
|
||||||
wl_callback_add_listener(_glfw.wl.libdecor.callback,
|
wl_callback_add_listener(callback, &libdecorReadyListener, NULL);
|
||||||
&libdecorReadyListener,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,18 +926,6 @@ void _glfwTerminateWayland(void)
|
|||||||
libdecor_unref(_glfw.wl.libdecor.context);
|
libdecor_unref(_glfw.wl.libdecor.context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.wl.libdecor.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
|
|
||||||
_glfw.wl.libdecor.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.wl.egl.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
|
|
||||||
_glfw.wl.egl.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.wl.xkb.composeState)
|
if (_glfw.wl.xkb.composeState)
|
||||||
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
||||||
if (_glfw.wl.xkb.keymap)
|
if (_glfw.wl.xkb.keymap)
|
||||||
@@ -927,21 +934,11 @@ void _glfwTerminateWayland(void)
|
|||||||
xkb_state_unref(_glfw.wl.xkb.state);
|
xkb_state_unref(_glfw.wl.xkb.state);
|
||||||
if (_glfw.wl.xkb.context)
|
if (_glfw.wl.xkb.context)
|
||||||
xkb_context_unref(_glfw.wl.xkb.context);
|
xkb_context_unref(_glfw.wl.xkb.context);
|
||||||
if (_glfw.wl.xkb.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
|
|
||||||
_glfw.wl.xkb.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.wl.cursorTheme)
|
if (_glfw.wl.cursorTheme)
|
||||||
wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
|
wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
|
||||||
if (_glfw.wl.cursorThemeHiDPI)
|
if (_glfw.wl.cursorThemeHiDPI)
|
||||||
wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
|
wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
|
||||||
if (_glfw.wl.cursor.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
|
|
||||||
_glfw.wl.cursor.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
|
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
|
||||||
wl_data_offer_destroy(_glfw.wl.offers[i].offer);
|
wl_data_offer_destroy(_glfw.wl.offers[i].offer);
|
||||||
@@ -1001,7 +998,18 @@ void _glfwTerminateWayland(void)
|
|||||||
if (_glfw.wl.cursorTimerfd >= 0)
|
if (_glfw.wl.cursorTimerfd >= 0)
|
||||||
close(_glfw.wl.cursorTimerfd);
|
close(_glfw.wl.cursorTimerfd);
|
||||||
|
|
||||||
|
// Free modules only after all Wayland termination functions are called
|
||||||
|
|
||||||
|
_glfwPlatformFreeModule(_glfw.egl.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.wl.client.handle);
|
||||||
|
|
||||||
_glfw_free(_glfw.wl.clipboardString);
|
_glfw_free(_glfw.wl.clipboardString);
|
||||||
|
|
||||||
|
memset(&_glfw.wl, 0, sizeof(_glfw.wl));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WAYLAND
|
#endif // _GLFW_WAYLAND
|
||||||
|
|||||||
+49
-10
@@ -42,8 +42,6 @@ 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);
|
||||||
@@ -53,6 +51,10 @@ typedef void (* PFN_wl_display_disconnect)(struct wl_display*);
|
|||||||
typedef int (* PFN_wl_display_roundtrip)(struct wl_display*);
|
typedef int (* PFN_wl_display_roundtrip)(struct wl_display*);
|
||||||
typedef int (* PFN_wl_display_get_fd)(struct wl_display*);
|
typedef int (* PFN_wl_display_get_fd)(struct wl_display*);
|
||||||
typedef int (* PFN_wl_display_prepare_read)(struct wl_display*);
|
typedef int (* PFN_wl_display_prepare_read)(struct wl_display*);
|
||||||
|
typedef struct wl_event_queue* (* PFN_wl_display_create_queue)(struct wl_display*);
|
||||||
|
typedef void (* PFN_wl_event_queue_destroy)(struct wl_event_queue*);
|
||||||
|
typedef int (* PFN_wl_display_prepare_read_queue)(struct wl_display*,struct wl_event_queue*);
|
||||||
|
typedef int (* PFN_wl_display_dispatch_queue_pending)(struct wl_display*,struct wl_event_queue*);
|
||||||
typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*,uint32_t,...);
|
typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*,uint32_t,...);
|
||||||
typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*,void(**)(void),void*);
|
typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*,void(**)(void),void*);
|
||||||
typedef void (* PFN_wl_proxy_destroy)(struct wl_proxy*);
|
typedef void (* PFN_wl_proxy_destroy)(struct wl_proxy*);
|
||||||
@@ -64,6 +66,9 @@ typedef void (* PFN_wl_proxy_set_tag)(struct wl_proxy*,const char*const*);
|
|||||||
typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*);
|
typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*);
|
||||||
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
|
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
|
||||||
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...);
|
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...);
|
||||||
|
typedef void* (* PFN_wl_proxy_create_wrapper)(void*);
|
||||||
|
typedef void (* PFN_wl_proxy_wrapper_destroy)(void*);
|
||||||
|
typedef void (* PFN_wl_proxy_set_queue)(struct wl_proxy*,struct wl_event_queue*);
|
||||||
#define wl_display_flush _glfw.wl.client.display_flush
|
#define wl_display_flush _glfw.wl.client.display_flush
|
||||||
#define wl_display_cancel_read _glfw.wl.client.display_cancel_read
|
#define wl_display_cancel_read _glfw.wl.client.display_cancel_read
|
||||||
#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending
|
#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending
|
||||||
@@ -72,6 +77,10 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_
|
|||||||
#define wl_display_roundtrip _glfw.wl.client.display_roundtrip
|
#define wl_display_roundtrip _glfw.wl.client.display_roundtrip
|
||||||
#define wl_display_get_fd _glfw.wl.client.display_get_fd
|
#define wl_display_get_fd _glfw.wl.client.display_get_fd
|
||||||
#define wl_display_prepare_read _glfw.wl.client.display_prepare_read
|
#define wl_display_prepare_read _glfw.wl.client.display_prepare_read
|
||||||
|
#define wl_display_create_queue _glfw.wl.client.display_create_queue
|
||||||
|
#define wl_display_prepare_read_queue _glfw.wl.client.display_prepare_read_queue
|
||||||
|
#define wl_display_dispatch_queue_pending _glfw.wl.client.display_dispatch_queue_pending
|
||||||
|
#define wl_event_queue_destroy _glfw.wl.client.event_queue_destroy
|
||||||
#define wl_proxy_marshal _glfw.wl.client.proxy_marshal
|
#define wl_proxy_marshal _glfw.wl.client.proxy_marshal
|
||||||
#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener
|
#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener
|
||||||
#define wl_proxy_destroy _glfw.wl.client.proxy_destroy
|
#define wl_proxy_destroy _glfw.wl.client.proxy_destroy
|
||||||
@@ -83,6 +92,9 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_
|
|||||||
#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag
|
#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag
|
||||||
#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
|
#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
|
||||||
#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
|
#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
|
||||||
|
#define wl_proxy_create_wrapper _glfw.wl.client.proxy_create_wrapper
|
||||||
|
#define wl_proxy_wrapper_destroy _glfw.wl.client.proxy_wrapper_destroy
|
||||||
|
#define wl_proxy_set_queue _glfw.wl.client.proxy_set_queue
|
||||||
|
|
||||||
struct wl_shm;
|
struct wl_shm;
|
||||||
struct wl_output;
|
struct wl_output;
|
||||||
@@ -136,18 +148,22 @@ struct wl_output;
|
|||||||
#define GLFW_WAYLAND_MONITOR_STATE _GLFWmonitorWayland wl;
|
#define GLFW_WAYLAND_MONITOR_STATE _GLFWmonitorWayland wl;
|
||||||
#define GLFW_WAYLAND_CURSOR_STATE _GLFWcursorWayland wl;
|
#define GLFW_WAYLAND_CURSOR_STATE _GLFWcursorWayland wl;
|
||||||
|
|
||||||
struct wl_cursor_image {
|
struct wl_cursor_image
|
||||||
|
{
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
uint32_t hotspot_x;
|
uint32_t hotspot_x;
|
||||||
uint32_t hotspot_y;
|
uint32_t hotspot_y;
|
||||||
uint32_t delay;
|
uint32_t delay;
|
||||||
};
|
};
|
||||||
struct wl_cursor {
|
|
||||||
|
struct wl_cursor
|
||||||
|
{
|
||||||
unsigned int image_count;
|
unsigned int image_count;
|
||||||
struct wl_cursor_image** images;
|
struct wl_cursor_image** images;
|
||||||
char* name;
|
char* name;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*);
|
typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*);
|
||||||
typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*);
|
typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*);
|
||||||
typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*);
|
typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*);
|
||||||
@@ -356,14 +372,17 @@ typedef struct _GLFWwindowWayland
|
|||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
GLFWbool activated;
|
GLFWbool activated;
|
||||||
GLFWbool fullscreen;
|
GLFWbool fullscreen;
|
||||||
GLFWbool hovered;
|
|
||||||
GLFWbool transparent;
|
GLFWbool transparent;
|
||||||
GLFWbool scaleFramebuffer;
|
GLFWbool scaleFramebuffer;
|
||||||
struct wl_surface* surface;
|
struct wl_surface* surface;
|
||||||
struct wl_callback* callback;
|
struct wl_callback* callback;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
struct wl_event_queue* queue;
|
||||||
struct wl_egl_window* window;
|
struct wl_egl_window* window;
|
||||||
|
struct wl_callback* callback;
|
||||||
|
struct wl_surface* wrapper;
|
||||||
|
int interval;
|
||||||
} egl;
|
} egl;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -385,7 +404,6 @@ typedef struct _GLFWwindowWayland
|
|||||||
struct libdecor_frame* frame;
|
struct libdecor_frame* frame;
|
||||||
} libdecor;
|
} libdecor;
|
||||||
|
|
||||||
_GLFWcursor* currentCursor;
|
|
||||||
double cursorPosX, cursorPosY;
|
double cursorPosX, cursorPosY;
|
||||||
|
|
||||||
char* appId;
|
char* appId;
|
||||||
@@ -412,8 +430,8 @@ typedef struct _GLFWwindowWayland
|
|||||||
GLFWbool decorations;
|
GLFWbool decorations;
|
||||||
struct wl_buffer* buffer;
|
struct wl_buffer* buffer;
|
||||||
_GLFWfallbackEdgeWayland top, left, right, bottom;
|
_GLFWfallbackEdgeWayland top, left, right, bottom;
|
||||||
struct wl_surface* focus;
|
double pointerX, pointerY;
|
||||||
wl_fixed_t pointerX, pointerY;
|
uint32_t buttonPressSerial;
|
||||||
const char* cursorName;
|
const char* cursorName;
|
||||||
} fallback;
|
} fallback;
|
||||||
} _GLFWwindowWayland;
|
} _GLFWwindowWayland;
|
||||||
@@ -453,6 +471,7 @@ typedef struct _GLFWlibraryWayland
|
|||||||
|
|
||||||
const char* tag;
|
const char* tag;
|
||||||
|
|
||||||
|
struct wl_surface* pointerSurface;
|
||||||
struct wl_cursor_theme* cursorTheme;
|
struct wl_cursor_theme* cursorTheme;
|
||||||
struct wl_cursor_theme* cursorThemeHiDPI;
|
struct wl_cursor_theme* cursorThemeHiDPI;
|
||||||
struct wl_surface* cursorSurface;
|
struct wl_surface* cursorSurface;
|
||||||
@@ -470,6 +489,19 @@ typedef struct _GLFWlibraryWayland
|
|||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
char keynames[GLFW_KEY_LAST + 1][5];
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_surface* pointerSurface;
|
||||||
|
unsigned int events;
|
||||||
|
double pointerX;
|
||||||
|
double pointerY;
|
||||||
|
double scrollX;
|
||||||
|
double scrollY;
|
||||||
|
double discreteX;
|
||||||
|
double discreteY;
|
||||||
|
int button;
|
||||||
|
int action;
|
||||||
|
} pending;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void* handle;
|
void* handle;
|
||||||
struct xkb_context* context;
|
struct xkb_context* context;
|
||||||
@@ -511,7 +543,6 @@ typedef struct _GLFWlibraryWayland
|
|||||||
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
|
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
|
||||||
} xkb;
|
} xkb;
|
||||||
|
|
||||||
_GLFWwindow* pointerFocus;
|
|
||||||
_GLFWwindow* keyboardFocus;
|
_GLFWwindow* keyboardFocus;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -524,6 +555,10 @@ typedef struct _GLFWlibraryWayland
|
|||||||
PFN_wl_display_roundtrip display_roundtrip;
|
PFN_wl_display_roundtrip display_roundtrip;
|
||||||
PFN_wl_display_get_fd display_get_fd;
|
PFN_wl_display_get_fd display_get_fd;
|
||||||
PFN_wl_display_prepare_read display_prepare_read;
|
PFN_wl_display_prepare_read display_prepare_read;
|
||||||
|
PFN_wl_display_create_queue display_create_queue;
|
||||||
|
PFN_wl_display_prepare_read_queue display_prepare_read_queue;
|
||||||
|
PFN_wl_display_dispatch_queue_pending display_dispatch_queue_pending;
|
||||||
|
PFN_wl_event_queue_destroy event_queue_destroy;
|
||||||
PFN_wl_proxy_marshal proxy_marshal;
|
PFN_wl_proxy_marshal proxy_marshal;
|
||||||
PFN_wl_proxy_add_listener proxy_add_listener;
|
PFN_wl_proxy_add_listener proxy_add_listener;
|
||||||
PFN_wl_proxy_destroy proxy_destroy;
|
PFN_wl_proxy_destroy proxy_destroy;
|
||||||
@@ -535,6 +570,9 @@ typedef struct _GLFWlibraryWayland
|
|||||||
PFN_wl_proxy_set_tag proxy_set_tag;
|
PFN_wl_proxy_set_tag proxy_set_tag;
|
||||||
PFN_wl_proxy_get_version proxy_get_version;
|
PFN_wl_proxy_get_version proxy_get_version;
|
||||||
PFN_wl_proxy_marshal_flags proxy_marshal_flags;
|
PFN_wl_proxy_marshal_flags proxy_marshal_flags;
|
||||||
|
PFN_wl_proxy_create_wrapper proxy_create_wrapper;
|
||||||
|
PFN_wl_proxy_wrapper_destroy proxy_wrapper_destroy;
|
||||||
|
PFN_wl_proxy_set_queue proxy_set_queue;
|
||||||
} client;
|
} client;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -557,7 +595,6 @@ 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_;
|
||||||
@@ -693,3 +730,5 @@ void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window);
|
|||||||
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
||||||
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
||||||
|
|
||||||
|
GLFWbool _glfwWaitForEGLFrameWayland(_GLFWwindow* window);
|
||||||
|
|
||||||
|
|||||||
+356
-111
@@ -55,6 +55,12 @@
|
|||||||
#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_BUTTON 2
|
||||||
|
#define GLFW_PENDING_MOTION 4
|
||||||
|
#define GLFW_PENDING_SCROLL 8
|
||||||
|
#define GLFW_PENDING_DISCRETE 16
|
||||||
|
|
||||||
static int createTmpfileCloexec(char* tmpname)
|
static int createTmpfileCloexec(char* tmpname)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
@@ -193,6 +199,16 @@ 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,
|
||||||
@@ -253,6 +269,9 @@ static void createFallbackDecorations(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge)
|
static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge)
|
||||||
{
|
{
|
||||||
|
if (edge->surface == _glfw.wl.pointerSurface)
|
||||||
|
_glfw.wl.pointerSurface = NULL;
|
||||||
|
|
||||||
if (edge->subsurface)
|
if (edge->subsurface)
|
||||||
wl_subsurface_destroy(edge->subsurface);
|
wl_subsurface_destroy(edge->subsurface);
|
||||||
if (edge->surface)
|
if (edge->surface)
|
||||||
@@ -275,39 +294,35 @@ static void destroyFallbackDecorations(_GLFWwindow* window)
|
|||||||
destroyFallbackEdge(&window->wl.fallback.bottom);
|
destroyFallbackEdge(&window->wl.fallback.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateFallbackDecorationCursor(_GLFWwindow* window,
|
static void updateFallbackDecorationCursor(_GLFWwindow* window, double xpos, double ypos)
|
||||||
wl_fixed_t sx,
|
|
||||||
wl_fixed_t sy)
|
|
||||||
{
|
{
|
||||||
window->wl.fallback.pointerX = sx;
|
window->wl.fallback.pointerX = xpos;
|
||||||
window->wl.fallback.pointerY = sy;
|
window->wl.fallback.pointerY = ypos;
|
||||||
|
|
||||||
const double xpos = wl_fixed_to_double(sx);
|
|
||||||
const double ypos = wl_fixed_to_double(sy);
|
|
||||||
const char* cursorName = "left_ptr";
|
const char* cursorName = "left_ptr";
|
||||||
|
|
||||||
if (window->resizable)
|
if (window->resizable)
|
||||||
{
|
{
|
||||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
if (_glfw.wl.pointerSurface == window->wl.fallback.top.surface)
|
||||||
{
|
{
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
cursorName = "n-resize";
|
cursorName = "n-resize";
|
||||||
}
|
}
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
else if (_glfw.wl.pointerSurface == window->wl.fallback.left.surface)
|
||||||
{
|
{
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
cursorName = "nw-resize";
|
cursorName = "nw-resize";
|
||||||
else
|
else
|
||||||
cursorName = "w-resize";
|
cursorName = "w-resize";
|
||||||
}
|
}
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
else if (_glfw.wl.pointerSurface == window->wl.fallback.right.surface)
|
||||||
{
|
{
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
cursorName = "ne-resize";
|
cursorName = "ne-resize";
|
||||||
else
|
else
|
||||||
cursorName = "e-resize";
|
cursorName = "e-resize";
|
||||||
}
|
}
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
else if (_glfw.wl.pointerSurface == window->wl.fallback.bottom.surface)
|
||||||
{
|
{
|
||||||
if (xpos < GLFW_BORDER_SIZE)
|
if (xpos < GLFW_BORDER_SIZE)
|
||||||
cursorName = "sw-resize";
|
cursorName = "sw-resize";
|
||||||
@@ -358,39 +373,41 @@ static void updateFallbackDecorationCursor(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleFallbackDecorationButton(_GLFWwindow* window,
|
static void handleFallbackDecorationButton(_GLFWwindow* window, int button, int action)
|
||||||
uint32_t serial,
|
|
||||||
uint32_t button)
|
|
||||||
{
|
{
|
||||||
const double xpos = wl_fixed_to_double(window->wl.fallback.pointerX);
|
if (action != GLFW_PRESS)
|
||||||
const double ypos = wl_fixed_to_double(window->wl.fallback.pointerY);
|
return;
|
||||||
|
|
||||||
if (button == BTN_LEFT)
|
const double xpos = window->wl.fallback.pointerX;
|
||||||
|
const double ypos = window->wl.fallback.pointerY;
|
||||||
|
const uint32_t serial = window->wl.fallback.buttonPressSerial;
|
||||||
|
|
||||||
|
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
||||||
{
|
{
|
||||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||||
|
|
||||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
if (_glfw.wl.pointerSurface == window->wl.fallback.top.surface)
|
||||||
{
|
{
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
||||||
else
|
else
|
||||||
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
||||||
}
|
}
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
else if (_glfw.wl.pointerSurface == window->wl.fallback.left.surface)
|
||||||
{
|
{
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
||||||
else
|
else
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
||||||
}
|
}
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
else if (_glfw.wl.pointerSurface == window->wl.fallback.right.surface)
|
||||||
{
|
{
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
||||||
else
|
else
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
||||||
}
|
}
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
else if (_glfw.wl.pointerSurface == window->wl.fallback.bottom.surface)
|
||||||
{
|
{
|
||||||
if (xpos < GLFW_BORDER_SIZE)
|
if (xpos < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
||||||
@@ -403,21 +420,19 @@ static void handleFallbackDecorationButton(_GLFWwindow* window,
|
|||||||
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
|
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
|
||||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, serial, edges);
|
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, serial, edges);
|
||||||
}
|
}
|
||||||
else if (button == BTN_RIGHT)
|
else if (button == GLFW_MOUSE_BUTTON_RIGHT)
|
||||||
{
|
{
|
||||||
if (!window->wl.xdg.toplevel)
|
if (!window->wl.xdg.toplevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->wl.fallback.focus != window->wl.fallback.top.surface)
|
if (_glfw.wl.pointerSurface != window->wl.fallback.top.surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, _glfw.wl.seat, serial,
|
||||||
_glfw.wl.seat, serial,
|
xpos, ypos - GLFW_CAPTION_HEIGHT - GLFW_BORDER_SIZE);
|
||||||
xpos,
|
|
||||||
ypos - GLFW_CAPTION_HEIGHT - GLFW_BORDER_SIZE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1267,14 +1282,16 @@ static void setCursorImage(_GLFWwindow* window,
|
|||||||
wl_surface_commit(surface);
|
wl_surface_commit(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void incrementCursorImage(_GLFWwindow* window)
|
static void incrementCursorImage(void)
|
||||||
{
|
{
|
||||||
_GLFWcursor* cursor;
|
if (!_glfw.wl.pointerSurface)
|
||||||
|
|
||||||
if (!window || !window->wl.hovered)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cursor = window->wl.currentCursor;
|
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface);
|
||||||
|
if (window->wl.surface != _glfw.wl.pointerSurface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_GLFWcursor* cursor = window->cursor;
|
||||||
if (cursor && cursor->wl.cursor)
|
if (cursor && cursor->wl.cursor)
|
||||||
{
|
{
|
||||||
cursor->wl.currentImage += 1;
|
cursor->wl.currentImage += 1;
|
||||||
@@ -1436,7 +1453,7 @@ static void handleEvents(double* timeout)
|
|||||||
uint64_t repeats;
|
uint64_t repeats;
|
||||||
|
|
||||||
if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)
|
if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)
|
||||||
incrementCursorImage(_glfw.wl.pointerFocus);
|
incrementCursorImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fds[LIBDECOR_FD].revents & POLLIN)
|
if (fds[LIBDECOR_FD].revents & POLLIN)
|
||||||
@@ -1513,6 +1530,70 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void processPointerEnterSurface(struct wl_surface* surface)
|
||||||
|
{
|
||||||
|
_glfw.wl.pointerSurface = surface;
|
||||||
|
|
||||||
|
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface);
|
||||||
|
if (window->wl.surface == _glfw.wl.pointerSurface)
|
||||||
|
{
|
||||||
|
_glfwSetCursorWayland(window, window->cursor);
|
||||||
|
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void processPointerLeaveSurface(struct wl_surface* surface)
|
||||||
|
{
|
||||||
|
_glfw.wl.pointerSurface = NULL;
|
||||||
|
|
||||||
|
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||||
|
if (window->wl.surface == surface)
|
||||||
|
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (window->wl.fallback.decorations)
|
||||||
|
window->wl.fallback.cursorName = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void processPointerMotion(double xpos, double ypos)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface);
|
||||||
|
if (window->wl.surface == _glfw.wl.pointerSurface)
|
||||||
|
{
|
||||||
|
if (window->cursorMode != GLFW_CURSOR_DISABLED)
|
||||||
|
{
|
||||||
|
window->wl.cursorPosX = xpos;
|
||||||
|
window->wl.cursorPosY = ypos;
|
||||||
|
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (window->wl.fallback.decorations)
|
||||||
|
updateFallbackDecorationCursor(window, xpos, ypos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void processPointerButton(int button, int action)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface);
|
||||||
|
if (window->wl.surface == _glfw.wl.pointerSurface)
|
||||||
|
_glfwInputMouseClick(window, button, action, _glfw.wl.xkb.modifiers);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (window->wl.fallback.decorations)
|
||||||
|
handleFallbackDecorationButton(window, button, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void processPointerScroll(double xoffset, double yoffset)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface);
|
||||||
|
if (window->wl.surface == _glfw.wl.pointerSurface)
|
||||||
|
_glfwInputScroll(window, xoffset, yoffset);
|
||||||
|
}
|
||||||
|
|
||||||
static void pointerHandleEnter(void* userData,
|
static void pointerHandleEnter(void* userData,
|
||||||
struct wl_pointer* pointer,
|
struct wl_pointer* pointer,
|
||||||
uint32_t serial,
|
uint32_t serial,
|
||||||
@@ -1527,32 +1608,23 @@ static void pointerHandleEnter(void* userData,
|
|||||||
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerEnterSerial = serial;
|
_glfw.wl.pointerEnterSerial = serial;
|
||||||
_glfw.wl.pointerFocus = window;
|
|
||||||
|
|
||||||
if (surface == window->wl.surface)
|
const double xpos = wl_fixed_to_double(sx);
|
||||||
{
|
const double ypos = wl_fixed_to_double(sy);
|
||||||
window->wl.hovered = GLFW_TRUE;
|
|
||||||
_glfwSetCursorWayland(window, window->wl.currentCursor);
|
|
||||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
|
||||||
|
|
||||||
if (window->cursorMode != GLFW_CURSOR_DISABLED)
|
if (wl_pointer_get_version(pointer) >= WL_POINTER_FRAME_SINCE_VERSION)
|
||||||
{
|
{
|
||||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
_glfw.wl.pending.events |= (GLFW_PENDING_SURFACE | GLFW_PENDING_MOTION);
|
||||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
_glfw.wl.pending.pointerSurface = surface;
|
||||||
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
|
_glfw.wl.pending.pointerX = xpos;
|
||||||
}
|
_glfw.wl.pending.pointerY = ypos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (window->wl.fallback.decorations)
|
processPointerEnterSurface(surface);
|
||||||
{
|
processPointerMotion(xpos, ypos);
|
||||||
window->wl.fallback.focus = surface;
|
|
||||||
updateFallbackDecorationCursor(window, sx, sy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1567,26 +1639,15 @@ static void pointerHandleLeave(void* userData,
|
|||||||
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
|
||||||
if (!window)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerFocus = NULL;
|
|
||||||
|
|
||||||
if (window->wl.hovered)
|
if (wl_pointer_get_version(pointer) >= WL_POINTER_FRAME_SINCE_VERSION)
|
||||||
{
|
{
|
||||||
window->wl.hovered = GLFW_FALSE;
|
_glfw.wl.pending.events |= GLFW_PENDING_SURFACE;
|
||||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
_glfw.wl.pending.pointerSurface = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
processPointerLeaveSurface(surface);
|
||||||
if (window->wl.fallback.decorations)
|
|
||||||
{
|
|
||||||
window->wl.fallback.focus = NULL;
|
|
||||||
window->wl.fallback.cursorName = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointerHandleMotion(void* userData,
|
static void pointerHandleMotion(void* userData,
|
||||||
@@ -1595,51 +1656,52 @@ static void pointerHandleMotion(void* userData,
|
|||||||
wl_fixed_t sx,
|
wl_fixed_t sx,
|
||||||
wl_fixed_t sy)
|
wl_fixed_t sy)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
if (!_glfw.wl.pointerSurface)
|
||||||
if (!window)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
const double xpos = wl_fixed_to_double(sx);
|
||||||
return;
|
const double ypos = wl_fixed_to_double(sy);
|
||||||
|
|
||||||
if (window->wl.hovered)
|
if (wl_pointer_get_version(pointer) >= WL_POINTER_FRAME_SINCE_VERSION)
|
||||||
{
|
{
|
||||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
_glfw.wl.pending.events |= GLFW_PENDING_MOTION;
|
||||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
_glfw.wl.pending.pointerX = xpos;
|
||||||
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
|
_glfw.wl.pending.pointerY = ypos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
processPointerMotion(xpos, ypos);
|
||||||
if (window->wl.fallback.decorations)
|
|
||||||
updateFallbackDecorationCursor(window, sx, sy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointerHandleButton(void* userData,
|
static void pointerHandleButton(void* userData,
|
||||||
struct wl_pointer* pointer,
|
struct wl_pointer* pointer,
|
||||||
uint32_t serial,
|
uint32_t serial,
|
||||||
uint32_t time,
|
uint32_t time,
|
||||||
uint32_t button,
|
uint32_t buttonID,
|
||||||
uint32_t state)
|
uint32_t state)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
if (!_glfw.wl.pointerSurface)
|
||||||
if (!window)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->wl.hovered)
|
|
||||||
{
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
|
|
||||||
_glfwInputMouseClick(window,
|
const int button = buttonID - BTN_LEFT;
|
||||||
button - BTN_LEFT,
|
const int action = (state == WL_POINTER_BUTTON_STATE_PRESSED);
|
||||||
state == WL_POINTER_BUTTON_STATE_PRESSED,
|
|
||||||
_glfw.wl.xkb.modifiers);
|
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface);
|
||||||
|
if (window->wl.fallback.decorations)
|
||||||
|
{
|
||||||
|
if (action == GLFW_PRESS)
|
||||||
|
window->wl.fallback.buttonPressSerial = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wl_pointer_get_version(pointer) >= WL_POINTER_FRAME_SINCE_VERSION)
|
||||||
|
{
|
||||||
|
_glfw.wl.pending.events |= GLFW_PENDING_BUTTON;
|
||||||
|
_glfw.wl.pending.button = button;
|
||||||
|
_glfw.wl.pending.action = action;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
processPointerButton(button, action);
|
||||||
if (window->wl.fallback.decorations)
|
|
||||||
handleFallbackDecorationButton(window, serial, button);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointerHandleAxis(void* userData,
|
static void pointerHandleAxis(void* userData,
|
||||||
@@ -1648,20 +1710,90 @@ static void pointerHandleAxis(void* userData,
|
|||||||
uint32_t axis,
|
uint32_t axis,
|
||||||
wl_fixed_t value)
|
wl_fixed_t value)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
if (!_glfw.wl.pointerSurface)
|
||||||
if (!window)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->wl.hovered)
|
if (wl_pointer_get_version(pointer) >= WL_POINTER_FRAME_SINCE_VERSION)
|
||||||
|
{
|
||||||
|
_glfw.wl.pending.events |= GLFW_PENDING_SCROLL;
|
||||||
|
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
||||||
|
_glfw.wl.pending.scrollX = -wl_fixed_to_double(value) / 10.0;
|
||||||
|
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||||
|
_glfw.wl.pending.scrollY = -wl_fixed_to_double(value) / 10.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// NOTE: 10 units of motion per mouse wheel step seems to be a common ratio
|
// NOTE: 10 units of motion per mouse wheel step seems to be a common ratio
|
||||||
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
||||||
_glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0);
|
processPointerScroll(-wl_fixed_to_double(value) / 10.0, 0.0);
|
||||||
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||||
_glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0);
|
processPointerScroll(0.0, -wl_fixed_to_double(value) / 10.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pointerHandleFrame(void* userData, struct wl_pointer* pointer)
|
||||||
|
{
|
||||||
|
if (_glfw.wl.pending.events & GLFW_PENDING_SURFACE)
|
||||||
|
{
|
||||||
|
if (_glfw.wl.pointerSurface)
|
||||||
|
processPointerLeaveSurface(_glfw.wl.pointerSurface);
|
||||||
|
|
||||||
|
if (_glfw.wl.pending.pointerSurface)
|
||||||
|
processPointerEnterSurface(_glfw.wl.pending.pointerSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfw.wl.pointerSurface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_glfw.wl.pending.events & GLFW_PENDING_MOTION)
|
||||||
|
processPointerMotion(_glfw.wl.pending.pointerX, _glfw.wl.pending.pointerY);
|
||||||
|
|
||||||
|
if (_glfw.wl.pending.events & GLFW_PENDING_BUTTON)
|
||||||
|
processPointerButton(_glfw.wl.pending.button, _glfw.wl.pending.action);
|
||||||
|
|
||||||
|
if (_glfw.wl.pending.events & GLFW_PENDING_DISCRETE)
|
||||||
|
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);
|
||||||
|
|
||||||
|
memset(&_glfw.wl.pending, 0, sizeof(_glfw.wl.pending));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointerHandleAxisSource(void* userData,
|
||||||
|
struct wl_pointer* pointer,
|
||||||
|
uint32_t axisSource)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointerHandleAxisStop(void* userData,
|
||||||
|
struct wl_pointer* pointer,
|
||||||
|
uint32_t time,
|
||||||
|
uint32_t axis)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointerHandleAxisDiscrete(void* userData,
|
||||||
|
struct wl_pointer* pointer,
|
||||||
|
uint32_t axis,
|
||||||
|
int32_t discrete)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
@@ -1669,6 +1801,11 @@ static const struct wl_pointer_listener pointerListener =
|
|||||||
pointerHandleMotion,
|
pointerHandleMotion,
|
||||||
pointerHandleButton,
|
pointerHandleButton,
|
||||||
pointerHandleAxis,
|
pointerHandleAxis,
|
||||||
|
pointerHandleFrame,
|
||||||
|
pointerHandleAxisSource,
|
||||||
|
pointerHandleAxisStop,
|
||||||
|
pointerHandleAxisDiscrete,
|
||||||
|
pointerHandleAxisValue120
|
||||||
};
|
};
|
||||||
|
|
||||||
static void keyboardHandleKeymap(void* userData,
|
static void keyboardHandleKeymap(void* userData,
|
||||||
@@ -1691,8 +1828,9 @@ static void keyboardHandleKeymap(void* userData,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
mapStr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
if (mapStr == MAP_FAILED) {
|
if (mapStr == MAP_FAILED)
|
||||||
|
{
|
||||||
close(fd);
|
close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1700,7 +1838,7 @@ static void keyboardHandleKeymap(void* userData,
|
|||||||
keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context,
|
keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context,
|
||||||
mapStr,
|
mapStr,
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||||
0);
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
munmap(mapStr, size);
|
munmap(mapStr, size);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@@ -1838,7 +1976,9 @@ static void keyboardHandleKey(void* userData,
|
|||||||
timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;
|
timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;
|
||||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
}
|
}
|
||||||
} else if (scancode == _glfw.wl.keyRepeatScancode) {
|
}
|
||||||
|
else if (scancode == _glfw.wl.keyRepeatScancode)
|
||||||
|
{
|
||||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1929,7 +2069,11 @@ static void seatHandleCapabilities(void* userData,
|
|||||||
}
|
}
|
||||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
|
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
|
||||||
{
|
{
|
||||||
|
if (wl_pointer_get_version(_glfw.wl.pointer) >= WL_POINTER_RELEASE_SINCE_VERSION)
|
||||||
|
wl_pointer_release(_glfw.wl.pointer);
|
||||||
|
else
|
||||||
wl_pointer_destroy(_glfw.wl.pointer);
|
wl_pointer_destroy(_glfw.wl.pointer);
|
||||||
|
|
||||||
_glfw.wl.pointer = NULL;
|
_glfw.wl.pointer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1937,10 +2081,21 @@ static void seatHandleCapabilities(void* userData,
|
|||||||
{
|
{
|
||||||
_glfw.wl.keyboard = wl_seat_get_keyboard(seat);
|
_glfw.wl.keyboard = wl_seat_get_keyboard(seat);
|
||||||
wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);
|
wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);
|
||||||
|
|
||||||
|
if (wl_keyboard_get_version(_glfw.wl.keyboard) <
|
||||||
|
WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
|
||||||
|
{
|
||||||
|
_glfw.wl.keyRepeatRate = 4;
|
||||||
|
_glfw.wl.keyRepeatDelay = 500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
|
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
|
||||||
{
|
{
|
||||||
|
if (wl_keyboard_get_version(_glfw.wl.keyboard) >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
|
||||||
|
wl_keyboard_release(_glfw.wl.keyboard);
|
||||||
|
else
|
||||||
wl_keyboard_destroy(_glfw.wl.keyboard);
|
wl_keyboard_destroy(_glfw.wl.keyboard);
|
||||||
|
|
||||||
_glfw.wl.keyboard = NULL;
|
_glfw.wl.keyboard = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2151,6 +2306,18 @@ static const struct xdg_activation_token_v1_listener xdgActivationListener =
|
|||||||
xdgActivationHandleDone
|
xdgActivationHandleDone
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void callbackHandleFrame(void* userData, struct wl_callback* callback, uint32_t data)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = userData;
|
||||||
|
wl_callback_destroy(callback);
|
||||||
|
window->wl.egl.callback = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_callback_listener frameCallbackListener =
|
||||||
|
{
|
||||||
|
callbackHandleFrame
|
||||||
|
};
|
||||||
|
|
||||||
void _glfwAddSeatListenerWayland(struct wl_seat* seat)
|
void _glfwAddSeatListenerWayland(struct wl_seat* seat)
|
||||||
{
|
{
|
||||||
wl_seat_add_listener(seat, &seatListener, NULL);
|
wl_seat_add_listener(seat, &seatListener, NULL);
|
||||||
@@ -2161,6 +2328,42 @@ void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device)
|
|||||||
wl_data_device_add_listener(device, &dataDeviceListener, NULL);
|
wl_data_device_add_listener(device, &dataDeviceListener, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwWaitForEGLFrameWayland(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
double timeout = 0.02;
|
||||||
|
|
||||||
|
while (window->wl.egl.callback)
|
||||||
|
{
|
||||||
|
if (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);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
return window->wl.visible;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@@ -2189,6 +2392,27 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window->wl.egl.queue = wl_display_create_queue(_glfw.wl.display);
|
||||||
|
if (!window->wl.egl.queue)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create EGL frame queue");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->wl.egl.wrapper = wl_proxy_create_wrapper(window->wl.surface);
|
||||||
|
if (!window->wl.egl.wrapper)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create surface wrapper");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_proxy_set_queue((struct wl_proxy*) window->wl.egl.wrapper,
|
||||||
|
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))
|
||||||
@@ -2220,8 +2444,8 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
|
|||||||
|
|
||||||
void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window == _glfw.wl.pointerFocus)
|
if (window->wl.surface == _glfw.wl.pointerSurface)
|
||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerSurface = NULL;
|
||||||
|
|
||||||
if (window == _glfw.wl.keyboardFocus)
|
if (window == _glfw.wl.keyboardFocus)
|
||||||
{
|
{
|
||||||
@@ -2260,6 +2484,15 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
|||||||
if (window->wl.fallback.buffer)
|
if (window->wl.fallback.buffer)
|
||||||
wl_buffer_destroy(window->wl.fallback.buffer);
|
wl_buffer_destroy(window->wl.fallback.buffer);
|
||||||
|
|
||||||
|
if (window->wl.egl.callback)
|
||||||
|
wl_callback_destroy(window->wl.egl.callback);
|
||||||
|
|
||||||
|
if (window->wl.egl.wrapper)
|
||||||
|
wl_proxy_wrapper_destroy(window->wl.egl.wrapper);
|
||||||
|
|
||||||
|
if (window->wl.egl.queue)
|
||||||
|
wl_event_queue_destroy(window->wl.egl.queue);
|
||||||
|
|
||||||
if (window->wl.egl.window)
|
if (window->wl.egl.window)
|
||||||
wl_egl_window_destroy(window->wl.egl.window);
|
wl_egl_window_destroy(window->wl.egl.window);
|
||||||
|
|
||||||
@@ -2493,6 +2726,8 @@ 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2597,7 +2832,7 @@ GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window)
|
|||||||
|
|
||||||
GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window)
|
GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return window->wl.hovered;
|
return window->wl.surface == _glfw.wl.pointerSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window)
|
GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window)
|
||||||
@@ -2707,7 +2942,9 @@ void _glfwWaitEventsTimeoutWayland(double timeout)
|
|||||||
|
|
||||||
void _glfwPostEmptyEventWayland(void)
|
void _glfwPostEmptyEventWayland(void)
|
||||||
{
|
{
|
||||||
wl_display_sync(_glfw.wl.display);
|
struct wl_callback* callback = wl_display_sync(_glfw.wl.display);
|
||||||
|
wl_callback_add_listener(callback, &noopCallbackListener, NULL);
|
||||||
|
|
||||||
flushDisplay();
|
flushDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2727,7 +2964,7 @@ void _glfwSetCursorPosWayland(_GLFWwindow* window, double x, double y)
|
|||||||
|
|
||||||
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
|
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
|
||||||
{
|
{
|
||||||
_glfwSetCursorWayland(window, window->wl.currentCursor);
|
_glfwSetCursorWayland(window, window->cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwGetScancodeNameWayland(int scancode)
|
const char* _glfwGetScancodeNameWayland(int scancode)
|
||||||
@@ -2974,10 +3211,16 @@ static void lockPointer(_GLFWwindow* window)
|
|||||||
if (!_glfw.wl.relativePointerManager)
|
if (!_glfw.wl.relativePointerManager)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
"Wayland: The compositor does not support pointer locking");
|
"Wayland: The compositor does not support relative pointer motion");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_glfw.wl.pointerConstraints)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
|
"Wayland: The compositor does not support locking the pointer");
|
||||||
|
}
|
||||||
|
|
||||||
window->wl.relativePointer =
|
window->wl.relativePointer =
|
||||||
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||||
_glfw.wl.relativePointerManager,
|
_glfw.wl.relativePointerManager,
|
||||||
@@ -3025,6 +3268,12 @@ static const struct zwp_confined_pointer_v1_listener confinedPointerListener =
|
|||||||
|
|
||||||
static void confinePointer(_GLFWwindow* window)
|
static void confinePointer(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (!_glfw.wl.pointerConstraints)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
|
"Wayland: The compositor does not support confining the pointer");
|
||||||
|
}
|
||||||
|
|
||||||
window->wl.confinedPointer =
|
window->wl.confinedPointer =
|
||||||
zwp_pointer_constraints_v1_confine_pointer(
|
zwp_pointer_constraints_v1_confine_pointer(
|
||||||
_glfw.wl.pointerConstraints,
|
_glfw.wl.pointerConstraints,
|
||||||
@@ -3049,11 +3298,7 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
if (!_glfw.wl.pointer)
|
if (!_glfw.wl.pointer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window->wl.currentCursor = cursor;
|
if (window->wl.surface != _glfw.wl.pointerSurface)
|
||||||
|
|
||||||
// If we're not in the correct window just save the cursor
|
|
||||||
// the next time the pointer enters the window the cursor will change
|
|
||||||
if (!window->wl.hovered)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update pointer lock to match cursor mode
|
// Update pointer lock to match cursor mode
|
||||||
|
|||||||
+10
-46
@@ -1592,65 +1592,29 @@ void _glfwTerminateX11(void)
|
|||||||
_glfw.x11.display = NULL;
|
_glfw.x11.display = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.x11.x11xcb.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.x11.x11xcb.handle);
|
|
||||||
_glfw.x11.x11xcb.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.xcursor.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.x11.xcursor.handle);
|
|
||||||
_glfw.x11.xcursor.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.randr.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.x11.randr.handle);
|
|
||||||
_glfw.x11.randr.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.xinerama.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.x11.xinerama.handle);
|
|
||||||
_glfw.x11.xinerama.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.xrender.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.x11.xrender.handle);
|
|
||||||
_glfw.x11.xrender.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.vidmode.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.x11.vidmode.handle);
|
|
||||||
_glfw.x11.vidmode.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.xi.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.x11.xi.handle);
|
|
||||||
_glfw.x11.xi.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwTerminateOSMesa();
|
_glfwTerminateOSMesa();
|
||||||
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
||||||
// cleanup callbacks that get called by that function
|
// cleanup callbacks that get called by that function
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
_glfwTerminateGLX();
|
_glfwTerminateGLX();
|
||||||
|
|
||||||
if (_glfw.x11.xlib.handle)
|
_glfwPlatformFreeModule(_glfw.x11.x11xcb.handle);
|
||||||
{
|
_glfwPlatformFreeModule(_glfw.x11.xcursor.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.x11.randr.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.x11.xinerama.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.x11.xrender.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.x11.xshape.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.x11.vidmode.handle);
|
||||||
|
_glfwPlatformFreeModule(_glfw.x11.xi.handle);
|
||||||
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
|
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
|
||||||
_glfw.x11.xlib.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.emptyEventPipe[0] || _glfw.x11.emptyEventPipe[1])
|
if (_glfw.x11.emptyEventPipe[0] || _glfw.x11.emptyEventPipe[1])
|
||||||
{
|
{
|
||||||
close(_glfw.x11.emptyEventPipe[0]);
|
close(_glfw.x11.emptyEventPipe[0]);
|
||||||
close(_glfw.x11.emptyEventPipe[1]);
|
close(_glfw.x11.emptyEventPipe[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&_glfw.x11, 0, sizeof(_glfw.x11));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_X11
|
#endif // _GLFW_X11
|
||||||
|
|||||||
@@ -151,6 +151,12 @@ void _glfwPollMonitorsX11(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||||
|
if (!ci)
|
||||||
|
{
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||||
{
|
{
|
||||||
widthMM = oi->mm_height;
|
widthMM = oi->mm_height;
|
||||||
|
|||||||
+15
-15
@@ -452,9 +452,6 @@ 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;
|
||||||
@@ -463,6 +460,7 @@ 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
|
||||||
//
|
//
|
||||||
@@ -505,18 +503,18 @@ typedef struct _GLFWlibraryGLX
|
|||||||
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
|
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
|
||||||
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
|
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
|
||||||
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||||
GLFWbool SGI_swap_control;
|
bool SGI_swap_control;
|
||||||
GLFWbool EXT_swap_control;
|
bool EXT_swap_control;
|
||||||
GLFWbool MESA_swap_control;
|
bool MESA_swap_control;
|
||||||
GLFWbool ARB_multisample;
|
bool ARB_multisample;
|
||||||
GLFWbool ARB_framebuffer_sRGB;
|
bool ARB_framebuffer_sRGB;
|
||||||
GLFWbool EXT_framebuffer_sRGB;
|
bool EXT_framebuffer_sRGB;
|
||||||
GLFWbool ARB_create_context;
|
bool ARB_create_context;
|
||||||
GLFWbool ARB_create_context_profile;
|
bool ARB_create_context_profile;
|
||||||
GLFWbool ARB_create_context_robustness;
|
bool ARB_create_context_robustness;
|
||||||
GLFWbool EXT_create_context_es2_profile;
|
bool EXT_create_context_es2_profile;
|
||||||
GLFWbool ARB_create_context_no_error;
|
bool ARB_create_context_no_error;
|
||||||
GLFWbool ARB_context_flush_control;
|
bool ARB_context_flush_control;
|
||||||
} _GLFWlibraryGLX;
|
} _GLFWlibraryGLX;
|
||||||
|
|
||||||
// X11-specific per-window data
|
// X11-specific per-window data
|
||||||
@@ -985,6 +983,8 @@ 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);
|
||||||
|
|||||||
+49
-23
@@ -576,6 +576,10 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
height *= _glfw.x11.contentScaleY;
|
height *= _glfw.x11.contentScaleY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The dimensions must be nonzero, or a BadValue error results.
|
||||||
|
width = _glfw_max(1, width);
|
||||||
|
height = _glfw_max(1, height);
|
||||||
|
|
||||||
int xpos = 0, ypos = 0;
|
int xpos = 0, ypos = 0;
|
||||||
|
|
||||||
if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION)
|
if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION)
|
||||||
@@ -1304,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 = _glfwKeySym2Unicode(keysym);
|
const uint32_t codepoint = _glfwKeySym2UnicodeX11(keysym);
|
||||||
if (codepoint != GLFW_INVALID_CODEPOINT)
|
if (codepoint != GLFW_INVALID_CODEPOINT)
|
||||||
_glfwInputChar(window, codepoint, mods, plain);
|
_glfwInputChar(window, codepoint, mods, plain);
|
||||||
}
|
}
|
||||||
@@ -2203,6 +2207,10 @@ void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height)
|
|||||||
|
|
||||||
void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height)
|
void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
|
// The dimensions must be nonzero, or a BadValue error results
|
||||||
|
width = _glfw_max(1, width);
|
||||||
|
height = _glfw_max(1, height);
|
||||||
|
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
{
|
{
|
||||||
if (window->monitor->window == window)
|
if (window->monitor->window == window)
|
||||||
@@ -2430,6 +2438,38 @@ void _glfwShowWindowX11(_GLFWwindow* window)
|
|||||||
if (_glfwWindowVisibleX11(window))
|
if (_glfwWindowVisibleX11(window))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (window->floating && _glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE)
|
||||||
|
{
|
||||||
|
Atom* states = NULL;
|
||||||
|
const unsigned long count =
|
||||||
|
_glfwGetWindowPropertyX11(window->x11.handle,
|
||||||
|
_glfw.x11.NET_WM_STATE,
|
||||||
|
XA_ATOM, (unsigned char**) &states);
|
||||||
|
|
||||||
|
// NOTE: We don't check for failure as this property may not exist yet
|
||||||
|
// and that's fine (and we'll create it implicitly with append)
|
||||||
|
|
||||||
|
unsigned long i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == count)
|
||||||
|
{
|
||||||
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
|
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||||
|
PropModeAppend,
|
||||||
|
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (states)
|
||||||
|
XFree(states);
|
||||||
|
}
|
||||||
|
|
||||||
XMapWindow(_glfw.x11.display, window->x11.handle);
|
XMapWindow(_glfw.x11.display, window->x11.handle);
|
||||||
waitForVisibilityNotify(window);
|
waitForVisibilityNotify(window);
|
||||||
}
|
}
|
||||||
@@ -2659,6 +2699,10 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// NOTE: _NET_WM_STATE_ABOVE is added when the window is shown
|
||||||
|
if (enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
Atom* states = NULL;
|
Atom* states = NULL;
|
||||||
const unsigned long count =
|
const unsigned long count =
|
||||||
_glfwGetWindowPropertyX11(window->x11.handle,
|
_glfwGetWindowPropertyX11(window->x11.handle,
|
||||||
@@ -2669,8 +2713,6 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
// NOTE: We don't check for failure as this property may not exist yet
|
// NOTE: We don't check for failure as this property may not exist yet
|
||||||
// and that's fine (and we'll create it implicitly with append)
|
// and that's fine (and we'll create it implicitly with append)
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
@@ -2679,28 +2721,12 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == count)
|
if (i < count)
|
||||||
{
|
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
|
||||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
|
||||||
PropModeAppend,
|
|
||||||
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (states)
|
|
||||||
{
|
|
||||||
for (unsigned long i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
|
||||||
{
|
{
|
||||||
states[i] = states[count - 1];
|
states[i] = states[count - 1];
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||||
PropModeReplace, (unsigned char*) states, count - 1);
|
PropModeReplace, (unsigned char*) states, count - 1);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (states)
|
if (states)
|
||||||
@@ -2918,7 +2944,7 @@ const char* _glfwGetScancodeNameX11(int scancode)
|
|||||||
if (keysym == NoSymbol)
|
if (keysym == NoSymbol)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
const uint32_t codepoint = _glfwKeySym2UnicodeX11(keysym);
|
||||||
if (codepoint == GLFW_INVALID_CODEPOINT)
|
if (codepoint == GLFW_INVALID_CODEPOINT)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -3318,8 +3344,6 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
|
|||||||
|
|
||||||
GLFWAPI void glfwSetX11SelectionString(const char* string)
|
GLFWAPI void glfwSetX11SelectionString(const char* string)
|
||||||
{
|
{
|
||||||
assert(string != NULL);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
|
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
|
||||||
@@ -3328,6 +3352,8 @@ GLFWAPI void glfwSetX11SelectionString(const char* string)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(string != NULL);
|
||||||
|
|
||||||
_glfw_free(_glfw.x11.primarySelectionString);
|
_glfw_free(_glfw.x11.primarySelectionString);
|
||||||
_glfw.x11.primarySelectionString = _glfw_strdup(string);
|
_glfw.x11.primarySelectionString = _glfw_strdup(string);
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
|
#if defined(_GLFW_X11)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 _glfwKeySym2Unicode(unsigned int keysym)
|
uint32_t _glfwKeySym2UnicodeX11(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 _glfwKeySym2Unicode(unsigned int keysym)
|
|||||||
return GLFW_INVALID_CODEPOINT;
|
return GLFW_INVALID_CODEPOINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WAYLAND or _GLFW_X11
|
#endif // _GLFW_X11
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
+73
-28
@@ -23,7 +23,10 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
//
|
//
|
||||||
// This test is intended to verify that posting of empty events works
|
// This test is intended to verify that the 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.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
@@ -37,25 +40,53 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
static volatile int running = GLFW_TRUE;
|
struct State
|
||||||
|
{
|
||||||
|
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 timespec time;
|
struct State* const state = data;
|
||||||
|
|
||||||
while (running)
|
srand((unsigned int) time(NULL));
|
||||||
|
|
||||||
|
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;
|
||||||
@@ -64,28 +95,38 @@ 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, GLFW_TRUE);
|
glfwSetWindowShouldClose(window, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float nrand(void)
|
static void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
return (float) rand() / (float) RAND_MAX;
|
struct State* const state = glfwGetWindowUserPointer(window);
|
||||||
|
|
||||||
|
mtx_lock(&state->lock);
|
||||||
|
state->width = width;
|
||||||
|
state->height = height;
|
||||||
|
state->needs_update = true;
|
||||||
|
mtx_unlock(&state->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int result;
|
struct State state = { .running = true };
|
||||||
thrd_t thread;
|
|
||||||
GLFWwindow* window;
|
|
||||||
|
|
||||||
srand((unsigned int) time(NULL));
|
if (mtx_init(&state.lock, mtx_plain) != thrd_success)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_color(&state);
|
||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@@ -95,8 +136,13 @@ 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);
|
||||||
|
|
||||||
if (thrd_create(&thread, thread_main, NULL) != thrd_success)
|
thrd_t color_thread;
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
@@ -104,28 +150,27 @@ int main(void)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (running)
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
int width, height;
|
if (state.needs_update)
|
||||||
float r = nrand(), g = nrand(), b = nrand();
|
{
|
||||||
float l = (float) sqrt(r * r + g * g + b * b);
|
mtx_lock(&state.lock);
|
||||||
|
glViewport(0, 0, state.width, state.height);
|
||||||
|
glClearColor(state.r, state.g, state.b, 1.f);
|
||||||
|
state.needs_update = false;
|
||||||
|
mtx_unlock(&state.lock);
|
||||||
|
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
|
||||||
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
glClearColor(r / l, g / l, b / l, 1.f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
}
|
||||||
|
|
||||||
glfwWaitEvents();
|
glfwWaitEvents();
|
||||||
|
|
||||||
if (glfwWindowShouldClose(window))
|
|
||||||
running = GLFW_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwHideWindow(window);
|
glfwHideWindow(window);
|
||||||
thrd_join(thread, &result);
|
state.running = false;
|
||||||
glfwDestroyWindow(window);
|
thrd_join(color_thread, NULL);
|
||||||
|
mtx_destroy(&state.lock);
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
|||||||
@@ -146,6 +146,10 @@ int main(void)
|
|||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
thrd_join(threads[i].id, &result);
|
thrd_join(threads[i].id, &result);
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
glfwDestroyWindow(threads[i].window);
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-1
@@ -36,6 +36,14 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
static bool needs_update;
|
||||||
|
|
||||||
|
static void window_close_callback(GLFWwindow* window)
|
||||||
|
{
|
||||||
|
needs_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
static void error_callback(int error, const char* description)
|
static void error_callback(int error, const char* description)
|
||||||
{
|
{
|
||||||
@@ -45,7 +53,15 @@ static void error_callback(int error, const char* description)
|
|||||||
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, GLFW_TRUE);
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||||
|
needs_update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
|
{
|
||||||
|
needs_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float nrand(void)
|
static float nrand(void)
|
||||||
@@ -72,8 +88,11 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
|
glfwSwapInterval(0);
|
||||||
gladLoadGL(glfwGetProcAddress);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
|
glfwSetWindowCloseCallback(window, window_close_callback);
|
||||||
glfwSetKeyCallback(window, key_callback);
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
@@ -87,8 +106,18 @@ int main(void)
|
|||||||
glClearColor(r / l, g / l, b / l, 1.f);
|
glClearColor(r / l, g / l, b / l, 1.f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
needs_update = false;
|
||||||
|
|
||||||
glfwWaitEventsTimeout(1.0);
|
const double start = glfwGetTime();
|
||||||
|
|
||||||
|
while (!needs_update)
|
||||||
|
{
|
||||||
|
const double elapsed = glfwGetTime() - start;
|
||||||
|
if (elapsed >= 1.0)
|
||||||
|
needs_update = true;
|
||||||
|
else
|
||||||
|
glfwWaitEventsTimeout(1.0 - elapsed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
|
|||||||
Reference in New Issue
Block a user