mirror of
https://github.com/glfw/glfw.git
synced 2024-12-01 22:37:12 +00:00
Merge branch 'master' into merge-request-egl-config
This commit is contained in:
commit
55d398da97
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@ -73,8 +73,8 @@ jobs:
|
|||||||
- name: Build shared library
|
- name: Build shared library
|
||||||
run: cmake --build build-shared --parallel
|
run: cmake --build build-shared --parallel
|
||||||
|
|
||||||
build-windows-win32-vs2019:
|
build-windows-win32-vs2022:
|
||||||
name: Win32 (Windows, VS2019)
|
name: Win32 (Windows, VS2022)
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
env:
|
env:
|
||||||
CFLAGS: /WX
|
CFLAGS: /WX
|
||||||
@ -82,12 +82,12 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Configure static library
|
- name: Configure static library
|
||||||
run: cmake -S . -B build-static -G "Visual Studio 16 2019"
|
run: cmake -S . -B build-static -G "Visual Studio 17 2022"
|
||||||
- name: Build static library
|
- name: Build static library
|
||||||
run: cmake --build build-static --parallel
|
run: cmake --build build-static --parallel
|
||||||
|
|
||||||
- name: Configure shared library
|
- name: Configure shared library
|
||||||
run: cmake -S . -B build-shared -G "Visual Studio 16 2019" -D BUILD_SHARED_LIBS=ON
|
run: cmake -S . -B build-shared -G "Visual Studio 17 2022" -D BUILD_SHARED_LIBS=ON
|
||||||
- name: Build shared library
|
- name: Build shared library
|
||||||
run: cmake --build build-shared --parallel
|
run: cmake --build build-shared --parallel
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ video tutorials.
|
|||||||
- Matt Arsenault
|
- Matt Arsenault
|
||||||
- ashishgamedev
|
- ashishgamedev
|
||||||
- David Avedissian
|
- David Avedissian
|
||||||
|
- Luca Bacci
|
||||||
- Keith Bauer
|
- Keith Bauer
|
||||||
- John Bartholomew
|
- John Bartholomew
|
||||||
- Coşku Baş
|
- Coşku Baş
|
||||||
@ -29,6 +30,7 @@ video tutorials.
|
|||||||
- David Carlier
|
- David Carlier
|
||||||
- Arturo Castro
|
- Arturo Castro
|
||||||
- Chi-kwan Chan
|
- Chi-kwan Chan
|
||||||
|
- TheChocolateOre
|
||||||
- Joseph Chua
|
- Joseph Chua
|
||||||
- Ian Clarkson
|
- Ian Clarkson
|
||||||
- Michał Cichoń
|
- Michał Cichoń
|
||||||
@ -68,6 +70,7 @@ video tutorials.
|
|||||||
- Ryan C. Gordon
|
- Ryan C. Gordon
|
||||||
- Stephen Gowen
|
- Stephen Gowen
|
||||||
- Kovid Goyal
|
- Kovid Goyal
|
||||||
|
- Kevin Grandemange
|
||||||
- Eloi Marín Gratacós
|
- Eloi Marín Gratacós
|
||||||
- Stefan Gustavson
|
- Stefan Gustavson
|
||||||
- Andrew Gutekanst
|
- Andrew Gutekanst
|
||||||
@ -81,10 +84,14 @@ video tutorials.
|
|||||||
- Paul Holden
|
- Paul Holden
|
||||||
- Warren Hu
|
- Warren Hu
|
||||||
- Charles Huber
|
- Charles Huber
|
||||||
|
- Brent Huisman
|
||||||
|
- illustris
|
||||||
- InKryption
|
- InKryption
|
||||||
- IntellectualKitty
|
- IntellectualKitty
|
||||||
- Aaron Jacobs
|
- Aaron Jacobs
|
||||||
|
- JannikGM
|
||||||
- Erik S. V. Jansson
|
- Erik S. V. Jansson
|
||||||
|
- jjYBdx4IL
|
||||||
- Toni Jovanoski
|
- Toni Jovanoski
|
||||||
- Arseny Kapoulkine
|
- Arseny Kapoulkine
|
||||||
- Cem Karan
|
- Cem Karan
|
||||||
@ -183,13 +190,16 @@ video tutorials.
|
|||||||
- Ali Sherief
|
- Ali Sherief
|
||||||
- Yoshiki Shibukawa
|
- Yoshiki Shibukawa
|
||||||
- Dmitri Shuralyov
|
- Dmitri Shuralyov
|
||||||
|
- Joao da Silva
|
||||||
- Daniel Sieger
|
- Daniel Sieger
|
||||||
- Daniel Skorupski
|
- Daniel Skorupski
|
||||||
|
- Slemmie
|
||||||
- Anthony Smith
|
- Anthony Smith
|
||||||
- Bradley Smith
|
- Bradley Smith
|
||||||
- Cliff Smolinsky
|
- Cliff Smolinsky
|
||||||
- Patrick Snape
|
- Patrick Snape
|
||||||
- Erlend Sogge Heggen
|
- Erlend Sogge Heggen
|
||||||
|
- Olivier Sohn
|
||||||
- Julian Squires
|
- Julian Squires
|
||||||
- Johannes Stein
|
- Johannes Stein
|
||||||
- Pontus Stenetorp
|
- Pontus Stenetorp
|
||||||
@ -202,6 +212,7 @@ video tutorials.
|
|||||||
- Jared Tiala
|
- Jared Tiala
|
||||||
- Sergey Tikhomirov
|
- Sergey Tikhomirov
|
||||||
- Arthur Tombs
|
- Arthur Tombs
|
||||||
|
- TronicLabs
|
||||||
- Ioannis Tsakpinis
|
- Ioannis Tsakpinis
|
||||||
- Samuli Tuomola
|
- Samuli Tuomola
|
||||||
- Matthew Turner
|
- Matthew Turner
|
||||||
|
21
README.md
21
README.md
@ -205,6 +205,16 @@ information on what to include when reporting a bug.
|
|||||||
- [Win32] Bugfix: Content scale queries could fail silently (#1615)
|
- [Win32] Bugfix: Content scale queries could fail silently (#1615)
|
||||||
- [Win32] Bugfix: Content scales could have garbage values if monitor was recently
|
- [Win32] Bugfix: Content scales could have garbage values if monitor was recently
|
||||||
disconnected (#1615)
|
disconnected (#1615)
|
||||||
|
- [Win32] Bugfix: A window created maximized and undecorated would cover the whole
|
||||||
|
monitor (#1806)
|
||||||
|
- [Win32] Bugfix: The default restored window position was lost when creating a maximized
|
||||||
|
window
|
||||||
|
- [Win32] Bugfix: `glfwMaximizeWindow` would make a hidden window visible
|
||||||
|
- [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different
|
||||||
|
scancode than `PrtSc` (#1993)
|
||||||
|
- [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not
|
||||||
|
match event scancode (#1993)
|
||||||
|
- [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395)
|
||||||
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
||||||
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
||||||
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649)
|
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649)
|
||||||
@ -235,6 +245,7 @@ information on what to include when reporting a bug.
|
|||||||
a fraction of a second (#1962)
|
a fraction of a second (#1962)
|
||||||
- [Cocoa] Bugfix: `kIOMasterPortDefault` was deprecated in macOS 12.0 (#1980)
|
- [Cocoa] Bugfix: `kIOMasterPortDefault` was deprecated in macOS 12.0 (#1980)
|
||||||
- [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003)
|
- [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003)
|
||||||
|
- [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791)
|
||||||
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
|
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
|
||||||
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
|
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
|
||||||
(#1462,#1528)
|
(#1462,#1528)
|
||||||
@ -266,6 +277,14 @@ information on what to include when reporting a bug.
|
|||||||
- [X11] Bugfix: Icon pixel format conversion worked only by accident, relying on
|
- [X11] Bugfix: Icon pixel format conversion worked only by accident, relying on
|
||||||
undefined behavior (#1986)
|
undefined behavior (#1986)
|
||||||
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
|
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
|
||||||
|
- [X11] Bugfix: Waiting for events would fail if file descriptor was too large
|
||||||
|
(#2024)
|
||||||
|
- [X11] Bugfix: Joystick events could lead to busy-waiting (#1872)
|
||||||
|
- [X11] Bugfix: `glfwWaitEvents*` did not continue for joystick events
|
||||||
|
- [X11] Bugfix: `glfwPostEmptyEvent` could be ignored due to race condition
|
||||||
|
(#379,#1281,#1285,#2033)
|
||||||
|
- [X11] Bugfix: Dynamic loading on NetBSD failed due to soname differences
|
||||||
|
- [X11] Bugfix: Left shift of int constant relied on undefined behavior (#1951)
|
||||||
- [Wayland] Added dynamic loading of all Wayland libraries
|
- [Wayland] Added dynamic loading of all Wayland libraries
|
||||||
- [Wayland] Added support for key names via xkbcommon
|
- [Wayland] Added support for key names via xkbcommon
|
||||||
- [Wayland] Removed support for `wl_shell` (#1443)
|
- [Wayland] Removed support for `wl_shell` (#1443)
|
||||||
@ -290,6 +309,7 @@ information on what to include when reporting a bug.
|
|||||||
- [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE`
|
- [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE`
|
||||||
- [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN`
|
- [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN`
|
||||||
- [Wayland] Bugfix: Text input did not repeat along with key repeat
|
- [Wayland] Bugfix: Text input did not repeat along with key repeat
|
||||||
|
- [Wayland] Bugfix: `glfwPostEmptyEvent` sometimes had no effect (#1520,#1521)
|
||||||
- [POSIX] Removed use of deprecated function `gettimeofday`
|
- [POSIX] Removed use of deprecated function `gettimeofday`
|
||||||
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
||||||
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
||||||
@ -305,6 +325,7 @@ information on what to include when reporting a bug.
|
|||||||
(#1380)
|
(#1380)
|
||||||
- [EGL] Bugfix: The `GLFW_DOUBLEBUFFER` context attribute was ignored (#1843)
|
- [EGL] Bugfix: The `GLFW_DOUBLEBUFFER` context attribute was ignored (#1843)
|
||||||
- [EGL] Made it possible to query the `EGLConfig` that was chosen to create a given window via `glfwGetEGLConfig`
|
- [EGL] Made it possible to query the `EGLConfig` that was chosen to create a given window via `glfwGetEGLConfig`
|
||||||
|
- [GLX] Bugfix: Context creation failed if GLX 1.4 was not exported by GLX library
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
@ -68,8 +68,10 @@ install the `xorgproto` package.
|
|||||||
pkg install xorgproto
|
pkg install xorgproto
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
On Cygwin the `xorgproto` package in the Devel section of the GUI installer will
|
On Cygwin the `libXcursor-devel`, `libXi-devel`, `libXinerama-devel`,
|
||||||
install the headers and other development related files for all of X11.
|
`libXrandr-devel` and `libXrender-devel` packages in the Libs section of the GUI
|
||||||
|
installer will install all the headers and other development related files GLFW
|
||||||
|
requires for X11.
|
||||||
|
|
||||||
Once you have the required dependencies, move on to @ref compile_generate.
|
Once you have the required dependencies, move on to @ref compile_generate.
|
||||||
|
|
||||||
|
@ -821,7 +821,7 @@ The second value is always the human-readable name of the gamepad.
|
|||||||
All subsequent values are in the form `<field>:<value>` and describe the layout
|
All subsequent values are in the form `<field>:<value>` and describe the layout
|
||||||
of the mapping. These fields may not all be present and may occur in any order.
|
of the mapping. These fields may not all be present and may occur in any order.
|
||||||
|
|
||||||
The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`,
|
The button fields are `a`, `b`, `x`, `y`, `back`, `start`, `guide`, `dpup`,
|
||||||
`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
|
`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
|
||||||
`rightstick`.
|
`rightstick`.
|
||||||
|
|
||||||
|
@ -144,6 +144,12 @@ GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off
|
|||||||
(the Transparency setting under Personalization > Window Color).
|
(the Transparency setting under Personalization > Window Color).
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection emptyevents_34 Empty events on X11 no longer roundtrip to server
|
||||||
|
|
||||||
|
Events posted with @ref glfwPostEmptyEvent now use a separate unnamed pipe
|
||||||
|
instead of sending an X11 client event to the helper window.
|
||||||
|
|
||||||
|
|
||||||
@subsection deprecations_34 Deprecations in version 3.4
|
@subsection deprecations_34 Deprecations in version 3.4
|
||||||
|
|
||||||
@subsection removals_34 Removals in 3.4
|
@subsection removals_34 Removals in 3.4
|
||||||
|
@ -3258,7 +3258,8 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
|
|||||||
* count is zero.
|
* count is zero.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
* GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref
|
||||||
|
* GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||||
*
|
*
|
||||||
* @pointer_lifetime The specified image data is copied before this function
|
* @pointer_lifetime The specified image data is copied before this function
|
||||||
* returns.
|
* returns.
|
||||||
@ -4892,8 +4893,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
|
|||||||
* @return The handle of the created cursor, or `NULL` if an
|
* @return The handle of the created cursor, or `NULL` if an
|
||||||
* [error](@ref error_handling) occurred.
|
* [error](@ref error_handling) occurred.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
|
||||||
*
|
*
|
||||||
* @pointer_lifetime The specified image data is copied before this function
|
* @pointer_lifetime The specified image data is copied before this function
|
||||||
* returns.
|
* returns.
|
||||||
|
@ -82,9 +82,10 @@ extern "C" {
|
|||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
/* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||||
// example to allow applications to correctly declare a GL_KHR_debug callback)
|
* example to allow applications to correctly declare a GL_KHR_debug callback)
|
||||||
// but windows.h assumes no one will define APIENTRY before it does
|
* but windows.h assumes no one will define APIENTRY before it does
|
||||||
|
*/
|
||||||
#if defined(GLFW_APIENTRY_DEFINED)
|
#if defined(GLFW_APIENTRY_DEFINED)
|
||||||
#undef APIENTRY
|
#undef APIENTRY
|
||||||
#undef GLFW_APIENTRY_DEFINED
|
#undef GLFW_APIENTRY_DEFINED
|
||||||
@ -111,12 +112,22 @@ extern "C" {
|
|||||||
/* NSGL is declared by Cocoa.h */
|
/* NSGL is declared by Cocoa.h */
|
||||||
#endif
|
#endif
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
|
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
|
||||||
|
* default it also acts as an OpenGL header
|
||||||
|
* However, glx.h will include gl.h, which will define it unconditionally
|
||||||
|
*/
|
||||||
|
#undef GLAPIENTRY
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||||
|
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
|
||||||
|
* default it also acts as an OpenGL header
|
||||||
|
* However, osmesa.h will include gl.h, which will define it unconditionally
|
||||||
|
*/
|
||||||
|
#undef GLAPIENTRY
|
||||||
#include <GL/osmesa.h>
|
#include <GL/osmesa.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND)
|
|||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
|
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
|
||||||
endif()
|
endif()
|
||||||
|
target_sources(glfw PRIVATE posix_poll.h posix_poll.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (GLFW_BUILD_WAYLAND)
|
if (GLFW_BUILD_WAYLAND)
|
||||||
|
@ -98,11 +98,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
|
|||||||
IOObjectRelease(it);
|
IOObjectRelease(it);
|
||||||
|
|
||||||
if (!service)
|
if (!service)
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Cocoa: Failed to find service port for display");
|
|
||||||
return _glfw_strdup("Display");
|
return _glfw_strdup("Display");
|
||||||
}
|
|
||||||
|
|
||||||
CFDictionaryRef names =
|
CFDictionaryRef names =
|
||||||
CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
|
CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
|
||||||
|
@ -325,7 +325,7 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
"libEGL.dylib",
|
"libEGL.dylib",
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
"libEGL-1.so",
|
"libEGL-1.so",
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libEGL.so",
|
"libEGL.so",
|
||||||
#else
|
#else
|
||||||
"libEGL.so.1",
|
"libEGL.so.1",
|
||||||
@ -506,7 +506,7 @@ void _glfwTerminateEGL(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define SET_ATTRIB(a, v) \
|
||||||
{ \
|
{ \
|
||||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = a; \
|
||||||
@ -584,13 +584,13 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||||
EGL_NO_RESET_NOTIFICATION_KHR);
|
EGL_NO_RESET_NOTIFICATION_KHR);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||||
EGL_LOSE_CONTEXT_ON_RESET_KHR);
|
EGL_LOSE_CONTEXT_ON_RESET_KHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
||||||
@ -599,42 +599,42 @@ 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)
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
|
SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
|
SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
|
||||||
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
|
SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
|
SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags);
|
SET_ATTRIB(EGL_CONTEXT_FLAGS_KHR, flags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
|
SET_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.egl.KHR_context_flush_control)
|
if (_glfw.egl.KHR_context_flush_control)
|
||||||
{
|
{
|
||||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
||||||
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
|
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
||||||
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
|
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setAttrib(EGL_NONE, EGL_NONE);
|
SET_ATTRIB(EGL_NONE, EGL_NONE);
|
||||||
|
|
||||||
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
|
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
|
||||||
config, share, attribs);
|
config, share, attribs);
|
||||||
@ -653,16 +653,16 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
if (fbconfig->sRGB)
|
if (fbconfig->sRGB)
|
||||||
{
|
{
|
||||||
if (_glfw.egl.KHR_gl_colorspace)
|
if (_glfw.egl.KHR_gl_colorspace)
|
||||||
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
SET_ATTRIB(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fbconfig->doublebuffer)
|
if (!fbconfig->doublebuffer)
|
||||||
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
|
SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
|
||||||
|
|
||||||
if (_glfw.egl.EXT_present_opaque)
|
if (_glfw.egl.EXT_present_opaque)
|
||||||
setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
||||||
|
|
||||||
setAttrib(EGL_NONE, EGL_NONE);
|
SET_ATTRIB(EGL_NONE, EGL_NONE);
|
||||||
|
|
||||||
native = _glfw.platform.getEGLNativeWindow(window);
|
native = _glfw.platform.getEGLNativeWindow(window);
|
||||||
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
|
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
|
||||||
@ -702,7 +702,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
"libGLES_CM.dll",
|
"libGLES_CM.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
"libGLESv1_CM.dylib",
|
"libGLESv1_CM.dylib",
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libGLESv1_CM.so",
|
"libGLESv1_CM.so",
|
||||||
#else
|
#else
|
||||||
"libGLESv1_CM.so.1",
|
"libGLESv1_CM.so.1",
|
||||||
@ -721,7 +721,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
"libGLESv2.dylib",
|
"libGLESv2.dylib",
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
"libGLESv2-2.so",
|
"libGLESv2-2.so",
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libGLESv2.so",
|
"libGLESv2.so",
|
||||||
#else
|
#else
|
||||||
"libGLESv2.so.2",
|
"libGLESv2.so.2",
|
||||||
@ -734,7 +734,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
_GLFW_OPENGL_LIBRARY,
|
_GLFW_OPENGL_LIBRARY,
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_GLFW_WIN32)
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libGL.so",
|
"libGL.so",
|
||||||
#else
|
#else
|
||||||
"libGL.so.1",
|
"libGL.so.1",
|
||||||
@ -782,7 +782,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef setAttrib
|
#undef SET_ATTRIB
|
||||||
|
|
||||||
// Returns the Visual and depth of the chosen EGLConfig
|
// Returns the Visual and depth of the chosen EGLConfig
|
||||||
//
|
//
|
||||||
|
@ -259,7 +259,7 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
_GLFW_GLX_LIBRARY,
|
_GLFW_GLX_LIBRARY,
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
"libGL-1.so",
|
"libGL-1.so",
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libGL.so",
|
"libGL.so",
|
||||||
#else
|
#else
|
||||||
"libGL.so.1",
|
"libGL.so.1",
|
||||||
@ -308,10 +308,6 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateWindow");
|
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateWindow");
|
||||||
_glfw.glx.DestroyWindow = (PFNGLXDESTROYWINDOWPROC)
|
_glfw.glx.DestroyWindow = (PFNGLXDESTROYWINDOWPROC)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyWindow");
|
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyWindow");
|
||||||
_glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress");
|
|
||||||
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddressARB");
|
|
||||||
_glfw.glx.GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
|
_glfw.glx.GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetVisualFromFBConfig");
|
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetVisualFromFBConfig");
|
||||||
|
|
||||||
@ -327,8 +323,6 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
!_glfw.glx.CreateNewContext ||
|
!_glfw.glx.CreateNewContext ||
|
||||||
!_glfw.glx.CreateWindow ||
|
!_glfw.glx.CreateWindow ||
|
||||||
!_glfw.glx.DestroyWindow ||
|
!_glfw.glx.DestroyWindow ||
|
||||||
!_glfw.glx.GetProcAddress ||
|
|
||||||
!_glfw.glx.GetProcAddressARB ||
|
|
||||||
!_glfw.glx.GetVisualFromFBConfig)
|
!_glfw.glx.GetVisualFromFBConfig)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@ -336,6 +330,12 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Unlike GLX 1.3 entry points these are not required to be present
|
||||||
|
_glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress");
|
||||||
|
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddressARB");
|
||||||
|
|
||||||
if (!glXQueryExtension(_glfw.x11.display,
|
if (!glXQueryExtension(_glfw.x11.display,
|
||||||
&_glfw.glx.errorBase,
|
&_glfw.glx.errorBase,
|
||||||
&_glfw.glx.eventBase))
|
&_glfw.glx.eventBase))
|
||||||
@ -435,7 +435,7 @@ void _glfwTerminateGLX(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define SET_ATTRIB(a, v) \
|
||||||
{ \
|
{ \
|
||||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = a; \
|
||||||
@ -523,13 +523,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
GLX_NO_RESET_NOTIFICATION_ARB);
|
GLX_NO_RESET_NOTIFICATION_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
GLX_LOSE_CONTEXT_ON_RESET_ARB);
|
GLX_LOSE_CONTEXT_ON_RESET_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
@ -542,13 +542,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -556,7 +556,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
if (ctxconfig->noerror)
|
if (ctxconfig->noerror)
|
||||||
{
|
{
|
||||||
if (_glfw.glx.ARB_create_context_no_error)
|
if (_glfw.glx.ARB_create_context_no_error)
|
||||||
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
SET_ATTRIB(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||||
@ -564,17 +564,17 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
// highest version supported by the driver
|
// highest version supported by the driver
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
SET_ATTRIB(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||||
setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
SET_ATTRIB(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
|
SET_ATTRIB(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
setAttrib(GLX_CONTEXT_FLAGS_ARB, flags);
|
SET_ATTRIB(GLX_CONTEXT_FLAGS_ARB, flags);
|
||||||
|
|
||||||
setAttrib(None, None);
|
SET_ATTRIB(None, None);
|
||||||
|
|
||||||
window->context.glx.handle =
|
window->context.glx.handle =
|
||||||
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
|
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
|
||||||
@ -631,7 +631,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef setAttrib
|
#undef SET_ATTRIB
|
||||||
|
|
||||||
// Returns the Visual and depth of the chosen GLXFBConfig
|
// Returns the Visual and depth of the chosen GLXFBConfig
|
||||||
//
|
//
|
||||||
|
10
src/init.c
10
src/init.c
@ -179,6 +179,16 @@ char* _glfw_strdup(const char* source)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfw_min(int a, int b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfw_max(int a, int b)
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
float _glfw_fminf(float a, float b)
|
float _glfw_fminf(float a, float b)
|
||||||
{
|
{
|
||||||
if (a != a)
|
if (a != a)
|
||||||
|
@ -764,9 +764,16 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
|
|||||||
_GLFWcursor* cursor;
|
_GLFWcursor* cursor;
|
||||||
|
|
||||||
assert(image != NULL);
|
assert(image != NULL);
|
||||||
|
assert(image->pixels != NULL);
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (image->width <= 0 || image->height <= 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image dimensions for cursor");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
|
cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
|
||||||
cursor->next = _glfw.cursorListHead;
|
cursor->next = _glfw.cursorListHead;
|
||||||
_glfw.cursorListHead = cursor;
|
_glfw.cursorListHead = cursor;
|
||||||
|
@ -998,6 +998,8 @@ const char* _glfwGetVulkanResultString(VkResult result);
|
|||||||
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
||||||
|
|
||||||
char* _glfw_strdup(const char* source);
|
char* _glfw_strdup(const char* source);
|
||||||
|
int _glfw_min(int a, int b);
|
||||||
|
int _glfw_max(int a, int b);
|
||||||
float _glfw_fminf(float a, float b);
|
float _glfw_fminf(float a, float b);
|
||||||
float _glfw_fmaxf(float a, float b);
|
float _glfw_fmaxf(float a, float b);
|
||||||
|
|
||||||
|
@ -188,45 +188,45 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
|
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
|
||||||
// are not a hard constraint, so ignore and continue
|
// are not a hard constraint, so ignore and continue
|
||||||
|
|
||||||
#define addAttrib(a) \
|
#define ADD_ATTRIB(a) \
|
||||||
{ \
|
{ \
|
||||||
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = a; \
|
||||||
}
|
}
|
||||||
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); }
|
#define SET_ATTRIB(a, v) { ADD_ATTRIB(a); ADD_ATTRIB(v); }
|
||||||
|
|
||||||
NSOpenGLPixelFormatAttribute attribs[40];
|
NSOpenGLPixelFormatAttribute attribs[40];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
addAttrib(NSOpenGLPFAAccelerated);
|
ADD_ATTRIB(NSOpenGLPFAAccelerated);
|
||||||
addAttrib(NSOpenGLPFAClosestPolicy);
|
ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
|
||||||
|
|
||||||
if (ctxconfig->nsgl.offline)
|
if (ctxconfig->nsgl.offline)
|
||||||
{
|
{
|
||||||
addAttrib(NSOpenGLPFAAllowOfflineRenderers);
|
ADD_ATTRIB(NSOpenGLPFAAllowOfflineRenderers);
|
||||||
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
|
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
|
||||||
// Info.plist for unbundled applications
|
// Info.plist for unbundled applications
|
||||||
// HACK: This assumes that NSOpenGLPixelFormat will remain
|
// HACK: This assumes that NSOpenGLPixelFormat will remain
|
||||||
// a straightforward wrapper of its CGL counterpart
|
// a straightforward wrapper of its CGL counterpart
|
||||||
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
|
ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||||
if (ctxconfig->major >= 4)
|
if (ctxconfig->major >= 4)
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||||
if (ctxconfig->major >= 3)
|
if (ctxconfig->major >= 3)
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->major <= 2)
|
if (ctxconfig->major <= 2)
|
||||||
{
|
{
|
||||||
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
|
SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
|
||||||
|
|
||||||
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
|
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
|
||||||
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
|
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
|
||||||
@ -238,7 +238,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
fbconfig->accumBlueBits +
|
fbconfig->accumBlueBits +
|
||||||
fbconfig->accumAlphaBits;
|
fbconfig->accumAlphaBits;
|
||||||
|
|
||||||
setAttrib(NSOpenGLPFAAccumSize, accumBits);
|
SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,17 +256,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
else if (colorBits < 15)
|
else if (colorBits < 15)
|
||||||
colorBits = 15;
|
colorBits = 15;
|
||||||
|
|
||||||
setAttrib(NSOpenGLPFAColorSize, colorBits);
|
SET_ATTRIB(NSOpenGLPFAColorSize, colorBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
SET_ATTRIB(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
||||||
|
|
||||||
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
SET_ATTRIB(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
||||||
|
|
||||||
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
|
SET_ATTRIB(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
|
||||||
|
|
||||||
if (fbconfig->stereo)
|
if (fbconfig->stereo)
|
||||||
{
|
{
|
||||||
@ -275,33 +275,33 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
"NSGL: Stereo rendering is deprecated");
|
"NSGL: Stereo rendering is deprecated");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
#else
|
#else
|
||||||
addAttrib(NSOpenGLPFAStereo);
|
ADD_ATTRIB(NSOpenGLPFAStereo);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fbconfig->doublebuffer)
|
if (fbconfig->doublebuffer)
|
||||||
addAttrib(NSOpenGLPFADoubleBuffer);
|
ADD_ATTRIB(NSOpenGLPFADoubleBuffer);
|
||||||
|
|
||||||
if (fbconfig->samples != GLFW_DONT_CARE)
|
if (fbconfig->samples != GLFW_DONT_CARE)
|
||||||
{
|
{
|
||||||
if (fbconfig->samples == 0)
|
if (fbconfig->samples == 0)
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFASampleBuffers, 0);
|
SET_ATTRIB(NSOpenGLPFASampleBuffers, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFASampleBuffers, 1);
|
SET_ATTRIB(NSOpenGLPFASampleBuffers, 1);
|
||||||
setAttrib(NSOpenGLPFASamples, fbconfig->samples);
|
SET_ATTRIB(NSOpenGLPFASamples, fbconfig->samples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
|
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
|
||||||
// framebuffer, so there's no need (and no way) to request it
|
// framebuffer, so there's no need (and no way) to request it
|
||||||
|
|
||||||
addAttrib(0);
|
ADD_ATTRIB(0);
|
||||||
|
|
||||||
#undef addAttrib
|
#undef ADD_ATTRIB
|
||||||
#undef setAttrib
|
#undef SET_ATTRIB
|
||||||
|
|
||||||
window->context.nsgl.pixelFormat =
|
window->context.nsgl.pixelFormat =
|
||||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
||||||
|
@ -39,15 +39,15 @@ static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
|
|||||||
*height = (int) (*width / ratio);
|
*height = (int) (*width / ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->minwidth != GLFW_DONT_CARE && *width < window->minwidth)
|
if (window->minwidth != GLFW_DONT_CARE)
|
||||||
*width = window->minwidth;
|
*width = _glfw_max(*width, window->minwidth);
|
||||||
else if (window->maxwidth != GLFW_DONT_CARE && *width > window->maxwidth)
|
else if (window->maxwidth != GLFW_DONT_CARE)
|
||||||
*width = window->maxwidth;
|
*width = _glfw_min(*width, window->maxwidth);
|
||||||
|
|
||||||
if (window->minheight != GLFW_DONT_CARE && *height < window->minheight)
|
if (window->minheight != GLFW_DONT_CARE)
|
||||||
*height = window->minheight;
|
*height = _glfw_min(*height, window->minheight);
|
||||||
else if (window->maxheight != GLFW_DONT_CARE && *height > window->maxheight)
|
else if (window->maxheight != GLFW_DONT_CARE)
|
||||||
*height = window->maxheight;
|
*height = _glfw_max(*height, window->maxheight);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fitToMonitor(_GLFWwindow* window)
|
static void fitToMonitor(_GLFWwindow* window)
|
||||||
|
@ -124,7 +124,7 @@ GLFWbool _glfwInitOSMesa(void)
|
|||||||
"libOSMesa.8.dylib",
|
"libOSMesa.8.dylib",
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
"libOSMesa-8.so",
|
"libOSMesa-8.so",
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
"libOSMesa.so",
|
"libOSMesa.so",
|
||||||
#else
|
#else
|
||||||
"libOSMesa.so.8",
|
"libOSMesa.so.8",
|
||||||
@ -190,7 +190,7 @@ void _glfwTerminateOSMesa(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define SET_ATTRIB(a, v) \
|
||||||
{ \
|
{ \
|
||||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = a; \
|
||||||
@ -221,24 +221,24 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
int index = 0, attribs[40];
|
int index = 0, attribs[40];
|
||||||
|
|
||||||
setAttrib(OSMESA_FORMAT, OSMESA_RGBA);
|
SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA);
|
||||||
setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits);
|
SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits);
|
||||||
setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
|
SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
|
||||||
setAttrib(OSMESA_ACCUM_BITS, accumBits);
|
SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits);
|
||||||
|
|
||||||
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
{
|
{
|
||||||
setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
|
SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
{
|
{
|
||||||
setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
|
SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
{
|
{
|
||||||
setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
|
SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
|
||||||
setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
|
SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->forward)
|
if (ctxconfig->forward)
|
||||||
@ -248,7 +248,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
setAttrib(0, 0);
|
SET_ATTRIB(0, 0);
|
||||||
|
|
||||||
window->context.osmesa.handle =
|
window->context.osmesa.handle =
|
||||||
OSMesaCreateContextAttribs(attribs, share);
|
OSMesaCreateContextAttribs(attribs, share);
|
||||||
@ -287,7 +287,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef setAttrib
|
#undef SET_ATTRIB
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
81
src/posix_poll.c
Normal file
81
src/posix_poll.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.4 POSIX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
const uint64_t base = _glfwPlatformGetTimerValue();
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||||
|
const time_t seconds = (time_t) *timeout;
|
||||||
|
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||||
|
const struct timespec ts = { seconds, nanoseconds };
|
||||||
|
const int result = ppoll(fds, count, &ts, NULL);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
const time_t seconds = (time_t) *timeout;
|
||||||
|
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||||
|
const struct timespec ts = { seconds, nanoseconds };
|
||||||
|
const int result = pollts(fds, count, &ts, NULL);
|
||||||
|
#else
|
||||||
|
const int milliseconds = (int) (*timeout * 1e3);
|
||||||
|
const int result = poll(fds, count, milliseconds);
|
||||||
|
#endif
|
||||||
|
const int error = errno; // clock_gettime may overwrite our error
|
||||||
|
|
||||||
|
*timeout -= (_glfwPlatformGetTimerValue() - base) /
|
||||||
|
(double) _glfwPlatformGetTimerFrequency();
|
||||||
|
|
||||||
|
if (result > 0)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
else if (result == -1 && error != EINTR && error != EAGAIN)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
else if (*timeout <= 0.0)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int result = poll(fds, count, -1);
|
||||||
|
if (result > 0)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
else if (result == -1 && errno != EINTR && errno != EAGAIN)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
32
src/posix_poll.h
Normal file
32
src/posix_poll.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.4 POSIX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout);
|
||||||
|
|
@ -63,7 +63,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
_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 = _glfwLoadLocalVulkanLoaderCocoa();
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
|
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
|
||||||
#else
|
#else
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
|
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
|
||||||
|
@ -52,12 +52,12 @@ static int findPixelFormatAttribValueWGL(const int* attribs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define addAttrib(a) \
|
#define ADD_ATTRIB(a) \
|
||||||
{ \
|
{ \
|
||||||
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
|
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
attribs[attribCount++] = a; \
|
attribs[attribCount++] = a; \
|
||||||
}
|
}
|
||||||
#define findAttribValue(a) \
|
#define FIND_ATTRIB_VALUE(a) \
|
||||||
findPixelFormatAttribValueWGL(attribs, attribCount, values, a)
|
findPixelFormatAttribValueWGL(attribs, attribCount, values, a)
|
||||||
|
|
||||||
// Return a list of available and usable framebuffer configs
|
// Return a list of available and usable framebuffer configs
|
||||||
@ -84,41 +84,41 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
addAttrib(WGL_SUPPORT_OPENGL_ARB);
|
ADD_ATTRIB(WGL_SUPPORT_OPENGL_ARB);
|
||||||
addAttrib(WGL_DRAW_TO_WINDOW_ARB);
|
ADD_ATTRIB(WGL_DRAW_TO_WINDOW_ARB);
|
||||||
addAttrib(WGL_PIXEL_TYPE_ARB);
|
ADD_ATTRIB(WGL_PIXEL_TYPE_ARB);
|
||||||
addAttrib(WGL_ACCELERATION_ARB);
|
ADD_ATTRIB(WGL_ACCELERATION_ARB);
|
||||||
addAttrib(WGL_RED_BITS_ARB);
|
ADD_ATTRIB(WGL_RED_BITS_ARB);
|
||||||
addAttrib(WGL_RED_SHIFT_ARB);
|
ADD_ATTRIB(WGL_RED_SHIFT_ARB);
|
||||||
addAttrib(WGL_GREEN_BITS_ARB);
|
ADD_ATTRIB(WGL_GREEN_BITS_ARB);
|
||||||
addAttrib(WGL_GREEN_SHIFT_ARB);
|
ADD_ATTRIB(WGL_GREEN_SHIFT_ARB);
|
||||||
addAttrib(WGL_BLUE_BITS_ARB);
|
ADD_ATTRIB(WGL_BLUE_BITS_ARB);
|
||||||
addAttrib(WGL_BLUE_SHIFT_ARB);
|
ADD_ATTRIB(WGL_BLUE_SHIFT_ARB);
|
||||||
addAttrib(WGL_ALPHA_BITS_ARB);
|
ADD_ATTRIB(WGL_ALPHA_BITS_ARB);
|
||||||
addAttrib(WGL_ALPHA_SHIFT_ARB);
|
ADD_ATTRIB(WGL_ALPHA_SHIFT_ARB);
|
||||||
addAttrib(WGL_DEPTH_BITS_ARB);
|
ADD_ATTRIB(WGL_DEPTH_BITS_ARB);
|
||||||
addAttrib(WGL_STENCIL_BITS_ARB);
|
ADD_ATTRIB(WGL_STENCIL_BITS_ARB);
|
||||||
addAttrib(WGL_ACCUM_BITS_ARB);
|
ADD_ATTRIB(WGL_ACCUM_BITS_ARB);
|
||||||
addAttrib(WGL_ACCUM_RED_BITS_ARB);
|
ADD_ATTRIB(WGL_ACCUM_RED_BITS_ARB);
|
||||||
addAttrib(WGL_ACCUM_GREEN_BITS_ARB);
|
ADD_ATTRIB(WGL_ACCUM_GREEN_BITS_ARB);
|
||||||
addAttrib(WGL_ACCUM_BLUE_BITS_ARB);
|
ADD_ATTRIB(WGL_ACCUM_BLUE_BITS_ARB);
|
||||||
addAttrib(WGL_ACCUM_ALPHA_BITS_ARB);
|
ADD_ATTRIB(WGL_ACCUM_ALPHA_BITS_ARB);
|
||||||
addAttrib(WGL_AUX_BUFFERS_ARB);
|
ADD_ATTRIB(WGL_AUX_BUFFERS_ARB);
|
||||||
addAttrib(WGL_STEREO_ARB);
|
ADD_ATTRIB(WGL_STEREO_ARB);
|
||||||
addAttrib(WGL_DOUBLE_BUFFER_ARB);
|
ADD_ATTRIB(WGL_DOUBLE_BUFFER_ARB);
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_multisample)
|
if (_glfw.wgl.ARB_multisample)
|
||||||
addAttrib(WGL_SAMPLES_ARB);
|
ADD_ATTRIB(WGL_SAMPLES_ARB);
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
{
|
{
|
||||||
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
|
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
|
||||||
addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
ADD_ATTRIB(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_glfw.wgl.EXT_colorspace)
|
if (_glfw.wgl.EXT_colorspace)
|
||||||
addAttrib(WGL_COLORSPACE_EXT);
|
ADD_ATTRIB(WGL_COLORSPACE_EXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -152,48 +152,48 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) ||
|
if (!FIND_ATTRIB_VALUE(WGL_SUPPORT_OPENGL_ARB) ||
|
||||||
!findAttribValue(WGL_DRAW_TO_WINDOW_ARB))
|
!FIND_ATTRIB_VALUE(WGL_DRAW_TO_WINDOW_ARB))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
|
if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
|
if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (findAttribValue(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
|
if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u->redBits = findAttribValue(WGL_RED_BITS_ARB);
|
u->redBits = FIND_ATTRIB_VALUE(WGL_RED_BITS_ARB);
|
||||||
u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB);
|
u->greenBits = FIND_ATTRIB_VALUE(WGL_GREEN_BITS_ARB);
|
||||||
u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB);
|
u->blueBits = FIND_ATTRIB_VALUE(WGL_BLUE_BITS_ARB);
|
||||||
u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB);
|
u->alphaBits = FIND_ATTRIB_VALUE(WGL_ALPHA_BITS_ARB);
|
||||||
|
|
||||||
u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB);
|
u->depthBits = FIND_ATTRIB_VALUE(WGL_DEPTH_BITS_ARB);
|
||||||
u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB);
|
u->stencilBits = FIND_ATTRIB_VALUE(WGL_STENCIL_BITS_ARB);
|
||||||
|
|
||||||
u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB);
|
u->accumRedBits = FIND_ATTRIB_VALUE(WGL_ACCUM_RED_BITS_ARB);
|
||||||
u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB);
|
u->accumGreenBits = FIND_ATTRIB_VALUE(WGL_ACCUM_GREEN_BITS_ARB);
|
||||||
u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB);
|
u->accumBlueBits = FIND_ATTRIB_VALUE(WGL_ACCUM_BLUE_BITS_ARB);
|
||||||
u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB);
|
u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB);
|
||||||
|
|
||||||
u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB);
|
u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB);
|
||||||
|
|
||||||
if (findAttribValue(WGL_STEREO_ARB))
|
if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB))
|
||||||
u->stereo = GLFW_TRUE;
|
u->stereo = GLFW_TRUE;
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_multisample)
|
if (_glfw.wgl.ARB_multisample)
|
||||||
u->samples = findAttribValue(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)
|
||||||
{
|
{
|
||||||
if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
||||||
u->sRGB = GLFW_TRUE;
|
u->sRGB = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (_glfw.wgl.EXT_colorspace)
|
if (_glfw.wgl.EXT_colorspace)
|
||||||
{
|
{
|
||||||
if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
|
if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
|
||||||
u->sRGB = GLFW_TRUE;
|
u->sRGB = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,8 +290,8 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
|
|||||||
return pixelFormat;
|
return pixelFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef addAttrib
|
#undef ADD_ATTRIB
|
||||||
#undef findAttribValue
|
#undef FIND_ATTRIB_VALUE
|
||||||
|
|
||||||
static void makeContextCurrentWGL(_GLFWwindow* window)
|
static void makeContextCurrentWGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
@ -523,7 +523,7 @@ void _glfwTerminateWGL(void)
|
|||||||
_glfwPlatformFreeModule(_glfw.wgl.instance);
|
_glfwPlatformFreeModule(_glfw.wgl.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define SET_ATTRIB(a, v) \
|
||||||
{ \
|
{ \
|
||||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = a; \
|
||||||
@ -631,13 +631,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
WGL_NO_RESET_NOTIFICATION_ARB);
|
WGL_NO_RESET_NOTIFICATION_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
@ -650,13 +650,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,7 +664,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
if (ctxconfig->noerror)
|
if (ctxconfig->noerror)
|
||||||
{
|
{
|
||||||
if (_glfw.wgl.ARB_create_context_no_error)
|
if (_glfw.wgl.ARB_create_context_no_error)
|
||||||
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||||
@ -672,17 +672,17 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
// highest version supported by the driver
|
// highest version supported by the driver
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||||
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
|
SET_ATTRIB(WGL_CONTEXT_FLAGS_ARB, flags);
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||||
|
|
||||||
setAttrib(0, 0);
|
SET_ATTRIB(0, 0);
|
||||||
|
|
||||||
window->context.wgl.handle =
|
window->context.wgl.handle =
|
||||||
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
|
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
|
||||||
@ -765,7 +765,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef setAttrib
|
#undef SET_ATTRIB
|
||||||
|
|
||||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
||||||
{
|
{
|
||||||
|
@ -71,6 +71,16 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
|||||||
//
|
//
|
||||||
static GLFWbool loadLibraries(void)
|
static GLFWbool loadLibraries(void)
|
||||||
{
|
{
|
||||||
|
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||||
|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||||
|
(const WCHAR*) &_glfw,
|
||||||
|
(HMODULE*) &_glfw.win32.instance))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to retrieve own module handle");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
_glfw.win32.user32.instance = _glfwPlatformLoadModule("user32.dll");
|
_glfw.win32.user32.instance = _glfwPlatformLoadModule("user32.dll");
|
||||||
if (!_glfw.win32.user32.instance)
|
if (!_glfw.win32.user32.instance)
|
||||||
{
|
{
|
||||||
@ -91,6 +101,8 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetDpiForWindow");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetDpiForWindow");
|
||||||
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
||||||
|
_glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetSystemMetricsForDpi");
|
||||||
|
|
||||||
_glfw.win32.dinput8.instance = _glfwPlatformLoadModule("dinput8.dll");
|
_glfw.win32.dinput8.instance = _glfwPlatformLoadModule("dinput8.dll");
|
||||||
if (_glfw.win32.dinput8.instance)
|
if (_glfw.win32.dinput8.instance)
|
||||||
@ -251,7 +263,6 @@ static void createKeyTables(void)
|
|||||||
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
|
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
|
||||||
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
|
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
|
||||||
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
|
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
|
||||||
_glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
|
|
||||||
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
|
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
|
||||||
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
|
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
|
||||||
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
|
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
|
||||||
@ -333,7 +344,7 @@ static GLFWbool createHelperWindow(void)
|
|||||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||||
0, 0, 1, 1,
|
0, 0, 1, 1,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
GetModuleHandleW(NULL),
|
_glfw.win32.instance,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!_glfw.win32.helperWindowHandle)
|
if (!_glfw.win32.helperWindowHandle)
|
||||||
@ -483,7 +494,7 @@ void _glfwUpdateKeyNamesWin32(void)
|
|||||||
vk = vks[key - GLFW_KEY_KP_0];
|
vk = vks[key - GLFW_KEY_KP_0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
|
vk = MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK);
|
||||||
|
|
||||||
length = ToUnicode(vk, scancode, state,
|
length = ToUnicode(vk, scancode, state,
|
||||||
chars, sizeof(chars) / sizeof(WCHAR),
|
chars, sizeof(chars) / sizeof(WCHAR),
|
||||||
@ -506,7 +517,8 @@ void _glfwUpdateKeyNamesWin32(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
|
// Replacement for IsWindowsVersionOrGreater, as we cannot rely on the
|
||||||
|
// application having a correct embedded manifest
|
||||||
//
|
//
|
||||||
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
||||||
{
|
{
|
||||||
@ -626,7 +638,7 @@ int _glfwInitWin32(void)
|
|||||||
createKeyTables();
|
createKeyTables();
|
||||||
_glfwUpdateKeyNamesWin32();
|
_glfwUpdateKeyNamesWin32();
|
||||||
|
|
||||||
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1703OrGreaterWin32())
|
||||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
else if (IsWindows8Point1OrGreater())
|
else if (IsWindows8Point1OrGreater())
|
||||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
|
@ -574,7 +574,7 @@ GLFWbool _glfwInitJoysticksWin32(void)
|
|||||||
{
|
{
|
||||||
if (_glfw.win32.dinput8.instance)
|
if (_glfw.win32.dinput8.instance)
|
||||||
{
|
{
|
||||||
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
|
if (FAILED(DirectInput8Create(_glfw.win32.instance,
|
||||||
DIRECTINPUT_VERSION,
|
DIRECTINPUT_VERSION,
|
||||||
&IID_IDirectInput8W,
|
&IID_IDirectInput8W,
|
||||||
(void**) &_glfw.win32.dinput8.api,
|
(void**) &_glfw.win32.dinput8.api,
|
||||||
|
@ -381,7 +381,7 @@ void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor,
|
|||||||
int* width, int* height)
|
int* width, int* height)
|
||||||
{
|
{
|
||||||
MONITORINFO mi = { sizeof(mi) };
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
GetMonitorInfo(monitor->win32.handle, &mi);
|
GetMonitorInfoW(monitor->win32.handle, &mi);
|
||||||
|
|
||||||
if (xpos)
|
if (xpos)
|
||||||
*xpos = mi.rcWork.left;
|
*xpos = mi.rcWork.left;
|
||||||
|
@ -162,7 +162,9 @@ typedef enum
|
|||||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
|
||||||
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
||||||
|
|
||||||
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
// Replacement for versionhelpers.h macros, as we cannot rely on the
|
||||||
|
// application having a correct embedded manifest
|
||||||
|
//
|
||||||
#define IsWindowsVistaOrGreater() \
|
#define IsWindowsVistaOrGreater() \
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
||||||
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
||||||
@ -176,9 +178,11 @@ typedef enum
|
|||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
||||||
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
||||||
|
|
||||||
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \
|
// Windows 10 Anniversary Update
|
||||||
|
#define _glfwIsWindows10Version1607OrGreaterWin32() \
|
||||||
_glfwIsWindows10BuildOrGreaterWin32(14393)
|
_glfwIsWindows10BuildOrGreaterWin32(14393)
|
||||||
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \
|
// Windows 10 Creators Update
|
||||||
|
#define _glfwIsWindows10Version1703OrGreaterWin32() \
|
||||||
_glfwIsWindows10BuildOrGreaterWin32(15063)
|
_glfwIsWindows10BuildOrGreaterWin32(15063)
|
||||||
|
|
||||||
// HACK: Define macros that some xinput.h variants don't
|
// HACK: Define macros that some xinput.h variants don't
|
||||||
@ -283,12 +287,14 @@ typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
|
|||||||
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
|
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
|
||||||
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
||||||
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
||||||
|
typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
|
||||||
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||||
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||||
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
||||||
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
||||||
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
||||||
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
|
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
|
||||||
|
#define GetSystemMetricsForDpi _glfw.win32.user32.GetSystemMetricsForDpi_
|
||||||
|
|
||||||
// dwmapi.dll function pointer typedefs
|
// dwmapi.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
@ -436,6 +442,7 @@ typedef struct _GLFWwindowWin32
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWlibraryWin32
|
typedef struct _GLFWlibraryWin32
|
||||||
{
|
{
|
||||||
|
HINSTANCE instance;
|
||||||
HWND helperWindowHandle;
|
HWND helperWindowHandle;
|
||||||
HDEVNOTIFY deviceNotificationHandle;
|
HDEVNOTIFY deviceNotificationHandle;
|
||||||
int acquiredMonitorCount;
|
int acquiredMonitorCount;
|
||||||
@ -471,6 +478,7 @@ typedef struct _GLFWlibraryWin32
|
|||||||
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
||||||
PFN_GetDpiForWindow GetDpiForWindow_;
|
PFN_GetDpiForWindow GetDpiForWindow_;
|
||||||
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
|
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
|
||||||
|
PFN_GetSystemMetricsForDpi GetSystemMetricsForDpi_;
|
||||||
} user32;
|
} user32;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -97,8 +97,7 @@ static const GLFWimage* chooseImage(int count, const GLFWimage* images,
|
|||||||
|
|
||||||
// Creates an RGBA icon or cursor
|
// Creates an RGBA icon or cursor
|
||||||
//
|
//
|
||||||
static HICON createIcon(const GLFWimage* image,
|
static HICON createIcon(const GLFWimage* image, int xhot, int yhot, GLFWbool icon)
|
||||||
int xhot, int yhot, GLFWbool icon)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
HDC dc;
|
HDC dc;
|
||||||
@ -194,7 +193,7 @@ static void getFullWindowSize(DWORD style, DWORD exStyle,
|
|||||||
{
|
{
|
||||||
RECT rect = { 0, 0, contentWidth, contentHeight };
|
RECT rect = { 0, 0, contentWidth, contentHeight };
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
|
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
|
||||||
else
|
else
|
||||||
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||||
@ -211,7 +210,7 @@ static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
|
|||||||
UINT dpi = USER_DEFAULT_SCREEN_DPI;
|
UINT dpi = USER_DEFAULT_SCREEN_DPI;
|
||||||
const float ratio = (float) window->numer / (float) window->denom;
|
const float ratio = (float) window->numer / (float) window->denom;
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
dpi = GetDpiForWindow(window->win32.handle);
|
dpi = GetDpiForWindow(window->win32.handle);
|
||||||
|
|
||||||
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
||||||
@ -354,7 +353,7 @@ static void updateWindowStyles(const _GLFWwindow* window)
|
|||||||
|
|
||||||
GetClientRect(window->win32.handle, &rect);
|
GetClientRect(window->win32.handle, &rect);
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
{
|
{
|
||||||
AdjustWindowRectExForDpi(&rect, style, FALSE,
|
AdjustWindowRectExForDpi(&rect, style, FALSE,
|
||||||
getWindowExStyle(window),
|
getWindowExStyle(window),
|
||||||
@ -434,7 +433,7 @@ static int getKeyMods(void)
|
|||||||
static void fitToMonitor(_GLFWwindow* window)
|
static void fitToMonitor(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MONITORINFO mi = { sizeof(mi) };
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
GetMonitorInfo(window->monitor->win32.handle, &mi);
|
GetMonitorInfoW(window->monitor->win32.handle, &mi);
|
||||||
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
||||||
mi.rcMonitor.left,
|
mi.rcMonitor.left,
|
||||||
mi.rcMonitor.top,
|
mi.rcMonitor.top,
|
||||||
@ -453,8 +452,8 @@ static void acquireMonitor(_GLFWwindow* window)
|
|||||||
|
|
||||||
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
||||||
// the OpenGL ICD switches to page flipping
|
// the OpenGL ICD switches to page flipping
|
||||||
SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
|
SystemParametersInfoW(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
|
||||||
SystemParametersInfo(SPI_SETMOUSETRAILS, 0, 0, 0);
|
SystemParametersInfoW(SPI_SETMOUSETRAILS, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window->monitor->window)
|
if (!window->monitor->window)
|
||||||
@ -477,17 +476,66 @@ static void releaseMonitor(_GLFWwindow* window)
|
|||||||
SetThreadExecutionState(ES_CONTINUOUS);
|
SetThreadExecutionState(ES_CONTINUOUS);
|
||||||
|
|
||||||
// HACK: Restore mouse trail length saved in acquireMonitor
|
// HACK: Restore mouse trail length saved in acquireMonitor
|
||||||
SystemParametersInfo(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
|
SystemParametersInfoW(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
_glfwInputMonitorWindow(window->monitor, NULL);
|
||||||
_glfwRestoreVideoModeWin32(window->monitor);
|
_glfwRestoreVideoModeWin32(window->monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manually maximize the window, for when SW_MAXIMIZE cannot be used
|
||||||
|
//
|
||||||
|
static void maximizeWindowManually(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
DWORD style;
|
||||||
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
|
|
||||||
|
GetMonitorInfoW(MonitorFromWindow(window->win32.handle,
|
||||||
|
MONITOR_DEFAULTTONEAREST), &mi);
|
||||||
|
|
||||||
|
rect = mi.rcWork;
|
||||||
|
|
||||||
|
if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
rect.right = _glfw_min(rect.right, rect.left + window->maxwidth);
|
||||||
|
rect.bottom = _glfw_min(rect.bottom, rect.top + window->maxheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
style = GetWindowLongW(window->win32.handle, GWL_STYLE);
|
||||||
|
style |= WS_MAXIMIZE;
|
||||||
|
SetWindowLongW(window->win32.handle, GWL_STYLE, style);
|
||||||
|
|
||||||
|
if (window->decorated)
|
||||||
|
{
|
||||||
|
const DWORD exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||||
|
|
||||||
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
|
{
|
||||||
|
const UINT dpi = GetDpiForWindow(window->win32.handle);
|
||||||
|
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
|
||||||
|
OffsetRect(&rect, 0, GetSystemMetricsForDpi(SM_CYCAPTION, dpi));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||||
|
OffsetRect(&rect, 0, GetSystemMetrics(SM_CYCAPTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.bottom = _glfw_min(rect.bottom, mi.rcWork.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||||
|
rect.left,
|
||||||
|
rect.top,
|
||||||
|
rect.right - rect.left,
|
||||||
|
rect.bottom - rect.top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
// Window callback function (handles window messages)
|
// Window callback function (handles window messages)
|
||||||
//
|
//
|
||||||
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = GetPropW(hWnd, L"GLFW");
|
_GLFWwindow* window = GetPropW(hWnd, L"GLFW");
|
||||||
if (!window)
|
if (!window)
|
||||||
@ -499,7 +547,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
{
|
{
|
||||||
case WM_NCCREATE:
|
case WM_NCCREATE:
|
||||||
{
|
{
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
{
|
{
|
||||||
const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam;
|
const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam;
|
||||||
const _GLFWwndconfig* wndconfig = cs->lpCreateParams;
|
const _GLFWwndconfig* wndconfig = cs->lpCreateParams;
|
||||||
@ -704,6 +752,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
|
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: Alt+PrtSc has a different scancode than just PrtSc
|
||||||
|
if (scancode == 0x54)
|
||||||
|
scancode = 0x137;
|
||||||
|
|
||||||
|
// HACK: Ctrl+Pause has a different scancode than just Pause
|
||||||
|
if (scancode == 0x146)
|
||||||
|
scancode = 0x45;
|
||||||
|
|
||||||
key = _glfw.win32.keycodes[scancode];
|
key = _glfw.win32.keycodes[scancode];
|
||||||
|
|
||||||
// The Ctrl keys require special handling
|
// The Ctrl keys require special handling
|
||||||
@ -1045,7 +1101,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
dpi = GetDpiForWindow(window->win32.handle);
|
dpi = GetDpiForWindow(window->win32.handle);
|
||||||
|
|
||||||
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
||||||
@ -1073,7 +1129,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
ZeroMemory(&mi, sizeof(mi));
|
ZeroMemory(&mi, sizeof(mi));
|
||||||
mi.cbSize = sizeof(mi);
|
mi.cbSize = sizeof(mi);
|
||||||
GetMonitorInfo(mh, &mi);
|
GetMonitorInfoW(mh, &mi);
|
||||||
|
|
||||||
mmi->ptMaxPosition.x = mi.rcWork.left - mi.rcMonitor.left;
|
mmi->ptMaxPosition.x = mi.rcWork.left - mi.rcMonitor.left;
|
||||||
mmi->ptMaxPosition.y = mi.rcWork.top - mi.rcMonitor.top;
|
mmi->ptMaxPosition.y = mi.rcWork.top - mi.rcMonitor.top;
|
||||||
@ -1120,7 +1176,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Adjust the window size to keep the content area size constant
|
// Adjust the window size to keep the content area size constant
|
||||||
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1703OrGreaterWin32())
|
||||||
{
|
{
|
||||||
RECT source = {0}, target = {0};
|
RECT source = {0}, target = {0};
|
||||||
SIZE* size = (SIZE*) lParam;
|
SIZE* size = (SIZE*) lParam;
|
||||||
@ -1151,7 +1207,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
// need it to compensate for non-client area scaling
|
// need it to compensate for non-client area scaling
|
||||||
if (!window->monitor &&
|
if (!window->monitor &&
|
||||||
(window->win32.scaleToMonitor ||
|
(window->win32.scaleToMonitor ||
|
||||||
_glfwIsWindows10CreatorsUpdateOrGreaterWin32()))
|
_glfwIsWindows10Version1703OrGreaterWin32()))
|
||||||
{
|
{
|
||||||
RECT* suggested = (RECT*) lParam;
|
RECT* suggested = (RECT*) lParam;
|
||||||
SetWindowPos(window->win32.handle, HWND_TOP,
|
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||||
@ -1265,7 +1321,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
fullWidth, fullHeight,
|
fullWidth, fullHeight,
|
||||||
NULL, // No parent window
|
NULL, // No parent window
|
||||||
NULL, // No window menu
|
NULL, // No window menu
|
||||||
GetModuleHandleW(NULL),
|
_glfw.win32.instance,
|
||||||
(LPVOID) wndconfig);
|
(LPVOID) wndconfig);
|
||||||
|
|
||||||
_glfw_free(wideTitle);
|
_glfw_free(wideTitle);
|
||||||
@ -1292,18 +1348,22 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
||||||
window->win32.keymenu = wndconfig->win32.keymenu;
|
window->win32.keymenu = wndconfig->win32.keymenu;
|
||||||
|
|
||||||
// Adjust window rect to account for DPI scaling of the window frame and
|
|
||||||
// (if enabled) DPI scaling of the content area
|
|
||||||
// This cannot be done until we know what monitor the window was placed on
|
|
||||||
if (!window->monitor)
|
if (!window->monitor)
|
||||||
{
|
{
|
||||||
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
||||||
WINDOWPLACEMENT wp = { sizeof(wp) };
|
WINDOWPLACEMENT wp = { sizeof(wp) };
|
||||||
|
const HMONITOR mh = MonitorFromWindow(window->win32.handle,
|
||||||
|
MONITOR_DEFAULTTONEAREST);
|
||||||
|
|
||||||
|
// Adjust window rect to account for DPI scaling of the window frame and
|
||||||
|
// (if enabled) DPI scaling of the content area
|
||||||
|
// This cannot be done until we know what monitor the window was placed on
|
||||||
|
// Only update the restored window rect as the window may be maximized
|
||||||
|
|
||||||
if (wndconfig->scaleToMonitor)
|
if (wndconfig->scaleToMonitor)
|
||||||
{
|
{
|
||||||
float xscale, yscale;
|
float xscale, yscale;
|
||||||
_glfwGetWindowContentScaleWin32(window, &xscale, &yscale);
|
_glfwGetHMONITORContentScaleWin32(mh, &xscale, &yscale);
|
||||||
|
|
||||||
if (xscale > 0.f && yscale > 0.f)
|
if (xscale > 0.f && yscale > 0.f)
|
||||||
{
|
{
|
||||||
@ -1312,10 +1372,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
|
||||||
{
|
{
|
||||||
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
|
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
|
||||||
GetDpiForWindow(window->win32.handle));
|
GetDpiForWindow(window->win32.handle));
|
||||||
@ -1323,11 +1380,30 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
else
|
else
|
||||||
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||||
|
|
||||||
// Only update the restored window rect as the window may be maximized
|
|
||||||
GetWindowPlacement(window->win32.handle, &wp);
|
GetWindowPlacement(window->win32.handle, &wp);
|
||||||
|
OffsetRect(&rect,
|
||||||
|
wp.rcNormalPosition.left - rect.left,
|
||||||
|
wp.rcNormalPosition.top - rect.top);
|
||||||
|
|
||||||
wp.rcNormalPosition = rect;
|
wp.rcNormalPosition = rect;
|
||||||
wp.showCmd = SW_HIDE;
|
wp.showCmd = SW_HIDE;
|
||||||
SetWindowPlacement(window->win32.handle, &wp);
|
SetWindowPlacement(window->win32.handle, &wp);
|
||||||
|
|
||||||
|
// Adjust rect of maximized undecorated window, because by default Windows will
|
||||||
|
// make such a window cover the whole monitor instead of its workarea
|
||||||
|
|
||||||
|
if (wndconfig->maximized && !wndconfig->decorated)
|
||||||
|
{
|
||||||
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
|
GetMonitorInfoW(mh, &mi);
|
||||||
|
|
||||||
|
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||||
|
mi.rcWork.left,
|
||||||
|
mi.rcWork.top,
|
||||||
|
mi.rcWork.right - mi.rcWork.left,
|
||||||
|
mi.rcWork.bottom - mi.rcWork.top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DragAcceptFiles(window->win32.handle, TRUE);
|
DragAcceptFiles(window->win32.handle, TRUE);
|
||||||
@ -1353,7 +1429,7 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
|
|||||||
wc.cbSize = sizeof(wc);
|
wc.cbSize = sizeof(wc);
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||||
wc.lpfnWndProc = (WNDPROC) windowProc;
|
wc.lpfnWndProc = (WNDPROC) windowProc;
|
||||||
wc.hInstance = GetModuleHandleW(NULL);
|
wc.hInstance = _glfw.win32.instance;
|
||||||
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
|
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
|
||||||
wc.lpszClassName = _GLFW_WNDCLASSNAME;
|
wc.lpszClassName = _GLFW_WNDCLASSNAME;
|
||||||
|
|
||||||
@ -1383,7 +1459,7 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
|
|||||||
//
|
//
|
||||||
void _glfwUnregisterWindowClassWin32(void)
|
void _glfwUnregisterWindowClassWin32(void)
|
||||||
{
|
{
|
||||||
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
|
UnregisterClassW(_GLFW_WNDCLASSNAME, _glfw.win32.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwCreateWindowWin32(_GLFWwindow* window,
|
int _glfwCreateWindowWin32(_GLFWwindow* window,
|
||||||
@ -1465,8 +1541,7 @@ void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title)
|
|||||||
_glfw_free(wideTitle);
|
_glfw_free(wideTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwSetWindowIconWin32(_GLFWwindow* window,
|
void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images)
|
||||||
int count, const GLFWimage* images)
|
|
||||||
{
|
{
|
||||||
HICON bigIcon = NULL, smallIcon = NULL;
|
HICON bigIcon = NULL, smallIcon = NULL;
|
||||||
|
|
||||||
@ -1488,8 +1563,8 @@ void _glfwSetWindowIconWin32(_GLFWwindow* window,
|
|||||||
smallIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICONSM);
|
smallIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICONSM);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);
|
SendMessageW(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);
|
||||||
SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);
|
SendMessageW(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);
|
||||||
|
|
||||||
if (window->win32.bigIcon)
|
if (window->win32.bigIcon)
|
||||||
DestroyIcon(window->win32.bigIcon);
|
DestroyIcon(window->win32.bigIcon);
|
||||||
@ -1519,7 +1594,7 @@ void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos)
|
|||||||
{
|
{
|
||||||
RECT rect = { xpos, ypos, xpos, ypos };
|
RECT rect = { xpos, ypos, xpos, ypos };
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
{
|
{
|
||||||
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
FALSE, getWindowExStyle(window),
|
FALSE, getWindowExStyle(window),
|
||||||
@ -1560,7 +1635,7 @@ void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height)
|
|||||||
{
|
{
|
||||||
RECT rect = { 0, 0, width, height };
|
RECT rect = { 0, 0, width, height };
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
{
|
{
|
||||||
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
FALSE, getWindowExStyle(window),
|
FALSE, getWindowExStyle(window),
|
||||||
@ -1579,8 +1654,8 @@ void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _glfwSetWindowSizeLimitsWin32(_GLFWwindow* window,
|
void _glfwSetWindowSizeLimitsWin32(_GLFWwindow* window,
|
||||||
int minwidth, int minheight,
|
int minwidth, int minheight,
|
||||||
int maxwidth, int maxheight)
|
int maxwidth, int maxheight)
|
||||||
{
|
{
|
||||||
RECT area;
|
RECT area;
|
||||||
|
|
||||||
@ -1618,8 +1693,8 @@ void _glfwGetFramebufferSizeWin32(_GLFWwindow* window, int* width, int* height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window,
|
void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window,
|
||||||
int* left, int* top,
|
int* left, int* top,
|
||||||
int* right, int* bottom)
|
int* right, int* bottom)
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
int width, height;
|
int width, height;
|
||||||
@ -1627,7 +1702,7 @@ void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window,
|
|||||||
_glfwGetWindowSizeWin32(window, &width, &height);
|
_glfwGetWindowSizeWin32(window, &width, &height);
|
||||||
SetRect(&rect, 0, 0, width, height);
|
SetRect(&rect, 0, 0, width, height);
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
{
|
{
|
||||||
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
FALSE, getWindowExStyle(window),
|
FALSE, getWindowExStyle(window),
|
||||||
@ -1668,7 +1743,10 @@ void _glfwRestoreWindowWin32(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwMaximizeWindowWin32(_GLFWwindow* window)
|
void _glfwMaximizeWindowWin32(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
ShowWindow(window->win32.handle, SW_MAXIMIZE);
|
if (IsWindowVisible(window->win32.handle))
|
||||||
|
ShowWindow(window->win32.handle, SW_MAXIMIZE);
|
||||||
|
else
|
||||||
|
maximizeWindowManually(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwShowWindowWin32(_GLFWwindow* window)
|
void _glfwShowWindowWin32(_GLFWwindow* window)
|
||||||
@ -1713,7 +1791,7 @@ void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
RECT rect = { xpos, ypos, xpos + width, ypos + height };
|
RECT rect = { xpos, ypos, xpos + width, ypos + height };
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
{
|
{
|
||||||
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
FALSE, getWindowExStyle(window),
|
FALSE, getWindowExStyle(window),
|
||||||
@ -1755,7 +1833,7 @@ void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
|
|||||||
|
|
||||||
acquireMonitor(window);
|
acquireMonitor(window);
|
||||||
|
|
||||||
GetMonitorInfo(window->monitor->win32.handle, &mi);
|
GetMonitorInfoW(window->monitor->win32.handle, &mi);
|
||||||
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
||||||
mi.rcMonitor.left,
|
mi.rcMonitor.left,
|
||||||
mi.rcMonitor.top,
|
mi.rcMonitor.top,
|
||||||
@ -1784,7 +1862,7 @@ void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
|
|||||||
else
|
else
|
||||||
after = HWND_NOTOPMOST;
|
after = HWND_NOTOPMOST;
|
||||||
|
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
if (_glfwIsWindows10Version1607OrGreaterWin32())
|
||||||
{
|
{
|
||||||
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
FALSE, getWindowExStyle(window),
|
FALSE, getWindowExStyle(window),
|
||||||
@ -2052,7 +2130,7 @@ void _glfwWaitEventsTimeoutWin32(double timeout)
|
|||||||
|
|
||||||
void _glfwPostEmptyEventWin32(void)
|
void _glfwPostEmptyEventWin32(void)
|
||||||
{
|
{
|
||||||
PostMessage(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0);
|
PostMessageW(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos)
|
void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos)
|
||||||
@ -2113,8 +2191,8 @@ int _glfwGetKeyScancodeWin32(int key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int _glfwCreateCursorWin32(_GLFWcursor* cursor,
|
int _glfwCreateCursorWin32(_GLFWcursor* cursor,
|
||||||
const GLFWimage* image,
|
const GLFWimage* image,
|
||||||
int xhot, int yhot)
|
int xhot, int yhot)
|
||||||
{
|
{
|
||||||
cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE);
|
cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE);
|
||||||
if (!cursor->win32.handle)
|
if (!cursor->win32.handle)
|
||||||
@ -2369,7 +2447,7 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance,
|
|||||||
|
|
||||||
memset(&sci, 0, sizeof(sci));
|
memset(&sci, 0, sizeof(sci));
|
||||||
sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
sci.hinstance = GetModuleHandle(NULL);
|
sci.hinstance = _glfw.win32.instance;
|
||||||
sci.hwnd = window->win32.handle;
|
sci.hwnd = window->win32.handle;
|
||||||
|
|
||||||
err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
|
err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
|
||||||
|
21
src/window.c
21
src/window.c
@ -514,12 +514,33 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
|
|||||||
GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
|
GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
|
||||||
int count, const GLFWimage* images)
|
int count, const GLFWimage* images)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
assert(count >= 0);
|
assert(count >= 0);
|
||||||
assert(count == 0 || images != NULL);
|
assert(count == 0 || images != NULL);
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
if (count < 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
assert(images[i].pixels != NULL);
|
||||||
|
|
||||||
|
if (images[i].width <= 0 || images[i].height <= 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Invalid image dimensions for window icon");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_glfw.platform.setWindowIcon(window, count, images);
|
_glfw.platform.setWindowIcon(window, count, images);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +57,6 @@
|
|||||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol-code.h"
|
#include "wayland-idle-inhibit-unstable-v1-client-protocol-code.h"
|
||||||
|
|
||||||
|
|
||||||
static inline int min(int n1, int n2)
|
|
||||||
{
|
|
||||||
return n1 < n2 ? n1 : n2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||||
int* which)
|
int* which)
|
||||||
{
|
{
|
||||||
@ -788,7 +783,7 @@ static void registryHandleGlobal(void* data,
|
|||||||
{
|
{
|
||||||
if (strcmp(interface, "wl_compositor") == 0)
|
if (strcmp(interface, "wl_compositor") == 0)
|
||||||
{
|
{
|
||||||
_glfw.wl.compositorVersion = min(3, version);
|
_glfw.wl.compositorVersion = _glfw_min(3, version);
|
||||||
_glfw.wl.compositor =
|
_glfw.wl.compositor =
|
||||||
wl_registry_bind(registry, name, &wl_compositor_interface,
|
wl_registry_bind(registry, name, &wl_compositor_interface,
|
||||||
_glfw.wl.compositorVersion);
|
_glfw.wl.compositorVersion);
|
||||||
@ -811,7 +806,7 @@ static void registryHandleGlobal(void* data,
|
|||||||
{
|
{
|
||||||
if (!_glfw.wl.seat)
|
if (!_glfw.wl.seat)
|
||||||
{
|
{
|
||||||
_glfw.wl.seatVersion = min(4, version);
|
_glfw.wl.seatVersion = _glfw_min(4, version);
|
||||||
_glfw.wl.seat =
|
_glfw.wl.seat =
|
||||||
wl_registry_bind(registry, name, &wl_seat_interface,
|
wl_registry_bind(registry, name, &wl_seat_interface,
|
||||||
_glfw.wl.seatVersion);
|
_glfw.wl.seatVersion);
|
||||||
@ -1367,14 +1362,15 @@ int _glfwInitWayland(void)
|
|||||||
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
|
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
|
||||||
_glfw.wl.seat);
|
_glfw.wl.seat);
|
||||||
wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
|
wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
|
||||||
_glfw.wl.clipboardString = _glfw_calloc(4096, 1);
|
|
||||||
|
_glfw.wl.clipboardSize = 4096;
|
||||||
|
_glfw.wl.clipboardString = _glfw_calloc(_glfw.wl.clipboardSize, 1);
|
||||||
if (!_glfw.wl.clipboardString)
|
if (!_glfw.wl.clipboardString)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_OUT_OF_MEMORY,
|
||||||
"Wayland: Unable to allocate clipboard memory");
|
"Wayland: Unable to allocate clipboard memory");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
_glfw.wl.clipboardSize = 4096;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -1460,9 +1456,7 @@ void _glfwTerminateWayland(void)
|
|||||||
if (_glfw.wl.cursorTimerfd >= 0)
|
if (_glfw.wl.cursorTimerfd >= 0)
|
||||||
close(_glfw.wl.cursorTimerfd);
|
close(_glfw.wl.cursorTimerfd);
|
||||||
|
|
||||||
if (_glfw.wl.clipboardString)
|
_glfw_free(_glfw.wl.clipboardString);
|
||||||
_glfw_free(_glfw.wl.clipboardString);
|
_glfw_free(_glfw.wl.clipboardSendString);
|
||||||
if (_glfw.wl.clipboardSendString)
|
|
||||||
_glfw_free(_glfw.wl.clipboardSendString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWa
|
|||||||
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
|
||||||
|
|
||||||
#include "xkb_unicode.h"
|
#include "xkb_unicode.h"
|
||||||
|
#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);
|
||||||
|
102
src/wl_window.c
102
src/wl_window.c
@ -345,26 +345,21 @@ static void resizeWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void checkScaleChange(_GLFWwindow* window)
|
static void checkScaleChange(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
int scale = 1;
|
|
||||||
int monitorScale;
|
|
||||||
|
|
||||||
// Check if we will be able to set the buffer scale or not.
|
// Check if we will be able to set the buffer scale or not.
|
||||||
if (_glfw.wl.compositorVersion < 3)
|
if (_glfw.wl.compositorVersion < 3)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get the scale factor from the highest scale monitor.
|
// Get the scale factor from the highest scale monitor.
|
||||||
for (int i = 0; i < window->wl.monitorsCount; ++i)
|
int maxScale = 1;
|
||||||
{
|
|
||||||
monitorScale = window->wl.monitors[i]->wl.scale;
|
for (int i = 0; i < window->wl.monitorsCount; i++)
|
||||||
if (scale < monitorScale)
|
maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale);
|
||||||
scale = monitorScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only change the framebuffer size if the scale changed.
|
// Only change the framebuffer size if the scale changed.
|
||||||
if (scale != window->wl.scale)
|
if (window->wl.scale != maxScale)
|
||||||
{
|
{
|
||||||
window->wl.scale = scale;
|
window->wl.scale = maxScale;
|
||||||
wl_surface_set_buffer_scale(window->wl.surface, scale);
|
wl_surface_set_buffer_scale(window->wl.surface, maxScale);
|
||||||
resizeWindow(window);
|
resizeWindow(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -717,8 +712,28 @@ static void incrementCursorImage(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleEvents(int timeout)
|
static GLFWbool flushDisplay(void)
|
||||||
{
|
{
|
||||||
|
while (wl_display_flush(_glfw.wl.display) == -1)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
struct pollfd fd = { wl_display_get_fd(_glfw.wl.display), POLLOUT };
|
||||||
|
|
||||||
|
while (poll(&fd, 1, -1) == -1)
|
||||||
|
{
|
||||||
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleEvents(double* timeout)
|
||||||
|
{
|
||||||
|
GLFWbool event = GLFW_FALSE;
|
||||||
struct pollfd fds[] =
|
struct pollfd fds[] =
|
||||||
{
|
{
|
||||||
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
||||||
@ -726,30 +741,38 @@ static void handleEvents(int timeout)
|
|||||||
{ _glfw.wl.cursorTimerfd, POLLIN },
|
{ _glfw.wl.cursorTimerfd, POLLIN },
|
||||||
};
|
};
|
||||||
|
|
||||||
while (wl_display_prepare_read(_glfw.wl.display) != 0)
|
while (!event)
|
||||||
wl_display_dispatch_pending(_glfw.wl.display);
|
|
||||||
|
|
||||||
// If an error other than EAGAIN happens, we have likely been disconnected
|
|
||||||
// from the Wayland session; try to handle that the best we can.
|
|
||||||
if (wl_display_flush(_glfw.wl.display) < 0 && errno != EAGAIN)
|
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.windowListHead;
|
while (wl_display_prepare_read(_glfw.wl.display) != 0)
|
||||||
while (window)
|
wl_display_dispatch_pending(_glfw.wl.display);
|
||||||
|
|
||||||
|
// If an error other than EAGAIN happens, we have likely been disconnected
|
||||||
|
// from the Wayland session; try to handle that the best we can.
|
||||||
|
if (!flushDisplay())
|
||||||
{
|
{
|
||||||
_glfwInputWindowCloseRequest(window);
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
window = window->next;
|
|
||||||
|
_GLFWwindow* window = _glfw.windowListHead;
|
||||||
|
while (window)
|
||||||
|
{
|
||||||
|
_glfwInputWindowCloseRequest(window);
|
||||||
|
window = window->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_display_cancel_read(_glfw.wl.display);
|
if (!_glfwPollPOSIX(fds, 3, timeout))
|
||||||
return;
|
{
|
||||||
}
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (poll(fds, 3, timeout) > 0)
|
|
||||||
{
|
|
||||||
if (fds[0].revents & POLLIN)
|
if (fds[0].revents & POLLIN)
|
||||||
{
|
{
|
||||||
wl_display_read_events(_glfw.wl.display);
|
wl_display_read_events(_glfw.wl.display);
|
||||||
wl_display_dispatch_pending(_glfw.wl.display);
|
if (wl_display_dispatch_pending(_glfw.wl.display) > 0)
|
||||||
|
event = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wl_display_cancel_read(_glfw.wl.display);
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
@ -770,6 +793,8 @@ static void handleEvents(int timeout)
|
|||||||
_glfwInputTextWayland(_glfw.wl.keyboardFocus,
|
_glfwInputTextWayland(_glfw.wl.keyboardFocus,
|
||||||
_glfw.wl.keyboardLastScancode);
|
_glfw.wl.keyboardLastScancode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,11 +803,12 @@ static void handleEvents(int 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(_glfw.wl.pointerFocus);
|
||||||
|
event = GLFW_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
wl_display_cancel_read(_glfw.wl.display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -1149,22 +1175,24 @@ GLFWbool _glfwRawMouseMotionSupportedWayland(void)
|
|||||||
|
|
||||||
void _glfwPollEventsWayland(void)
|
void _glfwPollEventsWayland(void)
|
||||||
{
|
{
|
||||||
handleEvents(0);
|
double timeout = 0.0;
|
||||||
|
handleEvents(&timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwWaitEventsWayland(void)
|
void _glfwWaitEventsWayland(void)
|
||||||
{
|
{
|
||||||
handleEvents(-1);
|
handleEvents(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwWaitEventsTimeoutWayland(double timeout)
|
void _glfwWaitEventsTimeoutWayland(double timeout)
|
||||||
{
|
{
|
||||||
handleEvents((int) (timeout * 1e3));
|
handleEvents(&timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPostEmptyEventWayland(void)
|
void _glfwPostEmptyEventWayland(void)
|
||||||
{
|
{
|
||||||
wl_display_sync(_glfw.wl.display);
|
wl_display_sync(_glfw.wl.display);
|
||||||
|
flushDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos)
|
void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos)
|
||||||
@ -1675,7 +1703,7 @@ static GLFWbool growClipboardString(void)
|
|||||||
clipboard = _glfw_realloc(clipboard, _glfw.wl.clipboardSize * 2);
|
clipboard = _glfw_realloc(clipboard, _glfw.wl.clipboardSize * 2);
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_OUT_OF_MEMORY,
|
||||||
"Wayland: Impossible to grow clipboard string");
|
"Wayland: Impossible to grow clipboard string");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@ -1710,9 +1738,9 @@ const char* _glfwGetClipboardStringWayland(void)
|
|||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
|
|
||||||
// XXX: this is a huge hack, this function shouldn’t be synchronous!
|
// XXX: this is a huge hack, this function shouldn’t be synchronous!
|
||||||
handleEvents(-1);
|
handleEvents(NULL);
|
||||||
|
|
||||||
while (1)
|
for (;;)
|
||||||
{
|
{
|
||||||
// Grow the clipboard if we need to paste something bigger, there is no
|
// Grow the clipboard if we need to paste something bigger, there is no
|
||||||
// shrink operation yet.
|
// shrink operation yet.
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
// Translate the X11 KeySyms for a key to a GLFW key code
|
// Translate the X11 KeySyms for a key to a GLFW key code
|
||||||
@ -601,7 +603,7 @@ static void detectEWMH(void)
|
|||||||
//
|
//
|
||||||
static GLFWbool initExtensions(void)
|
static GLFWbool initExtensions(void)
|
||||||
{
|
{
|
||||||
#if defined(__OpenBSD__)
|
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so");
|
_glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so.1");
|
_glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so.1");
|
||||||
@ -625,7 +627,7 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi-6.so");
|
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi-6.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so");
|
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so.6");
|
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so.6");
|
||||||
@ -657,7 +659,7 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr-2.so");
|
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr-2.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so");
|
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so.2");
|
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so.2");
|
||||||
@ -751,7 +753,7 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor-1.so");
|
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor-1.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so");
|
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so.1");
|
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so.1");
|
||||||
@ -774,7 +776,7 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama-1.so");
|
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama-1.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so");
|
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so.1");
|
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so.1");
|
||||||
@ -829,7 +831,7 @@ static GLFWbool initExtensions(void)
|
|||||||
{
|
{
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb-1.so");
|
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb-1.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so");
|
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so.1");
|
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so.1");
|
||||||
@ -844,7 +846,7 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender-1.so");
|
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender-1.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so");
|
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so.1");
|
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so.1");
|
||||||
@ -873,7 +875,7 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext-6.so");
|
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext-6.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so");
|
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so");
|
||||||
#else
|
#else
|
||||||
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so.6");
|
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so.6");
|
||||||
@ -1042,6 +1044,37 @@ static Window createHelperWindow(void)
|
|||||||
CWEventMask, &wa);
|
CWEventMask, &wa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the pipe for empty events without assumuing the OS has pipe2(2)
|
||||||
|
//
|
||||||
|
static GLFWbool createEmptyEventPipe(void)
|
||||||
|
{
|
||||||
|
if (pipe(_glfw.x11.emptyEventPipe) != 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to create empty event pipe: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
const int sf = fcntl(_glfw.x11.emptyEventPipe[i], F_GETFL, 0);
|
||||||
|
const int df = fcntl(_glfw.x11.emptyEventPipe[i], F_GETFD, 0);
|
||||||
|
|
||||||
|
if (sf == -1 || df == -1 ||
|
||||||
|
fcntl(_glfw.x11.emptyEventPipe[i], F_SETFL, sf | O_NONBLOCK) == -1 ||
|
||||||
|
fcntl(_glfw.x11.emptyEventPipe[i], F_SETFD, df | FD_CLOEXEC) == -1)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to set flags for empty event pipe: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// X error handler
|
// X error handler
|
||||||
//
|
//
|
||||||
static int errorHandler(Display *display, XErrorEvent* event)
|
static int errorHandler(Display *display, XErrorEvent* event)
|
||||||
@ -1221,7 +1254,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
|||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
void* module = _glfwPlatformLoadModule("libX11-6.so");
|
void* module = _glfwPlatformLoadModule("libX11-6.so");
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
void* module = _glfwPlatformLoadModule("libX11.so");
|
void* module = _glfwPlatformLoadModule("libX11.so");
|
||||||
#else
|
#else
|
||||||
void* module = _glfwPlatformLoadModule("libX11.so.6");
|
void* module = _glfwPlatformLoadModule("libX11.so.6");
|
||||||
@ -1491,6 +1524,9 @@ int _glfwInitX11(void)
|
|||||||
|
|
||||||
getSystemContentScale(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY);
|
getSystemContentScale(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY);
|
||||||
|
|
||||||
|
if (!createEmptyEventPipe())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!initExtensions())
|
if (!initExtensions())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
@ -1604,5 +1640,11 @@ void _glfwTerminateX11(void)
|
|||||||
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
|
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
|
||||||
_glfw.x11.xlib.handle = NULL;
|
_glfw.x11.xlib.handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_glfw.x11.emptyEventPipe[0] || _glfw.x11.emptyEventPipe[1])
|
||||||
|
{
|
||||||
|
close(_glfw.x11.emptyEventPipe[0]);
|
||||||
|
close(_glfw.x11.emptyEventPipe[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,6 +453,7 @@ typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSur
|
|||||||
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 "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;
|
||||||
@ -582,6 +583,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
double restoreCursorPosX, restoreCursorPosY;
|
double restoreCursorPosX, restoreCursorPosY;
|
||||||
// The window whose disabled cursor mode is active
|
// The window whose disabled cursor mode is active
|
||||||
_GLFWwindow* disabledCursorWindow;
|
_GLFWwindow* disabledCursorWindow;
|
||||||
|
int emptyEventPipe[2];
|
||||||
|
|
||||||
// Window manager atoms
|
// Window manager atoms
|
||||||
Atom NET_SUPPORTED;
|
Atom NET_SUPPORTED;
|
||||||
|
134
src/x11_window.c
134
src/x11_window.c
@ -32,7 +32,7 @@
|
|||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/Xmd.h>
|
#include <X11/Xmd.h>
|
||||||
|
|
||||||
#include <sys/select.h>
|
#include <poll.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -56,50 +56,79 @@
|
|||||||
|
|
||||||
#define _GLFW_XDND_VERSION 5
|
#define _GLFW_XDND_VERSION 5
|
||||||
|
|
||||||
|
// Wait for event data to arrive on the X11 display socket
|
||||||
// Wait for data to arrive using select
|
|
||||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||||
// covers GLX functions
|
// covers GLX functions
|
||||||
//
|
//
|
||||||
static GLFWbool waitForEvent(double* timeout)
|
static GLFWbool waitForX11Event(double* timeout)
|
||||||
{
|
{
|
||||||
fd_set fds;
|
struct pollfd fd = { ConnectionNumber(_glfw.x11.display), POLLIN };
|
||||||
const int fd = ConnectionNumber(_glfw.x11.display);
|
|
||||||
int count = fd + 1;
|
while (!XPending(_glfw.x11.display))
|
||||||
|
{
|
||||||
|
if (!_glfwPollPOSIX(&fd, 1, timeout))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for event data to arrive on any event file descriptor
|
||||||
|
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||||
|
// covers GLX functions
|
||||||
|
//
|
||||||
|
static GLFWbool waitForAnyEvent(double* timeout)
|
||||||
|
{
|
||||||
|
nfds_t count = 2;
|
||||||
|
struct pollfd fds[3] =
|
||||||
|
{
|
||||||
|
{ ConnectionNumber(_glfw.x11.display), POLLIN },
|
||||||
|
{ _glfw.x11.emptyEventPipe[0], POLLIN }
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if (_glfw.linjs.inotify > fd)
|
if (_glfw.joysticksInitialized)
|
||||||
count = _glfw.linjs.inotify + 1;
|
fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
while (!XPending(_glfw.x11.display))
|
||||||
|
{
|
||||||
|
if (!_glfwPollPOSIX(fds, count, timeout))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
for (int i = 1; i < count; i++)
|
||||||
|
{
|
||||||
|
if (fds[i].revents & POLLIN)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes a byte to the empty event pipe
|
||||||
|
//
|
||||||
|
static void writeEmptyEvent(void)
|
||||||
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
FD_ZERO(&fds);
|
const char byte = 0;
|
||||||
FD_SET(fd, &fds);
|
const int result = write(_glfw.x11.emptyEventPipe[1], &byte, 1);
|
||||||
#if defined(__linux__)
|
if (result == 1 || (result == -1 && errno != EINTR))
|
||||||
if (_glfw.linjs.inotify > 0)
|
break;
|
||||||
FD_SET(_glfw.linjs.inotify, &fds);
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (timeout)
|
// Drains available data from the empty event pipe
|
||||||
{
|
//
|
||||||
const long seconds = (long) *timeout;
|
static void drainEmptyEvents(void)
|
||||||
const long microseconds = (long) ((*timeout - seconds) * 1e6);
|
{
|
||||||
struct timeval tv = { seconds, microseconds };
|
for (;;)
|
||||||
const uint64_t base = _glfwPlatformGetTimerValue();
|
{
|
||||||
|
char dummy[64];
|
||||||
const int result = select(count, &fds, NULL, NULL, &tv);
|
const int result = read(_glfw.x11.emptyEventPipe[0], dummy, sizeof(dummy));
|
||||||
const int error = errno;
|
if (result == -1 && errno != EINTR)
|
||||||
|
break;
|
||||||
*timeout -= (_glfwPlatformGetTimerValue() - base) /
|
|
||||||
(double) _glfwPlatformGetTimerFrequency();
|
|
||||||
|
|
||||||
if (result > 0)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
if ((result == -1 && error == EINTR) || *timeout <= 0.0)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +145,7 @@ static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
|
|||||||
VisibilityNotify,
|
VisibilityNotify,
|
||||||
&dummy))
|
&dummy))
|
||||||
{
|
{
|
||||||
if (!waitForEvent(&timeout))
|
if (!waitForX11Event(&timeout))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,7 +987,7 @@ static const char* getSelectionString(Atom selection)
|
|||||||
SelectionNotify,
|
SelectionNotify,
|
||||||
¬ification))
|
¬ification))
|
||||||
{
|
{
|
||||||
waitForEvent(NULL);
|
waitForX11Event(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.xselection.property == None)
|
if (notification.xselection.property == None)
|
||||||
@ -994,7 +1023,7 @@ static const char* getSelectionString(Atom selection)
|
|||||||
isSelPropNewValueNotify,
|
isSelPropNewValueNotify,
|
||||||
(XPointer) ¬ification))
|
(XPointer) ¬ification))
|
||||||
{
|
{
|
||||||
waitForEvent(NULL);
|
waitForX11Event(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree(data);
|
XFree(data);
|
||||||
@ -1238,7 +1267,7 @@ static void processEvent(XEvent *event)
|
|||||||
// (the server never sends a timestamp of zero)
|
// (the server never sends a timestamp of zero)
|
||||||
// NOTE: Timestamp difference is compared to handle wrap-around
|
// NOTE: Timestamp difference is compared to handle wrap-around
|
||||||
Time diff = event->xkey.time - window->x11.keyPressTimes[keycode];
|
Time diff = event->xkey.time - window->x11.keyPressTimes[keycode];
|
||||||
if (diff == event->xkey.time || (diff > 0 && diff < (1 << 31)))
|
if (diff == event->xkey.time || (diff > 0 && diff < ((Time)1 << 31)))
|
||||||
{
|
{
|
||||||
if (keycode)
|
if (keycode)
|
||||||
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
||||||
@ -1896,7 +1925,7 @@ void _glfwPushSelectionToManagerX11(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForEvent(NULL);
|
waitForX11Event(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2238,7 +2267,7 @@ void _glfwGetWindowFrameSizeX11(_GLFWwindow* window,
|
|||||||
isFrameExtentsEvent,
|
isFrameExtentsEvent,
|
||||||
(XPointer) window))
|
(XPointer) window))
|
||||||
{
|
{
|
||||||
if (!waitForEvent(&timeout))
|
if (!waitForX11Event(&timeout))
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
|
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
|
||||||
@ -2744,7 +2773,7 @@ GLFWbool _glfwRawMouseMotionSupportedX11(void)
|
|||||||
|
|
||||||
void _glfwPollEventsX11(void)
|
void _glfwPollEventsX11(void)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window;
|
drainEmptyEvents();
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if (_glfw.joysticksInitialized)
|
if (_glfw.joysticksInitialized)
|
||||||
@ -2759,7 +2788,7 @@ void _glfwPollEventsX11(void)
|
|||||||
processEvent(&event);
|
processEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
window = _glfw.x11.disabledCursorWindow;
|
_GLFWwindow* window = _glfw.x11.disabledCursorWindow;
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
@ -2779,32 +2808,19 @@ void _glfwPollEventsX11(void)
|
|||||||
|
|
||||||
void _glfwWaitEventsX11(void)
|
void _glfwWaitEventsX11(void)
|
||||||
{
|
{
|
||||||
while (!XPending(_glfw.x11.display))
|
waitForAnyEvent(NULL);
|
||||||
waitForEvent(NULL);
|
|
||||||
|
|
||||||
_glfwPollEventsX11();
|
_glfwPollEventsX11();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwWaitEventsTimeoutX11(double timeout)
|
void _glfwWaitEventsTimeoutX11(double timeout)
|
||||||
{
|
{
|
||||||
while (!XPending(_glfw.x11.display))
|
waitForAnyEvent(&timeout);
|
||||||
{
|
|
||||||
if (!waitForEvent(&timeout))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwPollEventsX11();
|
_glfwPollEventsX11();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPostEmptyEventX11(void)
|
void _glfwPostEmptyEventX11(void)
|
||||||
{
|
{
|
||||||
XEvent event = { ClientMessage };
|
writeEmptyEvent();
|
||||||
event.xclient.window = _glfw.x11.helperWindowHandle;
|
|
||||||
event.xclient.format = 32; // Data is 32-bit longs
|
|
||||||
event.xclient.message_type = _glfw.x11.NULL_;
|
|
||||||
|
|
||||||
XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event);
|
|
||||||
XFlush(_glfw.x11.display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwGetCursorPosX11(_GLFWwindow* window, double* xpos, double* ypos)
|
void _glfwGetCursorPosX11(_GLFWwindow* window, double* xpos, double* ypos)
|
||||||
|
Loading…
Reference in New Issue
Block a user