Compare commits

...

136 Commits

Author SHA1 Message Date
Camilla Löwy e91fa399f1 Merge branch 'latest' into new-cursors-on-3.3-stable 2024-02-23 12:47:46 +01:00
Camilla Löwy dc46d3f812 Remove reference to stale Coverity result
(cherry picked from commit 421dc66afb)
2024-02-20 23:50:30 +01:00
Camilla Löwy 07efe9068e Improved build guide slightly
This was adapted to 3.3-stable from
b864e4baeb.
2024-02-20 23:50:30 +01:00
Camilla Löwy 3af1a1f514 NSGL: ANGLE exists
(cherry picked from commit 8f2f766f0d)
2024-02-20 23:50:30 +01:00
Camilla Löwy a7c3e95980 Fix bad merge
This regression was introduced by
2d51e650be.
2024-02-20 23:50:30 +01:00
Camilla Löwy 0cac1ad41f Fix spelling
This was adapted to 3.3-stable from
5a0ab56ed7.
2024-02-14 23:31:36 +01:00
Camilla Löwy 2d51e650be Document GLFW_FLOATING not supported on Wayland
(cherry picked from commit 12043e72189d80ef7574c2ea8fb8190288db6be7)
2024-02-05 16:25:27 +01:00
Camilla Löwy bc788a9333 WGL: Fix pixel format count in a Parallels VM
In a Parallels VM wglGetPixelFormatAttribivARB returns fewer pixel
formats than DescribePixelFormat.  This broke context creation on
Windows in Parallels since the changes in
2c0f34b60f.  The previous version of the
code worked accidentally.

This adds a workaround by iterating through the minimum of both counts.
It should have no effect when running on conforming implementations.

Tested on Parallels by @ dougbinks.

Closes #2191
Fixes #2406
Fixes #2467

This was adapted to 3.3-stable from
00e86d4b73.
2024-02-05 16:25:27 +01:00
Camilla Löwy ae44e10b33 Fix function return value when uninitialized
(cherry picked from commit d7aeb1eae8)
2024-02-05 16:25:27 +01:00
Camilla Löwy 438cd224d7 Fix function return value when uninitialized
(cherry picked from commit f74ff2aa10)
2024-02-05 16:25:27 +01:00
Camilla Löwy 8d95aeac69 Remove further traces of IRC channel
(cherry picked from commit 23962c9dc7)
2024-02-05 16:25:27 +01:00
Camilla Löwy a1090c867d Wayland: Fix compilation on FreeBSD
The list of compile-time dependencies on FreeBSD lacked evdev-proto.

Unlike on Linux, the input-event-codes.h header file was not implicitly
included on FreeBSD.

Fixes #2445

This was adapted to 3.3-stable from
51920ede68.
2024-02-05 16:25:27 +01:00
Camilla Löwy 15b771759d OSMesa: Fix headers included before shared header
The shared header, internal.h, must be the first header included in
every compilation unit of GLFW.

(cherry picked from commit 291f4d89cd)
2024-02-05 16:25:27 +01:00
Bruce Mitchener d172fec64b Update to actions/checkout@v4 from v3
This mainly updates the version of NodeJS used internally to keep
up with what's going on at GitHub Actions.

Closes #2447

This was adapted to 3.3-stable from
becf1dc14b.
2024-02-05 16:25:27 +01:00
Camilla Löwy bfa24c9f2d Fix glfwGetKeyName incorrectly emitting error
glfwGetKeyName emitted GLFW_INVALID_VALUE when passed GLFW_KEY_UNKNOWN
and any scancode not associated with a key token on that platform.

This causes physical keys with no associated key token to emit
GLFW_INVALID_VALUE when the key and scancode are passed directly from
the key event to glfwGetKeyName.  This breaks the promise made in the
reference documentation for glfwGetKeyName.

This commit removes that error for the whole range of valid scancodes.

Fixes #1785
Fixes #2214

This was adapted to 3.3-stable from
86bf5698ec.
2024-02-05 16:25:27 +01:00
Camilla Löwy 20bd0329a5 Clarify event test reporting of keys
Reshuffled line to group key-related items together.  Omitted key code
output for unknown keys to put focus on the (lack of) name.

(cherry picked from commit d81fcb93f1)
2024-02-05 16:25:27 +01:00
Camilla Löwy fafcba3824 Wayland: Clean up pointer axis handler
(cherry picked from commit 9afbcb442b)
2024-02-05 16:25:27 +01:00
Camilla Löwy 7554375d6d Update CODEOWNERS file
(cherry picked from commit cf29ff2b9d)
2024-02-02 13:27:42 +01:00
Camilla Löwy dbe2d7cb4a Set timeout for build GH workflow jobs
This is in order to catch and stop any malfunctioning job.

This was adapted to 3.3-stable from
d5461d2927ac712ded603f7f133f18e9a02caeb4.
2024-02-02 13:26:50 +01:00
Camilla Löwy 76227fa519 Fix missing error in docs for glfwCreateWindow
The GLFW_NO_WINDOW_CONTEXT error can be emitted if the window passed in
for context sharing does not have a context.

Fixes #2456

(cherry picked from commit 73948e6c0f)
2024-01-14 23:57:45 +01:00
Camilla Löwy 0161cde6f3 Add build- prefix to .gitignore
(cherry picked from commit 5a9ea8f99f)
2024-01-14 23:57:44 +01:00
Camilla Löwy c710d2c05d Wayland: Fix segfault on termination
A segfault could occur during termination if libdecor was found but no
windows were created between initialization and termination.  The wait
for libdecor to finish its initialization was only performed before
window creation, not at termination.

Regression introduced by 9fdc425931.

This was adapted to 3.3-stable from
4e8c4901e9.
2024-01-14 23:57:44 +01:00
Camilla Löwy a943d9ac17 Add credit
I lost track of the existing PR #2254 when fixing #2161 with
5e4496cb42.

Closes #2254

(cherry picked from commit ab09dc8fb1)
2024-01-14 23:57:44 +01:00
Camilla Löwy 7998629ad2 Linux: Fix regfree being called on invalid data
This was caused by a careless merge that did not take the differences
between the branches into account.

Regression introduced by 7c7cc59889.

Fixes #2464
2024-01-14 23:56:09 +01:00
Camilla Löwy 9ba47ca13a Start 3.3.10 2024-01-14 23:27:14 +01:00
Camilla Löwy dd288eabf6 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2023-12-12 23:03:54 +01:00
Camilla Löwy e2c9264546 Update changelog
These are changes since the release of 3.3.8 but not since 3.3, and
mistakenly did not get changelog entries when merged to 3.3-stable.
2023-12-12 19:00:27 +01:00
Camilla Löwy 7b60753aeb Cocoa: Fix segfault querying joystick elements
It is reportedly possible for IOHIDDeviceCopyMatchingElements to return
NULL on macOS 13 if the application lacks input monitoring permissions.

This commit only prevents the segfault.  More work will be needed to
correctly handle this situation, including Game Controller support.

Related to #2320
Closes #2321

(cherry picked from commit 2c1d31009f)
2023-12-12 18:48:53 +01:00
Camilla Löwy 628385e99e Update changelog and add credit
Related to #2348

(cherry picked from commit ea3ea62708)
2023-12-12 16:06:10 +01:00
lo-v-ol 217c269d66 EGL: Fix GLFW_CONTEXT_NO_ERROR on Mesa
Mesa EGL requires the context version to be set to 2.0 or greater before
EGL_CONTEXT_OPENGL_NO_ERROR_KHR in the attribute list.

Without this, context creation via Mesa EGL with
EGL_CONTEXT_OPENGL_NO_ERROR_KHR set fails with EGL_BAD_ATTRIBUTE.

Fixes #2348

(cherry picked from commit eeeb56eb23)
2023-12-12 16:04:57 +01:00
Camilla Löwy 6ea5bf9032 Fix Markdown formatting for changelog entry
(cherry picked from commit 378e5fc814)
2023-12-12 16:03:37 +01:00
Camilla Löwy 1fab407e44 Update changelog and add credit
Related to #2377
Related to #2405

This was adapted to 3.3-stable from
7b152019da.
2023-12-12 16:02:47 +01:00
FuzzyQuills 7cdd41170b Cocoa: No NSWindowStyleMaskResizable in fullscreen
On macOS 10.15 Catalina and earlier, not having the resizable bit
cleared in NSWindowStyleMask in fullscreen leads to windows minimising
when clicked anywhere in the content area.

On all tested macOS versions it also causes the fullscreen window to be
resizable by the user.

Regression introduced by 0d599026d0.

Fixes #2377
Closes #2405

(cherry picked from commit 8e9a5d29a8)
2023-12-12 15:58:33 +01:00
Camilla Löwy e0de6ea513 EGL: Only use EGL_EXT_present_opaque on Wayland
The EGL_EXT_present_opaque extension is primarily a workaround meant for
Wayland, even if the language in it doesn't mention this.  GLFW
previously always enabled this extension where supported.  This caused
issues on X11 when running the Nvidia binary blob.

This commit ensures the extension is only enabled on Wayland.

Fixes #2365

This was adapted to 3.3-stable from
46cebb5081.
2023-12-07 18:04:48 +01:00
Camilla Löwy 79d957ca18 Add credit
Fixes #2397

(cherry picked from commit 68edc66aa4)
2023-12-07 18:04:48 +01:00
Camilla Löwy 63bba49e31 Cocoa: Fix compilation error on OS X 10.8
The occlusion state parts of NSWindow are OS X 10.9+ only but we still
(technically) support building for only 10.8.

Fixes #2161

(cherry picked from commit 5e4496cb42)
2023-12-07 18:04:48 +01:00
Peter Johnson 80d45cdfd7 Win32: Fix invalid hat bit mask being accepted
It is reportedly possible to get opposing directions of an XInput DPad
bit mask set simultaneously with some controllers.

This commit ensures that those values are not passed on to other parts
of GLFW.

This commit is based on the PR #2291 by @ PeterJohnson but with the
following changes:
 - moved XInput-specific special case to XInput implementation
 - attempt to preserve data by only masking out the invalid axis
 - admin (credit, changelog, commit message)

Closes #2291

(cherry picked from commit 52405a9d59)
2023-12-07 18:04:48 +01:00
Camilla Löwy 683b7524d2 Improve documentation relating to key tokens
Shifted the documentation away from the term 'named keys' as something
different than keys that glfwGetKeyName will return a name for.  The
already existing term 'key token' should now be used to refer to the
GLFW_KEY_* constants.

The associated term 'named mouse button' was also replaced with
'supported mouse button'.

The parts explaining which key tokens will return a valid scancode from
glfwGetKeyScancode have hopefully been clarified.  This issue was
reported in #2055.

The GLFW_KEY_UNKNOWN constant has been moved out of the list of key
tokens to simplify and hopefully clarify the related documentation.

Various other keyboard key related edits were made, hopefully resulting
in improvements.

Related to #2055

(cherry picked from commit 9959dc69ca)
2023-12-07 18:04:48 +01:00
Camilla Löwy 356f56a166 Fix list of possible errors for glfwGetKeyName
(cherry picked from commit 557a633b2d)
2023-12-07 18:04:48 +01:00
Camilla Löwy 5f936a6276 Fix glfwGetKeyName not checking key token is valid
(cherry picked from commit b1517e5b3e)
2023-12-07 18:04:48 +01:00
Camilla Löwy 1c989eace3 Clarify documentation for glfwMakeContextCurrent
(cherry picked from commit 3f31519de8)
2023-12-07 18:04:48 +01:00
Camilla Löwy c98860db9e Add assertions for context function invariants
Related to #2327

(cherry picked from commit 93d70cb6a8)
2023-12-07 18:04:48 +01:00
Camilla Löwy cb0dafa7c0 Fix potential violation of invariant
The shared function for reading back context attributes,
_glfwRefreshContextAttribs, did not check whether the newly created
context had been successfully made current.  This violated the invariant
that the context TLS slot always points to a valid window and that its
context is current whenever _glfw.platform.getProcAddress is called.

Related to #2327

This was adapted to 3.3-stable from
fa0ea5c41f and
ddd92a4fa8.
2023-12-07 18:04:08 +01:00
Camilla Löwy 11f517e557 Fix return value on error for glfwGetKeyScancode
The documentation says it should be -1, not zero.

(cherry picked from commit 8c5471d6cd)
2023-12-07 17:33:52 +01:00
Camilla Löwy 2a4e26870b Fix remaining use of actions/checkout@v2
Related to #2255
2023-12-05 16:18:59 +01:00
Camilla Löwy 31f08cc7fc Wayland: Fix heuristics for what counts as events
The Wayland implementation of glfwWaitEvents* keeps waiting until it
sees evidence that a significant event has been processed.  However,
this included updating an animated cursor (not a significant event)
but did not include previously buffered Wayland events or libdecor
events (definitely significant events).

This commit corrects these cases.

(cherry picked from commit d097e35743)
2023-11-30 21:34:16 +01:00
Camilla Löwy 9809035ed2 Wayland: Fix protocol error on undecorated window
When setting the visibility of a libdecor frame on a compositor that
supports XDG decorations, libdecor 0.1 will update the geometry of the
XDG surface.  GLFW attempted to set the visibility before having told
libdecor what size the content area is.  This caused a Wayland protocol
error when libdecor attempted to set the window size to 0x0.

This commit adds setting the content area size for the libdecor frame
directly after creation, allowing libdecor to know what it's doing.

(cherry picked from commit 23e40548b1)
2023-11-30 21:34:06 +01:00
Camilla Löwy 7cc8879ab9 Wayland: Use Wayland to wait for libdecor to init
Much of libdecor is initialized only after certain events have been
received from the compositor and some parts of libdecor 0.1 are unsafe
to use until this delayed initialization has completed.

Since libdecor does not provide an API to query if or be notified when
this has happened, GLFW processed events until its newly created
libdecor frame had created its XDG shell objects.

This commit switches to using a generic Wayland sync point created just
after libdecor (and presumably its plugin) has set up its delayed
initialization, instead of relying on the more specific implementation
detail mentioned above.

It also makes this wait mandatory before the first libdecor frame is
created instead of a pre-condition for certain libdecor frame calls,
hopefully removing even more dependence on implementation details.

(cherry picked from commit 9fdc425931)
2023-11-30 21:31:58 +01:00
Doug Binks 89b149a56f Reorder credit
(cherry picked from commit 659d161446)
2023-11-28 22:19:11 +01:00
Grzesiek11 b52b074be5 Documentation: only named keys generate synthetic key releases
The current wording states that all keys have synthetic key release
events generated after focus is lost, but keys that aren't named
don't have any state held, so no such events are generated for them.

The new wording clarifies that only named keys have the events generated
for them.

(cherry picked from commit dbe810e403)
2023-11-28 22:19:08 +01:00
Camilla Löwy b211975131 Update changelog and add credit
Related to #2229

(cherry picked from commit a87acd8c1f)
2023-11-28 22:18:36 +01:00
Camilla Löwy 2c09407bff Cleanup
(cherry picked from commit 2a4dd9c28f)
2023-11-28 22:17:40 +01:00
Michael Skec 7c7cc59889 Linux: Fix memory leak when inotify init failed
This introduces regex_compiled boolean to track whether the regex is
compiled successfully.

Closes #2229

(cherry picked from commit c992226a9c)
2023-11-28 22:16:53 +01:00
Camilla Löwy 6f9686f1f4 Fix unneccessary use of "must"
Passing a context-less window to a function that requires a context only
emits a harmless GLFW_NO_WINDOW_CONTEXT error.

(cherry picked from commit 0bd3e879e1)
2023-11-28 22:15:43 +01:00
Camilla Löwy 89bea58b18 Win32: Fix glfwWaitEventsTimeout ignoring messages
The bitmask passed to MsgWaitForMultipleObjects was missing
QS_SENDMESSAGE, causing glfwWaitEventsTimeout not to return when the
thread received messages sent from other threads.

Fixes #2408

(cherry picked from commit 509f4131be)
2023-11-28 22:15:23 +01:00
Camilla Löwy ff156743ab Update Doxyfile template for Doxygen 1.9.7
This was adapted to 3.3-stable from
938a3c29b2.
2023-11-28 22:04:48 +01:00
Doug Binks 489339b837 Updated credit
(cherry picked from commit 3ed6e9d89a)
2023-11-27 17:12:44 +01:00
Doug Binks af93f06259 Add credits
Related to #2386 and #2420

(cherry picked from commit 9a80225ddf)
2023-11-27 17:12:40 +01:00
Doug Binks 8ef347157a Updated changelog
(cherry picked from commit 46c2e35c55)
2023-11-27 17:10:50 +01:00
moritz-h c754de5deb Win32: Add library name suffix to pkg-config file
Closes #2386

This was adapted to 3.3-stable from
93a3ba8080.
2023-11-27 17:01:35 +01:00
Andy Williams bf429fb628 Fix macOS Print Screen
Many years ago this value was changed from F13 to Print Screen with
1ae9ce1e0a.  However, this was later
reverted to F13 with 5759d0fdf2.

This changes it back to Print Screen for consistency with other
platforms.

Closes #1786
Fixes #2169

(cherry picked from commit c940695eb0)
2023-11-16 22:50:41 +01:00
Camilla Löwy 8da6223c90 Wayland: Cleanup
Update naming and declarations to current standard.

(cherry picked from commit 3eaf1255b2)
2023-07-19 17:51:56 +02:00
Camilla Löwy c3f15da23a Wayland: Merge function called once
This brings together the two halves of the cursor setting logic for the
fallback decorations.

(cherry picked from commit 6b48f2be97)
2023-07-19 17:51:53 +02:00
Camilla Löwy 1d766c8b39 Wayland: Fix fallback decorations emitting errors
A GLFW_CURSOR_UNAVAILABLE error would be emitted each time the cursor
moved over the fallback decorations if the standard cursor shape
appropriate for that part was missing on the system.

These errors served no useful purpose and have been removed.

(cherry picked from commit 00a663dafd)
2023-07-19 17:50:49 +02:00
TheBrokenRail 67d722788d Wayland: Fix detection of joysticks after init
Closes #2198

This was adapted to 3.3-stable from
0b94e1b29b and
3fa2360720.
2023-07-19 17:48:46 +02:00
Camilla Löwy 06a2ed38ea Fix glfwinfo output of Vulkan layer spec version
(cherry picked from commit f27daa34ad)
2023-07-19 17:44:21 +02:00
Camilla Löwy 0c2db4a23e Wayland: Add initial support for libdecor
This is partly based on the implementation of libdecor support in
PR #1693 by @ christianrauch.

Where available, the libdecor library is loaded at init and becomes the
preferred method for window decorations.  On compositors that support
XDG decorations, libdecor in turn uses those.  If not, libdecor has
a plug-in archtecture and may load additional libraries to either use
compositor-specific decorations or draw its own.

If necessary, support for libdecor can be disabled with the
GLFW_WAYLAND_LIBDECOR init hint.  This is mostly in case some part of
the dynamic loading or duplication of header material added here turns
out to cause problems with future versions of libdecor-0.so.0.

Fixes #1639
Closes #1693
Related to #1725

This was adapted to 3.3-stable from
fbdb53b9ca.
2023-07-19 17:23:25 +02:00
Camilla Löwy 1ad5df8032 Wayland: Simplify decoration side detection
This commit simplifies the detection of which element of a fallback
decorated window the pointer has entered.  Instead of looping through
the list of windows, the user pointer of fallback decoration surfaces is
set to the GLFW window object.

(cherry picked from commit cd466cf9fd)
2023-03-28 17:46:41 +02:00
Camilla Löwy 95b35c43c2 Wayland: Clean up enum value names
(cherry picked from commit 39f0e86228)
2023-03-28 17:44:56 +02:00
Camilla Löwy e5d19c9fac Wayland: Simplify per-window ouput scales tracking
This replaces (one case of) manual management of weak links between
windows and monitors, both objects with complex life times, with
wl_object pointers used as opaque key values.

(cherry picked from commit efa9297a41)
2023-03-28 17:43:39 +02:00
Camilla Löwy 5ac970120a Wayland: Use tags to verify proxy ownership
This is in preparation for adding support for libdecor, which creates
its own proxies on our display.  It will likely also be helpful to some
people using native access on Wayland.

This is partly based on the implementation of libdecor support in
PR #1693 by @ christianrauch.

(cherry picked from commit 91c837ace5)
2023-03-28 17:38:33 +02:00
Camilla Löwy 677fbb0f82 Wayland: Remove duplicate setting of user data
The surface user data is already set by wl_surface_add_listener.

(cherry picked from commit 6d9083af03)
2023-03-28 17:36:29 +02:00
Camilla Löwy a29b5f38c6 Wayland: Stop manually tracking interface versions
This is already tracked by the proxies we care about.

(cherry picked from commit 4cf510511c)
2023-03-28 17:36:22 +02:00
Camilla Löwy 1de73c0dc5 Wayland: Emit size event when setting aspect ratio
(cherry picked from commit c1a79c1c41)
2023-03-28 17:36:18 +02:00
Camilla Löwy a6e3efbafc Wayland: Fix some missing window refresh events
(cherry picked from commit 8397b39afa)
2023-03-28 17:36:13 +02:00
Camilla Löwy ba99e20f6a Wayland: Fix decorations not always being created
If a window was initially fullscreen then it would not get an XDG
decoration object.  If the window was later switched to windowed mode it
would then get fallback decorations instead of XDG ones.

(cherry picked from commit 735fc101f5)
2023-03-28 17:36:09 +02:00
Camilla Löwy 8522447792 Wayland: Simplify test for fallback decorations
The GLFW fallback decorations only exist when the window is visible,
decorated and in windowed mode.

(cherry picked from commit 228428fa4f)
2023-03-28 17:36:05 +02:00
Camilla Löwy ba80e23dab Wayland: Pick more plausible default cursor size
This is not intended as a replacement for actually querying the desktop
for the correct size, but it appears to be a better fallback value.

(cherry picked from commit 82e77dbff4)
2023-03-28 17:36:01 +02:00
Juan Ramos 2178c3e536 Update to actions/checkout@v3
Fixes the following CI warning:

"Node.js 12 actions are deprecated. Please update the following
actions to use Node.js 16: actions/checkout@v2..."

Closes #2255

(cherry picked from commit 9a87635686)
2023-03-28 17:35:56 +02:00
Juan Ramos 1b4e126dc0 Remove CMAKE_LEGACY_CYGWIN_WIN32 CMake option
This was needed for compatibility with CMake versions before 2.8.4.

Related to #2256

(cherry picked from commit 30b91c8b60)
2023-03-28 17:27:25 +02:00
Camilla Löwy 71dfc3f65c Add support for manually running build workflow
(cherry picked from commit 8f470597d6)
2023-03-28 17:26:31 +02:00
Camilla Löwy 4a33051456 Update change log and add credit
Related to #2225

This was adapted to 3.3-stable from
57cbded076.
2023-01-07 23:45:04 +01:00
Takuro Ashie b06a91e92b Wayland: Fix wrong array size for _GLFWofferWayland
Closes #2225

(cherry picked from commit 41d8da1cea)
2023-01-07 23:13:16 +01:00
Camilla Löwy c7a5333873 Add window surface creation to glfwinfo
The glfwinfo tool now attempts Vulkan surface creation via
glfwCreateWindowSurface and reports the results.

(cherry picked from commit 0beadfdc66)
2022-11-23 21:42:56 +01:00
Camilla Löwy 05e28537a3 Remove Doxyfile tags deprecated by Doxygen 1.9.5
(cherry picked from commit d299d9f788)
2022-10-31 22:16:33 +01:00
Camilla Löwy af3e14fbc2 Document X11 WM_CLASS hint behavior
Fixes #2180

(cherry picked from commit ed1d9e1ca7)
2022-10-31 22:13:27 +01:00
Camilla Löwy d36d062d72 Win32: Remove unhelpful helper function
(cherry picked from commit ab3ea8ac9f)
2022-10-31 22:13:01 +01:00
Camilla Löwy 493df4a0b5 EGL: Cleanup
Both config parameters are "desired", but one is older and never had its
name updated.

This commit at least makes it clearer that they are similar.

(cherry picked from commit ab1b1edfd0)
2022-10-31 22:05:22 +01:00
Camilla Löwy 31b038663a EGL: Add better error for no stereo
(cherry picked from commit 93e93135f2)
2022-10-31 22:04:00 +01:00
Camilla Löwy 6fb86c089e EGL: Add better errors for client API mismatch
Because EGL ties client API support to configs, attempts to create
a context with an unavailable client API will fail with the unhelpful
"failed to find suitable config" error description.

This attempts to detect cases where there are usable configs for the
other client API and emit a hopefully more helpful error.

Related to #2173

(cherry picked from commit e057666642)
2022-10-31 22:03:56 +01:00
Camilla Löwy bc36010350 Check if context creation APIs match when sharing
(cherry picked from commit 6b57e08bb0)
2022-10-31 22:03:47 +01:00
Camilla Löwy bd13f55ca8 WGL: Fix count of displayable pixel formats
We only care about displayable pixel formats (as defined in
WGL_ARB_pixel_format) for window context creation.

This changes pixel format enumeration to ignore non-displayable formats,
which are specified to be listed after displayable ones, by always using
the return value of DescribePixelFormat as the pixel format count.

(cherry picked from commit 2c0f34b60f)
2022-10-31 22:03:35 +01:00
Camilla Löwy 8b4f1ebbea Wayland: Fix window opacity on older systems
On systems lacking the EGL_EXT_present_opaque extension, some
compositors treat any buffer with an alpha channel as per-pixel
transparent.

This commit ignores any EGLConfig with an alpha channel if the extension
is missing and the window is created with GLFW_TRANSPARENT_FRAMEBUFFER
set to false.

This is technically not a breaking change since GLFW_ALPHA_BITS is not
a hard constraint, but it is still going to inconvenience anyone using
the framebuffer alpa channel to store other kinds of data.

Related to #1895

(cherry picked from commit ef6c9d8b4f)
2022-10-31 22:02:06 +01:00
Camilla Löwy 1f675ab62f GLX: Add support for loading glvnd libGLX
(cherry picked from commit c18851f52e)
2022-10-31 21:57:21 +01:00
Camilla Löwy ed55529ce8 EGL: Add support for loading glvnd libOpenGL
(cherry picked from commit 55aad3c37b)
2022-10-31 21:48:45 +01:00
Camilla Löwy 426c6ed6b1 X11: Preserve unrelated values in WM_NORMAL_HINTS
This stops GLFW overwriting the whole WM_NORMAL_HINTS property every
time it updates size-related parts of it.

(cherry picked from commit 7d73629e50)
2022-10-31 21:48:04 +01:00
Camilla Löwy 1fe29e2c19 Fix native access macros being mutually exclusive
The documentation was updated with the introduction of run-time platform
selection, but the preprocessor logic was not.

(cherry picked from commit 2efc598d70)
2022-10-31 21:47:57 +01:00
TheChocolateOre 34bfb52641 Fix typos and other issues in docs
This fixes spelling, grammar and punctuation issues, missing words and
stray words across the documentation.  A confusing sentence was removed
from the tutorial.

Closes #2085

(cherry picked from commit 2e12ef00bb)
2022-10-31 21:47:01 +01:00
Camilla Löwy 3670cd0561 Wayland: Remove unreachable code
This platform function is only called if the cursor is enabled.

(cherry picked from commit 3a5c726d1b)
2022-10-31 21:34:38 +01:00
Camilla Löwy 0ee9b7281b Wayland: Clean up pointer helper function order
(cherry picked from commit 7be6a2cabe)
2022-10-31 21:34:33 +01:00
Camilla Löwy 5f3e5542cf Refactor cursor mode paths
This is the refactoring part of adding GLFW_CURSOR_CAPTURED, separated
out to help keep 3.3-stable similar to the main branch.

Related to #58.

(cherry picked from commit a46f829de8)
2022-10-31 21:29:42 +01:00
Camilla Löwy 632d35e0d4 Wayland: Fix leaks of pointer related objects
(cherry picked from commit 03af6b3d4c)
2022-10-31 21:19:15 +01:00
Camilla Löwy 5189d52ae3 Wayland: Clean up pointer locking
Shorten names and allow C99 declarations.  Replace helper function with
the NULL check it was hiding.  Separate cursor hiding from pointer
locking.

(cherry picked from commit e85b645b8a)
2022-10-31 21:18:12 +01:00
Camilla Löwy 78edf2516e Wayland: Static function more static when static
(cherry picked from commit 26b85215c0)
2022-10-31 21:12:07 +01:00
Camilla Löwy 74090d30cd Wayland: Clean up cursor theme loading
(cherry picked from commit 6987294df9)
2022-10-31 21:12:01 +01:00
Camilla Löwy ad206bdaee Wayland: Fix crash if mouse connected after init
The cursor theme was only loaded if the chosen seat had a mouse
(wl_pointer) during initialization.  If a mouse was connected only after
glfwInit, there would be no cursor theme but the rest of the cursor
related code assumed one had already been loaded.

This also moves the details of cursor theme loading out into a separate
function to declutter platform init.

Because the original cursor theme loading code checked whether we got
a wl_shm, and because the rest of the code just assumes we have
a wl_shm, initialization will now fail if there isn't one.

Fixes #1450

(cherry picked from commit 71be34a6c3)
2022-10-31 21:11:11 +01:00
Camilla Löwy b08271d315 Wayland: Clean up shared memory buffer creation
(cherry picked from commit 7cc8b053b8)
2022-10-31 21:02:14 +01:00
Camilla Löwy 2ca3bda1cc Update changelog and add credit
Related to #2042
Related to #2043

(cherry picked from commit 91a96ed434)
2022-10-31 20:59:10 +01:00
Björn Hempel 388d0cf7c2 Linux: Fix joystick without buttons being ignored
Joysticks in Linux without buttons were ignored by device enumeration.
Remove the mandatory button attribute from detection.

Fixes #2042
Closes #2043

(cherry picked from commit c424fe5589)
2022-10-31 20:58:19 +01:00
Camilla Löwy 4affd2207c Make events test window appear on Wayland
(cherry picked from commit c50d53160f)
2022-10-31 20:58:13 +01:00
Camilla Löwy dea9914692 Wayland: Fix reappearing key repeat
If the key or character callback performs actions that indirectly
updates the key repeat timer, those changes would be undone once the key
callback returned.

This fixes the order of operations so that key repeat is fully set up
before the key related events are emitted.

(cherry picked from commit 40b5a8a37c)
2022-10-31 20:57:20 +01:00
Camilla Löwy 1acd67eeb6 Wayland: Clean up key repeat logic
(cherry picked from commit 9180923ea0)
2022-10-31 20:57:02 +01:00
Camilla Löwy a8d543f1f8 Wayland: Make text input logic static
Since the seat listener was moved into wl_window.c there is no reason
for text input to have external linkage.

(cherry picked from commit a1a73ee862)
2022-10-31 20:56:39 +01:00
Camilla Löwy ca5ccd819d Wayland: Update state before emitting events
(cherry picked from commit e47cb7c1e2)
2022-10-31 20:56:17 +01:00
Camilla Löwy 41bb7b8617 Wayland: Do not emit events for destroyed window
During platform window destruction, all of its callbacks have already
been removed, so emitting events for it does nothing.

(cherry picked from commit 4df24735ef)
2022-10-31 20:54:45 +01:00
Camilla Löwy ccbbada181 Wayland: Fix non-standard struct initialization
(cherry picked from commit d77aaa770f)
2022-10-31 20:54:34 +01:00
Camilla Löwy fe2ac5027b Start 3.3.9 2022-07-22 16:04:36 +02:00
Camilla Löwy 74a1ae065a Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2022-03-20 18:03:04 +01:00
Camilla Löwy 2a6dac679c Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2022-03-04 15:10:14 +01:00
Camilla Löwy cc5f563905 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2021-10-14 00:17:57 +02:00
Camilla Löwy 2927cc87c8 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2021-08-16 23:24:52 +02:00
Camilla Löwy 747224cb54 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2021-06-25 00:29:19 +02:00
Camilla Löwy 82b8651e00 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2021-04-12 22:13:50 +02:00
Camilla Löwy cbce7a3648 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2021-02-10 22:38:33 +01:00
Camilla Löwy de3b5ec937 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2020-12-14 23:07:00 +01:00
Camilla Löwy 78dccc5c00 Add missing changelog issue number
(cherry picked from commit 7e8da57094)
2020-12-14 22:56:10 +01:00
Leonard König 63e535210c Wayland: Fix destroying CSDs in the correct order
On Wayland we implement Client-Side Decorations if the compositors do not
implement SSDs.  In that case, the destructors of the surfaces were called
in the wrong order, leading to a dereference of an already freed object.
We need to first destroy the subsurface before destroying the parent surface.

Related PR on kitty: https://github.com/kovidgoyal/kitty/pull/3066
Related issue on kitty: https://github.com/kovidgoyal/kitty/issues/3051

Closes #1798.

(cherry picked from commit 0dc1005c85)
2020-12-14 22:55:28 +01:00
Camilla Löwy ae8561d740 Cocoa: Fix ObjC being built as C with CMake 3.19
CMake 3.19 adds -xc when the LANGUAGE file property is C, breaking our
workaround for CMake 3.15 and earlier not understanding the .m suffix.

Fixes #1787.

(cherry picked from commit 3327050ca6)
2020-12-14 22:54:25 +01:00
Camilla Löwy ddd85a9e2f Win32: Filter out duplicate size events
This mirrors the filtering done on X11 and Cocoa.  Possibly this should
be done by shared code instead.

Fixes #1610.

(cherry picked from commit 0bccc3852b)
2020-12-14 22:51:31 +01:00
Camilla Löwy 83dbe197c0 Win32: Fix clang-cl interpreting -Wall as /Wall
Unlike -Wall, VS /Wall really means all warnings.

Closes #1780.

(cherry picked from commit ac627706ef)
2020-12-14 22:50:40 +01:00
Camilla Löwy e669471aca Win32: Enable /W3 on VS for library sources
/W3 is the default for new VS projects and the library builds cleanly
with it on VS 2010-2019 so let's try to keep it that way.

(cherry picked from commit 6b78419c9a)
2020-12-14 22:50:37 +01:00
Camilla Löwy 1a965d2230 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2020-07-23 18:49:52 +02:00
Camilla Löwy 02bd652f2b Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2020-07-16 13:35:26 +02:00
Camilla Löwy 0ebae5a3df Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2020-07-02 23:24:20 +02:00
Camilla Löwy 830b05ecf9 Merge branch '3.3-stable' into new-cursors-on-3.3-stable 2020-06-02 19:47:53 +02:00
Camilla Löwy 02461dc843 Add more standard cursors
This adds the standard cursors for diagonal and omnidirectional
resize/move and operation-not-allowed.  It also adds new (better?) names
for the horizontal and vertical resize/move and pointing hand cursors.

References:
 - https://developer.apple.com/documentation/appkit/nscursor
 - https://stackoverflow.com/questions/10733228/
 - https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setsystemcursor
 - https://freedesktop.org/wiki/Specifications/cursor-spec/
 - https://tronche.com/gui/x/xlib/appendix/b/

Related to #427.
2020-04-02 23:28:42 +02:00
54 changed files with 3973 additions and 1883 deletions
-2
View File
@@ -1,8 +1,6 @@
* @elmindreda
src/wl_* @linkmauve
docs/*.css @glfw/webdev
docs/*.scss @glfw/webdev
docs/*.html @glfw/webdev
+11 -5
View File
@@ -3,6 +3,7 @@ on:
pull_request:
push:
branches: [ ci, master, latest, 3.3-stable ]
workflow_dispatch:
permissions:
statuses: write
contents: read
@@ -11,11 +12,12 @@ jobs:
build-linux-x11-clang:
name: X11 (Linux, Clang)
runs-on: ubuntu-latest
timeout-minutes: 4
env:
CC: clang
CFLAGS: -Werror
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt update
@@ -34,11 +36,12 @@ jobs:
build-linux-wayland-clang:
name: Wayland (Linux, Clang)
runs-on: ubuntu-latest
timeout-minutes: 4
env:
CC: clang
CFLAGS: -Werror
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt update
@@ -57,11 +60,12 @@ jobs:
build-linux-null-clang:
name: Null (Linux, Clang)
runs-on: ubuntu-latest
timeout-minutes: 4
env:
CC: clang
CFLAGS: -Werror
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt update
@@ -80,11 +84,12 @@ jobs:
build-macos-cocoa-clang:
name: Cocoa (macOS, Clang)
runs-on: macos-latest
timeout-minutes: 4
env:
CFLAGS: -Werror
MACOSX_DEPLOYMENT_TARGET: 10.8
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Configure static library
run: cmake -S . -B build-static
@@ -99,10 +104,11 @@ jobs:
build-windows-win32-vs2022:
name: Win32 (Windows, VS2022)
runs-on: windows-latest
timeout-minutes: 4
env:
CFLAGS: /WX
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Configure static library
run: cmake -S . -B build-static -G "Visual Studio 17 2022"
+1
View File
@@ -1,5 +1,6 @@
# The canonical out-of-tree build subdirectory
build
build-*
# Visual Studio clutter
_ReSharper*
+6 -3
View File
@@ -1,8 +1,6 @@
cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR)
project(GLFW VERSION 3.3.8 LANGUAGES C)
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
project(GLFW VERSION 3.3.10 LANGUAGES C)
if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
@@ -47,6 +45,7 @@ if (BUILD_SHARED_LIBS AND UNIX)
else()
set(GLFW_LIB_NAME glfw3)
endif()
set(GLFW_LIB_NAME_SUFFIX "")
if (GLFW_VULKAN_STATIC)
if (BUILD_SHARED_LIBS)
@@ -198,6 +197,10 @@ if (_GLFW_WIN32)
if (GLFW_USE_HYBRID_HPG)
set(_GLFW_USE_HYBRID_HPG 1)
endif()
if (BUILD_SHARED_LIBS)
set (GLFW_LIB_NAME_SUFFIX "dll")
endif()
endif()
#--------------------------------------------------------------------
+24
View File
@@ -8,6 +8,7 @@ video tutorials.
- Bobyshev Alexander
- Laurent Aphecetche
- Matt Arsenault
- Takuro Ashie
- ashishgamedev
- David Avedissian
- Keith Bauer
@@ -44,6 +45,7 @@ video tutorials.
- Bailey Cosier
- Noel Cower
- CuriouserThing
- Bill Currie
- Jason Daly
- danhambleton
- Jarrod Davis
@@ -63,11 +65,13 @@ video tutorials.
- Nikita Fediuchin
- Felipe Ferreira
- Michael Fogleman
- forworldm
- Jason Francis
- Gerald Franz
- Mário Freitas
- GeO4d
- Marcus Geelnard
- Gegy
- ghuser404
- Charles Giessen
- Ryan C. Gordon
@@ -75,12 +79,16 @@ video tutorials.
- Kovid Goyal
- Kevin Grandemange
- Eloi Marín Gratacós
- Grzesiek11
- Stefan Gustavson
- Andrew Gutekanst
- Stephen Gutekanst
- Jonathan Hale
- Daniel Hauser
- hdf89shfdfs
- Moritz Heinemann
- Sylvain Hellegouarch
- Björn Hempel
- Matthew Henry
- heromyth
- Lucas Hinderberger
@@ -96,6 +104,7 @@ video tutorials.
- JannikGM
- Erik S. V. Jansson
- jjYBdx4IL
- Peter Johnson
- Toni Jovanoski
- Arseny Kapoulkine
- Cem Karan
@@ -118,12 +127,16 @@ video tutorials.
- Anders Lindqvist
- Leon Linhart
- Marco Lizza
- lo-v-ol
- Eyal Lotem
- Aaron Loucks
- Ned Loynd
- Luflosi
- lukect
- Tristam MacDonald
- Jean-Luc Mackail
- Hans Mackowiak
- Ramiro Magno
- Дмитри Малышев
- Zbigniew Mandziejewicz
- Adam Marcus
@@ -136,6 +149,7 @@ video tutorials.
- Marcel Metz
- Liam Middlebrook
- Ave Milia
- Icyllis Milica
- Jonathan Miller
- Kenneth Miller
- Bruce Mitchener
@@ -149,6 +163,7 @@ video tutorials.
- Martins Mozeiko
- James Murphy
- Julian Møller
- NateIsStalling
- ndogxj
- F. Nedelec
- Kristian Nielsen
@@ -179,26 +194,31 @@ video tutorials.
- pthom
- Martin Pulec
- Guillaume Racicot
- Christian Rauch
- Philip Rideout
- Eddie Ringle
- Max Risuhin
- Joe Roback
- Jorge Rodriguez
- Luca Rood
- Ed Ropple
- Aleksey Rybalkin
- Mikko Rytkönen
- Riku Salminen
- Anton Samokhvalov
- Brandon Schaefer
- Sebastian Schuberth
- Christian Sdunek
- Matt Sealey
- Steve Sexton
- Arkady Shapkin
- Mingjie Shen
- Ali Sherief
- Yoshiki Shibukawa
- Dmitri Shuralyov
- Joao da Silva
- Daniel Sieger
- Michael Skec
- Daniel Skorupski
- Slemmie
- Bradley Smith
@@ -215,6 +235,7 @@ video tutorials.
- Paul Sultana
- Nathan Sweet
- TTK-Bandit
- Nuno Teixeira
- Sergey Tikhomirov
- Arthur Tombs
- TronicLabs
@@ -227,14 +248,17 @@ video tutorials.
- Jari Vetoniemi
- Ricardo Vieira
- Nicholas Vitovitch
- Vladimír Vondruš
- Simon Voordouw
- Corentin Wallez
- Torsten Walluhn
- Patrick Walton
- Jim Wang
- Xo Wang
- Jay Weisskopf
- Frank Wille
- Richard A. Wilkes
- Andy Williams
- Tatsuya Yatagawa
- Ryogo Yoshimura
- Rácz Zalán
+8 -72
View File
@@ -2,7 +2,6 @@
[![Build status](https://github.com/glfw/glfw/actions/workflows/build.yml/badge.svg)](https://github.com/glfw/glfw/actions)
[![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw)
[![Coverity Scan](https://scan.coverity.com/projects/4884/badge.svg)](https://scan.coverity.com/projects/glfw-glfw)
## Introduction
@@ -123,74 +122,12 @@ information on what to include when reporting a bug.
## Changelog
- Added `GLFW_NATIVE_INCLUDE_NONE` for disabling inclusion of native headers (#1348)
- Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization
- Bugfix: `glfwSetGammaRamp` could emit `GLFW_INVALID_VALUE` before initialization
- Bugfix: `glfwGetJoystickUserPointer` returned `NULL` during disconnection (#2092)
- [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)
- [Win32] Bugfix: The OSMesa library was not unloaded on termination
- [Win32] Bugfix: Right shift emitted `GLFW_KEY_UNKNOWN` when using a CJK IME (#2050)
- [Cocoa] Disabled macOS fullscreen when `GLFW_RESIZABLE` is false
- [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791)
- [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination
- [Cocoa] Bugfix: `GLFW_MAXIMIZED` was always true when `GLFW_RESIZABLE` was false
- [Cocoa] Bugfix: Changing `GLFW_DECORATED` in macOS fullscreen would abort
application (#1886)
- [Cocoa] Bugfix: Setting a monitor from macOS fullscreen would abort
application (#2110)
- [Cocoa] Bugfix: The Vulkan loader was not loaded from the `Frameworks` bundle
subdirectory (#2113,#2120)
- [X11] Bugfix: The OSMesa libray was not unloaded on termination
- [X11] Bugfix: A malformed response during selection transfer could cause a segfault
- [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108)
- [Wayland] Added support for file path drop events (#2040)
- [Wayland] Added support for more human-readable monitor names where available
- [Wayland] Removed support for the deprecated wl\_shell protocol
- [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of
`glfwGetClipboardString`
- [Wayland] Bugfix: Data source creation error would cause double free at termination
- [Wayland] Bugfix: Partial writes of clipboard string would cause beginning to repeat
- [Wayland] Bugfix: Some errors would cause clipboard string transfer to hang
- [Wayland] Bugfix: Drag and drop data was misinterpreted as clipboard string
- [Wayland] Bugfix: MIME type matching was not performed for clipboard string
- [Wayland] Bugfix: The OSMesa library was not unloaded on termination
- [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_PLATFORM_ERROR`
- [Wayland] Bugfix: Lock key modifier bits were only set when lock keys were pressed
- [Wayland] Bugfix: A window leaving full screen mode would be iconified (#1995)
- [Wayland] Bugfix: A window leaving full screen mode ignored its desired size
- [Wayland] Bugfix: `glfwSetWindowMonitor` did not update windowed mode size
- [Wayland] Bugfix: `glfwRestoreWindow` would make a full screen window windowed
- [Wayland] Bugfix: A window maximized or restored by the user would enter an
inconsistent state
- [Wayland] Bugfix: Window maximization events were not emitted
- [Wayland] Bugfix: `glfwRestoreWindow` assumed it was always in windowed mode
- [Wayland] Bugfix: `glfwSetWindowSize` would resize a full screen window
- [Wayland] Bugfix: A window content scale event would be emitted every time
the window resized
- [Wayland] Bugfix: If `glfwInit` failed it would close stdin
- [Wayland] Bugfix: Manual resizing with fallback decorations behaved erratically
(#1991,#2115,#2127)
- [Wayland] Bugfix: Size limits included frame size for fallback decorations
- [Wayland] Bugfix: Updating `GLFW_DECORATED` had no effect on server-side
decorations
- [Wayland] Bugfix: A monitor would be reported as connected again if its scale
changed
- [Wayland] Bugfix: `glfwTerminate` would segfault if any monitor had changed
scale
- [Wayland] Bugfix: Window content scale events were not emitted when monitor
scale changed
- [Wayland] Bugfix: `glfwSetWindowAspectRatio` reported an error instead of
applying the specified ratio
- [Wayland] Bugfix: `GLFW_MAXIMIZED` window hint had no effect
- [Wayland] Bugfix: `glfwRestoreWindow` had no effect before first show
- [Wayland] Bugfix: Hiding and then showing a window caused program abort on
wlroots compositors (#1268)
- [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG
decorations
- Bugfix: `glfwGetKeyName` emitted `GLFW_INVALID_VALUE` for scancodes with no
key token (#1785,#2214)
- [Wayland] Bugfix: Terminating the library before showing a window could segfault
- [Wayland] Bugfix: Compilation failed on FreeBSD (#2445)
- [Linux] Bugfix: `regfree´ was called on invalid data (#2464)
- [WGL] Bugfix: Context creation failed in Parallels VM (#2191,#2406,#2467)
## Contact
@@ -199,13 +136,12 @@ On [glfw.org](https://www.glfw.org/) you can find the latest version of GLFW, as
well as news, documentation and other information about the project.
If you have questions related to the use of GLFW, we have a
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
[Libera.Chat](https://libera.chat/).
[forum](https://discourse.glfw.org/).
If you have a bug to report, a patch to submit or a feature you'd like to
request, please file it in the
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
Finally, if you're interested in helping out with the development of GLFW or
porting it to your favorite platform, join us on the forum, GitHub or IRC.
porting it to your favorite platform, join us on the forum or GitHub.
+3 -4
View File
@@ -23,13 +23,12 @@ Questions about how to use GLFW should be asked either in the [support
section](https://discourse.glfw.org/c/support) of the forum, under the [Stack
Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game
Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on
Stack Exchange or in the IRC channel `#glfw` on
[Libera.Chat](https://libera.chat/).
Stack Exchange.
Questions about the design or implementation of GLFW or about future plans
should be asked in the [dev section](https://discourse.glfw.org/c/dev) of the
forum or in the IRC channel. Please don't open a GitHub issue to discuss design
questions without first checking with a maintainer.
forum. Please don't open a GitHub issue to discuss design questions without
first checking with a maintainer.
## Reporting a bug
+1849 -940
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -4,8 +4,7 @@ See the [latest documentation](https://www.glfw.org/docs/latest/) for tutorials,
guides and the API reference.
If you have questions about using GLFW, we have a
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
[Libera.Chat](https://libera.chat/).
[forum](https://discourse.glfw.org/).
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
Please check the [contribution
+95 -18
View File
@@ -26,7 +26,7 @@ GLFW.
@endcode
This header defines all the constants and declares all the types and function
prototypes of the GLFW API. By default it also includes the OpenGL header from
prototypes of the GLFW API. By default, it also includes the OpenGL header from
your development environment. See [option macros](@ref build_macros) below for
how to select OpenGL ES headers and more.
@@ -160,20 +160,94 @@ A good general introduction to linking is
David Drysdale.
@subsection build_link_win32 With MinGW or Visual C++ on Windows
@subsection build_link_win32 With Visual C++ and GLFW binaries
The static version of the GLFW library is named `glfw3`. When using this
version, it is also necessary to link with some libraries that GLFW uses.
If you are using a downloaded
[binary archive](https://www.glfw.org/download.html), first make sure you have
the archive matching the architecture you are building for (32-bit or 64-bit),
or you will get link errors. Also make sure you are using the binaries for your
version of Visual C++ or you may get other link errors.
When using MinGW to link an application with the static version of GLFW, you
must also explicitly link with `gdi32`. Other toolchains including MinGW-w64
include it in the set of default libraries along with other dependencies like
`user32` and `kernel32`.
There are two version of the static GLFW library in the binary archive, because
it needs to use the same base run-time library variant as the rest of your
executable.
The link library for the GLFW DLL is named `glfw3dll`. When compiling an
application that uses the DLL version of GLFW, you need to define the @ref
GLFW_DLL macro _before_ any inclusion of the GLFW header. This can be done
either with a compiler switch or by defining it in your source code.
One is named `glfw3.lib` and is for projects with the _Runtime Library_ project
option set to _Multi-threaded DLL_ or _Multi-threaded Debug DLL_. The other is
named `glfw3_mt.lib` and is for projects with _Runtime Library_ set to
_Multi-threaded_ or _Multi-threaded Debug_. To use the static GLFW library you
will need to add `path/to/glfw3.lib` or `path/to/glfw3_mt.lib` to the
_Additional Dependencies_ project option.
If you compiled a GLFW static library yourself then there will only be one,
named `glfw3.lib`, and you have to make sure the run-time library variant
matches.
The DLL version of the GLFW library is named `glfw3.dll`, but you will be
linking against the `glfw3dll.lib` link library. To use the DLL you will need
to add `path/to/glfw3dll.lib` to the _Additional Dependencies_ project option.
All of its dependencies are already listed there by default, but when building
with the DLL version of GLFW, you also need to define the @ref GLFW_DLL. This
can be done either in the _Preprocessor Definitions_ project option or by
defining it in your source code before including the GLFW header.
@code
#define GLFW_DLL
#include <GLFW/glfw3.h>
@endcode
All link-time dependencies for GLFW are already listed in the _Additional
Dependencies_ option by default.
@subsection build_link_mingw With MinGW-w64 and GLFW binaries
This is intended for building a program from the command-line or by writing
a makefile, on Windows with [MinGW-w64](https://www.mingw-w64.org/) and GLFW
binaries. These can be from a downloaded and extracted
[binary archive](https://www.glfw.org/download.html) or by compiling GLFW
yourself. The paths below assume a binary archive is used.
If you are using a downloaded binary archive, first make sure you have the
archive matching the architecture you are building for (32-bit or 64-bit) or you
will get link errors.
Note that the order of source files and libraries matter for GCC. Dependencies
must be listed after the files that depend on them. Any source files that
depend on GLFW must be listed before the GLFW library. GLFW in turn depends on
`gdi32` and must be listed before it.
If you are using the static version of the GLFW library, which is named
`libglfw3.a`, do:
@code{.sh}
gcc -o myprog myprog.c -I path/to/glfw/include path/to/glfw/lib-mingw-w64/libglfw3.a -lgdi32
@endcode
If you are using the DLL version of the GLFW library, which is named
`glfw3.dll`, you will need to use the `libglfw3dll.a` link library.
@code{.sh}
gcc -o myprog myprog.c -I path/to/glfw/include path/to/glfw/lib-mingw-w64/libglfw3dll.a -lgdi32
@endcode
The resulting executable will need to find `glfw3.dll` to run, typically by
keeping both files in the same directory.
When you are building with the DLL version of GLFW, you will also need to define
the @ref GLFW_DLL macro. This can be done in your source files, as long as it
done before including the GLFW header:
@code
#define GLFW_DLL
#include <GLFW/glfw3.h>
@endcode
It can also be done on the command-line:
@code{.sh}
gcc -o myprog myprog.c -D GLFW_DLL -I path/to/glfw/include path/to/glfw/lib-mingw-w64/libglfw3dll.a -lgdi32
@endcode
@subsection build_link_cmake_source With CMake and GLFW source
@@ -271,7 +345,10 @@ target_link_libraries(myapp OpenGL::GL)
@endcode
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
@subsection build_link_pkgconfig With pkg-config and GLFW binaries on Unix
This is intended for building a program from the command-line or by writing
a makefile, on macOS or any Unix-like system like Linux, FreeBSD and Cygwin.
GLFW supports [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/),
and the `glfw3.pc` pkg-config file is generated when the GLFW library is built
@@ -322,13 +399,13 @@ OpenGL and IOKit frameworks to the project as dependencies. They can all be
found in `/System/Library/Frameworks`.
@subsection build_link_osx With command-line on macOS
@subsection build_link_osx With command-line or makefile on macOS
It is recommended that you use [pkg-config](@ref build_link_pkgconfig) when
building from the command line on macOS. That way you will get any new
dependencies added automatically. If you still wish to build manually, you need
to add the required frameworks and libraries to your command-line yourself using
the `-l` and `-framework` switches.
using installed GLFW binaries from the command line on macOS. That way you will
get any new dependencies added automatically. If you still wish to build
manually, you need to add the required frameworks and libraries to your
command-line yourself using the `-l` and `-framework` switches.
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
+18 -3
View File
@@ -85,6 +85,13 @@ transparent window framebuffers. If the running X server does not support this
extension or there is no running compositing manager, the
`GLFW_TRANSPARENT_FRAMEBUFFER` framebuffer hint will have no effect.
GLFW uses both the Xcursor extension and the freedesktop cursor conventions to
provide an expanded set of standard cursor shapes. If the running X server does
not support this extension or the current cursor theme does not support the
conventions, the `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR` and
`GLFW_NOT_ALLOWED_CURSOR` shapes will not be available and other shapes may use
legacy images.
@section compat_wayland Wayland protocols and IPC standards
@@ -122,6 +129,14 @@ wayland-protocols 1.6, and mandatory at build time. If the running compositor
does not support this protocol, the screensaver may start even for full screen
windows.
GLFW uses the [libdecor library](https://gitlab.freedesktop.org/libdecor/libdecor)
for window decorations, where available. This in turn provides good quality
client-side decorations (drawn by the application) on desktop systems that do
not support server-side decorations (drawn by the window manager). On systems
that do not provide either libdecor or xdg-decoration, very basic window
decorations are provided. These do not include the window title or any caption
buttons.
GLFW uses the [xdg-decoration
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
to request decorations to be drawn around its windows. This protocol is part
@@ -146,7 +161,7 @@ formats. If GLX 1.3 is not supported, @ref glfwInit will fail.
GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and
`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization
(or _vsync_), in that order of preference. Where none of these extension are
(or _vsync_), in that order of preference. When none of these extensions are
available, calling @ref glfwSwapInterval will have no effect.
GLFW uses the `GLX_ARB_multisample` extension to create contexts with
@@ -215,8 +230,8 @@ extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no
effect and the context will always be flushed when released.
GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB`
extensions to provide support for sRGB framebuffers. Where both of these
extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
extensions to provide support for sRGB framebuffers. When both of these
extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
@section compat_osx OpenGL on macOS
+9 -8
View File
@@ -45,7 +45,7 @@ Linux and FreeBSD you will need a few extra packages.
To compile GLFW for X11, you need to have the X11 development packages
installed. They are not needed to build or run programs that use GLFW.
On Debian and derivates like Ubuntu and Linux Mint the `xorg-dev` meta-package
On Debian and derivatives like Ubuntu and Linux Mint the `xorg-dev` meta-package
pulls in the development packages for all of X11.
@code{.sh}
@@ -82,8 +82,9 @@ To compile GLFW for Wayland, you need to have the Wayland and xkbcommon
development packages installed. They are not needed to build or run programs
that use GLFW.
On Debian and derivates like Ubuntu and Linux Mint you will need the `libwayland-dev`,
On Debian and derivatives like Ubuntu and Linux Mint you will need the `libwayland-dev`,
`libxkbcommon-dev`, `wayland-protocols` and `extra-cmake-modules` packages.
These will pull in all other dependencies.
@code{.sh}
sudo apt install libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules
@@ -96,11 +97,11 @@ On Fedora and derivatives like Red Hat you will need the `wayland-devel`,
sudo dnf install wayland-devel libxkbcommon-devel wayland-protocols-devel extra-cmake-modules
@endcode
On FreeBSD you will need the `wayland`, `libxkbcommon`, `wayland-protocols` and
`kf5-extra-cmake-modules` packages.
On FreeBSD you will need the `wayland`, `libxkbcommon`, `wayland-protocols`,
`evdev-proto` and `kf5-extra-cmake-modules` packages.
@code{.sh}
pkg install wayland libxkbcommon wayland-protocols kf5-extra-cmake-modules
pkg install wayland libxkbcommon wayland-protocols evdev-proto kf5-extra-cmake-modules
@endcode
Once you have the required depdendencies, move on to @ref compile_generate.
@@ -137,7 +138,7 @@ If you wish change any CMake variables in the list, press _Configure_ and then
_Generate_ to have the new values take effect. The variable list will be
populated after the first configure step.
By default GLFW will use X11 on Linux and other Unix-like systems other
By default, GLFW will use X11 on Linux and other Unix-like systems other
than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` option in the
GLFW section of the variable list, then apply the new value as described above.
@@ -171,7 +172,7 @@ flag.
cmake -S path/to/glfw -B path/to/build -G Xcode
@endcode
By default GLFW will use X11 on Linux and other Unix-like systems other
By default, GLFW will use X11 on Linux and other Unix-like systems other
than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` CMake option.
@code{.sh}
@@ -327,7 +328,7 @@ For more details see the
@section compile_manual Compiling GLFW manually
If you wish to compile GLFW without its CMake build environment then you will
have to do at least some of the platform detection yourself. GLFW needs
have to do at least some of the platform-detection yourself. GLFW needs
a configuration macro to be defined in order to know what window system it is
being compiled for and also has optional, platform-specific ones for various
features.
+7 -6
View File
@@ -61,7 +61,7 @@ information. The name and number of this chapter unfortunately varies between
versions and APIs, but has at times been named _Shared Objects and Multiple
Contexts_.
GLFW comes with a barebones object sharing example program called `sharing`.
GLFW comes with a bare-bones object sharing example program called `sharing`.
@subsection context_offscreen Offscreen contexts
@@ -92,9 +92,10 @@ creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
@subsection context_less Windows without contexts
You can disable context creation by setting the
[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`. Windows
without contexts must not be passed to @ref glfwMakeContextCurrent or @ref
glfwSwapBuffers.
[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`.
Windows without contexts should not be passed to @ref glfwMakeContextCurrent or
@ref glfwSwapBuffers. Doing this generates a @ref GLFW_NO_WINDOW_CONTEXT error.
@section context_current Current context
@@ -193,7 +194,7 @@ it suppresses the development environment's OpenGL or OpenGL ES header.
#include <GLFW/glfw3.h>
@endcode
Finally you need to initialize glad once you have a suitable current context.
Finally, you need to initialize glad once you have a suitable current context.
@code
window = glfwCreateWindow(640, 480, "My Window", NULL, NULL);
@@ -209,7 +210,7 @@ gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
Once glad has been loaded, you have access to all OpenGL core and extension
functions supported by both the context you created and the glad loader you
generated and you are ready to start rendering.
generated. After that, you are ready to start rendering.
You can specify a minimum required OpenGL or OpenGL ES version with
[context hints](@ref window_hints_ctx). If your needs are more complex, you can
+24 -15
View File
@@ -24,7 +24,7 @@ All input callbacks receive a window handle. By using the
or objects from your callbacks.
To get a better feel for how the various events callbacks behave, run the
`events` test program. It register every callback supported by GLFW and prints
`events` test program. It registers every callback supported by GLFW and prints
out all arguments provided for every event, along with time and sequence
information.
@@ -95,7 +95,7 @@ new size before everything returns back out of the @ref glfwSetWindowSize call.
GLFW divides keyboard input into two categories; key events and character
events. Key events relate to actual physical keyboard keys, whereas character
events relate to the Unicode code points generated by pressing some of them.
events relate to the text that is generated by pressing some of them.
Keys and characters do not map 1:1. A single key press may produce several
characters, and a single character may require several keys to produce. This
@@ -127,6 +127,10 @@ The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. Events with
`GLFW_PRESS` and `GLFW_RELEASE` actions are emitted for every key press. Most
keys will also emit events with `GLFW_REPEAT` actions while a key is held down.
Note that many keyboards have a limit on how many keys being simultaneous held
down that they can detect. This limit is called
[key rollover](https://en.wikipedia.org/wiki/Key_rollover).
Key events with `GLFW_REPEAT` actions are intended for text input. They are
emitted at the rate set in the user's keyboard settings. At most one key is
repeated even if several keys are held down. `GLFW_REPEAT` actions should not
@@ -142,16 +146,16 @@ keys.
The scancode is unique for every key, regardless of whether it has a key token.
Scancodes are platform-specific but consistent over time, so keys will have
different scancodes depending on the platform but they are safe to save to disk.
You can query the scancode for any [named key](@ref keys) on the current
platform with @ref glfwGetKeyScancode.
You can query the scancode for any [key token](@ref keys) supported on the
current platform with @ref glfwGetKeyScancode.
@code
const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
set_key_mapping(scancode, swap_weapons);
@endcode
The last reported state for every [named key](@ref keys) is also saved in
per-window state arrays that can be polled with @ref glfwGetKey.
The last reported state for every physical key with a [key token](@ref keys) is
also saved in per-window state arrays that can be polled with @ref glfwGetKey.
@code
int state = glfwGetKey(window, GLFW_KEY_E);
@@ -164,7 +168,8 @@ if (state == GLFW_PRESS)
The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
This function only returns cached key event state. It does not poll the
system for the current physical state of the key.
system for the current state of the physical key. It also does not provide any
key repeat information.
@anchor GLFW_STICKY_KEYS
Whenever you poll state, you risk missing the state change you are looking for.
@@ -195,15 +200,15 @@ Lock was on when the event occurred and the @ref GLFW_MOD_NUM_LOCK bit set if
Num Lock was on.
The `GLFW_KEY_LAST` constant holds the highest value of any
[named key](@ref keys).
[key token](@ref keys).
@subsection input_char Text input
GLFW supports text input in the form of a stream of
[Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the
operating system text input system. Unlike key input, text input obeys keyboard
layouts and modifier keys and supports composing characters using
operating system text input system. Unlike key input, text input is affected by
keyboard layouts and modifier keys and supports composing characters using
[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can
encode the code points into UTF-8 or any other encoding you prefer.
@@ -382,15 +387,18 @@ sequential rows, starting from the top-left corner.
@subsubsection cursor_standard Standard cursor creation
A cursor with a [standard shape](@ref shapes) from the current system cursor
theme can be can be created with @ref glfwCreateStandardCursor.
theme can be created with @ref glfwCreateStandardCursor.
@code
GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
@endcode
These cursor objects behave in the exact same way as those created with @ref
glfwCreateCursor except that the system cursor theme provides the actual image.
A few of these shapes are not available everywhere. If a shape is unavailable,
`NULL` is returned. See @ref glfwCreateStandardCursor for details.
@subsubsection cursor_destruction Cursor destruction
@@ -487,8 +495,9 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
Mouse button states for [named buttons](@ref buttons) are also saved in
per-window state arrays that can be polled with @ref glfwGetMouseButton.
The last reported state for every [supported mouse button](@ref buttons) is also
saved in per-window state arrays that can be polled with @ref
glfwGetMouseButton.
@code
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
@@ -521,7 +530,7 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
otherwise it will remain `GLFW_PRESS`.
The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
[named button](@ref buttons).
[supported mouse button](@ref buttons).
@subsection scrolling Scroll input
+32 -7
View File
@@ -102,6 +102,30 @@ a nib or manually, when the first window is created, which is when AppKit is
initialized. Set this with @ref glfwInitHint.
@subsubsection init_hints_wayland Wayland specific init hints
@anchor GLFW_WAYLAND_LIBDECOR_hint
__GLFW_WAYLAND_LIBDECOR__ specifies whether to use
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) for window
decorations where available. Possible values are `GLFW_WAYLAND_PREFER_LIBDECOR`
and `GLFW_WAYLAND_DISABLE_LIBDECOR`. This is ignored on other platforms.
@note This init hint was added in 3.3.9 and is not present in earlier patch releases. It
is safe to attempt to set this hint on earlier versions of GLFW 3.3 but it will emit
a harmless @ref GLFW_INVALID_ENUM error. If you need to avoid causing any errors, you can
check the library version first with @ref glfwGetVersion.
@note To set this hint while also building against earlier versions of GLFW 3.3, you can
use the numerical constants directly.
@note @code
int minor, patch;
glfwGetVersion(NULL, &minor, &patch);
if (minor > 3 || (minor == 3 && patch >= 9))
glfwInitHint(0x00053001 /*GLFW_WAYLAND_LIBDECOR*/, 0x00038002 /*GLFW_WAYLAND_DISABLE_LIBDECOR*/);
@endcode
@subsubsection init_hints_values Supported and default values
Initialization hint | Default value | Supported values
@@ -109,6 +133,7 @@ Initialization hint | Default value | Supported values
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_WAYLAND_LIBDECOR | `GLFW_WAYLAND_PREFER_LIBDECOR` | `GLFW_WAYLAND_PREFER_LIBDECOR` or `GLFW_WAYLAND_DISABLE_LIBDECOR`
@subsection intro_init_terminate Terminating GLFW
@@ -124,9 +149,9 @@ This will destroy any remaining window, monitor and cursor objects, restore any
modified gamma ramps, re-enable the screensaver if it had been disabled and free
any other resources allocated by GLFW.
Once the library is terminated, it is as if it had never been initialized and
Once the library is terminated, it is as if it had never been initialized, therefore
you will need to initialize it again before being able to use GLFW. If the
library was not initialized or had already been terminated, it return
library was not initialized or had already been terminated, it returns
immediately.
@@ -246,14 +271,14 @@ which monitor the window is currently considered to be on.
This section describes the conditions under which GLFW can be expected to
function, barring bugs in the operating system or drivers. Use of GLFW outside
of these limits may work on some platforms, or on some machines, or some of the
these limits may work on some platforms, or on some machines, or some of the
time, or on some versions of GLFW, but it may break at any time and this will
not be considered a bug.
@subsection lifetime Pointer lifetimes
GLFW will never free any pointer you provide to it and you must never free any
GLFW will never free any pointer you provide to it, and you must never free any
pointer it provides to you.
Many GLFW functions return pointers to dynamically allocated structures, strings
@@ -444,11 +469,11 @@ The format of the string is as follows:
- The name of the context creation API
- Any additional options or APIs
For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL
back ends, the version string may look something like this:
For example, when compiling GLFW 3.3.9 with MinGW for Windows, may result in
a version string like this:
@code
3.0.0 Win32 WGL MinGW
3.3.9 Win32 WGL EGL OSMesa MinGW
@endcode
*/
+2 -2
View File
@@ -138,7 +138,7 @@ glfwGetMonitorPhysicalSize(monitor, &width_mm, &height_mm);
@endcode
While this can be used to calculate the raw DPI of a monitor, this is often not
useful. Instead use the [monitor content scale](@ref monitor_scale) and
useful. Instead, use the [monitor content scale](@ref monitor_scale) and
[window content scale](@ref window_scale) to scale your content.
@@ -261,7 +261,7 @@ To experiment with gamma correction via the @ref glfwSetGamma function, run the
`gamma` test program.
@note The software controlled gamma ramp is applied _in addition_ to the
hardware gamma correction, which today is usually an approximation of sRGB
hardware gamma correction, which today is typically an approximation of sRGB
gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
produce the default (usually sRGB-like) behavior.
+3 -3
View File
@@ -243,7 +243,7 @@ while (!glfwWindowShouldClose(window))
@endcode
The close callback no longer returns a value. Instead, it is called after the
close flag has been set so it can override its value, if it chooses to, before
close flag has been set, so it can optionally override its value, before
event processing completes. You may however not call @ref glfwDestroyWindow
from the close callback (or any other window related callback).
@@ -350,11 +350,11 @@ from a repeat. Note that @ref glfwGetKey still returns only `GLFW_PRESS` or
GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to
the values generated by the current keyboard layout. The tokens are named
according to the values they would have using the standard US layout, but this
according to the values they would have in the standard US layout, but this
is only a convenience, as most programmers are assumed to know that layout.
This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and
is the same key in the same place regardless of what keyboard layouts the users
of your program has.
of your program have.
The key input facility was never meant for text input, although using it that
way worked slightly better in GLFW 2. If you were using it to input text, you
+26
View File
@@ -37,6 +37,16 @@ SDK](https://vulkan.lunarg.com/).
For more information see @ref vulkan_guide.
@subsubsection wayland_libdecor_33 Wayland libdecor decorations
GLFW now supports improved fallback window decorations via
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor).
Support for libdecor can be toggled before GLFW is initialized with the
[GLFW_WAYLAND_LIBDECOR](@ref GLFW_WAYLAND_LIBDECOR_hint) init hint. It is
enabled by default.
@subsubsection content_scale_33 Content scale queries for DPI-aware rendering
GLFW now provides content scales for windows and monitors, i.e. the ratio
@@ -312,6 +322,19 @@ Starting with GLFW 3.3.7, events posted with @ref glfwPostEmptyEvent now use a s
unnamed pipe instead of sending an X11 client event to the helper window.
@subsubsection wayland_alpha_33 Framebuffer may lack alpha channel on older Wayland systems
On Wayland, when creating an EGL context on a machine lacking the new
`EGL_EXT_present_opaque` extension, the @ref GLFW_ALPHA_BITS window hint will be
ignored and the framebuffer will have no alpha channel. This is because some
Wayland compositors treat any buffer with an alpha channel as per-pixel
transparent.
If you want a per-pixel transparent window, see the
[GLFW_TRANSPARENT_FRAMEBUFFER](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) window
hint.
@subsection deprecations_33 Deprecations in version 3.3
@subsubsection charmods_callback_33 Character with modifiers callback
@@ -430,6 +453,9 @@ Use Wayland or X11 instead.
- @ref GLFWwindowmaximizefun
- @ref GLFWwindowcontentscalefun
- @ref GLFWgamepadstate
- @ref GLFW_WAYLAND_LIBDECOR
- @ref GLFW_WAYLAND_PREFER_LIBDECOR
- @ref GLFW_WAYLAND_DISABLE_LIBDECOR
@subsubsection constants_33 New constants in version 3.3
+1 -5
View File
@@ -144,10 +144,6 @@ if (!window)
}
@endcode
The window handle is passed to all window related functions and is provided to
along to all window related callbacks, so they can tell which window received
the event.
When a window and context is no longer needed, destroy it.
@code
@@ -233,7 +229,7 @@ events as described below.
@subsection quick_render Rendering with OpenGL
Once you have a current OpenGL context, you can use OpenGL normally. In this
tutorial, a multi-colored rotating triangle will be rendered. The framebuffer
tutorial, a multicolored rotating triangle will be rendered. The framebuffer
size needs to be retrieved for `glViewport`.
@code
+1 -1
View File
@@ -131,7 +131,7 @@ PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
@endcode
Device-specific functions may execute a little bit faster, due to not having to
Device-specific functions may execute a little faster, due to not having to
dispatch internally based on the device passed to them. For more information
about `vkGetDeviceProcAddr`, see the Vulkan documentation.
+2 -1
View File
@@ -471,7 +471,8 @@ should also declare this in its `Info.plist` by setting the
@anchor GLFW_X11_CLASS_NAME_hint
@anchor GLFW_X11_INSTANCE_NAME_hint
__GLFW_X11_CLASS_NAME__ and __GLFW_X11_INSTANCE_NAME__ specifies the desired
ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property.
ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. Both
hints need to be set to something other than an empty string for them to take effect.
These are set with @ref glfwWindowHintString.
+169 -43
View File
@@ -298,7 +298,7 @@ extern "C" {
* release is made that does not contain any API changes.
* @ingroup init
*/
#define GLFW_VERSION_REVISION 8
#define GLFW_VERSION_REVISION 10
/*! @} */
/*! @brief One.
@@ -361,10 +361,15 @@ extern "C" {
#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP)
#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
/*! @ingroup input
*/
#define GLFW_KEY_UNKNOWN -1
/*! @} */
/*! @defgroup keys Keyboard keys
* @brief Keyboard key IDs.
/*! @defgroup keys Keyboard key tokens
* @brief Keyboard key tokens.
*
* See [key input](@ref input_key) for how these are used.
*
@@ -387,9 +392,6 @@ extern "C" {
* @{
*/
/* The unknown key */
#define GLFW_KEY_UNKNOWN -1
/* Printable keys */
#define GLFW_KEY_SPACE 32
#define GLFW_KEY_APOSTROPHE 39 /* ' */
@@ -785,6 +787,17 @@ extern "C" {
* @analysis Application programmer error. Fix the offending call.
*/
#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
/*! @brief The specified cursor shape is not available.
*
* The specified standard cursor shape is not available, either because the
* current system cursor theme does not provide it or because it is not
* available on the platform.
*
* @analysis Platform or system settings limitation. Pick another
* [standard cursor shape](@ref shapes) or create a
* [custom cursor](@ref cursor_custom).
*/
#define GLFW_CURSOR_UNAVAILABLE 0x0001000B
/*! @} */
/*! @addtogroup window
@@ -1063,17 +1076,21 @@ extern "C" {
#define GLFW_EGL_CONTEXT_API 0x00036002
#define GLFW_OSMESA_CONTEXT_API 0x00036003
#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
/*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes.
*
* See [standard cursor creation](@ref cursor_standard) for how these are used.
* These are the [standard cursor shapes](@ref cursor_standard) that can be
* requested from the window system.
*
* @ingroup input
* @{ */
/*! @brief The regular arrow cursor shape.
*
* The regular arrow cursor.
* The regular arrow cursor shape.
*/
#define GLFW_ARROW_CURSOR 0x00036001
/*! @brief The text input I-beam cursor shape.
@@ -1081,26 +1098,91 @@ extern "C" {
* The text input I-beam cursor shape.
*/
#define GLFW_IBEAM_CURSOR 0x00036002
/*! @brief The crosshair shape.
/*! @brief The crosshair cursor shape.
*
* The crosshair shape.
* The crosshair cursor shape.
*/
#define GLFW_CROSSHAIR_CURSOR 0x00036003
/*! @brief The hand shape.
/*! @brief The pointing hand cursor shape.
*
* The hand shape.
* The pointing hand cursor shape.
*/
#define GLFW_HAND_CURSOR 0x00036004
/*! @brief The horizontal resize arrow shape.
#define GLFW_POINTING_HAND_CURSOR 0x00036004
/*! @brief The horizontal resize/move arrow shape.
*
* The horizontal resize arrow shape.
* The horizontal resize/move arrow shape. This is usually a horizontal
* double-headed arrow.
*/
#define GLFW_HRESIZE_CURSOR 0x00036005
/*! @brief The vertical resize arrow shape.
#define GLFW_RESIZE_EW_CURSOR 0x00036005
/*! @brief The vertical resize/move arrow shape.
*
* The vertical resize arrow shape.
* The vertical resize/move shape. This is usually a vertical double-headed
* arrow.
*/
#define GLFW_VRESIZE_CURSOR 0x00036006
#define GLFW_RESIZE_NS_CURSOR 0x00036006
/*! @brief The top-left to bottom-right diagonal resize/move arrow shape.
*
* The top-left to bottom-right diagonal resize/move shape. This is usually
* a diagonal double-headed arrow.
*
* @note @macos This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* cursor themes.
*
* @note @wayland This shape is provided by a newer standard not supported by
* all cursor themes.
*/
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
/*! @brief The top-right to bottom-left diagonal resize/move arrow shape.
*
* The top-right to bottom-left diagonal resize/move shape. This is usually
* a diagonal double-headed arrow.
*
* @note @macos This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* cursor themes.
*
* @note @wayland This shape is provided by a newer standard not supported by
* all cursor themes.
*/
#define GLFW_RESIZE_NESW_CURSOR 0x00036008
/*! @brief The omni-directional resize/move cursor shape.
*
* The omni-directional resize cursor/move shape. This is usually either
* a combined horizontal and vertical double-headed arrow or a grabbing hand.
*/
#define GLFW_RESIZE_ALL_CURSOR 0x00036009
/*! @brief The operation-not-allowed shape.
*
* The operation-not-allowed shape. This is usually a circle with a diagonal
* line through it.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* cursor themes.
*
* @note @wayland This shape is provided by a newer standard not supported by
* all cursor themes.
*/
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
/*! @brief Legacy name for compatibility.
*
* This is an alias for compatibility with earlier versions.
*/
#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR
/*! @brief Legacy name for compatibility.
*
* This is an alias for compatibility with earlier versions.
*/
#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR
/*! @brief Legacy name for compatibility.
*
* This is an alias for compatibility with earlier versions.
*/
#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR
/*! @} */
#define GLFW_CONNECTED 0x00040001
@@ -1123,6 +1205,11 @@ extern "C" {
* macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint).
*/
#define GLFW_COCOA_MENUBAR 0x00051002
/*! @brief Wayland specific init hint.
*
* Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint).
*/
#define GLFW_WAYLAND_LIBDECOR 0x00053001
/*! @} */
#define GLFW_DONT_CARE -1
@@ -2601,8 +2688,8 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref
* GLFW_PLATFORM_ERROR.
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
*
* @remark @win32 Window creation will fail if the Microsoft GDI software
* OpenGL implementation is the only one available.
@@ -3551,11 +3638,15 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
* @param[in] value `GLFW_TRUE` or `GLFW_FALSE`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR.
*
* @remark Calling @ref glfwGetWindowAttrib will always return the latest
* value, even if that value is ignored by the current mode of the window.
*
* @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window
* attribute is not supported. Setting this will emit @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_attribs
@@ -4230,8 +4321,8 @@ GLFWAPI int glfwRawMouseMotionSupported(void);
* @param[in] scancode The scancode of the key to query.
* @return The UTF-8 encoded, layout-specific name of the key, or `NULL`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
*
* @remark The contents of the returned string may change when a keyboard
* layout change event is received.
@@ -4253,15 +4344,18 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode);
*
* This function returns the platform-specific scancode of the specified key.
*
* If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this
* method will return `-1`.
* If the specified [key token](@ref keys) corresponds to a physical key not
* supported on the current platform then this method will return `-1`.
* Calling this function with anything other than a key token will return `-1`
* and generate a @ref GLFW_INVALID_ENUM error.
*
* @param[in] key Any [named key](@ref keys).
* @return The platform-specific scancode for the key, or `-1` if an
* [error](@ref error_handling) occurred.
* @param[in] key Any [key token](@ref keys).
* @return The platform-specific scancode for the key, or `-1` if the key is
* not supported on the current platform or an [error](@ref error_handling)
* occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_ENUM.
*
* @thread_safety This function may be called from any thread.
*
@@ -4459,19 +4553,44 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
/*! @brief Creates a cursor with a standard shape.
*
* Returns a cursor with a [standard shape](@ref shapes), that can be set for
* a window with @ref glfwSetCursor.
* Returns a cursor with a standard shape, that can be set for a window with
* @ref glfwSetCursor. The images for these cursors come from the system
* cursor theme and their exact appearance will vary between platforms.
*
* Most of these shapes are guaranteed to exist on every supported platform but
* a few may not be present. See the table below for details.
*
* Cursor shape | Windows | macOS | X11 | Wayland
* ------------------------------ | ------- | ----- | ------ | -------
* @ref GLFW_ARROW_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_IBEAM_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_CROSSHAIR_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_POINTING_HAND_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_RESIZE_EW_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_RESIZE_NS_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_RESIZE_NWSE_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
* @ref GLFW_RESIZE_NESW_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
* @ref GLFW_RESIZE_ALL_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_NOT_ALLOWED_CURSOR | Yes | Yes | Maybe<sup>2</sup> | Maybe<sup>2</sup>
*
* 1) This uses a private system API and may fail in the future.
*
* 2) This uses a newer standard that not all cursor themes support.
*
* If the requested shape is not available, this function emits a @ref
* GLFW_CURSOR_UNAVAILABLE error and returns `NULL`.
*
* @param[in] shape One of the [standard shapes](@ref shapes).
* @return A new cursor ready to use or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
* GLFW_INVALID_ENUM, @ref GLFW_CURSOR_UNAVAILABLE and @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref cursor_object
* @sa @ref cursor_standard
* @sa @ref glfwCreateCursor
*
* @since Added in version 3.1.
@@ -4545,9 +4664,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
* [character callback](@ref glfwSetCharCallback) instead.
*
* When a window loses input focus, it will generate synthetic key release
* events for all pressed keys. You can tell these events from user-generated
* events by the fact that the synthetic ones are generated after the focus
* loss event has been processed, i.e. after the
* events for all pressed keys with associated key tokens. You can tell these
* events from user-generated events by the fact that the synthetic ones are
* generated after the focus loss event has been processed, i.e. after the
* [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
*
* The scancode of a key is specific to that platform or sometimes even to that
@@ -5446,12 +5565,15 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
* thread.
*
* This function makes the OpenGL or OpenGL ES context of the specified window
* current on the calling thread. A context must only be made current on
* a single thread at a time and each thread can have only a single current
* context at a time.
* current on the calling thread. It can also detach the current context from
* the calling thread without making a new one current by passing in `NULL`.
*
* When moving a context between threads, you must make it non-current on the
* old thread before making it current on the new one.
* A context must only be made current on a single thread at a time and each
* thread can have only a single current context at a time. Making a context
* current detaches any previously current context on the calling thread.
*
* When moving a context between threads, you must detach it (make it
* non-current) on the old thread before making it current on the new one.
*
* By default, making a context non-current implicitly forces a pipeline flush.
* On machines that support `GL_KHR_context_flush_control`, you can control
@@ -5466,6 +5588,10 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
* @param[in] window The window whose context to make current, or `NULL` to
* detach the current context.
*
* @remarks If the previously current context was created via a different
* context creation API than the one passed to this function, GLFW will still
* detach the previous one from its API before making the new one current.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
*
+9 -3
View File
@@ -103,17 +103,23 @@ extern "C" {
#undef GLFW_APIENTRY_DEFINED
#endif
#include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
#endif
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
+1
View File
@@ -168,6 +168,7 @@ if (BUILD_SHARED_LIBS)
# Add a suffix to the import library to avoid naming conflicts
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
endif()
set (GLFW_LIB_NAME_SUFFIX "dll")
target_compile_definitions(glfw INTERFACE GLFW_DLL)
elseif (APPLE)
+1 -1
View File
@@ -251,7 +251,7 @@ static void createKeyTables(void)
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
_glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
_glfw.ns.keycodes[0x69] = GLFW_KEY_F13;
_glfw.ns.keycodes[0x69] = GLFW_KEY_PRINT_SCREEN;
_glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
_glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
+8 -3
View File
@@ -137,6 +137,14 @@ static void matchCallback(void* context,
return;
}
CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
// It is reportedly possible for this to fail on macOS 13 Ventura
// if the application does not have input monitoring permissions
if (!elements)
return;
axes = CFArrayCreateMutable(NULL, 0, NULL);
buttons = CFArrayCreateMutable(NULL, 0, NULL);
hats = CFArrayCreateMutable(NULL, 0, NULL);
@@ -180,9 +188,6 @@ static void matchCallback(void* context,
name[8], name[9], name[10]);
}
CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
for (i = 0; i < CFArrayGetCount(elements); i++)
{
IOHIDElementRef native = (IOHIDElementRef)
+53 -21
View File
@@ -309,10 +309,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidChangeOcclusionState:(NSNotification* )notification
{
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
window->ns.occluded = GLFW_FALSE;
else
window->ns.occluded = GLFW_TRUE;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
if ([window->ns.object respondsToSelector:@selector(occlusionState)])
{
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
window->ns.occluded = GLFW_FALSE;
else
window->ns.occluded = GLFW_TRUE;
}
#endif
}
@end
@@ -1260,7 +1265,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
if (window->monitor)
{
styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable);
styleMask |= NSWindowStyleMaskBorderless;
}
else
@@ -1630,14 +1635,15 @@ const char* _glfwPlatformGetScancodeName(int scancode)
{
@autoreleasepool {
if (scancode < 0 || scancode > 0xff ||
_glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN)
if (scancode < 0 || scancode > 0xff)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
return NULL;
}
const int key = _glfw.ns.keycodes[scancode];
if (key == GLFW_KEY_UNKNOWN)
return NULL;
UInt32 deadKeyState = 0;
UniChar characters[4];
@@ -1728,23 +1734,49 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
@autoreleasepool {
if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR)
cursor->ns.object = [NSCursor IBeamCursor];
else if (shape == GLFW_CROSSHAIR_CURSOR)
cursor->ns.object = [NSCursor crosshairCursor];
else if (shape == GLFW_HAND_CURSOR)
cursor->ns.object = [NSCursor pointingHandCursor];
else if (shape == GLFW_HRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeLeftRightCursor];
else if (shape == GLFW_VRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeUpDownCursor];
SEL cursorSelector = NULL;
// HACK: Try to use a private message
if (shape == GLFW_RESIZE_EW_CURSOR)
cursorSelector = @selector(_windowResizeEastWestCursor);
else if (shape == GLFW_RESIZE_NS_CURSOR)
cursorSelector = @selector(_windowResizeNorthSouthCursor);
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
cursorSelector = @selector(_windowResizeNorthWestSouthEastCursor);
else if (shape == GLFW_RESIZE_NESW_CURSOR)
cursorSelector = @selector(_windowResizeNorthEastSouthWestCursor);
if (cursorSelector && [NSCursor respondsToSelector:cursorSelector])
{
id object = [NSCursor performSelector:cursorSelector];
if ([object isKindOfClass:[NSCursor class]])
cursor->ns.object = object;
}
if (!cursor->ns.object)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve standard cursor");
if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR)
cursor->ns.object = [NSCursor IBeamCursor];
else if (shape == GLFW_CROSSHAIR_CURSOR)
cursor->ns.object = [NSCursor crosshairCursor];
else if (shape == GLFW_POINTING_HAND_CURSOR)
cursor->ns.object = [NSCursor pointingHandCursor];
else if (shape == GLFW_RESIZE_EW_CURSOR)
cursor->ns.object = [NSCursor resizeLeftRightCursor];
else if (shape == GLFW_RESIZE_NS_CURSOR)
cursor->ns.object = [NSCursor resizeUpDownCursor];
else if (shape == GLFW_RESIZE_ALL_CURSOR)
cursor->ns.object = [NSCursor closedHandCursor];
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
cursor->ns.object = [NSCursor operationNotAllowedCursor];
}
if (!cursor->ns.object)
{
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
"Cocoa: Standard cursor shape unavailable");
return GLFW_FALSE;
}
+19 -10
View File
@@ -48,16 +48,6 @@
//
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
}
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
ctxconfig->source != GLFW_EGL_CONTEXT_API &&
ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
@@ -78,6 +68,23 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
return GLFW_FALSE;
}
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (ctxconfig->source != ctxconfig->share->context.source)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Context creation APIs do not match between contexts");
return GLFW_FALSE;
}
}
if (ctxconfig->client == GLFW_OPENGL_API)
{
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
@@ -356,6 +363,8 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
glfwMakeContextCurrent((GLFWwindow*) window);
if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
return GLFW_FALSE;
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
window->context.getProcAddress("glGetIntegerv");
+76 -35
View File
@@ -88,13 +88,30 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
// Return the EGLConfig most closely matching the specified hints
//
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* desired,
const _GLFWfbconfig* fbconfig,
EGLConfig* result)
{
EGLConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int i, nativeCount, usableCount;
int i, nativeCount, usableCount, apiBit;
GLFWbool wrongApiAvailable = GLFW_FALSE;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
apiBit = EGL_OPENGL_ES_BIT;
else
apiBit = EGL_OPENGL_ES2_BIT;
}
else
apiBit = EGL_OPENGL_BIT;
if (fbconfig->stereo)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
return GLFW_FALSE;
}
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
if (!nativeCount)
@@ -131,7 +148,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (!vi.visualid)
continue;
if (desired->transparent)
if (fbconfig->transparent)
{
int count;
XVisualInfo* vis =
@@ -145,23 +162,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
}
#endif // _GLFW_X11
if (ctxconfig->client == GLFW_OPENGL_ES_API)
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit))
{
if (ctxconfig->major == 1)
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
continue;
}
else
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
continue;
}
}
else if (ctxconfig->client == GLFW_OPENGL_API)
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
continue;
wrongApiAvailable = GLFW_TRUE;
continue;
}
u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
@@ -172,16 +176,57 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
#if defined(_GLFW_WAYLAND)
// NOTE: The wl_surface opaque region is no guarantee that its buffer
// is presented as opaque, if it also has an alpha channel
// HACK: If EGL_EXT_present_opaque is unavailable, ignore any config
// with an alpha channel to ensure the buffer is opaque
if (!_glfw.egl.EXT_present_opaque)
{
if (!fbconfig->transparent && u->alphaBits > 0)
continue;
}
#endif // _GLFW_WAYLAND
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = desired->doublebuffer;
u->doublebuffer = fbconfig->doublebuffer;
u->handle = (uintptr_t) n;
usableCount++;
}
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
if (closest)
*result = (EGLConfig) closest->handle;
else
{
if (wrongApiAvailable)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 1.x");
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 2 or later");
}
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL");
}
}
else
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
}
}
free(nativeConfigs);
free(usableConfigs);
@@ -259,6 +304,7 @@ static int extensionSupportedEGL(const char* extension)
static GLFWglproc getProcAddressEGL(const char* procname)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
if (window->context.egl.client)
{
@@ -485,11 +531,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
share = ctxconfig->share->context.egl.handle;
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
@@ -546,18 +588,18 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
}
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
}
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
}
if (mask)
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
@@ -609,8 +651,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (!fbconfig->doublebuffer)
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
#if defined(_GLFW_WAYLAND)
if (_glfw.egl.EXT_present_opaque)
setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
#endif // _GLFW_WAYLAND
setAttrib(EGL_NONE, EGL_NONE);
@@ -678,6 +722,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else
"libOpenGL.so.0",
"libGL.so.1",
#endif
NULL
@@ -740,11 +785,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const long vimask = VisualScreenMask | VisualIDMask;
if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE;
}
eglGetConfigAttrib(_glfw.egl.display, native,
EGL_NATIVE_VISUAL_ID, &visualID);
+1 -1
View File
@@ -8,6 +8,6 @@ Description: A multi-platform library for OpenGL, window and input
Version: @GLFW_VERSION@
URL: https://www.glfw.org/
Requires.private: @GLFW_PKG_DEPS@
Libs: -L${libdir} -l@GLFW_LIB_NAME@
Libs: -L${libdir} -l@GLFW_LIB_NAME@@GLFW_LIB_NAME_SUFFIX@
Libs.private: @GLFW_PKG_LIBS@
Cflags: -I${includedir}
+5
View File
@@ -190,6 +190,7 @@ static void swapBuffersGLX(_GLFWwindow* window)
static void swapIntervalGLX(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
if (_glfw.glx.EXT_swap_control)
{
@@ -226,7 +227,10 @@ static GLFWglproc getProcAddressGLX(const char* procname)
else if (_glfw.glx.GetProcAddressARB)
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
else
{
// NOTE: glvnd provides GLX 1.4, so this can only happen with libGL
return _glfw_dlsym(_glfw.glx.handle, procname);
}
}
static void destroyContextGLX(_GLFWwindow* window)
@@ -263,6 +267,7 @@ GLFWbool _glfwInitGLX(void)
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else
"libGLX.so.0",
"libGL.so.1",
"libGL.so",
#endif
-1
View File
@@ -127,7 +127,6 @@ typedef struct _GLFWlibraryGLX
int eventBase;
int errorBase;
// dlopen handle for libGL.so.1
void* handle;
// GLX 1.3 functions
+9 -1
View File
@@ -54,7 +54,10 @@ static _GLFWinitconfig _glfwInitHints =
{
GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir
}
},
{
GLFW_WAYLAND_PREFER_LIBDECOR // Wayland libdecor mode
},
};
// Terminate the library
@@ -281,6 +284,8 @@ void _glfwInputError(int code, const char* format, ...)
strcpy(description, "The requested format is unavailable");
else if (code == GLFW_NO_WINDOW_CONTEXT)
strcpy(description, "The specified window has no context");
else if (code == GLFW_CURSOR_UNAVAILABLE)
strcpy(description, "The specified cursor shape is unavailable");
else
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
}
@@ -367,6 +372,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
case GLFW_COCOA_MENUBAR:
_glfwInitHints.ns.menubar = value;
return;
case GLFW_WAYLAND_LIBDECOR:
_glfwInitHints.wl.libdecorMode = value;
return;
}
_glfwInputError(GLFW_INVALID_ENUM,
+15 -5
View File
@@ -616,6 +616,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
if (key != GLFW_KEY_UNKNOWN)
{
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
return NULL;
}
if (key != GLFW_KEY_KP_EQUAL &&
(key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) &&
(key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2))
@@ -631,12 +637,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
GLFWAPI int glfwGetKeyScancode(int key)
{
_GLFW_REQUIRE_INIT_OR_RETURN(-1);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
return GLFW_RELEASE;
return -1;
}
return _glfwPlatformGetKeyScancode(key);
@@ -780,9 +786,13 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
if (shape != GLFW_ARROW_CURSOR &&
shape != GLFW_IBEAM_CURSOR &&
shape != GLFW_CROSSHAIR_CURSOR &&
shape != GLFW_HAND_CURSOR &&
shape != GLFW_HRESIZE_CURSOR &&
shape != GLFW_VRESIZE_CURSOR)
shape != GLFW_POINTING_HAND_CURSOR &&
shape != GLFW_RESIZE_EW_CURSOR &&
shape != GLFW_RESIZE_NS_CURSOR &&
shape != GLFW_RESIZE_NWSE_CURSOR &&
shape != GLFW_RESIZE_NESW_CURSOR &&
shape != GLFW_RESIZE_ALL_CURSOR &&
shape != GLFW_NOT_ALLOWED_CURSOR)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
return NULL;
+3
View File
@@ -244,6 +244,9 @@ struct _GLFWinitconfig
GLFWbool menubar;
GLFWbool chdir;
} ns;
struct {
int libdecorMode;
} wl;
};
// Window configuration
+6 -4
View File
@@ -157,7 +157,7 @@ static GLFWbool openJoystickDevice(const char* path)
}
// Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
if (!isBitSet(EV_ABS, evBits))
{
close(linjs.fd);
return GLFW_FALSE;
@@ -283,7 +283,8 @@ GLFWbool _glfwInitJoysticksLinux(void)
// Continue without device connection notifications if inotify fails
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
_glfw.linjs.regexCompiled = (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) == 0);
if (!_glfw.linjs.regexCompiled)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
return GLFW_FALSE;
@@ -333,8 +334,6 @@ void _glfwTerminateJoysticksLinux(void)
closeJoystick(js);
}
regfree(&_glfw.linjs.regex);
if (_glfw.linjs.inotify > 0)
{
if (_glfw.linjs.watch > 0)
@@ -342,6 +341,9 @@ void _glfwTerminateJoysticksLinux(void)
close(_glfw.linjs.inotify);
}
if (_glfw.linjs.regexCompiled)
regfree(&_glfw.linjs.regex);
}
void _glfwDetectJoystickConnectionLinux(void)
+1
View File
@@ -53,6 +53,7 @@ typedef struct _GLFWlibraryLinux
int inotify;
int watch;
regex_t regex;
GLFWbool regexCompiled;
GLFWbool dropped;
} _GLFWlibraryLinux;
+5 -6
View File
@@ -81,11 +81,10 @@ static void swapIntervalNSGL(int interval)
@autoreleasepool {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window)
{
[window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
}
assert(window != NULL);
[window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
} // autoreleasepool
}
@@ -162,7 +161,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: OpenGL ES is not available on macOS");
"NSGL: OpenGL ES is not available via NSGL");
return GLFW_FALSE;
}
+2 -3
View File
@@ -27,13 +27,12 @@
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "internal.h"
static void makeContextCurrentOSMesa(_GLFWwindow* window)
{
if (window)
+14 -8
View File
@@ -73,18 +73,30 @@ static int choosePixelFormat(_GLFWwindow* window,
int attribs[40];
int values[sizeof(attribs) / sizeof(attribs[0])];
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
if (_glfw.wgl.ARB_pixel_format)
{
// NOTE: In a Parallels VM WGL_ARB_pixel_format returns fewer pixel formats than
// DescribePixelFormat, violating the guarantees of the extension spec
// HACK: Iterate through the minimum of both counts
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
int extensionCount;
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
1, 0, 1, &attrib, &nativeCount))
1, 0, 1, &attrib, &extensionCount))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
return 0;
}
nativeCount = _glfw_min(nativeCount, extensionCount);
addAttrib(WGL_SUPPORT_OPENGL_ARB);
addAttrib(WGL_DRAW_TO_WINDOW_ARB);
addAttrib(WGL_PIXEL_TYPE_ARB);
@@ -122,13 +134,6 @@ static int choosePixelFormat(_GLFWwindow* window,
addAttrib(WGL_COLORSPACE_EXT);
}
}
else
{
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
}
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
@@ -345,6 +350,7 @@ static void swapBuffersWGL(_GLFWwindow* window)
static void swapIntervalWGL(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
window->context.wgl.interval = interval;
+7
View File
@@ -736,6 +736,13 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
dpad |= GLFW_HAT_LEFT;
// Treat invalid combinations as neither being pressed
// while preserving what data can be preserved
if ((dpad & GLFW_HAT_RIGHT) && (dpad & GLFW_HAT_LEFT))
dpad &= ~(GLFW_HAT_RIGHT | GLFW_HAT_LEFT);
if ((dpad & GLFW_HAT_UP) && (dpad & GLFW_HAT_DOWN))
dpad &= ~(GLFW_HAT_UP | GLFW_HAT_DOWN);
_glfwInputJoystickHat(js, 0, dpad);
}
+2
View File
@@ -347,6 +347,8 @@ typedef struct _GLFWlibraryWin32
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// The window the cursor is captured in
_GLFWwindow* capturedCursorWindow;
RAWINPUT* rawInput;
int rawInputSize;
UINT mouseTrailSize;
+123 -85
View File
@@ -186,53 +186,38 @@ static HICON createIcon(const GLFWimage* image,
return handle;
}
// Translate content area size to full window size according to styles and DPI
//
static void getFullWindowSize(DWORD style, DWORD exStyle,
int contentWidth, int contentHeight,
int* fullWidth, int* fullHeight,
UINT dpi)
{
RECT rect = { 0, 0, contentWidth, contentHeight };
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
else
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
*fullWidth = rect.right - rect.left;
*fullHeight = rect.bottom - rect.top;
}
// Enforce the content area aspect ratio based on which edge is being dragged
//
static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
{
int xoff, yoff;
UINT dpi = USER_DEFAULT_SCREEN_DPI;
RECT frame = {0};
const float ratio = (float) window->numer / (float) window->denom;
const DWORD style = getWindowStyle(window);
const DWORD exStyle = getWindowExStyle(window);
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
dpi = GetDpiForWindow(window->win32.handle);
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
0, 0, &xoff, &yoff, dpi);
{
AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,
GetDpiForWindow(window->win32.handle));
}
else
AdjustWindowRectEx(&frame, style, FALSE, exStyle);
if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT ||
edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)
{
area->bottom = area->top + yoff +
(int) ((area->right - area->left - xoff) / ratio);
area->bottom = area->top + (frame.bottom - frame.top) +
(int) (((area->right - area->left) - (frame.right - frame.left)) / ratio);
}
else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT)
{
area->top = area->bottom - yoff -
(int) ((area->right - area->left - xoff) / ratio);
area->top = area->bottom - (frame.bottom - frame.top) -
(int) (((area->right - area->left) - (frame.right - frame.left)) / ratio);
}
else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM)
{
area->right = area->left + xoff +
(int) ((area->bottom - area->top - yoff) * ratio);
area->right = area->left + (frame.right - frame.left) +
(int) (((area->bottom - area->top) - (frame.bottom - frame.top)) * ratio);
}
}
@@ -251,20 +236,24 @@ static void updateCursorImage(_GLFWwindow* window)
SetCursor(NULL);
}
// Updates the cursor clip rect
// Sets the cursor clip rect to the window content area
//
static void updateClipRect(_GLFWwindow* window)
static void captureCursor(_GLFWwindow* window)
{
if (window)
{
RECT clipRect;
GetClientRect(window->win32.handle, &clipRect);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
ClipCursor(&clipRect);
}
else
ClipCursor(NULL);
RECT clipRect;
GetClientRect(window->win32.handle, &clipRect);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
ClipCursor(&clipRect);
_glfw.win32.capturedCursorWindow = window;
}
// Disabled clip cursor
//
static void releaseCursor(void)
{
ClipCursor(NULL);
_glfw.win32.capturedCursorWindow = NULL;
}
// Enables WM_INPUT messages for the mouse for the specified window
@@ -303,7 +292,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.win32.restoreCursorPosY);
updateCursorImage(window);
_glfwCenterCursorInContentArea(window);
updateClipRect(window);
captureCursor(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
@@ -317,7 +306,7 @@ static void enableCursor(_GLFWwindow* window)
disableRawMouseMotion(window);
_glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL);
releaseCursor();
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
@@ -1033,8 +1022,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
(window->win32.maximized &&
wParam != SIZE_RESTORED);
if (_glfw.win32.disabledCursorWindow == window)
updateClipRect(window);
if (_glfw.win32.capturedCursorWindow == window)
captureCursor(window);
if (window->win32.iconified != iconified)
_glfwInputWindowIconify(window, iconified);
@@ -1069,8 +1058,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOVE:
{
if (_glfw.win32.disabledCursorWindow == window)
updateClipRect(window);
if (_glfw.win32.capturedCursorWindow == window)
captureCursor(window);
// NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
// those macros do not handle negative window positions correctly
@@ -1094,31 +1083,34 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_GETMINMAXINFO:
{
int xoff, yoff;
UINT dpi = USER_DEFAULT_SCREEN_DPI;
RECT frame = {0};
MINMAXINFO* mmi = (MINMAXINFO*) lParam;
const DWORD style = getWindowStyle(window);
const DWORD exStyle = getWindowExStyle(window);
if (window->monitor)
break;
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
dpi = GetDpiForWindow(window->win32.handle);
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
0, 0, &xoff, &yoff, dpi);
{
AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,
GetDpiForWindow(window->win32.handle));
}
else
AdjustWindowRectEx(&frame, style, FALSE, exStyle);
if (window->minwidth != GLFW_DONT_CARE &&
window->minheight != GLFW_DONT_CARE)
{
mmi->ptMinTrackSize.x = window->minwidth + xoff;
mmi->ptMinTrackSize.y = window->minheight + yoff;
mmi->ptMinTrackSize.x = window->minwidth + frame.right - frame.left;
mmi->ptMinTrackSize.y = window->minheight + frame.bottom - frame.top;
}
if (window->maxwidth != GLFW_DONT_CARE &&
window->maxheight != GLFW_DONT_CARE)
{
mmi->ptMaxTrackSize.x = window->maxwidth + xoff;
mmi->ptMaxTrackSize.y = window->maxheight + yoff;
mmi->ptMaxTrackSize.x = window->maxwidth + frame.right - frame.left;
mmi->ptMaxTrackSize.y = window->maxheight + frame.bottom - frame.top;
}
if (!window->decorated)
@@ -1277,7 +1269,7 @@ static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{
int xpos, ypos, fullWidth, fullHeight;
int frameX, frameY, frameWidth, frameHeight;
WCHAR* wideTitle;
DWORD style = getWindowStyle(window);
DWORD exStyle = getWindowExStyle(window);
@@ -1290,24 +1282,25 @@ static int createNativeWindow(_GLFWwindow* window,
// NOTE: This window placement is temporary and approximate, as the
// correct position and size cannot be known until the monitor
// video mode has been picked in _glfwSetVideoModeWin32
xpos = mi.rcMonitor.left;
ypos = mi.rcMonitor.top;
fullWidth = mi.rcMonitor.right - mi.rcMonitor.left;
fullHeight = mi.rcMonitor.bottom - mi.rcMonitor.top;
frameX = mi.rcMonitor.left;
frameY = mi.rcMonitor.top;
frameWidth = mi.rcMonitor.right - mi.rcMonitor.left;
frameHeight = mi.rcMonitor.bottom - mi.rcMonitor.top;
}
else
{
xpos = CW_USEDEFAULT;
ypos = CW_USEDEFAULT;
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
window->win32.maximized = wndconfig->maximized;
if (wndconfig->maximized)
style |= WS_MAXIMIZE;
getFullWindowSize(style, exStyle,
wndconfig->width, wndconfig->height,
&fullWidth, &fullHeight,
USER_DEFAULT_SCREEN_DPI);
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
frameX = CW_USEDEFAULT;
frameY = CW_USEDEFAULT;
frameWidth = rect.right - rect.left;
frameHeight = rect.bottom - rect.top;
}
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
@@ -1318,8 +1311,8 @@ static int createNativeWindow(_GLFWwindow* window,
_GLFW_WNDCLASSNAME,
wideTitle,
style,
xpos, ypos,
fullWidth, fullHeight,
frameX, frameY,
frameWidth, frameHeight,
NULL, // No parent window
NULL, // No window menu
_glfw.win32.instance,
@@ -1540,7 +1533,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->context.destroy(window);
if (_glfw.win32.disabledCursorWindow == window)
_glfw.win32.disabledCursorWindow = NULL;
enableCursor(window);
if (_glfw.win32.capturedCursorWindow == window)
releaseCursor();
if (window->win32.handle)
{
@@ -2117,7 +2113,7 @@ void _glfwPlatformWaitEvents(void)
void _glfwPlatformWaitEventsTimeout(double timeout)
{
MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);
MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLINPUT);
_glfwPlatformPollEvents();
}
@@ -2156,27 +2152,58 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (mode == GLFW_CURSOR_DISABLED)
if (_glfwPlatformWindowFocused(window))
{
if (_glfwPlatformWindowFocused(window))
disableCursor(window);
if (mode == GLFW_CURSOR_DISABLED)
{
_glfwPlatformGetCursorPos(window,
&_glfw.win32.restoreCursorPosX,
&_glfw.win32.restoreCursorPosY);
_glfwCenterCursorInContentArea(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
}
else if (_glfw.win32.disabledCursorWindow == window)
{
if (window->rawMouseMotion)
disableRawMouseMotion(window);
}
if (mode == GLFW_CURSOR_DISABLED)
captureCursor(window);
else
releaseCursor();
if (mode == GLFW_CURSOR_DISABLED)
_glfw.win32.disabledCursorWindow = window;
else if (_glfw.win32.disabledCursorWindow == window)
{
_glfw.win32.disabledCursorWindow = NULL;
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
}
}
else if (_glfw.win32.disabledCursorWindow == window)
enableCursor(window);
else if (cursorInContentArea(window))
if (cursorInContentArea(window))
updateCursorImage(window);
}
const char* _glfwPlatformGetScancodeName(int scancode)
{
if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) ||
_glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN)
int key;
if (scancode < 0 || scancode > (KF_EXTENDED | 0xff))
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
return NULL;
}
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
key = _glfw.win32.keycodes[scancode];
if (key == GLFW_KEY_UNKNOWN)
return NULL;
return _glfw.win32.keynames[key];
}
int _glfwPlatformGetKeyScancode(int key)
@@ -2205,14 +2232,25 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
id = OCR_IBEAM;
else if (shape == GLFW_CROSSHAIR_CURSOR)
id = OCR_CROSS;
else if (shape == GLFW_HAND_CURSOR)
else if (shape == GLFW_POINTING_HAND_CURSOR)
id = OCR_HAND;
else if (shape == GLFW_HRESIZE_CURSOR)
else if (shape == GLFW_RESIZE_EW_CURSOR)
id = OCR_SIZEWE;
else if (shape == GLFW_VRESIZE_CURSOR)
else if (shape == GLFW_RESIZE_NS_CURSOR)
id = OCR_SIZENS;
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
id = OCR_SIZENWSE;
else if (shape == GLFW_RESIZE_NESW_CURSOR)
id = OCR_SIZENESW;
else if (shape == GLFW_RESIZE_ALL_CURSOR)
id = OCR_SIZEALL;
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
id = OCR_NO;
else
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Unknown standard cursor");
return GLFW_FALSE;
}
cursor->win32.handle = LoadImageW(NULL,
MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0,
+1 -1
View File
@@ -694,7 +694,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(1.f);
_GLFW_REQUIRE_INIT_OR_RETURN(0.f);
return _glfwPlatformGetWindowOpacity(window);
}
+201 -40
View File
@@ -40,6 +40,7 @@
#include <sys/timerfd.h>
#include <unistd.h>
#include <wayland-client.h>
#include <assert.h>
static void wmBaseHandlePing(void* userData,
struct xdg_wm_base* wmBase,
@@ -61,10 +62,9 @@ static void registryHandleGlobal(void* userData,
{
if (strcmp(interface, "wl_compositor") == 0)
{
_glfw.wl.compositorVersion = _glfw_min(3, version);
_glfw.wl.compositor =
wl_registry_bind(registry, name, &wl_compositor_interface,
_glfw.wl.compositorVersion);
_glfw_min(3, version));
}
else if (strcmp(interface, "wl_subcompositor") == 0)
{
@@ -84,10 +84,9 @@ static void registryHandleGlobal(void* userData,
{
if (!_glfw.wl.seat)
{
_glfw.wl.seatVersion = _glfw_min(4, version);
_glfw.wl.seat =
wl_registry_bind(registry, name, &wl_seat_interface,
_glfw.wl.seatVersion);
_glfw_min(4, version));
_glfwAddSeatListenerWayland(_glfw.wl.seat);
}
}
@@ -165,6 +164,36 @@ static const struct wl_registry_listener registryListener =
registryHandleGlobalRemove
};
void libdecorHandleError(struct libdecor* context,
enum libdecor_error error,
const char* message)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: libdecor error %u: %s",
error, message);
}
static const struct libdecor_interface libdecorInterface =
{
libdecorHandleError
};
static void libdecorReadyCallback(void* userData,
struct wl_callback* callback,
uint32_t time)
{
_glfw.wl.libdecor.ready = GLFW_TRUE;
assert(_glfw.wl.libdecor.callback == callback);
wl_callback_destroy(_glfw.wl.libdecor.callback);
_glfw.wl.libdecor.callback = NULL;
}
static const struct wl_callback_listener libdecorReadyListener =
{
libdecorReadyCallback
};
// Create key code translation tables
//
static void createKeyTables(void)
@@ -300,6 +329,38 @@ static void createKeyTables(void)
}
}
static GLFWbool loadCursorTheme(void)
{
int cursorSize = 16;
const char* sizeString = getenv("XCURSOR_SIZE");
if (sizeString)
{
errno = 0;
const long cursorSizeLong = strtol(sizeString, NULL, 10);
if (errno == 0 && cursorSizeLong > 0 && cursorSizeLong < INT_MAX)
cursorSize = (int) cursorSizeLong;
}
const char* themeName = getenv("XCURSOR_THEME");
_glfw.wl.cursorTheme = wl_cursor_theme_load(themeName, cursorSize, _glfw.wl.shm);
if (!_glfw.wl.cursorTheme)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to load default cursor theme");
return GLFW_FALSE;
}
// If this happens to be NULL, we just fallback to the scale=1 version.
_glfw.wl.cursorThemeHiDPI =
wl_cursor_theme_load(themeName, cursorSize * 2, _glfw.wl.shm);
_glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor);
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
@@ -307,16 +368,12 @@ static void createKeyTables(void)
int _glfwPlatformInit(void)
{
const char* cursorTheme;
const char* cursorSizeStr;
char* cursorSizeEnd;
long cursorSizeLong;
int cursorSize;
// These must be set before any failure checks
_glfw.wl.timerfd = -1;
_glfw.wl.keyRepeatTimerfd = -1;
_glfw.wl.cursorTimerfd = -1;
_glfw.wl.tag = glfwGetVersionString();
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
if (!_glfw.wl.cursor.handle)
{
@@ -407,6 +464,93 @@ int _glfwPlatformInit(void)
return GLFW_FALSE;
}
if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR)
_glfw.wl.libdecor.handle = _glfw_dlopen("libdecor-0.so.0");
if (_glfw.wl.libdecor.handle)
{
_glfw.wl.libdecor.libdecor_new_ = (PFN_libdecor_new)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_new");
_glfw.wl.libdecor.libdecor_unref_ = (PFN_libdecor_unref)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_unref");
_glfw.wl.libdecor.libdecor_get_fd_ = (PFN_libdecor_get_fd)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_get_fd");
_glfw.wl.libdecor.libdecor_dispatch_ = (PFN_libdecor_dispatch)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_dispatch");
_glfw.wl.libdecor.libdecor_decorate_ = (PFN_libdecor_decorate)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_decorate");
_glfw.wl.libdecor.libdecor_frame_unref_ = (PFN_libdecor_frame_unref)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unref");
_glfw.wl.libdecor.libdecor_frame_set_app_id_ = (PFN_libdecor_frame_set_app_id)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_app_id");
_glfw.wl.libdecor.libdecor_frame_set_title_ = (PFN_libdecor_frame_set_title)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_title");
_glfw.wl.libdecor.libdecor_frame_set_minimized_ = (PFN_libdecor_frame_set_minimized)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_minimized");
_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ = (PFN_libdecor_frame_set_fullscreen)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_fullscreen");
_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ = (PFN_libdecor_frame_unset_fullscreen)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unset_fullscreen");
_glfw.wl.libdecor.libdecor_frame_map_ = (PFN_libdecor_frame_map)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_map");
_glfw.wl.libdecor.libdecor_frame_commit_ = (PFN_libdecor_frame_commit)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_commit");
_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ = (PFN_libdecor_frame_set_min_content_size)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_min_content_size");
_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ = (PFN_libdecor_frame_set_max_content_size)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_max_content_size");
_glfw.wl.libdecor.libdecor_frame_set_maximized_ = (PFN_libdecor_frame_set_maximized)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_maximized");
_glfw.wl.libdecor.libdecor_frame_unset_maximized_ = (PFN_libdecor_frame_unset_maximized)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unset_maximized");
_glfw.wl.libdecor.libdecor_frame_set_capabilities_ = (PFN_libdecor_frame_set_capabilities)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_capabilities");
_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ = (PFN_libdecor_frame_unset_capabilities)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities");
_glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility");
_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel");
_glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_configuration_get_content_size");
_glfw.wl.libdecor.libdecor_configuration_get_window_state_ = (PFN_libdecor_configuration_get_window_state)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_configuration_get_window_state");
_glfw.wl.libdecor.libdecor_state_new_ = (PFN_libdecor_state_new)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_state_new");
_glfw.wl.libdecor.libdecor_state_free_ = (PFN_libdecor_state_free)
_glfw_dlsym(_glfw.wl.libdecor.handle, "libdecor_state_free");
if (!_glfw.wl.libdecor.libdecor_new_ ||
!_glfw.wl.libdecor.libdecor_unref_ ||
!_glfw.wl.libdecor.libdecor_get_fd_ ||
!_glfw.wl.libdecor.libdecor_dispatch_ ||
!_glfw.wl.libdecor.libdecor_decorate_ ||
!_glfw.wl.libdecor.libdecor_frame_unref_ ||
!_glfw.wl.libdecor.libdecor_frame_set_app_id_ ||
!_glfw.wl.libdecor.libdecor_frame_set_title_ ||
!_glfw.wl.libdecor.libdecor_frame_set_minimized_ ||
!_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ ||
!_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ ||
!_glfw.wl.libdecor.libdecor_frame_map_ ||
!_glfw.wl.libdecor.libdecor_frame_commit_ ||
!_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ ||
!_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ ||
!_glfw.wl.libdecor.libdecor_frame_set_maximized_ ||
!_glfw.wl.libdecor.libdecor_frame_unset_maximized_ ||
!_glfw.wl.libdecor.libdecor_frame_set_capabilities_ ||
!_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ ||
!_glfw.wl.libdecor.libdecor_frame_set_visibility_ ||
!_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ ||
!_glfw.wl.libdecor.libdecor_configuration_get_content_size_ ||
!_glfw.wl.libdecor.libdecor_configuration_get_window_state_ ||
!_glfw.wl.libdecor.libdecor_state_new_ ||
!_glfw.wl.libdecor.libdecor_state_free_)
{
_glfw_dlclose(_glfw.wl.libdecor.handle);
memset(&_glfw.wl.libdecor, 0, sizeof(_glfw.wl.libdecor));
}
}
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
@@ -433,9 +577,28 @@ int _glfwPlatformInit(void)
_glfwInitTimerPOSIX();
if (_glfw.wl.libdecor.handle)
{
_glfw.wl.libdecor.context = libdecor_new(_glfw.wl.display, &libdecorInterface);
if (_glfw.wl.libdecor.context)
{
// Perform an initial dispatch and flush to get the init started
libdecor_dispatch(_glfw.wl.libdecor.context, 0);
// Create sync point to "know" when libdecor is ready for use
_glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display);
wl_callback_add_listener(_glfw.wl.libdecor.callback,
&libdecorReadyListener,
NULL);
}
}
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
_glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
{
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
}
#endif
if (!_glfw.wl.wmBase)
@@ -445,34 +608,16 @@ int _glfwPlatformInit(void)
return GLFW_FALSE;
}
if (_glfw.wl.pointer && _glfw.wl.shm)
if (!_glfw.wl.shm)
{
cursorTheme = getenv("XCURSOR_THEME");
cursorSizeStr = getenv("XCURSOR_SIZE");
cursorSize = 32;
if (cursorSizeStr)
{
errno = 0;
cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10);
if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX)
cursorSize = (int)cursorSizeLong;
}
_glfw.wl.cursorTheme =
wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm);
if (!_glfw.wl.cursorTheme)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to load default cursor theme");
return GLFW_FALSE;
}
// If this happens to be NULL, we just fallback to the scale=1 version.
_glfw.wl.cursorThemeHiDPI =
wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
_glfw.wl.cursorSurface =
wl_compositor_create_surface(_glfw.wl.compositor);
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to find wl_shm in your compositor");
return GLFW_FALSE;
}
if (!loadCursorTheme())
return GLFW_FALSE;
if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
{
_glfw.wl.dataDevice =
@@ -492,6 +637,22 @@ void _glfwPlatformTerminate(void)
_glfwTerminateEGL();
_glfwTerminateOSMesa();
if (_glfw.wl.libdecor.context)
{
// Allow libdecor to finish receiving all its requested globals
// and ensure the associated sync callback object is destroyed
while (!_glfw.wl.libdecor.ready)
_glfwPlatformWaitEvents();
libdecor_unref(_glfw.wl.libdecor.context);
}
if (_glfw.wl.libdecor.handle)
{
_glfw_dlclose(_glfw.wl.libdecor.handle);
_glfw.wl.libdecor.handle = NULL;
}
if (_glfw.wl.egl.handle)
{
_glfw_dlclose(_glfw.wl.egl.handle);
@@ -571,8 +732,8 @@ void _glfwPlatformTerminate(void)
wl_display_disconnect(_glfw.wl.display);
}
if (_glfw.wl.timerfd >= 0)
close(_glfw.wl.timerfd);
if (_glfw.wl.keyRepeatTimerfd >= 0)
close(_glfw.wl.keyRepeatTimerfd);
if (_glfw.wl.cursorTimerfd >= 0)
close(_glfw.wl.cursorTimerfd);
+8 -6
View File
@@ -110,14 +110,15 @@ static void outputHandleScale(void* userData,
{
struct _GLFWmonitor* monitor = userData;
monitor->wl.scale = factor;
monitor->wl.contentScale = factor;
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
{
for (int i = 0; i < window->wl.monitorsCount; i++)
for (int i = 0; i < window->wl.scaleCount; i++)
{
if (window->wl.monitors[i] == monitor)
if (window->wl.scales[i].output == monitor->wl.output)
{
window->wl.scales[i].factor = monitor->wl.contentScale;
_glfwUpdateContentScaleWayland(window);
break;
}
@@ -183,10 +184,11 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
// The actual name of this output will be set in the geometry handler
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
monitor->wl.scale = 1;
monitor->wl.contentScale = 1;
monitor->wl.output = output;
monitor->wl.name = name;
wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag);
wl_output_add_listener(output, &outputListener, monitor);
}
@@ -213,9 +215,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = (float) monitor->wl.scale;
*xscale = (float) monitor->wl.contentScale;
if (yscale)
*yscale = (float) monitor->wl.scale;
*yscale = (float) monitor->wl.contentScale;
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
+179 -22
View File
@@ -29,6 +29,8 @@
#include <xkbcommon/xkbcommon-compose.h>
#include <dlfcn.h>
#include <stdbool.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR
@@ -146,13 +148,129 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st
#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
struct libdecor;
struct libdecor_frame;
struct libdecor_state;
struct libdecor_configuration;
enum libdecor_error
{
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
};
enum libdecor_window_state
{
LIBDECOR_WINDOW_STATE_NONE = 0,
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
};
enum libdecor_capabilities
{
LIBDECOR_ACTION_MOVE = 1,
LIBDECOR_ACTION_RESIZE = 2,
LIBDECOR_ACTION_MINIMIZE = 4,
LIBDECOR_ACTION_FULLSCREEN = 8,
LIBDECOR_ACTION_CLOSE = 16
};
struct libdecor_interface
{
void (* error)(struct libdecor*,enum libdecor_error,const char*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
struct libdecor_frame_interface
{
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
void (* close)(struct libdecor_frame*,void*);
void (* commit)(struct libdecor_frame*,void*);
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
typedef void (* PFN_libdecor_unref)(struct libdecor*);
typedef int (* PFN_libdecor_get_fd)(struct libdecor*);
typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int);
typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*);
typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*);
typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*);
typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*);
typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*);
typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int);
typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int);
typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible);
typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*);
typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*);
typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*);
typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int);
typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);
#define libdecor_new _glfw.wl.libdecor.libdecor_new_
#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_
#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_
#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_
#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_
#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_
#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_
#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_
#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_
#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_
#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_
#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_
#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_
#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_
#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_
#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_
#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_
#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_
#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_
#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_
#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_
#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_
#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_
#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_
#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_
typedef enum _GLFWdecorationSideWayland
{
mainWindow,
topDecoration,
leftDecoration,
rightDecoration,
bottomDecoration,
GLFW_MAIN_WINDOW,
GLFW_TOP_DECORATION,
GLFW_LEFT_DECORATION,
GLFW_RIGHT_DECORATION,
GLFW_BOTTOM_DECORATION
} _GLFWdecorationSideWayland;
typedef struct _GLFWdecorationWayland
@@ -169,6 +287,12 @@ typedef struct _GLFWofferWayland
GLFWbool text_uri_list;
} _GLFWofferWayland;
typedef struct _GLFWscaleWayland
{
struct wl_output* output;
int factor;
} _GLFWscaleWayland;
// Wayland-specific per-window data
//
typedef struct _GLFWwindowWayland
@@ -202,6 +326,11 @@ typedef struct _GLFWwindowWayland
uint32_t decorationMode;
} xdg;
struct {
struct libdecor_frame* frame;
int mode;
} libdecor;
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY;
@@ -209,15 +338,13 @@ typedef struct _GLFWwindowWayland
// We need to track the monitors the window spans on to calculate the
// optimal scaling factor.
int scale;
_GLFWmonitor** monitors;
int monitorsCount;
int monitorsSize;
int contentScale;
_GLFWscaleWayland* scales;
int scaleCount;
int scaleSize;
struct {
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
} pointerLock;
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
struct zwp_idle_inhibitor_v1* idleInhibitor;
@@ -259,8 +386,7 @@ typedef struct _GLFWlibraryWayland
_GLFWwindow* dragFocus;
uint32_t dragSerial;
int compositorVersion;
int seatVersion;
const char* tag;
struct wl_cursor_theme* cursorTheme;
struct wl_cursor_theme* cursorThemeHiDPI;
@@ -270,12 +396,12 @@ typedef struct _GLFWlibraryWayland
uint32_t serial;
uint32_t pointerEnterSerial;
int32_t keyboardRepeatRate;
int32_t keyboardRepeatDelay;
int keyboardLastKey;
int keyboardLastScancode;
int keyRepeatTimerfd;
int32_t keyRepeatRate;
int32_t keyRepeatDelay;
int keyRepeatScancode;
char* clipboardString;
int timerfd;
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
@@ -337,6 +463,38 @@ typedef struct _GLFWlibraryWayland
PFN_wl_egl_window_destroy window_destroy;
PFN_wl_egl_window_resize window_resize;
} egl;
struct {
void* handle;
struct libdecor* context;
struct wl_callback* callback;
GLFWbool ready;
PFN_libdecor_new libdecor_new_;
PFN_libdecor_unref libdecor_unref_;
PFN_libdecor_get_fd libdecor_get_fd_;
PFN_libdecor_dispatch libdecor_dispatch_;
PFN_libdecor_decorate libdecor_decorate_;
PFN_libdecor_frame_unref libdecor_frame_unref_;
PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_;
PFN_libdecor_frame_set_title libdecor_frame_set_title_;
PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_;
PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_;
PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_;
PFN_libdecor_frame_map libdecor_frame_map_;
PFN_libdecor_frame_commit libdecor_frame_commit_;
PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_;
PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_;
PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_;
PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_;
PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_;
PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_;
PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_;
PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_;
PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_;
PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_;
PFN_libdecor_state_new libdecor_state_new_;
PFN_libdecor_state_free libdecor_state_free_;
} libdecor;
} _GLFWlibraryWayland;
// Wayland-specific per-monitor data
@@ -349,7 +507,7 @@ typedef struct _GLFWmonitorWayland
int x;
int y;
int scale;
int contentScale;
} _GLFWmonitorWayland;
// Wayland-specific per-cursor data
@@ -366,7 +524,6 @@ typedef struct _GLFWcursorWayland
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode);
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
+690 -403
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -735,6 +735,12 @@ static GLFWbool initExtensions(void)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
_glfw.x11.xcursor.GetTheme = (PFN_XcursorGetTheme)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetTheme");
_glfw.x11.xcursor.GetDefaultSize = (PFN_XcursorGetDefaultSize)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetDefaultSize");
_glfw.x11.xcursor.LibraryLoadImage = (PFN_XcursorLibraryLoadImage)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorLibraryLoadImage");
}
#if defined(__CYGWIN__)
+9
View File
@@ -85,9 +85,15 @@ typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
typedef char* (* PFN_XcursorGetTheme)(Display*);
typedef int (* PFN_XcursorGetDefaultSize)(Display*);
typedef XcursorImage* (* PFN_XcursorLibraryLoadImage)(const char*,const char*,int);
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
#define XcursorGetTheme _glfw.x11.xcursor.GetTheme
#define XcursorGetDefaultSize _glfw.x11.xcursor.GetDefaultSize
#define XcursorLibraryLoadImage _glfw.x11.xcursor.LibraryLoadImage
typedef Bool (* PFN_XineramaIsActive)(Display*);
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
@@ -356,6 +362,9 @@ typedef struct _GLFWlibraryX11
PFN_XcursorImageCreate ImageCreate;
PFN_XcursorImageDestroy ImageDestroy;
PFN_XcursorImageLoadCursor ImageLoadCursor;
PFN_XcursorGetTheme GetTheme;
PFN_XcursorGetDefaultSize GetDefaultSize;
PFN_XcursorLibraryLoadImage LibraryLoadImage;
} xcursor;
struct {
+151 -41
View File
@@ -321,6 +321,11 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
{
XSizeHints* hints = XAllocSizeHints();
long supplied;
XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied);
hints->flags &= ~(PMinSize | PMaxSize | PAspect);
if (!window->monitor)
{
if (window->resizable)
@@ -357,9 +362,6 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
}
}
hints->flags |= PWinGravity;
hints->win_gravity = StaticGravity;
XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
XFree(hints);
}
@@ -523,6 +525,25 @@ static void updateCursorImage(_GLFWwindow* window)
}
}
// Grabs the cursor and confines it to the window
//
static void captureCursor(_GLFWwindow* window)
{
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync,
window->x11.handle,
None,
CurrentTime);
}
// Ungrabs the cursor
//
static void releaseCursor(void)
{
XUngrabPointer(_glfw.x11.display, CurrentTime);
}
// Enable XI2 raw mouse motion events
//
static void enableRawMouseMotion(_GLFWwindow* window)
@@ -565,12 +586,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.x11.restoreCursorPosY);
updateCursorImage(window);
_glfwCenterCursorInContentArea(window);
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync,
window->x11.handle,
_glfw.x11.hiddenCursorHandle,
CurrentTime);
captureCursor(window);
}
// Exit disabled cursor mode for the specified window
@@ -581,7 +597,7 @@ static void enableCursor(_GLFWwindow* window)
disableRawMouseMotion(window);
_glfw.x11.disabledCursorWindow = NULL;
XUngrabPointer(_glfw.x11.display, CurrentTime);
releaseCursor();
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
@@ -726,7 +742,28 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
XFree(hints);
}
updateNormalHints(window, width, height);
// Set ICCCM WM_NORMAL_HINTS property
{
XSizeHints* hints = XAllocSizeHints();
if (!hints)
{
_glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate size hints");
return GLFW_FALSE;
}
if (!wndconfig->resizable)
{
hints->flags |= (PMinSize | PMaxSize);
hints->min_width = hints->max_width = width;
hints->min_height = hints->max_height = height;
}
hints->flags |= PWinGravity;
hints->win_gravity = StaticGravity;
XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
XFree(hints);
}
// Set ICCCM WM_CLASS property
{
@@ -2044,7 +2081,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (_glfw.x11.disabledCursorWindow == window)
_glfw.x11.disabledCursorWindow = NULL;
enableCursor(window);
if (window->monitor)
releaseMonitor(window);
@@ -2851,16 +2888,40 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (mode == GLFW_CURSOR_DISABLED)
if (_glfwPlatformWindowFocused(window))
{
if (_glfwPlatformWindowFocused(window))
disableCursor(window);
}
else if (_glfw.x11.disabledCursorWindow == window)
enableCursor(window);
else
updateCursorImage(window);
if (mode == GLFW_CURSOR_DISABLED)
{
_glfwPlatformGetCursorPos(window,
&_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY);
_glfwCenterCursorInContentArea(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
}
else if (_glfw.x11.disabledCursorWindow == window)
{
if (window->rawMouseMotion)
disableRawMouseMotion(window);
}
if (mode == GLFW_CURSOR_DISABLED)
captureCursor(window);
else
releaseCursor();
if (mode == GLFW_CURSOR_DISABLED)
_glfw.x11.disabledCursorWindow = window;
else if (_glfw.x11.disabledCursorWindow == window)
{
_glfw.x11.disabledCursorWindow = NULL;
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
}
}
updateCursorImage(window);
XFlush(_glfw.x11.display);
}
@@ -2869,14 +2930,16 @@ const char* _glfwPlatformGetScancodeName(int scancode)
if (!_glfw.x11.xkb.available)
return NULL;
if (scancode < 0 || scancode > 0xff ||
_glfw.x11.keycodes[scancode] == GLFW_KEY_UNKNOWN)
if (scancode < 0 || scancode > 0xff)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
return NULL;
}
const int key = _glfw.x11.keycodes[scancode];
if (key == GLFW_KEY_UNKNOWN)
return NULL;
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display,
scancode, _glfw.x11.xkb.group, 0);
if (keysym == NoSymbol)
@@ -2912,29 +2975,76 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
int native = 0;
if (_glfw.x11.xcursor.handle)
{
char* theme = XcursorGetTheme(_glfw.x11.display);
if (theme)
{
const int size = XcursorGetDefaultSize(_glfw.x11.display);
const char* name = NULL;
if (shape == GLFW_ARROW_CURSOR)
native = XC_left_ptr;
else if (shape == GLFW_IBEAM_CURSOR)
native = XC_xterm;
else if (shape == GLFW_CROSSHAIR_CURSOR)
native = XC_crosshair;
else if (shape == GLFW_HAND_CURSOR)
native = XC_hand2;
else if (shape == GLFW_HRESIZE_CURSOR)
native = XC_sb_h_double_arrow;
else if (shape == GLFW_VRESIZE_CURSOR)
native = XC_sb_v_double_arrow;
else
return GLFW_FALSE;
if (shape == GLFW_ARROW_CURSOR)
name = "default";
else if (shape == GLFW_IBEAM_CURSOR)
name = "text";
else if (shape == GLFW_CROSSHAIR_CURSOR)
name = "crosshair";
else if (shape == GLFW_POINTING_HAND_CURSOR)
name = "pointer";
else if (shape == GLFW_RESIZE_EW_CURSOR)
name = "ew-resize";
else if (shape == GLFW_RESIZE_NS_CURSOR)
name = "ns-resize";
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
name = "nwse-resize";
else if (shape == GLFW_RESIZE_NESW_CURSOR)
name = "nesw-resize";
else if (shape == GLFW_RESIZE_ALL_CURSOR)
name = "all-scroll";
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
name = "not-allowed";
XcursorImage* image = XcursorLibraryLoadImage(name, theme, size);
if (image)
{
cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, image);
XcursorImageDestroy(image);
}
}
}
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
if (!cursor->x11.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create standard cursor");
return GLFW_FALSE;
unsigned int native = 0;
if (shape == GLFW_ARROW_CURSOR)
native = XC_left_ptr;
else if (shape == GLFW_IBEAM_CURSOR)
native = XC_xterm;
else if (shape == GLFW_CROSSHAIR_CURSOR)
native = XC_crosshair;
else if (shape == GLFW_POINTING_HAND_CURSOR)
native = XC_hand2;
else if (shape == GLFW_RESIZE_EW_CURSOR)
native = XC_sb_h_double_arrow;
else if (shape == GLFW_RESIZE_NS_CURSOR)
native = XC_sb_v_double_arrow;
else if (shape == GLFW_RESIZE_ALL_CURSOR)
native = XC_fleur;
else
{
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
"X11: Standard cursor shape unavailable");
return GLFW_FALSE;
}
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
if (!cursor->x11.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create standard cursor");
return GLFW_FALSE;
}
}
return GLFW_TRUE;
+20 -25
View File
@@ -69,7 +69,7 @@ static int swap_interval = 1;
static int wait_events = GLFW_TRUE;
static int animate_cursor = GLFW_FALSE;
static int track_cursor = GLFW_FALSE;
static GLFWcursor* standard_cursors[6];
static GLFWcursor* standard_cursors[10];
static GLFWcursor* tracking_cursor = NULL;
static void error_callback(int error, const char* description)
@@ -271,28 +271,24 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
break;
case GLFW_KEY_1:
glfwSetCursor(window, standard_cursors[0]);
break;
case GLFW_KEY_2:
glfwSetCursor(window, standard_cursors[1]);
break;
case GLFW_KEY_3:
glfwSetCursor(window, standard_cursors[2]);
break;
case GLFW_KEY_4:
glfwSetCursor(window, standard_cursors[3]);
break;
case GLFW_KEY_5:
glfwSetCursor(window, standard_cursors[4]);
break;
case GLFW_KEY_6:
glfwSetCursor(window, standard_cursors[5]);
case GLFW_KEY_7:
case GLFW_KEY_8:
case GLFW_KEY_9:
{
int index = key - GLFW_KEY_1;
if (mods & GLFW_MOD_SHIFT)
index += 9;
if (index < sizeof(standard_cursors) / sizeof(standard_cursors[0]))
glfwSetCursor(window, standard_cursors[index]);
break;
}
case GLFW_KEY_F11:
case GLFW_KEY_ENTER:
@@ -358,17 +354,16 @@ int main(void)
GLFW_ARROW_CURSOR,
GLFW_IBEAM_CURSOR,
GLFW_CROSSHAIR_CURSOR,
GLFW_HAND_CURSOR,
GLFW_HRESIZE_CURSOR,
GLFW_VRESIZE_CURSOR
GLFW_POINTING_HAND_CURSOR,
GLFW_RESIZE_EW_CURSOR,
GLFW_RESIZE_NS_CURSOR,
GLFW_RESIZE_NWSE_CURSOR,
GLFW_RESIZE_NESW_CURSOR,
GLFW_RESIZE_ALL_CURSOR,
GLFW_NOT_ALLOWED_CURSOR
};
standard_cursors[i] = glfwCreateStandardCursor(shapes[i]);
if (!standard_cursors[i])
{
glfwTerminate();
exit(EXIT_FAILURE);
}
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
+24 -14
View File
@@ -393,24 +393,34 @@ static void scroll_callback(GLFWwindow* window, double x, double y)
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
Slot* slot = glfwGetWindowUserPointer(window);
const char* name = glfwGetKeyName(key, scancode);
if (name)
if (key == GLFW_KEY_UNKNOWN)
{
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s\n",
counter++, slot->number, glfwGetTime(), key, scancode,
get_key_name(key),
name,
get_mods_name(mods),
get_action_name(action));
printf("%08x to %i at %0.3f: Key (%s) Scancode 0x%04x (with%s) was %s\n",
counter++, slot->number, glfwGetTime(),
get_key_name(key), scancode,
get_mods_name(mods),
get_action_name(action));
}
else
{
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n",
counter++, slot->number, glfwGetTime(), key, scancode,
get_key_name(key),
get_mods_name(mods),
get_action_name(action));
const char* name = glfwGetKeyName(key, scancode);
if (name)
{
printf("%08x to %i at %0.3f: Key 0x%04x (%s) Scancode 0x%04x Name %s (with%s) was %s\n",
counter++, slot->number, glfwGetTime(),
key, get_key_name(key), scancode, name,
get_mods_name(mods),
get_action_name(action));
}
else
{
printf("%08x to %i at %0.3f: Key 0x%04x (%s) Scancode 0x%04x (with%s) was %s\n",
counter++, slot->number, glfwGetTime(),
key, get_key_name(key), scancode,
get_mods_name(mods),
get_action_name(action));
}
}
if (action != GLFW_PRESS)
@@ -621,7 +631,7 @@ int main(int argc, char** argv)
glfwMakeContextCurrent(slots[i].window);
gladLoadGL(glfwGetProcAddress);
glfwSwapInterval(1);
glfwSwapBuffers(slots[i].window);
}
printf("Main loop starting\n");
+32 -4
View File
@@ -230,9 +230,10 @@ static void list_vulkan_instance_layers(void)
for (i = 0; i < lp_count; i++)
{
printf(" %s (v%u) \"%s\"\n",
printf(" %s (spec version %u.%u) \"%s\"\n",
lp[i].layerName,
lp[i].specVersion >> 22,
VK_VERSION_MAJOR(lp[i].specVersion),
VK_VERSION_MINOR(lp[i].specVersion),
lp[i].description);
}
@@ -259,9 +260,10 @@ static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice devi
for (i = 0; i < lp_count; i++)
{
printf(" %s (v%u) \"%s\"\n",
printf(" %s (spec version %u.%u) \"%s\"\n",
lp[i].layerName,
lp[i].specVersion >> 22,
VK_VERSION_MAJOR(lp[i].specVersion),
VK_VERSION_MINOR(lp[i].specVersion),
lp[i].description);
}
@@ -753,6 +755,17 @@ int main(int argc, char** argv)
if (list_extensions)
list_context_extensions(client, major, minor);
glfwDestroyWindow(window);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
printf("Vulkan loader: %s\n",
glfwVulkanSupported() ? "available" : "missing");
@@ -851,6 +864,19 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE);
}
if (re)
{
VkSurfaceKHR surface = VK_NULL_HANDLE;
if (glfwCreateWindowSurface(instance, window, NULL, &surface) == VK_SUCCESS)
{
printf("Vulkan window surface created successfully\n");
vkDestroySurfaceKHR(instance, surface, NULL);
}
else
printf("Failed to create Vulkan window surface\n");
}
free((void*) re);
gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, instance);
@@ -937,6 +963,8 @@ int main(int argc, char** argv)
vkDestroyInstance(instance, NULL);
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}